bonus-material-app/src/pages/picking/outbound/numCodeSelect.vue

642 lines
19 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<!-- 编码出库-->
<view class="page-container">
<!-- 表单信息区域 -->
<scroll-view scroll-y style="height: 100vh">
<view class="form-section">
<view class="section-header" @tap="toggleForm">
<text class="title">任务信息</text>
<text class="toggle-icon" :class="{ 'is-expanded': isExpanded }"></text>
</view>
<view class="form-content" :class="{ 'is-expanded': isExpanded }">
<uni-forms :model="formData" label-width="100" :border="true">
<uni-forms-item label="领料单位:" name="leaseUnit">
<span class="form-view">{{ queryParams.leaseUnit }}</span>
</uni-forms-item>
<uni-forms-item label="领料工程:" name="leaseProject">
<span class="form-view">{{ queryParams.leaseProject }}</span>
</uni-forms-item>
<uni-forms-item label="物资类型:" name="maTypeName">
<span class="form-view">{{ queryParams.maTypeName }}</span>
</uni-forms-item>
<uni-forms-item label="规格型号:" name="typeName">
<span class="form-view">{{ queryParams.typeName }}</span>
</uni-forms-item>
<uni-forms-item label="待出库数量:" name="maxNum">
<span class="form-view">{{ maxNum }}</span>
</uni-forms-item>
</uni-forms>
</view>
</view>
<view class="table-list-item">
<uni-row :gutter="24" style="display: flex; align-items: center">
<uni-col :span="6">出库方式</uni-col>
<!-- <uni-col :span="6">
<view class="coding-btn" @tap="onCodeIdentify">编码识别</view>
</uni-col>
-->
<uni-col :span="6">
<view class="coding-btn" @tap="scanStart">二维码添加</view>
</uni-col>
<uni-col :span="6">
<view class="coding-btn" @tap="boxScan">标准箱添加</view>
</uni-col>
</uni-row>
</view>
<ScanQrCode
ref="scanQrCodeRef"
@scanSuccess="handleScanSuccess"
@scanError="handleScanError"
/>
<ScanQrCodeBox
ref="scanQrCodeRefBox"
@scanSuccessBox="handleScanSuccessBox"
@scanErrorBox="handleScanErrorBox"
/>
<view class="table-list-item">
<uni-row :gutter="24" style="display: flex; align-items: center">
<uni-col :span="6">
<view> 设备编码 </view>
</uni-col>
<uni-col :span="12">
<view>
<uni-easyinput
v-model="queryCodeParams.maCode"
placeholder="请输入内容"
/>
</view>
</uni-col>
<uni-col :span="6">
<view class="coding-btn search-btn" @tap="onCodeSearch">编码检索</view>
</uni-col>
</uni-row>
</view>
<scroll-view
scroll-y
@scrolltolower="onScrollTolower"
style="padding-bottom: 90rpx; height: 70vh"
>
<view class="table-list-item" v-for="item in codeDeviceList" :key="item.maId">
<uni-row :gutter="24">
<uni-col :span="6">物资类型:</uni-col>
<uni-col :span="14">
<view class="cont">{{ item.materialName }}</view>
</uni-col>
<uni-col :span="4">
<checkbox-group @change="onChangeChecked(item)">
<label>
<checkbox
color="#409eff"
borderColor="#409eff"
activeBorderColor="#409eff"
:checked="item.checked"
:disabled="maxNum === isSelectNum && !item.checked"
style="transform: scale(0.7)"
/>
</label>
</checkbox-group>
</uni-col>
</uni-row>
<uni-row :gutter="24">
<uni-col :span="6">规格型号:</uni-col>
<uni-col :span="16">
<view class="cont">{{ item.materialModel }}</view>
</uni-col>
</uni-row>
<uni-row :gutter="24">
<uni-col :span="6">设备编码:</uni-col>
<uni-col :span="16">
<view class="cont">{{ item.maCode }}</view>
</uni-col>
</uni-row>
<uni-row :gutter="24">
<uni-col :span="6">设备数量:</uni-col>
<uni-col :span="16">
<view class="cont">1</view>
</uni-col>
</uni-row>
</view>
<view class="loading-text">
{{ '没有更多数据了~' }}
</view>
</scroll-view>
</scroll-view>
<view class="outbound-btn" @tap="onHandleOutbound"> 添加编码 </view>
</view>
</template>
<script setup>
import { ref, computed } from 'vue'
import { onLoad, onShow } from '@dcloudio/uni-app'
import {
getCodeDetailAPI,
getCodeScanAPI,
getInfoByTypeId,
getBoxDetailsAPI,
} from '@/services/picking/outbound.js'
import { debounce } from 'lodash-es'
import ScanQrCode from '@/pages/devicesSearch/ScanQrCode.vue'
import ScanQrCodeBox from '@/pages/devicesSearch/ScanQrCodeBox.vue'
const loading = ref(false)
const scanQrCodeRef = ref(null)
const scanQrCodeRefBox = ref(null)
const queryParams = ref({})
const formData = ref({})
const codeDeviceList = ref([])
const maxNum = ref(0)
const total = ref(0)
const boxCode = ref('')
const boxInfo = ref({})
// 编码设备列表查询参数
const queryCodeParams = ref({
pageNum: 1,
pageSize: 10,
typeId: '',
})
const qrCodeScan = ref('')
const codeData = ref({})
// 控制表单展开收起
const isExpanded = ref(false)
// 切换表单展开状态
const toggleForm = () => {
isExpanded.value = !isExpanded.value
}
// 页面加载完毕
onLoad((options) => {
console.log(queryParams.value)
queryParams.value = JSON.parse(options.queryParams)
})
onShow(() => {
console.log(queryParams.value)
getCodeDetailData(queryParams.value.id, queryParams.value.publishTask, queryParams.value.typeId) //获取详情
})
// 获取编码列表
const getCodeDetailData = async (id, publishTask, typeId) => {
console.log('yyyyyyyyyy', id, publishTask, typeId)
const res = await getCodeDetailAPI({ id: id, publishTask: publishTask, typeId: typeId })
console.log('zzzzzzzzz', res)
formData.value = res.data
console.log('xxxxxxxxxxxxxx', formData.value, maxNum.value)
maxNum.value = formData.value.preNum - formData.value.alNum
queryCodeParams.value.typeId = queryParams.value.typeId
queryCodeParams.value.pageNum = 1
codeDeviceList.value = []
getCodeDeviceListData() //获取编码列表
}
// 获取编码列表
const getCodeDeviceListData = async () => {
// 记录已勾选的设备ID
const res = await getInfoByTypeId(queryCodeParams.value)
codeDeviceList.value = res.data
if (queryParams.value.maCodeList.length > 0) {
const checkedIds = queryParams.value.maCodeList.map((e) => e.maId)
codeDeviceList.value.forEach((item) => {
item.checked = checkedIds.includes(item.maId)
})
} else {
codeDeviceList.value.forEach((item) => {
item.checked = false
})
}
}
// 编码搜索按钮
const onCodeSearch = () => {
queryCodeParams.value.pageNum = 1
codeDeviceList.value = []
getCodeDeviceListData()
}
// 滚动触底事件
const onScrollTolower = debounce(() => {
// console.log('滚动触底--')
}, 500)
// 判断数<E696AD><E695B0>是否加载完毕
const finish = computed(() => {
if (total.value === codeDeviceList.value.length) return true
})
// 复选框事件
const onChangeChecked = (item) => {
item.checked = !item.checked
}
// 计算已选择数量
const isSelectNum = computed(() => {
const isSelectList = codeDeviceList.value.filter((e) => e.checked === true)
if (maxNum.value === isSelectList.length) {
uni.showToast({
title: '勾选设备已达到最大待出库数量!',
icon: 'none',
})
}
return isSelectList.length
})
// 出库按钮
const onHandleOutbound = async () => {
const isSelect = codeDeviceList.value.some((e) => e.checked === true)
if (!isSelect) {
uni.showToast({
title: '请添加编码',
icon: 'none',
})
return
}
if (loading.value) {
uni.showToast({
title: '请勿重复提交!',
icon: 'none',
})
return
}
loading.value = true
// 组装出库参数
const maCodeList = []
codeDeviceList.value.map((e) => {
if (e.checked) {
maCodeList.push({
maId: e.maId,
maCode: e.maCode,
typeId: queryParams.value.typeId,
})
}
})
console.log('maCodeList', maCodeList)
uni.$emit('maCodeList', { maCodeList })
uni.navigateBack()
}
// 标准箱识别
const boxScan = async () => {
if (maxNum.value == 0) {
uni.showToast({
title: '待出库数量已为0',
icon: 'none',
})
} else {
boxCode.value = ''
if (scanQrCodeRefBox.value) {
scanQrCodeRefBox.value.scanQrCode()
}
}
}
// 处理扫描成功事件
const handleScanSuccessBox = (result) => {
boxCode.value = result?.text || ''
if (boxCode.value === '') {
uni.showToast({ title: '扫码识别失败', icon: 'none' })
} else {
boxOut()
}
}
// 处理扫描失败事件
const handleScanErrorBox = (error) => {
console.error('扫描出错:', error.message)
uni.showToast({ title: error.message, icon: 'none' })
}
// 标准箱出库确认
const boxOut = async () => {
console.log(queryParams)
try {
const res = await getBoxDetailsAPI({ boxCode: boxCode.value })
console.log('🚀 ~ boxOut ~ res:', res)
if (res.code === 200 && res.data && res.data.length > 0) {
const maCodeList = res.data.map((item) => ({
maId: item.maId,
maCode: item.maCode,
typeId: queryParams.value.typeId,
}))
uni.$emit('maCodeList', { maCodeList })
uni.navigateBack()
}
} catch (error) {
console.log('🚀 ~ boxOut ~ error:', error)
}
}
// 扫码识别按钮
const scanStart = () => {
if (maxNum.value == 0) {
uni.showToast({
title: '待出库数量已为0',
icon: 'none',
})
} else {
if (scanQrCodeRef.value) {
scanQrCodeRef.value.scanQrCode()
}
}
}
// 处理扫描成功事件
const handleScanSuccess = (result) => {
qrCodeScan.value = result?.text?.split('?qrcode=')[1] || result?.text
if (qrCodeScan.value === '') {
uni.showToast({ title: '扫码识别失败', icon: 'none' })
} else {
getMaInfoScan()
}
}
// 处理扫描失败事件
const handleScanError = (error) => {
console.error('扫描出错:', error.message)
uni.showToast({ title: error.message, icon: 'none' })
}
//查看是否是该规格型号
const getMaInfoScan = async () => {
let param = {
qrCode: qrCodeScan.value,
}
const res = await getCodeScanAPI(param)
if (res.code == 200) {
if (res.data && res.data.recordList.length > 0) {
const maCodeList = res.data.recordList.map((item) => ({
maId: item.maId,
maCode: item.maCode,
typeId: queryParams.value.typeId,
}))
console.log('🚀 ~ maCodeList ~ maCodeList:', maCodeList)
uni.$emit('maCodeList', { maCodeList })
uni.navigateBack()
} else {
uni.showToast({ title: res.data.msg, icon: 'none' })
}
} else {
uni.showToast({ title: res.data.msg, icon: 'none' })
}
}
</script>
<style lang="scss" scoped>
.page-container {
display: flex;
height: 100%;
flex-direction: column;
background-color: #f7f8fa;
padding: 24rpx;
.table-list-item {
background: #fff;
padding: 15rpx 32rpx;
border-radius: 20rpx;
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.06);
margin-bottom: 24rpx;
// 表单样式
:deep(.uni-forms) {
.uni-forms-item {
margin-bottom: 24rpx;
padding: 0;
&:last-child {
margin-bottom: 0;
}
.uni-forms-item__label {
color: #8c8c8c;
font-size: 28rpx;
font-weight: 500;
padding: 0;
line-height: 1.8;
}
.uni-forms-item__content {
display: flex;
align-items: center;
min-height: unset;
}
}
}
// 编码按钮组
.coding-btn {
padding: 16rpx 0;
background: linear-gradient(135deg, #4b8eff 0%, #3784fb 100%);
border-radius: 12rpx;
text-align: center;
color: #fff;
font-size: 28rpx;
font-weight: 600;
box-shadow: 0 6rpx 20rpx rgba(55, 132, 251, 0.2);
transition: all 0.3s ease;
&:active {
transform: scale(0.98);
opacity: 0.9;
}
// 编码检索按钮特殊样式
&.search-btn {
padding: 12rpx 0;
background: #fff;
color: #ff9800;
border: 2rpx solid rgba(255, 152, 0, 0.5);
background: linear-gradient(
to bottom,
rgba(255, 152, 0, 0.05),
rgba(255, 152, 0, 0.1)
);
box-shadow: none;
font-weight: 600;
letter-spacing: 1rpx;
&:active {
background: rgba(255, 152, 0, 0.15);
border-color: rgba(255, 152, 0, 0.6);
transform: translateY(1rpx);
}
}
}
// 编码列表样式
:deep(.uni-row) {
// margin-bottom: 20rpx;
&:last-child {
margin-bottom: 0;
}
.uni-col-6 {
color: #8c8c8c;
font-size: 28rpx;
font-weight: 500;
}
.cont {
color: #262626;
font-size: 28rpx;
font-weight: 500;
line-height: 1.8;
}
}
// 输入框样式
:deep(.uni-easyinput__content) {
background-color: #f7f8fa;
border: 2rpx solid #e8e8e8;
border-radius: 12rpx;
height: 75rpx;
transition: all 0.3s ease;
&:focus-within {
border-color: #3784fb;
box-shadow: 0 0 0 2rpx rgba(55, 132, 251, 0.1);
}
.uni-easyinput__content-input {
font-size: 28rpx;
color: #262626;
}
}
// 复选框样式
:deep(checkbox) {
.wx-checkbox-input {
width: 36rpx;
height: 36rpx;
border-radius: 8rpx;
border: 2rpx solid #e8e8e8;
background: transparent;
&.wx-checkbox-input-checked {
background: #3784fb;
border-color: #3784fb;
&::before {
font-size: 28rpx;
color: #fff;
}
}
&.wx-checkbox-input-disabled {
background: #f5f5f5;
border-color: #e8e8e8;
}
}
}
}
// 底部出库按钮
.outbound-btn {
position: fixed;
bottom: 40rpx;
left: 50%;
transform: translateX(-50%);
width: 90%;
height: 88rpx;
background: linear-gradient(135deg, #4b8eff 0%, #3784fb 100%);
text-align: center;
line-height: 88rpx;
color: #fff;
border-radius: 12rpx;
font-size: 32rpx;
font-weight: 600;
box-shadow: 0 6rpx 20rpx rgba(55, 132, 251, 0.2);
transition: all 0.3s ease;
&:active {
transform: translateX(-50%) scale(0.98);
opacity: 0.9;
}
}
}
// 加载提示文字
.loading-text {
text-align: center;
font-size: 26rpx;
color: #8c8c8c;
padding: 32rpx 0;
letter-spacing: 1rpx;
}
.form-section {
background: #fff;
border-radius: 20rpx;
margin-bottom: 24rpx;
overflow: hidden;
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.06);
// 头部样式
.section-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 24rpx 32rpx;
background: #fff;
cursor: pointer;
transition: all 0.3s ease;
&:active {
background: #f7f8fa;
}
.title {
font-size: 32rpx;
font-weight: 600;
color: #262626;
}
.toggle-icon {
font-size: 40rpx;
color: #8c8c8c;
transform: rotate(90deg);
transition: transform 0.3s ease;
display: inline-block;
&.is-expanded {
transform: rotate(-90deg);
}
}
}
// 表单内容区域
.form-content {
max-height: 0;
overflow: hidden;
transition: max-height 0.3s ease-out;
&.is-expanded {
max-height: 1000rpx; // 根据实际内容调整
}
:deep(.uni-forms) {
padding: 0 32rpx 32rpx;
}
:deep(.uni-forms-item) {
margin-bottom: 24rpx;
&:last-child {
margin-bottom: 0;
}
.uni-forms-item__label {
color: #8c8c8c;
}
.form-view {
color: #262626;
font-size: 28rpx;
}
}
}
}
</style>