<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>
|