<script setup lang="ts"> import { onLoad } from '@dcloudio/uni-app'; import { showToast } from 'vant'; import { ref } from 'vue'; import { getAction, postAction, uploadAction } from '../../common/http'; import { formatDate } from '../../utils/date'; // 定义 props defineProps<{ item ?: string; }>(); const itemList = ref() const processes = ref({} as any) const status = ref('' as any) const indexData = ref() const specialPro = ref([] as any[]) const list = ref([] as any[]) const special = ref('' as any) const trackingLog = ref([] as any[]) const form = ref({ czrq: formatDate(new Date()), yjxybrq: formatDate(new Date()) } as any) onLoad(async (option : any) => { if (option) { try { itemList.value = JSON.parse(option.item) if (itemList.value.sd === '门店' && !itemList.value.processes) { let res : any = await getAction('/flowBind') if (res.code === 200) { let item = res.data.find((l : any) => l.craftName === itemList.value.craft) let item2 = item.flows.find((l : any) => l.bind === "仅现货") if (item2) { let url = '/craftFlows/byName?name=' + item2.name let res1 : any = await getAction(url) if (res1.code === 200) { processes.value = res1.data } else { showToast('暂无此工艺!') } } else { showToast('暂无此工艺!') } } } else { processes.value = itemList.value.processes } indexData.value = processes.value.processes.findIndex((l : any) => l.name == itemList.value.zt) let nameZt = '' if (indexData.value > 0 && !processes.value.processes[indexData.value].id) { nameZt = processes.value.processes[indexData.value - 1].name } else if (indexData.value == 0 && !processes.value.processes[indexData.value].id) { nameZt = '待进厂' } else { nameZt = itemList.value.zt } let name = processes.value.processes.find((l : any, j : any) => j > indexData.value && (l.necessary)) postAction('/process/getNext', [nameZt, name ? name.name : '0x7c00']).then((res : any) => { if (res.code === 200) { specialPro.value = res.data } }) getAction('/tracking/getLog?id=' + itemList.value.id).then((res : any) => { if (res.code === 200) { trackingLog.value = res.data processes.value.processes.forEach((m : any) => { if (!m.id) { let a = res.data.find((l : any) => l.details.zt == m.name) if (a) { m.rq = a.details.form.czrq res.data = res.data.concat(a.details.trackingLog) } } }) processes.value.processes.forEach((m : any) => { let a = res.data.find((l : any) => l.details.zt == m.name) if (a) { m.rq = a.details.form.czrq } }) } }) } catch (error) { console.error('Failed to parse item JSON:', error); // 可以选择在这里显示错误消息给用户 } } }) const onClickLeft = () => { history.back() } //选择框事件 const show = ref(false) const dataType = ref() const chooseDate = (val : any) => { dataType.value = val show.value = true } //日期选择 const onConfirmDate = (val : any) => { form.value[dataType.value] = formatDate(val) show.value = false } const showPicker = ref(false) const popuList = ref([] as any[]) const indexType = ref() //选择框事件 const choosePic = (index : any) => { indexType.value = index showPicker.value = true } //选择框确认 const pickerConfirm = (val : any) => { if (indexType.value === 'craftFlow') { let url = '/craftFlows/byName?name=' + val.selectedValues[0] getAction(url).then((res : any) => { if (res.code === 200) { craftFlowLc.value = JSON.stringify(res.data) craftFlowLc.value.unshift({ name: special.value }) craftFlow.value = val.selectedValues[0] } else { showToast('请重新选择工艺流程!') craftFlow.value = '' } }) } else { list.value[indexType.value].value = val.selectedValues[0] } showPickerCancel() } //取消 const showPickerCancel = () => { showPicker.value = false } //弹窗开启事件 const handleOpen = () => { if (indexType.value === 'craftFlow') { popuList.value = flowList.value let item = {} as any flowList.value.forEach((l : any) => { if (l.craftName === itemList.value.craft) { item = l; } }) popuList.value = [] if (item.flows) { item.flows.forEach((l : any) => { if (itemList.value.sd === '门店' && l.bind === '仅现货') { popuList.value.push({ value: l.name, text: l.name }) } else if (l.bind === '通用') { popuList.value.push({ value: l.name, text: l.name }) } }) } } else { popuList.value = list.value[indexType.value].chooses.map((l : any) => ({ text: l.value, value: l.value })) } } const chooseStatus = (item : any, index : any) => { if (indexData.value >= index) return try { special.value = '' processes.value.processes.forEach((l : any, j : any) => { if (j > indexData.value && index > j) { if (l.necessary) { status.value = l.name throw l.name + '不可跳过!' } } else { status.value = item.name } }) getAction('/process/byName?name=' + status.value).then((res : any) => { if (res.code === 200) { list.value = res.data.evidence } }) } catch (err) { showToast(err) } } const showDialog = ref(false) const contentType = ref([]) const bhList = ref([] as any[]) const czyy = ref() const mls1 = ref([] as any[]) const mls2 = ref([] as any[]) const specialItem = ref() const craftFlow = ref() const craftFlowLc = ref() const flowList = ref([] as any[]) const OrderAlert = ref() //选择特殊工艺 const chooseSpecial = (item : any) => { let a = specialPro.value.find((l : any) => l.name === item.name) list.value = a.evidence if (itemList.value.sd === '门店') { OrderAlert.value = a.internalOrderAlert } else { OrderAlert.value = a.externalOrderAlert } let cs=0 processes.value.processes.forEach((l:any)=>{ if(l.name==item.name){ cs++ } }) if(cs>=Number(OrderAlert.value)) return showToast('已超过系统限制,请联系管理员!') special.value = item.name specialItem.value = item status.value = '' showDialog.value = true getAction('/flowBind').then((res : any) => { if (res.code === 200) { flowList.value = res.data } }) } const addBh = (item : any, itemz : any) => { let index = bhList.value.findIndex((l : any) => l.bh === item.bh && l.ms === item.ms) if (index >= 0) { bhList.value.splice(index, 1) } else { bhList.value.push({ ...item, mz: itemz.mz, sh: itemz.sh }) } } const confirmSecond = () => { mls1.value = [] mls2.value = [] itemList.value.mls.forEach((l : any) => { l.xxs.forEach((j : any) => { let item = bhList.value.find((m : any) => m.mz == l.mz && m.sh == l.sh && m.bh == j.bh && m.ms == j.ms) if (item) { let item1 = mls2.value.find((k : any) => k.mz == item.mz && k.sh == item.sh) if (item1) { item1.xxs.push({ bh: item.bh, index: item.index, ms: item.ms }) } else { mls2.value.push({ mz: item.mz, sh: item.sh, xxs: [{ bh: item.bh, index: item.index, ms: item.ms }] }) } } else { let item1 = mls1.value.find((k : any) => k.mz == l.mz && k.sh == l.sh) if (item1) { item1.xxs.push({ bh: j.bh, index: j.index, ms: j.ms }) } else { mls1.value.push({ mz: l.mz, sh: l.sh, xxs: [{ bh: j.bh, index: j.index, ms: j.ms }] }) } } }) }) if (indexData.value == -1) { if (!processes.value.processes[0].id) { processes.value.processes[0] = { name: special.value, } } else { processes.value.processes.unshift({ name: special.value, }) } } else { if (!processes.value.processes[indexData.value + 1].id) { processes.value.processes[indexData.value + 1] = { name: special.value, } } else { processes.value.processes.splice(indexData.value + 1, 0, { name: special.value, }) } } showDialog.value = false } //提交 const onSubmit = () => { if (!status.value && !special.value) return showToast('请选择工序!') let data = {} if (special.value) { if (mls2.value.length == 0) return showToast(specialItem.value.nextStep + '未选择面料!') data = { trackingLogId: itemList.value.id, subId: itemList.value.subId, details: { trackingLog: trackingLog.value, zt: special.value, list: list.value, form: form.value, type: specialItem.value.nextStep, mls1: mls1.value.length == 0 ? [] : mls1.value, mls2: mls1.value.length == 0 ? [] : mls2.value, craftFlow: craftFlow.value ? craftFlow.value : null, processes: specialItem.value.nextStep == 'ChangeCraft' ? craftFlowLc.value : processes.value, czyy: czyy.value, }, } } else if (status.value) { data = { subId: itemList.value.subId, trackingLogId: itemList.value.id, details: { zt: status.value == processes.value.processes[processes.value.processes.length-1].name ? '待出厂' : status.value, list: list.value, form: form.value, }, } } postAction('/tracking', data).then((res : any) => { if (res.code === 200) { showToast('提交成功!') window.history.back() } }) } const fileList = ref([] as any[]) const afterRead = (file : any) => { file.status = 'uploading'; file.message = '上传中...'; uploadAction('/upload', file.file).then((res : any) => { if (res.code === 200) { file.status = 'success'; file.message = '成功!'; list.value[indexType.value].pic = res.data } }) }; </script> <template> <view class="flex"> <van-nav-bar title="工序详情" left-text="返回" left-arrow @click-left="onClickLeft" /> <view class="content"> <van-cell-group inset> <van-field v-model="itemList.craft" name="工艺名称" label="工艺名称" colon label-width="5em" readonly /> <van-field v-model="itemList.craftCmt.name" name="工艺要求" label="工艺要求" colon label-width="5em" readonly /> <van-field v-model="itemList.innerComment" name="内部备注" label="内部备注" colon label-width="5em" readonly /> <van-field name="工艺流程" label="工艺流程" colon label-width="5em" readonly /> <view class="grid-container"> <view class="grid-item" v-for="(item,index) in processes.processes" :key="index"> <view :class="(indexData>=index)||(status==item.name)?item.id?'btn1':'btn2':'btn'" @click="chooseStatus(item,index)">{{item.name}}</view> <p>{{item.rq}}</p> </view> </view> <van-field name="特殊工序" label="特殊工序" colon label-width="5em" readonly /> <view class="grid-container"> <view class="grid-item" v-for="(item,index) in specialPro" :key="index"> <view :class="special==item.name?'btn1':'btn'" @click="chooseSpecial(item)">{{item.name}}</view> </view> </view> </van-cell-group> <van-form @submit="onSubmit"> <van-cell-group inset> <view v-for="(item,index) in list" :key="index"> <template v-if="item.type==='Select'"> <van-field v-model="item.value" :name="item.name" :label="item.name" colon class="bor" label-width="5em" readonly :rules="item.necessary?[{ required: true, message: '请选择' }]:[]" @click="choosePic(index)" /> </template> <template v-if="item.type==='Input'"> <van-field v-model="item.value" v-if="item.contentType.find(l=>l=='Text')" :name="item.name" :label="item.name" colon class="bor-n" label-width="5em" :rules="item.necessary?[{ required: true, message: '请填写' }]:[]" /> <van-field name="uploader" v-if="item.contentType.find(l=>l=='File')" :label="item.name" label-width="5em" colon :rules="item.necessary?[{ required: true, message: '请上传' }]:[]"> <template #input> <van-uploader v-model="fileList" multiple :max-count="1" :after-read="afterRead" @click="indexType=index" /> </template> </van-field> </template> </view> <van-field v-model="form.czrq" name="操作日期" label="操作日期" colon label-width="5em" :rules="[{ required: true, message: '请填写' }]" readonly class="bor" @click="chooseDate('czrq')" /> <van-field v-model="form.yjxybrq" name="预计下一步日期" label="预计下一步日期" colon label-width="8em" :rules="[{ required: true, message: '请填写' }]" readonly class="bor" @click="chooseDate('yjxybrq')" /> </van-cell-group> <view style="margin: 32rpx;"> <van-button round block type="primary" native-type="submit"> 更新状态 </van-button> </view> </van-form> </view> </view> <van-dialog v-model:show="showDialog" :showConfirmButton="false" width="90vw"> <van-form @submit="confirmSecond"> <van-cell-group inset> <view style="padding: 10rpx 15rpx;"> <van-field name="请选择面料" label="请选择面料" label-width="6em"> <template #input> <van-checkbox-group v-model="contentType" direction="horizontal"> <van-checkbox name="All">全部</van-checkbox> </van-checkbox-group> </template> </van-field> <p style="color: #7f7f7f;">如果无法辨认,请选择米数相近的面料</p> <view class="grid-container1"> <view v-for="(item,index) in itemList.mls" :key="index"> <view class="grid-item" v-for="(itemSecond,indexSecond) in item.xxs" :key="indexSecond"> <view :class="contentType[0]||bhList.find(l=>(l.bh===itemSecond.bh&&l.ms==itemSecond.ms))?'btn1':'btn'" @click="addBh(itemSecond,item)">{{item.mz}}<br>{{itemSecond.ms}}米/{{itemSecond.bh}} </view> </view> </view> </view> <van-field v-if="specialItem.nextStep=='ChangeCraft'" v-model="craftFlow" name="工艺流程" colon label="工艺流程" :rules="specialItem.nextStep=='ChangeCraft'?[{ required: true, message: '请填写' }]:[]" label-width="5em" readonly class="bor" @click="choosePic('craftFlow')" /> <van-field v-model="czyy" name="操作原因" colon label="操作原因" label-width="5em" class="bor-n" /> </view> <view class="footer-button"> <van-button plain size="small" native-type="button" style="width: 25vw;" @click="showDialog=false"> 取消 </van-button> <van-button size="small" type="success" native-type="submit" style="width: 25vw;"> 确认 </van-button> </view> </van-cell-group> </van-form> </van-dialog> <!--选择框--> <van-popup v-model:show="showPicker" round position="bottom" @open="handleOpen"> <van-picker show-toolbar :columns="popuList" @confirm="pickerConfirm" @cancel="showPickerCancel" ref="pickerRef" /> </van-popup> <van-calendar v-model:show="show" @confirm="onConfirmDate" :min-date="new Date(2025, 0, 1)" /> </template> <style lang="scss" scoped> .flex { display: flex; flex-direction: column; height: 100vh; width: 100vw; overflow-y: hidden; .van-nav-bar { width: 100%; } .grid-container { display: grid; grid-template-columns: 1fr 1fr 1fr; padding: 10rpx 15rpx; .grid-item { display: flex; flex-direction: column; text-align: center; align-items: center; margin-top: 10rpx; .btn { border: 1rpx solid #d7d7d7; padding: 10rpx 30rpx; border-radius: 10rpx; } .btn2 { border: 1rpx solid red; padding: 10rpx 30rpx; border-radius: 10rpx; background-color: red; color: #fff; } .btn1 { border: 1rpx solid #169bd5; padding: 10rpx 30rpx; border-radius: 10rpx; background-color: #169bd5; color: #fff; } } } .content { flex: 1; overflow-y: scroll; font-size: 16px; } } .grid-container1 { display: grid; grid-template-columns: 1fr 1fr; padding: 10rpx 15rpx; .grid-item { display: flex; flex-direction: column; text-align: center; align-items: center; justify-content: center; margin-top: 10rpx; .btn { border: 1rpx solid #d7d7d7; padding: 10rpx 30rpx; border-radius: 10rpx; } .btn1 { border: 1rpx solid #169bd5; padding: 10rpx 30rpx; border-radius: 10rpx; background-color: #169bd5; color: #fff; } } } .bor { ::v-deep .van-field__control { border: 1px solid #d7d7d7; text-align: center; } } .bor-n { ::v-deep .van-field__control { border-bottom: 1px solid #d7d7d7; text-align: center; } } ::v-deep .van-cell { padding: 5px !important; } ::v-deep .van-field { font-size: 16px; } ::v-deep .van-field__control { font-size: 16px; } .footer-button { margin: 20px; display: flex; justify-content: space-around; } </style>