Commit 4f015bcc4e585b39d806ffdcd92ffd7d93cf32df

Authored by gesilong
1 parent 1e1cd31d

commit:联调审批

... ... @@ -69,6 +69,11 @@
69 69 <view v-if="!planList.length" class="empty-tip">选择计划后自动带出</view>
70 70 <view v-for="(item, idx) in planList" :key="'p-' + (item.id || idx)" class="block">
71 71 <uni-list>
  72 + <uni-list-item title="计划编号">
  73 + <template v-slot:footer>
  74 + <uni-easyinput :value="item.planCode" :inputBorder="false" disabled />
  75 + </template>
  76 + </uni-list-item>
72 77 <uni-list-item title="计划品种">
73 78 <template v-slot:footer>
74 79 <uni-easyinput :value="item.productName" :inputBorder="false" disabled />
... ... @@ -79,11 +84,6 @@
79 84 <uni-easyinput :value="item.quantity" :inputBorder="false" disabled />
80 85 </template>
81 86 </uni-list-item>
82   - <uni-list-item title="计划编号">
83   - <template v-slot:footer>
84   - <uni-easyinput :value="item.planCode" :inputBorder="false" disabled />
85   - </template>
86   - </uni-list-item>
87 87 </uni-list>
88 88 </view>
89 89 </view>
... ... @@ -102,12 +102,25 @@
102 102 <view v-if="!weighList.length" class="empty-tip">暂无明细,请添加</view>
103 103 <view v-for="(item, idx) in weighList" :key="'w-' + (item.id || idx)" class="block">
104 104 <uni-list>
  105 + <uni-list-item class="select-item" :class="item.planCode ? 'is-filled' : 'is-empty'">
  106 + <template v-slot:body>
  107 + <view class="item-title"><text class="required">*</text><text>计划编号</text></view>
  108 + </template>
  109 + <template v-slot:footer>
  110 + <picker mode="selector" :range="planCodeLabels"
  111 + @change="(e) => handleWeighPlanChange(idx, Number(e.detail.value))">
  112 + <view class="picker-value" :class="{ placeholder: !item.planCode }">
  113 + {{ item.planCode || '请选择计划编号' }}
  114 + </view>
  115 + </picker>
  116 + </template>
  117 + </uni-list-item>
105 118 <uni-list-item class="select-item" :class="item.productId ? 'is-filled' : 'is-empty'">
106 119 <template v-slot:body>
107 120 <view class="item-title"><text class="required">*</text><text>过磅品种</text></view>
108 121 </template>
109 122 <template v-slot:footer>
110   - <picker mode="selector" :range="weightProductLabels"
  123 + <picker mode="selector" :range="getWeightProductLabels(item)"
111 124 @change="(e) => handleWeightProductChange(idx, Number(e.detail.value))">
112 125 <view class="picker-value" :class="{ placeholder: !item.productId }">
113 126 {{ getWeightProductLabel(item) || '请选择过磅品种' }}
... ... @@ -128,11 +141,6 @@
128 141 <uni-easyinput v-model="item.quantity" type="digit" :inputBorder="false" placeholder="请输入过磅数量" />
129 142 </template>
130 143 </uni-list-item>
131   - <uni-list-item title="计划编号">
132   - <template v-slot:footer>
133   - <uni-easyinput v-model="item.planCode" :inputBorder="false" disabled />
134   - </template>
135   - </uni-list-item>
136 144 </uni-list>
137 145 <view class="block-ops">
138 146 <div class="del" @click="removeRow('weigh', idx)">
... ... @@ -372,11 +380,20 @@ export default {
372 380 const first = (this.selectedPlanRows || [])[0]
373 381 return !!(first && first.buyout)
374 382 },
375   - // 过磅品种下拉:数据来自计划单明细
376   - weightProductLabels() {
377   - return (this.planList || []).map(item =>
378   - [item.productName, item.planCode].filter(Boolean).join(' ')
379   - )
  383 + // 过磅明细-计划编号下拉选项(范围=基础信息已选计划)
  384 + planCodeOptions() {
  385 + const seen = new Set()
  386 + const opts = []
  387 + ;(this.selectedPlanRows || []).forEach(it => {
  388 + const code = it.code || ''
  389 + if (!code || seen.has(code)) return
  390 + seen.add(code)
  391 + opts.push({ code: code, planId: it.id })
  392 + })
  393 + return opts
  394 + },
  395 + planCodeLabels() {
  396 + return this.planCodeOptions.map(o => o.code)
380 397 },
381 398 varietyLabels() {
382 399 return (this.varietyOptions || []).map(item =>
... ... @@ -535,17 +552,40 @@ export default {
535 552 this.weighList = []
536 553 })
537 554 },
  555 + // 过磅明细-计划编号变更:更新行计划编号/计划id,并清空品种选择
  556 + handleWeighPlanChange(idx, optIdx) {
  557 + const opt = (this.planCodeOptions || [])[optIdx]
  558 + if (!opt) return
  559 + const row = this.weighList[idx]
  560 + row.planCode = opt.code
  561 + row.procurementPlanId = opt.planId || ''
  562 + row.productId = ''
  563 + row.productName = ''
  564 + row.invoiceProductName = ''
  565 + },
  566 + // 当前计划编号下的品种选项
  567 + getWeightProductLabels(item) {
  568 + return (this.planList || [])
  569 + .filter(it => it.planCode === item.planCode)
  570 + .map(it => it.productName || '')
  571 + },
538 572 getWeightProductLabel(item) {
539 573 if (!item.productId) return ''
540   - const found = (this.planList || []).find(it => it.productId === item.productId)
541   - return found ? [found.productName, found.planCode].filter(Boolean).join(' ') : ''
  574 + const found = (this.planList || []).find(it => it.productId === item.productId && it.planCode === item.planCode)
  575 + return found ? (found.productName || '') : ''
542 576 },
543   - // 过磅品种改选:整行替换为选中计划明细数据
  577 + // 过磅品种改选:整行替换为对应计划明细数据(保留行id与计划编号)
544 578 handleWeightProductChange(idx, optIdx) {
545   - const raw = (this.planList || [])[optIdx]
  579 + const row = this.weighList[idx]
  580 + const options = (this.planList || []).filter(it => it.planCode === row.planCode)
  581 + const raw = options[optIdx]
546 582 if (!raw) return
547   - const rowId = this.weighList[idx].id
548   - this.weighList.splice(idx, 1, { ...raw, id: rowId })
  583 + this.weighList.splice(idx, 1, {
  584 + ...raw,
  585 + id: row.id,
  586 + planCode: row.planCode || raw.planCode || '',
  587 + procurementPlanId: row.procurementPlanId || raw.procurementPlanId || ''
  588 + })
549 589 },
550 590 getVarietyLabel(item) {
551 591 if (!item.breedRelationshipId) return ''
... ... @@ -592,10 +632,11 @@ export default {
592 632 if (!f.supplierStockMaterial) return this.tip('请输入供应存欠料')
593 633 if (!f.logisticsStockMaterial) return this.tip('请输入物流存欠料')
594 634 if (!f.plateNumber) return this.tip('请输入车牌号')
595   - // 过磅明细:品种、数量必填
  635 + // 过磅明细:计划编号、品种、数量必填
596 636 const weightList = this.weighList || []
597 637 for (let i = 0; i < weightList.length; i++) {
598 638 const row = weightList[i]
  639 + if (!row.planCode) return this.tip(`过磅明细第${i + 1}行:请选择计划编号`)
599 640 if (!row.productId) return this.tip(`过磅明细第${i + 1}行:请选择过磅品种`)
600 641 if (row.quantity === '' || row.quantity == null) return this.tip(`过磅明细第${i + 1}行:请输入过磅数量`)
601 642 }
... ...
... ... @@ -27,9 +27,9 @@
27 27 <view v-if="!planList.length" class="empty-tip">暂无明细</view>
28 28 <view v-for="(item, idx) in planList" :key="'p-' + (item.id || idx)" class="card">
29 29 <view class="card-index">第 {{ idx + 1 }} 行</view>
  30 + <view class="row"><text class="label">计划编号</text><text class="value">{{ safeText(item.planCode) }}</text></view>
30 31 <view class="row"><text class="label">计划品种</text><text class="value">{{ safeText(item.productName) }}</text></view>
31 32 <view class="row"><text class="label">计划数量</text><text class="value">{{ formatNumber(item.quantity) }}</text></view>
32   - <view class="row"><text class="label">计划编号</text><text class="value">{{ safeText(item.planCode) }}</text></view>
33 33 </view>
34 34 </view>
35 35 </view>
... ... @@ -48,10 +48,10 @@
48 48 <view v-if="!weighList.length" class="empty-tip">暂无明细</view>
49 49 <view v-for="(item, idx) in weighList" :key="'w-' + (item.id || idx)" class="card">
50 50 <view class="card-index">第 {{ idx + 1 }} 行</view>
  51 + <view class="row"><text class="label">计划编号</text><text class="value">{{ safeText(item.planCode) }}</text></view>
51 52 <view class="row"><text class="label">过磅品种</text><text class="value">{{ safeText(item.productName) }}</text></view>
52 53 <view class="row"><text class="label">开票品名</text><text class="value">{{ safeText(item.invoiceProductName) }}</text></view>
53 54 <view class="row"><text class="label">过磅数量</text><text class="value">{{ formatNumber(item.quantity) }}</text></view>
54   - <view class="row"><text class="label">计划编号</text><text class="value">{{ safeText(item.planCode) }}</text></view>
55 55 </view>
56 56 </view>
57 57 </view>
... ... @@ -152,10 +152,12 @@ export default {
152 152 buttons: [
153 153 { text: '修改', visible: true, variant: 'outline', event: 'edit' },
154 154 { text: '提交审核', visible: true, variant: 'outline', event: 'submitAudit' },
  155 + { text: '审核', visible: true, variant: 'primary', event: 'audit' },
  156 + { text: '审核详情', visible: true, variant: 'outline', event: 'auditDetail' },
155 157 { text: '作废', visible: true, variant: 'outline', event: 'cancel' },
156 158 { text: '上传签字凭证', visible: true, variant: 'outline', event: 'uploadSign' },
157 159 { text: '上传延期说明', visible: true, variant: 'outline', event: 'uploadDelay' },
158   - { text: '复磅', visible: true, variant: 'primary', event: 'reweigh' }
  160 + { text: '复磅', visible: true, variant: 'outline', event: 'reweigh' }
159 161 ]
160 162 }
161 163 },
... ... @@ -181,6 +183,9 @@ export default {
181 183 const status = this.form.approvalStatus || ''
182 184 const isMine = this.form.createById === this.currentUserId
183 185 const isPass = status === 'PASS'
  186 + const isAudit = status === 'AUDIT'
  187 + const showExamine = this.form.showExamine === true
  188 + const showExamineDetail = this.form.showExamineDetail === true
184 189 return [
185 190 {
186 191 ...this.buttons[0],
... ... @@ -192,18 +197,26 @@ export default {
192 197 },
193 198 {
194 199 ...this.buttons[2],
195   - visible: isPass && this.$auth.hasPermi('warehouse-manage:weight-ticket:cancel')
  200 + visible: isAudit && showExamine && this.$auth.hasPermi('warehouse-manage:weight-ticket:approve')
196 201 },
197 202 {
198 203 ...this.buttons[3],
199   - visible: isPass && this.$auth.hasPermi('warehouse-manage:weight-ticket:uploadSigned')
  204 + visible: (isAudit || isPass) && showExamineDetail && this.$auth.hasPermi('warehouse-manage:weight-ticket:review')
200 205 },
201 206 {
202 207 ...this.buttons[4],
203   - visible: isPass && this.$auth.hasPermi('warehouse-manage:weight-ticket:uploadExtension')
  208 + visible: isPass && this.$auth.hasPermi('warehouse-manage:weight-ticket:cancel')
204 209 },
205 210 {
206 211 ...this.buttons[5],
  212 + visible: isPass && this.$auth.hasPermi('warehouse-manage:weight-ticket:uploadSigned')
  213 + },
  214 + {
  215 + ...this.buttons[6],
  216 + visible: isPass && this.$auth.hasPermi('warehouse-manage:weight-ticket:uploadExtension')
  217 + },
  218 + {
  219 + ...this.buttons[7],
207 220 visible: isPass && this.$auth.hasPermi('warehouse-manage:weight-ticket:reweigh')
208 221 }
209 222 ]
... ... @@ -271,6 +284,8 @@ export default {
271 284 const e = btn.event || ''
272 285 if (e === 'edit') return this.onEdit()
273 286 if (e === 'submitAudit') return this.onSubmitAudit()
  287 + if (e === 'audit') return this.onAudit()
  288 + if (e === 'auditDetail') return this.onAuditDetail()
274 289 if (e === 'cancel') return this.onCancel()
275 290 if (e === 'uploadSign') return this.onUpload('sign')
276 291 if (e === 'uploadDelay') return this.onUpload('delay')
... ... @@ -279,6 +294,20 @@ export default {
279 294 onEdit() {
280 295 uni.navigateTo({ url: '/pages/weight-ticket/modify?id=' + this.id })
281 296 },
  297 + onAudit() {
  298 + const id = this.id || (this.form && this.form.id) || ''
  299 + if (!id) return
  300 + uni.setStorageSync('contractType', 'WEIGHING_RECORD')
  301 + uni.setStorageSync('sourceBusinessId', id)
  302 + uni.navigateTo({ url: '/pages/flow/audit' })
  303 + },
  304 + onAuditDetail() {
  305 + const id = this.id || (this.form && this.form.id) || ''
  306 + if (!id) return
  307 + uni.setStorageSync('contractType', 'WEIGHING_RECORD')
  308 + uni.setStorageSync('sourceBusinessId', id)
  309 + uni.navigateTo({ url: '/pages/flow/audit_detail' })
  310 + },
282 311 onUpload(mode) {
283 312 uni.navigateTo({ url: '/pages/weight-ticket/upload?id=' + this.id + '&mode=' + mode })
284 313 },
... ...
... ... @@ -99,12 +99,25 @@
99 99 <view v-if="!weighList.length" class="empty-tip">暂无明细,请添加</view>
100 100 <view v-for="(item, idx) in weighList" :key="'w-' + (item.id || idx)" class="block">
101 101 <uni-list>
  102 + <uni-list-item class="select-item" :class="item.planCode ? 'is-filled' : 'is-empty'">
  103 + <template v-slot:body>
  104 + <view class="item-title"><text class="required">*</text><text>计划编号</text></view>
  105 + </template>
  106 + <template v-slot:footer>
  107 + <picker mode="selector" :range="planCodeLabels"
  108 + @change="(e) => handleWeighPlanChange(idx, Number(e.detail.value))">
  109 + <view class="picker-value" :class="{ placeholder: !item.planCode }">
  110 + {{ item.planCode || '请选择计划编号' }}
  111 + </view>
  112 + </picker>
  113 + </template>
  114 + </uni-list-item>
102 115 <uni-list-item class="select-item" :class="item.productId ? 'is-filled' : 'is-empty'">
103 116 <template v-slot:body>
104 117 <view class="item-title"><text class="required">*</text><text>过磅品种</text></view>
105 118 </template>
106 119 <template v-slot:footer>
107   - <picker mode="selector" :range="weightProductLabels"
  120 + <picker mode="selector" :range="getWeightProductLabels(item)"
108 121 @change="(e) => handleWeightProductChange(idx, Number(e.detail.value))">
109 122 <view class="picker-value" :class="{ placeholder: !item.productId }">
110 123 {{ getWeightProductLabel(item) || '请选择过磅品种' }}
... ... @@ -125,11 +138,6 @@
125 138 <uni-easyinput v-model="item.quantity" type="digit" :inputBorder="false" placeholder="请输入过磅数量" />
126 139 </template>
127 140 </uni-list-item>
128   - <uni-list-item title="计划编号">
129   - <template v-slot:footer>
130   - <uni-easyinput v-model="item.planCode" :inputBorder="false" disabled />
131   - </template>
132   - </uni-list-item>
133 141 </uni-list>
134 142 <view class="block-ops">
135 143 <div class="del" @click="removeRow('weigh', idx)">
... ... @@ -370,11 +378,20 @@ export default {
370 378 const first = (this.selectedPlanRows || [])[0]
371 379 return !!(first && first.buyout)
372 380 },
373   - // 过磅品种下拉:数据来自计划单明细
374   - weightProductLabels() {
375   - return (this.planList || []).map(item =>
376   - [item.productName, item.planCode].filter(Boolean).join(' ')
377   - )
  381 + // 过磅明细-计划编号下拉选项(范围=基础信息已选计划)
  382 + planCodeOptions() {
  383 + const seen = new Set()
  384 + const opts = []
  385 + ;(this.selectedPlanRows || []).forEach(it => {
  386 + const code = it.code || ''
  387 + if (!code || seen.has(code)) return
  388 + seen.add(code)
  389 + opts.push({ code: code, planId: it.id })
  390 + })
  391 + return opts
  392 + },
  393 + planCodeLabels() {
  394 + return this.planCodeOptions.map(o => o.code)
378 395 },
379 396 varietyLabels() {
380 397 return (this.varietyOptions || []).map(item =>
... ... @@ -467,10 +484,13 @@ export default {
467 484 .then(res => {
468 485 const data = res && res.data ? (res.data.data || res.data) : {}
469 486 const buyout = !!data.buyout
  487 + // 计划编号:详情接口可能返回数组(如 ["260900006","260900006_03"]),统一转逗号拼接字符串
  488 + const planCodeRaw = data.planCode || data.planCodes || ''
  489 + const planCodeText = Array.isArray(planCodeRaw) ? planCodeRaw.filter(Boolean).join(',') : String(planCodeRaw || '')
470 490 this.form = {
471 491 code: data.code || '',
472 492 type: data.type != null ? String(data.type) : '',
473   - planCode: data.planCode || data.planCodes || '',
  493 + planCode: planCodeText,
474 494 unit: data.unit || '',
475 495 supplierName: data.supplierName || '',
476 496 companyShortName: data.companyShortName || '',
... ... @@ -569,17 +589,40 @@ export default {
569 589 this.weighList = []
570 590 })
571 591 },
  592 + // 过磅明细-计划编号变更:更新行计划编号/计划id,并清空品种选择
  593 + handleWeighPlanChange(idx, optIdx) {
  594 + const opt = (this.planCodeOptions || [])[optIdx]
  595 + if (!opt) return
  596 + const row = this.weighList[idx]
  597 + row.planCode = opt.code
  598 + row.procurementPlanId = opt.planId || ''
  599 + row.productId = ''
  600 + row.productName = ''
  601 + row.invoiceProductName = ''
  602 + },
  603 + // 当前计划编号下的品种选项
  604 + getWeightProductLabels(item) {
  605 + return (this.planList || [])
  606 + .filter(it => it.planCode === item.planCode)
  607 + .map(it => it.productName || '')
  608 + },
572 609 getWeightProductLabel(item) {
573 610 if (!item.productId) return ''
574   - const found = (this.planList || []).find(it => it.productId === item.productId)
575   - return found ? [found.productName, found.planCode].filter(Boolean).join(' ') : ''
  611 + const found = (this.planList || []).find(it => it.productId === item.productId && it.planCode === item.planCode)
  612 + return found ? (found.productName || '') : ''
576 613 },
577   - // 过磅品种改选:整行替换为选中计划明细数据
  614 + // 过磅品种改选:整行替换为对应计划明细数据(保留行id与计划编号)
578 615 handleWeightProductChange(idx, optIdx) {
579   - const raw = (this.planList || [])[optIdx]
  616 + const row = this.weighList[idx]
  617 + const options = (this.planList || []).filter(it => it.planCode === row.planCode)
  618 + const raw = options[optIdx]
580 619 if (!raw) return
581   - const rowId = this.weighList[idx].id
582   - this.weighList.splice(idx, 1, { ...raw, id: rowId })
  620 + this.weighList.splice(idx, 1, {
  621 + ...raw,
  622 + id: row.id,
  623 + planCode: row.planCode || raw.planCode || '',
  624 + procurementPlanId: row.procurementPlanId || raw.procurementPlanId || ''
  625 + })
583 626 },
584 627 getVarietyLabel(item) {
585 628 if (!item.breedRelationshipId) return ''
... ... @@ -626,10 +669,11 @@ export default {
626 669 if (!f.supplierStockMaterial) return this.tip('请输入供应存欠料')
627 670 if (!f.logisticsStockMaterial) return this.tip('请输入物流存欠料')
628 671 if (!f.plateNumber) return this.tip('请输入车牌号')
629   - // 过磅明细:品种、数量必填
  672 + // 过磅明细:计划编号、品种、数量必填
630 673 const weightList = this.weighList || []
631 674 for (let i = 0; i < weightList.length; i++) {
632 675 const row = weightList[i]
  676 + if (!row.planCode) return this.tip(`过磅明细第${i + 1}行:请选择计划编号`)
633 677 if (!row.productId) return this.tip(`过磅明细第${i + 1}行:请选择过磅品种`)
634 678 if (row.quantity === '' || row.quantity == null) return this.tip(`过磅明细第${i + 1}行:请输入过磅数量`)
635 679 }
... ...
... ... @@ -58,6 +58,11 @@
58 58 <view v-if="!planList.length" class="empty-tip">暂无明细</view>
59 59 <view v-for="(item, idx) in planList" :key="'p-' + (item.id || idx)" class="block">
60 60 <uni-list>
  61 + <uni-list-item title="计划编号">
  62 + <template v-slot:footer>
  63 + <uni-easyinput :value="item.planCode" :inputBorder="false" disabled />
  64 + </template>
  65 + </uni-list-item>
61 66 <uni-list-item title="计划品种">
62 67 <template v-slot:footer>
63 68 <uni-easyinput :value="item.productName" :inputBorder="false" disabled />
... ... @@ -68,11 +73,6 @@
68 73 <uni-easyinput :value="item.quantity" :inputBorder="false" disabled />
69 74 </template>
70 75 </uni-list-item>
71   - <uni-list-item title="计划编号">
72   - <template v-slot:footer>
73   - <uni-easyinput :value="item.planCode" :inputBorder="false" disabled />
74   - </template>
75   - </uni-list-item>
76 76 </uni-list>
77 77 </view>
78 78 </view>
... ... @@ -88,6 +88,11 @@
88 88 <view v-if="!weighList.length" class="empty-tip">暂无明细</view>
89 89 <view v-for="(item, idx) in weighList" :key="'w-' + (item.id || idx)" class="block">
90 90 <uni-list>
  91 + <uni-list-item title="计划编号">
  92 + <template v-slot:footer>
  93 + <uni-easyinput :value="item.planCode" :inputBorder="false" disabled />
  94 + </template>
  95 + </uni-list-item>
91 96 <uni-list-item title="过磅品种">
92 97 <template v-slot:footer>
93 98 <uni-easyinput :value="item.productName" :inputBorder="false" disabled />
... ... @@ -106,11 +111,6 @@
106 111 <uni-easyinput v-model="item.quantity" type="digit" :inputBorder="false" placeholder="请输入过磅数量" />
107 112 </template>
108 113 </uni-list-item>
109   - <uni-list-item title="计划编号">
110   - <template v-slot:footer>
111   - <uni-easyinput :value="item.planCode" :inputBorder="false" disabled />
112   - </template>
113   - </uni-list-item>
114 114 </uni-list>
115 115 </view>
116 116 </view>
... ...
... ... @@ -22,9 +22,9 @@
22 22 <view v-if="!planList.length" class="empty-tip">暂无明细</view>
23 23 <view v-for="(item, idx) in planList" :key="'p-' + (item.id || idx)" class="card">
24 24 <view class="card-index">第 {{ idx + 1 }} 行</view>
  25 + <view class="row"><text class="label">计划编号</text><text class="value">{{ item.planCode || '-' }}</text></view>
25 26 <view class="row"><text class="label">计划品种</text><text class="value">{{ item.productName || '-' }}</text></view>
26 27 <view class="row"><text class="label">计划数量</text><text class="value">{{ formatNumber(item.quantity) }}</text></view>
27   - <view class="row"><text class="label">计划编号</text><text class="value">{{ item.planCode || '-' }}</text></view>
28 28 </view>
29 29 </view>
30 30 </view>
... ... @@ -39,10 +39,10 @@
39 39 <view v-if="!weighList.length" class="empty-tip">暂无明细</view>
40 40 <view v-for="(item, idx) in weighList" :key="'w-' + (item.id || idx)" class="card">
41 41 <view class="card-index">第 {{ idx + 1 }} 行</view>
  42 + <view class="row"><text class="label">计划编号</text><text class="value">{{ item.planCode || '-' }}</text></view>
42 43 <view class="row"><text class="label">过磅品种</text><text class="value">{{ item.productName || '-' }}</text></view>
43 44 <view class="row"><text class="label">开票品名</text><text class="value">{{ item.invoiceProductName || '-' }}</text></view>
44 45 <view class="row"><text class="label">过磅数量</text><text class="value">{{ formatNumber(item.quantity) }}</text></view>
45   - <view class="row"><text class="label">计划编号</text><text class="value">{{ item.planCode || '-' }}</text></view>
46 46 </view>
47 47 </view>
48 48 </view>
... ...
  1 +<template>
  2 + <view class="detail-page">
  3 + <scroll-view class="scroll" scroll-y>
  4 + <!-- 基础信息 -->
  5 + <view class="section">
  6 + <text class="row company">{{ safeText(form.code) }}</text>
  7 + <view class="row"><text class="label">类型</text><text class="value">{{ typeName }}</text></view>
  8 + <view class="row"><text class="label">计划编号</text><text class="value">{{ safeText(planCodeText) }}</text></view>
  9 + <view class="row"><text class="label">单位</text><text class="value">{{ safeText(form.unit) }}</text></view>
  10 + <view class="row"><text class="label">时间</text><text class="value">{{ formatDate(form.firstGrossWeightTime) }}</text></view>
  11 + <view class="row"><text class="label">供料单位</text><text class="value">{{ safeText(form.supplierName) }}</text></view>
  12 + <view class="row"><text class="label">收料单位</text><text class="value">{{ safeText(form.companyShortName) }}</text></view>
  13 + </view>
  14 +
  15 + <!-- 计划单明细 -->
  16 + <view class="sub-table">
  17 + <view class="sub-header">
  18 + <image class="sub-bar" src="/static/images/title.png" />
  19 + <text class="sub-title">计划单明细</text>
  20 + </view>
  21 + <view class="sub-body">
  22 + <view v-if="!planList.length" class="empty-tip">暂无明细</view>
  23 + <view v-for="(item, idx) in planList" :key="'p-' + (item.id || idx)" class="card">
  24 + <view class="card-index">第 {{ idx + 1 }} 行</view>
  25 + <view class="row"><text class="label">计划品种</text><text class="value">{{ safeText(item.productName) }}</text></view>
  26 + <view class="row"><text class="label">计划数量</text><text class="value">{{ formatNumber(item.quantity) }}</text></view>
  27 + <view class="row"><text class="label">计划编号</text><text class="value">{{ safeText(item.planCode) }}</text></view>
  28 + </view>
  29 + </view>
  30 + </view>
  31 +
  32 + <!-- 过磅明细 -->
  33 + <view class="sub-table">
  34 + <view class="sub-header">
  35 + <image class="sub-bar" src="/static/images/title.png" />
  36 + <text class="sub-title">过磅明细</text>
  37 + </view>
  38 + <view class="sub-body">
  39 + <view v-if="!weighList.length" class="empty-tip">暂无明细</view>
  40 + <view v-for="(item, idx) in weighList" :key="'w-' + (item.id || idx)" class="card">
  41 + <view class="card-index">第 {{ idx + 1 }} 行</view>
  42 + <view class="row"><text class="label">过磅品种</text><text class="value">{{ safeText(item.productName) }}</text></view>
  43 + <view class="row"><text class="label">开票品名</text><text class="value">{{ safeText(item.invoiceProductName) }}</text></view>
  44 + <view class="row"><text class="label">过磅数量</text><text class="value">{{ formatNumber(item.quantity) }}</text></view>
  45 + <view class="row"><text class="label">计划编号</text><text class="value">{{ safeText(item.planCode) }}</text></view>
  46 + </view>
  47 + </view>
  48 + </view>
  49 +
  50 + <!-- 申请数量明细(仅买断展示) -->
  51 + <view v-if="isBuyout" class="sub-table">
  52 + <view class="sub-header">
  53 + <image class="sub-bar" src="/static/images/title.png" />
  54 + <text class="sub-title">申请数量明细</text>
  55 + </view>
  56 + <view class="sub-body">
  57 + <view v-if="!applyList.length" class="empty-tip">暂无明细</view>
  58 + <view v-for="(item, idx) in applyList" :key="'a-' + (item.id || idx)" class="card">
  59 + <view class="card-index">第 {{ idx + 1 }} 行</view>
  60 + <view class="row"><text class="label">类别</text><text class="value">{{ safeText(item.category) }}</text></view>
  61 + <view class="row"><text class="label">数量</text><text class="value">{{ formatNumber(item.quantity) }}</text></view>
  62 + </view>
  63 + </view>
  64 + </view>
  65 +
  66 + <!-- 其他信息 -->
  67 + <view class="title-header">
  68 + <image class="title-header_icon" src="/static/images/title.png" />
  69 + <span>其他信息</span>
  70 + </view>
  71 + <view class="section">
  72 + <view class="row"><text class="label">物料名称</text><text class="value">{{ safeText(form.materialName) }}</text></view>
  73 + <view class="row"><text class="label">过磅总重</text><text class="value">{{ formatNumber(form.totalGrossWeight) }}</text></view>
  74 + <view class="row"><text class="label">实际伙重</text><text class="value">{{ formatNumber(form.actualImpurityWeight) }}</text></view>
  75 + <view class="row"><text class="label">货物净重</text><text class="value">{{ formatNumber(form.netWeight) }}</text></view>
  76 + <view class="row"><text class="label">净重大写</text><text class="value">{{ safeText(form.netWeightUpper) }}</text></view>
  77 + <view class="row"><text class="label">来料扣杂类型</text><text class="value">{{ deductionNames }}</text></view>
  78 + <view class="row"><text class="label">供应存欠料</text><text class="value">{{ safeText(form.supplierStockMaterial) }}</text></view>
  79 + <view class="row"><text class="label">物流存欠料</text><text class="value">{{ safeText(form.logisticsStockMaterial) }}</text></view>
  80 + <view class="row"><text class="label">车牌号</text><text class="value">{{ safeText(form.plateNumber) }}</text></view>
  81 + </view>
  82 +
  83 + <!-- 业务摘要 -->
  84 + <view class="title-header">
  85 + <image class="title-header_icon" src="/static/images/title.png" />
  86 + <span>业务摘要</span>
  87 + </view>
  88 + <view class="section">
  89 + <text class="remark-text">{{ safeText(form.businessSummary) }}</text>
  90 + </view>
  91 +
  92 + <!-- 特别说明 -->
  93 + <view class="title-header">
  94 + <image class="title-header_icon" src="/static/images/title.png" />
  95 + <span>特别说明</span>
  96 + </view>
  97 + <view class="section">
  98 + <text class="remark-text">{{ safeText(form.specialNote) }}</text>
  99 + </view>
  100 +
  101 + <!-- 单据备注 -->
  102 + <view class="title-header">
  103 + <image class="title-header_icon" src="/static/images/title.png" />
  104 + <span>单据备注</span>
  105 + </view>
  106 + <view class="section">
  107 + <text class="remark-text">{{ safeText(form.documentRemark) }}</text>
  108 + </view>
  109 + </scroll-view>
  110 + </view>
  111 +</template>
  112 +
  113 +<script>
  114 +import { weighTicketDetailApi } from '@/api/procure-manage/weighTicket.js'
  115 +import { getDicByCodes, getDicName } from '@/utils/dic.js'
  116 +
  117 +export default {
  118 + name: 'WeightTicketViewer',
  119 + props: { id: { type: [String, Number], default: '' } },
  120 + data() {
  121 + return {
  122 + form: {},
  123 + planList: [],
  124 + weighList: [],
  125 + applyList: [],
  126 + buyout: false,
  127 + dicOptions: {
  128 + TYPE: [],
  129 + DEDUCTION_TYPE: []
  130 + }
  131 + }
  132 + },
  133 + computed: {
  134 + typeName() {
  135 + const v = this.form.type == null ? '' : String(this.form.type)
  136 + if (!v) return '-'
  137 + return getDicName('TYPE', v, this.dicOptions.TYPE) || v
  138 + },
  139 + planCodeText() {
  140 + const codes = Array.from(new Set((this.planList || []).map(it => it.planCode).filter(Boolean)))
  141 + return codes.join(',')
  142 + },
  143 + deductionNames() {
  144 + const codes = (this.form.deductionTypes == null ? '' : String(this.form.deductionTypes)).split(',').filter(Boolean)
  145 + const names = codes.map(code => getDicName('DEDUCTION_TYPE', code, this.dicOptions.DEDUCTION_TYPE)).filter(Boolean)
  146 + return names.length ? names.join('、') : '-'
  147 + },
  148 + isBuyout() {
  149 + return this.buyout || (this.applyList || []).length > 0
  150 + }
  151 + },
  152 + created() {
  153 + this.loadDicData()
  154 + },
  155 + watch: {
  156 + id: {
  157 + immediate: true,
  158 + handler(val) {
  159 + const v = (val !== undefined && val !== null) ? String(val) : ''
  160 + if (v) this.loadDetail(v)
  161 + }
  162 + }
  163 + },
  164 + methods: {
  165 + async loadDicData() {
  166 + try {
  167 + const results = await getDicByCodes(['TYPE', 'DEDUCTION_TYPE'])
  168 + this.dicOptions.TYPE = (results.TYPE && results.TYPE.data) || []
  169 + this.dicOptions.DEDUCTION_TYPE = (results.DEDUCTION_TYPE && results.DEDUCTION_TYPE.data) || []
  170 + } catch (e) {
  171 + this.dicOptions = { TYPE: [], DEDUCTION_TYPE: [] }
  172 + }
  173 + },
  174 + loadDetail(id) {
  175 + weighTicketDetailApi({ id })
  176 + .then(res => {
  177 + const data = res && res.data ? (res.data.data || res.data) : {}
  178 + this.form = Object.assign({}, data)
  179 + this.buyout = !!data.buyout
  180 + this.planList = Array.isArray(data.planLines) ? data.planLines.map(x => ({ ...x })) : []
  181 + this.weighList = Array.isArray(data.weighLines) ? data.weighLines.map(x => ({ ...x })) : []
  182 + this.applyList = Array.isArray(data.applyLines) ? data.applyLines.map(x => ({ ...x })) : []
  183 + })
  184 + .catch(() => {
  185 + uni.showToast({ title: '详情加载失败', icon: 'none' })
  186 + })
  187 + },
  188 + safeText(v) {
  189 + const s = v == null ? '' : String(v)
  190 + return s.trim() ? s : '-'
  191 + },
  192 + formatNumber(v) {
  193 + if (v === null || v === undefined || v === '') return '-'
  194 + const n = Number(v)
  195 + if (isNaN(n)) return String(v)
  196 + return n.toLocaleString('zh-CN', { maximumFractionDigits: 4 })
  197 + },
  198 + formatDate(v) {
  199 + const s = v == null ? '' : String(v).trim()
  200 + if (!s) return '-'
  201 + return s
  202 + }
  203 + }
  204 +}
  205 +</script>
  206 +
  207 +<style lang="scss" scoped>
  208 +.detail-page {
  209 + background: #f3f3f3;
  210 + min-height: 100%;
  211 +}
  212 +.scroll {
  213 + height: 100%;
  214 +}
  215 +.section {
  216 + padding: 32rpx;
  217 + background: #fff;
  218 + margin-bottom: 20rpx;
  219 +}
  220 +.title-header {
  221 + display: flex;
  222 + align-items: center;
  223 + padding: 24rpx 32rpx 12rpx;
  224 + background-color: #ffffff;
  225 +
  226 + .title-header_icon {
  227 + width: 36rpx;
  228 + height: 36rpx;
  229 + margin-right: 12rpx;
  230 + }
  231 +
  232 + span {
  233 + font-size: 34rpx;
  234 + font-weight: 600;
  235 + color: rgba(0, 0, 0, 0.9);
  236 + }
  237 +}
  238 +.row {
  239 + display: flex;
  240 + margin-bottom: 28rpx;
  241 +
  242 + &:last-child {
  243 + margin-bottom: 0;
  244 + }
  245 +
  246 + &.company {
  247 + font-size: 36rpx;
  248 + font-weight: 600;
  249 + color: rgba(0, 0, 0, 0.9);
  250 + padding-top: 8rpx;
  251 + line-height: 50rpx;
  252 + }
  253 +
  254 + .label {
  255 + max-width: 420rpx;
  256 + margin-right: 20rpx;
  257 + line-height: 32rpx;
  258 + font-size: 28rpx;
  259 + color: rgba(0, 0, 0, 0.6);
  260 + }
  261 +
  262 + .value {
  263 + flex: 1;
  264 + line-height: 32rpx;
  265 + font-size: 28rpx;
  266 + color: rgba(0, 0, 0, 0.9);
  267 + text-align: right;
  268 + word-break: break-all;
  269 + }
  270 +}
  271 +.remark-text {
  272 + font-size: 28rpx;
  273 + color: rgba(0, 0, 0, 0.9);
  274 + line-height: 1.6;
  275 + white-space: pre-wrap;
  276 +}
  277 +.sub-table {
  278 + background: #fff;
  279 + margin-bottom: 20rpx;
  280 +}
  281 +.sub-header {
  282 + display: flex;
  283 + align-items: center;
  284 + padding: 16rpx 0 16rpx 32rpx;
  285 +
  286 + .sub-bar {
  287 + width: 6rpx;
  288 + height: 32rpx;
  289 + margin-right: 14rpx;
  290 + }
  291 +
  292 + .sub-title {
  293 + font-size: 30rpx;
  294 + font-weight: 600;
  295 + color: rgba(0, 0, 0, 0.9);
  296 + flex: 1;
  297 + line-height: 42rpx;
  298 + }
  299 +}
  300 +.sub-body {
  301 + padding: 0 32rpx 24rpx;
  302 +
  303 + .empty-tip {
  304 + text-align: center;
  305 + padding: 60rpx 0;
  306 + color: rgba(0, 0, 0, 0.4);
  307 + font-size: 28rpx;
  308 + }
  309 +
  310 + .card {
  311 + position: relative;
  312 + background: #fafafa;
  313 + border-radius: 12rpx;
  314 + padding: 32rpx 28rpx 20rpx;
  315 + margin-bottom: 24rpx;
  316 +
  317 + .card-index {
  318 + position: absolute;
  319 + top: 0;
  320 + right: 0;
  321 + background: rgba(24, 144, 255, 0.08);
  322 + color: $theme-primary;
  323 + font-size: 22rpx;
  324 + line-height: 36rpx;
  325 + padding: 0 16rpx;
  326 + border-bottom-left-radius: 12rpx;
  327 + border-top-right-radius: 12rpx;
  328 + }
  329 +
  330 + .row {
  331 + align-items: center;
  332 + justify-content: space-between;
  333 + padding: 14rpx 0;
  334 + margin-bottom: 0;
  335 + border-bottom: 1rpx dashed #f2f2f2;
  336 +
  337 + &:last-child {
  338 + border-bottom: none;
  339 + }
  340 +
  341 + .label {
  342 + flex-shrink: 0;
  343 + width: 220rpx;
  344 + max-width: none;
  345 + margin-right: 0;
  346 + font-size: 28rpx;
  347 + color: rgba(0, 0, 0, 0.6);
  348 + line-height: 40rpx;
  349 + }
  350 +
  351 + .value {
  352 + flex: 1;
  353 + text-align: right;
  354 + font-size: 28rpx;
  355 + color: rgba(0, 0, 0, 0.9);
  356 + line-height: 40rpx;
  357 + overflow: hidden;
  358 + text-overflow: ellipsis;
  359 + white-space: nowrap;
  360 + }
  361 + }
  362 + }
  363 +}
  364 +</style>
... ...
... ... @@ -29,6 +29,7 @@ import FollowUpFormViewer from '@/pages/follow_up_form/viewer.vue'
29 29 import DomesticPlanViewer from '@/pages/domestic-plan/domesticPlanViewer.vue'
30 30 import SupplePlanViewer from '@/pages/supple-plan/supplePlanViewer.vue'
31 31 import DomesticAgreementViewer from '@/pages/domestic-agreement/domesticAgreementViewer.vue'
  32 +import WeightTicketViewer from '@/pages/weight-ticket/weightTicketViewer.vue'
32 33
33 34 export default function registerComponents(Vue) {
34 35 Vue.component('CustomerDevelopViewer', CustomerDevelopViewer)
... ... @@ -62,4 +63,5 @@ export default function registerComponents(Vue) {
62 63 Vue.component('DomesticPlanViewer', DomesticPlanViewer)
63 64 Vue.component('SupplePlanViewer', SupplePlanViewer)
64 65 Vue.component('DomesticAgreementViewer', DomesticAgreementViewer)
  66 + Vue.component('WeightTicketViewer', WeightTicketViewer)
65 67 }
... ...
... ... @@ -153,6 +153,12 @@ export const getSysFlowComponentPath = (bizFlag) => {
153 153 case 'PROCUREMENT_CONTRACT_EDIT': // 内贸协议
154 154 componentPath = 'DomesticAgreementViewer'; // 内贸协议-审批
155 155 break;
  156 + case 'WEIGHING_RECORD': // 过磅码单
  157 + componentPath = 'WeightTicketViewer'; // 过磅码单-审批详情
  158 + break;
  159 + case 'WEIGHING_RECORD_EDIT': // 过磅码单
  160 + componentPath = 'WeightTicketViewer'; // 过磅码单-审批
  161 + break;
156 162 }
157 163 return componentPath;
158 164 };
... ...