Commit 4a089258846759aed1e8979411559944c46615d6

Authored by gesilong
2 parents 0bc993b6 232949c0

Merge branch 'cjerp-2.0-plan' into test_cjerp

@@ -24,3 +24,10 @@ export function buyoutApplyAbolishApi(planId) { @@ -24,3 +24,10 @@ export function buyoutApplyAbolishApi(planId) {
24 params: { planId: planId } 24 params: { planId: planId }
25 }) 25 })
26 } 26 }
  27 +
  28 +export function buyoutApplyDeleteByPlanIdApi(planId) {
  29 + return request({
  30 + url: '/procurement/buyout/apply/deleteByPlanId?planId=' + planId,
  31 + method: 'post',
  32 + })
  33 +}
@@ -130,41 +130,36 @@ export function procurementPlanGetApi(id) { @@ -130,41 +130,36 @@ export function procurementPlanGetApi(id) {
130 130
131 export function procurementPlanGenerateContractApi(id) { 131 export function procurementPlanGenerateContractApi(id) {
132 return request({ 132 return request({
133 - url: '/procurement/plan/generateContract', 133 + url: '/procurement/plan/generateContract?id=' + id,
134 method: 'post', 134 method: 'post',
135 - params: { id: id }  
136 }) 135 })
137 } 136 }
138 137
139 export function procurementPlanSubmitAuditApi(id) { 138 export function procurementPlanSubmitAuditApi(id) {
140 return request({ 139 return request({
141 - url: '/procurement/plan/submitAudit', 140 + url: '/procurement/plan/submitAudit?id=' + id,
142 method: 'post', 141 method: 'post',
143 - params: { id: id }  
144 }) 142 })
145 } 143 }
146 144
147 export function procurementPlanSubmitApi(id) { 145 export function procurementPlanSubmitApi(id) {
148 return request({ 146 return request({
149 - url: '/procurement/plan/submit', 147 + url: '/procurement/plan/submit?id=' + id,
150 method: 'post', 148 method: 'post',
151 - params: { id: id }  
152 }) 149 })
153 } 150 }
154 151
155 export function procurementPlanStopApi(id) { 152 export function procurementPlanStopApi(id) {
156 return request({ 153 return request({
157 - url: '/procurement/plan/stop', 154 + url: '/procurement/plan/stop?id=' + id,
158 method: 'post', 155 method: 'post',
159 - params: { id: id }  
160 }) 156 })
161 } 157 }
162 158
163 export function procurementPlanChangeSubmitApi(id) { 159 export function procurementPlanChangeSubmitApi(id) {
164 return request({ 160 return request({
165 - url: '/procurement/plan/change/submit', 161 + url: '/procurement/plan/change/submit?id=' + id,
166 method: 'post', 162 method: 'post',
167 - params: { id: id }  
168 }) 163 })
169 } 164 }
170 165
@@ -72,3 +72,12 @@ export function salesmanQuotationCancelApi(params) { @@ -72,3 +72,12 @@ export function salesmanQuotationCancelApi(params) {
72 params 72 params
73 }) 73 })
74 } 74 }
  75 +
  76 +// 生成计划
  77 +export function salesmanQuotationCreatePlanApi(params) {
  78 + return request({
  79 + url: '/procurement/salesmanQuotation/createPlan?id=' + params.id,
  80 + method: 'post',
  81 + params
  82 + })
  83 +}
@@ -82,7 +82,7 @@ @@ -82,7 +82,7 @@
82 import DetailButtons from '@/components/detail-buttons/index.vue' 82 import DetailButtons from '@/components/detail-buttons/index.vue'
83 import ProductRel from './productRel.vue' 83 import ProductRel from './productRel.vue'
84 import { procurementPlanDetailApi, procurementPlanGenerateContractApi, procurementPlanSubmitAuditApi, procurementPlanSubmitApi, procurementPlanStopApi } from '@/api/procure-manage/procurementPlan.js' 84 import { procurementPlanDetailApi, procurementPlanGenerateContractApi, procurementPlanSubmitAuditApi, procurementPlanSubmitApi, procurementPlanStopApi } from '@/api/procure-manage/procurementPlan.js'
85 -import { buyoutApplyCreateApi, buyoutApplyAbolishApi } from '@/api/procure-manage/buyout.js' 85 +import { buyoutApplyCreateApi, buyoutApplyAbolishApi, buyoutApplyDeleteByPlanIdApi } from '@/api/procure-manage/buyout.js'
86 import { getDicByCodes, getDicName } from '@/utils/dic.js' 86 import { getDicByCodes, getDicName } from '@/utils/dic.js'
87 import { getInfo } from '@/api/login.js' 87 import { getInfo } from '@/api/login.js'
88 import { priceTableQueryApi, breedRelationshipQueryApi, workshopQueryApi } from '@/api/devManage.js' 88 import { priceTableQueryApi, breedRelationshipQueryApi, workshopQueryApi } from '@/api/devManage.js'
@@ -209,9 +209,9 @@ export default { @@ -209,9 +209,9 @@ export default {
209 approve: (inStatus([SC.AUDIT, SC.REFUSE]) && aStatus === 'AUDIT' && !!f.showExamine) && perms.approve, 209 approve: (inStatus([SC.AUDIT, SC.REFUSE]) && aStatus === 'AUDIT' && !!f.showExamine) && perms.approve,
210 approveDetail: !!f.showExamineDetail && (inStatus([SC.AUDIT, SC.COMPLETED, SC.REFUSE])) && perms.approveDetail, 210 approveDetail: !!f.showExamineDetail && (inStatus([SC.AUDIT, SC.COMPLETED, SC.REFUSE])) && perms.approveDetail,
211 print: inStatus([SC.TO_SUBMIT_REVIEW, SC.AUDIT, SC.COMPLETED, SC.ABORTED, SC.REFUSE]) && perms.print, 211 print: inStatus([SC.TO_SUBMIT_REVIEW, SC.AUDIT, SC.COMPLETED, SC.ABORTED, SC.REFUSE]) && perms.print,
212 - generate: !!f.showGenerateBuyoutApply && inStatus([SC.TO_SUBMIT_REVIEW, SC.AUDIT, SC.COMPLETED]) && perms.generateBuyoutApply,  
213 - cancel: !!f.showAbolishBuyoutApply && inStatus([SC.TO_SUBMIT_REVIEW, SC.AUDIT, SC.COMPLETED]) && perms.abolishBuyoutApply,  
214 - look: inStatus([SC.TO_SUBMIT_REVIEW, SC.AUDIT, SC.COMPLETED, SC.REFUSE]) && perms.viewBuyoutApply, 212 + generate: !!f.showGenerateBuyoutApply && inStatus([SC.TO_SUBMIT_REVIEW, SC.AUDIT, SC.COMPLETED]) && perms.generate,
  213 + cancel: !!f.showAbolishBuyoutApply && inStatus([SC.TO_SUBMIT_REVIEW, SC.AUDIT, SC.COMPLETED]) && perms.cancel,
  214 + look: inStatus([SC.TO_SUBMIT_REVIEW, SC.AUDIT, SC.COMPLETED, SC.REFUSE]) && perms.look,
215 // uploadAttachment: inStatus([SC.COMPLETED]) && !!this.planRoleFlags.isPlanner && perms.uploadAttachment 215 // uploadAttachment: inStatus([SC.COMPLETED]) && !!this.planRoleFlags.isPlanner && perms.uploadAttachment
216 } 216 }
217 var out = [] 217 var out = []
@@ -232,6 +232,13 @@ export default { @@ -232,6 +232,13 @@ export default {
232 this.getUserInfo() 232 this.getUserInfo()
233 this.loadDetail() 233 this.loadDetail()
234 }, 234 },
  235 + onShow() {
  236 + var needRefresh = ''
  237 + try { needRefresh = uni.getStorageSync('DOMESTIC_PLAN_DETAIL_NEED_REFRESH') } catch (e) {}
  238 + if (!needRefresh) return
  239 + try { uni.removeStorageSync('DOMESTIC_PLAN_DETAIL_NEED_REFRESH') } catch (e) {}
  240 + this.loadDetail()
  241 + },
235 methods: { 242 methods: {
236 hasPerm(code) { 243 hasPerm(code) {
237 try { 244 try {
@@ -415,10 +422,11 @@ export default { @@ -415,10 +422,11 @@ export default {
415 if (e === 'approveDetail') return this.onApproveDetail() 422 if (e === 'approveDetail') return this.onApproveDetail()
416 if (e === 'print') return this.onPrint() 423 if (e === 'print') return this.onPrint()
417 if (e === 'generateBuyoutApply') return this.onGenerateBuyoutApply() 424 if (e === 'generateBuyoutApply') return this.onGenerateBuyoutApply()
418 - if (e === 'abolishBuyoutApply') return this.onAbolishBuyoutApply() 425 + if (e === 'cancel') return this.onAbolishBuyoutApply()
419 if (e === 'look') return this.onViewBuyoutApply() 426 if (e === 'look') return this.onViewBuyoutApply()
420 if (e === 'uploadAttachment') return this.onUploadAttachment() 427 if (e === 'uploadAttachment') return this.onUploadAttachment()
421 }, 428 },
  429 +
422 onView() { 430 onView() {
423 uni.showToast({ title: '查看', icon: 'none' }) 431 uni.showToast({ title: '查看', icon: 'none' })
424 }, 432 },
@@ -562,7 +570,7 @@ export default { @@ -562,7 +570,7 @@ export default {
562 loading: '废除中', 570 loading: '废除中',
563 successText: '废除成功', 571 successText: '废除成功',
564 failText: '废除买断操作申请单失败', 572 failText: '废除买断操作申请单失败',
565 - run: function () { return buyoutApplyAbolishApi(id) } 573 + run: function () { return buyoutApplyDeleteByPlanIdApi(id) }
566 }) 574 })
567 }, 575 },
568 onViewBuyoutApply() { 576 onViewBuyoutApply() {
  1 +<template>
  2 + <view class="detail-page">
  3 + <scroll-view class="scroll" scroll-y>
  4 + <view class="section">
  5 + <text class="row company">{{ safeText(form.code) }}</text>
  6 + <view class="row"><text class="label">公司简称</text><text class="value">{{ safeText(form.companyShortName || form.companyName) }}</text></view>
  7 + <view class="row"><text class="label">供应商名称</text><text class="value">{{ safeText(form.supplierName) }}</text></view>
  8 + <view class="row"><text class="label">采购处</text><text class="value">{{ safeText(form.purchaseDepartmentName || form.purchaseDepartment) }}</text></view>
  9 + <view class="row"><text class="label">区域</text><text class="value">{{ safeText(form.regionName || form.region) }}</text></view>
  10 + <view class="row"><text class="label">日期</text><text class="value">{{ formatDateOnly(form.date) }}</text></view>
  11 + <view class="row"><text class="label">报价时效</text><text class="value">{{ safeText(form.validityPeriod) }}</text></view>
  12 + <view class="row"><text class="label">报价人</text><text class="value">{{ safeText(form.quoterName) }}</text></view>
  13 + <view class="row"><text class="label">是否长单操作</text><text class="value">{{ boolText(form.longTermOperation) }}</text></view>
  14 + <view class="row"><text class="label">是否终端客户</text><text class="value">{{ boolText(form.terminalCustomer) }}</text></view>
  15 + <view class="row"><text class="label">是否未点价</text><text class="value">{{ boolText(form.priced) }}</text></view>
  16 + <view v-if="form.priced === true" class="row"><text class="label">点价截止日期</text><text class="value">{{ formatDateOnly(form.pricingDeadline) }}</text></view>
  17 + <view v-if="form.priced === true" class="row"><text class="label">是否暂定价</text><text class="value">{{ boolText(form.temporaryPrice) }}</text></view>
  18 + <view class="row"><text class="label">其他费用凭票到厂另行结算</text><text class="value">{{ boolText(form.otherExpenseSettlement) }}</text></view>
  19 + <view class="row"><text class="label">交提货方式</text><text class="value">{{ getDeliveryMethodLabel() }}</text></view>
  20 + <view class="row"><text class="label">是否通货买断</text><text class="value">{{ boolText(form.commodityBuyout) }}</text></view>
  21 + <view class="row"><text class="label">是否质量买断</text><text class="value">{{ boolText(form.qualityBuyout) }}</text></view>
  22 + <view class="row"><text class="label">是否数量买断</text><text class="value">{{ boolText(form.quantityBuyout) }}</text></view>
  23 + <view class="row"><text class="label">是否送货上门</text><text class="value">{{ boolText(form.doorDelivery) }}</text></view>
  24 + <view class="row"><text class="label">另付运费</text><text class="value">{{ formatNumber(form.shippingCost) }}</text></view>
  25 + <view class="row"><text class="label">装车费</text><text class="value">{{ formatNumber(form.loadingFee) }}</text></view>
  26 + <view class="row"><text class="label">开票品名</text><text class="value">{{ safeText(form.invoiceProductName) }}</text></view>
  27 + <view class="row"><text class="label">交货日期</text><text class="value">{{ formatDateOnly(form.deliveryDate) }}</text></view>
  28 + <view class="row"><text class="label">结算方式</text><text class="value">{{ safeText(form.settlementMethod) }}</text></view>
  29 + <view class="row"><text class="label">结算比例(%)</text><text class="value">{{ formatNumber(form.settlementRatio) }}</text></view>
  30 + <view class="row"><text class="label">价格表编号</text><text class="value">{{ getPriceTableLabel() }}</text></view>
  31 + <view class="row"><text class="label">协调事由</text><text class="value">{{ safeText(form.coordinationReason) }}</text></view>
  32 + <view class="row"><text class="label">票类状况</text><text class="value">{{ safeText(form.invoiceTypeStatus) }}</text></view>
  33 + <view class="row" v-if="attachmentList.length">
  34 + <text class="label">附件</text>
  35 + <view class="attach-list">
  36 + <view v-for="(at, idx) in attachmentList" :key="idx" class="attach-item">
  37 + <text class="attach-name">{{ at.name }}</text>
  38 + <text class="attach-view" @click.stop="onPreviewAttachment(at)">查看</text>
  39 + </view>
  40 + </view>
  41 + </view>
  42 + </view>
  43 +
  44 + <ProductRel
  45 + mode="view"
  46 + :list="lineListWithName"
  47 + :product-options="productOptions"
  48 + :workshop-options="workshopOptions"
  49 + />
  50 +
  51 + <view class="title-header">
  52 + <image class="title-header_icon" src="/static/images/title.png" />
  53 + <span>料质状况</span>
  54 + </view>
  55 + <view class="section">
  56 + <view class="row"><text class="label">是否启用料质状况</text><text class="value">{{ boolText(form.materialConditionEnabled) }}</text></view>
  57 + <template v-if="form.materialConditionEnabled">
  58 + <view v-for="mc in materialConditionConfigs" :key="mc.field" class="material-group">
  59 + <text class="material-label">{{ mc.label }}</text>
  60 + <view class="tag-list">
  61 + <view v-for="opt in getDictOptions(mc.dictCode)" :key="opt.code" class="tag-btn" :class="{ active: isTagSelected(mc.field, opt.code) }">{{ opt.name }}</view>
  62 + </view>
  63 + </view>
  64 + </template>
  65 + </view>
  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 + <text class="remark-text">{{ safeText(form.remark) }}</text>
  73 + </view>
  74 + </scroll-view>
  75 + </view>
  76 +</template>
  77 +
  78 +<script>
  79 +import ProductRel from './productRel.vue'
  80 +import { procurementPlanDetailApi } from '@/api/procure-manage/procurementPlan.js'
  81 +import { getDicByCodes, getDicName } from '@/utils/dic.js'
  82 +import { priceTableQueryApi, breedRelationshipQueryApi, workshopQueryApi } from '@/api/devManage.js'
  83 +
  84 +export default {
  85 + name: 'DomesticPlanViewer',
  86 + components: { ProductRel },
  87 + props: {
  88 + id: { type: [String, Number], default: '' }
  89 + },
  90 + data() {
  91 + return {
  92 + form: {},
  93 + lineList: [],
  94 + attachmentList: [],
  95 + materialConditionConfigs: [
  96 + { field: 'materialConditionCopperRice', label: '铜米', dictCode: 'COPPER_RICE' },
  97 + { field: 'materialConditionBrightCopper', label: '光亮铜', dictCode: 'BRIGHT_COPPER' },
  98 + { field: 'materialConditionFirstClass', label: '一特', dictCode: 'FIRST_CLASS' },
  99 + { field: 'materialConditionSecondClass', label: '二特', dictCode: 'SECOND_CLASS' },
  100 + { field: 'materialConditionTinCoated', label: '镀锡紫', dictCode: 'TIN_COATED' },
  101 + { field: 'materialConditionScrap', label: '角料', dictCode: 'SCRAP' },
  102 + { field: 'materialConditionWhiteYellow', label: '镀白黄', dictCode: 'WHITE_YELLOW' },
  103 + { field: 'materialConditionPhosphorCopper', label: '磷铜', dictCode: 'PHOSPHOR_COPPER' }
  104 + ],
  105 + dicOptions: {
  106 + AUDIT_STATUS: [],
  107 + PROCESS_STATUS: [],
  108 + DELIVERY_METHOD: []
  109 + },
  110 + dictData: {},
  111 + priceTableList: [],
  112 + productOptions: [],
  113 + workshopOptions: []
  114 + }
  115 + },
  116 + computed: {
  117 + productMap() {
  118 + var list = Array.isArray(this.productOptions) ? this.productOptions : []
  119 + var m = {}
  120 + list.forEach(function (o) {
  121 + var key = String(o.productId || o.id || o.value || '')
  122 + if (key) m[key] = o
  123 + })
  124 + return m
  125 + },
  126 + workshopMap() {
  127 + var list = Array.isArray(this.workshopOptions) ? this.workshopOptions : []
  128 + var m = {}
  129 + list.forEach(function (o) {
  130 + var key = String(o.workshopId || o.id || o.value || '')
  131 + if (key) m[key] = o
  132 + })
  133 + return m
  134 + },
  135 + lineListWithName() {
  136 + var self = this
  137 + var list = Array.isArray(this.lineList) ? this.lineList : []
  138 + return list.map(function (row) {
  139 + var pid = String(row.productId || '')
  140 + var wid = String(row.workshopId || '')
  141 + var p = pid ? self.productMap[pid] : null
  142 + var w = wid ? self.workshopMap[wid] : null
  143 + return Object.assign({}, row, {
  144 + productName: row.productName || (p ? (p.productName || p.name || p.label || '') : ''),
  145 + workshopName: row.workshopName || (w ? (w.workshopName || w.name || w.label || '') : '')
  146 + })
  147 + })
  148 + }
  149 + },
  150 + created() {
  151 + this.loadDictData()
  152 + this.loadRefData()
  153 + },
  154 + watch: {
  155 + id: {
  156 + immediate: true,
  157 + handler(val) {
  158 + var v = (val !== undefined && val !== null) ? String(val) : ''
  159 + if (v) this.loadDetail(v)
  160 + }
  161 + }
  162 + },
  163 + methods: {
  164 + async loadDictData() {
  165 + var self = this
  166 + var codes = [].concat(
  167 + this.materialConditionConfigs.map(function (mc) { return mc.dictCode }),
  168 + ['DELIVERY_METHOD', 'AUDIT_STATUS', 'PROCESS_STATUS']
  169 + )
  170 + try {
  171 + var results = await getDicByCodes(codes)
  172 + var d = results || {}
  173 + this.dictData = d
  174 + this.dicOptions.AUDIT_STATUS = (d.AUDIT_STATUS && d.AUDIT_STATUS.data) || []
  175 + this.dicOptions.PROCESS_STATUS = (d.PROCESS_STATUS && d.PROCESS_STATUS.data) || []
  176 + this.dicOptions.DELIVERY_METHOD = (d.DELIVERY_METHOD && d.DELIVERY_METHOD.data) || []
  177 + } catch (e) {
  178 + this.dictData = {}
  179 + }
  180 + },
  181 + getDictOptions(dictCode) {
  182 + var data = this.dictData[dictCode]
  183 + return (data && data.data) ? data.data : []
  184 + },
  185 + isTagSelected(field, code) {
  186 + var selected = this.form ? this.form[field] : undefined
  187 + if (Array.isArray(selected)) return selected.indexOf(code) >= 0
  188 + if (typeof selected === 'string' && selected) {
  189 + return selected.split(',').indexOf(code) >= 0
  190 + }
  191 + return false
  192 + },
  193 + getAuditStatusText(status) {
  194 + var v = status == null ? '' : String(status)
  195 + if (!v) return '-'
  196 + return getDicName('AUDIT_STATUS', v, this.dicOptions.AUDIT_STATUS) || v
  197 + },
  198 + getProcessStatusText(status) {
  199 + var v = status == null ? '' : String(status)
  200 + if (!v) return '-'
  201 + return getDicName('PROCESS_STATUS', v, this.dicOptions.PROCESS_STATUS) || v
  202 + },
  203 + getDeliveryMethodLabel() {
  204 + var opts = this.getDictOptions('DELIVERY_METHOD') || []
  205 + var v = String(this.form.deliveryMode != null ? this.form.deliveryMode : '')
  206 + if (!v) return '-'
  207 + for (var i = 0; i < opts.length; i++) {
  208 + var o = opts[i]
  209 + var code = o.code != null ? String(o.code) : (o.value != null ? String(o.value) : '')
  210 + if (code === v) return o.name || o.label || '-'
  211 + }
  212 + return v
  213 + },
  214 + getPriceTableLabel() {
  215 + var code = this.form.priceTableCode != null ? this.form.priceTableCode : (this.form.priceId != null ? this.form.priceId : '')
  216 + if (code == null || String(code).trim() === '') return '-'
  217 + var sc = String(code)
  218 + var list = Array.isArray(this.priceTableList) ? this.priceTableList : []
  219 + for (var i = 0; i < list.length; i++) {
  220 + var o = list[i]
  221 + var id = String(o.id || o.priceId || o.value || '')
  222 + var c = String(o.priceTableCode || o.code || o.priceCode || '')
  223 + if (id === sc || c === sc) {
  224 + var name = o.priceTableName || o.tableName || o.name || o.label || ''
  225 + var cd = o.priceTableCode || o.code || c
  226 + return (name ? name + ' ' : '') + (cd ? cd : '') || '-'
  227 + }
  228 + }
  229 + return sc
  230 + },
  231 + async loadRefData() {
  232 + var self = this
  233 + try {
  234 + var results = await Promise.all([
  235 + this.pCall(priceTableQueryApi, { pageIndex: 1, pageSize: 1000 }),
  236 + this.pCall(breedRelationshipQueryApi, { pageIndex: 1, pageSize: 1000 }),
  237 + this.pCall(workshopQueryApi, { pageIndex: 1, pageSize: 1000 })
  238 + ])
  239 + var r1 = (results[0] && results[0].data) ? results[0].data : {}
  240 + var r2 = (results[1] && results[1].data) ? results[1].data : {}
  241 + var r3 = (results[2] && results[2].data) ? results[2].data : {}
  242 + self.priceTableList = (r1.datas && Array.isArray(r1.datas)) ? r1.datas : ((r1.list && Array.isArray(r1.list)) ? r1.list : ((r1.records && Array.isArray(r1.records)) ? r1.records : []))
  243 + self.productOptions = (r2.datas && Array.isArray(r2.datas)) ? r2.datas : ((r2.list && Array.isArray(r2.list)) ? r2.list : ((r2.records && Array.isArray(r2.records)) ? r2.records : []))
  244 + self.workshopOptions = (r3.datas && Array.isArray(r3.datas)) ? r3.datas : ((r3.list && Array.isArray(r3.list)) ? r3.list : ((r3.records && Array.isArray(r3.records)) ? r3.records : []))
  245 + } catch (e) {
  246 + self.priceTableList = []
  247 + self.productOptions = []
  248 + self.workshopOptions = []
  249 + }
  250 + },
  251 + pCall(fn, params) {
  252 + try {
  253 + return Promise.resolve(fn(params))
  254 + } catch (e) {
  255 + return Promise.reject(e)
  256 + }
  257 + },
  258 + boolText(v) {
  259 + if (typeof v !== 'boolean') return '-'
  260 + return v ? '是' : '否'
  261 + },
  262 + formatDateOnly(v) {
  263 + var s = v == null ? '' : String(v).trim()
  264 + if (!s) return '-'
  265 + if (s.length >= 10) return s.slice(0, 10)
  266 + return s
  267 + },
  268 + safeText(v) {
  269 + var s = v == null ? '' : String(v)
  270 + return s.trim() ? s : '-'
  271 + },
  272 + formatNumber(v) {
  273 + if (v == null || v === '') return '-'
  274 + var n = Number(v)
  275 + if (isNaN(n)) return String(v)
  276 + return n.toLocaleString('zh-CN', { maximumFractionDigits: 4 })
  277 + },
  278 + buildAttachmentList() {
  279 + var ids = this.form.attachmentFileIds
  280 + var names = this.form.attachmentFileNames
  281 + var idArr = (typeof ids === 'string' && ids) ? ids.split(',').filter(Boolean) : (Array.isArray(ids) ? ids : [])
  282 + var nameArr = (typeof names === 'string' && names) ? names.split(',').filter(Boolean) : (Array.isArray(names) ? names : [])
  283 + var len = Math.max(idArr.length, nameArr.length)
  284 + var list = []
  285 + for (var i = 0; i < len; i++) {
  286 + list.push({ id: idArr[i] || '', name: nameArr[i] || ('附件' + (i + 1)) })
  287 + }
  288 + this.attachmentList = list
  289 + },
  290 + getFormValues() {
  291 + var self = this
  292 + var form = this.form || {}
  293 + var result = JSON.parse(JSON.stringify(form))
  294 + this.materialConditionConfigs.forEach(function (mc) {
  295 + var arr = form[mc.field]
  296 + var listField = mc.field + 'List'
  297 + if (Array.isArray(arr)) {
  298 + result[mc.field] = arr.join(',')
  299 + result[listField] = arr.slice()
  300 + } else if (typeof arr === 'string' && arr) {
  301 + result[mc.field] = arr
  302 + result[listField] = arr.split(',').filter(Boolean)
  303 + } else {
  304 + result[mc.field] = ''
  305 + result[listField] = []
  306 + }
  307 + })
  308 + var lines = Array.isArray(this.lineList) ? this.lineList : []
  309 + result.procurementPlanLineList = lines.map(function (r) {
  310 + var line = JSON.parse(JSON.stringify(r))
  311 + if (r.shippingCost != null && r.shippingCost !== '') {
  312 + line.shippingCost = self.toNumber ? self.toNumber(r.shippingCost) : Number(r.shippingCost)
  313 + }
  314 + if (r.loadingFee != null && r.loadingFee !== '') {
  315 + line.loadingFee = self.toNumber ? self.toNumber(r.loadingFee) : Number(r.loadingFee)
  316 + }
  317 + if (r.actualPurchasePrice != null && r.actualPurchasePrice !== '') {
  318 + line.actualPurchasePrice = self.toNumber ? self.toNumber(r.actualPurchasePrice) : Number(r.actualPurchasePrice)
  319 + }
  320 + if (r.includingShippingPrice != null && r.includingShippingPrice !== '') {
  321 + line.includingShippingPrice = self.toNumber ? self.toNumber(r.includingShippingPrice) : Number(r.includingShippingPrice)
  322 + }
  323 + if (r.coordinationRange != null && r.coordinationRange !== '') {
  324 + line.coordinationRange = self.toNumber ? self.toNumber(r.coordinationRange) : Number(r.coordinationRange)
  325 + }
  326 + if (r.priceListPrices != null && r.priceListPrices !== '') {
  327 + line.priceListPrices = self.toNumber ? self.toNumber(r.priceListPrices) : Number(r.priceListPrices)
  328 + }
  329 + if (r.quantity != null && r.quantity !== '') {
  330 + line.quantity = self.toNumber ? self.toNumber(r.quantity) : Number(r.quantity)
  331 + }
  332 + if (r.estimatedLoss != null && r.estimatedLoss !== '') {
  333 + line.estimatedLoss = self.toNumber ? self.toNumber(r.estimatedLoss) : Number(r.estimatedLoss)
  334 + }
  335 + if (r.applicationAttrition != null && r.applicationAttrition !== '') {
  336 + line.applicationAttrition = self.toNumber ? self.toNumber(r.applicationAttrition) : Number(r.applicationAttrition)
  337 + }
  338 + return line
  339 + })
  340 + return result
  341 + },
  342 + checkForm() {
  343 + return true
  344 + },
  345 + async loadDetail(id) {
  346 + try {
  347 + var res = await procurementPlanDetailApi({ id: id })
  348 + var d = (res && res.data) ? res.data : {}
  349 + var self = this
  350 + this.materialConditionConfigs.forEach(function (mc) {
  351 + var v = d[mc.field]
  352 + if (typeof v === 'string' && v) {
  353 + d[mc.field] = v.split(',').filter(Boolean)
  354 + } else if (!Array.isArray(v)) {
  355 + d[mc.field] = []
  356 + }
  357 + })
  358 + this.form = d
  359 + this.lineList = Array.isArray(d.procurementPlanLineList) ? d.procurementPlanLineList : []
  360 + this.buildAttachmentList()
  361 + } catch (e) {
  362 + this.form = {}
  363 + this.lineList = []
  364 + this.attachmentList = []
  365 + }
  366 + },
  367 + onPreviewAttachment(at) {
  368 + if (!at || !at.id) {
  369 + uni.showToast({ title: '无法查看', icon: 'none' })
  370 + return
  371 + }
  372 + uni.showToast({ title: '查看附件 ' + at.name, icon: 'none' })
  373 + }
  374 + }
  375 +}
  376 +</script>
  377 +
  378 +<style lang="scss" scoped>
  379 +.detail-page {
  380 + background: #f3f3f3;
  381 +}
  382 +.scroll {
  383 + flex: 1;
  384 + padding: 8rpx 0 144rpx;
  385 +}
  386 +.title-header {
  387 + display: flex;
  388 + align-items: center;
  389 + padding: 24rpx 32rpx 12rpx;
  390 + background-color: #ffffff;
  391 + .title-header_icon {
  392 + width: 36rpx;
  393 + height: 36rpx;
  394 + margin-right: 12rpx;
  395 + }
  396 + span {
  397 + font-size: 34rpx;
  398 + font-weight: 600;
  399 + color: rgba(0, 0, 0, 0.9);
  400 + }
  401 +}
  402 +.section {
  403 + padding: 32rpx;
  404 + background: #fff;
  405 + margin-bottom: 20rpx;
  406 +}
  407 +.row {
  408 + display: flex;
  409 + margin-bottom: 28rpx;
  410 + &:last-child { margin-bottom: 0; }
  411 + &.company {
  412 + font-size: 36rpx;
  413 + font-weight: 600;
  414 + color: rgba(0, 0, 0, 0.9);
  415 + padding-top: 8rpx;
  416 + line-height: 50rpx;
  417 + }
  418 + .label {
  419 + max-width: 420rpx;
  420 + margin-right: 20rpx;
  421 + line-height: 32rpx;
  422 + font-size: 28rpx;
  423 + color: rgba(0, 0, 0, 0.6);
  424 + }
  425 + .value {
  426 + flex: 1;
  427 + line-height: 32rpx;
  428 + font-size: 28rpx;
  429 + color: rgba(0, 0, 0, 0.9);
  430 + text-align: right;
  431 + word-break: break-all;
  432 + }
  433 +}
  434 +.attach-list {
  435 + flex: 1;
  436 + display: flex;
  437 + flex-direction: column;
  438 + align-items: flex-end;
  439 + gap: 8rpx;
  440 +}
  441 +.attach-item {
  442 + display: flex;
  443 + align-items: center;
  444 + gap: 16rpx;
  445 + .attach-name {
  446 + font-size: 26rpx;
  447 + color: rgba(0, 0, 0, 0.9);
  448 + }
  449 + .attach-view {
  450 + font-size: 26rpx;
  451 + color: $theme-primary;
  452 + }
  453 +}
  454 +.material-group {
  455 + margin-top: 32rpx;
  456 + &:first-child { margin-top: 0; }
  457 +}
  458 +.material-label {
  459 + display: block;
  460 + font-size: 28rpx;
  461 + color: rgba(0, 0, 0, 0.6);
  462 + margin-bottom: 20rpx;
  463 +}
  464 +.tag-list {
  465 + display: flex;
  466 + flex-wrap: wrap;
  467 + gap: 16rpx;
  468 +}
  469 +.tag-btn {
  470 + padding: 12rpx 24rpx;
  471 + border: 1rpx solid #ddd;
  472 + border-radius: 8rpx;
  473 + font-size: 28rpx;
  474 + color: #999;
  475 + background: #f5f5f5;
  476 +}
  477 +.tag-btn.active {
  478 + background: $theme-primary;
  479 + border-color: $theme-primary;
  480 + color: #fff;
  481 +}
  482 +.remark-text {
  483 + font-size: 28rpx;
  484 + color: rgba(0, 0, 0, 0.9);
  485 + line-height: 1.6;
  486 + white-space: pre-wrap;
  487 +}
  488 +</style>
@@ -67,27 +67,7 @@ @@ -67,27 +67,7 @@
67 </uni-list-item> 67 </uni-list-item>
68 <uni-list-item title="含运到厂价"> 68 <uni-list-item title="含运到厂价">
69 <template v-slot:footer> 69 <template v-slot:footer>
70 - <!-- <template v-if="isSupplement">  
71 - <uni-easyinput  
72 - v-model="item.includingShippingPrice"  
73 - type="digit"  
74 - :inputBorder="false"  
75 - placeholder="请输入含运到厂价"  
76 - @input="onNonNegativeInput(idx, 'includingShippingPrice')"  
77 - @blur="onNonNegativeBlur(idx, 'includingShippingPrice', 2)"  
78 - />  
79 - </template> -->  
80 - <template v-if="!isSelectWorkshop || isSupplement">  
81 - <uni-easyinput  
82 - v-model="item.includingShippingPrice"  
83 - type="digit"  
84 - :inputBorder="false"  
85 - placeholder="请输入含运到厂价"  
86 - @input="onNonNegativeInput(idx, 'includingShippingPrice')"  
87 - @blur="onNonNegativeBlur(idx, 'includingShippingPrice', 2)"  
88 - />  
89 - </template>  
90 - <text v-else class="lock-value">{{ formatTextNumber(item.includingShippingPrice) }}</text> 70 + <text class="lock-value">{{ formatTextNumber(item.includingShippingPrice) }}</text>
91 </template> 71 </template>
92 </uni-list-item> 72 </uni-list-item>
93 <uni-list-item title="价格表价格"> 73 <uni-list-item title="价格表价格">
@@ -106,27 +86,7 @@ @@ -106,27 +86,7 @@
106 </uni-list-item> 86 </uni-list-item>
107 <uni-list-item title="协调幅度"> 87 <uni-list-item title="协调幅度">
108 <template v-slot:footer> 88 <template v-slot:footer>
109 - <template v-if="isSupplement">  
110 - <uni-easyinput  
111 - v-model="item.coordinationRange"  
112 - type="digit"  
113 - :inputBorder="false"  
114 - placeholder="请输入协调幅度"  
115 - @input="onSignedInput(idx, 'coordinationRange')"  
116 - @blur="onNonNegativeBlur(idx, 'coordinationRange', 2)"  
117 - />  
118 - </template>  
119 - <template v-else-if="!isSelectWorkshop">  
120 - <uni-easyinput  
121 - v-model="item.coordinationRange"  
122 - type="digit"  
123 - :inputBorder="false"  
124 - placeholder="请输入协调幅度"  
125 - @input="onSignedInput(idx, 'coordinationRange')"  
126 - @blur="onNonNegativeBlur(idx, 'coordinationRange', 2)"  
127 - />  
128 - </template>  
129 - <text v-else class="lock-value">{{ formatTextNumber(item.coordinationRange) }}</text> 89 + <text class="lock-value">{{ formatTextNumber(item.coordinationRange) }}</text>
130 </template> 90 </template>
131 </uni-list-item> 91 </uni-list-item>
132 <uni-list-item title="买断料预计损耗"> 92 <uni-list-item title="买断料预计损耗">
@@ -303,7 +303,8 @@ export default { @@ -303,7 +303,8 @@ export default {
303 dictData: {}, 303 dictData: {},
304 lineList: [], 304 lineList: [],
305 productOptions: [], 305 productOptions: [],
306 - workshopOptions: [] 306 + workshopOptions: [],
  307 + priceTableList: []
307 } 308 }
308 }, 309 },
309 computed: { 310 computed: {
@@ -360,10 +361,23 @@ export default { @@ -360,10 +361,23 @@ export default {
360 }, 361 },
361 priceTableDisplay() { 362 priceTableDisplay() {
362 var d = this.detail || {} 363 var d = this.detail || {}
363 - var c = d.priceTableCode != null ? d.priceTableCode : (d.priceTableId != null ? d.priceTableId : '')  
364 - var n = d.priceTableName != null ? d.priceTableName : ''  
365 - if (!c && !n) return ''  
366 - return n ? (n + (c ? ' (' + c + ')' : '')) : c 364 + var code = d.priceTableCode != null ? d.priceTableCode : (d.priceId != null ? d.priceId : (d.priceTableId != null ? d.priceTableId : ''))
  365 + if (code == null || String(code).trim() === '') return ''
  366 + var sc = String(code)
  367 + var list = Array.isArray(this.priceTableList) ? this.priceTableList : []
  368 + for (var i = 0; i < list.length; i++) {
  369 + var o = list[i]
  370 + var id = String(o.id || o.priceId || o.value || '')
  371 + var c = String(o.priceTableCode || o.code || o.priceCode || '')
  372 + if (id === sc || c === sc) {
  373 + var name = o.priceTableName || o.tableName || o.name || o.label || ''
  374 + var cd = o.priceTableCode || o.code || c
  375 + return (name ? name + ' ' : '') + (cd ? cd : '') || ''
  376 + }
  377 + }
  378 + var fallbackName = d.priceTableName != null ? d.priceTableName : ''
  379 + var fallbackCode = d.priceTableCode != null ? d.priceTableCode : sc
  380 + return (fallbackName ? fallbackName + ' ' : '') + (fallbackCode ? fallbackCode : '') || ''
367 } 381 }
368 }, 382 },
369 onLoad(query) { 383 onLoad(query) {
@@ -470,15 +484,19 @@ export default { @@ -470,15 +484,19 @@ export default {
470 async loadRefData() { 484 async loadRefData() {
471 try { 485 try {
472 var results = await Promise.all([ 486 var results = await Promise.all([
  487 + this.$pCall(priceTableQueryApi, { pageIndex: 1, pageSize: 1000 }),
473 this.$pCall(breedRelationshipQueryApi, { pageIndex: 1, pageSize: 1000 }), 488 this.$pCall(breedRelationshipQueryApi, { pageIndex: 1, pageSize: 1000 }),
474 this.$pCall(workshopQueryApi, { pageIndex: 1, pageSize: 1000 }) 489 this.$pCall(workshopQueryApi, { pageIndex: 1, pageSize: 1000 })
475 ]) 490 ])
476 - var r1 = (results[0] && results[0].data) ? results[0].data : {}  
477 - var r2 = (results[1] && results[1].data) ? results[1].data : {} 491 + var r0 = (results[0] && results[0].data) ? results[0].data : {}
  492 + var r1 = (results[1] && results[1].data) ? results[1].data : {}
  493 + var r2 = (results[2] && results[2].data) ? results[2].data : {}
  494 + this.priceTableList = (r0.datas && Array.isArray(r0.datas)) ? r0.datas : ((r0.list && Array.isArray(r0.list)) ? r0.list : ((r0.records && Array.isArray(r0.records)) ? r0.records : []))
478 this.productOptions = (r1.datas && Array.isArray(r1.datas)) ? r1.datas : ((r1.list && Array.isArray(r1.list)) ? r1.list : ((r1.records && Array.isArray(r1.records)) ? r1.records : [])) 495 this.productOptions = (r1.datas && Array.isArray(r1.datas)) ? r1.datas : ((r1.list && Array.isArray(r1.list)) ? r1.list : ((r1.records && Array.isArray(r1.records)) ? r1.records : []))
479 this.workshopOptions = (r2.datas && Array.isArray(r2.datas)) ? r2.datas : ((r2.list && Array.isArray(r2.list)) ? r2.list : ((r2.records && Array.isArray(r2.records)) ? r2.records : [])) 496 this.workshopOptions = (r2.datas && Array.isArray(r2.datas)) ? r2.datas : ((r2.list && Array.isArray(r2.list)) ? r2.list : ((r2.records && Array.isArray(r2.records)) ? r2.records : []))
480 this.fillLineNames() 497 this.fillLineNames()
481 } catch (e) { 498 } catch (e) {
  499 + this.priceTableList = []
482 this.productOptions = [] 500 this.productOptions = []
483 this.workshopOptions = [] 501 this.workshopOptions = []
484 } 502 }
@@ -733,6 +751,7 @@ export default { @@ -733,6 +751,7 @@ export default {
733 try { 751 try {
734 uni.setStorageSync('DOMESTIC_PLAN_LIST_NEED_REFRESH', '1') 752 uni.setStorageSync('DOMESTIC_PLAN_LIST_NEED_REFRESH', '1')
735 uni.setStorageSync('SUPPLE_PLAN_LIST_NEED_REFRESH', '1') 753 uni.setStorageSync('SUPPLE_PLAN_LIST_NEED_REFRESH', '1')
  754 + uni.setStorageSync('DOMESTIC_PLAN_DETAIL_NEED_REFRESH', '1')
736 } catch (e) {} 755 } catch (e) {}
737 var self = this 756 var self = this
738 setTimeout(function () { 757 setTimeout(function () {
@@ -536,7 +536,7 @@ export default { @@ -536,7 +536,7 @@ export default {
536 this.buildAttachmentList() 536 this.buildAttachmentList()
537 this.fillLineNames() 537 this.fillLineNames()
538 this.refreshLinesFromShipping() 538 this.refreshLinesFromShipping()
539 - this.loadLatestPriceTableAndApply() 539 + this.fillPriceTableFromDetail(d)
540 } catch (e) { 540 } catch (e) {
541 uni.showToast({ title: '加载报价单失败', icon: 'none' }) 541 uni.showToast({ title: '加载报价单失败', icon: 'none' })
542 } 542 }
@@ -544,15 +544,19 @@ export default { @@ -544,15 +544,19 @@ export default {
544 async loadRefData() { 544 async loadRefData() {
545 try { 545 try {
546 var results = await Promise.all([ 546 var results = await Promise.all([
  547 + this.$pCall(priceTableQueryApi, { pageIndex: 1, pageSize: 1000 }),
547 this.$pCall(breedRelationshipQueryApi, { pageIndex: 1, pageSize: 1000 }), 548 this.$pCall(breedRelationshipQueryApi, { pageIndex: 1, pageSize: 1000 }),
548 this.$pCall(workshopQueryApi, { pageIndex: 1, pageSize: 1000 }) 549 this.$pCall(workshopQueryApi, { pageIndex: 1, pageSize: 1000 })
549 ]) 550 ])
550 - var r1 = (results[0] && results[0].data) ? results[0].data : {}  
551 - var r2 = (results[1] && results[1].data) ? results[1].data : {} 551 + var r0 = (results[0] && results[0].data) ? results[0].data : {}
  552 + var r1 = (results[1] && results[1].data) ? results[1].data : {}
  553 + var r2 = (results[2] && results[2].data) ? results[2].data : {}
  554 + this.priceTableList = (r0.datas && Array.isArray(r0.datas)) ? r0.datas : ((r0.list && Array.isArray(r0.list)) ? r0.list : ((r0.records && Array.isArray(r0.records)) ? r0.records : []))
552 this.productOptions = (r1.datas && Array.isArray(r1.datas)) ? r1.datas : ((r1.list && Array.isArray(r1.list)) ? r1.list : ((r1.records && Array.isArray(r1.records)) ? r1.records : [])) 555 this.productOptions = (r1.datas && Array.isArray(r1.datas)) ? r1.datas : ((r1.list && Array.isArray(r1.list)) ? r1.list : ((r1.records && Array.isArray(r1.records)) ? r1.records : []))
553 this.workshopOptions = (r2.datas && Array.isArray(r2.datas)) ? r2.datas : ((r2.list && Array.isArray(r2.list)) ? r2.list : ((r2.records && Array.isArray(r2.records)) ? r2.records : [])) 556 this.workshopOptions = (r2.datas && Array.isArray(r2.datas)) ? r2.datas : ((r2.list && Array.isArray(r2.list)) ? r2.list : ((r2.records && Array.isArray(r2.records)) ? r2.records : []))
554 this.fillLineNames() 557 this.fillLineNames()
555 } catch (e) { 558 } catch (e) {
  559 + this.priceTableList = []
556 this.productOptions = [] 560 this.productOptions = []
557 this.workshopOptions = [] 561 this.workshopOptions = []
558 } 562 }
@@ -621,6 +625,35 @@ export default { @@ -621,6 +625,35 @@ export default {
621 this.fetchPriceDetailAndApply(this.form.priceTableId) 625 this.fetchPriceDetailAndApply(this.form.priceTableId)
622 } 626 }
623 }, 627 },
  628 + fillPriceTableFromDetail(d) {
  629 + var detail = d || this.detail || {}
  630 + var code = detail.priceTableCode != null ? detail.priceTableCode : (detail.priceId != null ? detail.priceId : (detail.priceTableId != null ? detail.priceTableId : ''))
  631 + if (!code) return
  632 + var sc = String(code)
  633 + var list = Array.isArray(this.priceTableList) ? this.priceTableList : []
  634 + var matched = null
  635 + for (var i = 0; i < list.length; i++) {
  636 + var o = list[i]
  637 + var id = String(o.id || o.priceId || o.value || '')
  638 + var c = String(o.priceTableCode || o.code || o.priceCode || '')
  639 + if (id === sc || c === sc) {
  640 + matched = o
  641 + break
  642 + }
  643 + }
  644 + if (matched) {
  645 + this.selectPriceTableRow(matched)
  646 + return
  647 + }
  648 + this.form.priceTableId = detail.priceId != null ? detail.priceId : (detail.priceTableId != null ? detail.priceTableId : sc)
  649 + this.form.priceTableCode = detail.priceTableCode != null ? detail.priceTableCode : sc
  650 + var name = detail.priceTableName != null ? detail.priceTableName : ''
  651 + var cd = detail.priceTableCode != null ? detail.priceTableCode : sc
  652 + this.form.priceTableCodeLabel = name ? (name + (cd ? ' (' + cd + ')' : '')) : cd
  653 + if (this.form.priceTableId) {
  654 + this.fetchPriceDetailAndApply(this.form.priceTableId)
  655 + }
  656 + },
624 async loadLatestPriceTableAndApply() { 657 async loadLatestPriceTableAndApply() {
625 var self = this 658 var self = this
626 try { 659 try {
@@ -927,6 +960,7 @@ export default { @@ -927,6 +960,7 @@ export default {
927 try { 960 try {
928 uni.setStorageSync('DOMESTIC_PLAN_LIST_NEED_REFRESH', '1') 961 uni.setStorageSync('DOMESTIC_PLAN_LIST_NEED_REFRESH', '1')
929 uni.setStorageSync('SUPPLE_PLAN_LIST_NEED_REFRESH', '1') 962 uni.setStorageSync('SUPPLE_PLAN_LIST_NEED_REFRESH', '1')
  963 + uni.setStorageSync('DOMESTIC_PLAN_DETAIL_NEED_REFRESH', '1')
930 } catch (e) {} 964 } catch (e) {}
931 var self = this 965 var self = this
932 setTimeout(function () { 966 setTimeout(function () {
@@ -152,7 +152,6 @@ @@ -152,7 +152,6 @@
152 152
153 <script> 153 <script>
154 import { buyoutApplyDetailByPlanIdApi } from '@/api/procure-manage/buyout.js' 154 import { buyoutApplyDetailByPlanIdApi } from '@/api/procure-manage/buyout.js'
155 -import { procurementPlanDetailApi } from '@/api/procure-manage/procurementPlan.js'  
156 import { breedRelationshipQueryApi } from '@/api/devManage.js' 155 import { breedRelationshipQueryApi } from '@/api/devManage.js'
157 156
158 export default { 157 export default {
@@ -160,15 +159,16 @@ export default { @@ -160,15 +159,16 @@ export default {
160 data() { 159 data() {
161 return { 160 return {
162 planId: '', 161 planId: '',
163 - planData: {},  
164 buyoutData: null, 162 buyoutData: null,
165 breedOptions: [], 163 breedOptions: [],
166 main: { 164 main: {
167 code: '', 165 code: '',
168 supplierName: '', 166 supplierName: '',
169 purchaseDepartment: '', 167 purchaseDepartment: '',
  168 + purchaseDepartmentName: '',
170 purchaseDepartmentId: '', 169 purchaseDepartmentId: '',
171 region: '', 170 region: '',
  171 + regionName: '',
172 regionId: '', 172 regionId: '',
173 date: '', 173 date: '',
174 shippingCost: '', 174 shippingCost: '',
@@ -186,29 +186,27 @@ export default { @@ -186,29 +186,27 @@ export default {
186 computed: { 186 computed: {
187 purchaseDepartmentDisplay() { 187 purchaseDepartmentDisplay() {
188 var m = this.main || {} 188 var m = this.main || {}
189 - var p = this.planData || {}  
190 - var v1 = m.purchaseDepartment != null ? String(m.purchaseDepartment) : ''  
191 - var v2 = p.purchaseDepartmentName != null ? String(p.purchaseDepartmentName) : (p.purchaseDepartment != null ? String(p.purchaseDepartment) : '')  
192 - return v1 ? v1 : v2 189 + var v = m.purchaseDepartmentName != null ? m.purchaseDepartmentName : (m.purchaseDepartment != null ? m.purchaseDepartment : '')
  190 + v = v != null ? String(v) : ''
  191 + return v
193 }, 192 },
194 regionDisplay() { 193 regionDisplay() {
195 var m = this.main || {} 194 var m = this.main || {}
196 - var p = this.planData || {}  
197 - var v1 = m.region != null ? String(m.region) : ''  
198 - var v2 = p.regionName != null ? String(p.regionName) : (p.region != null ? String(p.region) : '')  
199 - return v1 ? v1 : v2 195 + var v = m.regionName != null ? m.regionName : (m.region != null ? m.region : '')
  196 + v = v != null ? String(v) : ''
  197 + return v
200 }, 198 },
201 dateDisplay() { 199 dateDisplay() {
202 - var s = String(this.main.date || (this.planData.date || '')).trim() 200 + var s = String(this.main.date || '').trim()
203 if (!s) return '' 201 if (!s) return ''
204 return s.length >= 10 ? s.slice(0, 10) : s 202 return s.length >= 10 ? s.slice(0, 10) : s
205 }, 203 },
206 shippingCostDisplay() { 204 shippingCostDisplay() {
207 - var v = this.toNumber(this.main.shippingCost != null ? this.main.shippingCost : this.planData.shippingCost) 205 + var v = this.toNumber(this.main.shippingCost)
208 return v === 0 ? '0.00' : v.toFixed(2) 206 return v === 0 ? '0.00' : v.toFixed(2)
209 }, 207 },
210 loadingFeeDisplay() { 208 loadingFeeDisplay() {
211 - var v = this.toNumber(this.main.loadingFee != null ? this.main.loadingFee : this.planData.loadingFee) 209 + var v = this.toNumber(this.main.loadingFee)
212 return v === 0 ? '0.00' : v.toFixed(2) 210 return v === 0 ? '0.00' : v.toFixed(2)
213 }, 211 },
214 paintLossRatioDisplay() { 212 paintLossRatioDisplay() {
@@ -260,6 +258,19 @@ export default { @@ -260,6 +258,19 @@ export default {
260 var s = v == null ? '' : String(v) 258 var s = v == null ? '' : String(v)
261 return s.trim() ? s : '-' 259 return s.trim() ? s : '-'
262 }, 260 },
  261 + pickValue(obj, keys, defaultValue) {
  262 + var source = obj || {}
  263 + var list = Array.isArray(keys) ? keys : [keys]
  264 + for (var i = 0; i < list.length; i++) {
  265 + var key = list[i]
  266 + if (source[key] != null && source[key] !== '') return source[key]
  267 + }
  268 + return defaultValue
  269 + },
  270 + pickArray(obj, keys) {
  271 + var arr = this.pickValue(obj, keys, [])
  272 + return Array.isArray(arr) ? arr : []
  273 + },
263 async loadAll() { 274 async loadAll() {
264 var self = this 275 var self = this
265 try { 276 try {
@@ -317,54 +328,53 @@ export default { @@ -317,54 +328,53 @@ export default {
317 }, 328 },
318 async loadPlanAndApply() { 329 async loadPlanAndApply() {
319 var self = this 330 var self = this
320 - var planRes = null  
321 - var plan = {}  
322 - if (this.planId) {  
323 - try { planRes = await procurementPlanDetailApi({ id: this.planId }) } catch (e) { planRes = null }  
324 - plan = (planRes && planRes.data) ? planRes.data : {}  
325 - this.planData = plan || {}  
326 - }  
327 var buyout = null 331 var buyout = null
328 if (this.planId) { 332 if (this.planId) {
329 try { 333 try {
330 var bRes = await buyoutApplyDetailByPlanIdApi(this.planId) 334 var bRes = await buyoutApplyDetailByPlanIdApi(this.planId)
  335 + console.log('buyoutApplyDetailByPlanIdApi', bRes)
331 if (bRes && (bRes.data != null || (bRes.code && bRes.code === 200))) { 336 if (bRes && (bRes.data != null || (bRes.code && bRes.code === 200))) {
332 - buyout = bRes.data ? bRes.data : {} 337 + buyout = bRes.data ? bRes.data : null
333 if (buyout && (buyout.id || buyout.code || (Array.isArray(buyout.procurementBuyoutApplyLineList) && buyout.procurementBuyoutApplyLineList.length))) { 338 if (buyout && (buyout.id || buyout.code || (Array.isArray(buyout.procurementBuyoutApplyLineList) && buyout.procurementBuyoutApplyLineList.length))) {
334 this.buyoutData = buyout 339 this.buyoutData = buyout
  340 + } else {
  341 + this.buyoutData = null
335 } 342 }
336 } 343 }
337 } catch (e) { 344 } catch (e) {
338 buyout = null 345 buyout = null
339 } 346 }
340 } 347 }
341 - this.buildMain(plan, buyout)  
342 - this.buildLineList(plan, buyout) 348 + this.buildMain(buyout)
  349 + this.buildLineList(buyout)
343 }, 350 },
344 - buildMain(plan, buyout) { 351 + buildMain(buyout) {
345 var b = buyout || {} 352 var b = buyout || {}
346 - var p = plan || {}  
347 - var code = b.code || p.code || ''  
348 - var supplierName = b.supplierName != null ? b.supplierName : (p.supplierName != null ? p.supplierName : '')  
349 - var pd = b.purchaseDepartment != null ? b.purchaseDepartment : (p.purchaseDepartmentName != null ? p.purchaseDepartmentName : p.purchaseDepartment)  
350 - var pdId = b.purchaseDepartmentId != null ? b.purchaseDepartmentId : (p.purchaseDepartmentId != null ? p.purchaseDepartmentId : p.purchaseDepartment)  
351 - var region = b.region != null ? b.region : (p.regionName != null ? p.regionName : p.region)  
352 - var regionId = b.regionId != null ? b.regionId : (p.regionId != null ? p.regionId : p.region)  
353 - var date = b.date != null ? b.date : p.date  
354 - var shippingCost = b.shippingCost != null ? b.shippingCost : (p.shippingCost != null ? p.shippingCost : '')  
355 - var appearanceDesc = b.appearanceDesc != null ? b.appearanceDesc : '厂家生产过程中报废的一手料'  
356 - var materialQualityDesc = b.materialQualityDesc != null ? b.materialQualityDesc : '料质清爽'  
357 - var impurityDesc = b.impurityDesc != null ? b.impurityDesc : '含少量杂质'  
358 - var oilWaterDesc = b.oilWaterDesc != null ? b.oilWaterDesc : ''  
359 - var loadingFee = b.loadingFee != null ? b.loadingFee : (p.loadingFee != null ? p.loadingFee : '')  
360 - var buyoutReason = b.buyoutReason != null ? b.buyoutReason : ''  
361 - var paintLossRatio = b.paintLossRatio != null ? b.paintLossRatio : (p.paintLossRatio != null ? p.paintLossRatio : '') 353 + var code = this.pickValue(b, ['code'], '')
  354 + var supplierName = this.pickValue(b, ['supplierName', 'supplier'], '')
  355 + var pd = this.pickValue(b, ['purchaseDepartment'], '')
  356 + var pdName = this.pickValue(b, ['purchaseDepartmentName'], '')
  357 + var pdId = this.pickValue(b, ['purchaseDepartmentId'], '')
  358 + var region = this.pickValue(b, ['region'], '')
  359 + var regionName = this.pickValue(b, ['regionName'], '')
  360 + var regionId = this.pickValue(b, ['regionId'], '')
  361 + var date = this.pickValue(b, ['date'], '')
  362 + var shippingCost = this.pickValue(b, ['shippingCost'], '')
  363 + var appearanceDesc = this.pickValue(b, ['appearanceDesc'], '')
  364 + var materialQualityDesc = this.pickValue(b, ['materialQualityDesc'], '')
  365 + var impurityDesc = this.pickValue(b, ['impurityDesc'], '')
  366 + var oilWaterDesc = this.pickValue(b, ['oilWaterDesc'], '')
  367 + var loadingFee = this.pickValue(b, ['loadingFee'], '')
  368 + var buyoutReason = this.pickValue(b, ['buyoutReason'], '')
  369 + var paintLossRatio = this.pickValue(b, ['paintLossRatio'], '')
362 this.main = { 370 this.main = {
363 code: code, 371 code: code,
364 supplierName: supplierName, 372 supplierName: supplierName,
365 purchaseDepartment: pd, 373 purchaseDepartment: pd,
  374 + purchaseDepartmentName: pdName,
366 purchaseDepartmentId: pdId, 375 purchaseDepartmentId: pdId,
367 region: region, 376 region: region,
  377 + regionName: regionName,
368 regionId: regionId, 378 regionId: regionId,
369 date: date, 379 date: date,
370 shippingCost: shippingCost, 380 shippingCost: shippingCost,
@@ -377,50 +387,54 @@ export default { @@ -377,50 +387,54 @@ export default {
377 paintLossRatio: paintLossRatio 387 paintLossRatio: paintLossRatio
378 } 388 }
379 }, 389 },
380 - buildLineList(plan, buyout) { 390 + buildLineList(buyout) {
381 var self = this 391 var self = this
382 var lines = [] 392 var lines = []
383 - var bLines = (buyout && buyout.procurementBuyoutApplyLineList && Array.isArray(buyout.procurementBuyoutApplyLineList)) ? buyout.procurementBuyoutApplyLineList : null  
384 - var pLines = (plan && plan.procurementPlanLineList && Array.isArray(plan.procurementPlanLineList)) ? plan.procurementPlanLineList.slice() : []  
385 - if (bLines && bLines.length) {  
386 - lines = bLines  
387 - } else {  
388 - lines = pLines  
389 - }  
390 - var shippingCost = this.toNumber(this.main.shippingCost != null ? this.main.shippingCost : this.planData.shippingCost)  
391 - var loadingFee = this.toNumber(this.main.loadingFee != null ? this.main.loadingFee : this.planData.loadingFee)  
392 - var defaultPaintLossRatio = this.toNumber(this.main.paintLossRatio != null ? this.main.paintLossRatio : this.planData.paintLossRatio) 393 + var bLines = this.pickArray(buyout, ['lineList', 'procurementBuyoutApplyLineList'])
  394 + lines = bLines
  395 + var shippingCost = this.toNumber(this.main.shippingCost)
  396 + var loadingFee = this.toNumber(this.main.loadingFee)
  397 + var defaultPaintLossRatio = this.toNumber(this.main.paintLossRatio)
393 this.lineList = lines.map(function (r, i) { 398 this.lineList = lines.map(function (r, i) {
394 var row = r || {} 399 var row = r || {}
395 - var productId = row.productId 400 + var productId = self.pickValue(row, ['productId', 'breedId'], '')
  401 + var productName = self.pickValue(row, ['productName', 'productIdName', 'breedName'], '')
  402 + var actualPurchase = self.pickValue(row, ['actualPurchasePrice', 'buyoutPrice'], 0)
  403 + var buyoutPrice = self.pickValue(row, ['buyoutPrice', 'actualPurchasePrice'], 0)
  404 + var estimatedLoss = self.pickValue(row, ['estimatedLoss'], 0)
  405 + var includingShippingPrice = self.pickValue(row, ['includingShippingPrice'], '')
  406 + var priceListPrices = self.pickValue(row, ['priceListPrices'], '')
  407 + var coordinationRange = self.pickValue(row, ['coordinationRange'], '')
  408 + var applicationAttrition = self.pickValue(row, ['applicationAttrition'], '')
  409 + var workshopName = self.pickValue(row, ['workshopName', 'workshopIdName'], '')
396 var breedPaintLossRatio = self.getPaintLossRatioFromBreed(productId, defaultPaintLossRatio) 410 var breedPaintLossRatio = self.getPaintLossRatioFromBreed(productId, defaultPaintLossRatio)
397 - var withPaint = self.isWithPaintByBreed(productId, row.productName, breedPaintLossRatio) 411 + var withPaint = self.isWithPaintByBreed(productId, productName, breedPaintLossRatio)
398 var ratio = withPaint ? breedPaintLossRatio : 0 412 var ratio = withPaint ? breedPaintLossRatio : 0
399 var ratioFrac = ratio / 100 413 var ratioFrac = ratio / 100
400 if (ratioFrac < 0) ratioFrac = 0 414 if (ratioFrac < 0) ratioFrac = 0
401 if (ratioFrac >= 1) ratioFrac = 0.9999 415 if (ratioFrac >= 1) ratioFrac = 0.9999
402 - var actualPurchase = row.actualPurchasePrice != null ? row.actualPurchasePrice : (row.buyoutPrice != null ? row.buyoutPrice : 0)  
403 - var buyoutPrice = row.buyoutPrice != null ? row.buyoutPrice : actualPurchase  
404 - var estimatedLoss = row.estimatedLoss != null ? row.estimatedLoss : 0  
405 var divisor = 1 - ratioFrac 416 var divisor = 1 - ratioFrac
406 var base = divisor > 0 ? (self.toNumber(actualPurchase) / divisor) : self.toNumber(actualPurchase) 417 var base = divisor > 0 ? (self.toNumber(actualPurchase) / divisor) : self.toNumber(actualPurchase)
407 var pureCopperPrice = base + shippingCost + self.toNumber(estimatedLoss) + loadingFee 418 var pureCopperPrice = base + shippingCost + self.toNumber(estimatedLoss) + loadingFee
408 return { 419 return {
409 _key: row._key || row.id || ('row-' + i + '-' + Date.now()), 420 _key: row._key || row.id || ('row-' + i + '-' + Date.now()),
410 productId: productId, 421 productId: productId,
411 - productName: row.productName || '',  
412 - materialType: row.materialType || '',  
413 - quantity: row.quantity != null ? row.quantity : 0, 422 + productName: productName,
  423 + materialType: self.pickValue(row, ['materialType'], ''),
  424 + quantity: self.pickValue(row, ['quantity'], 0),
  425 + actualPurchasePrice: actualPurchase,
  426 + includingShippingPrice: includingShippingPrice,
  427 + priceListPrices: priceListPrices,
  428 + coordinationRange: coordinationRange,
414 buyoutPrice: buyoutPrice, 429 buyoutPrice: buyoutPrice,
415 estimatedLoss: estimatedLoss, 430 estimatedLoss: estimatedLoss,
  431 + applicationAttrition: applicationAttrition,
  432 + workshopName: workshopName,
416 paintLossRatio: ratio, 433 paintLossRatio: ratio,
417 withPaint: !!withPaint, 434 withPaint: !!withPaint,
418 pureCopperPrice: pureCopperPrice 435 pureCopperPrice: pureCopperPrice
419 } 436 }
420 }) 437 })
421 - if (!this.main.paintLossRatio && defaultPaintLossRatio > 0) {  
422 - this.main.paintLossRatio = defaultPaintLossRatio  
423 - }  
424 } 438 }
425 } 439 }
426 } 440 }
@@ -71,7 +71,7 @@ @@ -71,7 +71,7 @@
71 <script> 71 <script>
72 import DetailButtons from '@/components/detail-buttons/index.vue' 72 import DetailButtons from '@/components/detail-buttons/index.vue'
73 import ProductRel from './productRel.vue' 73 import ProductRel from './productRel.vue'
74 -import { salesmanQuotationDetailApi, salesmanQuotationCancelApi } from '@/api/procure-manage/salesmanQuotation.js' 74 +import { salesmanQuotationDetailApi, salesmanQuotationCancelApi, salesmanQuotationCreatePlanApi } from '@/api/procure-manage/salesmanQuotation.js'
75 import { getDicByCodes } from '@/utils/dic.js' 75 import { getDicByCodes } from '@/utils/dic.js'
76 import { getInfo } from '@/api/login.js' 76 import { getInfo } from '@/api/login.js'
77 export default { 77 export default {
@@ -113,7 +113,7 @@ export default { @@ -113,7 +113,7 @@ export default {
113 { ...this.buttons[0], visible: (s === 'REFUSE' && c === this.investigatorId && this.$auth.hasPermi('procure-manage:sales-price:modify')) }, 113 { ...this.buttons[0], visible: (s === 'REFUSE' && c === this.investigatorId && this.$auth.hasPermi('procure-manage:sales-price:modify')) },
114 { ...this.buttons[1], visible: this.$auth.hasPermi('procure-manage:sales-price:copy') }, 114 { ...this.buttons[1], visible: this.$auth.hasPermi('procure-manage:sales-price:copy') },
115 { ...this.buttons[2], visible: (s === 'REFUSE' && c === this.investigatorId && this.$auth.hasPermi('procure-manage:sales-price:cancel')) }, 115 { ...this.buttons[2], visible: (s === 'REFUSE' && c === this.investigatorId && this.$auth.hasPermi('procure-manage:sales-price:cancel')) },
116 - { ...this.buttons[3], visible: (p === 'DEAL_CLOSED' && this.$auth.hasPermi('procure-manage:sales-price:create')) }, 116 + { ...this.buttons[3], visible: (p === 'DEAL_CLOSED' && this.form.generatedPlan === false && c === this.investigatorId && this.$auth.hasPermi('procure-manage:sales-price:create')) },
117 { ...this.buttons[4], visible: (s === 'AUDIT' && this.form.showExamine && this.$auth.hasPermi('procure-manage:sales-price:approves')) }, 117 { ...this.buttons[4], visible: (s === 'AUDIT' && this.form.showExamine && this.$auth.hasPermi('procure-manage:sales-price:approves')) },
118 { ...this.buttons[5], visible: (this.form.showExamineDetail && this.$auth.hasPermi('procure-manage:sales-price:view')) }, 118 { ...this.buttons[5], visible: (this.form.showExamineDetail && this.$auth.hasPermi('procure-manage:sales-price:view')) },
119 ] 119 ]
@@ -131,7 +131,7 @@ export default { @@ -131,7 +131,7 @@ export default {
131 async getUserInfo() { 131 async getUserInfo() {
132 getInfo() 132 getInfo()
133 .then((res) => { 133 .then((res) => {
134 - this.investigatorId = res?.id || ''; 134 + this.investigatorId = res?.data?.id || '';
135 }) 135 })
136 .catch((err) => { 136 .catch((err) => {
137 console.error('获取用户信息失败:', err); 137 console.error('获取用户信息失败:', err);
@@ -197,7 +197,9 @@ export default { @@ -197,7 +197,9 @@ export default {
197 if (e === 'approve') return this.onApprove() 197 if (e === 'approve') return this.onApprove()
198 if (e === 'approveDetail') return this.onApproveDetail() 198 if (e === 'approveDetail') return this.onApproveDetail()
199 if (e === 'cancel') return this.onCancel() 199 if (e === 'cancel') return this.onCancel()
  200 + if (e === 'plan') return this.onPlan()
200 }, 201 },
  202 +
201 onEdit() { 203 onEdit() {
202 uni.navigateTo({ url: '/pages/sales-price/modify?id=' + this.id }) 204 uni.navigateTo({ url: '/pages/sales-price/modify?id=' + this.id })
203 }, 205 },
@@ -225,6 +227,60 @@ export default { @@ -225,6 +227,60 @@ export default {
225 } 227 }
226 }) 228 })
227 }, 229 },
  230 + refreshListFlags() {
  231 + try {
  232 + uni.setStorageSync('SALES_PRICE_LIST_NEED_REFRESH', '1')
  233 + } catch (e) {}
  234 + },
  235 + runWithConfirm(opts) {
  236 + var self = this
  237 + var title = opts.title || '提示'
  238 + var content = opts.content || ''
  239 + var run = opts.run
  240 + var loading = opts.loading || '处理中'
  241 + var successText = opts.successText || '操作成功'
  242 + var failText = opts.failText || '操作失败'
  243 + if (!this.id) {
  244 + uni.showToast({ title: '缺少单据id', icon: 'none' })
  245 + return
  246 + }
  247 + var apiFn = function () {
  248 + uni.showLoading({ title: loading, mask: true })
  249 + Promise.resolve(run(self.id)).then(function () {
  250 + uni.hideLoading()
  251 + uni.showToast({ title: successText, icon: 'none' })
  252 + self.refreshListFlags()
  253 + self.loadDetail()
  254 + }).catch(function (e) {
  255 + uni.hideLoading()
  256 + uni.showToast({ title: (e && (e.msg || e.message)) ? (e.msg || e.message) : failText, icon: 'none' })
  257 + })
  258 + }
  259 + if (opts.skipConfirm) {
  260 + apiFn()
  261 + return
  262 + }
  263 + uni.showModal({
  264 + title: title,
  265 + content: content,
  266 + confirmText: '确定',
  267 + cancelText: '取消',
  268 + success: function (res) {
  269 + if (!res || !res.confirm) return
  270 + apiFn()
  271 + }
  272 + })
  273 + },
  274 + onPlan() {
  275 + this.runWithConfirm({
  276 + title: '生成计划',
  277 + content: '确认生成采购计划吗?',
  278 + loading: '生成中',
  279 + successText: '生成计划成功',
  280 + failText: '生成计划失败',
  281 + run: function (id) { return salesmanQuotationCreatePlanApi({ id: id }) }
  282 + })
  283 + },
228 onApprove() { 284 onApprove() {
229 const id = this.id || (this.form && this.form.id) || '' 285 const id = this.id || (this.form && this.form.id) || ''
230 if (!id) return 286 if (!id) return
@@ -106,6 +106,7 @@ import { procurementPlanChangeFindByIdApi, procurementPlanChangeSubmitApi, procu @@ -106,6 +106,7 @@ import { procurementPlanChangeFindByIdApi, procurementPlanChangeSubmitApi, procu
106 import { breedRelationshipQueryApi, priceTableDetailApi, workshopQueryApi } from '@/api/devManage.js' 106 import { breedRelationshipQueryApi, priceTableDetailApi, workshopQueryApi } from '@/api/devManage.js'
107 import { getDicByCodes } from '@/utils/dic.js' 107 import { getDicByCodes } from '@/utils/dic.js'
108 import DetailButtons from '@/components/detail-buttons/index.vue' 108 import DetailButtons from '@/components/detail-buttons/index.vue'
  109 +import { getInfo } from '@/api/login.js'
109 export default { 110 export default {
110 name: 'SchedulePlanDetail', 111 name: 'SchedulePlanDetail',
111 components: { DetailButtons }, 112 components: { DetailButtons },
@@ -135,6 +136,7 @@ export default { @@ -135,6 +136,7 @@ export default {
135 { text: '审核', visible: true, variant: 'primary', event: 'approve' }, 136 { text: '审核', visible: true, variant: 'primary', event: 'approve' },
136 { text: '审核详情', visible: true, event: 'approveDetail' }, 137 { text: '审核详情', visible: true, event: 'approveDetail' },
137 ], 138 ],
  139 + investigatorId: '',
138 } 140 }
139 }, 141 },
140 computed: { 142 computed: {
@@ -187,8 +189,8 @@ export default { @@ -187,8 +189,8 @@ export default {
187 const isRefuse = status === 'REFUSE'; 189 const isRefuse = status === 'REFUSE';
188 const canExamine = isAudit && this.form && this.form.showExamine === true; 190 const canExamine = isAudit && this.form && this.form.showExamine === true;
189 return [ 191 return [
190 - { ...this.buttons[0], visible: ((isDraft || isRefuse) && this.$auth.hasPermi('plan-manage:schedule-plan:modify')) },  
191 - { ...this.buttons[1], visible: ((isDraft || isRefuse) && this.$auth.hasPermi('plan-manage:schedule-plan:initiate')) }, 192 + { ...this.buttons[0], visible: ((isDraft || isRefuse || !status) && this.investigatorId === this.form?.createById && this.$auth.hasPermi('plan-manage:schedule-plan:modify')) },
  193 + { ...this.buttons[1], visible: ((isDraft || isRefuse || !status) && this.investigatorId === this.form?.createById && this.$auth.hasPermi('plan-manage:schedule-plan:initiate')) },
192 { ...this.buttons[2], visible: (isRefuse && this.$auth.hasPermi('plan-manage:schedule-plan:cancel')) }, 194 { ...this.buttons[2], visible: (isRefuse && this.$auth.hasPermi('plan-manage:schedule-plan:cancel')) },
193 { ...this.buttons[3], visible: (canExamine && this.$auth.hasPermi('plan-manage:schedule-plan:approve')) }, 195 { ...this.buttons[3], visible: (canExamine && this.$auth.hasPermi('plan-manage:schedule-plan:approve')) },
194 { ...this.buttons[4], visible: ((isAudit || isPass) && this.form.showExamine && this.$auth.hasPermi('plan-manage:schedule-plan:view')) }, 196 { ...this.buttons[4], visible: ((isAudit || isPass) && this.form.showExamine && this.$auth.hasPermi('plan-manage:schedule-plan:view')) },
@@ -200,8 +202,18 @@ export default { @@ -200,8 +202,18 @@ export default {
200 this.loadDictData() 202 this.loadDictData()
201 this.loadRefData() 203 this.loadRefData()
202 this.loadDetail() 204 this.loadDetail()
  205 + this.getUserInfo()
203 }, 206 },
204 methods: { 207 methods: {
  208 + async getUserInfo() {
  209 + getInfo()
  210 + .then((res) => {
  211 + this.investigatorId = res?.data?.id || '';
  212 + })
  213 + .catch((err) => {
  214 + console.error('获取用户信息失败:', err);
  215 + });
  216 + },
205 handleButtonClick(btn) { 217 handleButtonClick(btn) {
206 if (!btn || btn.disabled) return 218 if (!btn || btn.disabled) return
207 const e = btn.event || '' 219 const e = btn.event || ''
1 <template> 1 <template>
2 <view class="detail-page"> 2 <view class="detail-page">
3 <scroll-view class="scroll" scroll-y> 3 <scroll-view class="scroll" scroll-y>
4 - <view class="section">  
5 - <text class="row company">{{ safeText(form.code) }}</text>  
6 - <view v-if="canEdit" class="row">  
7 - <text class="label required">公司名称</text>  
8 - <view class="value select-value" @click="openCompanySheet">  
9 - <text :class="form.companyShortName || form.companyName ? '' : 'placeholder'">{{ form.companyShortName || form.companyName || '请选择公司名称' }}</text>  
10 - <text class="arrow">›</text> 4 + <template v-if="isEditLayout">
  5 + <uni-list class="edit-list">
  6 + <uni-list-item class="select-item is-filled">
  7 + <template v-slot:body>
  8 + <view class="item-title"><text>编号</text></view>
  9 + </template>
  10 + <template v-slot:footer>
  11 + <view class="serial-number-row">
  12 + <text class="readonly-text value-code">{{ safeText(form.code) }}</text>
  13 + </view>
  14 + </template>
  15 + </uni-list-item>
  16 +
  17 + <uni-list-item
  18 + class="select-item"
  19 + :class="(form.companyShortName || form.companyName) ? 'is-filled' : 'is-empty'"
  20 + :clickable="canEdit"
  21 + :rightText="canEdit ? (form.companyShortName || form.companyName || '请选择公司名称') : ''"
  22 + :showArrow="canEdit"
  23 + @click="canEdit ? openCompanySheet() : undefined"
  24 + >
  25 + <template v-slot:body>
  26 + <view class="item-title">
  27 + <text class="required" v-if="canEdit">*</text><text>公司名称</text>
  28 + </view>
  29 + </template>
  30 + <template v-if="!canEdit" v-slot:footer>
  31 + <uni-easyinput :value="form.companyShortName || form.companyName" :inputBorder="false" disabled placeholder="-" />
  32 + </template>
  33 + </uni-list-item>
  34 +
  35 + <uni-list-item title="供应商名称">
  36 + <template v-slot:footer>
  37 + <uni-easyinput :value="form.supplierName" :inputBorder="false" disabled placeholder="-" />
  38 + </template>
  39 + </uni-list-item>
  40 +
  41 + <uni-list-item title="采购处">
  42 + <template v-slot:footer>
  43 + <uni-easyinput :value="purchaseDepartmentDisplay" :inputBorder="false" disabled placeholder="-" />
  44 + </template>
  45 + </uni-list-item>
  46 +
  47 + <uni-list-item title="区域">
  48 + <template v-slot:footer>
  49 + <uni-easyinput :value="regionDisplay" :inputBorder="false" disabled placeholder="-" />
  50 + </template>
  51 + </uni-list-item>
  52 +
  53 + <uni-list-item>
  54 + <template v-slot:body>
  55 + <view class="item-title">
  56 + <text class="required" v-if="canEdit">*</text><text>日期</text>
  57 + </view>
  58 + </template>
  59 + <template v-slot:footer>
  60 + <uni-datetime-picker v-if="canEdit" type="date" v-model="form.date" return-type="string" />
  61 + <uni-easyinput v-else :value="formatDateOnly(form.date)" :inputBorder="false" disabled placeholder="-" />
  62 + </template>
  63 + </uni-list-item>
  64 +
  65 + <uni-list-item title="报价时效">
  66 + <template v-slot:footer>
  67 + <uni-easyinput :value="form.validityPeriod" :inputBorder="false" disabled placeholder="-" />
  68 + </template>
  69 + </uni-list-item>
  70 +
  71 + <uni-list-item title="报价人">
  72 + <template v-slot:footer>
  73 + <uni-easyinput :value="form.quoterName" :inputBorder="false" disabled placeholder="-" />
  74 + </template>
  75 + </uni-list-item>
  76 +
  77 + <uni-list-item class="select-item" :class="typeof form.longTermOperation === 'boolean' ? 'is-filled' : 'is-empty'">
  78 + <template v-slot:body>
  79 + <view class="item-title"><text>是否长单操作</text></view>
  80 + </template>
  81 + <template v-slot:footer>
  82 + <text class="readonly-text">{{ boolText(form.longTermOperation) }}</text>
  83 + </template>
  84 + </uni-list-item>
  85 +
  86 + <uni-list-item class="select-item" :class="typeof form.terminalCustomer === 'boolean' ? 'is-filled' : 'is-empty'">
  87 + <template v-slot:body>
  88 + <view class="item-title"><text>是否终端客户</text></view>
  89 + </template>
  90 + <template v-slot:footer>
  91 + <text class="readonly-text">{{ boolText(form.terminalCustomer) }}</text>
  92 + </template>
  93 + </uni-list-item>
  94 +
  95 + <uni-list-item class="select-item" :class="typeof form.priced === 'boolean' ? 'is-filled' : 'is-empty'">
  96 + <template v-slot:body>
  97 + <view class="item-title"><text>是否未点价</text></view>
  98 + </template>
  99 + <template v-slot:footer>
  100 + <text class="readonly-text">{{ boolText(form.priced) }}</text>
  101 + </template>
  102 + </uni-list-item>
  103 +
  104 + <uni-list-item v-if="form.priced === true" title="点价截止日期">
  105 + <template v-slot:footer>
  106 + <uni-easyinput :value="pricingDeadlineDisplay" :inputBorder="false" disabled placeholder="-" />
  107 + </template>
  108 + </uni-list-item>
  109 +
  110 + <uni-list-item v-if="form.priced === true" class="select-item" :class="typeof form.temporaryPrice === 'boolean' ? 'is-filled' : 'is-empty'">
  111 + <template v-slot:body>
  112 + <view class="item-title"><text>是否暂定价</text></view>
  113 + </template>
  114 + <template v-slot:footer>
  115 + <text class="readonly-text">{{ boolText(form.temporaryPrice) }}</text>
  116 + </template>
  117 + </uni-list-item>
  118 +
  119 + <uni-list-item class="select-item" :class="typeof form.otherExpenseSettlement === 'boolean' ? 'is-filled' : 'is-empty'">
  120 + <template v-slot:body>
  121 + <view class="item-title"><text>其他费用凭票到厂另行结算</text></view>
  122 + </template>
  123 + <template v-slot:footer>
  124 + <text class="readonly-text">{{ boolText(form.otherExpenseSettlement) }}</text>
  125 + </template>
  126 + </uni-list-item>
  127 +
  128 + <uni-list-item class="select-item" :class="form.deliveryMode ? 'is-filled' : 'is-empty'">
  129 + <template v-slot:body>
  130 + <view class="item-title"><text>交提货方式</text></view>
  131 + </template>
  132 + <template v-slot:footer>
  133 + <text class="readonly-text">{{ getDeliveryMethodLabel() }}</text>
  134 + </template>
  135 + </uni-list-item>
  136 +
  137 + <uni-list-item class="select-item" :class="typeof form.commodityBuyout === 'boolean' ? 'is-filled' : 'is-empty'">
  138 + <template v-slot:body>
  139 + <view class="item-title"><text>是否通货买断</text></view>
  140 + </template>
  141 + <template v-slot:footer>
  142 + <text class="readonly-text">{{ boolText(form.commodityBuyout) }}</text>
  143 + </template>
  144 + </uni-list-item>
  145 +
  146 + <uni-list-item class="select-item" :class="typeof form.qualityBuyout === 'boolean' ? 'is-filled' : 'is-empty'">
  147 + <template v-slot:body>
  148 + <view class="item-title"><text>是否质量买断</text></view>
  149 + </template>
  150 + <template v-slot:footer>
  151 + <text class="readonly-text">{{ boolText(form.qualityBuyout) }}</text>
  152 + </template>
  153 + </uni-list-item>
  154 +
  155 + <uni-list-item class="select-item" :class="typeof form.quantityBuyout === 'boolean' ? 'is-filled' : 'is-empty'">
  156 + <template v-slot:body>
  157 + <view class="item-title"><text>是否数量买断</text></view>
  158 + </template>
  159 + <template v-slot:footer>
  160 + <text class="readonly-text">{{ boolText(form.quantityBuyout) }}</text>
  161 + </template>
  162 + </uni-list-item>
  163 +
  164 + <uni-list-item class="select-item" :class="typeof form.doorDelivery === 'boolean' ? 'is-filled' : 'is-empty'">
  165 + <template v-slot:body>
  166 + <view class="item-title"><text>是否送货上门</text></view>
  167 + </template>
  168 + <template v-slot:footer>
  169 + <text class="readonly-text">{{ boolText(form.doorDelivery) }}</text>
  170 + </template>
  171 + </uni-list-item>
  172 +
  173 + <uni-list-item title="另付运费">
  174 + <template v-slot:footer>
  175 + <uni-easyinput
  176 + v-if="canEdit"
  177 + v-model="form.shippingCost"
  178 + type="digit"
  179 + :inputBorder="false"
  180 + placeholder="请输入另付运费"
  181 + @input="onShippingCostInput"
  182 + @blur="onShippingCostBlur"
  183 + />
  184 + <uni-easyinput v-else :value="shippingCostDisplay" :inputBorder="false" disabled placeholder="-" />
  185 + </template>
  186 + </uni-list-item>
  187 +
  188 + <uni-list-item title="装车费">
  189 + <template v-slot:footer>
  190 + <uni-easyinput :value="loadingFeeDisplay" :inputBorder="false" disabled placeholder="-" />
  191 + </template>
  192 + </uni-list-item>
  193 +
  194 + <uni-list-item title="开票品名">
  195 + <template v-slot:footer>
  196 + <uni-easyinput :value="form.invoiceProductName" :inputBorder="false" disabled placeholder="-" />
  197 + </template>
  198 + </uni-list-item>
  199 +
  200 + <uni-list-item title="交货日期">
  201 + <template v-slot:footer>
  202 + <uni-easyinput :value="deliveryDateDisplay" :inputBorder="false" disabled placeholder="-" />
  203 + </template>
  204 + </uni-list-item>
  205 +
  206 + <uni-list-item title="结算方式">
  207 + <template v-slot:footer>
  208 + <uni-easyinput :value="form.settlementMethod" :inputBorder="false" disabled placeholder="-" />
  209 + </template>
  210 + </uni-list-item>
  211 +
  212 + <uni-list-item title="结算比例(%)">
  213 + <template v-slot:footer>
  214 + <uni-easyinput :value="settlementRatioDisplay" :inputBorder="false" disabled placeholder="-" />
  215 + </template>
  216 + </uni-list-item>
  217 +
  218 + <uni-list-item
  219 + class="select-item"
  220 + :class="(form.priceTableId || form.priceTableCode) ? 'is-filled' : 'is-empty'"
  221 + :clickable="canEdit"
  222 + :rightText="canEdit ? (priceTableCodeLabel || '请选择价格表编号') : ''"
  223 + :showArrow="canEdit"
  224 + @click="canEdit ? openPriceTableSheet() : undefined"
  225 + >
  226 + <template v-slot:body>
  227 + <view class="item-title">
  228 + <text class="required" v-if="canEdit">*</text><text>价格表编号</text>
  229 + </view>
  230 + </template>
  231 + <template v-if="!canEdit" v-slot:footer>
  232 + <uni-easyinput :value="priceTableDisplay === '-' ? '' : priceTableDisplay" :inputBorder="false" disabled placeholder="-" />
  233 + </template>
  234 + </uni-list-item>
  235 +
  236 + <uni-list-item title="协调事由">
  237 + <template v-slot:footer>
  238 + <uni-easyinput :value="form.coordinationReason" :inputBorder="false" disabled placeholder="-" />
  239 + </template>
  240 + </uni-list-item>
  241 +
  242 + <uni-list-item title="票类状况">
  243 + <template v-slot:footer>
  244 + <uni-easyinput :value="form.invoiceTypeStatus" :inputBorder="false" disabled placeholder="-" />
  245 + </template>
  246 + </uni-list-item>
  247 +
  248 + <uni-list-item title="数量合计">
  249 + <template v-slot:footer>
  250 + <uni-easyinput :value="totalQuantityDisplay" :inputBorder="false" disabled placeholder="-" />
  251 + </template>
  252 + </uni-list-item>
  253 +
  254 + <uni-list-item v-if="attachmentList.length" title="附件">
  255 + <template v-slot:footer>
  256 + <view class="attach-list">
  257 + <view v-for="(at, idx) in attachmentList" :key="idx" class="attach-item">
  258 + <text class="attach-name">{{ at.name }}</text>
  259 + <text class="attach-view" @click.stop="onPreviewAttachment(at)">查看</text>
  260 + </view>
  261 + </view>
  262 + </template>
  263 + </uni-list-item>
  264 + </uni-list>
  265 +
  266 + <view class="title-header">
  267 + <image class="title-header_icon" src="/static/images/title.png" />
  268 + <span>明细信息</span>
  269 + </view>
  270 + <view v-if="lineListWithName.length" class="edit-line-list">
  271 + <view v-for="(line, idx) in lineListWithName" :key="line.itemId || idx" class="edit-line-block">
  272 + <view class="line-title">明细{{ idx + 1 }}</view>
  273 + <uni-list>
  274 + <uni-list-item title="品种">
  275 + <template v-slot:footer>
  276 + <uni-easyinput :value="line.productName" :inputBorder="false" disabled placeholder="-" />
  277 + </template>
  278 + </uni-list-item>
  279 + <uni-list-item title="料型">
  280 + <template v-slot:footer>
  281 + <uni-easyinput :value="line.materialType" :inputBorder="false" disabled placeholder="-" />
  282 + </template>
  283 + </uni-list-item>
  284 + <uni-list-item title="数量(吨)">
  285 + <template v-slot:footer>
  286 + <uni-easyinput :value="lineNumberDisplay(line.quantity)" :inputBorder="false" disabled placeholder="-" />
  287 + </template>
  288 + </uni-list-item>
  289 + <uni-list-item title="实际采购价">
  290 + <template v-slot:footer>
  291 + <uni-easyinput :value="lineNumberDisplay(line.actualPurchasePrice)" :inputBorder="false" disabled placeholder="-" />
  292 + </template>
  293 + </uni-list-item>
  294 + <uni-list-item title="含运到厂价">
  295 + <template v-slot:footer>
  296 + <uni-easyinput :value="lineNumberDisplay(line.includingShippingPrice)" :inputBorder="false" disabled placeholder="-" />
  297 + </template>
  298 + </uni-list-item>
  299 + <uni-list-item title="价格表价格">
  300 + <template v-slot:footer>
  301 + <uni-easyinput
  302 + v-if="canEdit"
  303 + v-model="line.priceListPrices"
  304 + type="digit"
  305 + :inputBorder="false"
  306 + placeholder="请输入价格表价格"
  307 + @input="onLinePriceInput(idx, $event)"
  308 + @blur="onLinePriceBlur(idx)"
  309 + />
  310 + <uni-easyinput v-else :value="lineNumberDisplay(line.priceListPrices)" :inputBorder="false" disabled placeholder="-" />
  311 + </template>
  312 + </uni-list-item>
  313 + <uni-list-item title="协调幅度">
  314 + <template v-slot:footer>
  315 + <uni-easyinput :value="lineNumberDisplay(line.coordinationRange)" :inputBorder="false" disabled placeholder="-" />
  316 + </template>
  317 + </uni-list-item>
  318 + <uni-list-item title="买断料预计损耗">
  319 + <template v-slot:footer>
  320 + <uni-easyinput :value="lineNumberDisplay(line.estimatedLoss)" :inputBorder="false" disabled placeholder="-" />
  321 + </template>
  322 + </uni-list-item>
  323 + <uni-list-item title="申请损耗(%)">
  324 + <template v-slot:footer>
  325 + <uni-easyinput :value="lineNumberDisplay(line.applicationAttrition)" :inputBorder="false" disabled placeholder="-" />
  326 + </template>
  327 + </uni-list-item>
  328 + <uni-list-item
  329 + class="select-item"
  330 + :class="line.workshopName ? 'is-filled' : 'is-empty'"
  331 + :clickable="canEditWorkshop"
  332 + :rightText="canEditWorkshop ? (line.workshopName || '请选择分厂') : ''"
  333 + :showArrow="canEditWorkshop"
  334 + @click="canEditWorkshop ? openWorkshopSheet(idx) : undefined"
  335 + >
  336 + <template v-slot:body>
  337 + <view class="item-title">
  338 + <text class="required" v-if="canEditWorkshop">*</text><text>选择分厂</text>
  339 + </view>
  340 + </template>
  341 + <template v-if="!canEditWorkshop" v-slot:footer>
  342 + <uni-easyinput :value="line.workshopName" :inputBorder="false" disabled placeholder="-" />
  343 + </template>
  344 + </uni-list-item>
  345 + </uni-list>
11 </view> 346 </view>
12 </view> 347 </view>
13 - <view v-else class="row"><text class="label">公司简称</text><text class="value">{{ safeText(form.companyShortName || form.companyName) }}</text></view>  
14 - <view class="row"><text class="label">供应商名称</text><text class="value">{{ safeText(form.supplierName) }}</text></view>  
15 - <view class="row"><text class="label">采购处</text><text class="value">{{ safeText(form.purchaseDepartmentName || form.purchaseDepartment) }}</text></view>  
16 - <view class="row"><text class="label">区域</text><text class="value">{{ safeText(form.regionName || form.region) }}</text></view>  
17 - <view v-if="canEdit" class="row">  
18 - <text class="label required">日期</text>  
19 - <view class="value date-value">  
20 - <uni-datetime-picker type="date" v-model="form.date" return-type="string" /> 348 + <view v-else class="section empty-tip">暂无明细</view>
  349 +
  350 + <view class="material-condition-section">
  351 + <view class="section-header">
  352 + <image class="opCollapse" src="/static/images/title.png" />
  353 + <text class="section-title">料质状况</text>
  354 + </view>
  355 + <view class="section-content">
  356 + <view class="form-row">
  357 + <text class="form-label">是否启用料质状况</text>
  358 + <text class="form-value">{{ boolText(form.materialConditionEnabled) }}</text>
  359 + </view>
  360 + <template v-if="form.materialConditionEnabled">
  361 + <view v-for="mc in materialConditionConfigs" :key="mc.field" class="material-group">
  362 + <text class="material-label">{{ mc.label }}</text>
  363 + <view class="tag-list">
  364 + <view v-for="opt in getDictOptions(mc.dictCode)" :key="opt.code" class="tag-btn" :class="{ active: isTagSelected(mc.field, opt.code) }">{{ opt.name }}</view>
  365 + </view>
  366 + </view>
  367 + </template>
21 </view> 368 </view>
22 </view> 369 </view>
23 - <view v-else class="row"><text class="label">日期</text><text class="value">{{ formatDateOnly(form.date) }}</text></view>  
24 - <view class="row"><text class="label">报价时效</text><text class="value">{{ safeText(form.validityPeriod) }}</text></view>  
25 - <view class="row"><text class="label">报价人</text><text class="value">{{ safeText(form.quoterName) }}</text></view>  
26 - <view class="row"><text class="label">是否长单操作</text><text class="value">{{ boolText(form.longTermOperation) }}</text></view>  
27 - <view class="row"><text class="label">是否终端客户</text><text class="value">{{ boolText(form.terminalCustomer) }}</text></view>  
28 - <view class="row"><text class="label">是否未点价</text><text class="value">{{ boolText(form.priced) }}</text></view>  
29 - <view v-if="form.priced === true" class="row"><text class="label">点价截止日期</text><text class="value">{{ formatDateOnly(form.pricingDeadline) }}</text></view>  
30 - <view v-if="form.priced === true" class="row"><text class="label">是否暂定价</text><text class="value">{{ boolText(form.temporaryPrice) }}</text></view>  
31 - <view class="row"><text class="label">其他费用凭票到厂另行结算</text><text class="value">{{ boolText(form.otherExpenseSettlement) }}</text></view>  
32 - <view class="row"><text class="label">交提货方式</text><text class="value">{{ getDeliveryMethodLabel() }}</text></view>  
33 - <view class="row"><text class="label">是否通货买断</text><text class="value">{{ boolText(form.commodityBuyout) }}</text></view>  
34 - <view class="row"><text class="label">是否质量买断</text><text class="value">{{ boolText(form.qualityBuyout) }}</text></view>  
35 - <view class="row"><text class="label">是否数量买断</text><text class="value">{{ boolText(form.quantityBuyout) }}</text></view>  
36 - <view class="row"><text class="label">是否送货上门</text><text class="value">{{ boolText(form.doorDelivery) }}</text></view>  
37 - <view class="row">  
38 - <text class="label">另付运费</text>  
39 - <input v-if="canEdit" class="value line-input" v-model="form.shippingCost" type="digit" placeholder="请输入" @input="onShippingCostInput" @blur="onShippingCostBlur" />  
40 - <text v-else class="value">{{ formatNumber(form.shippingCost) }}</text> 370 +
  371 + <view class="remark-section">
  372 + <view class="section-header">
  373 + <image class="opCollapse" src="/static/images/title.png" />
  374 + <text class="section-title">备注</text>
  375 + </view>
  376 + <view class="section-content">
  377 + <text class="remark-text">{{ safeText(form.remark) }}</text>
  378 + </view>
41 </view> 379 </view>
42 - <view class="row"><text class="label">装车费</text><text class="value">{{ formatNumber(form.loadingFee) }}</text></view>  
43 - <view class="row"><text class="label">开票品名</text><text class="value">{{ safeText(form.invoiceProductName) }}</text></view>  
44 - <view class="row"><text class="label">交货日期</text><text class="value">{{ formatDateOnly(form.deliveryDate) }}</text></view>  
45 - <view class="row"><text class="label">结算方式</text><text class="value">{{ safeText(form.settlementMethod) }}</text></view>  
46 - <view class="row"><text class="label">结算比例(%)</text><text class="value">{{ formatNumber(form.settlementRatio) }}</text></view>  
47 - <view class="row">  
48 - <text class="label" :class="{ required: canEdit }">价格表编号</text>  
49 - <view v-if="canEdit" class="value select-value" @click="openPriceTableSheet">  
50 - <text :class="priceTableCodeLabel ? '' : 'placeholder'">{{ priceTableCodeLabel || '请选择价格表编号' }}</text>  
51 - <text class="arrow">›</text> 380 +
  381 + <view class="remark-section">
  382 + <view class="section-header">
  383 + <image class="opCollapse" src="/static/images/title.png" />
  384 + <text class="section-title">变更事由</text>
  385 + </view>
  386 + <view class="section-content">
  387 + <text class="remark-text">{{ safeText(form.changeReason) }}</text>
52 </view> 388 </view>
53 - <text v-else class="value">{{ priceTableDisplay }}</text>  
54 </view> 389 </view>
55 - <view class="row"><text class="label">协调事由</text><text class="value">{{ safeText(form.coordinationReason) }}</text></view>  
56 - <view class="row"><text class="label">票类状况</text><text class="value">{{ safeText(form.invoiceTypeStatus) }}</text></view>  
57 - <view class="row"><text class="label">数量合计</text><text class="value">{{ formatNumber(form.totalQuantity) }}</text></view>  
58 - <view class="row" v-if="attachmentList.length">  
59 - <text class="label">附件</text>  
60 - <view class="attach-list">  
61 - <view v-for="(at, idx) in attachmentList" :key="idx" class="attach-item">  
62 - <text class="attach-name">{{ at.name }}</text>  
63 - <text class="attach-view" @click.stop="onPreviewAttachment(at)">查看</text> 390 + </template>
  391 +
  392 + <template v-else>
  393 + <view class="section">
  394 + <text class="row company">{{ safeText(form.code) }}</text>
  395 + <view class="row"><text class="label">公司简称</text><text class="value">{{ safeText(form.companyShortName || form.companyName) }}</text></view>
  396 + <view class="row"><text class="label">供应商名称</text><text class="value">{{ safeText(form.supplierName) }}</text></view>
  397 + <view class="row"><text class="label">采购处</text><text class="value">{{ safeText(form.purchaseDepartmentName || form.purchaseDepartment) }}</text></view>
  398 + <view class="row"><text class="label">区域</text><text class="value">{{ safeText(form.regionName || form.region) }}</text></view>
  399 + <view class="row"><text class="label">日期</text><text class="value">{{ formatDateOnly(form.date) }}</text></view>
  400 + <view class="row"><text class="label">报价时效</text><text class="value">{{ safeText(form.validityPeriod) }}</text></view>
  401 + <view class="row"><text class="label">报价人</text><text class="value">{{ safeText(form.quoterName) }}</text></view>
  402 + <view class="row"><text class="label">是否长单操作</text><text class="value">{{ boolText(form.longTermOperation) }}</text></view>
  403 + <view class="row"><text class="label">是否终端客户</text><text class="value">{{ boolText(form.terminalCustomer) }}</text></view>
  404 + <view class="row"><text class="label">是否未点价</text><text class="value">{{ boolText(form.priced) }}</text></view>
  405 + <view v-if="form.priced === true" class="row"><text class="label">点价截止日期</text><text class="value">{{ formatDateOnly(form.pricingDeadline) }}</text></view>
  406 + <view v-if="form.priced === true" class="row"><text class="label">是否暂定价</text><text class="value">{{ boolText(form.temporaryPrice) }}</text></view>
  407 + <view class="row"><text class="label">其他费用凭票到厂另行结算</text><text class="value">{{ boolText(form.otherExpenseSettlement) }}</text></view>
  408 + <view class="row"><text class="label">交提货方式</text><text class="value">{{ getDeliveryMethodLabel() }}</text></view>
  409 + <view class="row"><text class="label">是否通货买断</text><text class="value">{{ boolText(form.commodityBuyout) }}</text></view>
  410 + <view class="row"><text class="label">是否质量买断</text><text class="value">{{ boolText(form.qualityBuyout) }}</text></view>
  411 + <view class="row"><text class="label">是否数量买断</text><text class="value">{{ boolText(form.quantityBuyout) }}</text></view>
  412 + <view class="row"><text class="label">是否送货上门</text><text class="value">{{ boolText(form.doorDelivery) }}</text></view>
  413 + <view class="row"><text class="label">另付运费</text><text class="value">{{ formatNumber(form.shippingCost) }}</text></view>
  414 + <view class="row"><text class="label">装车费</text><text class="value">{{ formatNumber(form.loadingFee) }}</text></view>
  415 + <view class="row"><text class="label">开票品名</text><text class="value">{{ safeText(form.invoiceProductName) }}</text></view>
  416 + <view class="row"><text class="label">交货日期</text><text class="value">{{ formatDateOnly(form.deliveryDate) }}</text></view>
  417 + <view class="row"><text class="label">结算方式</text><text class="value">{{ safeText(form.settlementMethod) }}</text></view>
  418 + <view class="row"><text class="label">结算比例(%)</text><text class="value">{{ formatNumber(form.settlementRatio) }}</text></view>
  419 + <view class="row"><text class="label">价格表编号</text><text class="value">{{ priceTableDisplay }}</text></view>
  420 + <view class="row"><text class="label">协调事由</text><text class="value">{{ safeText(form.coordinationReason) }}</text></view>
  421 + <view class="row"><text class="label">票类状况</text><text class="value">{{ safeText(form.invoiceTypeStatus) }}</text></view>
  422 + <view class="row"><text class="label">数量合计</text><text class="value">{{ formatNumber(form.totalQuantity) }}</text></view>
  423 + <view class="row" v-if="attachmentList.length">
  424 + <text class="label">附件</text>
  425 + <view class="attach-list">
  426 + <view v-for="(at, idx) in attachmentList" :key="idx" class="attach-item">
  427 + <text class="attach-name">{{ at.name }}</text>
  428 + <text class="attach-view" @click.stop="onPreviewAttachment(at)">查看</text>
  429 + </view>
64 </view> 430 </view>
65 </view> 431 </view>
66 </view> 432 </view>
67 - </view>  
68 -  
69 - <view class="title-header">  
70 - <image class="title-header_icon" src="/static/images/title.png" />  
71 - <span>明细信息</span>  
72 - </view>  
73 - <view v-if="lineListWithName.length" class="section">  
74 - <view v-for="(line, idx) in lineListWithName" :key="line.itemId || idx" class="line-block">  
75 - <view class="line-title">明细{{ idx + 1 }}</view>  
76 - <view class="row"><text class="label">品种</text><text class="value">{{ safeText(line.productName) }}</text></view>  
77 - <view class="row"><text class="label">料型</text><text class="value">{{ safeText(line.materialType) }}</text></view>  
78 - <view class="row"><text class="label">数量(吨)</text><text class="value">{{ formatNumber(line.quantity) }}</text></view>  
79 - <view class="row"><text class="label">实际采购价</text><text class="value">{{ formatNumber(line.actualPurchasePrice) }}</text></view>  
80 - <view class="row"><text class="label">含运到厂价</text><text class="value">{{ formatNumber(line.includingShippingPrice) }}</text></view>  
81 - <view class="row">  
82 - <text class="label">价格表价格</text>  
83 - <input v-if="canEdit" class="value line-input" v-model="line.priceListPrices" type="digit" placeholder="请输入" @input="onLinePriceInput(idx, $event)" @blur="onLinePriceBlur(idx)" />  
84 - <text v-else class="value">{{ formatNumber(line.priceListPrices) }}</text>  
85 - </view>  
86 - <view class="row"><text class="label">协调幅度</text><text class="value">{{ formatNumber(line.coordinationRange) }}</text></view>  
87 - <view class="row"><text class="label">买断料预计损耗</text><text class="value">{{ formatNumber(line.estimatedLoss) }}</text></view>  
88 - <view class="row"><text class="label">申请损耗(%)</text><text class="value">{{ formatNumber(line.applicationAttrition) }}</text></view>  
89 - <view class="row">  
90 - <text class="label" :class="{ required: canEditWorkshop }">选择分厂</text>  
91 - <view v-if="canEditWorkshop" class="value select-value" @click="openWorkshopSheet(idx)">  
92 - <text :class="line.workshopName ? '' : 'placeholder'">{{ line.workshopName || '请选择分厂' }}</text>  
93 - <text class="arrow">›</text>  
94 - </view>  
95 - <text v-else class="value">{{ safeText(line.workshopName) }}</text> 433 +
  434 + <view class="title-header">
  435 + <image class="title-header_icon" src="/static/images/title.png" />
  436 + <span>明细信息</span>
  437 + </view>
  438 + <view v-if="lineListWithName.length" class="section">
  439 + <view v-for="(line, idx) in lineListWithName" :key="line.itemId || idx" class="line-block">
  440 + <view class="line-title">明细{{ idx + 1 }}</view>
  441 + <view class="row"><text class="label">品种</text><text class="value">{{ safeText(line.productName) }}</text></view>
  442 + <view class="row"><text class="label">料型</text><text class="value">{{ safeText(line.materialType) }}</text></view>
  443 + <view class="row"><text class="label">数量(吨)</text><text class="value">{{ formatNumber(line.quantity) }}</text></view>
  444 + <view class="row"><text class="label">实际采购价</text><text class="value">{{ formatNumber(line.actualPurchasePrice) }}</text></view>
  445 + <view class="row"><text class="label">含运到厂价</text><text class="value">{{ formatNumber(line.includingShippingPrice) }}</text></view>
  446 + <view class="row"><text class="label">价格表价格</text><text class="value">{{ formatNumber(line.priceListPrices) }}</text></view>
  447 + <view class="row"><text class="label">协调幅度</text><text class="value">{{ formatNumber(line.coordinationRange) }}</text></view>
  448 + <view class="row"><text class="label">买断料预计损耗</text><text class="value">{{ formatNumber(line.estimatedLoss) }}</text></view>
  449 + <view class="row"><text class="label">申请损耗(%)</text><text class="value">{{ formatNumber(line.applicationAttrition) }}</text></view>
  450 + <view class="row"><text class="label">选择分厂</text><text class="value">{{ safeText(line.workshopName) }}</text></view>
96 </view> 451 </view>
97 </view> 452 </view>
98 - </view>  
99 - <view v-else class="section empty-tip">暂无明细</view>  
100 -  
101 - <view class="title-header">  
102 - <image class="title-header_icon" src="/static/images/title.png" />  
103 - <span>料质状况</span>  
104 - </view>  
105 - <view class="section">  
106 - <view class="row"><text class="label">是否启用料质状况</text><text class="value">{{ boolText(form.materialConditionEnabled) }}</text></view>  
107 - <template v-if="form.materialConditionEnabled">  
108 - <view v-for="mc in materialConditionConfigs" :key="mc.field" class="material-group">  
109 - <text class="material-label">{{ mc.label }}</text>  
110 - <view class="tag-list">  
111 - <view v-for="opt in getDictOptions(mc.dictCode)" :key="opt.code" class="tag-btn" :class="{ active: isTagSelected(mc.field, opt.code) }">{{ opt.name }}</view> 453 + <view v-else class="section empty-tip">暂无明细</view>
  454 +
  455 + <view class="title-header">
  456 + <image class="title-header_icon" src="/static/images/title.png" />
  457 + <span>料质状况</span>
  458 + </view>
  459 + <view class="section">
  460 + <view class="row"><text class="label">是否启用料质状况</text><text class="value">{{ boolText(form.materialConditionEnabled) }}</text></view>
  461 + <template v-if="form.materialConditionEnabled">
  462 + <view v-for="mc in materialConditionConfigs" :key="mc.field" class="material-group">
  463 + <text class="material-label">{{ mc.label }}</text>
  464 + <view class="tag-list">
  465 + <view v-for="opt in getDictOptions(mc.dictCode)" :key="opt.code" class="tag-btn" :class="{ active: isTagSelected(mc.field, opt.code) }">{{ opt.name }}</view>
  466 + </view>
112 </view> 467 </view>
113 - </view>  
114 - </template>  
115 - </view>  
116 -  
117 - <view class="title-header">  
118 - <image class="title-header_icon" src="/static/images/title.png" />  
119 - <span>备注</span>  
120 - </view>  
121 - <view class="section">  
122 - <text class="remark-text">{{ safeText(form.remark) }}</text>  
123 - </view>  
124 -  
125 - <view class="title-header">  
126 - <image class="title-header_icon" src="/static/images/title.png" />  
127 - <span>变更事由</span>  
128 - </view>  
129 - <view class="section">  
130 - <text class="remark-text">{{ safeText(form.changeReason) }}</text>  
131 - </view> 468 + </template>
  469 + </view>
  470 +
  471 + <view class="title-header">
  472 + <image class="title-header_icon" src="/static/images/title.png" />
  473 + <span>备注</span>
  474 + </view>
  475 + <view class="section">
  476 + <text class="remark-text">{{ safeText(form.remark) }}</text>
  477 + </view>
  478 +
  479 + <view class="title-header">
  480 + <image class="title-header_icon" src="/static/images/title.png" />
  481 + <span>变更事由</span>
  482 + </view>
  483 + <view class="section">
  484 + <text class="remark-text">{{ safeText(form.changeReason) }}</text>
  485 + </view>
  486 + </template>
132 </scroll-view> 487 </scroll-view>
133 488
134 <RelateSelectSheet 489 <RelateSelectSheet
@@ -172,12 +527,13 @@ import SingleSelectSheet from '@/components/single-select/index.vue' @@ -172,12 +527,13 @@ import SingleSelectSheet from '@/components/single-select/index.vue'
172 export default { 527 export default {
173 name: 'SchedulePlanChangeViewer', 528 name: 'SchedulePlanChangeViewer',
174 components: { RelateSelectSheet, SingleSelectSheet }, 529 components: { RelateSelectSheet, SingleSelectSheet },
175 - props: { id: { type: [String, Number], default: '' } }, 530 + props: { id: { type: [String, Number], default: '' }, roleCodes: { type: Array, default: function () { return [] } } },
176 data() { 531 data() {
177 return { 532 return {
178 form: {}, 533 form: {},
179 lineList: [], 534 lineList: [],
180 attachmentList: [], 535 attachmentList: [],
  536 + _roleCodesFromApi: [],
181 materialConditionConfigs: [ 537 materialConditionConfigs: [
182 { field: 'materialConditionCopperRice', label: '铜米', dictCode: 'COPPER_RICE' }, 538 { field: 'materialConditionCopperRice', label: '铜米', dictCode: 'COPPER_RICE' },
183 { field: 'materialConditionBrightCopper', label: '光亮铜', dictCode: 'BRIGHT_COPPER' }, 539 { field: 'materialConditionBrightCopper', label: '光亮铜', dictCode: 'BRIGHT_COPPER' },
@@ -191,16 +547,18 @@ export default { @@ -191,16 +547,18 @@ export default {
191 dictData: {}, 547 dictData: {},
192 productOptions: [], 548 productOptions: [],
193 workshopOptions: [], 549 workshopOptions: [],
  550 + priceTableList: [],
194 deliveryOptions: [], 551 deliveryOptions: [],
195 isGyglkzg: false, 552 isGyglkzg: false,
196 isGyglkzlglg: false, 553 isGyglkzlglg: false,
  554 + isGyglkjhgly: false,
197 companySheetVisible: false, 555 companySheetVisible: false,
198 priceSheetVisible: false, 556 priceSheetVisible: false,
199 workshopSheet: { visible: false, title: '请选择分厂', options: [], value: '', idx: -1 }, 557 workshopSheet: { visible: false, title: '请选择分厂', options: [], value: '', idx: -1 },
200 companyDisplayFields: [ 558 companyDisplayFields: [
201 - { label: '公司简称', field: 'companyShortName' }, 559 + { label: '公司简称', field: 'shortName' },
202 { label: '公司名称', field: 'companyName' }, 560 { label: '公司名称', field: 'companyName' },
203 - { label: '编码', field: 'code' } 561 + { label: '办事处', field: 'deptName' }
204 ], 562 ],
205 priceTableDisplayFields: [ 563 priceTableDisplayFields: [
206 { label: '价格表编号', field: 'priceTableCode' }, 564 { label: '价格表编号', field: 'priceTableCode' },
@@ -210,21 +568,93 @@ export default { @@ -210,21 +568,93 @@ export default {
210 } 568 }
211 }, 569 },
212 computed: { 570 computed: {
  571 + isEditLayout() {
  572 + return this.canEdit || this.canEditWorkshop
  573 + },
  574 + parentRoleCodes() {
  575 + try {
  576 + var codes = null
  577 + var p = this.$parent
  578 + for (var i = 0; i < 5 && p; i++) {
  579 + if (p.roleCodes != null && Array.isArray(p.roleCodes)) {
  580 + codes = p.roleCodes
  581 + break
  582 + }
  583 + if (p.$store && p.$store.getters && Array.isArray(p.$store.getters.roleCodes)) {
  584 + codes = p.$store.getters.roleCodes
  585 + break
  586 + }
  587 + p = p.$parent
  588 + }
  589 + if (!codes && this.$store && this.$store.getters && Array.isArray(this.$store.getters.roleCodes)) {
  590 + codes = this.$store.getters.roleCodes
  591 + }
  592 + return Array.isArray(codes) ? codes : []
  593 + } catch (e) {
  594 + return []
  595 + }
  596 + },
  597 + mergedRoleCodes() {
  598 + var r1 = Array.isArray(this.roleCodes) ? this.roleCodes : []
  599 + var r2 = Array.isArray(this.parentRoleCodes) ? this.parentRoleCodes : []
  600 + if (!r1.length && !r2.length) return []
  601 + var map = {}
  602 + ;[]
  603 + .concat(r1)
  604 + .concat(r2)
  605 + .forEach(function (c) {
  606 + if (c != null && c !== '') map[String(c)] = true
  607 + })
  608 + return Object.keys(map)
  609 + },
213 isAuditPage() { 610 isAuditPage() {
214 try { 611 try {
  612 + // 优先:父级 audit.vue 已明确存在(roleCodes 能取到 或 父级路由配置)
  613 + if (Array.isArray(this.parentRoleCodes) && this.parentRoleCodes.length) {
  614 + return true
  615 + }
215 var pages = getCurrentPages() 616 var pages = getCurrentPages()
216 var cur = pages[pages.length - 1] 617 var cur = pages[pages.length - 1]
217 var route = cur && cur.route ? String(cur.route) : '' 618 var route = cur && cur.route ? String(cur.route) : ''
218 - return route === 'pages/flow/audit' 619 + var options = cur && cur.options ? cur.options : {}
  620 + var path = (cur && cur.$page && cur.$page.fullPath) ? String(cur.$page.fullPath) : ''
  621 + var url = (cur && cur.url) ? String(cur.url) : ''
  622 + if (
  623 + route.indexOf('pages/flow/audit') !== -1 ||
  624 + route === 'pages/flow/audit' ||
  625 + path.indexOf('pages/flow/audit') !== -1 ||
  626 + url.indexOf('pages/flow/audit') !== -1 ||
  627 + (options && options.taskId) ||
  628 + (options && options.instanceId)
  629 + ) {
  630 + return true
  631 + }
  632 + var p2 = this.$parent
  633 + for (var j = 0; j < 5 && p2; j++) {
  634 + var n = p2.$options && p2.$options.name ? String(p2.$options.name) : ''
  635 + var r = p2.$options && p2.$options.__file ? String(p2.$options.__file) : ''
  636 + if (
  637 + n.indexOf('Audit') !== -1 ||
  638 + n === 'FlowAudit' ||
  639 + r.indexOf('flow/audit') !== -1 ||
  640 + (p2.auditCtx && typeof p2.auditCtx === 'object')
  641 + ) {
  642 + return true
  643 + }
  644 + p2 = p2.$parent
  645 + }
  646 + return false
219 } catch (e) { 647 } catch (e) {
220 return false 648 return false
221 } 649 }
222 }, 650 },
223 canEdit() { 651 canEdit() {
224 - return !!this.isGyglkzg && this.isAuditPage 652 + var codes = this.mergedRoleCodes.length ? this.mergedRoleCodes : (Array.isArray(this._roleCodesFromApi) ? this._roleCodesFromApi : [])
  653 + return ( codes.includes('gyglkjhgly')) && this.isAuditPage
225 }, 654 },
226 canEditWorkshop() { 655 canEditWorkshop() {
227 - return !!this.isGyglkzlglg && this.isAuditPage 656 + var codes = this.mergedRoleCodes.length ? this.mergedRoleCodes : (Array.isArray(this._roleCodesFromApi) ? this._roleCodesFromApi : [])
  657 + return codes.includes('gyglkzlglg') && this.isAuditPage
228 }, 658 },
229 workshopOptsComputed() { 659 workshopOptsComputed() {
230 var list = Array.isArray(this.workshopOptions) ? this.workshopOptions : [] 660 var list = Array.isArray(this.workshopOptions) ? this.workshopOptions : []
@@ -241,10 +671,60 @@ export default { @@ -241,10 +671,60 @@ export default {
241 var n = Number(v) 671 var n = Number(v)
242 return isNaN(n) ? 0 : n 672 return isNaN(n) ? 0 : n
243 }, 673 },
  674 + purchaseDepartmentDisplay() {
  675 + var d = this.form || {}
  676 + return d.purchaseDepartmentName != null ? d.purchaseDepartmentName : (d.purchaseDepartment != null ? d.purchaseDepartment : '')
  677 + },
  678 + regionDisplay() {
  679 + var d = this.form || {}
  680 + return d.regionName != null ? d.regionName : (d.region != null ? d.region : '')
  681 + },
  682 + pricingDeadlineDisplay() {
  683 + var d = this.form || {}
  684 + var s = d.pricingDeadline == null ? '' : String(d.pricingDeadline).trim()
  685 + if (!s) return ''
  686 + if (s.length >= 10) return s.slice(0, 10)
  687 + return s
  688 + },
  689 + deliveryDateDisplay() {
  690 + var d = this.form || {}
  691 + var s = d.deliveryDate == null ? '' : String(d.deliveryDate).trim()
  692 + if (!s) return ''
  693 + if (s.length >= 10) return s.slice(0, 10)
  694 + return s
  695 + },
  696 + loadingFeeDisplay() {
  697 + var v = (this.form || {}).loadingFee
  698 + if (v == null || v === '') return ''
  699 + var n = Number(v)
  700 + if (isNaN(n)) return String(v)
  701 + return n.toLocaleString('zh-CN', { maximumFractionDigits: 4 })
  702 + },
  703 + settlementRatioDisplay() {
  704 + var v = (this.form || {}).settlementRatio
  705 + if (v == null || v === '') return ''
  706 + var n = Number(v)
  707 + if (isNaN(n)) return String(v)
  708 + return n.toLocaleString('zh-CN', { maximumFractionDigits: 4 })
  709 + },
  710 + shippingCostDisplay() {
  711 + var v = (this.form || {}).shippingCost
  712 + if (v == null || v === '') return ''
  713 + var n = Number(v)
  714 + if (isNaN(n)) return String(v)
  715 + return n.toLocaleString('zh-CN', { maximumFractionDigits: 4 })
  716 + },
  717 + totalQuantityDisplay() {
  718 + var v = (this.form || {}).totalQuantity
  719 + if (v == null || v === '') return ''
  720 + var n = Number(v)
  721 + if (isNaN(n)) return String(v)
  722 + return n.toLocaleString('zh-CN', { maximumFractionDigits: 4 })
  723 + },
244 priceTableCodeLabel() { 724 priceTableCodeLabel() {
245 var d = this.form || {} 725 var d = this.form || {}
246 - var code = d.priceTableCode != null ? d.priceTableCode : ''  
247 - var name = d.priceTableName || '' 726 + var code = d.priceTableCode != null ? d.priceTableCode : (d.priceId != null ? d.priceId : (d.priceTableId != null ? d.priceTableId : ''))
  727 + var name = d.priceTableName || d.tableName || d.name || ''
248 if (name || code) { 728 if (name || code) {
249 return (name ? name + (code ? ' (' + code + ')' : '') : String(code)) 729 return (name ? name + (code ? ' (' + code + ')' : '') : String(code))
250 } 730 }
@@ -287,8 +767,8 @@ export default { @@ -287,8 +767,8 @@ export default {
287 }, 767 },
288 priceTableDisplay() { 768 priceTableDisplay() {
289 var d = this.form || {} 769 var d = this.form || {}
290 - var code = d.priceTableCode != null ? String(d.priceTableCode).trim() : ''  
291 - var name = d.priceTableName || '' 770 + var code = d.priceTableCode != null ? String(d.priceTableCode).trim() : (d.priceId != null ? String(d.priceId).trim() : (d.priceTableId != null ? String(d.priceTableId).trim() : ''))
  771 + var name = d.priceTableName || d.tableName || d.name || ''
292 if (name || code) { 772 if (name || code) {
293 return (name ? name + (code ? ' (' + code + ')' : '') : String(code)) 773 return (name ? name + (code ? ' (' + code + ')' : '') : String(code))
294 } 774 }
@@ -311,10 +791,14 @@ export default { @@ -311,10 +791,14 @@ export default {
311 }, 791 },
312 methods: { 792 methods: {
313 getUserInfo() { 793 getUserInfo() {
  794 + var self = this
314 getInfo() 795 getInfo()
315 .then((res) => { 796 .then((res) => {
316 - this.isGyglkzg = !!(res?.roleCodes?.includes('gyglkzg') && res?.roleCodes?.includes('001'));  
317 - this.isGyglkzlglg = !!(res?.roleCodes?.includes('gyglkzlglg') && res?.roleCodes?.includes('001')); 797 + var codes = Array.isArray(res?.roleCodes) ? res.roleCodes : []
  798 + self._roleCodesFromApi = codes
  799 + // self.isGyglkzg = !!(codes.includes('gyglkzg') && codes.includes('001'));
  800 + self.isGyglkzlglg = !!(codes.includes('gyglkzlglg') && codes.includes('001'));
  801 + self.isGyglkjhgly = codes.includes('gyglkjhgly');
318 }) 802 })
319 .catch((err) => { 803 .catch((err) => {
320 console.error('获取用户信息失败:', err); 804 console.error('获取用户信息失败:', err);
@@ -353,14 +837,22 @@ export default { @@ -353,14 +837,22 @@ export default {
353 var self = this 837 var self = this
354 try { 838 try {
355 var results = await Promise.all([ 839 var results = await Promise.all([
  840 + this.pCall(priceTableQueryApi, { pageIndex: 1, pageSize: 1000 }),
356 this.pCall(breedRelationshipQueryApi, { pageIndex: 1, pageSize: 1000 }), 841 this.pCall(breedRelationshipQueryApi, { pageIndex: 1, pageSize: 1000 }),
357 this.pCall(workshopQueryApi, { pageIndex: 1, pageSize: 1000 }) 842 this.pCall(workshopQueryApi, { pageIndex: 1, pageSize: 1000 })
358 ]) 843 ])
359 - var r1 = (results[0] && results[0].data) ? results[0].data : {}  
360 - var r2 = (results[1] && results[1].data) ? results[1].data : {} 844 + var r0 = (results[0] && results[0].data) ? results[0].data : {}
  845 + var r1 = (results[1] && results[1].data) ? results[1].data : {}
  846 + var r2 = (results[2] && results[2].data) ? results[2].data : {}
  847 + var rawPriceTableList = (r0.datas && Array.isArray(r0.datas)) ? r0.datas : ((r0.list && Array.isArray(r0.list)) ? r0.list : ((r0.records && Array.isArray(r0.records)) ? r0.records : []))
  848 + self.priceTableList = Array.isArray(rawPriceTableList) ? rawPriceTableList.map(function (item) { return self.normalizePriceTableRow(item) }) : []
361 self.productOptions = (r1.datas && Array.isArray(r1.datas)) ? r1.datas : ((r1.list && Array.isArray(r1.list)) ? r1.list : ((r1.records && Array.isArray(r1.records)) ? r1.records : [])) 849 self.productOptions = (r1.datas && Array.isArray(r1.datas)) ? r1.datas : ((r1.list && Array.isArray(r1.list)) ? r1.list : ((r1.records && Array.isArray(r1.records)) ? r1.records : []))
362 self.workshopOptions = (r2.datas && Array.isArray(r2.datas)) ? r2.datas : ((r2.list && Array.isArray(r2.list)) ? r2.list : ((r2.records && Array.isArray(r2.records)) ? r2.records : [])) 850 self.workshopOptions = (r2.datas && Array.isArray(r2.datas)) ? r2.datas : ((r2.list && Array.isArray(r2.list)) ? r2.list : ((r2.records && Array.isArray(r2.records)) ? r2.records : []))
  851 + if (self.isGyglkjhgly && self.isAuditPage && !self.priceTableCodeLabel && (self.form.priceTableId || self.form.priceId || self.form.priceTableCode)) {
  852 + self.fillPriceTableFromDetail(self.form)
  853 + }
363 } catch (e) { 854 } catch (e) {
  855 + self.priceTableList = []
364 self.productOptions = [] 856 self.productOptions = []
365 self.workshopOptions = [] 857 self.workshopOptions = []
366 } 858 }
@@ -399,15 +891,23 @@ export default { @@ -399,15 +891,23 @@ export default {
399 var lines = d.lines || d.procurementPlanLineList || d.lineList || [] 891 var lines = d.lines || d.procurementPlanLineList || d.lineList || []
400 this.lineList = Array.isArray(lines) ? lines.slice() : [] 892 this.lineList = Array.isArray(lines) ? lines.slice() : []
401 // 初始化可编辑字段 893 // 初始化可编辑字段
402 - this.form.companyId = d.companyId || ''  
403 - this.form.companyShortName = d.companyShortName || d.companyName || '' 894 + this.form.companyId = d.companyId || d.companyShortId || ''
  895 + this.form.companyShortId = d.companyShortId || d.companyId || ''
  896 + this.form.companyShortName = d.companyShortName || d.shortName || d.companyName || d.name || ''
  897 + this.form.companyName = d.companyName || d.companyShortName || d.shortName || d.name || ''
  898 + this.form.priceTableId = d.priceTableId || d.priceId || ''
  899 + this.form.priceId = d.priceId || d.priceTableId || ''
  900 + this.form.priceTableCode = d.priceTableCode || d.code || ''
  901 + this.form.priceTableName = d.priceTableName || d.tableName || d.name || ''
404 var date = d.date ? String(d.date).trim() : '' 902 var date = d.date ? String(d.date).trim() : ''
405 this.form.date = date.length >= 10 ? date.slice(0, 10) : date 903 this.form.date = date.length >= 10 ? date.slice(0, 10) : date
406 var sc = d.shippingCost 904 var sc = d.shippingCost
407 this.form.shippingCost = (sc != null && sc !== '') ? this.toFixed(sc, 2) : '' 905 this.form.shippingCost = (sc != null && sc !== '') ? this.toFixed(sc, 2) : ''
408 this.buildAttachmentList() 906 this.buildAttachmentList()
409 this.refreshLinesFromShipping() 907 this.refreshLinesFromShipping()
410 - if (this.canEdit) { 908 + if (this.isGyglkjhgly && this.isAuditPage) {
  909 + this.fillPriceTableFromDetail(d)
  910 + } else if (this.canEdit) {
411 this.loadLatestPriceTableAndApply() 911 this.loadLatestPriceTableAndApply()
412 } else { 912 } else {
413 this.fetchPriceDetailAndApply(d.priceId) 913 this.fetchPriceDetailAndApply(d.priceId)
@@ -476,6 +976,12 @@ export default { @@ -476,6 +976,12 @@ export default {
476 if (isNaN(n)) return String(v) 976 if (isNaN(n)) return String(v)
477 return n.toLocaleString('zh-CN', { maximumFractionDigits: 4 }) 977 return n.toLocaleString('zh-CN', { maximumFractionDigits: 4 })
478 }, 978 },
  979 + lineNumberDisplay(v) {
  980 + if (v == null || v === '') return ''
  981 + var n = Number(v)
  982 + if (isNaN(n)) return String(v)
  983 + return n.toLocaleString('zh-CN', { maximumFractionDigits: 4 })
  984 + },
479 onPreviewAttachment(at) { 985 onPreviewAttachment(at) {
480 if (!at || !at.id) { 986 if (!at || !at.id) {
481 uni.showToast({ title: '无法查看', icon: 'none' }) 987 uni.showToast({ title: '无法查看', icon: 'none' })
@@ -484,14 +990,36 @@ export default { @@ -484,14 +990,36 @@ export default {
484 uni.showToast({ title: '查看附件 ' + at.name, icon: 'none' }) 990 uni.showToast({ title: '查看附件 ' + at.name, icon: 'none' })
485 }, 991 },
486 // ==================== 公司下拉 ==================== 992 // ==================== 公司下拉 ====================
  993 + normalizeCompanyRow(row) {
  994 + var item = row || {}
  995 + var id = item.id != null ? item.id : (item.companyShortId != null ? item.companyShortId : (item.companyId != null ? item.companyId : (item.value != null ? item.value : '')))
  996 + var shortName = item.shortName != null ? item.shortName : (item.companyShortName != null ? item.companyShortName : (item.companyName != null ? item.companyName : (item.name != null ? item.name : '')))
  997 + var companyName = item.companyName != null ? item.companyName : (item.name != null ? item.name : shortName)
  998 + var deptName = item.deptName != null ? item.deptName : (item.departmentName != null ? item.departmentName : '')
  999 + var code = item.code != null ? item.code : (item.companyCode != null ? item.companyCode : '')
  1000 + return Object.assign({}, item, {
  1001 + id: id,
  1002 + value: id,
  1003 + companyId: id,
  1004 + companyShortId: id,
  1005 + shortName: shortName,
  1006 + companyShortName: shortName,
  1007 + companyName: companyName,
  1008 + name: companyName,
  1009 + deptName: deptName,
  1010 + code: code
  1011 + })
  1012 + },
487 fetchCompanyList(args) { 1013 fetchCompanyList(args) {
488 var extra = (args && args.extra) ? args.extra : {} 1014 var extra = (args && args.extra) ? args.extra : {}
489 var keyword = extra.keyword || extra.name || '' 1015 var keyword = extra.keyword || extra.name || ''
490 var params = { pageIndex: args.pageIndex || 1, pageSize: args.pageSize || 20 } 1016 var params = { pageIndex: args.pageIndex || 1, pageSize: args.pageSize || 20 }
491 if (keyword) params.name = keyword 1017 if (keyword) params.name = keyword
  1018 + var self = this
492 return companyShortQueryApi(params).then(function (res) { 1019 return companyShortQueryApi(params).then(function (res) {
493 var d = (res && res.data) ? res.data : {} 1020 var d = (res && res.data) ? res.data : {}
494 var records = (d.datas && Array.isArray(d.datas)) ? d.datas : ((d.records && Array.isArray(d.records)) ? d.records : ((d.list && Array.isArray(d.list)) ? d.list : [])) 1021 var records = (d.datas && Array.isArray(d.datas)) ? d.datas : ((d.records && Array.isArray(d.records)) ? d.records : ((d.list && Array.isArray(d.list)) ? d.list : []))
  1022 + records = Array.isArray(records) ? records.map(function (item) { return self.normalizeCompanyRow(item) }) : []
495 var total = d.totalCount || d.count || (records ? records.length : 0) 1023 var total = d.totalCount || d.count || (records ? records.length : 0)
496 var hasNext = !!d.hasNext 1024 var hasNext = !!d.hasNext
497 return { records: records, totalCount: total, hasNext: hasNext } 1025 return { records: records, totalCount: total, hasNext: hasNext }
@@ -505,9 +1033,11 @@ export default { @@ -505,9 +1033,11 @@ export default {
505 onCompanyConfirm(e) { 1033 onCompanyConfirm(e) {
506 var items = (e && e.items) ? e.items : [] 1034 var items = (e && e.items) ? e.items : []
507 if (!items.length) return 1035 if (!items.length) return
508 - var row = items[0] || {} 1036 + var row = this.normalizeCompanyRow(items[0] || {})
509 this.form.companyId = row.id || '' 1037 this.form.companyId = row.id || ''
510 - this.form.companyShortName = row.companyShortName || row.companyName || row.name || '' 1038 + this.form.companyShortId = row.id || ''
  1039 + this.form.companyShortName = row.companyShortName || ''
  1040 + this.form.companyName = row.companyName || row.companyShortName || ''
511 }, 1041 },
512 // ==================== 价格表下拉 ==================== 1042 // ==================== 价格表下拉 ====================
513 fetchPriceTableList(args) { 1043 fetchPriceTableList(args) {
@@ -515,9 +1045,11 @@ export default { @@ -515,9 +1045,11 @@ export default {
515 var keyword = extra.keyword || extra.name || '' 1045 var keyword = extra.keyword || extra.name || ''
516 var params = { pageIndex: args.pageIndex || 1, pageSize: args.pageSize || 20 } 1046 var params = { pageIndex: args.pageIndex || 1, pageSize: args.pageSize || 20 }
517 if (keyword) params.name = keyword 1047 if (keyword) params.name = keyword
  1048 + var self = this
518 return priceTableQueryApi(params).then(function (res) { 1049 return priceTableQueryApi(params).then(function (res) {
519 var d = (res && res.data) ? res.data : {} 1050 var d = (res && res.data) ? res.data : {}
520 var records = (d.datas && Array.isArray(d.datas)) ? d.datas : ((d.records && Array.isArray(d.records)) ? d.records : ((d.list && Array.isArray(d.list)) ? d.list : [])) 1051 var records = (d.datas && Array.isArray(d.datas)) ? d.datas : ((d.records && Array.isArray(d.records)) ? d.records : ((d.list && Array.isArray(d.list)) ? d.list : []))
  1052 + records = Array.isArray(records) ? records.map(function (item) { return self.normalizePriceTableRow(item) }) : []
521 var total = d.totalCount || d.count || (records ? records.length : 0) 1053 var total = d.totalCount || d.count || (records ? records.length : 0)
522 var hasNext = !!d.hasNext 1054 var hasNext = !!d.hasNext
523 return { records: records, totalCount: total, hasNext: hasNext } 1055 return { records: records, totalCount: total, hasNext: hasNext }
@@ -533,10 +1065,60 @@ export default { @@ -533,10 +1065,60 @@ export default {
533 if (!items.length) return 1065 if (!items.length) return
534 this.selectPriceTableRow(items[0] || {}) 1066 this.selectPriceTableRow(items[0] || {})
535 }, 1067 },
  1068 + normalizePriceTableRow(row) {
  1069 + var item = row || {}
  1070 + var id = item.id != null ? item.id : (item.priceId != null ? item.priceId : (item.value != null ? item.value : ''))
  1071 + var code = item.priceTableCode != null ? item.priceTableCode : (item.code != null ? item.code : (item.priceCode != null ? item.priceCode : ''))
  1072 + var name = item.priceTableName != null ? item.priceTableName : (item.tableName != null ? item.tableName : (item.name != null ? item.name : (item.label != null ? item.label : '')))
  1073 + var effectiveDate = item.effectiveDate != null ? item.effectiveDate : (item.createTime != null ? item.createTime : (item.updateTime != null ? item.updateTime : (item.date != null ? item.date : '')))
  1074 + return Object.assign({}, item, {
  1075 + id: id,
  1076 + priceId: id,
  1077 + priceTableId: id,
  1078 + code: code,
  1079 + priceTableCode: code,
  1080 + name: name,
  1081 + tableName: name,
  1082 + priceTableName: name,
  1083 + effectiveDate: effectiveDate
  1084 + })
  1085 + },
536 selectPriceTableRow(row) { 1086 selectPriceTableRow(row) {
537 - this.form.priceTableId = row.id || ''  
538 - this.form.priceTableCode = row.priceTableCode || row.code || ''  
539 - this.form.priceTableName = row.priceTableName || row.name || '' 1087 + var item = this.normalizePriceTableRow(row)
  1088 + this.form.priceTableId = item.id || ''
  1089 + this.form.priceId = item.id || ''
  1090 + this.form.priceTableCode = item.priceTableCode || ''
  1091 + this.form.priceTableName = item.priceTableName || ''
  1092 + if (this.form.priceTableId) {
  1093 + this.fetchPriceDetailAndApply(this.form.priceTableId)
  1094 + }
  1095 + },
  1096 + fillPriceTableFromDetail(d) {
  1097 + var detail = d || this.form || {}
  1098 + var code = detail.priceTableCode != null ? detail.priceTableCode : ''
  1099 + var id = detail.priceTableId != null ? detail.priceTableId : (detail.priceId != null ? detail.priceId : '')
  1100 + var token = code || id
  1101 + if (!token) return
  1102 + var sc = String(token)
  1103 + var list = Array.isArray(this.priceTableList) ? this.priceTableList : []
  1104 + var matched = null
  1105 + for (var i = 0; i < list.length; i++) {
  1106 + var o = list[i]
  1107 + var id = String(o.id || o.priceId || o.value || '')
  1108 + var c = String(o.priceTableCode || o.code || o.priceCode || '')
  1109 + if (id === sc || c === sc) {
  1110 + matched = o
  1111 + break
  1112 + }
  1113 + }
  1114 + if (matched) {
  1115 + this.selectPriceTableRow(matched)
  1116 + return
  1117 + }
  1118 + this.form.priceTableId = id || ''
  1119 + this.form.priceId = id || ''
  1120 + this.form.priceTableCode = code || (id ? String(id) : '')
  1121 + this.form.priceTableName = detail.priceTableName != null ? detail.priceTableName : (detail.tableName != null ? detail.tableName : (detail.name != null ? detail.name : ''))
540 if (this.form.priceTableId) { 1122 if (this.form.priceTableId) {
541 this.fetchPriceDetailAndApply(this.form.priceTableId) 1123 this.fetchPriceDetailAndApply(this.form.priceTableId)
542 } 1124 }
@@ -548,7 +1130,7 @@ export default { @@ -548,7 +1130,7 @@ export default {
548 var d = (res && res.data) ? res.data : {} 1130 var d = (res && res.data) ? res.data : {}
549 var list = (d.datas && Array.isArray(d.datas)) ? d.datas : ((d.records && Array.isArray(d.records)) ? d.records : ((d.list && Array.isArray(d.list)) ? d.list : [])) 1131 var list = (d.datas && Array.isArray(d.datas)) ? d.datas : ((d.records && Array.isArray(d.records)) ? d.records : ((d.list && Array.isArray(d.list)) ? d.list : []))
550 if (!list || !list.length) return 1132 if (!list || !list.length) return
551 - self.selectPriceTableRow(list[0]) 1133 + self.selectPriceTableRow(self.normalizePriceTableRow(list[0]))
552 } catch (e) { 1134 } catch (e) {
553 return 1135 return
554 } 1136 }
@@ -559,11 +1141,16 @@ export default { @@ -559,11 +1141,16 @@ export default {
559 try { 1141 try {
560 var res = await priceTableDetailApi({ id: priceId }) 1142 var res = await priceTableDetailApi({ id: priceId })
561 var d = (res && res.data) ? res.data : {} 1143 var d = (res && res.data) ? res.data : {}
  1144 + if (d.id != null && this.form) {
  1145 + this.$set(this.form, 'priceTableId', d.id)
  1146 + this.$set(this.form, 'priceId', d.id)
  1147 + }
562 if (d.code != null && this.form) { 1148 if (d.code != null && this.form) {
563 this.$set(this.form, 'priceTableCode', String(d.code)) 1149 this.$set(this.form, 'priceTableCode', String(d.code))
564 } 1150 }
565 - if (d.priceTableName != null && this.form) {  
566 - this.$set(this.form, 'priceTableName', d.priceTableName) 1151 + var priceTableName = d.priceTableName != null ? d.priceTableName : (d.tableName != null ? d.tableName : (d.name != null ? d.name : ''))
  1152 + if (priceTableName && this.form) {
  1153 + this.$set(this.form, 'priceTableName', priceTableName)
567 } 1154 }
568 var priceLines = self.extractPriceLines(d) 1155 var priceLines = self.extractPriceLines(d)
569 self.applyPriceLinesToLines(priceLines) 1156 self.applyPriceLinesToLines(priceLines)
@@ -731,6 +1318,28 @@ export default { @@ -731,6 +1318,28 @@ export default {
731 this.$set(row, 'coordinationRange', this.toFixed(coord, 2)) 1318 this.$set(row, 'coordinationRange', this.toFixed(coord, 2))
732 }, 1319 },
733 // ==================== 审核提交 ==================== 1320 // ==================== 审核提交 ====================
  1321 + joinStr(arr) {
  1322 + if (Array.isArray(arr)) return arr.filter(Boolean).join(',')
  1323 + if (typeof arr === 'string') return arr
  1324 + return ''
  1325 + },
  1326 + pickId(v) {
  1327 + if (v == null || v === '') return ''
  1328 + if (typeof v === 'string' || typeof v === 'number') return String(v)
  1329 + if (typeof v === 'object') {
  1330 + return String(v.id != null ? v.id : (v.value != null ? v.value : (v.code != null ? v.code : '')))
  1331 + }
  1332 + return String(v)
  1333 + },
  1334 + toBool(v, fallback) {
  1335 + if (typeof v === 'boolean') return v
  1336 + if (v === 'true' || v === '1' || v === 1) return true
  1337 + if (v === 'false' || v === '0' || v === 0) return false
  1338 + return typeof fallback === 'boolean' ? fallback : false
  1339 + },
  1340 + boolToStr(v) {
  1341 + return v === true ? 'true' : 'false'
  1342 + },
734 checkForm() { 1343 checkForm() {
735 if (!this.canEdit) return true 1344 if (!this.canEdit) return true
736 if (!this.form.companyId) { 1345 if (!this.form.companyId) {
@@ -758,25 +1367,73 @@ export default { @@ -758,25 +1367,73 @@ export default {
758 }, 1367 },
759 getFormValues() { 1368 getFormValues() {
760 var self = this 1369 var self = this
761 - var lines = Array.isArray(this.lineList) ? this.lineList : []  
762 - return {  
763 - companyId: this.form.companyId || '',  
764 - companyShortName: this.form.companyShortName || this.form.companyName || '',  
765 - date: this.form.date || '',  
766 - shippingCost: this.form.shippingCost != null && this.form.shippingCost !== '' ? this.toNumber(this.form.shippingCost) : null,  
767 - priceTableId: this.form.priceTableId || '',  
768 - priceTableCode: this.form.priceTableCode || '',  
769 - lineList: lines.map(function (r) {  
770 - return {  
771 - itemId: r.itemId || r.id || '',  
772 - workshopId: r.workshopId || '',  
773 - workshopName: r.workshopName || '',  
774 - priceListPrices: self.toNumber(r.priceListPrices),  
775 - includingShippingPrice: self.toNumber(r.includingShippingPrice),  
776 - coordinationRange: self.toNumber(r.coordinationRange)  
777 - }  
778 - }) 1370 + var d = this.form || {}
  1371 + var lines = Array.isArray(this.lineList) ? this.lineList.slice() : []
  1372 + var lineList = lines.map(function (row, i) {
  1373 + var r = row || {}
  1374 + var itemId = r.itemId != null ? r.itemId : (r.id != null ? String(r.id) : (r._key != null ? r._key : ('line-' + Date.now() + '-' + i)))
  1375 + return {
  1376 + id: r.id != null ? r.id : '',
  1377 + itemId: itemId,
  1378 + productId: self.pickId(r.productId),
  1379 + materialType: r.materialType != null ? String(r.materialType) : '',
  1380 + quantity: r.quantity != null ? (self.toNumber(r.quantity)) : '',
  1381 + actualPurchasePrice: r.actualPurchasePrice != null ? (self.toNumber(r.actualPurchasePrice)) : '',
  1382 + includingShippingPrice: r.includingShippingPrice != null ? (self.toNumber(r.includingShippingPrice)) : '',
  1383 + priceListPrices: r.priceListPrices != null ? (self.toNumber(r.priceListPrices)) : '',
  1384 + coordinationRange: r.coordinationRange != null ? (self.toNumber(r.coordinationRange)) : '',
  1385 + estimatedLoss: r.estimatedLoss != null ? (self.toNumber(r.estimatedLoss)) : '',
  1386 + applicationAttrition: r.applicationAttrition != null ? (self.toNumber(r.applicationAttrition)) : '',
  1387 + paintDamageRatio: r.paintDamageRatio != null ? (self.toNumber(r.paintDamageRatio)) : '',
  1388 + workshopId: self.pickId(r.workshopId),
  1389 + procurementPlanChangeId: r.procurementPlanChangeId != null ? r.procurementPlanChangeId : (d.id != null ? d.id : '')
  1390 + }
  1391 + })
  1392 + var body = {
  1393 + id: d.id || '',
  1394 + procurementPlanId: d.procurementPlanId || '',
  1395 + changeReason: d.changeReason != null ? String(d.changeReason) : '',
  1396 + code: d.code != null ? String(d.code) : '',
  1397 + companyShortId: this.pickId(d.companyShortId || d.companyId),
  1398 + supplierId: this.pickId(d.supplierId),
  1399 + purchaseDepartment: this.pickId(d.purchaseDepartmentId || d.purchaseDepartment),
  1400 + region: this.pickId(d.regionId || d.region),
  1401 + date: d.date != null ? String(d.date).slice(0, 10) : '',
  1402 + validityPeriod: d.validityPeriod != null ? String(d.validityPeriod) : '',
  1403 + quoterId: this.pickId(d.quoterId),
  1404 + quoterName: d.quoterName != null ? String(d.quoterName) : '',
  1405 + longTermOperation: this.boolToStr(this.toBool(d.longTermOperation, false)),
  1406 + terminalCustomer: this.boolToStr(this.toBool(d.terminalCustomer, false)),
  1407 + priced: this.boolToStr(this.toBool(d.priced, false)),
  1408 + pricingDeadline: d.pricingDeadline != null ? String(d.pricingDeadline) : '',
  1409 + temporaryPrice: this.boolToStr(this.toBool(d.temporaryPrice, false)),
  1410 + otherExpenseSettlement: this.boolToStr(this.toBool(d.otherExpenseSettlement, false)),
  1411 + deliveryMode: d.deliveryMode != null ? String(d.deliveryMode) : '',
  1412 + commodityBuyout: this.boolToStr(this.toBool(d.commodityBuyout, false)),
  1413 + qualityBuyout: this.boolToStr(this.toBool(d.qualityBuyout, false)),
  1414 + quantityBuyout: this.boolToStr(this.toBool(d.quantityBuyout, false)),
  1415 + doorDelivery: this.boolToStr(this.toBool(d.doorDelivery, false)),
  1416 + shippingCost: d.shippingCost != null ? (this.toNumber(d.shippingCost)) : '',
  1417 + loadingFee: d.loadingFee != null ? (this.toNumber(d.loadingFee)) : '',
  1418 + invoiceProductName: d.invoiceProductName != null ? String(d.invoiceProductName) : '',
  1419 + deliveryDate: d.deliveryDate != null ? String(d.deliveryDate) : '',
  1420 + settlementMethod: d.settlementMethod != null ? String(d.settlementMethod) : '',
  1421 + settlementRatio: d.settlementRatio != null ? (this.toNumber(d.settlementRatio)) : '',
  1422 + priceId: this.pickId(d.priceTableId || d.priceId),
  1423 + coordinationReason: d.coordinationReason != null ? String(d.coordinationReason) : '',
  1424 + invoiceTypeStatus: d.invoiceTypeStatus != null ? String(d.invoiceTypeStatus) : '',
  1425 + totalQuantity: d.totalQuantity != null ? (this.toNumber(d.totalQuantity)) : '',
  1426 + remark: d.remark != null ? String(d.remark) : '',
  1427 + materialConditionEnabled: this.boolToStr(this.toBool(d.materialConditionEnabled, false)),
  1428 + approvalStatus: d.approvalStatus != null ? String(d.approvalStatus) : '',
  1429 + processStatus: d.processStatus != null ? String(d.processStatus) : '',
  1430 + processNode: d.processNode != null ? String(d.processNode) : '',
  1431 + lines: lineList
779 } 1432 }
  1433 + this.materialConditionConfigs.forEach(function (mc) {
  1434 + body[mc.field] = self.joinStr(d[mc.field])
  1435 + })
  1436 + return body
780 } 1437 }
781 } 1438 }
782 } 1439 }
@@ -784,11 +1441,22 @@ export default { @@ -784,11 +1441,22 @@ export default {
784 <style lang="scss" scoped> 1441 <style lang="scss" scoped>
785 .detail-page { 1442 .detail-page {
786 background: #f3f3f3; 1443 background: #f3f3f3;
  1444 + min-height: 100%;
787 } 1445 }
788 .scroll { 1446 .scroll {
789 flex: 1; 1447 flex: 1;
790 padding: 8rpx 0 48rpx; 1448 padding: 8rpx 0 48rpx;
791 } 1449 }
  1450 +.edit-list,
  1451 +.edit-line-list {
  1452 + margin-bottom: 20rpx;
  1453 +}
  1454 +.edit-line-block {
  1455 + margin-bottom: 20rpx;
  1456 + &:last-child {
  1457 + margin-bottom: 0;
  1458 + }
  1459 +}
792 .title-header { 1460 .title-header {
793 display: flex; 1461 display: flex;
794 align-items: center; 1462 align-items: center;
@@ -956,4 +1624,147 @@ export default { @@ -956,4 +1624,147 @@ export default {
956 color: rgba(0, 0, 0, 0.4); 1624 color: rgba(0, 0, 0, 0.4);
957 padding: 24rpx 0; 1625 padding: 24rpx 0;
958 } 1626 }
  1627 +::v-deep .edit-list,
  1628 +::v-deep .edit-line-block .uni-list {
  1629 + background: transparent;
  1630 + .uni-list-item__container {
  1631 + padding: 32rpx;
  1632 + }
  1633 +}
  1634 +::v-deep .uni-list {
  1635 + .uni-easyinput {
  1636 + display: flex;
  1637 + .uni-input-input {
  1638 + color: rgba(0, 0, 0, 0.9);
  1639 + }
  1640 + }
  1641 + .uni-input-placeholder {
  1642 + z-index: 1;
  1643 + }
  1644 + .uni-input-input {
  1645 + background-color: #ffffff;
  1646 + }
  1647 + background: transparent;
  1648 + &-item {
  1649 + &__extra-text {
  1650 + font-size: 32rpx;
  1651 + }
  1652 + &__content-title {
  1653 + font-size: 32rpx;
  1654 + color: rgba(0, 0, 0, 0.9);
  1655 + }
  1656 + &__container {
  1657 + .uni-easyinput {
  1658 + &__placeholder-class {
  1659 + font-size: 32rpx;
  1660 + color: rgba(0, 0, 0, 0.4);
  1661 + }
  1662 + &__content {
  1663 + border: none;
  1664 + background-color: #ffffff !important;
  1665 + &-input {
  1666 + padding-left: 0 !important;
  1667 + height: 48rpx;
  1668 + line-height: 48rpx;
  1669 + font-size: 32rpx;
  1670 + }
  1671 + .content-clear-icon {
  1672 + font-size: 44rpx !important;
  1673 + }
  1674 + }
  1675 + }
  1676 + .item-title,
  1677 + .uni-list-item__content {
  1678 + flex: none;
  1679 + min-height: 48rpx;
  1680 + line-height: 48rpx;
  1681 + font-size: 32rpx;
  1682 + position: relative;
  1683 + width: 240rpx;
  1684 + margin-right: 32rpx;
  1685 + color: rgba(0, 0, 0, 0.9);
  1686 + .required {
  1687 + color: red;
  1688 + position: absolute;
  1689 + top: 50%;
  1690 + transform: translateY(-50%);
  1691 + left: -16rpx;
  1692 + }
  1693 + }
  1694 + }
  1695 + &.select-item {
  1696 + &.is-empty {
  1697 + .uni-list-item__extra-text {
  1698 + color: rgba(0, 0, 0, 0.4) !important;
  1699 + }
  1700 + }
  1701 + &.is-filled {
  1702 + .uni-list-item__extra-text {
  1703 + color: rgba(0, 0, 0, 0.9) !important;
  1704 + }
  1705 + }
  1706 + .serial-number-row {
  1707 + display: flex;
  1708 + align-items: center;
  1709 + }
  1710 + }
  1711 + }
  1712 +}
  1713 +.readonly-text {
  1714 + color: rgba(0, 0, 0, 0.9);
  1715 + font-size: 32rpx;
  1716 + line-height: 48rpx;
  1717 + text-align: right;
  1718 + white-space: pre-wrap;
  1719 + word-break: break-all;
  1720 +}
  1721 +.value-code {
  1722 + width: 260rpx;
  1723 + text-align: left;
  1724 +}
  1725 +.material-condition-section,
  1726 +.remark-section {
  1727 + margin-top: 20rpx;
  1728 + background: #fff;
  1729 +}
  1730 +.section-header {
  1731 + display: flex;
  1732 + align-items: center;
  1733 + padding: 24rpx 32rpx;
  1734 + border-bottom: 1rpx solid #f0f0f0;
  1735 +}
  1736 +.section-title {
  1737 + font-size: 32rpx;
  1738 + color: rgba(0, 0, 0, 0.9);
  1739 + font-weight: 600;
  1740 + line-height: 44rpx;
  1741 +}
  1742 +.opCollapse {
  1743 + width: 32rpx;
  1744 + height: 28rpx;
  1745 + margin-right: 16rpx;
  1746 + margin-top: 4rpx;
  1747 + flex: 0 0 32rpx;
  1748 +}
  1749 +.section-content {
  1750 + padding: 32rpx;
  1751 +}
  1752 +.form-row {
  1753 + display: flex;
  1754 + align-items: center;
  1755 + justify-content: space-between;
  1756 + margin-bottom: 24rpx;
  1757 +}
  1758 +.form-row:last-child {
  1759 + margin-bottom: 0;
  1760 +}
  1761 +.form-label {
  1762 + font-size: 32rpx;
  1763 + color: rgba(0, 0, 0, 0.9);
  1764 +}
  1765 +.form-value {
  1766 + font-size: 32rpx;
  1767 + color: rgba(0, 0, 0, 0.9);
  1768 + text-align: right;
  1769 +}
959 </style> 1770 </style>
@@ -920,7 +920,7 @@ export default { @@ -920,7 +920,7 @@ export default {
920 totalQuantity: d.totalQuantity != null ? String(d.totalQuantity) : '', 920 totalQuantity: d.totalQuantity != null ? String(d.totalQuantity) : '',
921 remark: d.remark != null ? String(d.remark) : '', 921 remark: d.remark != null ? String(d.remark) : '',
922 materialConditionEnabled: this.boolToStr(d.materialConditionEnabled), 922 materialConditionEnabled: this.boolToStr(d.materialConditionEnabled),
923 - lines: lineList 923 + procurementPlanReplenishLineList: lineList
924 } 924 }
925 this.materialConditionConfigs.forEach(function (mc) { 925 this.materialConditionConfigs.forEach(function (mc) {
926 body[mc.field] = self.joinStr(d[mc.field]) 926 body[mc.field] = self.joinStr(d[mc.field])
@@ -106,6 +106,7 @@ import { procurementPlanReplenishFindByIdApi, procurementPlanReplenishSubmitApi, @@ -106,6 +106,7 @@ import { procurementPlanReplenishFindByIdApi, procurementPlanReplenishSubmitApi,
106 import { breedRelationshipQueryApi, workshopQueryApi } from '@/api/devManage.js' 106 import { breedRelationshipQueryApi, workshopQueryApi } from '@/api/devManage.js'
107 import { getDicByCodes } from '@/utils/dic.js' 107 import { getDicByCodes } from '@/utils/dic.js'
108 import DetailButtons from '@/components/detail-buttons/index.vue' 108 import DetailButtons from '@/components/detail-buttons/index.vue'
  109 +import { getInfo } from '@/api/login.js'
109 export default { 110 export default {
110 name: 'SupplePlanDetail', 111 name: 'SupplePlanDetail',
111 components: { DetailButtons }, 112 components: { DetailButtons },
@@ -135,6 +136,8 @@ export default { @@ -135,6 +136,8 @@ export default {
135 { text: '审核', visible: true, variant: 'primary', event: 'approve' }, 136 { text: '审核', visible: true, variant: 'primary', event: 'approve' },
136 { text: '审核详情', visible: true, event: 'approveDetail' }, 137 { text: '审核详情', visible: true, event: 'approveDetail' },
137 ], 138 ],
  139 + investigatorId: '',
  140 + roleCodes: [],
138 } 141 }
139 }, 142 },
140 computed: { 143 computed: {
@@ -187,8 +190,8 @@ export default { @@ -187,8 +190,8 @@ export default {
187 const isRefuse = status === 'REFUSE'; 190 const isRefuse = status === 'REFUSE';
188 const canExamine = isAudit && this.form && this.form.showExamine === true; 191 const canExamine = isAudit && this.form && this.form.showExamine === true;
189 return [ 192 return [
190 - { ...this.buttons[0], visible: ((isDraft || isRefuse) && this.$auth.hasPermi('plan-manage:supple-plan:modify')) },  
191 - { ...this.buttons[1], visible: ((isDraft || isRefuse) && this.$auth.hasPermi('plan-manage:supple-plan:initiate')) }, 193 + { ...this.buttons[0], visible: ((isDraft || isRefuse) && this.investigatorId === this.form.initiatorId && this.$auth.hasPermi('plan-manage:supple-plan:modify')) },
  194 + { ...this.buttons[1], visible: ((isDraft || isRefuse) && this.investigatorId === this.form.initiatorId && this.$auth.hasPermi('plan-manage:supple-plan:initiate')) },
192 { ...this.buttons[2], visible: (isRefuse && this.$auth.hasPermi('plan-manage:supple-plan:cancel')) }, 195 { ...this.buttons[2], visible: (isRefuse && this.$auth.hasPermi('plan-manage:supple-plan:cancel')) },
193 { ...this.buttons[3], visible: (canExamine && this.$auth.hasPermi('plan-manage:supple-plan:approve')) }, 196 { ...this.buttons[3], visible: (canExamine && this.$auth.hasPermi('plan-manage:supple-plan:approve')) },
194 { ...this.buttons[4], visible: ((isAudit || isPass) && this.form.showExamine && this.$auth.hasPermi('plan-manage:supple-plan:view')) }, 197 { ...this.buttons[4], visible: ((isAudit || isPass) && this.form.showExamine && this.$auth.hasPermi('plan-manage:supple-plan:view')) },
@@ -200,8 +203,19 @@ export default { @@ -200,8 +203,19 @@ export default {
200 this.loadDictData() 203 this.loadDictData()
201 this.loadRefData() 204 this.loadRefData()
202 this.loadDetail() 205 this.loadDetail()
  206 + this.getUserInfo()
203 }, 207 },
204 methods: { 208 methods: {
  209 + async getUserInfo() {
  210 + getInfo()
  211 + .then((res) => {
  212 + this.investigatorId = res?.data?.id || '';
  213 + this.roleCodes = res?.data?.roleCodes || [];
  214 + })
  215 + .catch((err) => {
  216 + console.error('获取用户信息失败:', err);
  217 + });
  218 + },
205 handleButtonClick(btn) { 219 handleButtonClick(btn) {
206 if (!btn || btn.disabled) return 220 if (!btn || btn.disabled) return
207 const e = btn.event || '' 221 const e = btn.event || ''
@@ -26,6 +26,7 @@ import DelayedShipmentViewer from '@/pages/delay_invoice/viewer.vue' @@ -26,6 +26,7 @@ import DelayedShipmentViewer from '@/pages/delay_invoice/viewer.vue'
26 import ConfirmationFormViewer from '@/pages/confirmation_form/viewer.vue' 26 import ConfirmationFormViewer from '@/pages/confirmation_form/viewer.vue'
27 import ConfirmationFormApprove from '@/pages/confirmation_form/approve.vue' 27 import ConfirmationFormApprove from '@/pages/confirmation_form/approve.vue'
28 import FollowUpFormViewer from '@/pages/follow_up_form/viewer.vue' 28 import FollowUpFormViewer from '@/pages/follow_up_form/viewer.vue'
  29 +import DomesticPlanViewer from '@/pages/domestic-plan/domesticPlanViewer.vue'
29 30
30 export default function registerComponents(Vue) { 31 export default function registerComponents(Vue) {
31 Vue.component('CustomerDevelopViewer', CustomerDevelopViewer) 32 Vue.component('CustomerDevelopViewer', CustomerDevelopViewer)
@@ -56,4 +57,5 @@ export default function registerComponents(Vue) { @@ -56,4 +57,5 @@ export default function registerComponents(Vue) {
56 Vue.component('DraftDistAgmtViewer', DraftDistAgmtViewer) 57 Vue.component('DraftDistAgmtViewer', DraftDistAgmtViewer)
57 Vue.component('ForeignDraftDistAgmtViewer', ForeignDraftDistAgmtViewer) 58 Vue.component('ForeignDraftDistAgmtViewer', ForeignDraftDistAgmtViewer)
58 Vue.component('AgmtViewer', AgmtViewer) 59 Vue.component('AgmtViewer', AgmtViewer)
  60 + Vue.component('DomesticPlanViewer', DomesticPlanViewer)
59 } 61 }
@@ -136,6 +136,12 @@ export const getSysFlowComponentPath = (bizFlag) => { @@ -136,6 +136,12 @@ export const getSysFlowComponentPath = (bizFlag) => {
136 case 'RESULT_TRACKING_EDIT': // 产品试样跟踪单 136 case 'RESULT_TRACKING_EDIT': // 产品试样跟踪单
137 componentPath = 'FollowUpFormViewer'; // 产品试样跟踪单-审批 137 componentPath = 'FollowUpFormViewer'; // 产品试样跟踪单-审批
138 break; 138 break;
  139 + case 'PROCUREMENT_PLAN': // 采购计划
  140 + componentPath = 'DomesticPlanViewer'; // 采购计划-审批详情
  141 + break;
  142 + case 'PROCUREMENT_PLAN_EDIT': // 采购计划
  143 + componentPath = 'DomesticPlanViewer'; // 采购计划-审批
  144 + break;
139 } 145 }
140 return componentPath; 146 return componentPath;
141 }; 147 };