| <template> | 
|     <div class="zk"> | 
|         <div class="zk_list"> | 
|             <div class="zk_list_item" @click="open('r')"> | 
|                 <span>转入车间/仓库</span> | 
|                 <div class="zk_list_item_n"> | 
|                     <span :style="data.warehouseName ? 'color: black;' : ''">{{data.warehouseName ? data.warehouseName : '请选择'}}</span> | 
|                     <van-icon name="arrow" color="#999999" size="20" /> | 
|                 </div> | 
|             </div> | 
|             <div class="zk_list_item" @click="open('h')" v-if="isShow"> | 
|                 <span>货位</span> | 
|                 <div class="zk_list_item_n"> | 
|                     <span :style="data.locationName ? 'color: black;' : ''">{{data.locationName ? data.locationName : '请选择'}}</span> | 
|                     <van-icon name="arrow" color="#999999" size="20" /> | 
|                 </div> | 
|             </div> | 
|         </div> | 
|         <div class="zk_title"> | 
|             <div class="zk_title_left"> | 
|                 <div class="zk_title_i"></div> | 
|                 <span>转出工装列表({{list.length}})</span> | 
|             </div> | 
|             <div class="zk_title_right"> | 
|                 <span>总计:{{total}}</span> | 
|             </div> | 
|         </div> | 
|         <div class="zk_wl"> | 
|             <template v-if="list.length > 0"> | 
|                 <van-swipe-cell v-for="(item, i) in list" :key="i"> | 
|                     <div class="zk_wl_item"> | 
|                         <span>{{item.code}} {{item.num}}{{item.umodelName}}</span> | 
|                         <span>物料信息:{{item.mmodelName}} | {{item.mmodelCode}}</span> | 
|                         <span>批次号:{{item.batch}}</span> | 
|                         <span>生产工序:{{item.pmodelName}}</span> | 
|                     </div> | 
|                     <template #right> | 
|                         <van-button square type="danger" style="height: 100%;" text="删除" @click="dele(i)" /> | 
|                     </template> | 
|                 </van-swipe-cell> | 
|             </template> | 
|             <div class="zk_wl_w" v-else> | 
|                 <span>暂无数据</span> | 
|             </div> | 
|         </div> | 
|         <div class="zk_z"></div> | 
|         <div class="zk_footer"> | 
|             <div class="zk_footer_wl" @click="open('code')">继续扫码</div> | 
|             <div style="width: 20px"></div> | 
|             <div class="zk_footer_submit" @click="submit">提交</div> | 
|         </div> | 
|     </div> | 
|     <!--  货位  --> | 
|     <van-popup v-model:show="view.type" position="bottom" round :style="{ height: '50%' }"> | 
|         <van-picker | 
|             title="请选择货位" | 
|             :columns="locationData" | 
|             @confirm="onConfirm" | 
|             @cancel="onCancel" | 
|             :columns-field-names="customFieldName" | 
|         /> | 
|     </van-popup> | 
|     <!--  选择仓库  --> | 
|     <Warehouse :show="view.Warehouse" @close="view.Warehouse = false" @value="getValue" /> | 
|     <!--  扫码  --> | 
|     <v-ScanCode :openCode="openCodea" :infos="['请扫描工装码']" @closePopup="closePopupa" @onDecode="onDecodea" /> | 
| </template> | 
|   | 
| <script setup lang="ts"> | 
|     import { reactive, ref, onMounted, watch } from 'vue' | 
|     import { Toast } from 'vant' | 
|     import { useRouter, useRoute } from "vue-router" | 
|     import { getListByCondition, getListByWarehouseId, getBarcodeContent, scanTransfer } from '@/apis/WorkOrderAPI' | 
|     import { QRCodeType, Attribute } from "@/enum" | 
|     import Warehouse from '@/components/common/Warehouse.vue' | 
|   | 
|     const router = useRouter() | 
|     const route = useRoute() | 
|   | 
|     const openCodea = ref<boolean>(false)  // 控制扫码显示隐藏 | 
|     let list: any = ref([])  // 转出工装列表 | 
|     let locationData: any = ref([])  // 货位数据 | 
|     let isShow = ref(false) // 控制货位选择显示隐藏 | 
|     let total = ref(0)  // 总计数量 | 
|     let customFieldName = {  // 自定义下拉选项显示文字 | 
|         text: 'area' | 
|     } | 
|   | 
|     let data = reactive({ | 
|         type: '', | 
|   | 
|         warehouseName: '', | 
|         warehouseId: '', | 
|         locationName: '', | 
|         locationId: '' | 
|     }) | 
|   | 
|     let view = reactive({ | 
|         type: false, | 
|         Warehouse: false | 
|     }) | 
|   | 
|     // 创建转库单 | 
|     const submit = () => { | 
|         if (!data.warehouseId) return Toast.fail({ message: '入库车间/仓库不能为空' }) | 
|         if (isShow.value && !data.locationId) return Toast.fail({ message: '货位不能为空' }) | 
|         let idList = list.value.map((item: any) => { | 
|             return item.id | 
|         }) | 
|         scanTransfer({ | 
|             idList, | 
|             inLocationId: data.locationId, | 
|             inWarehouseId: data.warehouseId, | 
|             outWarehouseId: list.value[0].warehouseId | 
|         }).then(res => { | 
|             if (res.code === 200) { | 
|                 Toast.success({ message: '转库成功', duration: 2000, forbidClick: true }) | 
|                 setTimeout(() => { | 
|                     router.go(-1) | 
|                 }, 2000) | 
|             } | 
|         }) | 
|     } | 
|   | 
|     // 扫码回调 | 
|     const onDecodea = async (datav: string[]): Promise<void> => { | 
|         getBarcodeContent({ | 
|             barcode: datav[0] | 
|         }).then(res => { | 
|             if (res.code === 200) { | 
|                 if (res.data.barcodeType === QRCodeType.GZ) {   // 判断是否是工装码 | 
|                     getListByCondition({ id: res.data.id }) | 
|                         .then(res => { | 
|                             if (res.code === 200) { | 
|                                 if (res.data && res.data.length > 0) {    // 判断是否查询到工装 | 
|                                     let next: boolean = true | 
|                                     list.value.forEach((element: any) => {  // 判断是否有重复的工装 | 
|                                         if (element.id === res.data[0].id) { | 
|                                             next = false | 
|                                         } | 
|                                     }) | 
|                                     if (!next) { | 
|                                         Toast.fail({ message: '不能重复添加相同的工装' }) | 
|                                         return | 
|                                     } | 
|                                     if (res.data[0].status !== 1) {    // 判断工装是否为空 | 
|                                         if (res.data[0].warehouseId) {  // 判断工装是否在仓库下 | 
|                                             if (res.data[0].warehouseId === list.value[0].warehouseId) {    // 判断仓库是否一致 | 
|                                                 if (res.data[0].smodelLabel === list.value[0].smodelLabel) {    // 属性是否一致 | 
|                                                     if (res.data[0].locationId !== data.locationId) { | 
|                                                         list.value.push(res.data[0]) | 
|                                                     } else { | 
|                                                         Toast.fail({ message: '货位不能一致', duration: 2000 }) | 
|                                                     } | 
|                                                 } else { | 
|                                                     Toast.fail({ message: '属性不一致', duration: 2000 }) | 
|                                                 } | 
|                                             } else { | 
|                                                 Toast.fail({ message: '工装仓库不一致', duration: 2000 }) | 
|                                             } | 
|                                         } else { | 
|                                             Toast.fail({ message: '该工装不在仓库', duration: 2000 }) | 
|                                         } | 
|                                     } else { | 
|                                         Toast.fail({ message: '该工装状态为空', duration: 2000 }) | 
|                                     } | 
|                                 } else { | 
|                                     Toast.fail({ message: '未查询到工装', duration: 2000 }) | 
|                                 } | 
|                             } | 
|                         }) | 
|                 } else { | 
|                     Toast.fail({ message: '请扫描正确的工装码', duration: 2000 }) | 
|                 } | 
|             } | 
|         }).finally(() => { | 
|             openCodea.value = false | 
|         }) | 
|     } | 
|   | 
|     // 关闭扫码组件 | 
|     const closePopupa = (): void => { | 
|         openCodea.value = false | 
|     } | 
|   | 
|     // 删除物料 | 
|     const dele = (i: number): void => { | 
|         if (list.value.length === 1) { | 
|             Toast.fail({ message: '至少保留一项工装' }) | 
|             return | 
|         } | 
|         list.value.splice(i, 1) | 
|     } | 
|   | 
|     // 仓库回调 | 
|     const getValue = async (val: any): Promise<void> => { | 
|         if (val.id === list.value[0].warehouseId) { | 
|             data.warehouseId = val.id; | 
|             data.warehouseName = val.name; | 
|             if (val.useLocation === 1) { | 
|                 await getLocation(val.id) | 
|                 isShow.value = true | 
|             } else { | 
|                 isShow.value = false | 
|             } | 
|         } else { | 
|             locationData.value = [] | 
|             data.locationName = '' | 
|             data.locationId = '' | 
|             if (list.value[0].smodelLabel === Attribute.HH || val.tmodel.label === Attribute.HH) {   // 混合 可以选择任意仓库 | 
|                 data.warehouseId = val.id; | 
|                 data.warehouseName = val.name; | 
|             } else if (list.value[0].smodelLabel === val.tmodel.label) {    // 判断属性是否一致 | 
|                 data.warehouseId = val.id; | 
|                 data.warehouseName = val.name; | 
|             } else { | 
|                 Toast.fail({ message: '工装的质量属性和仓库属性不相符' }) | 
|             } | 
|             isShow.value = false | 
|         } | 
|         view.Warehouse = false; | 
|     } | 
|   | 
|     // 打开选择弹框 | 
|     const open = (type: string): void => { | 
|         if (type === 'r') { | 
|             view.Warehouse = true | 
|         } else if (type === 'h') { | 
|             view.type = true | 
|         } else if (type === 'code') { | 
|             if (!data.warehouseId) { | 
|                 Toast.fail({ message: '仓库不能为空' }) | 
|                 return | 
|             } | 
|             if (isShow.value && !data.locationId) { | 
|                 Toast.fail({ message: '货位不能为空' }) | 
|                 return | 
|             } | 
|             openCodea.value = true | 
|         } | 
|     } | 
|   | 
|     // 确认货位 | 
|     const onConfirm = (val: any): void => { | 
|         if (list.value[0].smodelLabel === Attribute.HH || val.label === Attribute.HH) {   // 混合 可以选择任意仓库 | 
|             if (list.value[0].locationId === val.id) { | 
|                 Toast.fail({ message: '货位不能一致' }) | 
|                 return | 
|             } | 
|             data.locationId = val.id | 
|             data.locationName = val.area | 
|         } else if (list.value[0].smodelLabel === val.label) {    // 判断属性是否一致 | 
|             if (list.value[0].locationId === val.id) { | 
|                 Toast.fail({ message: '货位不能一致' }) | 
|                 return | 
|             } | 
|             data.locationId = val.id | 
|             data.locationName = val.area | 
|         } else { | 
|             Toast.fail({ message: '工装和货位属性不一致' }) | 
|         } | 
|         view.type = false | 
|     } | 
|   | 
|     // 关闭货位弹框 | 
|     const onCancel = (): void => { | 
|         view.type = false | 
|     } | 
|   | 
|     // 获取工装信息 | 
|     const getGZInfo = (id: string): void => { | 
|         getListByCondition({ id }) | 
|             .then(res => { | 
|                 if (res.code === 200 && res.data.length > 0) { | 
|                     list.value.push(res.data[0] as never) | 
|                 } | 
|             }) | 
|     } | 
|   | 
|     // 根据仓库获取货位信息 | 
|     const getLocation = (id: string): void => { | 
|         getListByWarehouseId({ | 
|             wareHouseId: id | 
|         }).then(res => { | 
|             if (res.code === 200) { | 
|                 if (res.data && res.data.length > 0) { | 
|                     locationData.value = res.data | 
|                 } | 
|             } | 
|         }) | 
|     } | 
|   | 
|     // 监听工装数组,计算总数 | 
|     watch(() => list.value, () => { | 
|         if (list.value.length > 0) { | 
|             total.value = 0 | 
|             list.value.forEach((element: any) => { | 
|                 total.value = total.value + element.num | 
|             }) | 
|         } | 
|     }, { deep: true, immediate: true }) | 
|   | 
|     onMounted(() => { | 
|         getGZInfo(route.query.id as string) | 
|     }) | 
| </script> | 
|   | 
| <style lang="scss" scoped> | 
|     .zk { | 
|         position: absolute; | 
|         width: 100%; | 
|         .zk_list { | 
|             padding: 0 30px; | 
|             background: white; | 
|             margin-top: 20px; | 
|             .zk_list_item { | 
|                 height: 98px; | 
|                 display: flex; | 
|                 align-items: center; | 
|                 justify-content: space-between; | 
|                 border-bottom: 1PX solid #E5E5E5; | 
|                 &:last-child { | 
|                     border: none !important; | 
|                 } | 
|                 span { | 
|                     font-size: 30px; | 
|                     font-weight: 400; | 
|                     color: #222222; | 
|                 } | 
|                 .zk_list_item_n { | 
|                     display: flex; | 
|                     align-items: center; | 
|                     span { | 
|                         font-size: 28px; | 
|                         font-weight: 400; | 
|                         color: #999999; | 
|                         margin-right: 10px; | 
|                     } | 
|                 } | 
|             } | 
|         } | 
|         .zk_title { | 
|             padding: 40px 30px 30px 30px; | 
|             display: flex; | 
|             align-items: center; | 
|             justify-content: space-between; | 
|             .zk_title_left { | 
|                 display: flex; | 
|                 align-items: center; | 
|                 .zk_title_i { | 
|                     width: 8px; | 
|                     height: 30px; | 
|                     background: #4275FC; | 
|                     border-radius: 2px; | 
|                     margin-right: 12px; | 
|                 } | 
|                 span { | 
|                     font-size: 32px; | 
|                     font-weight: 500; | 
|                     color: #222222; | 
|                 } | 
|             } | 
|             .zk_title_right { | 
|                 span { | 
|                     font-size: 28px; | 
|                     color: $nav-color; | 
|                 } | 
|             } | 
|         } | 
|         .zk_wl { | 
|             background: white; | 
|             .zk_wl_w { | 
|                 width: 100%; | 
|                 height: 200px; | 
|                 background: white; | 
|                 display: flex; | 
|                 align-items: center; | 
|                 justify-content: center; | 
|                 font-size: 26px; | 
|                 color: black; | 
|             } | 
|             .zk_wl_item { | 
|                 display: flex; | 
|                 flex-direction: column; | 
|                 padding: 30px; | 
|                 border-bottom: 1PX solid #e2e2e2; | 
|                 span { | 
|                     font-size: 26px; | 
|                     font-weight: 500; | 
|                     color: #3d3d3d; | 
|                     margin-bottom: 24px; | 
|                     &:first-child { | 
|                         color: #000000; | 
|                         font-size: 30px; | 
|                     } | 
|                     &:last-child { | 
|                         margin-bottom: 0; | 
|                         border-bottom: 1PX solid #ffffff; | 
|                     } | 
|                 } | 
|             } | 
|         } | 
|         .zk_z { | 
|             height: 168px; | 
|         } | 
|         .zk_footer { | 
|             width: 100%; | 
|             box-sizing: border-box; | 
|             padding: 0 30px; | 
|             position: fixed; | 
|             bottom: 0; | 
|             left: 0; | 
|             padding-bottom: 68px; | 
|             display: flex; | 
|             align-items: center; | 
|             justify-content: space-between; | 
|             .zk_footer_wl { | 
|                 flex: 1; | 
|                 height: 88px; | 
|                 background: #FFFFFF; | 
|                 box-shadow: 0 0 12px 0 rgba(0,0,0,0.08); | 
|                 border-radius: 8px; | 
|                 display: flex; | 
|                 align-items: center; | 
|                 justify-content: center; | 
|                 font-size: 30px; | 
|                 font-weight: 500; | 
|                 color: $nav-color; | 
|             } | 
|             .zk_footer_submit { | 
|                 flex: 1; | 
|                 height: 88px; | 
|                 background: $nav-color; | 
|                 box-shadow: 0 0 12px 0 rgba(0,0,0,0.08); | 
|                 border-radius: 8px; | 
|                 display: flex; | 
|                 align-items: center; | 
|                 justify-content: center; | 
|                 font-size: 30px; | 
|                 font-weight: 500; | 
|                 color: #FFFFFF; | 
|             } | 
|         } | 
|     } | 
| </style> |