Commit 4b8806e36fc5e1b683d619cf864b05a1accbee7a

Authored by gesilong
2 parents 769adb99 a54ad5e5

Merge branch 'cjerp-2.0-fix' into publish_cjerp

... ... @@ -140,6 +140,12 @@
140 140 <uni-easyinput v-model="form.specialInstructions" placeholder="请输入特别说明" :inputBorder="false" />
141 141 </template>
142 142 </uni-list-item>
  143 + <uni-list-item v-if="this.customerRemarks.length" class="select-item" :class="defaultRemark ? 'is-filled' : 'is-empty'" clickable
  144 + @click="openSheet('historyRemarks')" :rightText="defaultRemark || '请选择'" showArrow>
  145 + <template v-slot:body>
  146 + <view class="item-title"><text>历史备注</text></view>
  147 + </template>
  148 + </uni-list-item>
143 149 <uni-list-item title="备注">
144 150 <template v-slot:footer>
145 151 <uni-easyinput type="textarea" v-model="form.remarks" placeholder="请输入备注" :inputBorder="false" maxlength="2000" />
... ... @@ -227,7 +233,7 @@
227 233 import SingleSelectSheet from '@/components/single-select/index.vue'
228 234 import RelateSelectSheet from '@/components/relate-select/index.vue'
229 235 import ProductRel from './productRel.vue'
230   -import { getRetailCodeApi, createContractApi, getDeptApi, getContractApi } from '@/api/contract'
  236 +import { getRetailCodeApi, createContractApi, getCustomerRemarks, getCustomerSpecificQualityRequirements, getDeptApi, getContractApi } from '@/api/contract'
231 237 import { getDicByCodes } from '@/utils/dic'
232 238 import { formatCurrencyToChinese } from '@/utils/common'
233 239 import { workshopQueryApi } from '@/api/devManage'
... ... @@ -289,7 +295,10 @@ export default {
289 295 totalAmountIncludingTax: 0,
290 296 productLineList: [],
291 297 productList: [],
  298 + customerRemarks: [],
  299 + defaultRemark: '',
292 300 regionOptions: [],
  301 + qualityReqSeq: 0,
293 302 }
294 303 },
295 304 onLoad(query) {
... ... @@ -310,6 +319,45 @@ export default {
310 319 if (this.copyId) this.loadCopyDetail(this.copyId)
311 320 },
312 321 watch: {
  322 + 'form.buyer': {
  323 + handler(newVal, oldVal) {
  324 + if (newVal) {
  325 + getCustomerRemarks(newVal).then(res => {
  326 + const remarksData = res.data || [];
  327 + this.customerRemarks = remarksData.map((item, index) => ({
  328 + label: `客户备注${index + 1}`,
  329 + value: item,
  330 + }));
  331 + if (remarksData.length > 0) {
  332 + this.defaultRemark = this.customerRemarks[0].label || '';
  333 + this.form.remarks = remarksData[0];
  334 + } else {
  335 + this.form.remarks = '';
  336 + this.defaultRemark = '';
  337 + }
  338 + })
  339 + this.getHistory()
  340 + }
  341 + }
  342 + },
  343 + productLineList: {
  344 + deep: true,
  345 + handler(newVal, oldVal) {
  346 + const n = Array.isArray(newVal) ? newVal : []
  347 + const o = Array.isArray(oldVal) ? oldVal : []
  348 + const changed = []
  349 + for (let i = 0; i < n.length; i++) {
  350 + const ni = n[i] && n[i].productId
  351 + const oi = o[i] && o[i].productId
  352 + if (ni !== oi && ni !== undefined) changed.push(ni)
  353 + }
  354 + console.log('changed', changed)
  355 + if (changed.length && this.form.buyer) {
  356 + const id = changed.join('')
  357 + this.fetchCustomerQualityRequirements(id)
  358 + }
  359 + }
  360 + },
313 361 },
314 362 methods: {
315 363 async loadCopyDetail(id) {
... ... @@ -406,6 +454,47 @@ export default {
406 454 }
407 455 })
408 456 },
  457 + getHistory() {
  458 + if (!this.productLineList.length || !this.productLineList[0].productId) {
  459 + return;
  460 + }
  461 + const id = this.productLineList.map(it => it.productId).join('')
  462 + this.fetchCustomerQualityRequirements(id)
  463 + },
  464 + async fetchCustomerQualityRequirements(id) {
  465 + if (!this.form.buyer || !id) {
  466 + return;
  467 + }
  468 + this.qualityReqSeq = (Number(this.qualityReqSeq) || 0) + 1
  469 + const seq = this.qualityReqSeq
  470 + try {
  471 + const result = await getCustomerSpecificQualityRequirements({
  472 + customerId: this.form.buyer,
  473 + productIdList:id,
  474 + });
  475 + if (seq !== this.qualityReqSeq) return
  476 + this.updateFormData(result.data || {});
  477 + } catch (error) {
  478 + if (seq !== this.qualityReqSeq) return
  479 + console.error('获取客户质量要求失败:', error);
  480 + // 可以根据需要添加错误提示逻辑
  481 + this.$message.error('获取历史数据失败,请稍后重试');
  482 + }
  483 + },
  484 + // 提取公共的字段更新方法
  485 + updateFormData(result) {
  486 + const fields = [
  487 + 'component',
  488 + 'packaging',
  489 + 'performance',
  490 + 'pieceWeightHead',
  491 + 'surface',
  492 + 'tolerance',
  493 + ];
  494 + fields.forEach((field) => {
  495 + this.form[field] = result[field] != null ? String(result[field]) : ''
  496 + });
  497 + },
409 498 onProductsChange(products) {
410 499 const list = Array.isArray(products) ? products : []
411 500 const sumQ = list.reduce((acc, it) => acc + (parseFloat(it.quantity) || 0), 0)
... ... @@ -483,6 +572,8 @@ export default {
483 572 setSheet('单价中是否已包含包装费', this.yesNoList)
484 573 } else if (field === 'includesTransportFee') {
485 574 setSheet('单价中是否已包含运费', this.yesNoList)
  575 + } else if (field === 'historyRemarks') {
  576 + setSheet('历史备注', this.customerRemarks)
486 577 }else if (field === 'region') {
487 578 setSheet('区域', this.regionOptions)
488 579 }
... ... @@ -491,8 +582,13 @@ export default {
491 582 const field = this.sheet.field
492 583 if (!field) return
493 584 const v = (value === undefined || value === null) ? '' : value
494   - this.form[field] = v
495   - this.form[field + 'Name'] = label || ''
  585 + if (field === 'historyRemarks') {
  586 + this.defaultRemark = label || ''
  587 + this.form.remarks = v
  588 + }else{
  589 + this.form[field] = v
  590 + this.form[field + 'Name'] = label || ''
  591 + }
496 592 },
497 593 openRelate(fieldKey) {
498 594 let config = {}
... ...
... ... @@ -80,6 +80,11 @@
80 80 >
81 81 <template v-slot="{ model }">
82 82 <view class="filter-form">
  83 + <view class="form-item" v-if="isExamineTab">
  84 + <view class="label">是否本人待办</view>
  85 + <uni-data-checkbox mode="tag" :multiple="false" :value-field="'value'" :text-field="'text'"
  86 + v-model="model.needExamine" @change="onNeedExamineChange" :localdata="needExamineOptions" />
  87 + </view>
83 88 <view class="form-item">
84 89 <view class="label">订货日期</view>
85 90 <uni-datetime-picker type="daterange" v-model="model.dateRange" start="2023-01-01" />
... ... @@ -106,7 +111,7 @@ export default {
106 111
107 112 status: 'DRAFT',
108 113
109   - query: { deptId: '', deptName: '', dateRange: [] },
  114 + query: { deptId: '', deptName: '', needExamine: '', dateRange: [] },
110 115 extraParams: {},
111 116
112 117 batchMode: false,
... ... @@ -114,8 +119,9 @@ export default {
114 119 currentItems: [],
115 120
116 121 filterVisible: false,
117   - filterForm: { deptId: '', deptName: '', dateRange: [] },
  122 + filterForm: { deptId: '', deptName: '', needExamine: '', dateRange: [] },
118 123 deptSelectVisible: false,
  124 + needExamineOptions: [{ text: '是', value: 'true' }, { text: '否', value: 'false' }],
119 125 statusStyle,
120 126 }
121 127 },
... ... @@ -141,8 +147,18 @@ export default {
141 147 return {
142 148 keyword: this.searchKeywordDebounced || undefined,
143 149 status: this.status || undefined,
144   - type: 'INTL_STD_CONTRACT'
  150 + type: 'INTL_STD_CONTRACT',
  151 + examineType: this.examineType
145 152 }
  153 + },
  154 + // 仅标准/正式合同 tab 需要"是否本人待办"筛选
  155 + isExamineTab() {
  156 + return this.status === 'STANDARD' || this.status === 'FORMAL'
  157 + },
  158 + examineType() {
  159 + if (this.status === 'STANDARD') return 'STANDARD'
  160 + if (this.status === 'FORMAL') return 'FORMAL'
  161 + return undefined
146 162 }
147 163 },
148 164 watch: {
... ... @@ -191,6 +207,19 @@ export default {
191 207 },
192 208 switchTab(item) {
193 209 this.status = item.value
  210 + // 切到非标准/正式合同 tab 时,清理"是否本人待办"条件
  211 + if (!this.isExamineTab) {
  212 + if (this.filterForm.needExamine) {
  213 + this.filterForm.needExamine = ''
  214 + const q = { ...this.query }
  215 + delete q.needExamine
  216 + this.query = q
  217 + }
  218 + }
  219 + },
  220 + onNeedExamineChange(e) {
  221 + const raw = e && e.detail && e.detail.value !== undefined ? e.detail.value : (e && e.value !== undefined ? e.value : '')
  222 + this.filterForm.needExamine = raw
194 223 },
195 224 openFilter() {
196 225 this.filterVisible = true
... ...
... ... @@ -143,6 +143,12 @@
143 143 <uni-easyinput v-model="form.specialInstructions" placeholder="请输入特别说明" :inputBorder="false" />
144 144 </template>
145 145 </uni-list-item>
  146 + <uni-list-item v-if="this.customerRemarks.length" class="select-item" :class="defaultRemark ? 'is-filled' : 'is-empty'" clickable
  147 + @click="openSheet('historyRemarks')" :rightText="defaultRemark || '请选择'" showArrow>
  148 + <template v-slot:body>
  149 + <view class="item-title"><text>历史备注</text></view>
  150 + </template>
  151 + </uni-list-item>
146 152 <uni-list-item title="备注">
147 153 <template v-slot:footer>
148 154 <uni-easyinput type="textarea" v-model="form.remarks" placeholder="请输入备注" :inputBorder="false" maxlength="2000" />
... ... @@ -230,7 +236,7 @@
230 236 import SingleSelectSheet from '@/components/single-select/index.vue'
231 237 import RelateSelectSheet from '@/components/relate-select/index.vue'
232 238 import ProductRel from './productRel.vue'
233   -import { getRetailCodeApi, createContractApi, getDeptApi, getContractApi } from '@/api/contract'
  239 +import { getRetailCodeApi, createContractApi, getCustomerSpecificQualityRequirements, getCustomerRemarks, getDeptApi, getContractApi } from '@/api/contract'
234 240 import { getDicByCodes } from '@/utils/dic'
235 241 import { formatCurrencyToChinese } from '@/utils/common'
236 242 import { workshopQueryApi } from '@/api/devManage'
... ... @@ -291,7 +297,10 @@ export default {
291 297 totalAmountIncludingTax: 0,
292 298 productLineList: [],
293 299 productList: [],
  300 + customerRemarks: [],
  301 + defaultRemark: '',
294 302 regionOptions: [],
  303 + qualityReqSeq: 0,
295 304 }
296 305 },
297 306 onLoad(query) {
... ... @@ -312,6 +321,45 @@ export default {
312 321 if (this.copyId) this.loadCopyDetail(this.copyId)
313 322 },
314 323 watch: {
  324 + 'form.buyer': {
  325 + handler(newVal, oldVal) {
  326 + if (newVal) {
  327 + getCustomerRemarks(newVal).then(res => {
  328 + const remarksData = res.data || [];
  329 + this.customerRemarks = remarksData.map((item, index) => ({
  330 + label: `客户备注${index + 1}`,
  331 + value: item,
  332 + }));
  333 + if (remarksData.length > 0) {
  334 + this.defaultRemark = this.customerRemarks[0].label || '';
  335 + this.form.remarks = remarksData[0];
  336 + } else {
  337 + this.form.remarks = '';
  338 + this.defaultRemark = '';
  339 + }
  340 + })
  341 + this.getHistory()
  342 + }
  343 + }
  344 + },
  345 + productLineList: {
  346 + deep: true,
  347 + handler(newVal, oldVal) {
  348 + const n = Array.isArray(newVal) ? newVal : []
  349 + const o = Array.isArray(oldVal) ? oldVal : []
  350 + const changed = []
  351 + for (let i = 0; i < n.length; i++) {
  352 + const ni = n[i] && n[i].productId
  353 + const oi = o[i] && o[i].productId
  354 + if (ni !== oi && ni !== undefined) changed.push(ni)
  355 + }
  356 + console.log('changed', changed)
  357 + if (changed.length && this.form.buyer) {
  358 + const id = changed.join('')
  359 + this.fetchCustomerQualityRequirements(id)
  360 + }
  361 + }
  362 + },
315 363 },
316 364 methods: {
317 365 async loadCopyDetail(id) {
... ... @@ -407,6 +455,49 @@ export default {
407 455 }
408 456 })
409 457 },
  458 + getHistory() {
  459 + console.log('this.productLineList', this.productLineList[0].productId)
  460 + if (!this.productLineList.length || !this.productLineList[0].productId) {
  461 + return;
  462 + }
  463 + const id = this.productLineList.map(it => it.productId).join('')
  464 + this.fetchCustomerQualityRequirements(id)
  465 + },
  466 + async fetchCustomerQualityRequirements(id) {
  467 + if (!this.form.buyer || !id) {
  468 + return;
  469 + }
  470 + this.qualityReqSeq = (Number(this.qualityReqSeq) || 0) + 1
  471 + const seq = this.qualityReqSeq
  472 + try {
  473 + const result = await getCustomerSpecificQualityRequirements({
  474 + customerId: this.form.buyer,
  475 + productIdList:id,
  476 + });
  477 + if (seq !== this.qualityReqSeq) return
  478 + this.updateFormData(result.data || {});
  479 + } catch (error) {
  480 + if (seq !== this.qualityReqSeq) return
  481 + console.error('获取客户质量要求失败:', error);
  482 + // 可以根据需要添加错误提示逻辑
  483 + this.$message.error('获取历史数据失败,请稍后重试');
  484 + }
  485 + },
  486 + // 提取公共的字段更新方法
  487 + updateFormData(result) {
  488 + console.log('result', result)
  489 + const fields = [
  490 + 'component',
  491 + 'packaging',
  492 + 'performance',
  493 + 'pieceWeightHead',
  494 + 'surface',
  495 + 'tolerance',
  496 + ];
  497 + fields.forEach((field) => {
  498 + this.form[field] = result[field] != null ? String(result[field]) : ''
  499 + });
  500 + },
410 501 onProductsChange(products) {
411 502 const list = Array.isArray(products) ? products : []
412 503 const sumQ = list.reduce((acc, it) => acc + (parseFloat(it.quantity) || 0), 0)
... ... @@ -484,7 +575,9 @@ export default {
484 575 setSheet('单价中是否已包含包装费', this.yesNoList)
485 576 } else if (field === 'includesTransportFee') {
486 577 setSheet('单价中是否已包含运费', this.yesNoList)
487   - } else if (field === 'region') {
  578 + } else if (field === 'historyRemarks') {
  579 + setSheet('历史备注', this.customerRemarks)
  580 + }else if (field === 'region') {
488 581 setSheet('区域', this.regionOptions)
489 582 }
490 583 },
... ... @@ -492,8 +585,13 @@ export default {
492 585 const field = this.sheet.field
493 586 if (!field) return
494 587 const v = (value === undefined || value === null) ? '' : value
495   - this.form[field] = v
496   - this.form[field + 'Name'] = label || ''
  588 + if (field === 'historyRemarks') {
  589 + this.defaultRemark = label || ''
  590 + this.form.remarks = v
  591 + }else{
  592 + this.form[field] = v
  593 + this.form[field + 'Name'] = label || ''
  594 + }
497 595 },
498 596 openRelate(fieldKey) {
499 597 let config = {}
... ...
... ... @@ -82,6 +82,11 @@
82 82 >
83 83 <template v-slot="{ model }">
84 84 <view class="filter-form">
  85 + <view class="form-item" v-if="isExamineTab">
  86 + <view class="label">是否本人待办</view>
  87 + <uni-data-checkbox mode="tag" :multiple="false" :value-field="'value'" :text-field="'text'"
  88 + v-model="model.needExamine" @change="onNeedExamineChange" :localdata="needExamineOptions" />
  89 + </view>
85 90 <view class="form-item">
86 91 <view class="label">订货日期</view>
87 92 <uni-datetime-picker type="daterange" v-model="model.dateRange" start="2023-01-01" />
... ... @@ -106,7 +111,7 @@ export default {
106 111 searchKeywordDebounced: '',
107 112 status: 'DRAFT',
108 113
109   - query: { deptId: '', deptName: '', dateRange: [] },
  114 + query: { deptId: '', deptName: '', needExamine: '', dateRange: [] },
110 115 extraParams: {},
111 116
112 117 batchMode: false,
... ... @@ -114,8 +119,9 @@ export default {
114 119 currentItems: [],
115 120
116 121 filterVisible: false,
117   - filterForm: { deptId: '', deptName: '', dateRange: [] },
  122 + filterForm: { deptId: '', deptName: '', needExamine: '', dateRange: [] },
118 123 deptSelectVisible: false,
  124 + needExamineOptions: [{ text: '是', value: 'true' }, { text: '否', value: 'false' }],
119 125 statusStyle,
120 126 }
121 127 },
... ... @@ -143,8 +149,18 @@ export default {
143 149 return {
144 150 keyword: this.searchKeywordDebounced || undefined,
145 151 status: this.status || undefined,
146   - type: 'INTL_INVENTORY_AGMT'
  152 + type: 'INTL_INVENTORY_AGMT',
  153 + examineType: this.examineType
147 154 }
  155 + },
  156 + // 仅标准/正式合同 tab 需要"是否本人待办"筛选
  157 + isExamineTab() {
  158 + return this.status === 'STANDARD' || this.status === 'FORMAL'
  159 + },
  160 + examineType() {
  161 + if (this.status === 'STANDARD') return 'STANDARD'
  162 + if (this.status === 'FORMAL') return 'FORMAL'
  163 + return undefined
148 164 }
149 165 },
150 166 watch: {
... ... @@ -193,6 +209,17 @@ export default {
193 209 },
194 210 switchTab(item) {
195 211 this.status = item.value
  212 + // 切到非标准/正式合同 tab 时,清理"是否本人待办"条件
  213 + if (!this.isExamineTab && this.filterForm.needExamine) {
  214 + this.filterForm.needExamine = ''
  215 + const q = { ...this.query }
  216 + delete q.needExamine
  217 + this.query = q
  218 + }
  219 + },
  220 + onNeedExamineChange(e) {
  221 + const raw = e && e.detail && e.detail.value !== undefined ? e.detail.value : (e && e.value !== undefined ? e.value : '')
  222 + this.filterForm.needExamine = raw
196 223 },
197 224 openFilter() {
198 225 this.filterVisible = true
... ...
... ... @@ -141,6 +141,12 @@
141 141 <uni-easyinput v-model="form.specialInstructions" placeholder="请输入特别说明" :inputBorder="false" />
142 142 </template>
143 143 </uni-list-item>
  144 + <uni-list-item v-if="this.customerRemarks.length" class="select-item" :class="defaultRemark ? 'is-filled' : 'is-empty'" clickable
  145 + @click="openSheet('historyRemarks')" :rightText="defaultRemark || '请选择'" showArrow>
  146 + <template v-slot:body>
  147 + <view class="item-title"><text>历史备注</text></view>
  148 + </template>
  149 + </uni-list-item>
144 150 <uni-list-item title="备注">
145 151 <template v-slot:footer>
146 152 <uni-easyinput type="textarea" v-model="form.remarks" placeholder="请输入备注" :inputBorder="false" maxlength="2000" />
... ... @@ -228,7 +234,7 @@
228 234 import SingleSelectSheet from '@/components/single-select/index.vue'
229 235 import RelateSelectSheet from '@/components/relate-select/index.vue'
230 236 import ProductRel from './productRel.vue'
231   -import { getRetailCodeApi, createContractApi, getDeptApi, getContractApi } from '@/api/contract'
  237 +import { getRetailCodeApi, createContractApi, getCustomerRemarks, getCustomerSpecificQualityRequirements, getDeptApi, getContractApi } from '@/api/contract'
232 238 import { getDicByCodes } from '@/utils/dic'
233 239 import { formatCurrencyToChinese } from '@/utils/common'
234 240 import { workshopQueryApi } from '@/api/devManage'
... ... @@ -289,7 +295,10 @@ export default {
289 295 totalAmountIncludingTax: 0,
290 296 productLineList: [],
291 297 productList: [],
  298 + customerRemarks: [],
  299 + defaultRemark: '',
292 300 regionOptions: [],
  301 + qualityReqSeq: 0,
293 302 }
294 303 },
295 304 onLoad(query) {
... ... @@ -310,6 +319,44 @@ export default {
310 319 if (this.copyId) this.loadCopyDetail(this.copyId)
311 320 },
312 321 watch: {
  322 + 'form.buyer': {
  323 + handler(newVal, oldVal) {
  324 + if (newVal) {
  325 + getCustomerRemarks(newVal).then(res => {
  326 + const remarksData = res.data || [];
  327 + this.customerRemarks = remarksData.map((item, index) => ({
  328 + label: `客户备注${index + 1}`,
  329 + value: item,
  330 + }));
  331 + if (remarksData.length > 0) {
  332 + this.defaultRemark = this.customerRemarks[0].label || '';
  333 + this.form.remarks = remarksData[0];
  334 + } else {
  335 + this.form.remarks = '';
  336 + this.defaultRemark = '';
  337 + }
  338 + })
  339 + this.getHistory()
  340 + }
  341 + }
  342 + },
  343 + productLineList: {
  344 + deep: true,
  345 + handler(newVal, oldVal) {
  346 + const n = Array.isArray(newVal) ? newVal : []
  347 + const o = Array.isArray(oldVal) ? oldVal : []
  348 + const changed = []
  349 + for (let i = 0; i < n.length; i++) {
  350 + const ni = n[i] && n[i].productId
  351 + const oi = o[i] && o[i].productId
  352 + if (ni !== oi && ni !== undefined) changed.push(ni)
  353 + }
  354 + if (changed.length && this.form.buyer) {
  355 + const id = changed.join('')
  356 + this.fetchCustomerQualityRequirements(id)
  357 + }
  358 + }
  359 + },
313 360 },
314 361 methods: {
315 362 async loadCopyDetail(id) {
... ... @@ -406,6 +453,49 @@ export default {
406 453 }
407 454 })
408 455 },
  456 + getHistory() {
  457 + console.log('this.productLineList', this.productLineList[0].productId)
  458 + if (!this.productLineList.length || !this.productLineList[0].productId) {
  459 + return;
  460 + }
  461 + const id = this.productLineList.map(it => it.productId).join('')
  462 + this.fetchCustomerQualityRequirements(id)
  463 + },
  464 + async fetchCustomerQualityRequirements(id) {
  465 + if (!this.form.buyer || !id) {
  466 + return;
  467 + }
  468 + this.qualityReqSeq = (Number(this.qualityReqSeq) || 0) + 1
  469 + const seq = this.qualityReqSeq
  470 + try {
  471 + const result = await getCustomerSpecificQualityRequirements({
  472 + customerId: this.form.buyer,
  473 + productIdList:id,
  474 + });
  475 + if (seq !== this.qualityReqSeq) return
  476 + this.updateFormData(result.data || {});
  477 + } catch (error) {
  478 + if (seq !== this.qualityReqSeq) return
  479 + console.error('获取客户质量要求失败:', error);
  480 + // 可以根据需要添加错误提示逻辑
  481 + this.$message.error('获取历史数据失败,请稍后重试');
  482 + }
  483 + },
  484 + // 提取公共的字段更新方法
  485 + updateFormData(result) {
  486 + console.log('result', result)
  487 + const fields = [
  488 + 'component',
  489 + 'packaging',
  490 + 'performance',
  491 + 'pieceWeightHead',
  492 + 'surface',
  493 + 'tolerance',
  494 + ];
  495 + fields.forEach((field) => {
  496 + this.form[field] = result[field] != null ? String(result[field]) : ''
  497 + });
  498 + },
409 499 onProductsChange(products) {
410 500 const list = Array.isArray(products) ? products : []
411 501 const sumQ = list.reduce((acc, it) => acc + (parseFloat(it.quantity) || 0), 0)
... ... @@ -483,7 +573,9 @@ export default {
483 573 setSheet('单价中是否已包含包装费', this.yesNoList)
484 574 } else if (field === 'includesTransportFee') {
485 575 setSheet('单价中是否已包含运费', this.yesNoList)
486   - } else if (field === 'region') {
  576 + } else if (field === 'historyRemarks') {
  577 + setSheet('历史备注', this.customerRemarks)
  578 + }else if (field === 'region') {
487 579 setSheet('区域', this.regionOptions)
488 580 }
489 581 },
... ... @@ -491,8 +583,13 @@ export default {
491 583 const field = this.sheet.field
492 584 if (!field) return
493 585 const v = (value === undefined || value === null) ? '' : value
494   - this.form[field] = v
495   - this.form[field + 'Name'] = label || ''
  586 + if (field === 'historyRemarks') {
  587 + this.defaultRemark = label || ''
  588 + this.form.remarks = v
  589 + }else{
  590 + this.form[field] = v
  591 + this.form[field + 'Name'] = label || ''
  592 + }
496 593 },
497 594 openRelate(fieldKey) {
498 595 let config = {}
... ...
... ... @@ -82,6 +82,11 @@
82 82 >
83 83 <template v-slot="{ model }">
84 84 <view class="filter-form">
  85 + <view class="form-item" v-if="isExamineTab">
  86 + <view class="label">是否本人待办</view>
  87 + <uni-data-checkbox mode="tag" :multiple="false" :value-field="'value'" :text-field="'text'"
  88 + v-model="model.needExamine" @change="onNeedExamineChange" :localdata="needExamineOptions" />
  89 + </view>
85 90 <view class="form-item">
86 91 <view class="label">订货日期</view>
87 92 <uni-datetime-picker type="daterange" v-model="model.dateRange" start="2023-01-01" />
... ... @@ -106,7 +111,7 @@ export default {
106 111 searchKeywordDebounced: '',
107 112 status: 'DRAFT',
108 113
109   - query: { deptId: '', deptName: '', dateRange: [] },
  114 + query: { deptId: '', deptName: '', needExamine: '', dateRange: [] },
110 115 extraParams: {},
111 116
112 117 batchMode: false,
... ... @@ -114,8 +119,9 @@ export default {
114 119 currentItems: [],
115 120
116 121 filterVisible: false,
117   - filterForm: { deptId: '', deptName: '', dateRange: [] },
  122 + filterForm: { deptId: '', deptName: '', needExamine: '', dateRange: [] },
118 123 deptSelectVisible: false,
  124 + needExamineOptions: [{ text: '是', value: 'true' }, { text: '否', value: 'false' }],
119 125 statusStyle
120 126 }
121 127 },
... ... @@ -143,8 +149,18 @@ export default {
143 149 return {
144 150 keyword: this.searchKeywordDebounced || undefined,
145 151 status: this.status || undefined,
146   - type: 'INTL_OPEN_SPEC_AGMT'
  152 + type: 'INTL_OPEN_SPEC_AGMT',
  153 + examineType: this.examineType
147 154 }
  155 + },
  156 + // 仅标准/正式合同 tab 需要"是否本人待办"筛选
  157 + isExamineTab() {
  158 + return this.status === 'STANDARD' || this.status === 'FORMAL'
  159 + },
  160 + examineType() {
  161 + if (this.status === 'STANDARD') return 'STANDARD'
  162 + if (this.status === 'FORMAL') return 'FORMAL'
  163 + return undefined
148 164 }
149 165 },
150 166 watch: {
... ... @@ -193,6 +209,17 @@ export default {
193 209 },
194 210 switchTab(item) {
195 211 this.status = item.value
  212 + // 切到非标准/正式合同 tab 时,清理"是否本人待办"条件
  213 + if (!this.isExamineTab && this.filterForm.needExamine) {
  214 + this.filterForm.needExamine = ''
  215 + const q = { ...this.query }
  216 + delete q.needExamine
  217 + this.query = q
  218 + }
  219 + },
  220 + onNeedExamineChange(e) {
  221 + const raw = e && e.detail && e.detail.value !== undefined ? e.detail.value : (e && e.value !== undefined ? e.value : '')
  222 + this.filterForm.needExamine = raw
196 223 },
197 224 openFilter() {
198 225 this.filterVisible = true
... ...
... ... @@ -143,6 +143,12 @@
143 143 <uni-easyinput v-model="form.specialInstructions" placeholder="请输入特别说明" :inputBorder="false" />
144 144 </template>
145 145 </uni-list-item>
  146 + <uni-list-item v-if="this.customerRemarks.length" class="select-item" :class="defaultRemark ? 'is-filled' : 'is-empty'" clickable
  147 + @click="openSheet('historyRemarks')" :rightText="defaultRemark || '请选择'" showArrow>
  148 + <template v-slot:body>
  149 + <view class="item-title"><text>历史备注</text></view>
  150 + </template>
  151 + </uni-list-item>
146 152 <uni-list-item title="备注">
147 153 <template v-slot:footer>
148 154 <uni-easyinput type="textarea" v-model="form.remarks" placeholder="请输入备注" :inputBorder="false" maxlength="2000" />
... ... @@ -231,7 +237,7 @@ import SingleSelectSheet from '@/components/single-select/index.vue'
231 237 import RelateSelectSheet from '@/components/relate-select/index.vue'
232 238 import ProductRel from './productRel.vue'
233 239 import CitySelector from '@/components/city-selector/index.vue'
234   -import { getRetailCodeApi, createContractApi, getDeptApi, getContractApi } from '@/api/contract'
  240 +import { getRetailCodeApi, createContractApi, getCustomerRemarks, getCustomerSpecificQualityRequirements, getDeptApi, getContractApi } from '@/api/contract'
235 241 import { getDicByCodes } from '@/utils/dic'
236 242 import { formatCurrencyToChinese } from '@/utils/common'
237 243 import { workshopQueryApi } from '@/api/devManage'
... ... @@ -298,6 +304,9 @@ export default {
298 304 rawToProdRatioList: [],
299 305 rawProductList: [],
300 306 rawProductGradeList: [],
  307 + customerRemarks: [],
  308 + defaultRemark: '',
  309 + qualityReqSeq: 0,
301 310 }
302 311 },
303 312 onLoad(query) {
... ... @@ -323,6 +332,44 @@ export default {
323 332 })
324 333 },
325 334 watch: {
  335 + 'form.buyer': {
  336 + handler(newVal, oldVal) {
  337 + if (newVal) {
  338 + getCustomerRemarks(newVal).then(res => {
  339 + const remarksData = res.data || [];
  340 + this.customerRemarks = remarksData.map((item, index) => ({
  341 + label: `客户备注${index + 1}`,
  342 + value: item,
  343 + }));
  344 + if (remarksData.length > 0) {
  345 + this.defaultRemark = this.customerRemarks[0].label || '';
  346 + this.form.remarks = remarksData[0];
  347 + } else {
  348 + this.form.remarks = '';
  349 + this.defaultRemark = '';
  350 + }
  351 + })
  352 + this.getHistory()
  353 + }
  354 + }
  355 + },
  356 + productLineList: {
  357 + deep: true,
  358 + handler(newVal, oldVal) {
  359 + const n = Array.isArray(newVal) ? newVal : []
  360 + const o = Array.isArray(oldVal) ? oldVal : []
  361 + const changed = []
  362 + for (let i = 0; i < n.length; i++) {
  363 + const ni = n[i] && n[i].rawProductId
  364 + const oi = o[i] && o[i].rawProductId
  365 + if (ni !== oi && ni !== undefined) changed.push(ni)
  366 + }
  367 + if (changed.length && this.form.buyer) {
  368 + const id = changed.join('')
  369 + this.fetchCustomerQualityRequirements(id)
  370 + }
  371 + }
  372 + },
326 373 },
327 374 methods: {
328 375 async loadCopyDetail(id) {
... ... @@ -442,6 +489,49 @@ export default {
442 489 }
443 490 })
444 491 },
  492 + getHistory() {
  493 + console.log('this.productLineList', this.productLineList[0].rawProductId)
  494 + if (!this.productLineList.length || !this.productLineList[0].rawProductId) {
  495 + return;
  496 + }
  497 + const id = this.productLineList.map(it => it.rawProductId).join('')
  498 + this.fetchCustomerQualityRequirements(id)
  499 + },
  500 + async fetchCustomerQualityRequirements(id) {
  501 + if (!this.form.buyer || !id) {
  502 + return;
  503 + }
  504 + this.qualityReqSeq = (Number(this.qualityReqSeq) || 0) + 1
  505 + const seq = this.qualityReqSeq
  506 + try {
  507 + const result = await getCustomerSpecificQualityRequirements({
  508 + customerId: this.form.buyer,
  509 + productIdList:id,
  510 + });
  511 + if (seq !== this.qualityReqSeq) return
  512 + this.updateFormData(result.data || {});
  513 + } catch (error) {
  514 + if (seq !== this.qualityReqSeq) return
  515 + console.error('获取客户质量要求失败:', error);
  516 + // 可以根据需要添加错误提示逻辑
  517 + this.$message.error('获取历史数据失败,请稍后重试');
  518 + }
  519 + },
  520 + // 提取公共的字段更新方法
  521 + updateFormData(result) {
  522 + console.log('result', result)
  523 + const fields = [
  524 + 'component',
  525 + 'packaging',
  526 + 'performance',
  527 + 'pieceWeightHead',
  528 + 'surface',
  529 + 'tolerance',
  530 + ];
  531 + fields.forEach((field) => {
  532 + this.form[field] = result[field] != null ? String(result[field]) : ''
  533 + });
  534 + },
445 535 onProductsChange(products) {
446 536 const list = Array.isArray(products) ? products : []
447 537 const sumQ = list.reduce((acc, it) => acc + (parseFloat(it.productQuantity) || 0), 0)
... ... @@ -528,6 +618,8 @@ export default {
528 618 setSheet('单价中是否已包含包装费', this.yesNoList)
529 619 } else if (field === 'includesTransportFee') {
530 620 setSheet('单价中是否已包含运费', this.yesNoList)
  621 + } else if (field === 'historyRemarks') {
  622 + setSheet('历史备注', this.customerRemarks)
531 623 }else if (field === 'region') {
532 624 setSheet('区域', this.regionOptions)
533 625 }
... ... @@ -536,8 +628,13 @@ export default {
536 628 const field = this.sheet.field
537 629 if (!field) return
538 630 const v = (value === undefined || value === null) ? '' : value
539   - this.form[field] = v
540   - this.form[field + 'Name'] = label || ''
  631 + if (field === 'historyRemarks') {
  632 + this.defaultRemark = label || ''
  633 + this.form.remarks = v
  634 + }else{
  635 + this.form[field] = v
  636 + this.form[field + 'Name'] = label || ''
  637 + }
541 638 },
542 639 openRelate(fieldKey) {
543 640 let config = {}
... ...
... ... @@ -80,6 +80,11 @@
80 80 >
81 81 <template v-slot="{ model }">
82 82 <view class="filter-form">
  83 + <view class="form-item" v-if="isExamineTab">
  84 + <view class="label">是否本人待办</view>
  85 + <uni-data-checkbox mode="tag" :multiple="false" :value-field="'value'" :text-field="'text'"
  86 + v-model="model.needExamine" @change="onNeedExamineChange" :localdata="needExamineOptions" />
  87 + </view>
83 88 <view class="form-item">
84 89 <view class="label">订货日期</view>
85 90 <uni-datetime-picker type="daterange" v-model="model.dateRange" start="2023-01-01" />
... ... @@ -104,7 +109,7 @@ export default {
104 109 searchKeywordDebounced: '',
105 110 status: 'DRAFT',
106 111
107   - query: { deptId: '', deptName: '', dateRange: [] },
  112 + query: { deptId: '', deptName: '', needExamine: '', dateRange: [] },
108 113 extraParams: {},
109 114
110 115 batchMode: false,
... ... @@ -112,8 +117,9 @@ export default {
112 117 currentItems: [],
113 118
114 119 filterVisible: false,
115   - filterForm: { deptId: '', deptName: '', dateRange: [] },
  120 + filterForm: { deptId: '', deptName: '', needExamine: '', dateRange: [] },
116 121 deptSelectVisible: false,
  122 + needExamineOptions: [{ text: '是', value: 'true' }, { text: '否', value: 'false' }],
117 123 statusStyle,
118 124 }
119 125 },
... ... @@ -139,8 +145,18 @@ export default {
139 145 return {
140 146 keyword: this.searchKeywordDebounced || undefined,
141 147 status: this.status || undefined,
142   - type: 'PROCESS_STD_AGMT'
  148 + type: 'PROCESS_STD_AGMT',
  149 + examineType: this.examineType
143 150 }
  151 + },
  152 + // 仅标准/正式合同 tab 需要"是否本人待办"筛选
  153 + isExamineTab() {
  154 + return this.status === 'STANDARD' || this.status === 'FORMAL'
  155 + },
  156 + examineType() {
  157 + if (this.status === 'STANDARD') return 'STANDARD'
  158 + if (this.status === 'FORMAL') return 'FORMAL'
  159 + return undefined
144 160 }
145 161 },
146 162 watch: {
... ... @@ -191,6 +207,17 @@ export default {
191 207 },
192 208 switchTab(item) {
193 209 this.status = item.value
  210 + // 切到非标准/正式合同 tab 时,清理"是否本人待办"条件
  211 + if (!this.isExamineTab && this.filterForm.needExamine) {
  212 + this.filterForm.needExamine = ''
  213 + const q = { ...this.query }
  214 + delete q.needExamine
  215 + this.query = q
  216 + }
  217 + },
  218 + onNeedExamineChange(e) {
  219 + const raw = e && e.detail && e.detail.value !== undefined ? e.detail.value : (e && e.value !== undefined ? e.value : '')
  220 + this.filterForm.needExamine = raw
194 221 },
195 222 openFilter() {
196 223 this.filterVisible = true
... ...
... ... @@ -139,6 +139,12 @@
139 139 <uni-easyinput v-model="form.specialInstructions" placeholder="请输入特别说明" :inputBorder="false" />
140 140 </template>
141 141 </uni-list-item>
  142 + <uni-list-item v-if="this.customerRemarks.length" class="select-item" :class="defaultRemark ? 'is-filled' : 'is-empty'" clickable
  143 + @click="openSheet('historyRemarks')" :rightText="defaultRemark || '请选择'" showArrow>
  144 + <template v-slot:body>
  145 + <view class="item-title"><text>历史备注</text></view>
  146 + </template>
  147 + </uni-list-item>
142 148 <uni-list-item title="备注">
143 149 <template v-slot:footer>
144 150 <uni-easyinput type="textarea" v-model="form.remarks" placeholder="请输入备注" :inputBorder="false" maxlength="2000" />
... ... @@ -227,7 +233,7 @@ import SingleSelectSheet from '@/components/single-select/index.vue'
227 233 import RelateSelectSheet from '@/components/relate-select/index.vue'
228 234 import ProductRel from './productRel.vue'
229 235 import CitySelector from '@/components/city-selector/index.vue'
230   -import { getRetailCodeApi, createContractApi, getDeptApi, getContractApi } from '@/api/contract'
  236 +import { getRetailCodeApi, createContractApi, getCustomerRemarks, getCustomerSpecificQualityRequirements, getDeptApi, getContractApi } from '@/api/contract'
231 237 import { getDicByCodes } from '@/utils/dic'
232 238 import { formatCurrencyToChinese } from '@/utils/common'
233 239 import { workshopQueryApi } from '@/api/devManage'
... ... @@ -289,7 +295,10 @@ export default {
289 295 totalAmountIncludingTax: 0,
290 296 productLineList: [],
291 297 productList: [],
  298 + customerRemarks: [],
  299 + defaultRemark: '',
292 300 regionOptions: [],
  301 + qualityReqSeq: 0,
293 302 }
294 303 },
295 304 onLoad(query) {
... ... @@ -315,6 +324,45 @@ export default {
315 324 })
316 325 },
317 326 watch: {
  327 + 'form.buyer': {
  328 + handler(newVal, oldVal) {
  329 + if (newVal) {
  330 + getCustomerRemarks(newVal).then(res => {
  331 + const remarksData = res.data || [];
  332 + this.customerRemarks = remarksData.map((item, index) => ({
  333 + label: `客户备注${index + 1}`,
  334 + value: item,
  335 + }));
  336 + if (remarksData.length > 0) {
  337 + this.defaultRemark = this.customerRemarks[0].label || '';
  338 + this.form.remarks = remarksData[0];
  339 + } else {
  340 + this.form.remarks = '';
  341 + this.defaultRemark = '';
  342 + }
  343 + })
  344 + this.getHistory()
  345 + }
  346 + }
  347 + },
  348 + productLineList: {
  349 + deep: true,
  350 + handler(newVal, oldVal) {
  351 + const n = Array.isArray(newVal) ? newVal : []
  352 + const o = Array.isArray(oldVal) ? oldVal : []
  353 + const changed = []
  354 + for (let i = 0; i < n.length; i++) {
  355 + const ni = n[i] && n[i].productId
  356 + const oi = o[i] && o[i].productId
  357 + if (ni !== oi && ni !== undefined) changed.push(ni)
  358 + }
  359 + console.log('changed', changed)
  360 + if (changed.length && this.form.buyer) {
  361 + const id = changed.join('')
  362 + this.fetchCustomerQualityRequirements(id)
  363 + }
  364 + }
  365 + },
318 366 },
319 367 methods: {
320 368 async loadCopyDetail(id) {
... ... @@ -412,6 +460,49 @@ export default {
412 460 }
413 461 })
414 462 },
  463 + getHistory() {
  464 + console.log('this.productLineList', this.productLineList[0].productId)
  465 + if (!this.productLineList.length || !this.productLineList[0].productId) {
  466 + return;
  467 + }
  468 + const id = this.productLineList.map(it => it.productId).join('')
  469 + this.fetchCustomerQualityRequirements(id)
  470 + },
  471 + async fetchCustomerQualityRequirements(id) {
  472 + if (!this.form.buyer || !id) {
  473 + return;
  474 + }
  475 + this.qualityReqSeq = (Number(this.qualityReqSeq) || 0) + 1
  476 + const seq = this.qualityReqSeq
  477 + try {
  478 + const result = await getCustomerSpecificQualityRequirements({
  479 + customerId: this.form.buyer,
  480 + productIdList:id,
  481 + });
  482 + if (seq !== this.qualityReqSeq) return
  483 + this.updateFormData(result.data || {});
  484 + } catch (error) {
  485 + if (seq !== this.qualityReqSeq) return
  486 + console.error('获取客户质量要求失败:', error);
  487 + // 可以根据需要添加错误提示逻辑
  488 + this.$message.error('获取历史数据失败,请稍后重试');
  489 + }
  490 + },
  491 + // 提取公共的字段更新方法
  492 + updateFormData(result) {
  493 + console.log('result', result)
  494 + const fields = [
  495 + 'component',
  496 + 'packaging',
  497 + 'performance',
  498 + 'pieceWeightHead',
  499 + 'surface',
  500 + 'tolerance',
  501 + ];
  502 + fields.forEach((field) => {
  503 + this.form[field] = result[field] != null ? String(result[field]) : ''
  504 + });
  505 + },
415 506 onProductsChange(products) {
416 507 const list = Array.isArray(products) ? products : []
417 508 const sumQ = list.reduce((acc, it) => acc + (parseFloat(it.quantity) || 0), 0)
... ... @@ -503,6 +594,8 @@ export default {
503 594 setSheet('单价中是否已包含包装费', this.yesNoList)
504 595 } else if (field === 'includesTransportFee') {
505 596 setSheet('单价中是否已包含运费', this.yesNoList)
  597 + } else if (field === 'historyRemarks') {
  598 + setSheet('历史备注', this.customerRemarks)
506 599 }else if (field === 'region') {
507 600 setSheet('区域', this.regionOptions)
508 601 }
... ... @@ -511,8 +604,13 @@ export default {
511 604 const field = this.sheet.field
512 605 if (!field) return
513 606 const v = (value === undefined || value === null) ? '' : value
514   - this.form[field] = v
515   - this.form[field + 'Name'] = label || ''
  607 + if (field === 'historyRemarks') {
  608 + this.defaultRemark = label || ''
  609 + this.form.remarks = v
  610 + }else{
  611 + this.form[field] = v
  612 + this.form[field + 'Name'] = label || ''
  613 + }
516 614 },
517 615 openRelate(fieldKey) {
518 616 let config = {}
... ...
... ... @@ -137,6 +137,12 @@
137 137 <uni-easyinput v-model="form.specialInstructions" placeholder="请输入特别说明" :inputBorder="false" />
138 138 </template>
139 139 </uni-list-item>
  140 + <uni-list-item v-if="this.customerRemarks.length" class="select-item" :class="defaultRemark ? 'is-filled' : 'is-empty'" clickable
  141 + @click="openSheet('historyRemarks')" :rightText="defaultRemark || '请选择'" showArrow>
  142 + <template v-slot:body>
  143 + <view class="item-title"><text>历史备注</text></view>
  144 + </template>
  145 + </uni-list-item>
140 146 <uni-list-item title="备注">
141 147 <template v-slot:footer>
142 148 <uni-easyinput type="textarea" v-model="form.remarks" placeholder="请输入备注" :inputBorder="false" maxlength="2000" />
... ... @@ -225,7 +231,7 @@ import SingleSelectSheet from '@/components/single-select/index.vue'
225 231 import RelateSelectSheet from '@/components/relate-select/index.vue'
226 232 import ProductRel from './productRel.vue'
227 233 import CitySelector from '@/components/city-selector/index.vue'
228   -import { getRetailCodeApi, createContractApi, getDeptApi,getContractApi } from '@/api/contract'
  234 +import { getRetailCodeApi, createContractApi,getCustomerRemarks,getCustomerSpecificQualityRequirements, getDeptApi,getContractApi } from '@/api/contract'
229 235 import { getDicByCodes } from '@/utils/dic'
230 236 import { formatCurrencyToChinese } from '@/utils/common'
231 237 import { workshopQueryApi } from '@/api/devManage'
... ... @@ -287,7 +293,10 @@ export default {
287 293 totalAmountIncludingTax: 0,
288 294 productLineList: [],
289 295 productList: [],
  296 + customerRemarks: [],
  297 + defaultRemark: '',
290 298 regionOptions: [],
  299 + qualityReqSeq: 0,
291 300 }
292 301 },
293 302 onLoad(query) {
... ... @@ -313,6 +322,44 @@ export default {
313 322 })
314 323 },
315 324 watch: {
  325 + 'form.buyer': {
  326 + handler(newVal, oldVal) {
  327 + if (newVal) {
  328 + getCustomerRemarks(newVal).then(res => {
  329 + const remarksData = res.data || [];
  330 + this.customerRemarks = remarksData.map((item, index) => ({
  331 + label: `客户备注${index + 1}`,
  332 + value: item,
  333 + }));
  334 + if (remarksData.length > 0) {
  335 + this.defaultRemark = this.customerRemarks[0].label || '';
  336 + this.form.remarks = remarksData[0];
  337 + } else {
  338 + this.form.remarks = '';
  339 + this.defaultRemark = '';
  340 + }
  341 + })
  342 + this.getHistory()
  343 + }
  344 + }
  345 + },
  346 + productLineList: {
  347 + deep: true,
  348 + handler(newVal, oldVal) {
  349 + const n = Array.isArray(newVal) ? newVal : []
  350 + const o = Array.isArray(oldVal) ? oldVal : []
  351 + const changed = []
  352 + for (let i = 0; i < n.length; i++) {
  353 + const ni = n[i] && n[i].productId
  354 + const oi = o[i] && o[i].productId
  355 + if (ni !== oi && ni !== undefined) changed.push(ni)
  356 + }
  357 + if (changed.length && this.form.buyer) {
  358 + const id = changed.join('')
  359 + this.fetchCustomerQualityRequirements(id)
  360 + }
  361 + }
  362 + },
316 363 },
317 364 methods: {
318 365 async loadCopyDetail(id) {
... ... @@ -410,6 +457,49 @@ export default {
410 457 }
411 458 })
412 459 },
  460 + getHistory() {
  461 + console.log('this.productLineList', this.productLineList[0].productId)
  462 + if (!this.productLineList.length || !this.productLineList[0].productId) {
  463 + return;
  464 + }
  465 + const id = this.productLineList.map(it => it.productId).join('')
  466 + this.fetchCustomerQualityRequirements(id)
  467 + },
  468 + async fetchCustomerQualityRequirements(id) {
  469 + if (!this.form.buyer || !id) {
  470 + return;
  471 + }
  472 + this.qualityReqSeq = (Number(this.qualityReqSeq) || 0) + 1
  473 + const seq = this.qualityReqSeq
  474 + try {
  475 + const result = await getCustomerSpecificQualityRequirements({
  476 + customerId: this.form.buyer,
  477 + productIdList:id,
  478 + });
  479 + if (seq !== this.qualityReqSeq) return
  480 + this.updateFormData(result.data || {});
  481 + } catch (error) {
  482 + if (seq !== this.qualityReqSeq) return
  483 + console.error('获取客户质量要求失败:', error);
  484 + // 可以根据需要添加错误提示逻辑
  485 + this.$message.error('获取历史数据失败,请稍后重试');
  486 + }
  487 + },
  488 + // 提取公共的字段更新方法
  489 + updateFormData(result) {
  490 + console.log('result', result)
  491 + const fields = [
  492 + 'component',
  493 + 'packaging',
  494 + 'performance',
  495 + 'pieceWeightHead',
  496 + 'surface',
  497 + 'tolerance',
  498 + ];
  499 + fields.forEach((field) => {
  500 + this.form[field] = result[field] != null ? String(result[field]) : ''
  501 + });
  502 + },
413 503 onProductsChange(products) {
414 504 const list = Array.isArray(products) ? products : []
415 505 const sumQ = list.reduce((acc, it) => acc + (parseFloat(it.quantity) || 0), 0)
... ... @@ -501,6 +591,8 @@ export default {
501 591 setSheet('单价中是否已包含包装费', this.yesNoList)
502 592 } else if (field === 'includesTransportFee') {
503 593 setSheet('单价中是否已包含运费', this.yesNoList)
  594 + } else if (field === 'historyRemarks') {
  595 + setSheet('历史备注', this.customerRemarks)
504 596 } else if (field === 'region') {
505 597 setSheet('区域', this.regionOptions)
506 598 }
... ... @@ -509,8 +601,13 @@ export default {
509 601 const field = this.sheet.field
510 602 if (!field) return
511 603 const v = (value === undefined || value === null) ? '' : value
512   - this.form[field] = v
513   - this.form[field + 'Name'] = label || ''
  604 + if (field === 'historyRemarks') {
  605 + this.defaultRemark = label || ''
  606 + this.form.remarks = v
  607 + }else{
  608 + this.form[field] = v
  609 + this.form[field + 'Name'] = label || ''
  610 + }
514 611 },
515 612 openRelate(fieldKey) {
516 613 let config = {}
... ...
... ... @@ -139,6 +139,12 @@
139 139 <uni-easyinput v-model="form.specialInstructions" placeholder="请输入特别说明" :inputBorder="false" />
140 140 </template>
141 141 </uni-list-item>
  142 + <uni-list-item v-if="this.customerRemarks.length" class="select-item" :class="defaultRemark ? 'is-filled' : 'is-empty'" clickable
  143 + @click="openSheet('historyRemarks')" :rightText="defaultRemark || '请选择'" showArrow>
  144 + <template v-slot:body>
  145 + <view class="item-title"><text>历史备注</text></view>
  146 + </template>
  147 + </uni-list-item>
142 148 <uni-list-item title="备注">
143 149 <template v-slot:footer>
144 150 <uni-easyinput type="textarea" v-model="form.remarks" placeholder="请输入备注" :inputBorder="false" maxlength="2000" />
... ... @@ -227,7 +233,7 @@ import SingleSelectSheet from '@/components/single-select/index.vue'
227 233 import RelateSelectSheet from '@/components/relate-select/index.vue'
228 234 import ProductRel from './productRel.vue'
229 235 import CitySelector from '@/components/city-selector/index.vue'
230   -import { getRetailCodeApi, createContractApi, getDeptApi, getContractApi } from '@/api/contract'
  236 +import { getRetailCodeApi, createContractApi, getCustomerRemarks, getCustomerSpecificQualityRequirements, getDeptApi, getContractApi } from '@/api/contract'
231 237 import { getDicByCodes } from '@/utils/dic'
232 238 import { formatCurrencyToChinese } from '@/utils/common'
233 239 import { workshopQueryApi } from '@/api/devManage'
... ... @@ -289,7 +295,10 @@ export default {
289 295 totalAmountIncludingTax: 0,
290 296 productLineList: [],
291 297 productList: [],
  298 + customerRemarks: [],
  299 + defaultRemark: '',
292 300 regionOptions: [],
  301 + qualityReqSeq: 0,
293 302 }
294 303 },
295 304 onLoad(query) {
... ... @@ -315,6 +324,46 @@ export default {
315 324 })
316 325 },
317 326 watch: {
  327 + 'form.buyer': {
  328 + handler(newVal, oldVal) {
  329 + if (newVal) {
  330 + getCustomerRemarks(newVal).then(res => {
  331 + const remarksData = res.data || [];
  332 + this.customerRemarks = remarksData.map((item, index) => ({
  333 + label: `客户备注${index + 1}`,
  334 + value: item,
  335 + }));
  336 + if (remarksData.length > 0) {
  337 + this.defaultRemark = this.customerRemarks[0].label || '';
  338 + this.form.remarks = remarksData[0];
  339 + } else {
  340 + this.form.remarks = '';
  341 + this.defaultRemark = '';
  342 + }
  343 + })
  344 + this.getHistory()
  345 + }
  346 + }
  347 + },
  348 + productLineList: {
  349 + deep: true,
  350 + handler(newVal, oldVal) {
  351 + console.log('newVal', newVal)
  352 + console.log('oldVal', oldVal)
  353 + const n = Array.isArray(newVal) ? newVal : []
  354 + const o = Array.isArray(oldVal) ? oldVal : []
  355 + const changed = []
  356 + for (let i = 0; i < n.length; i++) {
  357 + const ni = n[i] && n[i].productId
  358 + const oi = o[i] && o[i].productId
  359 + if (ni !== oi && ni !== undefined) changed.push(ni)
  360 + }
  361 + if (changed.length && this.form.buyer) {
  362 + const id = changed.join('')
  363 + this.fetchCustomerQualityRequirements(id)
  364 + }
  365 + }
  366 + },
318 367 },
319 368 methods: {
320 369 async loadCopyDetail(id) {
... ... @@ -412,6 +461,49 @@ export default {
412 461 }
413 462 })
414 463 },
  464 + getHistory() {
  465 + console.log('this.productLineList', this.productLineList[0].productId)
  466 + if (!this.productLineList.length || !this.productLineList[0].productId) {
  467 + return;
  468 + }
  469 + const id = this.productLineList.map(it => it.productId).join('')
  470 + this.fetchCustomerQualityRequirements(id)
  471 + },
  472 + async fetchCustomerQualityRequirements(id) {
  473 + if (!this.form.buyer || !id) {
  474 + return;
  475 + }
  476 + this.qualityReqSeq = (Number(this.qualityReqSeq) || 0) + 1
  477 + const seq = this.qualityReqSeq
  478 + try {
  479 + const result = await getCustomerSpecificQualityRequirements({
  480 + customerId: this.form.buyer,
  481 + productIdList:id,
  482 + });
  483 + if (seq !== this.qualityReqSeq) return
  484 + this.updateFormData(result.data || {});
  485 + } catch (error) {
  486 + if (seq !== this.qualityReqSeq) return
  487 + console.error('获取客户质量要求失败:', error);
  488 + // 可以根据需要添加错误提示逻辑
  489 + this.$message.error('获取历史数据失败,请稍后重试');
  490 + }
  491 + },
  492 + // 提取公共的字段更新方法
  493 + updateFormData(result) {
  494 + console.log('result', result)
  495 + const fields = [
  496 + 'component',
  497 + 'packaging',
  498 + 'performance',
  499 + 'pieceWeightHead',
  500 + 'surface',
  501 + 'tolerance',
  502 + ];
  503 + fields.forEach((field) => {
  504 + this.form[field] = result[field] != null ? String(result[field]) : ''
  505 + });
  506 + },
415 507 onProductsChange(products) {
416 508 console.log('products', products)
417 509 const list = Array.isArray(products) ? products : []
... ... @@ -504,6 +596,8 @@ export default {
504 596 setSheet('单价中是否已包含包装费', this.yesNoList)
505 597 } else if (field === 'includesTransportFee') {
506 598 setSheet('单价中是否已包含运费', this.yesNoList)
  599 + } else if (field === 'historyRemarks') {
  600 + setSheet('历史备注', this.customerRemarks)
507 601 } else if (field === 'region') {
508 602 setSheet('区域', this.regionOptions)
509 603 }
... ... @@ -512,8 +606,13 @@ export default {
512 606 const field = this.sheet.field
513 607 if (!field) return
514 608 const v = (value === undefined || value === null) ? '' : value
515   - this.form[field] = v
516   - this.form[field + 'Name'] = label || ''
  609 + if (field === 'historyRemarks') {
  610 + this.defaultRemark = label || ''
  611 + this.form.remarks = v
  612 + }else{
  613 + this.form[field] = v
  614 + this.form[field + 'Name'] = label || ''
  615 + }
517 616 },
518 617 openRelate(fieldKey) {
519 618 let config = {}
... ...
... ... @@ -66,6 +66,11 @@
66 66 :localdata="categoryLocal" />
67 67 </view>
68 68 <view class="form-item">
  69 + <view class="label">是否本人待办</view>
  70 + <uni-data-checkbox mode="tag" :multiple="false" :value-field="'value'" :text-field="'text'"
  71 + v-model="model.needExamine" @change="onNeedExamineChange" :localdata="needExamineLocal" />
  72 + </view>
  73 + <view class="form-item">
69 74 <view class="label">登记日期</view>
70 75 <uni-datetime-picker type="daterange" v-model="model.dateRange" start="2023-01-01" />
71 76 </view>
... ... @@ -104,6 +109,7 @@
104 109 query: {
105 110 status: '',
106 111 companySuggestedCategory: '',
  112 + needExamine: '',
107 113 dateRange: []
108 114 },
109 115 extraParams: {},
... ... @@ -117,6 +123,7 @@
117 123 filterForm: {
118 124 status: '',
119 125 companySuggestedCategory: '',
  126 + needExamine: '',
120 127 dateRange: []
121 128 },
122 129 dicOptions: {
... ... @@ -126,7 +133,8 @@
126 133 CREDIT_ZONE: []
127 134 },
128 135 statusLocal: [],
129   - categoryLocal: []
  136 + categoryLocal: [],
  137 + needExamineLocal: [{ text: '是', value: 'true' }, { text: '否', value: 'false' }]
130 138 }
131 139 },
132 140 computed: {
... ... @@ -208,6 +216,9 @@
208 216 .companySuggestedCategory !== '') {
209 217 payload.companySuggestedCategory = this.filterForm.companySuggestedCategory
210 218 }
  219 + if ((payload.needExamine === '' || payload.needExamine == null) && this.filterForm.needExamine !== '') {
  220 + payload.needExamine = this.filterForm.needExamine
  221 + }
211 222 this.query = {
212 223 ...payload
213 224 }
... ... @@ -223,6 +234,11 @@
223 234 e.value : '')
224 235 this.filterForm.companySuggestedCategory = raw
225 236 },
  237 + onNeedExamineChange(e) {
  238 + const raw = e && e.detail && e.detail.value !== undefined ? e.detail.value : (e && e.value !== undefined ?
  239 + e.value : '')
  240 + this.filterForm.needExamine = raw
  241 + },
226 242
227 243 // 列表接口(真实请求)
228 244 fetchList({
... ...
... ... @@ -72,6 +72,12 @@
72 72 </view>
73 73
74 74 <view class="form-item">
  75 + <view class="label">是否本人待办</view>
  76 + <uni-data-checkbox mode="tag" :multiple="false" :value-field="'value'" :text-field="'text'"
  77 + v-model="model.needExamine" @change="onNeedExamineChange" :localdata="needExamineOptions" />
  78 + </view>
  79 +
  80 + <view class="form-item">
75 81 <view class="label">订货日期</view>
76 82 <uni-datetime-picker type="daterange" v-model="model.dateRange" start="2023-01-01" @change="onDateChange($event, model)" />
77 83 </view>
... ... @@ -105,12 +111,14 @@ export default {
105 111 workshopId: '',
106 112 workshopIdName: '',
107 113 status: '',
  114 + needExamine: '',
108 115 dateRange: []
109 116 },
110 117 workshopOptions: [],
111 118 statusOptions: [],
112 119 examineStatusOptions: [],
113 120 sampleOrderOptions: [{ text: '是', value: 'true' }, { text: '否', value: 'false' }],
  121 + needExamineOptions: [{ text: '是', value: 'true' }, { text: '否', value: 'false' }],
114 122 query: {},
115 123 extraParams: {},
116 124 currentItems: []
... ... @@ -215,6 +223,10 @@ export default {
215 223 console.log('onSampleOrderChange', raw, typeof raw)
216 224 this.filterForm.sampleOrder = raw;
217 225 },
  226 + onNeedExamineChange(e) {
  227 + const raw = e && e.detail && e.detail.value !== undefined ? e.detail.value : (e && e.value !== undefined ? e.value : '')
  228 + this.filterForm.needExamine = raw
  229 + },
218 230 onWorkshopChange(e) {
219 231 const raw = e && e.detail && e.detail.value !== undefined ? e.detail.value : (e && e.value !== undefined ? e.value : '')
220 232 this.filterForm.workshopId = raw
... ...