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 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 130
131 131 export function procurementPlanGenerateContractApi(id) {
132 132 return request({
133   - url: '/procurement/plan/generateContract',
  133 + url: '/procurement/plan/generateContract?id=' + id,
134 134 method: 'post',
135   - params: { id: id }
136 135 })
137 136 }
138 137
139 138 export function procurementPlanSubmitAuditApi(id) {
140 139 return request({
141   - url: '/procurement/plan/submitAudit',
  140 + url: '/procurement/plan/submitAudit?id=' + id,
142 141 method: 'post',
143   - params: { id: id }
144 142 })
145 143 }
146 144
147 145 export function procurementPlanSubmitApi(id) {
148 146 return request({
149   - url: '/procurement/plan/submit',
  147 + url: '/procurement/plan/submit?id=' + id,
150 148 method: 'post',
151   - params: { id: id }
152 149 })
153 150 }
154 151
155 152 export function procurementPlanStopApi(id) {
156 153 return request({
157   - url: '/procurement/plan/stop',
  154 + url: '/procurement/plan/stop?id=' + id,
158 155 method: 'post',
159   - params: { id: id }
160 156 })
161 157 }
162 158
163 159 export function procurementPlanChangeSubmitApi(id) {
164 160 return request({
165   - url: '/procurement/plan/change/submit',
  161 + url: '/procurement/plan/change/submit?id=' + id,
166 162 method: 'post',
167   - params: { id: id }
168 163 })
169 164 }
170 165
... ...
... ... @@ -72,3 +72,12 @@ export function salesmanQuotationCancelApi(params) {
72 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 82 import DetailButtons from '@/components/detail-buttons/index.vue'
83 83 import ProductRel from './productRel.vue'
84 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 86 import { getDicByCodes, getDicName } from '@/utils/dic.js'
87 87 import { getInfo } from '@/api/login.js'
88 88 import { priceTableQueryApi, breedRelationshipQueryApi, workshopQueryApi } from '@/api/devManage.js'
... ... @@ -209,9 +209,9 @@ export default {
209 209 approve: (inStatus([SC.AUDIT, SC.REFUSE]) && aStatus === 'AUDIT' && !!f.showExamine) && perms.approve,
210 210 approveDetail: !!f.showExamineDetail && (inStatus([SC.AUDIT, SC.COMPLETED, SC.REFUSE])) && perms.approveDetail,
211 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 215 // uploadAttachment: inStatus([SC.COMPLETED]) && !!this.planRoleFlags.isPlanner && perms.uploadAttachment
216 216 }
217 217 var out = []
... ... @@ -232,6 +232,13 @@ export default {
232 232 this.getUserInfo()
233 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 242 methods: {
236 243 hasPerm(code) {
237 244 try {
... ... @@ -415,10 +422,11 @@ export default {
415 422 if (e === 'approveDetail') return this.onApproveDetail()
416 423 if (e === 'print') return this.onPrint()
417 424 if (e === 'generateBuyoutApply') return this.onGenerateBuyoutApply()
418   - if (e === 'abolishBuyoutApply') return this.onAbolishBuyoutApply()
  425 + if (e === 'cancel') return this.onAbolishBuyoutApply()
419 426 if (e === 'look') return this.onViewBuyoutApply()
420 427 if (e === 'uploadAttachment') return this.onUploadAttachment()
421 428 },
  429 +
422 430 onView() {
423 431 uni.showToast({ title: '查看', icon: 'none' })
424 432 },
... ... @@ -562,7 +570,7 @@ export default {
562 570 loading: '废除中',
563 571 successText: '废除成功',
564 572 failText: '废除买断操作申请单失败',
565   - run: function () { return buyoutApplyAbolishApi(id) }
  573 + run: function () { return buyoutApplyDeleteByPlanIdApi(id) }
566 574 })
567 575 },
568 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 67 </uni-list-item>
68 68 <uni-list-item title="含运到厂价">
69 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 71 </template>
92 72 </uni-list-item>
93 73 <uni-list-item title="价格表价格">
... ... @@ -106,27 +86,7 @@
106 86 </uni-list-item>
107 87 <uni-list-item title="协调幅度">
108 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 90 </template>
131 91 </uni-list-item>
132 92 <uni-list-item title="买断料预计损耗">
... ...
... ... @@ -303,7 +303,8 @@ export default {
303 303 dictData: {},
304 304 lineList: [],
305 305 productOptions: [],
306   - workshopOptions: []
  306 + workshopOptions: [],
  307 + priceTableList: []
307 308 }
308 309 },
309 310 computed: {
... ... @@ -360,10 +361,23 @@ export default {
360 361 },
361 362 priceTableDisplay() {
362 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 383 onLoad(query) {
... ... @@ -470,15 +484,19 @@ export default {
470 484 async loadRefData() {
471 485 try {
472 486 var results = await Promise.all([
  487 + this.$pCall(priceTableQueryApi, { pageIndex: 1, pageSize: 1000 }),
473 488 this.$pCall(breedRelationshipQueryApi, { pageIndex: 1, pageSize: 1000 }),
474 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 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 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 497 this.fillLineNames()
481 498 } catch (e) {
  499 + this.priceTableList = []
482 500 this.productOptions = []
483 501 this.workshopOptions = []
484 502 }
... ... @@ -733,6 +751,7 @@ export default {
733 751 try {
734 752 uni.setStorageSync('DOMESTIC_PLAN_LIST_NEED_REFRESH', '1')
735 753 uni.setStorageSync('SUPPLE_PLAN_LIST_NEED_REFRESH', '1')
  754 + uni.setStorageSync('DOMESTIC_PLAN_DETAIL_NEED_REFRESH', '1')
736 755 } catch (e) {}
737 756 var self = this
738 757 setTimeout(function () {
... ...
... ... @@ -536,7 +536,7 @@ export default {
536 536 this.buildAttachmentList()
537 537 this.fillLineNames()
538 538 this.refreshLinesFromShipping()
539   - this.loadLatestPriceTableAndApply()
  539 + this.fillPriceTableFromDetail(d)
540 540 } catch (e) {
541 541 uni.showToast({ title: '加载报价单失败', icon: 'none' })
542 542 }
... ... @@ -544,15 +544,19 @@ export default {
544 544 async loadRefData() {
545 545 try {
546 546 var results = await Promise.all([
  547 + this.$pCall(priceTableQueryApi, { pageIndex: 1, pageSize: 1000 }),
547 548 this.$pCall(breedRelationshipQueryApi, { pageIndex: 1, pageSize: 1000 }),
548 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 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 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 557 this.fillLineNames()
555 558 } catch (e) {
  559 + this.priceTableList = []
556 560 this.productOptions = []
557 561 this.workshopOptions = []
558 562 }
... ... @@ -621,6 +625,35 @@ export default {
621 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 657 async loadLatestPriceTableAndApply() {
625 658 var self = this
626 659 try {
... ... @@ -927,6 +960,7 @@ export default {
927 960 try {
928 961 uni.setStorageSync('DOMESTIC_PLAN_LIST_NEED_REFRESH', '1')
929 962 uni.setStorageSync('SUPPLE_PLAN_LIST_NEED_REFRESH', '1')
  963 + uni.setStorageSync('DOMESTIC_PLAN_DETAIL_NEED_REFRESH', '1')
930 964 } catch (e) {}
931 965 var self = this
932 966 setTimeout(function () {
... ...
... ... @@ -152,7 +152,6 @@
152 152
153 153 <script>
154 154 import { buyoutApplyDetailByPlanIdApi } from '@/api/procure-manage/buyout.js'
155   -import { procurementPlanDetailApi } from '@/api/procure-manage/procurementPlan.js'
156 155 import { breedRelationshipQueryApi } from '@/api/devManage.js'
157 156
158 157 export default {
... ... @@ -160,15 +159,16 @@ export default {
160 159 data() {
161 160 return {
162 161 planId: '',
163   - planData: {},
164 162 buyoutData: null,
165 163 breedOptions: [],
166 164 main: {
167 165 code: '',
168 166 supplierName: '',
169 167 purchaseDepartment: '',
  168 + purchaseDepartmentName: '',
170 169 purchaseDepartmentId: '',
171 170 region: '',
  171 + regionName: '',
172 172 regionId: '',
173 173 date: '',
174 174 shippingCost: '',
... ... @@ -186,29 +186,27 @@ export default {
186 186 computed: {
187 187 purchaseDepartmentDisplay() {
188 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 193 regionDisplay() {
195 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 199 dateDisplay() {
202   - var s = String(this.main.date || (this.planData.date || '')).trim()
  200 + var s = String(this.main.date || '').trim()
203 201 if (!s) return ''
204 202 return s.length >= 10 ? s.slice(0, 10) : s
205 203 },
206 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 206 return v === 0 ? '0.00' : v.toFixed(2)
209 207 },
210 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 210 return v === 0 ? '0.00' : v.toFixed(2)
213 211 },
214 212 paintLossRatioDisplay() {
... ... @@ -260,6 +258,19 @@ export default {
260 258 var s = v == null ? '' : String(v)
261 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 274 async loadAll() {
264 275 var self = this
265 276 try {
... ... @@ -317,54 +328,53 @@ export default {
317 328 },
318 329 async loadPlanAndApply() {
319 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 331 var buyout = null
328 332 if (this.planId) {
329 333 try {
330 334 var bRes = await buyoutApplyDetailByPlanIdApi(this.planId)
  335 + console.log('buyoutApplyDetailByPlanIdApi', bRes)
331 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 338 if (buyout && (buyout.id || buyout.code || (Array.isArray(buyout.procurementBuyoutApplyLineList) && buyout.procurementBuyoutApplyLineList.length))) {
334 339 this.buyoutData = buyout
  340 + } else {
  341 + this.buyoutData = null
335 342 }
336 343 }
337 344 } catch (e) {
338 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 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 370 this.main = {
363 371 code: code,
364 372 supplierName: supplierName,
365 373 purchaseDepartment: pd,
  374 + purchaseDepartmentName: pdName,
366 375 purchaseDepartmentId: pdId,
367 376 region: region,
  377 + regionName: regionName,
368 378 regionId: regionId,
369 379 date: date,
370 380 shippingCost: shippingCost,
... ... @@ -377,50 +387,54 @@ export default {
377 387 paintLossRatio: paintLossRatio
378 388 }
379 389 },
380   - buildLineList(plan, buyout) {
  390 + buildLineList(buyout) {
381 391 var self = this
382 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 398 this.lineList = lines.map(function (r, i) {
394 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 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 412 var ratio = withPaint ? breedPaintLossRatio : 0
399 413 var ratioFrac = ratio / 100
400 414 if (ratioFrac < 0) ratioFrac = 0
401 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 416 var divisor = 1 - ratioFrac
406 417 var base = divisor > 0 ? (self.toNumber(actualPurchase) / divisor) : self.toNumber(actualPurchase)
407 418 var pureCopperPrice = base + shippingCost + self.toNumber(estimatedLoss) + loadingFee
408 419 return {
409 420 _key: row._key || row.id || ('row-' + i + '-' + Date.now()),
410 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 429 buyoutPrice: buyoutPrice,
415 430 estimatedLoss: estimatedLoss,
  431 + applicationAttrition: applicationAttrition,
  432 + workshopName: workshopName,
416 433 paintLossRatio: ratio,
417 434 withPaint: !!withPaint,
418 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 71 <script>
72 72 import DetailButtons from '@/components/detail-buttons/index.vue'
73 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 75 import { getDicByCodes } from '@/utils/dic.js'
76 76 import { getInfo } from '@/api/login.js'
77 77 export default {
... ... @@ -113,7 +113,7 @@ export default {
113 113 { ...this.buttons[0], visible: (s === 'REFUSE' && c === this.investigatorId && this.$auth.hasPermi('procure-manage:sales-price:modify')) },
114 114 { ...this.buttons[1], visible: this.$auth.hasPermi('procure-manage:sales-price:copy') },
115 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 117 { ...this.buttons[4], visible: (s === 'AUDIT' && this.form.showExamine && this.$auth.hasPermi('procure-manage:sales-price:approves')) },
118 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 131 async getUserInfo() {
132 132 getInfo()
133 133 .then((res) => {
134   - this.investigatorId = res?.id || '';
  134 + this.investigatorId = res?.data?.id || '';
135 135 })
136 136 .catch((err) => {
137 137 console.error('获取用户信息失败:', err);
... ... @@ -197,7 +197,9 @@ export default {
197 197 if (e === 'approve') return this.onApprove()
198 198 if (e === 'approveDetail') return this.onApproveDetail()
199 199 if (e === 'cancel') return this.onCancel()
  200 + if (e === 'plan') return this.onPlan()
200 201 },
  202 +
201 203 onEdit() {
202 204 uni.navigateTo({ url: '/pages/sales-price/modify?id=' + this.id })
203 205 },
... ... @@ -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 284 onApprove() {
229 285 const id = this.id || (this.form && this.form.id) || ''
230 286 if (!id) return
... ...
... ... @@ -106,6 +106,7 @@ import { procurementPlanChangeFindByIdApi, procurementPlanChangeSubmitApi, procu
106 106 import { breedRelationshipQueryApi, priceTableDetailApi, workshopQueryApi } from '@/api/devManage.js'
107 107 import { getDicByCodes } from '@/utils/dic.js'
108 108 import DetailButtons from '@/components/detail-buttons/index.vue'
  109 +import { getInfo } from '@/api/login.js'
109 110 export default {
110 111 name: 'SchedulePlanDetail',
111 112 components: { DetailButtons },
... ... @@ -135,6 +136,7 @@ export default {
135 136 { text: '审核', visible: true, variant: 'primary', event: 'approve' },
136 137 { text: '审核详情', visible: true, event: 'approveDetail' },
137 138 ],
  139 + investigatorId: '',
138 140 }
139 141 },
140 142 computed: {
... ... @@ -187,8 +189,8 @@ export default {
187 189 const isRefuse = status === 'REFUSE';
188 190 const canExamine = isAudit && this.form && this.form.showExamine === true;
189 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 194 { ...this.buttons[2], visible: (isRefuse && this.$auth.hasPermi('plan-manage:schedule-plan:cancel')) },
193 195 { ...this.buttons[3], visible: (canExamine && this.$auth.hasPermi('plan-manage:schedule-plan:approve')) },
194 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 202 this.loadDictData()
201 203 this.loadRefData()
202 204 this.loadDetail()
  205 + this.getUserInfo()
203 206 },
204 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 217 handleButtonClick(btn) {
206 218 if (!btn || btn.disabled) return
207 219 const e = btn.event || ''
... ...
1 1 <template>
2 2 <view class="detail-page">
3 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 346 </view>
12 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 368 </view>
22 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 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 388 </view>
53   - <text v-else class="value">{{ priceTableDisplay }}</text>
54 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 430 </view>
65 431 </view>
66 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 451 </view>
97 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 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 487 </scroll-view>
133 488
134 489 <RelateSelectSheet
... ... @@ -172,12 +527,13 @@ import SingleSelectSheet from '@/components/single-select/index.vue'
172 527 export default {
173 528 name: 'SchedulePlanChangeViewer',
174 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 531 data() {
177 532 return {
178 533 form: {},
179 534 lineList: [],
180 535 attachmentList: [],
  536 + _roleCodesFromApi: [],
181 537 materialConditionConfigs: [
182 538 { field: 'materialConditionCopperRice', label: '铜米', dictCode: 'COPPER_RICE' },
183 539 { field: 'materialConditionBrightCopper', label: '光亮铜', dictCode: 'BRIGHT_COPPER' },
... ... @@ -191,16 +547,18 @@ export default {
191 547 dictData: {},
192 548 productOptions: [],
193 549 workshopOptions: [],
  550 + priceTableList: [],
194 551 deliveryOptions: [],
195 552 isGyglkzg: false,
196 553 isGyglkzlglg: false,
  554 + isGyglkjhgly: false,
197 555 companySheetVisible: false,
198 556 priceSheetVisible: false,
199 557 workshopSheet: { visible: false, title: '请选择分厂', options: [], value: '', idx: -1 },
200 558 companyDisplayFields: [
201   - { label: '公司简称', field: 'companyShortName' },
  559 + { label: '公司简称', field: 'shortName' },
202 560 { label: '公司名称', field: 'companyName' },
203   - { label: '编码', field: 'code' }
  561 + { label: '办事处', field: 'deptName' }
204 562 ],
205 563 priceTableDisplayFields: [
206 564 { label: '价格表编号', field: 'priceTableCode' },
... ... @@ -210,21 +568,93 @@ export default {
210 568 }
211 569 },
212 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 610 isAuditPage() {
214 611 try {
  612 + // 优先:父级 audit.vue 已明确存在(roleCodes 能取到 或 父级路由配置)
  613 + if (Array.isArray(this.parentRoleCodes) && this.parentRoleCodes.length) {
  614 + return true
  615 + }
215 616 var pages = getCurrentPages()
216 617 var cur = pages[pages.length - 1]
217 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 647 } catch (e) {
220 648 return false
221 649 }
222 650 },
223 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 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 659 workshopOptsComputed() {
230 660 var list = Array.isArray(this.workshopOptions) ? this.workshopOptions : []
... ... @@ -241,10 +671,60 @@ export default {
241 671 var n = Number(v)
242 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 724 priceTableCodeLabel() {
245 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 728 if (name || code) {
249 729 return (name ? name + (code ? ' (' + code + ')' : '') : String(code))
250 730 }
... ... @@ -287,8 +767,8 @@ export default {
287 767 },
288 768 priceTableDisplay() {
289 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 772 if (name || code) {
293 773 return (name ? name + (code ? ' (' + code + ')' : '') : String(code))
294 774 }
... ... @@ -311,10 +791,14 @@ export default {
311 791 },
312 792 methods: {
313 793 getUserInfo() {
  794 + var self = this
314 795 getInfo()
315 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 803 .catch((err) => {
320 804 console.error('获取用户信息失败:', err);
... ... @@ -353,14 +837,22 @@ export default {
353 837 var self = this
354 838 try {
355 839 var results = await Promise.all([
  840 + this.pCall(priceTableQueryApi, { pageIndex: 1, pageSize: 1000 }),
356 841 this.pCall(breedRelationshipQueryApi, { pageIndex: 1, pageSize: 1000 }),
357 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 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 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 854 } catch (e) {
  855 + self.priceTableList = []
364 856 self.productOptions = []
365 857 self.workshopOptions = []
366 858 }
... ... @@ -399,15 +891,23 @@ export default {
399 891 var lines = d.lines || d.procurementPlanLineList || d.lineList || []
400 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 902 var date = d.date ? String(d.date).trim() : ''
405 903 this.form.date = date.length >= 10 ? date.slice(0, 10) : date
406 904 var sc = d.shippingCost
407 905 this.form.shippingCost = (sc != null && sc !== '') ? this.toFixed(sc, 2) : ''
408 906 this.buildAttachmentList()
409 907 this.refreshLinesFromShipping()
410   - if (this.canEdit) {
  908 + if (this.isGyglkjhgly && this.isAuditPage) {
  909 + this.fillPriceTableFromDetail(d)
  910 + } else if (this.canEdit) {
411 911 this.loadLatestPriceTableAndApply()
412 912 } else {
413 913 this.fetchPriceDetailAndApply(d.priceId)
... ... @@ -476,6 +976,12 @@ export default {
476 976 if (isNaN(n)) return String(v)
477 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 985 onPreviewAttachment(at) {
480 986 if (!at || !at.id) {
481 987 uni.showToast({ title: '无法查看', icon: 'none' })
... ... @@ -484,14 +990,36 @@ export default {
484 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 1013 fetchCompanyList(args) {
488 1014 var extra = (args && args.extra) ? args.extra : {}
489 1015 var keyword = extra.keyword || extra.name || ''
490 1016 var params = { pageIndex: args.pageIndex || 1, pageSize: args.pageSize || 20 }
491 1017 if (keyword) params.name = keyword
  1018 + var self = this
492 1019 return companyShortQueryApi(params).then(function (res) {
493 1020 var d = (res && res.data) ? res.data : {}
494 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 1023 var total = d.totalCount || d.count || (records ? records.length : 0)
496 1024 var hasNext = !!d.hasNext
497 1025 return { records: records, totalCount: total, hasNext: hasNext }
... ... @@ -505,9 +1033,11 @@ export default {
505 1033 onCompanyConfirm(e) {
506 1034 var items = (e && e.items) ? e.items : []
507 1035 if (!items.length) return
508   - var row = items[0] || {}
  1036 + var row = this.normalizeCompanyRow(items[0] || {})
509 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 1043 fetchPriceTableList(args) {
... ... @@ -515,9 +1045,11 @@ export default {
515 1045 var keyword = extra.keyword || extra.name || ''
516 1046 var params = { pageIndex: args.pageIndex || 1, pageSize: args.pageSize || 20 }
517 1047 if (keyword) params.name = keyword
  1048 + var self = this
518 1049 return priceTableQueryApi(params).then(function (res) {
519 1050 var d = (res && res.data) ? res.data : {}
520 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 1053 var total = d.totalCount || d.count || (records ? records.length : 0)
522 1054 var hasNext = !!d.hasNext
523 1055 return { records: records, totalCount: total, hasNext: hasNext }
... ... @@ -533,10 +1065,60 @@ export default {
533 1065 if (!items.length) return
534 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 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 1122 if (this.form.priceTableId) {
541 1123 this.fetchPriceDetailAndApply(this.form.priceTableId)
542 1124 }
... ... @@ -548,7 +1130,7 @@ export default {
548 1130 var d = (res && res.data) ? res.data : {}
549 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 1132 if (!list || !list.length) return
551   - self.selectPriceTableRow(list[0])
  1133 + self.selectPriceTableRow(self.normalizePriceTableRow(list[0]))
552 1134 } catch (e) {
553 1135 return
554 1136 }
... ... @@ -559,11 +1141,16 @@ export default {
559 1141 try {
560 1142 var res = await priceTableDetailApi({ id: priceId })
561 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 1148 if (d.code != null && this.form) {
563 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 1155 var priceLines = self.extractPriceLines(d)
569 1156 self.applyPriceLinesToLines(priceLines)
... ... @@ -731,6 +1318,28 @@ export default {
731 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 1343 checkForm() {
735 1344 if (!this.canEdit) return true
736 1345 if (!this.form.companyId) {
... ... @@ -758,25 +1367,73 @@ export default {
758 1367 },
759 1368 getFormValues() {
760 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 1441 <style lang="scss" scoped>
785 1442 .detail-page {
786 1443 background: #f3f3f3;
  1444 + min-height: 100%;
787 1445 }
788 1446 .scroll {
789 1447 flex: 1;
790 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 1460 .title-header {
793 1461 display: flex;
794 1462 align-items: center;
... ... @@ -956,4 +1624,147 @@ export default {
956 1624 color: rgba(0, 0, 0, 0.4);
957 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 1770 </style>
... ...
... ... @@ -920,7 +920,7 @@ export default {
920 920 totalQuantity: d.totalQuantity != null ? String(d.totalQuantity) : '',
921 921 remark: d.remark != null ? String(d.remark) : '',
922 922 materialConditionEnabled: this.boolToStr(d.materialConditionEnabled),
923   - lines: lineList
  923 + procurementPlanReplenishLineList: lineList
924 924 }
925 925 this.materialConditionConfigs.forEach(function (mc) {
926 926 body[mc.field] = self.joinStr(d[mc.field])
... ...
... ... @@ -106,6 +106,7 @@ import { procurementPlanReplenishFindByIdApi, procurementPlanReplenishSubmitApi,
106 106 import { breedRelationshipQueryApi, workshopQueryApi } from '@/api/devManage.js'
107 107 import { getDicByCodes } from '@/utils/dic.js'
108 108 import DetailButtons from '@/components/detail-buttons/index.vue'
  109 +import { getInfo } from '@/api/login.js'
109 110 export default {
110 111 name: 'SupplePlanDetail',
111 112 components: { DetailButtons },
... ... @@ -135,6 +136,8 @@ export default {
135 136 { text: '审核', visible: true, variant: 'primary', event: 'approve' },
136 137 { text: '审核详情', visible: true, event: 'approveDetail' },
137 138 ],
  139 + investigatorId: '',
  140 + roleCodes: [],
138 141 }
139 142 },
140 143 computed: {
... ... @@ -187,8 +190,8 @@ export default {
187 190 const isRefuse = status === 'REFUSE';
188 191 const canExamine = isAudit && this.form && this.form.showExamine === true;
189 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 195 { ...this.buttons[2], visible: (isRefuse && this.$auth.hasPermi('plan-manage:supple-plan:cancel')) },
193 196 { ...this.buttons[3], visible: (canExamine && this.$auth.hasPermi('plan-manage:supple-plan:approve')) },
194 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 203 this.loadDictData()
201 204 this.loadRefData()
202 205 this.loadDetail()
  206 + this.getUserInfo()
203 207 },
204 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 219 handleButtonClick(btn) {
206 220 if (!btn || btn.disabled) return
207 221 const e = btn.event || ''
... ...
... ... @@ -26,6 +26,7 @@ import DelayedShipmentViewer from '@/pages/delay_invoice/viewer.vue'
26 26 import ConfirmationFormViewer from '@/pages/confirmation_form/viewer.vue'
27 27 import ConfirmationFormApprove from '@/pages/confirmation_form/approve.vue'
28 28 import FollowUpFormViewer from '@/pages/follow_up_form/viewer.vue'
  29 +import DomesticPlanViewer from '@/pages/domestic-plan/domesticPlanViewer.vue'
29 30
30 31 export default function registerComponents(Vue) {
31 32 Vue.component('CustomerDevelopViewer', CustomerDevelopViewer)
... ... @@ -56,4 +57,5 @@ export default function registerComponents(Vue) {
56 57 Vue.component('DraftDistAgmtViewer', DraftDistAgmtViewer)
57 58 Vue.component('ForeignDraftDistAgmtViewer', ForeignDraftDistAgmtViewer)
58 59 Vue.component('AgmtViewer', AgmtViewer)
  60 + Vue.component('DomesticPlanViewer', DomesticPlanViewer)
59 61 }
... ...
... ... @@ -136,6 +136,12 @@ export const getSysFlowComponentPath = (bizFlag) => {
136 136 case 'RESULT_TRACKING_EDIT': // 产品试样跟踪单
137 137 componentPath = 'FollowUpFormViewer'; // 产品试样跟踪单-审批
138 138 break;
  139 + case 'PROCUREMENT_PLAN': // 采购计划
  140 + componentPath = 'DomesticPlanViewer'; // 采购计划-审批详情
  141 + break;
  142 + case 'PROCUREMENT_PLAN_EDIT': // 采购计划
  143 + componentPath = 'DomesticPlanViewer'; // 采购计划-审批
  144 + break;
139 145 }
140 146 return componentPath;
141 147 };
... ...