Commit 362b7ef1b311bff35ed365fa54ef1a9713ee178f

Authored by gesilong
2 parents c50564e6 d8ca7459

Merge branch 'cjerp-contract-1.0' into test_cjerp

@@ -207,6 +207,16 @@ export function priceLock(data) { @@ -207,6 +207,16 @@ export function priceLock(data) {
207 region 207 region
208 }) 208 })
209 } 209 }
  210 +//拆分数量
  211 +export function splitQuantityLock(data) {
  212 + return request({
  213 + url: `${baseUrl}/contractDistributorStandard/split`,
  214 + method: 'post',
  215 + data,
  216 + contentType: ContentTypeEnum.JSON,
  217 + region
  218 + })
  219 +}
210 220
211 // 删除合同 221 // 删除合同
212 export function deleteContractApi(id) { 222 export function deleteContractApi(id) {
@@ -31,7 +31,7 @@ @@ -31,7 +31,7 @@
31 }}</text></view> 31 }}</text></view>
32 <view class="row"><text class="label">运输方式</text><text class="value">{{ detail.transportMode || 32 <view class="row"><text class="label">运输方式</text><text class="value">{{ detail.transportMode ||
33 '-'}}</text></view> 33 '-'}}</text></view>
34 - <view class="row"><text class="label">目的地</text><text class="value">{{ detail.destinationLabel || '-' 34 + <view class="row"><text class="label">目的地</text><text class="value">{{ detail.foreignDestination || '-'
35 }}</text></view> 35 }}</text></view>
36 <view class="row"><text class="label">单价中是否已包含包装费</text><text class="value">{{ 36 <view class="row"><text class="label">单价中是否已包含包装费</text><text class="value">{{
37 detail.includesPackagingFeeName || '-' }}</text></view> 37 detail.includesPackagingFeeName || '-' }}</text></view>
@@ -114,8 +114,7 @@ export default { @@ -114,8 +114,7 @@ export default {
114 packagingRequirements: '', 114 packagingRequirements: '',
115 paymentTerms: '', 115 paymentTerms: '',
116 transportMode: '', 116 transportMode: '',
117 - destinationId: '',  
118 - destinationLabel: '', 117 + foreignDestination: '',
119 specialInstructions: '', 118 specialInstructions: '',
120 remarks: '', 119 remarks: '',
121 pieceWeightHead: '', 120 pieceWeightHead: '',
@@ -154,8 +153,7 @@ export default { @@ -154,8 +153,7 @@ export default {
154 ...this.detail, 153 ...this.detail,
155 ...data, 154 ...data,
156 includesPackagingFeeName, includesTransportFeeName, 155 includesPackagingFeeName, includesTransportFeeName,
157 - destinationId: data.provinceId && data.cityId && data.districtId ? [data.provinceId, data.cityId, data.districtId] : '',  
158 - destinationLabel: data.provinceName && data.cityName && data.districtName ? `${data.provinceName} / ${data.cityName} / ${data.districtName}` : '', 156 + foreignDestination: (data.foreignDestination || ''),
159 } 157 }
160 const lines = Array.isArray(data.contractDistributorLineList) ? data.contractDistributorLineList : [] 158 const lines = Array.isArray(data.contractDistributorLineList) ? data.contractDistributorLineList : []
161 this.productList = lines 159 this.productList = lines
@@ -31,7 +31,7 @@ @@ -31,7 +31,7 @@
31 }}</text></view> 31 }}</text></view>
32 <view class="row"><text class="label">运输方式</text><text class="value">{{ detail.transportMode || 32 <view class="row"><text class="label">运输方式</text><text class="value">{{ detail.transportMode ||
33 '-'}}</text></view> 33 '-'}}</text></view>
34 - <view class="row"><text class="label">目的地</text><text class="value">{{ detail.destinationLabel || '-' 34 + <view class="row"><text class="label">目的地</text><text class="value">{{ detail.foreignDestination || '-'
35 }}</text></view> 35 }}</text></view>
36 <view class="row"><text class="label">单价中是否已包含包装费</text><text class="value">{{ 36 <view class="row"><text class="label">单价中是否已包含包装费</text><text class="value">{{
37 detail.includesPackagingFeeName || '-' }}</text></view> 37 detail.includesPackagingFeeName || '-' }}</text></view>
@@ -114,8 +114,7 @@ export default { @@ -114,8 +114,7 @@ export default {
114 packagingRequirements: '', 114 packagingRequirements: '',
115 paymentTerms: '', 115 paymentTerms: '',
116 transportMode: '', 116 transportMode: '',
117 - destinationId: '',  
118 - destinationLabel: '', 117 + foreignDestination: '',
119 specialInstructions: '', 118 specialInstructions: '',
120 remarks: '', 119 remarks: '',
121 pieceWeightHead: '', 120 pieceWeightHead: '',
@@ -154,8 +153,7 @@ export default { @@ -154,8 +153,7 @@ export default {
154 ...this.detail, 153 ...this.detail,
155 ...data, 154 ...data,
156 includesPackagingFeeName, includesTransportFeeName, 155 includesPackagingFeeName, includesTransportFeeName,
157 - destinationId: data.provinceId && data.cityId && data.districtId ? [data.provinceId, data.cityId, data.districtId] : '',  
158 - destinationLabel: data.provinceName && data.cityName && data.districtName ? `${data.provinceName} / ${data.cityName} / ${data.districtName}` : '', 156 + foreignDestination: (data.foreignDestination || ''),
159 } 157 }
160 const lines = Array.isArray(data.contractDistributorLineList) ? data.contractDistributorLineList : [] 158 const lines = Array.isArray(data.contractDistributorLineList) ? data.contractDistributorLineList : []
161 this.productList = lines 159 this.productList = lines
@@ -412,6 +412,14 @@ @@ -412,6 +412,14 @@
412 } 412 }
413 }, 413 },
414 { 414 {
  415 + "path": "pages/contract_stock/uploadStandard",
  416 + "style": {
  417 + "navigationBarTitleText": "上传合同附件",
  418 + "navigationBarBackgroundColor": "#ffffff",
  419 + "navigationBarTextStyle": "black"
  420 + }
  421 + },
  422 + {
415 "path": "pages/contract_stock/lock", 423 "path": "pages/contract_stock/lock",
416 "style": { 424 "style": {
417 "navigationBarTitleText": "锁价", 425 "navigationBarTitleText": "锁价",
@@ -420,6 +428,14 @@ @@ -420,6 +428,14 @@
420 } 428 }
421 }, 429 },
422 { 430 {
  431 + "path": "pages/contract_stock/split",
  432 + "style": {
  433 + "navigationBarTitleText": "拆分",
  434 + "navigationBarBackgroundColor": "#ffffff",
  435 + "navigationBarTextStyle": "black"
  436 + }
  437 + },
  438 + {
423 "path": "pages/contract_unplan/index", 439 "path": "pages/contract_unplan/index",
424 "style": { 440 "style": {
425 "navigationBarTitleText": "经销未锁规合同", 441 "navigationBarTitleText": "经销未锁规合同",
@@ -452,6 +468,14 @@ @@ -452,6 +468,14 @@
452 } 468 }
453 }, 469 },
454 { 470 {
  471 + "path": "pages/contract_unplan/uploadStandard",
  472 + "style": {
  473 + "navigationBarTitleText": "上传合同附件",
  474 + "navigationBarBackgroundColor": "#ffffff",
  475 + "navigationBarTextStyle": "black"
  476 + }
  477 + },
  478 + {
455 "path": "pages/contract_unplan/lock", 479 "path": "pages/contract_unplan/lock",
456 "style": { 480 "style": {
457 "navigationBarTitleText": "锁规", 481 "navigationBarTitleText": "锁规",
@@ -580,6 +604,14 @@ @@ -580,6 +604,14 @@
580 } 604 }
581 }, 605 },
582 { 606 {
  607 + "path": "pages/contract_foreign_stock/uploadStandard",
  608 + "style": {
  609 + "navigationBarTitleText": "上传合同附件",
  610 + "navigationBarBackgroundColor": "#ffffff",
  611 + "navigationBarTextStyle": "black"
  612 + }
  613 + },
  614 + {
583 "path": "pages/contract_foreign_stock/lock", 615 "path": "pages/contract_foreign_stock/lock",
584 "style": { 616 "style": {
585 "navigationBarTitleText": "锁价", 617 "navigationBarTitleText": "锁价",
@@ -588,6 +620,14 @@ @@ -588,6 +620,14 @@
588 } 620 }
589 }, 621 },
590 { 622 {
  623 + "path": "pages/contract_foreign_stock/split",
  624 + "style": {
  625 + "navigationBarTitleText": "拆分",
  626 + "navigationBarBackgroundColor": "#ffffff",
  627 + "navigationBarTextStyle": "black"
  628 + }
  629 + },
  630 + {
591 "path": "pages/contract_foreign_unplan/index", 631 "path": "pages/contract_foreign_unplan/index",
592 "style": { 632 "style": {
593 "navigationBarTitleText": "外贸未锁规合同", 633 "navigationBarTitleText": "外贸未锁规合同",
@@ -620,6 +660,14 @@ @@ -620,6 +660,14 @@
620 } 660 }
621 }, 661 },
622 { 662 {
  663 + "path": "pages/contract_foreign_unplan/uploadStandard",
  664 + "style": {
  665 + "navigationBarTitleText": "上传合同附件",
  666 + "navigationBarBackgroundColor": "#ffffff",
  667 + "navigationBarTextStyle": "black"
  668 + }
  669 + },
  670 + {
623 "path": "pages/contract_foreign_unplan/lock", 671 "path": "pages/contract_foreign_unplan/lock",
624 "style": { 672 "style": {
625 "navigationBarTitleText": "锁规", 673 "navigationBarTitleText": "锁规",
@@ -88,11 +88,9 @@ @@ -88,11 +88,9 @@
88 </template> 88 </template>
89 </uni-list-item> 89 </uni-list-item>
90 90
91 - <uni-list-item class="select-item" :class="(Array.isArray(form.destinationId) && form.destinationId.length) ? 'is-filled' : 'is-empty'" clickable  
92 - @click="openCitySelector" :rightText="form.destinationLabel || '请选择'" showArrow>  
93 - <template v-slot:body>  
94 - <view class="item-title"><text>目的地</text></view>  
95 - <CitySelector ref="citySelectorRef" v-model="form.destinationId" @change="onCityChange" /> 91 + <uni-list-item title="目的地">
  92 + <template v-slot:footer>
  93 + <uni-easyinput v-model="form.foreignDestination" placeholder="请输入目的地" :inputBorder="false" />
96 </template> 94 </template>
97 </uni-list-item> 95 </uni-list-item>
98 <uni-list-item class="select-item" :class="form.includesPackagingFeeName ? 'is-filled' : 'is-empty'" clickable 96 <uni-list-item class="select-item" :class="form.includesPackagingFeeName ? 'is-filled' : 'is-empty'" clickable
@@ -229,7 +227,6 @@ @@ -229,7 +227,6 @@
229 import SingleSelectSheet from '@/components/single-select/index.vue' 227 import SingleSelectSheet from '@/components/single-select/index.vue'
230 import RelateSelectSheet from '@/components/relate-select/index.vue' 228 import RelateSelectSheet from '@/components/relate-select/index.vue'
231 import ProductRel from './productRel.vue' 229 import ProductRel from './productRel.vue'
232 -import CitySelector from '@/components/city-selector/index.vue'  
233 import { getRetailCodeApi, createContractApi, getCustomerRemarks, getCustomerSpecificQualityRequirements, getDeptApi, getContractApi } from '@/api/contract' 230 import { getRetailCodeApi, createContractApi, getCustomerRemarks, getCustomerSpecificQualityRequirements, getDeptApi, getContractApi } from '@/api/contract'
234 import { getDicByCodes } from '@/utils/dic' 231 import { getDicByCodes } from '@/utils/dic'
235 import { formatCurrencyToChinese } from '@/utils/common' 232 import { formatCurrencyToChinese } from '@/utils/common'
@@ -239,7 +236,7 @@ import { getArea } from '@/api/credit_manage.js' @@ -239,7 +236,7 @@ import { getArea } from '@/api/credit_manage.js'
239 236
240 export default { 237 export default {
241 name: 'AddContractForeignStd', 238 name: 'AddContractForeignStd',
242 - components: { SingleSelectSheet, RelateSelectSheet, ProductRel, CitySelector }, 239 + components: { SingleSelectSheet, RelateSelectSheet, ProductRel },
243 data() { 240 data() {
244 return { 241 return {
245 copyId: '', 242 copyId: '',
@@ -268,8 +265,7 @@ export default { @@ -268,8 +265,7 @@ export default {
268 includesTransportFeeName: '否', 265 includesTransportFeeName: '否',
269 unit: '美元、公斤、美元/公斤', 266 unit: '美元、公斤、美元/公斤',
270 totalAmountCapital: '', 267 totalAmountCapital: '',
271 - destinationId: [],  
272 - destinationLabel: '', 268 + foreignDestination: '',
273 workshopIdName: '', 269 workshopIdName: '',
274 workshopId: '', 270 workshopId: '',
275 remarks: '', 271 remarks: '',
@@ -315,11 +311,6 @@ export default { @@ -315,11 +311,6 @@ export default {
315 this.loadRegionOptions() 311 this.loadRegionOptions()
316 if (!this.copyId) this.form.orderDate = this.formatDate(new Date()) 312 if (!this.copyId) this.form.orderDate = this.formatDate(new Date())
317 if (this.copyId) this.loadCopyDetail(this.copyId) 313 if (this.copyId) this.loadCopyDetail(this.copyId)
318 - this.$nextTick(() => {  
319 - if (Array.isArray(this.form.destinationId) && this.form.destinationId.length) {  
320 - this.initDestinationLabel()  
321 - }  
322 - })  
323 }, 314 },
324 watch: { 315 watch: {
325 'form.buyer': { 316 'form.buyer': {
@@ -404,8 +395,7 @@ export default { @@ -404,8 +395,7 @@ export default {
404 packagingRequirements: m.packagingRequirements || '', 395 packagingRequirements: m.packagingRequirements || '',
405 paymentTerms: m.paymentTerms || '', 396 paymentTerms: m.paymentTerms || '',
406 transportMode: m.transportMode || '', 397 transportMode: m.transportMode || '',
407 - destinationId: (m.provinceId && m.cityId && m.districtId) ? [m.provinceId, m.cityId, m.districtId] : (Array.isArray(m.destinationId) ? m.destinationId : []),  
408 - destinationLabel: (m.provinceName && m.cityName && m.districtName) ? `${m.provinceName} / ${m.cityName} / ${m.districtName}` : (m.destinationLabel || ''), 398 + foreignDestination: (m.foreignDestination || ''),
409 specialInstructions: m.specialInstructions || '', 399 specialInstructions: m.specialInstructions || '',
410 remarks: m.remarks || '', 400 remarks: m.remarks || '',
411 pieceWeightHead: m.pieceWeightHead || '', 401 pieceWeightHead: m.pieceWeightHead || '',
@@ -551,20 +541,6 @@ export default { @@ -551,20 +541,6 @@ export default {
551 const val = m[field] 541 const val = m[field]
552 return val ? String(val) : map[field] 542 return val ? String(val) : map[field]
553 }, 543 },
554 - openCitySelector() {  
555 - this.$refs.citySelectorRef && this.$refs.citySelectorRef.open()  
556 - },  
557 - async initDestinationLabel() {  
558 - const comp = this.$refs.citySelectorRef  
559 - if (comp && typeof comp.getLabel === 'function') {  
560 - const label = await comp.getLabel()  
561 - this.form.destinationLabel = label || ''  
562 - }  
563 - },  
564 - onCityChange(payload) {  
565 - const label = payload && payload.label != null ? payload.label : ''  
566 - this.form.destinationLabel = label  
567 - },  
568 async openSheet(field) { 544 async openSheet(field) {
569 const setSheet = (title, options) => { 545 const setSheet = (title, options) => {
570 const current = this.form[field] 546 const current = this.form[field]
@@ -664,13 +640,9 @@ export default { @@ -664,13 +640,9 @@ export default {
664 return out 640 return out
665 } 641 }
666 const lines = (this.productLineList || []).map(it => clean(it)) 642 const lines = (this.productLineList || []).map(it => clean(it))
667 - const { destinationLabel, destinationId, ...formForSubmit } = this.form;  
668 - // 区id  
669 - const destination = destinationId && destinationId.length > 0 ? destinationId[destinationId.length - 1] : '';  
670 const payload = clean({ 643 const payload = clean({
671 - ...formForSubmit, 644 + ...this.form,
672 operateType: isCopy ? 'COPY' : 'ADD', 645 operateType: isCopy ? 'COPY' : 'ADD',
673 - destination,  
674 type: 'INTL_STD_CONTRACT', 646 type: 'INTL_STD_CONTRACT',
675 totalQuantity: this.totalQuantity, 647 totalQuantity: this.totalQuantity,
676 // totalAmountExcludingTax: this.totalAmountExcludingTax, 648 // totalAmountExcludingTax: this.totalAmountExcludingTax,
@@ -38,7 +38,7 @@ @@ -38,7 +38,7 @@
38 '-' }}</text></view> 38 '-' }}</text></view>
39 <view class="row"><text class="label">运输方式</text><text class="value">{{ detail.transportMode || '-' 39 <view class="row"><text class="label">运输方式</text><text class="value">{{ detail.transportMode || '-'
40 }}</text></view> 40 }}</text></view>
41 - <view class="row"><text class="label">目的地</text><text class="value">{{ detail.destinationLabel || 41 + <view class="row"><text class="label">目的地</text><text class="value">{{ detail.foreignDestination ||
42 '-' 42 '-'
43 }}</text></view> 43 }}</text></view>
44 <view class="row"><text class="label">单价中是否已包含包装费</text><text class="value">{{ 44 <view class="row"><text class="label">单价中是否已包含包装费</text><text class="value">{{
@@ -167,8 +167,7 @@ export default { @@ -167,8 +167,7 @@ export default {
167 packagingRequirements: '', 167 packagingRequirements: '',
168 paymentTerms: '', 168 paymentTerms: '',
169 transportMode: '', 169 transportMode: '',
170 - destinationId: '',  
171 - destinationLabel: '', 170 + foreignDestination: '',
172 specialInstructions: '', 171 specialInstructions: '',
173 remarks: '', 172 remarks: '',
174 pieceWeightHead: '', 173 pieceWeightHead: '',
@@ -386,7 +385,7 @@ export default { @@ -386,7 +385,7 @@ export default {
386 const e = btn.event || '' 385 const e = btn.event || ''
387 if (e === 'edit') return this.onEdit(btn && btn.params) 386 if (e === 'edit') return this.onEdit(btn && btn.params)
388 if (e === 'delete') return this.onDelete(btn && btn.params) 387 if (e === 'delete') return this.onDelete(btn && btn.params)
389 - if (e === 'upload') return this.uploadContract(this.detail.id || '') 388 + if (e === 'upload') return this.uploadContract(this.detail.id || '', 'standard')
390 if (e === 'uploadSeal') return this.uploadContract(this.detail.id || '', 'seal') 389 if (e === 'uploadSeal') return this.uploadContract(this.detail.id || '', 'seal')
391 if (e === 'audit') return this.onAudit(btn && btn.params) 390 if (e === 'audit') return this.onAudit(btn && btn.params)
392 if (e === 'auditDetail') return this.onAuditDetail(btn && btn.params) 391 if (e === 'auditDetail') return this.onAuditDetail(btn && btn.params)
@@ -435,8 +434,7 @@ export default { @@ -435,8 +434,7 @@ export default {
435 regionName: data.regionName || '', 434 regionName: data.regionName || '',
436 deptName: data.deptName || '', 435 deptName: data.deptName || '',
437 includesPackagingFeeName, includesTransportFeeName, 436 includesPackagingFeeName, includesTransportFeeName,
438 - destinationId: data.provinceId && data.cityId && data.districtId ? [data.provinceId, data.cityId, data.districtId] : '',  
439 - destinationLabel: data.provinceName && data.cityName && data.districtName ? `${data.provinceName} / ${data.cityName} / ${data.districtName}` : '', 437 + foreignDestination: (data.foreignDestination || ''),
440 } 438 }
441 this.detail = await fillStandardApprovedName(this.detail) 439 this.detail = await fillStandardApprovedName(this.detail)
442 const lines = Array.isArray(data.contractDistributorLineList) ? data.contractDistributorLineList : [] 440 const lines = Array.isArray(data.contractDistributorLineList) ? data.contractDistributorLineList : []
@@ -90,11 +90,9 @@ @@ -90,11 +90,9 @@
90 <uni-easyinput v-model="form.transportMode" placeholder="请输入运输方式" :inputBorder="false" /> 90 <uni-easyinput v-model="form.transportMode" placeholder="请输入运输方式" :inputBorder="false" />
91 </template> 91 </template>
92 </uni-list-item> 92 </uni-list-item>
93 - <uni-list-item class="select-item" :class="(Array.isArray(form.destinationId) && form.destinationId.length) ? 'is-filled' : 'is-empty'" clickable  
94 - @click="openCitySelector" :rightText="form.destinationLabel || '请选择'" showArrow>  
95 - <template v-slot:body>  
96 - <view class="item-title"><text>目的地</text></view>  
97 - <CitySelector ref="citySelectorRef" v-model="form.destinationId" @change="onCityChange" /> 93 + <uni-list-item title="目的地">
  94 + <template v-slot:footer>
  95 + <uni-easyinput v-model="form.foreignDestination" placeholder="请输入目的地" :inputBorder="false" />
98 </template> 96 </template>
99 </uni-list-item> 97 </uni-list-item>
100 98
@@ -214,7 +212,6 @@ @@ -214,7 +212,6 @@
214 import SingleSelectSheet from '@/components/single-select/index.vue' 212 import SingleSelectSheet from '@/components/single-select/index.vue'
215 import RelateSelectSheet from '@/components/relate-select/index.vue' 213 import RelateSelectSheet from '@/components/relate-select/index.vue'
216 import ProductRel from './productRel.vue' 214 import ProductRel from './productRel.vue'
217 -import CitySelector from '@/components/city-selector/index.vue'  
218 import { getContractApi, updateContractApi } from '@/api/contract' 215 import { getContractApi, updateContractApi } from '@/api/contract'
219 import { getDicByCodes } from '@/utils/dic' 216 import { getDicByCodes } from '@/utils/dic'
220 import { formatCurrencyToChinese } from '@/utils/common' 217 import { formatCurrencyToChinese } from '@/utils/common'
@@ -222,7 +219,7 @@ import { workshopQueryApi } from '@/api/devManage' @@ -222,7 +219,7 @@ import { workshopQueryApi } from '@/api/devManage'
222 import { getArea } from '@/api/credit_manage.js' 219 import { getArea } from '@/api/credit_manage.js'
223 export default { 220 export default {
224 name: 'ModifyContractForeignStd', 221 name: 'ModifyContractForeignStd',
225 - components: { SingleSelectSheet, RelateSelectSheet, ProductRel, CitySelector }, 222 + components: { SingleSelectSheet, RelateSelectSheet, ProductRel },
226 data() { 223 data() {
227 return { 224 return {
228 id: '', 225 id: '',
@@ -259,8 +256,7 @@ export default { @@ -259,8 +256,7 @@ export default {
259 packagingRequirements: '', 256 packagingRequirements: '',
260 paymentTerms: '', 257 paymentTerms: '',
261 transportMode: '', 258 transportMode: '',
262 - destinationId: [],  
263 - destinationLabel: '', 259 + foreignDestination: '',
264 specialInstructions: '', 260 specialInstructions: '',
265 remarks: '', 261 remarks: '',
266 pieceWeightHead: '', 262 pieceWeightHead: '',
@@ -293,11 +289,6 @@ export default { @@ -293,11 +289,6 @@ export default {
293 this.loadExtraOptions() 289 this.loadExtraOptions()
294 this.loadRegionOptions() 290 this.loadRegionOptions()
295 this.loadDetail() 291 this.loadDetail()
296 - this.$nextTick(() => {  
297 - if (Array.isArray(this.form.destinationId) && this.form.destinationId.length) {  
298 - this.initDestinationLabel()  
299 - }  
300 - })  
301 }, 292 },
302 methods: { 293 methods: {
303 async loadRegionOptions() { 294 async loadRegionOptions() {
@@ -344,8 +335,7 @@ export default { @@ -344,8 +335,7 @@ export default {
344 packagingRequirements: m.packagingRequirements || '', 335 packagingRequirements: m.packagingRequirements || '',
345 paymentTerms: m.paymentTerms || '', 336 paymentTerms: m.paymentTerms || '',
346 transportMode: m.transportMode || '', 337 transportMode: m.transportMode || '',
347 - destinationId: (m.provinceId && m.cityId && m.districtId) ? [m.provinceId, m.cityId, m.districtId] : (Array.isArray(m.destinationId) ? m.destinationId : []),  
348 - destinationLabel: (m.provinceName && m.cityName && m.districtName) ? `${m.provinceName} / ${m.cityName} / ${m.districtName}` : (m.destinationLabel || ''), 338 + foreignDestination: (m.foreignDestination || ''),
349 specialInstructions: m.specialInstructions || '', 339 specialInstructions: m.specialInstructions || '',
350 remarks: m.remarks || '', 340 remarks: m.remarks || '',
351 pieceWeightHead: m.pieceWeightHead || '', 341 pieceWeightHead: m.pieceWeightHead || '',
@@ -366,20 +356,6 @@ export default { @@ -366,20 +356,6 @@ export default {
366 this.onProductsChange(lines) 356 this.onProductsChange(lines)
367 } catch (e) { } 357 } catch (e) { }
368 }, 358 },
369 - async initDestinationLabel() {  
370 - const comp = this.$refs.citySelectorRef  
371 - if (comp && typeof comp.getLabel === 'function') {  
372 - const label = await comp.getLabel()  
373 - this.form.destinationLabel = label || ''  
374 - }  
375 - },  
376 - openCitySelector() {  
377 - this.$refs.citySelectorRef && this.$refs.citySelectorRef.open()  
378 - },  
379 - onCityChange(payload) {  
380 - const label = payload && payload.label != null ? payload.label : ''  
381 - this.form.destinationLabel = label  
382 - },  
383 onProductsChange(products) { 359 onProductsChange(products) {
384 const list = Array.isArray(products) ? products : [] 360 const list = Array.isArray(products) ? products : []
385 this.newProductLineList = list 361 this.newProductLineList = list
@@ -528,7 +504,6 @@ export default { @@ -528,7 +504,6 @@ export default {
528 return true 504 return true
529 }, 505 },
530 async onSubmit() { 506 async onSubmit() {
531 - console.log('onSubmit__payload', payload)  
532 if (!this.validateRequired()) return 507 if (!this.validateRequired()) return
533 const confirmRes = await new Promise(resolve => { 508 const confirmRes = await new Promise(resolve => {
534 uni.showModal({ title: '提示', content: '确定保存当前外贸标准合同吗?', confirmText: '确定', cancelText: '取消', success: resolve }) 509 uni.showModal({ title: '提示', content: '确定保存当前外贸标准合同吗?', confirmText: '确定', cancelText: '取消', success: resolve })
@@ -546,25 +521,22 @@ export default { @@ -546,25 +521,22 @@ export default {
546 return out 521 return out
547 } 522 }
548 const lines = (this.newProductLineList || []).map(it => clean(it)) 523 const lines = (this.newProductLineList || []).map(it => clean(it))
549 - const { destinationLabel, destinationId, ...formForSubmit } = this.form;  
550 - const destination = destinationId && destinationId.length > 0 ? destinationId[destinationId.length - 1] : '';  
551 - const payload = clean({  
552 - ...formForSubmit,  
553 - id: this.form.id,  
554 - destination,  
555 - type: 'INTL_STD_CONTRACT',  
556 - totalQuantity: this.totalQuantity,  
557 - // totalAmountExcludingTax: this.totalAmountExcludingTax,  
558 - totalAmountIncludingTax: this.totalAmountIncludingTax,  
559 - contractDistributorLineList: lines  
560 - })  
561 - try {  
562 - await updateContractApi(payload)  
563 - uni.showToast({ title: '保存成功', icon: 'none' })  
564 - setTimeout(() => { uni.redirectTo({ url: '/pages/contract_foreign_std/index' }) }, 400)  
565 - } catch (e) {  
566 - uni.showToast({ title: e.msg ||'提交失败', icon: 'none' })  
567 - } 524 + const payload = clean({
  525 + ...this.form,
  526 + id: this.form.id,
  527 + type: 'INTL_STD_CONTRACT',
  528 + totalQuantity: this.totalQuantity,
  529 + // totalAmountExcludingTax: this.totalAmountExcludingTax,
  530 + totalAmountIncludingTax: this.totalAmountIncludingTax,
  531 + contractDistributorLineList: lines
  532 + })
  533 + try {
  534 + await updateContractApi(payload)
  535 + uni.showToast({ title: '保存成功', icon: 'none' })
  536 + setTimeout(() => { uni.redirectTo({ url: '/pages/contract_foreign_std/index' }) }, 400)
  537 + } catch (e) {
  538 + uni.showToast({ title: e.msg ||'提交失败', icon: 'none' })
  539 + }
568 } 540 }
569 } 541 }
570 } 542 }
@@ -809,4 +781,4 @@ export default { @@ -809,4 +781,4 @@ export default {
809 } 781 }
810 } 782 }
811 783
812 -</style>  
  784 +</style>
@@ -89,12 +89,9 @@ @@ -89,12 +89,9 @@
89 <uni-easyinput v-model="form.transportMode" placeholder="请输入运输方式" :inputBorder="false" /> 89 <uni-easyinput v-model="form.transportMode" placeholder="请输入运输方式" :inputBorder="false" />
90 </template> 90 </template>
91 </uni-list-item> 91 </uni-list-item>
92 - <uni-list-item class="select-item"  
93 - :class="(Array.isArray(form.destinationId) && form.destinationId.length) ? 'is-filled' : 'is-empty'" clickable  
94 - @click="openCitySelector" :rightText="form.destinationLabel || '请选择'" showArrow>  
95 - <template v-slot:body>  
96 - <view class="item-title"><text>目的地</text></view>  
97 - <CitySelector ref="citySelectorRef" v-model="form.destinationId" @change="onCityChange" /> 92 + <uni-list-item title="目的地">
  93 + <template v-slot:footer>
  94 + <uni-easyinput v-model="form.foreignDestination" placeholder="请输入目的地" :inputBorder="false" />
98 </template> 95 </template>
99 </uni-list-item> 96 </uni-list-item>
100 97
@@ -219,7 +216,6 @@ @@ -219,7 +216,6 @@
219 import SingleSelectSheet from '@/components/single-select/index.vue' 216 import SingleSelectSheet from '@/components/single-select/index.vue'
220 import RelateSelectSheet from '@/components/relate-select/index.vue' 217 import RelateSelectSheet from '@/components/relate-select/index.vue'
221 import ProductRel from './productRel.vue' 218 import ProductRel from './productRel.vue'
222 -import CitySelector from '@/components/city-selector/index.vue'  
223 import FileUpload from '@/components/file-upload/index.vue' 219 import FileUpload from '@/components/file-upload/index.vue'
224 import { getContractApi, uploadStandardContract } from '@/api/contract' 220 import { getContractApi, uploadStandardContract } from '@/api/contract'
225 import { getDicByCodes } from '@/utils/dic' 221 import { getDicByCodes } from '@/utils/dic'
@@ -229,7 +225,7 @@ import { getArea } from '@/api/credit_manage.js' @@ -229,7 +225,7 @@ import { getArea } from '@/api/credit_manage.js'
229 225
230 export default { 226 export default {
231 name: 'UploadStandardContractForeignStd', 227 name: 'UploadStandardContractForeignStd',
232 - components: { SingleSelectSheet, RelateSelectSheet, ProductRel, CitySelector, FileUpload }, 228 + components: { SingleSelectSheet, RelateSelectSheet, ProductRel, FileUpload },
233 data() { 229 data() {
234 return { 230 return {
235 id: '', 231 id: '',
@@ -269,8 +265,7 @@ export default { @@ -269,8 +265,7 @@ export default {
269 packagingRequirements: '', 265 packagingRequirements: '',
270 paymentTerms: '', 266 paymentTerms: '',
271 transportMode: '', 267 transportMode: '',
272 - destinationId: [],  
273 - destinationLabel: '', 268 + foreignDestination: '',
274 specialInstructions: '', 269 specialInstructions: '',
275 remarks: '', 270 remarks: '',
276 pieceWeightHead: '', 271 pieceWeightHead: '',
@@ -311,11 +306,6 @@ export default { @@ -311,11 +306,6 @@ export default {
311 this.loadExtraOptions() 306 this.loadExtraOptions()
312 this.loadRegionOptions() 307 this.loadRegionOptions()
313 this.loadDetail() 308 this.loadDetail()
314 - this.$nextTick(() => {  
315 - if (Array.isArray(this.form.destinationId) && this.form.destinationId.length) {  
316 - this.initDestinationLabel()  
317 - }  
318 - })  
319 }, 309 },
320 methods: { 310 methods: {
321 async loadRegionOptions() { 311 async loadRegionOptions() {
@@ -362,8 +352,7 @@ export default { @@ -362,8 +352,7 @@ export default {
362 packagingRequirements: m.packagingRequirements || '', 352 packagingRequirements: m.packagingRequirements || '',
363 paymentTerms: m.paymentTerms || '', 353 paymentTerms: m.paymentTerms || '',
364 transportMode: m.transportMode || '', 354 transportMode: m.transportMode || '',
365 - destinationId: (m.provinceId && m.cityId && m.districtId) ? [m.provinceId, m.cityId, m.districtId] : (Array.isArray(m.destinationId) ? m.destinationId : []),  
366 - destinationLabel: (m.provinceName && m.cityName && m.districtName) ? `${m.provinceName} / ${m.cityName} / ${m.districtName}` : (m.destinationLabel || ''), 355 + foreignDestination: (m.foreignDestination || ''),
367 specialInstructions: m.specialInstructions || '', 356 specialInstructions: m.specialInstructions || '',
368 remarks: m.remarks || '', 357 remarks: m.remarks || '',
369 pieceWeightHead: m.pieceWeightHead || '', 358 pieceWeightHead: m.pieceWeightHead || '',
@@ -387,20 +376,6 @@ export default { @@ -387,20 +376,6 @@ export default {
387 this.onProductsChange(lines) 376 this.onProductsChange(lines)
388 } catch (e) { } 377 } catch (e) { }
389 }, 378 },
390 - async initDestinationLabel() {  
391 - const comp = this.$refs.citySelectorRef  
392 - if (comp && typeof comp.getLabel === 'function') {  
393 - const label = await comp.getLabel()  
394 - this.form.destinationLabel = label || ''  
395 - }  
396 - },  
397 - openCitySelector() {  
398 - this.$refs.citySelectorRef && this.$refs.citySelectorRef.open()  
399 - },  
400 - onCityChange(payload) {  
401 - const label = payload && payload.label != null ? payload.label : ''  
402 - this.form.destinationLabel = label  
403 - },  
404 onProductsChange(products) { 379 onProductsChange(products) {
405 const list = Array.isArray(products) ? products : [] 380 const list = Array.isArray(products) ? products : []
406 this.newProductLineList = list 381 this.newProductLineList = list
@@ -602,12 +577,9 @@ export default { @@ -602,12 +577,9 @@ export default {
602 return out 577 return out
603 } 578 }
604 const lines = (this.newProductLineList || []).map(it => clean(it)) 579 const lines = (this.newProductLineList || []).map(it => clean(it))
605 - const { destinationLabel, destinationId, ...formForSubmit } = this.form  
606 - const destination = destinationId && destinationId.length > 0 ? destinationId[destinationId.length - 1] : ''  
607 const payload = clean({ 580 const payload = clean({
608 - ...formForSubmit, 581 + ...this.form,
609 id: this.form.id, 582 id: this.form.id,
610 - destination,  
611 type: 'INTL_STD_CONTRACT', 583 type: 'INTL_STD_CONTRACT',
612 totalQuantity: this.totalQuantity, 584 totalQuantity: this.totalQuantity,
613 totalAmountIncludingTax: this.totalAmountIncludingTax, 585 totalAmountIncludingTax: this.totalAmountIncludingTax,
@@ -91,11 +91,9 @@ @@ -91,11 +91,9 @@
91 </template> 91 </template>
92 </uni-list-item> 92 </uni-list-item>
93 93
94 - <uni-list-item class="select-item" :class="(Array.isArray(form.destinationId) && form.destinationId.length) ? 'is-filled' : 'is-empty'" clickable  
95 - @click="openCitySelector" :rightText="form.destinationLabel || '请选择'" showArrow>  
96 - <template v-slot:body>  
97 - <view class="item-title"><text>目的地</text></view>  
98 - <CitySelector ref="citySelectorRef" v-model="form.destinationId" @change="onCityChange" /> 94 + <uni-list-item title="目的地">
  95 + <template v-slot:footer>
  96 + <uni-easyinput v-model="form.foreignDestination" placeholder="请输入目的地" :inputBorder="false" />
99 </template> 97 </template>
100 </uni-list-item> 98 </uni-list-item>
101 <uni-list-item class="select-item" :class="form.includesPackagingFeeName ? 'is-filled' : 'is-empty'" clickable 99 <uni-list-item class="select-item" :class="form.includesPackagingFeeName ? 'is-filled' : 'is-empty'" clickable
@@ -232,7 +230,6 @@ @@ -232,7 +230,6 @@
232 import SingleSelectSheet from '@/components/single-select/index.vue' 230 import SingleSelectSheet from '@/components/single-select/index.vue'
233 import RelateSelectSheet from '@/components/relate-select/index.vue' 231 import RelateSelectSheet from '@/components/relate-select/index.vue'
234 import ProductRel from './productRel.vue' 232 import ProductRel from './productRel.vue'
235 -import CitySelector from '@/components/city-selector/index.vue'  
236 import { getRetailCodeApi, createContractApi, getCustomerSpecificQualityRequirements, getCustomerRemarks, getDeptApi, getContractApi } from '@/api/contract' 233 import { getRetailCodeApi, createContractApi, getCustomerSpecificQualityRequirements, getCustomerRemarks, getDeptApi, getContractApi } from '@/api/contract'
237 import { getDicByCodes } from '@/utils/dic' 234 import { getDicByCodes } from '@/utils/dic'
238 import { formatCurrencyToChinese } from '@/utils/common' 235 import { formatCurrencyToChinese } from '@/utils/common'
@@ -241,7 +238,7 @@ import { getArea } from '@/api/credit_manage.js' @@ -241,7 +238,7 @@ import { getArea } from '@/api/credit_manage.js'
241 238
242 export default { 239 export default {
243 name: 'AddContractForeignStock', 240 name: 'AddContractForeignStock',
244 - components: { SingleSelectSheet, RelateSelectSheet, ProductRel, CitySelector }, 241 + components: { SingleSelectSheet, RelateSelectSheet, ProductRel },
245 data() { 242 data() {
246 return { 243 return {
247 copyId: '', 244 copyId: '',
@@ -268,8 +265,7 @@ export default { @@ -268,8 +265,7 @@ export default {
268 includesTransportFeeName: '否', 265 includesTransportFeeName: '否',
269 unit: '美元、公斤、美元/公斤', 266 unit: '美元、公斤、美元/公斤',
270 totalAmountCapital: '', 267 totalAmountCapital: '',
271 - destinationId: [],  
272 - destinationLabel: '', 268 + foreignDestination: '',
273 workshopIdName: '', 269 workshopIdName: '',
274 workshopId: '', 270 workshopId: '',
275 deptName: '', 271 deptName: '',
@@ -317,11 +313,6 @@ export default { @@ -317,11 +313,6 @@ export default {
317 this.loadRegionOptions() 313 this.loadRegionOptions()
318 if (!this.copyId) this.form.orderDate = this.formatDate(new Date()) 314 if (!this.copyId) this.form.orderDate = this.formatDate(new Date())
319 if (this.copyId) this.loadCopyDetail(this.copyId) 315 if (this.copyId) this.loadCopyDetail(this.copyId)
320 - this.$nextTick(() => {  
321 - if (Array.isArray(this.form.destinationId) && this.form.destinationId.length) {  
322 - this.initDestinationLabel()  
323 - }  
324 - })  
325 }, 316 },
326 watch: { 317 watch: {
327 'form.buyer': { 318 'form.buyer': {
@@ -406,8 +397,7 @@ export default { @@ -406,8 +397,7 @@ export default {
406 packagingRequirements: m.packagingRequirements || '', 397 packagingRequirements: m.packagingRequirements || '',
407 paymentTerms: m.paymentTerms || '', 398 paymentTerms: m.paymentTerms || '',
408 transportMode: m.transportMode || '', 399 transportMode: m.transportMode || '',
409 - destinationId: (m.provinceId && m.cityId && m.districtId) ? [m.provinceId, m.cityId, m.districtId] : (Array.isArray(m.destinationId) ? m.destinationId : []),  
410 - destinationLabel: (m.provinceName && m.cityName && m.districtName) ? `${m.provinceName} / ${m.cityName} / ${m.districtName}` : (m.destinationLabel || ''), 400 + foreignDestination: (m.foreignDestination || ''),
411 specialInstructions: m.specialInstructions || '', 401 specialInstructions: m.specialInstructions || '',
412 remarks: m.remarks || '', 402 remarks: m.remarks || '',
413 packaging: m.packaging || '', 403 packaging: m.packaging || '',
@@ -554,20 +544,6 @@ export default { @@ -554,20 +544,6 @@ export default {
554 const val = m[field] 544 const val = m[field]
555 return val ? String(val) : map[field] 545 return val ? String(val) : map[field]
556 }, 546 },
557 - openCitySelector() {  
558 - this.$refs.citySelectorRef && this.$refs.citySelectorRef.open()  
559 - },  
560 - async initDestinationLabel() {  
561 - const comp = this.$refs.citySelectorRef  
562 - if (comp && typeof comp.getLabel === 'function') {  
563 - const label = await comp.getLabel()  
564 - this.form.destinationLabel = label || ''  
565 - }  
566 - },  
567 - onCityChange(payload) {  
568 - const label = payload && payload.label != null ? payload.label : ''  
569 - this.form.destinationLabel = label  
570 - },  
571 async openSheet(field) { 547 async openSheet(field) {
572 const setSheet = (title, options) => { 548 const setSheet = (title, options) => {
573 const current = this.form[field] 549 const current = this.form[field]
@@ -667,13 +643,9 @@ export default { @@ -667,13 +643,9 @@ export default {
667 return out 643 return out
668 } 644 }
669 const lines = (this.productLineList || []).map(it => clean(it)) 645 const lines = (this.productLineList || []).map(it => clean(it))
670 - const { destinationLabel, destinationId, ...formForSubmit } = this.form;  
671 - // 区id  
672 - const destination = destinationId && destinationId.length > 0 ? destinationId[destinationId.length - 1] : '';  
673 const payload = clean({ 646 const payload = clean({
674 - ...formForSubmit, 647 + ...this.form,
675 operateType: isCopy ? 'COPY' : 'ADD', 648 operateType: isCopy ? 'COPY' : 'ADD',
676 - destination,  
677 type: 'INTL_INVENTORY_AGMT', 649 type: 'INTL_INVENTORY_AGMT',
678 totalQuantity: this.totalQuantity, 650 totalQuantity: this.totalQuantity,
679 // totalAmountExcludingTax: this.totalAmountExcludingTax, 651 // totalAmountExcludingTax: this.totalAmountExcludingTax,
@@ -50,7 +50,7 @@ @@ -50,7 +50,7 @@
50 '-' }}</text></view> 50 '-' }}</text></view>
51 <view class="row"><text class="label">运输方式</text><text class="value">{{ detail.transportMode || '-' 51 <view class="row"><text class="label">运输方式</text><text class="value">{{ detail.transportMode || '-'
52 }}</text></view> 52 }}</text></view>
53 - <view class="row"><text class="label">目的地</text><text class="value">{{ detail.destinationLabel || 53 + <view class="row"><text class="label">目的地</text><text class="value">{{ detail.foreignDestination ||
54 '-' 54 '-'
55 }}</text></view> 55 }}</text></view>
56 <view class="row"><text class="label">单价中是否已包含包装费</text><text class="value">{{ 56 <view class="row"><text class="label">单价中是否已包含包装费</text><text class="value">{{
@@ -188,8 +188,7 @@ export default { @@ -188,8 +188,7 @@ export default {
188 packagingRequirements: '', 188 packagingRequirements: '',
189 paymentTerms: '', 189 paymentTerms: '',
190 transportMode: '', 190 transportMode: '',
191 - destinationId: '',  
192 - destinationLabel: '', 191 + foreignDestination: '',
193 specialInstructions: '', 192 specialInstructions: '',
194 remarks: '', 193 remarks: '',
195 pieceWeightHead: '', 194 pieceWeightHead: '',
@@ -292,6 +291,12 @@ export default { @@ -292,6 +291,12 @@ export default {
292 variant: 'outline', 291 variant: 'outline',
293 event: 'print' 292 event: 'print'
294 }, 293 },
  294 + {
  295 + text: '拆分',
  296 + visible: true,
  297 + variant: 'outline',
  298 + event: 'split'
  299 + },
295 ], 300 ],
296 } 301 }
297 }, 302 },
@@ -303,6 +308,7 @@ export default { @@ -303,6 +308,7 @@ export default {
303 const a = this.detail.standardApproved || false 308 const a = this.detail.standardApproved || false
304 const e = this.detail.showExamine || false 309 const e = this.detail.showExamine || false
305 const f = this.detail.standardShowExamine || false 310 const f = this.detail.standardShowExamine || false
  311 + const g = this.detail.canSplit || false
306 return [ 312 return [
307 { ...this.buttons[0], visible: (s === 'DRAFT' && this.$auth.hasPermi('contract-manage:foreign-trade-inventory-contract:modify')) }, //编辑 313 { ...this.buttons[0], visible: (s === 'DRAFT' && this.$auth.hasPermi('contract-manage:foreign-trade-inventory-contract:modify')) }, //编辑
308 { ...this.buttons[1], visible: (s === 'DRAFT' && this.$auth.hasPermi('contract-manage:foreign-trade-inventory-contract:delete')) }, //删除 314 { ...this.buttons[1], visible: (s === 'DRAFT' && this.$auth.hasPermi('contract-manage:foreign-trade-inventory-contract:delete')) }, //删除
@@ -319,6 +325,7 @@ export default { @@ -319,6 +325,7 @@ export default {
319 { ...this.buttons[8], visible: (s === 'STANDARD' && f && a === 'AUDIT' && this.$auth.hasPermi('contract-manage:foreign-trade-inventory-contract:standard-approve')) }, 325 { ...this.buttons[8], visible: (s === 'STANDARD' && f && a === 'AUDIT' && this.$auth.hasPermi('contract-manage:foreign-trade-inventory-contract:standard-approve')) },
320 { ...this.buttons[13], visible: (s !== 'DELETED' && this.$auth.hasPermi('contract-manage:foreign-trade-inventory-contract:copy')) }, 326 { ...this.buttons[13], visible: (s !== 'DELETED' && this.$auth.hasPermi('contract-manage:foreign-trade-inventory-contract:copy')) },
321 { ...this.buttons[14], visible: true }, 327 { ...this.buttons[14], visible: true },
  328 + { ...this.buttons[15], visible: g },
322 ] 329 ]
323 } 330 }
324 }, 331 },
@@ -373,6 +380,13 @@ export default { @@ -373,6 +380,13 @@ export default {
373 uploadContract(id, type = 'formal') { 380 uploadContract(id, type = 'formal') {
374 if (!id) return 381 if (!id) return
375 this.uploadId = id 382 this.uploadId = id
  383 + if ((type === 'uploadParent' || type === 'upload' )&& this.detail?.canEdit) {
  384 + const query = `?id=${encodeURIComponent(id)}`
  385 + uni.navigateTo({
  386 + url: '/pages/contract_foreign_stock/uploadStandard' + query
  387 + })
  388 + return
  389 + }
376 this.uploadType = type 390 this.uploadType = type
377 this.$refs.uploadPopup.open() 391 this.$refs.uploadPopup.open()
378 }, 392 },
@@ -456,8 +470,8 @@ export default { @@ -456,8 +470,8 @@ export default {
456 if (e === 'edit') return this.onEdit(btn && btn.params) 470 if (e === 'edit') return this.onEdit(btn && btn.params)
457 if (e === 'delete') return this.onDelete(btn && btn.params) 471 if (e === 'delete') return this.onDelete(btn && btn.params)
458 if (e === 'lock') return this.onLock() 472 if (e === 'lock') return this.onLock()
459 - if (e === 'upload') return this.uploadContract(this.detail.id || '')  
460 - if (e === 'uploadParent') return this.uploadContract(this.detail.parentId || '') 473 + if (e === 'upload') return this.uploadContract(this.detail.id || '','upload')
  474 + if (e === 'uploadParent') return this.uploadContract(this.detail.parentId || '', 'uploadParent')
461 if (e === 'uploadStandard') return this.uploadContract(this.detail.id || '', 'standard') 475 if (e === 'uploadStandard') return this.uploadContract(this.detail.id || '', 'standard')
462 if (e === 'audit1') return this.onAudit(this.detail.id || '', 'FORMAL_CONTRACT') 476 if (e === 'audit1') return this.onAudit(this.detail.id || '', 'FORMAL_CONTRACT')
463 if (e === 'audit2') return this.onAudit(this.detail.parentId || '', 'FORMAL_CONTRACT') 477 if (e === 'audit2') return this.onAudit(this.detail.parentId || '', 'FORMAL_CONTRACT')
@@ -468,6 +482,12 @@ export default { @@ -468,6 +482,12 @@ export default {
468 if (e === 'uploadSeal') return this.uploadContract(this.detail.id || '', 'seal') 482 if (e === 'uploadSeal') return this.uploadContract(this.detail.id || '', 'seal')
469 if (e === 'copy') return this.onCopy(btn && btn.params) 483 if (e === 'copy') return this.onCopy(btn && btn.params)
470 if (e === 'print') return this.onPrint(this.detail.id || '') 484 if (e === 'print') return this.onPrint(this.detail.id || '')
  485 + if (e === 'split') return this.onSplit(this.detail.id || '')
  486 + },
  487 + onSplit(id) {
  488 + uni.navigateTo({
  489 + url: '/pages/contract_foreign_stock/split?id=' + id
  490 + })
471 }, 491 },
472 onPrint(id) { 492 onPrint(id) {
473 printFile(id) 493 printFile(id)
@@ -516,8 +536,7 @@ export default { @@ -516,8 +536,7 @@ export default {
516 regionName: data.regionName || '', 536 regionName: data.regionName || '',
517 deptName: data.deptName || '', 537 deptName: data.deptName || '',
518 includesPackagingFeeName, includesTransportFeeName, 538 includesPackagingFeeName, includesTransportFeeName,
519 - destinationId: data.provinceId && data.cityId && data.districtId ? [data.provinceId, data.cityId, data.districtId] : '',  
520 - destinationLabel: data.provinceName && data.cityName && data.districtName ? `${data.provinceName} / ${data.cityName} / ${data.districtName}` : '', 539 + foreignDestination: (data.foreignDestination || ''),
521 } 540 }
522 this.detail = await fillStandardApprovedName(this.detail) 541 this.detail = await fillStandardApprovedName(this.detail)
523 this.detail = await fillFormalApprovedName(this.detail) 542 this.detail = await fillFormalApprovedName(this.detail)
@@ -94,11 +94,9 @@ @@ -94,11 +94,9 @@
94 <uni-easyinput v-model="form.transportMode" placeholder="请输入运输方式" :inputBorder="false" /> 94 <uni-easyinput v-model="form.transportMode" placeholder="请输入运输方式" :inputBorder="false" />
95 </template> 95 </template>
96 </uni-list-item> 96 </uni-list-item>
97 - <uni-list-item class="select-item" :class="(Array.isArray(form.destinationId) && form.destinationId.length) ? 'is-filled' : 'is-empty'" clickable  
98 - @click="openCitySelector" :rightText="form.destinationLabel || '请选择'" showArrow>  
99 - <template v-slot:body>  
100 - <view class="item-title"><text>目的地</text></view>  
101 - <CitySelector ref="citySelectorRef" v-model="form.destinationId" @change="onCityChange" /> 97 + <uni-list-item title="目的地">
  98 + <template v-slot:footer>
  99 + <uni-easyinput v-model="form.foreignDestination" placeholder="请输入目的地" :inputBorder="false" />
102 </template> 100 </template>
103 </uni-list-item> 101 </uni-list-item>
104 102
@@ -218,7 +216,6 @@ @@ -218,7 +216,6 @@
218 import SingleSelectSheet from '@/components/single-select/index.vue' 216 import SingleSelectSheet from '@/components/single-select/index.vue'
219 import RelateSelectSheet from '@/components/relate-select/index.vue' 217 import RelateSelectSheet from '@/components/relate-select/index.vue'
220 import ProductRel from './productRel.vue' 218 import ProductRel from './productRel.vue'
221 -import CitySelector from '@/components/city-selector/index.vue'  
222 import { getContractApi, updateContractApi } from '@/api/contract' 219 import { getContractApi, updateContractApi } from '@/api/contract'
223 import { getDicByCodes } from '@/utils/dic' 220 import { getDicByCodes } from '@/utils/dic'
224 import { formatCurrencyToChinese } from '@/utils/common' 221 import { formatCurrencyToChinese } from '@/utils/common'
@@ -227,7 +224,7 @@ import { getArea } from '@/api/credit_manage.js' @@ -227,7 +224,7 @@ import { getArea } from '@/api/credit_manage.js'
227 224
228 export default { 225 export default {
229 name: 'ModifyContractForeignStock', 226 name: 'ModifyContractForeignStock',
230 - components: { SingleSelectSheet, RelateSelectSheet, ProductRel, CitySelector }, 227 + components: { SingleSelectSheet, RelateSelectSheet, ProductRel },
231 data() { 228 data() {
232 return { 229 return {
233 id: '', 230 id: '',
@@ -264,8 +261,7 @@ export default { @@ -264,8 +261,7 @@ export default {
264 packagingRequirements: '', 261 packagingRequirements: '',
265 paymentTerms: '', 262 paymentTerms: '',
266 transportMode: '', 263 transportMode: '',
267 - destinationId: [],  
268 - destinationLabel: '', 264 + foreignDestination: '',
269 specialInstructions: '', 265 specialInstructions: '',
270 remarks: '', 266 remarks: '',
271 pieceWeightHead: '', 267 pieceWeightHead: '',
@@ -298,11 +294,6 @@ export default { @@ -298,11 +294,6 @@ export default {
298 this.loadExtraOptions() 294 this.loadExtraOptions()
299 this.loadRegionOptions() 295 this.loadRegionOptions()
300 this.loadDetail() 296 this.loadDetail()
301 - this.$nextTick(() => {  
302 - if (Array.isArray(this.form.destinationId) && this.form.destinationId.length) {  
303 - this.initDestinationLabel()  
304 - }  
305 - })  
306 }, 297 },
307 methods: { 298 methods: {
308 async loadRegionOptions() { 299 async loadRegionOptions() {
@@ -349,8 +340,7 @@ export default { @@ -349,8 +340,7 @@ export default {
349 packagingRequirements: m.packagingRequirements || '', 340 packagingRequirements: m.packagingRequirements || '',
350 paymentTerms: m.paymentTerms || '', 341 paymentTerms: m.paymentTerms || '',
351 transportMode: m.transportMode || '', 342 transportMode: m.transportMode || '',
352 - destinationId: (m.provinceId && m.cityId && m.districtId) ? [m.provinceId, m.cityId, m.districtId] : (Array.isArray(m.destinationId) ? m.destinationId : []),  
353 - destinationLabel: (m.provinceName && m.cityName && m.districtName) ? `${m.provinceName} / ${m.cityName} / ${m.districtName}` : (m.destinationLabel || ''), 343 + foreignDestination: (m.foreignDestination || ''),
354 specialInstructions: m.specialInstructions || '', 344 specialInstructions: m.specialInstructions || '',
355 remarks: m.remarks || '', 345 remarks: m.remarks || '',
356 pieceWeightHead: m.pieceWeightHead || '', 346 pieceWeightHead: m.pieceWeightHead || '',
@@ -371,20 +361,6 @@ export default { @@ -371,20 +361,6 @@ export default {
371 this.onProductsChange(lines) 361 this.onProductsChange(lines)
372 } catch (e) { } 362 } catch (e) { }
373 }, 363 },
374 - async initDestinationLabel() {  
375 - const comp = this.$refs.citySelectorRef  
376 - if (comp && typeof comp.getLabel === 'function') {  
377 - const label = await comp.getLabel()  
378 - this.form.destinationLabel = label || ''  
379 - }  
380 - },  
381 - openCitySelector() {  
382 - this.$refs.citySelectorRef && this.$refs.citySelectorRef.open()  
383 - },  
384 - onCityChange(payload) {  
385 - const label = payload && payload.label != null ? payload.label : ''  
386 - this.form.destinationLabel = label  
387 - },  
388 onProductsChange(products) { 364 onProductsChange(products) {
389 const list = Array.isArray(products) ? products : [] 365 const list = Array.isArray(products) ? products : []
390 this.newProductLineList = list 366 this.newProductLineList = list
@@ -531,7 +507,6 @@ export default { @@ -531,7 +507,6 @@ export default {
531 return true 507 return true
532 }, 508 },
533 async onSubmit() { 509 async onSubmit() {
534 - console.log('onSubmit__payload', payload)  
535 if (!this.validateRequired()) return 510 if (!this.validateRequired()) return
536 const confirmRes = await new Promise(resolve => { 511 const confirmRes = await new Promise(resolve => {
537 uni.showModal({ title: '提示', content: '确定保存当前外贸库存合同吗?', confirmText: '确定', cancelText: '取消', success: resolve }) 512 uni.showModal({ title: '提示', content: '确定保存当前外贸库存合同吗?', confirmText: '确定', cancelText: '取消', success: resolve })
@@ -549,12 +524,9 @@ export default { @@ -549,12 +524,9 @@ export default {
549 return out 524 return out
550 } 525 }
551 const lines = (this.newProductLineList || []).map(it => clean(it)) 526 const lines = (this.newProductLineList || []).map(it => clean(it))
552 - const { destinationLabel, destinationId, ...formForSubmit } = this.form;  
553 - const destination = destinationId && destinationId.length > 0 ? destinationId[destinationId.length - 1] : '';  
554 const payload = clean({ 527 const payload = clean({
555 - ...formForSubmit, 528 + ...this.form,
556 id: this.form.id, 529 id: this.form.id,
557 - destination,  
558 type: 'INTL_INVENTORY_AGMT', 530 type: 'INTL_INVENTORY_AGMT',
559 totalQuantity: this.totalQuantity, 531 totalQuantity: this.totalQuantity,
560 // totalAmountExcludingTax: this.totalAmountExcludingTax, 532 // totalAmountExcludingTax: this.totalAmountExcludingTax,
@@ -812,4 +784,4 @@ export default { @@ -812,4 +784,4 @@ export default {
812 } 784 }
813 } 785 }
814 786
815 -</style>  
  787 +</style>
  1 +<template>
  2 + <view class="page">
  3 + <scroll-view class="scroll" scroll-y>
  4 + <view class="lock-page">
  5 + <view class="block" v-for="(item, idx) in items" :key="idx">
  6 + <view class="block-header">
  7 + <uni-data-checkbox multiple mode="default" :localdata="[{ text: '拆分', value: 'LOCKED' }]"
  8 + :modelValue="item.locked ? ['LOCKED'] : []" :disabled="true"
  9 + @change="onLockChange(idx, $event)" />
  10 + <view class="ops" @click="toggleItem(idx)">
  11 + <image class="opIcon"
  12 + :src="item.collapsed ? '/static/images/up.png' : '/static/images/down.png'" />
  13 + <text class="opText">{{ item.collapsed ? '收起' : '展开' }}</text>
  14 + </view>
  15 + </view>
  16 +
  17 + <uni-list v-show="item.collapsed">
  18 + <uni-list-item title="产品名称">
  19 + <template v-slot:footer>
  20 + <uni-easyinput v-model="item.productName" placeholder="请输入产品名称" :clearable="false"
  21 + disabled />
  22 + </template>
  23 + </uni-list-item>
  24 + <uni-list-item title="行业">
  25 + <template v-slot:footer>
  26 + <uni-easyinput v-model="item.industry" placeholder="请输入行业" :clearable="false"
  27 + disabled />
  28 + </template>
  29 + </uni-list-item>
  30 + <uni-list-item title="牌号">
  31 + <template v-slot:footer>
  32 + <uni-easyinput v-model="item.brand" placeholder="请输入牌号" :clearable="false" disabled />
  33 + </template>
  34 + </uni-list-item>
  35 + <uni-list-item title="品质">
  36 + <template v-slot:footer>
  37 + <uni-easyinput v-model="item.quality" placeholder="请输入品质" :clearable="false" disabled />
  38 + </template>
  39 + </uni-list-item>
  40 + <uni-list-item title="规格(mm)">
  41 + <template v-slot:footer>
  42 + <view class="value value-spec">
  43 + <view v-if="item.thickness" class="value-spec_val">{{ item.thickness }}</view>
  44 + <view v-if="item.thickness" class="value-spec_box">
  45 + <view v-if="item.thicknessTolPos" class="value-spec_box_1">{{
  46 + item.thicknessTolPos > 0 ? '+' + item.thicknessTolPos : item.thicknessTolPos
  47 + }}
  48 + </view>
  49 + <view v-if="item.thicknessTolNeg" class="value-spec_box_2">{{
  50 + item.thicknessTolNeg > 0 ? '+' + item.thicknessTolNeg : item.thicknessTolNeg
  51 + }}
  52 + </view>
  53 + </view>
  54 + <view v-if="item.width" class="value-spec_val p12">*</view>
  55 + <view v-if="item.width" class="value-spec_val">{{ item.width }}</view>
  56 + <view v-if="item.width" class="value-spec_box">
  57 + <view v-if="item.widthTolPos" class="value-spec_box_1">{{ item.widthTolPos > 0 ?
  58 + '+' + item.widthTolPos : item.widthTolPos }}
  59 + </view>
  60 + <view v-if="item.widthTolNeg" class="value-spec_box_2">{{ item.widthTolNeg > 0 ?
  61 + '+' + item.widthTolNeg : item.widthTolNeg }}
  62 + </view>
  63 + </view>
  64 + <view v-if="item.length" class="value-spec_val p12">*</view>
  65 + <view v-if="item.length" class="value-spec_val">{{ item.length }}</view>
  66 + <view v-if="item.length" class="value-spec_box">
  67 + <view v-if="item.lengthTolPos" class="value-spec_box_1">{{ item.lengthTolPos > 0
  68 + ? '+' + item.lengthTolPos : item.lengthTolPos }}
  69 + </view>
  70 + <view v-if="item.lengthTolNeg" class="value-spec_box_2">{{ item.lengthTolNeg > 0
  71 + ? '+' + item.lengthTolNeg : item.lengthTolNeg }}
  72 + </view>
  73 + </view>
  74 + </view>
  75 + </template>
  76 + </uni-list-item>
  77 + <uni-list-item title="物料编码">
  78 + <template v-slot:footer>
  79 + <uni-easyinput v-model="item.materialCode" placeholder="请输入物料编码" :clearable="false" disabled />
  80 + </template>
  81 + </uni-list-item>
  82 + <uni-list-item title="状态">
  83 + <template v-slot:footer>
  84 + <uni-easyinput v-model="item.status" placeholder="请输入状态" :clearable="false" disabled />
  85 + </template>
  86 + </uni-list-item>
  87 + <uni-list-item title="数量">
  88 + <template v-slot:footer>
  89 + <uni-easyinput v-model="item.quantity" type="number" :inputBorder="false" disabled
  90 + placeholder="不可编辑" />
  91 + </template>
  92 + </uni-list-item>
  93 + <uni-list-item title="本次锁价数量">
  94 + <template v-slot:footer>
  95 + <uni-easyinput v-model="item.currentQuantity" type="number" :inputBorder="false" placeholder="请输入本次锁价数量" @input="onImmediateChange(idx)" @blur="onNumberBlur(idx, 'currentQuantity', 3)" />
  96 + </template>
  97 + </uni-list-item>
  98 + <uni-list-item title="单价">
  99 + <template v-slot:footer>
  100 + <uni-easyinput v-model="item.unitPrice" type="digit" :inputBorder="false" disabled
  101 + placeholder="不可编辑" @input="onImmediateChange(idx)"
  102 + @blur="onNumberBlur(idx, 'unitPrice', 0)" />
  103 + </template>
  104 + </uni-list-item>
  105 + <!-- <uni-list-item title="不含税金额">
  106 + <template v-slot:footer>
  107 + <uni-easyinput v-model="item.amountExcludingTax" type="number" :inputBorder="false"
  108 + disabled placeholder="" />
  109 + </template>
  110 + </uni-list-item> -->
  111 + <uni-list-item title="总金额">
  112 + <template v-slot:footer>
  113 + <uni-easyinput v-model="item.totalAmount" type="number" :inputBorder="false" disabled
  114 + placeholder="" />
  115 + </template>
  116 + </uni-list-item>
  117 + <uni-list-item title="发货日期">
  118 + <template v-slot:footer>
  119 + <uni-easyinput v-model="item.deliveryDate" :inputBorder="false" disabled />
  120 + </template>
  121 + </uni-list-item>
  122 + </uni-list>
  123 +
  124 + <uni-list v-show="!item.collapsed">
  125 + <uni-list-item title="产品名称">
  126 + <template v-slot:footer>
  127 + <uni-easyinput v-model="item.productName" placeholder="请输入产品名称" :clearable="false"
  128 + disabled />
  129 + </template>
  130 + </uni-list-item>
  131 + <uni-list-item title="行业">
  132 + <template v-slot:footer>
  133 + <uni-easyinput v-model="item.industry" placeholder="请输入行业" :clearable="false"
  134 + disabled />
  135 + </template>
  136 + </uni-list-item>
  137 + <uni-list-item title="牌号">
  138 + <template v-slot:footer>
  139 + <uni-easyinput v-model="item.brand" placeholder="请输入牌号" :clearable="false" disabled />
  140 + </template>
  141 + </uni-list-item>
  142 +
  143 + </uni-list>
  144 + </view>
  145 + <view class="footer">
  146 + <button class="btn submit" type="primary" @click="onSubmit">提交</button>
  147 + </view>
  148 + </view>
  149 + </scroll-view>
  150 +
  151 +
  152 + </view>
  153 +</template>
  154 +
  155 +<script>
  156 +import { getContractApi, splitQuantityLock } from '@/api/contract'
  157 +
  158 +export default {
  159 + name: 'ContractUnplanLock',
  160 + data() {
  161 + return {
  162 + id: '',
  163 + items: [],
  164 + planQty: 30,
  165 + }
  166 + },
  167 + onLoad(options) {
  168 + const id = options && options.id ? options.id : ''
  169 + this.id = id
  170 + this.loadDetail()
  171 + },
  172 + methods: {
  173 + onLockChange(idx, e) {
  174 + const it = this.items[idx]
  175 + if (!it) return
  176 + const arr = e && e.detail && e.detail.value ? e.detail.value : []
  177 + it.locked = Array.isArray(arr) && arr.length > 0
  178 + this.$set(this.items, idx, it)
  179 + },
  180 + async loadDetail() {
  181 + if (!this.id) return
  182 + try {
  183 + const res = await getContractApi(this.id)
  184 + const data = res && res.data ? res.data : {}
  185 + const lines = Array.isArray(data.contractDistributorLineList) ? data.contractDistributorLineList : []
  186 + const init = lines.map(v => ({
  187 + locked: true,
  188 + collapsed: true,
  189 + raw: v,
  190 + productName: v.rawProductName || v.productName || '',
  191 + industry: v.industry || '',
  192 + brand: v.rawProductGrade || v.brand || '',
  193 + quality: v.quality || '',
  194 + thickness: v.thickness || '',
  195 + thicknessTolPos: v.thicknessTolPos || '',
  196 + thicknessTolNeg: v.thicknessTolNeg || '',
  197 + width: v.width || '',
  198 + widthTolPos: v.widthTolPos || '',
  199 + widthTolNeg: v.widthTolNeg || '',
  200 + length: v.length || '',
  201 + lengthTolPos: v.lengthTolPos || '',
  202 + lengthTolNeg: v.lengthTolNeg || '',
  203 + materialCode: v.materialCode || '',
  204 + status: v.status || '',
  205 + currentQuantity: v.currentQuantity === 0 ? 0 : (v.currentQuantity || ''),
  206 + quantity: v.productQuantity || v.quantity || '',
  207 + unitPrice: v.unitPrice || '',
  208 + // amountExcludingTax: v.amountExcludingTax || 0,
  209 + totalAmount: v.totalAmount || 0,
  210 + deliveryDate: v.deliveryDate || '',
  211 + specDisplay: ''
  212 + }))
  213 + this.items = init.map(it => ({ ...it, specDisplay: this.specOf(it) }))
  214 + this.recalculateAll()
  215 + } catch (e) {
  216 + this.items = []
  217 + }
  218 + },
  219 + toggleItem(idx) {
  220 + const it = this.items[idx]
  221 + if (!it) return
  222 + it.collapsed = !it.collapsed
  223 + this.$set(this.items, idx, it)
  224 + },
  225 + onImmediateChange(idx) {
  226 + this.$nextTick(() => this.recalculate(idx))
  227 + },
  228 + onNumberBlur(idx, field, digits) {
  229 + const it = this.items[idx]
  230 + if (!it) return
  231 + const raw = it[field]
  232 + if (raw === '' || raw === null || raw === undefined) {
  233 + this.$set(this.items, idx, it)
  234 + this.recalculate(idx)
  235 + return
  236 + }
  237 + const num = this.toNumber(raw)
  238 + const rounded = this.round(num, digits)
  239 + it[field] = rounded
  240 + this.$set(this.items, idx, it)
  241 + this.recalculate(idx)
  242 + },
  243 + recalculate(idx) {
  244 + const TAX_RATE = 0.13
  245 + const it = this.items[idx]
  246 + if (!it) return
  247 + const qty = this.toNumber(it.quantity)
  248 + const price = this.toNumber(it.unitPrice)
  249 + const total = this.round(qty * price, 2)
  250 + // const excl = this.round(total / (1 + TAX_RATE), 2)
  251 + // it.amountExcludingTax = excl
  252 + it.totalAmount = total
  253 + this.$set(this.items, idx, it)
  254 + },
  255 + recalculateAll() {
  256 + for (let i = 0; i < this.items.length; i++) this.recalculate(i)
  257 + },
  258 + toNumber(val) {
  259 + if (typeof val === 'number') return isNaN(val) ? 0 : val
  260 + const n = parseFloat(String(val).replace(/[^0-9.\-]/g, ''))
  261 + return isNaN(n) ? 0 : n
  262 + },
  263 + round(val, digits = 2) {
  264 + const n = Number(val)
  265 + if (isNaN(n)) return 0
  266 + const m = Math.pow(10, digits)
  267 + return Math.round(n * m) / m
  268 + },
  269 + specOf(item) {
  270 + const t = [item.thickness, item.thicknessTolPos, item.thicknessTolNeg].filter(Boolean).join('/ ')
  271 + const w = [item.width, item.widthTolPos, item.widthTolNeg].filter(Boolean).join('/ ')
  272 + const l = [item.length, item.lengthTolPos, item.lengthTolNeg].filter(Boolean).join('/ ')
  273 + return [t, w, l].filter(Boolean).join(' × ')
  274 + },
  275 + formatCurrency(val) {
  276 + if (val == null || val === '') return ''
  277 + const num = Number(val)
  278 + const pre = isNaN(num) ? '' : '¥'
  279 + const fixed = isNaN(num) ? String(val) : num.toFixed(2)
  280 + return `${pre}${fixed}`
  281 + },
  282 + onReset() {
  283 + this.items = this.items.map((it, i) => ({
  284 + ...it,
  285 + quantity: '',
  286 + currentQuantity: '',
  287 + unitPrice: '',
  288 + // amountExcludingTax: 0
  289 + }))
  290 + },
  291 + async onSubmit() {
  292 + const selected = this.items.filter(it => it.locked).map(it => {
  293 + const raw = { ...(it.raw || {}) }
  294 + const qty = this.toNumber(it.quantity)
  295 + const price = this.toNumber(it.unitPrice)
  296 + const curQtyRaw = it.currentQuantity
  297 + const total = this.toNumber(it.totalAmount)
  298 + // const excl = this.toNumber(it.amountExcludingTax)
  299 + if (Object.prototype.hasOwnProperty.call(raw, 'productQuantity')) raw.productQuantity = qty
  300 + else raw.quantity = qty
  301 + raw.currentQuantity = (curQtyRaw === '' || curQtyRaw === null || curQtyRaw === undefined) ? null : this.toNumber(curQtyRaw)
  302 + raw.unitPrice = price
  303 + raw.totalAmount = total
  304 + // raw.amountExcludingTax = excl
  305 + return raw
  306 + })
  307 + if (!selected.length) {
  308 + uni.showToast({ title: '未选择任何拆分项', icon: 'none' })
  309 + return
  310 + }
  311 + const invalidQty = selected.find(r => {
  312 + const q = this.toNumber(r.currentQuantity)
  313 + return !(q > 0)
  314 + })
  315 + if (invalidQty) {
  316 + uni.showToast({ title: '请填写本次拆分数量', icon: 'none' })
  317 + return
  318 + }
  319 + this.selectedItems = selected
  320 + const payload = {
  321 + id: this.id,
  322 + contractDistributorLineList: selected
  323 + }
  324 +
  325 + uni.showModal({
  326 + title: '确认提交',
  327 + content: '确定提交拆分吗?',
  328 + success: (res) => {
  329 + if (res.confirm) {
  330 + splitQuantityLock(payload).then(() => {
  331 + uni.showToast({ title: '拆分已提交', icon: 'success' })
  332 + setTimeout(() => {
  333 + uni.navigateTo({ url: '/pages/contract_foreign_stock/index' })
  334 + }, 500)
  335 + }).catch((err) => {
  336 + uni.showToast({ title: err.msg || '提交失败', icon: 'none' })
  337 + })
  338 + }
  339 + }
  340 + })
  341 + }
  342 + }
  343 +}
  344 +</script>
  345 +
  346 +<style lang="scss" scoped>
  347 +.page {
  348 + display: flex;
  349 + flex-direction: column;
  350 + height: 100%;
  351 +}
  352 +
  353 +.scroll {
  354 + flex: 1;
  355 + padding: 12rpx 0 392rpx !important;
  356 +}
  357 +
  358 +.header {
  359 + background-color: #fff;
  360 + display: flex;
  361 + align-items: center;
  362 + padding: 24rpx 32rpx;
  363 + border-bottom: 1rpx solid #f0f0f0;
  364 +}
  365 +
  366 +.title {
  367 + font-size: 32rpx;
  368 + color: rgba(0, 0, 0, 0.9);
  369 + font-weight: 600;
  370 +}
  371 +
  372 +.opCollapse {
  373 + width: 24rpx;
  374 + height: 24rpx;
  375 + margin-right: 16rpx;
  376 + margin-top: 8rpx;
  377 +}
  378 +
  379 +.block {
  380 + background: #fff;
  381 + margin-top: 20rpx;
  382 +}
  383 +
  384 +.block-header {
  385 + display: flex;
  386 + align-items: center;
  387 + padding: 24rpx 32rpx;
  388 + border-bottom: 1rpx solid #f0f0f0;
  389 +}
  390 +
  391 +.block-header ::v-deep .uni-data-checklist .checkbox__inner {
  392 + width: 36rpx;
  393 + height: 36rpx;
  394 +}
  395 +
  396 +.block-header ::v-deep .uni-data-checklist .checklist-text {
  397 + font-size: 28rpx;
  398 + margin-left: 12rpx;
  399 +}
  400 +
  401 +.block-title {
  402 + margin-left: 12rpx;
  403 + font-size: 28rpx;
  404 + color: rgba(0, 0, 0, 0.9);
  405 +}
  406 +
  407 +.ops {
  408 + margin-left: auto;
  409 + display: flex;
  410 + align-items: center;
  411 + color: $theme-primary;
  412 + font-size: 28rpx;
  413 +}
  414 +
  415 +.opIcon {
  416 + width: 40rpx;
  417 + height: 40rpx;
  418 +}
  419 +
  420 +.opText {
  421 + margin-left: 8rpx;
  422 + color: $theme-primary;
  423 +}
  424 +
  425 +::v-deep .uni-list {
  426 + .uni-easyinput {
  427 + display: flex;
  428 +
  429 + .uni-input-input {
  430 + color: rgba(0, 0, 0, 0.9);
  431 + }
  432 + }
  433 +
  434 + .uni-input-placeholder {
  435 + z-index: 1;
  436 + }
  437 +
  438 + .uni-input-input {
  439 + background-color: #ffffff;
  440 + }
  441 +
  442 + background: transparent;
  443 +
  444 + &-item {
  445 + &__extra-text {
  446 + font-size: 32rpx;
  447 + }
  448 +
  449 + &__content-title {
  450 + font-size: 32rpx;
  451 + color: rgba(0, 0, 0, 0.9);
  452 + }
  453 +
  454 + &__container {
  455 + padding: 32rpx;
  456 +
  457 + .uni-easyinput {
  458 + &__placeholder-class {
  459 + font-size: 32rpx;
  460 + color: rgba(0, 0, 0, 0.4);
  461 + }
  462 +
  463 + &__content {
  464 + border: none;
  465 + background-color: #ffffff !important;
  466 +
  467 + &-input {
  468 + padding-left: 0 !important;
  469 + height: 48rpx;
  470 + line-height: 48rpx;
  471 + font-size: 32rpx;
  472 + }
  473 +
  474 + .content-clear-icon {
  475 + font-size: 44rpx !important;
  476 + }
  477 + }
  478 + }
  479 +
  480 + .item-title,
  481 + .uni-list-item__content {
  482 + flex: none;
  483 + min-height: 48rpx;
  484 + line-height: 48rpx;
  485 + font-size: 32rpx;
  486 + position: relative;
  487 + width: 210rpx;
  488 + margin-right: 32rpx;
  489 + color: rgba(0, 0, 0, 0.9);
  490 +
  491 + .required {
  492 + color: red;
  493 + position: absolute;
  494 + top: 50%;
  495 + transform: translateY(-50%);
  496 + left: -16rpx;
  497 + }
  498 + }
  499 + }
  500 +
  501 + &.select-item {
  502 + &.is-empty {
  503 + .uni-list-item__extra-text {
  504 + color: rgba(0, 0, 0, 0.4) !important;
  505 + }
  506 + }
  507 +
  508 + &.is-filled {
  509 + .uni-list-item__extra-text {
  510 + color: rgba(0, 0, 0, 0.9) !important;
  511 + }
  512 + }
  513 + }
  514 +
  515 + &.mgb10 {
  516 + margin-bottom: 20rpx;
  517 + }
  518 + }
  519 +}
  520 +
  521 +// ::v-deep .uni-list-item__container {
  522 +// padding: 32rpx;
  523 +// }
  524 +
  525 +::v-deep .is-disabled {
  526 + background-color: transparent !important;
  527 +}
  528 +
  529 +// ::v-deep .uni-list-item__content-title {
  530 +// font-size: 28rpx;
  531 +// color: rgba(0, 0, 0, 0.9);
  532 +// }
  533 +
  534 +// ::v-deep .uni-list-item__extra-text {
  535 +// font-size: 32rpx;
  536 +// }
  537 +
  538 +::v-deep .uni-easyinput {
  539 + width: 100%;
  540 +}
  541 +
  542 +::v-deep .uni-easyinput__placeholder-class {
  543 + font-size: 32rpx;
  544 + color: rgba(0, 0, 0, 0.4);
  545 +}
  546 +
  547 +::v-deep .uni-easyinput__content {
  548 + border: none;
  549 + display: flex;
  550 +}
  551 +
  552 +::v-deep .uni-easyinput__content-input {
  553 + padding-left: 0 !important;
  554 + height: 48rpx;
  555 + line-height: 48rpx;
  556 + font-size: 32rpx;
  557 + color: rgba(0, 0, 0, 0.9);
  558 +}
  559 +
  560 +.amount-item .item-title {
  561 + display: flex;
  562 + align-items: center;
  563 +}
  564 +
  565 +.amount-row {
  566 + display: flex;
  567 + align-items: center;
  568 +}
  569 +
  570 +.amount-row .unit {
  571 + margin-left: 12rpx;
  572 + color: rgba(0, 0, 0, 0.6);
  573 +}
  574 +
  575 +.summary {
  576 + margin-top: 20rpx;
  577 + background: #fff;
  578 + padding-bottom: 12rpx;
  579 +}
  580 +
  581 +.title-header {
  582 + display: flex;
  583 + align-items: center;
  584 + padding: 20rpx 32rpx;
  585 +}
  586 +
  587 +.title-header_icon {
  588 + width: 24rpx;
  589 + height: 24rpx;
  590 + margin-right: 16rpx;
  591 +}
  592 +
  593 +.sum-card {
  594 + background: #f3f3f3;
  595 + border-radius: 16rpx;
  596 + padding: 24rpx;
  597 + margin: 0 32rpx 20rpx;
  598 +}
  599 +
  600 +.row {
  601 + display: flex;
  602 + margin-bottom: 16rpx;
  603 +}
  604 +
  605 +.row .label {
  606 + width: 140rpx;
  607 + color: rgba(0, 0, 0, 0.6);
  608 + font-size: 28rpx;
  609 +}
  610 +
  611 +.row .value {
  612 + flex: 1;
  613 + text-align: right;
  614 + color: rgba(0, 0, 0, 0.9);
  615 + font-size: 28rpx;
  616 +}
  617 +
  618 +.row .amount {
  619 + color: #D54941;
  620 +}
  621 +
  622 +.total {
  623 + .total-text {
  624 + font-weight: 600;
  625 + font-size: 32rpx;
  626 + color: rgba(0, 0, 0, 0.9);
  627 + padding-bottom: 28rpx;
  628 + border-bottom: 2rpx solid #E7E7E7;
  629 + }
  630 +
  631 + .total-item {
  632 + display: flex;
  633 + align-items: center;
  634 +
  635 + .total-item-text {
  636 + font-weight: 400;
  637 + font-size: 28rpx;
  638 + color: rgba(0, 0, 0, 0.6);
  639 + line-height: 32rpx;
  640 + width: 240rpx;
  641 + padding: 12rpx 0;
  642 + }
  643 +
  644 + .total-item-price {
  645 + font-weight: 600;
  646 + font-size: 32rpx;
  647 + color: rgba(0, 0, 0, 0.9);
  648 + line-height: 32rpx;
  649 + }
  650 +
  651 + .text-red {
  652 + color: #D54941;
  653 + }
  654 + }
  655 +
  656 +}
  657 +
  658 +.footer {
  659 + z-index: 2;
  660 + position: fixed;
  661 + left: 0;
  662 + right: 0;
  663 + bottom: 0;
  664 + padding: 32rpx;
  665 + padding-bottom: calc(32rpx + env(safe-area-inset-bottom));
  666 + background: #fff;
  667 + box-shadow: 0 -8rpx 24rpx rgba(0, 0, 0, 0.06);
  668 +
  669 + .btn {
  670 + height: 80rpx;
  671 + line-height: 80rpx;
  672 + border-radius: 12rpx;
  673 + font-size: 32rpx;
  674 + }
  675 +
  676 + .submit {
  677 + background: $theme-primary;
  678 + color: #fff;
  679 + }
  680 +}
  681 +
  682 +.btn {
  683 + height: 80rpx;
  684 + line-height: 80rpx;
  685 + border-radius: 12rpx;
  686 + font-size: 32rpx;
  687 + flex: 1;
  688 +}
  689 +
  690 +.submit {
  691 + background: $theme-primary;
  692 + color: #fff;
  693 +}
  694 +
  695 +.value-spec {
  696 + height: 48rpx;
  697 + display: flex;
  698 + align-items: center;
  699 + color: #000000;
  700 +
  701 + // justify-content: end;
  702 + &_box {
  703 + position: relative;
  704 + width: 60rpx;
  705 + height: 48rpx;
  706 +
  707 + &_1 {
  708 + font-size: 16rpx;
  709 + position: absolute;
  710 + top: -10rpx;
  711 + left: 0;
  712 + }
  713 +
  714 + &_2 {
  715 + font-size: 16rpx;
  716 + position: absolute;
  717 + bottom: -10rpx;
  718 + left: 0;
  719 + }
  720 + }
  721 +
  722 + &_val {
  723 + font-size: 28rpx;
  724 +
  725 + &.p12 {
  726 + padding-right: 12rpx;
  727 + }
  728 + }
  729 +}
  730 +
  731 +.row-spec {
  732 + height: 60rpx;
  733 + align-items: center;
  734 +}
  735 +</style>
  1 +<template>
  2 + <view class="page">
  3 + <scroll-view class="scroll" scroll-y>
  4 + <uni-list>
  5 + <uni-list-item title="编号">
  6 + <template v-slot:footer>
  7 + <uni-easyinput v-model="form.code" :inputBorder="false" disabled />
  8 + </template>
  9 + </uni-list-item>
  10 +
  11 + <uni-list-item class="select-item" :class="form.supplier ? 'is-filled' : 'is-empty'" clickable
  12 + @click="openSheet('supplier')" :rightText="displayLabel('supplierName')" showArrow>
  13 + <template v-slot:body>
  14 + <view class="item-title"><text class="required">*</text><text>供方</text></view>
  15 + </template>
  16 + </uni-list-item>
  17 +
  18 + <uni-list-item class="select-item" :class="form.buyer ? 'is-filled' : 'is-empty'" clickable
  19 + @click="openRelate('buyer')" :rightText="form.buyerName || '请选择需方'" showArrow>
  20 + <template v-slot:body>
  21 + <view class="item-title"><text class="required">*</text><text>需方</text></view>
  22 + </template>
  23 + </uni-list-item>
  24 +
  25 + <uni-list-item class="select-item" :class="form.stockUpCompanyId ? 'is-filled' : 'is-empty'" clickable
  26 + @click="openRelate('stockUpCompanyId')" :rightText="form.stockUpCompanyName || '请选择备货单位'" showArrow>
  27 + <template v-slot:body>
  28 + <view class="item-title"><text class="required">*</text><text>备货单位/人(生产标准)</text></view>
  29 + </template>
  30 + </uni-list-item>
  31 +
  32 + <uni-list-item class="select-item" :class="form.workshopId ? 'is-filled' : 'is-empty'" clickable
  33 + @click="openSheet('workshopId')" :rightText="form.workshopName || '请选择生产厂'" showArrow>
  34 + <template v-slot:body>
  35 + <view class="item-title"><text class="required">*</text><text>生产厂</text></view>
  36 + </template>
  37 + </uni-list-item>
  38 + <uni-list-item class="select-item" :class="form.deptName ? 'is-filled' : 'is-empty'">
  39 + <template v-slot:body>
  40 + <view class="item-title"><text class="required">*</text><text>办事处</text></view>
  41 + </template>
  42 + <template v-slot:footer>
  43 + <view class="serial-number-row">
  44 + <uni-easyinput v-model="form.deptName" :inputBorder="false" disabled />
  45 + </view>
  46 + </template>
  47 + </uni-list-item>
  48 + <uni-list-item class="select-item" :class="form.region ? 'is-filled' : 'is-empty'" clickable
  49 + @click="openSheet('region')" :rightText="displayLabel('regionName')" showArrow>
  50 + <template v-slot:body>
  51 + <view class="item-title"><text class="required">*</text><text>区域</text></view>
  52 + </template>
  53 + </uni-list-item>
  54 +
  55 + <uni-list-item title="订货日期">
  56 + <template v-slot:footer>
  57 + <uni-datetime-picker type="date" v-model="form.orderDate" />
  58 + </template>
  59 + </uni-list-item>
  60 +
  61 + <uni-list-item title="单位">
  62 + <template v-slot:footer>
  63 + <uni-easyinput v-model="form.unit" :inputBorder="false" disabled />
  64 + </template>
  65 + </uni-list-item>
  66 +
  67 + <ProductRel ref="productRel" mode="add" :deliveryDate="form.orderDate" :deliveryDateBase="form.deliveryDate"
  68 + :list="productLineList" @change="onProductsChange" :options="productList" />
  69 +
  70 + <uni-list-item title="合计金额(大写)">
  71 + <template v-slot:footer>
  72 + <uni-easyinput v-model="form.totalAmountCapital" placeholder="" :inputBorder="false" disabled />
  73 + </template>
  74 + </uni-list-item>
  75 + <uni-list-item title="交付定金、数额、时间">
  76 + <template v-slot:footer>
  77 + <uni-easyinput v-model="form.depositInfo" placeholder="请输入交付定金、数额、时间" :inputBorder="false" />
  78 + </template>
  79 + </uni-list-item>
  80 + <uni-list-item title="包装要求">
  81 + <template v-slot:footer>
  82 + <uni-easyinput v-model="form.packagingRequirements" placeholder="请输入包装要求" :inputBorder="false" />
  83 + </template>
  84 + </uni-list-item>
  85 + <uni-list-item title="付款方式、付款期限">
  86 + <template v-slot:footer>
  87 + <uni-easyinput v-model="form.paymentTerms" placeholder="请输入付款方式、付款期限" :inputBorder="false" />
  88 + </template>
  89 + </uni-list-item>
  90 + <uni-list-item title="运输方式">
  91 + <template v-slot:footer>
  92 + <uni-easyinput v-model="form.transportMode" placeholder="请输入运输方式" :inputBorder="false" />
  93 + </template>
  94 + </uni-list-item>
  95 + <uni-list-item title="目的地">
  96 + <template v-slot:footer>
  97 + <uni-easyinput v-model="form.foreignDestination" placeholder="请输入目的地" :inputBorder="false" />
  98 + </template>
  99 + </uni-list-item>
  100 +
  101 + <uni-list-item class="select-item" :class="form.includesPackagingFeeName ? 'is-filled' : 'is-empty'" clickable
  102 + @click="openSheet('includesPackagingFee')" :rightText="form.includesPackagingFeeName || '请选择'" showArrow>
  103 + <template v-slot:body>
  104 + <view class="item-title"><text>单价中是否已包含包装费</text></view>
  105 + </template>
  106 + </uni-list-item>
  107 + <uni-list-item class="select-item" :class="form.includesTransportFeeName ? 'is-filled' : 'is-empty'" clickable
  108 + @click="openSheet('includesTransportFee')" :rightText="form.includesTransportFeeName || '请选择'" showArrow>
  109 + <template v-slot:body>
  110 + <view class="item-title"><text>单价中是否已包含运费</text></view>
  111 + </template>
  112 + </uni-list-item>
  113 + <uni-list-item title="需方指定收货人">
  114 + <template v-slot:footer>
  115 + <uni-easyinput v-model="form.designatedConsignee" placeholder="请输入需方指定收货人" :inputBorder="false" />
  116 + </template>
  117 + </uni-list-item>
  118 + <uni-list-item class="select-item" :class="form.specialTermsName ? 'is-filled' : 'is-empty'" clickable
  119 + @click="openSheet('specialTerms')" :rightText="form.specialTermsName || '请选择'" showArrow>
  120 + <template v-slot:body>
  121 + <view class="item-title"><text class="required">*</text><text>特别条款要求</text></view>
  122 + </template>
  123 + </uni-list-item>
  124 + <uni-list-item class="select-item" :class="form.executionStandardName ? 'is-filled' : 'is-empty'" clickable
  125 + @click="openSheet('executionStandard')" :rightText="form.executionStandardName || '请选择'" showArrow>
  126 + <template v-slot:body>
  127 + <view class="item-title"><text>执行标准</text></view>
  128 + </template>
  129 + </uni-list-item>
  130 + <uni-list-item v-if="form.executionStandard === 'OTHER'" title="其他">
  131 + <template v-slot:footer>
  132 + <uni-easyinput v-model="form.executionStandardRemarks" placeholder="请输入其他标准备注" :inputBorder="false" />
  133 + </template>
  134 + </uni-list-item>
  135 + <uni-list-item title="特别说明" style="margin-top: 20rpx;">
  136 + <template v-slot:footer>
  137 + <uni-easyinput v-model="form.specialInstructions" placeholder="请输入特别说明" :inputBorder="false" />
  138 + </template>
  139 + </uni-list-item>
  140 + <uni-list-item title="备注">
  141 + <template v-slot:footer>
  142 + <uni-easyinput v-model="form.remarks" placeholder="请输入备注" :inputBorder="false" maxlength="2000" />
  143 + </template>
  144 + </uni-list-item>
  145 +
  146 + <view class="quality">
  147 + <image class="opCollapse" src="/static/images/title.png" />
  148 + <text class="title">具体质量要求</text>
  149 + </view>
  150 + <uni-list-item title="件重条头">
  151 + <template v-slot:footer>
  152 + <uni-easyinput v-model="form.pieceWeightHead" placeholder="请输入" :inputBorder="false" />
  153 + </template>
  154 + </uni-list-item>
  155 + <uni-list-item title="表面">
  156 + <template v-slot:footer>
  157 + <uni-easyinput v-model="form.surface" placeholder="请输入" :inputBorder="false" />
  158 + </template>
  159 + </uni-list-item>
  160 + <uni-list-item title="公差">
  161 + <template v-slot:footer>
  162 + <uni-easyinput v-model="form.tolerance" placeholder="请输入" :inputBorder="false" />
  163 + </template>
  164 + </uni-list-item>
  165 + <uni-list-item title="性能">
  166 + <template v-slot:footer>
  167 + <uni-easyinput v-model="form.performance" placeholder="请输入" :inputBorder="false" />
  168 + </template>
  169 + </uni-list-item>
  170 + <uni-list-item title="成分">
  171 + <template v-slot:footer>
  172 + <uni-easyinput v-model="form.component" placeholder="请输入" :inputBorder="false" />
  173 + </template>
  174 + </uni-list-item>
  175 + <uni-list-item title="包装">
  176 + <template v-slot:footer>
  177 + <uni-easyinput v-model="form.packaging" placeholder="请输入" :inputBorder="false" />
  178 + </template>
  179 + </uni-list-item>
  180 +
  181 + <uni-list-item :title="uploadType === 'seal' ? '双方盖章合同附件' : (uploadType === 'formal' ? '正式合同附件' : '标准合同附件')" style="margin-top: 20rpx;">
  182 + <template v-slot:footer>
  183 + <FileUpload v-model="fileInfo" />
  184 + </template>
  185 + </uni-list-item>
  186 + <uni-list-item v-if="uploadType !== 'seal'" class="select-item" :class="standardStandardizedName ? 'is-filled' : 'is-empty'" clickable
  187 + @click="openSheet('standardStandardized')" :rightText="standardStandardizedName || '请选择'" showArrow>
  188 + <template v-slot:body>
  189 + <view class="item-title"><text class="required">*</text><text>合同是否规范</text></view>
  190 + </template>
  191 + </uni-list-item>
  192 +
  193 + <view class="footer">
  194 + <div class="total">
  195 + <div class="total-text">合计</div>
  196 + <div class="total-item" style="padding: 20rpx 0;">
  197 + <div class="total-item-text">数量</div>
  198 + <div class="total-item-price">{{ (totalQuantity || 0).toFixed(2) }}kg</div>
  199 + </div>
  200 + </div>
  201 + <button class="btn submit" type="primary" @click="onSubmit">提交</button>
  202 + </view>
  203 + </uni-list>
  204 + </scroll-view>
  205 +
  206 + <SingleSelectSheet :visible.sync="sheet.visible" :title="sheet.title" :options="sheet.options" v-model="sheet.value"
  207 + @confirm="onSheetConfirm" />
  208 + <RelateSelectSheet :visible.sync="relate.visible" :title="relate.title" :source="relate.source"
  209 + :display-fields="relate.display" :multiple="relate.multiple" :row-key="relate.rowKey"
  210 + :selectedKeys.sync="relate.selectedKeys" @confirm="onRelateConfirm" />
  211 + </view>
  212 +</template>
  213 +
  214 +<script>
  215 +import SingleSelectSheet from '@/components/single-select/index.vue'
  216 +import RelateSelectSheet from '@/components/relate-select/index.vue'
  217 +import ProductRel from './productRel.vue'
  218 +import FileUpload from '@/components/file-upload/index.vue'
  219 +import { getContractApi, uploadFormalContract, uploadStandardContract, uploadSignedContractFile } from '@/api/contract'
  220 +import { getDicByCodes } from '@/utils/dic'
  221 +import { formatCurrencyToChinese } from '@/utils/common'
  222 +import { workshopQueryApi } from '@/api/devManage'
  223 +import { getArea } from '@/api/credit_manage.js'
  224 +
  225 +export default {
  226 + name: 'UploadContractForeignStock',
  227 + components: { SingleSelectSheet, RelateSelectSheet, ProductRel, FileUpload },
  228 + data() {
  229 + return {
  230 + id: '',
  231 + uploadType: 'formal',
  232 + fileInfo: { id: '', name: '' },
  233 + standardStandardized: '',
  234 + standardStandardizedName: '',
  235 + form: {
  236 + id: '',
  237 + code: '',
  238 + supplier: '',
  239 + supplierName: '',
  240 + buyer: '',
  241 + buyerName: '',
  242 + stockUpCompanyId: '',
  243 + stockUpCompanyName: '',
  244 + workshopId: '',
  245 + workshopName: '',
  246 + region: '',
  247 + regionName: '',
  248 + deptName: '',
  249 + deptId: '',
  250 + orderDate: '',
  251 + deliveryDate: '',
  252 + designatedConsignee: '',
  253 + specialTerms: '',
  254 + specialTermsName: '',
  255 + executionStandard: '',
  256 + executionStandardName: '',
  257 + executionStandardRemarks: '',
  258 + includesPackagingFee: false,
  259 + includesPackagingFeeName: '否',
  260 + includesTransportFee: false,
  261 + includesTransportFeeName: '否',
  262 + unit: '美元、公斤、美元/公斤',
  263 + totalAmountCapital: '',
  264 + depositInfo: '',
  265 + packagingRequirements: '',
  266 + paymentTerms: '',
  267 + transportMode: '',
  268 + foreignDestination: '',
  269 + specialInstructions: '',
  270 + remarks: '',
  271 + pieceWeightHead: '',
  272 + surface: '',
  273 + tolerance: '',
  274 + performance: '',
  275 + component: '',
  276 + packaging: ''
  277 + },
  278 + supplierList: [],
  279 + specialTermsList: [],
  280 + executionStandardList: [],
  281 + yesNoList: [{ label: '是', value: true }, { label: '否', value: false }],
  282 + sheet: { visible: false, title: '请选择', field: '', options: [], value: '' },
  283 + relate: { visible: false, title: '选择', source: '', display: [], multiple: false, rowKey: 'id', selectedKeys: [], fieldKey: '' },
  284 + totalQuantity: 0,
  285 + totalAmountIncludingTax: 0,
  286 + productLineList: [],
  287 + newProductLineList: [],
  288 + productList: [],
  289 + regionOptions: [],
  290 + }
  291 + },
  292 + onLoad(query) {
  293 + this.id = (query && query.id) ? query.id : ''
  294 + },
  295 + created() {
  296 + this.loadSuppliers()
  297 + this.loadExtraOptions()
  298 + this.loadRegionOptions()
  299 + this.loadDetail()
  300 + },
  301 + methods: {
  302 + async loadRegionOptions() {
  303 + try {
  304 + const res = await getArea()
  305 + const list = res.data || []
  306 + this.regionOptions = (list || []).map(it => ({ label: it.name || '', value: it.id || '' }))
  307 + } catch (e) {
  308 + this.regionOptions = []
  309 + }
  310 + },
  311 + async loadDetail() {
  312 + if (!this.id) return
  313 + try {
  314 + const res = await getContractApi(this.id)
  315 + const data = res && res.data ? res.data : {}
  316 + const includesPackagingFeeName = data.includesPackagingFeeName || (data.includesPackagingFee ? '是' : '否')
  317 + const includesTransportFeeName = data.includesTransportFeeName || (data.includesTransportFee ? '是' : '否')
  318 + const m = { ...data, includesPackagingFeeName, includesTransportFeeName }
  319 + this.form = {
  320 + ...this.form,
  321 + id: m.id || '',
  322 + code: m.code || '',
  323 + supplier: m.supplier || '',
  324 + supplierName: m.supplierName || '',
  325 + buyer: m.buyer || (m.customer && m.customer.id) || '',
  326 + buyerName: m.buyerName || (m.customer && m.customer.name) || '',
  327 + stockUpCompanyId: m.stockUpCompanyId || '',
  328 + stockUpCompanyName: m.stockUpCompanyName || '',
  329 + orderDate: m.orderDate || '',
  330 + designatedConsignee: m.designatedConsignee || '',
  331 + specialTerms: m.specialTerms || '',
  332 + specialTermsName: m.specialTermsName || '',
  333 + executionStandard: m.executionStandard || '',
  334 + executionStandardName: m.executionStandardName || '',
  335 + executionStandardRemarks: m.executionStandardRemarks || '',
  336 + includesPackagingFee: !!m.includesPackagingFee,
  337 + includesPackagingFeeName,
  338 + includesTransportFee: !!m.includesTransportFee,
  339 + includesTransportFeeName,
  340 + unit: m.unit || this.form.unit,
  341 + totalAmountCapital: m.totalAmountCapital || '',
  342 + depositInfo: m.depositInfo || '',
  343 + packagingRequirements: m.packagingRequirements || '',
  344 + paymentTerms: m.paymentTerms || '',
  345 + transportMode: m.transportMode || '',
  346 + foreignDestination: (m.foreignDestination || ''),
  347 + specialInstructions: m.specialInstructions || '',
  348 + remarks: m.remarks || '',
  349 + pieceWeightHead: m.pieceWeightHead || '',
  350 + surface: m.surface || '',
  351 + tolerance: m.tolerance || '',
  352 + performance: m.performance || '',
  353 + component: m.component || '',
  354 + packaging: m.packaging || '',
  355 + workshopId: m.workshopId || '',
  356 + workshopName: m.workshopName || '',
  357 + region: m.region || '',
  358 + regionName: m.regionName || '',
  359 + deptName: m.deptName || '',
  360 + deptId: m.deptId || '',
  361 + }
  362 +
  363 + const fileId = (this.uploadType === 'seal') ? m.signedContractFileId : (this.uploadType === 'formal') ? m.formalFileId : m.standardFileId
  364 + const fileName = (this.uploadType === 'seal') ? m.signedContractFileName : (this.uploadType === 'formal') ? m.formalFileName : m.standardFileName
  365 + const standardized = (this.uploadType === 'formal') ? m.formalStandardized : (this.uploadType === 'standard') ? m.standardStandardized : ''
  366 + this.fileInfo = { id: fileId || '', name: fileName || '' }
  367 + this.standardStandardized = (standardized === true || standardized === false) ? standardized : ''
  368 + this.standardStandardizedName = (this.standardStandardized === true) ? '是' : (this.standardStandardized === false) ? '否' : ''
  369 +
  370 + const lines = Array.isArray(m.contractDistributorLineList) ? m.contractDistributorLineList : []
  371 + this.productLineList = lines
  372 + this.onProductsChange(lines)
  373 + } catch (e) { }
  374 + },
  375 + onProductsChange(products) {
  376 + const list = Array.isArray(products) ? products : []
  377 + this.newProductLineList = list
  378 + const sumQ = list.reduce((acc, it) => acc + (parseFloat(it.quantity) || 0), 0)
  379 + const sumT = list.reduce((acc, it) => acc + (parseFloat(it.totalAmount) || 0), 0)
  380 + this.totalQuantity = sumQ
  381 + this.totalAmountIncludingTax = sumT
  382 + this.form.totalAmountCapital = formatCurrencyToChinese(sumT)
  383 + },
  384 + async loadSuppliers() {
  385 + try {
  386 + const results = await getDicByCodes(['SUPPLIER'])
  387 + const items = results && results.SUPPLIER && results.SUPPLIER.data ? results.SUPPLIER.data : []
  388 + this.supplierList = items.map(it => ({ label: it.name, value: it.code }))
  389 + } catch (e) { this.supplierList = [] }
  390 + },
  391 + async loadExtraOptions() {
  392 + try {
  393 + const results = await getDicByCodes(['CONDITIONS_REQUIRED', 'APPLICABLE_STANDARD', 'CONTRACT_PRODUCT'])
  394 + const c1 = results && results.CONDITIONS_REQUIRED && results.CONDITIONS_REQUIRED.data ? results.CONDITIONS_REQUIRED.data : []
  395 + const c2 = results && results.APPLICABLE_STANDARD && results.APPLICABLE_STANDARD.data ? results.APPLICABLE_STANDARD.data : []
  396 + const c3 = results && results.CONTRACT_PRODUCT && results.CONTRACT_PRODUCT.data ? results.CONTRACT_PRODUCT.data : []
  397 + this.specialTermsList = c1.map(it => ({ label: it.name, value: it.code }))
  398 + this.executionStandardList = c2.map(it => ({ label: it.name, value: it.code }))
  399 + this.productList = c3.map(it => ({ label: it.name, value: it.code }))
  400 + } catch (e) {
  401 + this.specialTermsList = []
  402 + this.executionStandardList = []
  403 + this.productList = []
  404 + }
  405 + },
  406 + displayLabel(field) {
  407 + const m = this.form
  408 + const map = { supplierName: '请选择供方', buyerName: '请选择需方', workshopName: '请选择生产厂', regionName: '请选择区域' }
  409 + const val = m[field]
  410 + return val ? String(val) : map[field]
  411 + },
  412 + async openSheet(field) {
  413 + if (field === 'standardStandardized') {
  414 + const options = this.yesNoList
  415 + const current = this.standardStandardized
  416 + const match = (options || []).find(o => String(o.value) === String(current) || String(o.label) === String(current))
  417 + this.sheet = { ...this.sheet, visible: true, title: '合同是否规范', options, field, value: match ? match.value : '' }
  418 + return
  419 + }
  420 + const setSheet = (title, options) => {
  421 + const current = this.form[field]
  422 + const match = (options || []).find(o => String(o.label) === String(current) || String(o.value) === String(current))
  423 + this.sheet = { ...this.sheet, visible: true, title, options, field, value: match ? match.value : '' }
  424 + }
  425 + if (field === 'workshopId') {
  426 + const res = await workshopQueryApi({ pageIndex: 1, pageSize: 9999 })
  427 + const _data = res.data || {}
  428 + const list = _data.datas || (Array.isArray(_data) ? _data : [])
  429 + const opts = (list || []).map(it => ({ label: it.name, value: it.id }))
  430 + setSheet('生产厂', opts)
  431 + } else if (field === 'supplier') {
  432 + setSheet('供方', this.supplierList)
  433 + } else if (field === 'specialTerms') {
  434 + setSheet('特别条款要求', this.specialTermsList)
  435 + } else if (field === 'executionStandard') {
  436 + setSheet('执行标准', this.executionStandardList)
  437 + } else if (field === 'includesPackagingFee') {
  438 + setSheet('单价中是否已包含包装费', this.yesNoList)
  439 + } else if (field === 'includesTransportFee') {
  440 + setSheet('单价中是否已包含运费', this.yesNoList)
  441 + } else if (field === 'region') {
  442 + setSheet('区域', this.regionOptions)
  443 + }
  444 + },
  445 + onSheetConfirm({ value, label }) {
  446 + const field = this.sheet.field
  447 + if (!field) return
  448 + const v = (value === undefined || value === null) ? '' : value
  449 + if (field === 'standardStandardized') {
  450 + this.standardStandardized = v
  451 + this.standardStandardizedName = label || ''
  452 + return
  453 + }
  454 + this.form[field] = v
  455 + this.form[field + 'Name'] = label || ''
  456 + },
  457 + openRelate(fieldKey) {
  458 + let config = {}
  459 + if (fieldKey === 'buyer') {
  460 + config = { title: '需方', source: 'customer', rowKey: 'id', multiple: false, display: [{ label: '名称', field: 'name' }, { label: '编号', field: 'code' }, { label: '状态', field: 'available', format: v => (v ? '启用' : '停用') }] }
  461 + } else if (fieldKey === 'stockUpCompanyId') {
  462 + config = { title: '备货单位/人(生产标准)', source: 'customer', rowKey: 'id', multiple: false, display: [{ label: '姓名', field: 'name' }, { label: '编号', field: 'code' }, { label: '状态', field: 'available', format: v => (v ? '启用' : '停用') }] }
  463 + }
  464 + const selectedKeys = this.form[fieldKey] ? [this.form[fieldKey]] : []
  465 + this.sheet.visible = false
  466 + this.relate = { ...this.relate, title: config.title, source: config.source, display: config.display, multiple: config.multiple, rowKey: config.rowKey, selectedKeys, fieldKey }
  467 + this.$nextTick(() => { this.relate.visible = true })
  468 + },
  469 + onRelateConfirm({ items }) {
  470 + const _fieldKey = this.relate.fieldKey
  471 + const first = (items && items.length > 0) ? items[0] : null
  472 + this.form[_fieldKey] = (first && first.id) ? first.id : ''
  473 + if (_fieldKey === 'stockUpCompanyId') {
  474 + this.form.stockUpCompanyName = (first && first.name) ? first.name : ''
  475 + } else {
  476 + this.form[_fieldKey + 'Name'] = (first && first.name) ? first.name : ''
  477 + }
  478 + },
  479 + validateRequired() {
  480 + const checks = [
  481 + { key: 'code', label: '编号' },
  482 + { key: 'supplier', label: '供方' },
  483 + { key: 'buyer', label: '需方' },
  484 + { key: 'stockUpCompanyId', label: '备货单位/人(生产标准)' },
  485 + { key: 'orderDate', label: '订货日期' },
  486 + { key: 'unit', label: '单位' },
  487 + { key: 'workshopId', label: '生产厂' },
  488 + { key: 'region', label: '区域' },
  489 + { key: 'specialTerms', label: '特别条款要求' },
  490 + ]
  491 + for (const it of checks) {
  492 + const val = this.form[it.key]
  493 + const empty = (val === undefined || val === null || (typeof val === 'string' && val.trim() === '') || (typeof val === 'number' && isNaN(val)))
  494 + if (empty) { uni.showToast({ title: `请先选择${it.label}`, icon: 'none' }); return false }
  495 + }
  496 + const list = Array.isArray(this.newProductLineList) ? this.newProductLineList : []
  497 + if (list.length === 0) {
  498 + uni.showToast({ title: '请至少添加一条产品明细', icon: 'none' }); return false
  499 + }
  500 + const strEmpty = (v) => (v === undefined || v === null || (typeof v === 'string' && v.trim() === ''))
  501 + const numEmpty = (v) => (v === undefined || v === null || v === '' || (typeof v === 'number' && isNaN(v)))
  502 + for (const [idx, it] of list.entries()) {
  503 + if (
  504 + strEmpty(it.productName) ||
  505 + strEmpty(it.industry) ||
  506 + strEmpty(it.quality) ||
  507 + strEmpty(it.brand) ||
  508 + numEmpty(it.quantity) ||
  509 + strEmpty(it.deliveryDate)
  510 + ) {
  511 + uni.showToast({ title: `第${idx + 1}条明细未完整填写`, icon: 'none' }); return false
  512 + }
  513 + }
  514 + if (this.$refs.productRel && !this.$refs.productRel.validate()) return false
  515 + return true
  516 + },
  517 + async onSubmit() {
  518 + if (!this.fileInfo.id) {
  519 + uni.showToast({ title: '请上传合同附件', icon: 'error' })
  520 + return
  521 + }
  522 + if (this.uploadType !== 'seal' && !this.standardStandardized && this.standardStandardized !== false) {
  523 + uni.showToast({ title: '请选择合同是否规范', icon: 'error' })
  524 + return
  525 + }
  526 + if (!this.validateRequired()) return
  527 + const confirmRes = await new Promise(resolve => {
  528 + uni.showModal({
  529 + title: '确认提交',
  530 + content: this.uploadType === 'seal' ? '确定提交双方盖章合同吗?' : this.uploadType === 'formal' ? '确定提交正式合同吗?' : '确定提交标准合同吗?',
  531 + confirmText: '确定',
  532 + cancelText: '取消',
  533 + success: resolve
  534 + })
  535 + })
  536 + if (!(confirmRes && confirmRes.confirm)) return
  537 + const clean = (obj) => {
  538 + const out = {}
  539 + Object.keys(obj || {}).forEach(k => {
  540 + const v = obj[k]
  541 + const isEmptyString = typeof v === 'string' && v.trim() === ''
  542 + const isUndef = v === undefined || v === null
  543 + const isNaNNumber = typeof v === 'number' && isNaN(v)
  544 + if (!(isEmptyString || isUndef || isNaNNumber)) out[k] = v
  545 + })
  546 + return out
  547 + }
  548 + const lines = (this.newProductLineList || []).map(it => clean(it))
  549 + const payload = clean({
  550 + ...this.form,
  551 + id: this.form.id,
  552 + type: 'INTL_INVENTORY_AGMT',
  553 + totalQuantity: this.totalQuantity,
  554 + totalAmountIncludingTax: this.totalAmountIncludingTax,
  555 + contractDistributorLineList: lines,
  556 + })
  557 +
  558 + let api = uploadStandardContract
  559 + if (this.uploadType === 'seal') {
  560 + api = uploadSignedContractFile
  561 + payload.signedContractFileId = this.fileInfo.id
  562 + payload.signedContractFileName = this.fileInfo.name
  563 + } else if (this.uploadType === 'formal') {
  564 + api = uploadFormalContract
  565 + payload.formalFileId = this.fileInfo.id
  566 + payload.formalFileName = this.fileInfo.name
  567 + payload.formalStandardized = this.standardStandardized
  568 + } else {
  569 + api = uploadStandardContract
  570 + payload.standardFileId = this.fileInfo.id
  571 + payload.standardFileName = this.fileInfo.name
  572 + payload.standardStandardized = this.standardStandardized
  573 + }
  574 +
  575 + try {
  576 + await api(payload)
  577 + uni.showToast({ title: '提交成功', icon: 'none' })
  578 + setTimeout(() => { uni.redirectTo({ url: '/pages/contract_foreign_stock/index' }) }, 400)
  579 + } catch (e) {
  580 + uni.showToast({ title: e.msg || '提交失败', icon: 'none' })
  581 + }
  582 + }
  583 + }
  584 +}
  585 +</script>
  586 +
  587 +<style lang="scss" scoped>
  588 +.total {
  589 + .total-text {
  590 + font-weight: 600;
  591 + font-size: 32rpx;
  592 + color: rgba(0, 0, 0, 0.9);
  593 + padding-bottom: 28rpx;
  594 + border-bottom: 2rpx solid #E7E7E7;
  595 + }
  596 +
  597 + .total-item {
  598 + display: flex;
  599 + align-items: center;
  600 + }
  601 +
  602 + .total-item-text {
  603 + font-weight: 400;
  604 + font-size: 28rpx;
  605 + color: rgba(0, 0, 0, 0.6);
  606 + line-height: 32rpx;
  607 + width: 240rpx;
  608 + padding: 12rpx 0;
  609 + }
  610 +
  611 + .total-item-price {
  612 + font-weight: 600;
  613 + font-size: 32rpx;
  614 + color: rgba(0, 0, 0, 0.9);
  615 + line-height: 32rpx;
  616 + }
  617 +
  618 + .text-red {
  619 + color: #D54941;
  620 + }
  621 +}
  622 +
  623 +.page {
  624 + display: flex;
  625 + flex-direction: column;
  626 + height: 100%;
  627 +}
  628 +
  629 +.scroll {
  630 + flex: 1;
  631 + padding: 12rpx 0 392rpx !important;
  632 +}
  633 +
  634 +.footer {
  635 + z-index: 2;
  636 + position: fixed;
  637 + left: 0;
  638 + right: 0;
  639 + bottom: 0;
  640 + padding: 32rpx;
  641 + padding-bottom: calc(32rpx + env(safe-area-inset-bottom));
  642 + background: #fff;
  643 + box-shadow: 0 -8rpx 24rpx rgba(0, 0, 0, 0.06);
  644 +}
  645 +
  646 +.footer .btn {
  647 + height: 80rpx;
  648 + line-height: 80rpx;
  649 + border-radius: 12rpx;
  650 + font-size: 32rpx;
  651 +}
  652 +
  653 +.footer .submit {
  654 + background: $theme-primary;
  655 + color: #fff;
  656 +}
  657 +
  658 +.quality {
  659 + background-color: #fff;
  660 + display: flex;
  661 + align-items: center;
  662 + padding: 24rpx 32rpx;
  663 + border-bottom: 1rpx solid #f0f0f0;
  664 + margin-top: 20rpx;
  665 +
  666 + .title {
  667 + font-size: 32rpx;
  668 + color: rgba(0, 0, 0, 0.9);
  669 + font-weight: 600;
  670 + }
  671 +
  672 + .opCollapse {
  673 + color: rgba(0, 0, 0, 0.6);
  674 + width: 32rpx;
  675 + height: 28rpx;
  676 + margin-right: 16rpx;
  677 + }
  678 +}
  679 +
  680 +::v-deep .uni-list {
  681 + background: transparent;
  682 +}
  683 +
  684 +::v-deep .uni-list .uni-easyinput .uni-input-input {
  685 + color: rgba(0, 0, 0, 0.9);
  686 +}
  687 +
  688 +::v-deep .uni-list .uni-input-placeholder {
  689 + z-index: 1;
  690 +}
  691 +
  692 +::v-deep .uni-list .uni-input-input {
  693 + background-color: #ffffff;
  694 +}
  695 +
  696 +::v-deep .uni-list-item__extra-text {
  697 + font-size: 32rpx;
  698 +}
  699 +
  700 +::v-deep .uni-list-item__content-title {
  701 + font-size: 32rpx;
  702 + color: rgba(0, 0, 0, 0.9);
  703 +}
  704 +
  705 +::v-deep .uni-list-item__container {
  706 + padding: 32rpx;
  707 +}
  708 +
  709 +::v-deep .uni-list-item__container .uni-easyinput__placeholder-class {
  710 + font-size: 32rpx;
  711 + color: rgba(0, 0, 0, 0.4);
  712 +}
  713 +
  714 +::v-deep .uni-list-item__container .uni-easyinput__content {
  715 + border: none;
  716 + background-color: #ffffff !important;
  717 +}
  718 +
  719 +::v-deep .uni-list-item__container .uni-easyinput__content-input {
  720 + padding-left: 0 !important;
  721 + height: 48rpx;
  722 + line-height: 48rpx;
  723 + font-size: 32rpx;
  724 +}
  725 +
  726 +::v-deep .uni-list-item__container .item-title,
  727 +::v-deep .uni-list-item__container .uni-list-item__content {
  728 + flex: none;
  729 + min-height: 48rpx;
  730 + line-height: 48rpx;
  731 + font-size: 32rpx;
  732 + position: relative;
  733 + width: 210rpx;
  734 + margin-right: 32rpx;
  735 + color: rgba(0, 0, 0, 0.9);
  736 +}
  737 +
  738 +::v-deep .uni-list-item__container .item-title .required {
  739 + color: red;
  740 + position: absolute;
  741 + top: 50%;
  742 + transform: translateY(-50%);
  743 + left: -16rpx;
  744 +}
  745 +
  746 +::v-deep .uni-list-item.select-item.is-empty .uni-list-item__extra-text {
  747 + color: rgba(0, 0, 0, 0.4) !important;
  748 +}
  749 +
  750 +::v-deep .uni-list-item.select-item.is-filled .uni-list-item__extra-text {
  751 + color: rgba(0, 0, 0, 0.9) !important;
  752 +}
  753 +</style>
@@ -89,11 +89,9 @@ @@ -89,11 +89,9 @@
89 </template> 89 </template>
90 </uni-list-item> 90 </uni-list-item>
91 91
92 - <uni-list-item class="select-item" :class="(Array.isArray(form.destinationId) && form.destinationId.length) ? 'is-filled' : 'is-empty'" clickable  
93 - @click="openCitySelector" :rightText="form.destinationLabel || '请选择'" showArrow>  
94 - <template v-slot:body>  
95 - <view class="item-title"><text>目的地</text></view>  
96 - <CitySelector ref="citySelectorRef" v-model="form.destinationId" @change="onCityChange" /> 92 + <uni-list-item title="目的地">
  93 + <template v-slot:footer>
  94 + <uni-easyinput v-model="form.foreignDestination" placeholder="请输入目的地" :inputBorder="false" />
97 </template> 95 </template>
98 </uni-list-item> 96 </uni-list-item>
99 <uni-list-item class="select-item" :class="form.includesPackagingFeeName ? 'is-filled' : 'is-empty'" clickable 97 <uni-list-item class="select-item" :class="form.includesPackagingFeeName ? 'is-filled' : 'is-empty'" clickable
@@ -230,7 +228,6 @@ @@ -230,7 +228,6 @@
230 import SingleSelectSheet from '@/components/single-select/index.vue' 228 import SingleSelectSheet from '@/components/single-select/index.vue'
231 import RelateSelectSheet from '@/components/relate-select/index.vue' 229 import RelateSelectSheet from '@/components/relate-select/index.vue'
232 import ProductRel from './productRel.vue' 230 import ProductRel from './productRel.vue'
233 -import CitySelector from '@/components/city-selector/index.vue'  
234 import { getRetailCodeApi, createContractApi, getCustomerRemarks, getCustomerSpecificQualityRequirements, getDeptApi, getContractApi } from '@/api/contract' 231 import { getRetailCodeApi, createContractApi, getCustomerRemarks, getCustomerSpecificQualityRequirements, getDeptApi, getContractApi } from '@/api/contract'
235 import { getDicByCodes } from '@/utils/dic' 232 import { getDicByCodes } from '@/utils/dic'
236 import { formatCurrencyToChinese } from '@/utils/common' 233 import { formatCurrencyToChinese } from '@/utils/common'
@@ -239,7 +236,7 @@ import { getArea } from '@/api/credit_manage.js' @@ -239,7 +236,7 @@ import { getArea } from '@/api/credit_manage.js'
239 236
240 export default { 237 export default {
241 name: 'AddContractForeignUnplan', 238 name: 'AddContractForeignUnplan',
242 - components: { SingleSelectSheet, RelateSelectSheet, ProductRel, CitySelector }, 239 + components: { SingleSelectSheet, RelateSelectSheet, ProductRel },
243 data() { 240 data() {
244 return { 241 return {
245 copyId: '', 242 copyId: '',
@@ -266,8 +263,7 @@ export default { @@ -266,8 +263,7 @@ export default {
266 includesTransportFeeName: '否', 263 includesTransportFeeName: '否',
267 unit: '美元、公斤、美元/公斤', 264 unit: '美元、公斤、美元/公斤',
268 totalAmountCapital: '', 265 totalAmountCapital: '',
269 - destinationId: [],  
270 - destinationLabel: '', 266 + foreignDestination: '',
271 workshopIdName: '', 267 workshopIdName: '',
272 workshopId: '', 268 workshopId: '',
273 deptName: '', 269 deptName: '',
@@ -315,11 +311,6 @@ export default { @@ -315,11 +311,6 @@ export default {
315 this.loadRegionOptions() 311 this.loadRegionOptions()
316 if (!this.copyId) this.form.orderDate = this.formatDate(new Date()) 312 if (!this.copyId) this.form.orderDate = this.formatDate(new Date())
317 if (this.copyId) this.loadCopyDetail(this.copyId) 313 if (this.copyId) this.loadCopyDetail(this.copyId)
318 - this.$nextTick(() => {  
319 - if (Array.isArray(this.form.destinationId) && this.form.destinationId.length) {  
320 - this.initDestinationLabel()  
321 - }  
322 - })  
323 }, 314 },
324 watch: { 315 watch: {
325 'form.buyer': { 316 'form.buyer': {
@@ -403,8 +394,7 @@ export default { @@ -403,8 +394,7 @@ export default {
403 packagingRequirements: m.packagingRequirements || '', 394 packagingRequirements: m.packagingRequirements || '',
404 paymentTerms: m.paymentTerms || '', 395 paymentTerms: m.paymentTerms || '',
405 transportMode: m.transportMode || '', 396 transportMode: m.transportMode || '',
406 - destinationId: (m.provinceId && m.cityId && m.districtId) ? [m.provinceId, m.cityId, m.districtId] : (Array.isArray(m.destinationId) ? m.destinationId : []),  
407 - destinationLabel: (m.provinceName && m.cityName && m.districtName) ? `${m.provinceName} / ${m.cityName} / ${m.districtName}` : (m.destinationLabel || ''), 397 + foreignDestination: (m.foreignDestination || ''),
408 specialInstructions: m.specialInstructions || '', 398 specialInstructions: m.specialInstructions || '',
409 remarks: m.remarks || '', 399 remarks: m.remarks || '',
410 pieceWeightHead: m.pieceWeightHead || '', 400 pieceWeightHead: m.pieceWeightHead || '',
@@ -552,20 +542,6 @@ export default { @@ -552,20 +542,6 @@ export default {
552 const val = m[field] 542 const val = m[field]
553 return val ? String(val) : map[field] 543 return val ? String(val) : map[field]
554 }, 544 },
555 - openCitySelector() {  
556 - this.$refs.citySelectorRef && this.$refs.citySelectorRef.open()  
557 - },  
558 - async initDestinationLabel() {  
559 - const comp = this.$refs.citySelectorRef  
560 - if (comp && typeof comp.getLabel === 'function') {  
561 - const label = await comp.getLabel()  
562 - this.form.destinationLabel = label || ''  
563 - }  
564 - },  
565 - onCityChange(payload) {  
566 - const label = payload && payload.label != null ? payload.label : ''  
567 - this.form.destinationLabel = label  
568 - },  
569 async openSheet(field) { 545 async openSheet(field) {
570 const setSheet = (title, options) => { 546 const setSheet = (title, options) => {
571 const current = this.form[field] 547 const current = this.form[field]
@@ -666,13 +642,9 @@ export default { @@ -666,13 +642,9 @@ export default {
666 return out 642 return out
667 } 643 }
668 const lines = (this.productLineList || []).map(it => clean(it)) 644 const lines = (this.productLineList || []).map(it => clean(it))
669 - const { destinationLabel, destinationId, ...formForSubmit } = this.form;  
670 - // 区id  
671 - const destination = destinationId && destinationId.length > 0 ? destinationId[destinationId.length - 1] : '';  
672 const payload = clean({ 645 const payload = clean({
673 - ...formForSubmit, 646 + ...this.form,
674 operateType: isCopy ? 'COPY' : 'ADD', 647 operateType: isCopy ? 'COPY' : 'ADD',
675 - destination,  
676 type: 'INTL_OPEN_SPEC_AGMT', 648 type: 'INTL_OPEN_SPEC_AGMT',
677 totalQuantity: this.totalQuantity, 649 totalQuantity: this.totalQuantity,
678 // totalAmountExcludingTax: this.totalAmountExcludingTax, 650 // totalAmountExcludingTax: this.totalAmountExcludingTax,
@@ -50,7 +50,7 @@ @@ -50,7 +50,7 @@
50 '-' }}</text></view> 50 '-' }}</text></view>
51 <view class="row"><text class="label">运输方式</text><text class="value">{{ detail.transportMode || '-' 51 <view class="row"><text class="label">运输方式</text><text class="value">{{ detail.transportMode || '-'
52 }}</text></view> 52 }}</text></view>
53 - <view class="row"><text class="label">目的地</text><text class="value">{{ detail.destinationLabel || 53 + <view class="row"><text class="label">目的地</text><text class="value">{{ detail.foreignDestination ||
54 '-' 54 '-'
55 }}</text></view> 55 }}</text></view>
56 <view class="row"><text class="label">单价中是否已包含包装费</text><text class="value">{{ 56 <view class="row"><text class="label">单价中是否已包含包装费</text><text class="value">{{
@@ -187,8 +187,7 @@ export default { @@ -187,8 +187,7 @@ export default {
187 packagingRequirements: '', 187 packagingRequirements: '',
188 paymentTerms: '', 188 paymentTerms: '',
189 transportMode: '', 189 transportMode: '',
190 - destinationId: '',  
191 - destinationLabel: '', 190 + foreignDestination: '',
192 specialInstructions: '', 191 specialInstructions: '',
193 remarks: '', 192 remarks: '',
194 pieceWeightHead: '', 193 pieceWeightHead: '',
@@ -392,6 +391,13 @@ export default { @@ -392,6 +391,13 @@ export default {
392 uploadContract(id, type = 'formal') { 391 uploadContract(id, type = 'formal') {
393 if (!id) return 392 if (!id) return
394 this.uploadId = id 393 this.uploadId = id
  394 + if (type === 'standard' && this.detail?.canEdit) {
  395 + const query = `?id=${encodeURIComponent(id)}&uploadType=${encodeURIComponent(type)}`
  396 + uni.navigateTo({
  397 + url: '/pages/contract_foreign_unplan/uploadStandard' + query
  398 + })
  399 + return
  400 + }
395 this.uploadType = type 401 this.uploadType = type
396 this.$refs.uploadPopup.open() 402 this.$refs.uploadPopup.open()
397 }, 403 },
@@ -529,8 +535,7 @@ export default { @@ -529,8 +535,7 @@ export default {
529 regionName: data.regionName || '', 535 regionName: data.regionName || '',
530 deptName: data.deptName || '', 536 deptName: data.deptName || '',
531 includesPackagingFeeName, includesTransportFeeName, 537 includesPackagingFeeName, includesTransportFeeName,
532 - destinationId: data.provinceId && data.cityId && data.districtId ? [data.provinceId, data.cityId, data.districtId] : '',  
533 - destinationLabel: data.provinceName && data.cityName && data.districtName ? `${data.provinceName} / ${data.cityName} / ${data.districtName}` : '', 538 + foreignDestination: (data.foreignDestination || ''),
534 } 539 }
535 this.detail = await fillStandardApprovedName(this.detail) 540 this.detail = await fillStandardApprovedName(this.detail)
536 this.detail = await fillFormalApprovedName(this.detail) 541 this.detail = await fillFormalApprovedName(this.detail)
@@ -93,11 +93,9 @@ @@ -93,11 +93,9 @@
93 <uni-easyinput v-model="form.transportMode" placeholder="请输入运输方式" :inputBorder="false" /> 93 <uni-easyinput v-model="form.transportMode" placeholder="请输入运输方式" :inputBorder="false" />
94 </template> 94 </template>
95 </uni-list-item> 95 </uni-list-item>
96 - <uni-list-item class="select-item" :class="(Array.isArray(form.destinationId) && form.destinationId.length) ? 'is-filled' : 'is-empty'" clickable  
97 - @click="openCitySelector" :rightText="form.destinationLabel || '请选择'" showArrow>  
98 - <template v-slot:body>  
99 - <view class="item-title"><text>目的地</text></view>  
100 - <CitySelector ref="citySelectorRef" v-model="form.destinationId" @change="onCityChange" /> 96 + <uni-list-item title="目的地">
  97 + <template v-slot:footer>
  98 + <uni-easyinput v-model="form.foreignDestination" placeholder="请输入目的地" :inputBorder="false" />
101 </template> 99 </template>
102 </uni-list-item> 100 </uni-list-item>
103 101
@@ -217,7 +215,6 @@ @@ -217,7 +215,6 @@
217 import SingleSelectSheet from '@/components/single-select/index.vue' 215 import SingleSelectSheet from '@/components/single-select/index.vue'
218 import RelateSelectSheet from '@/components/relate-select/index.vue' 216 import RelateSelectSheet from '@/components/relate-select/index.vue'
219 import ProductRel from './productRel.vue' 217 import ProductRel from './productRel.vue'
220 -import CitySelector from '@/components/city-selector/index.vue'  
221 import { getContractApi, updateContractApi } from '@/api/contract' 218 import { getContractApi, updateContractApi } from '@/api/contract'
222 import { getDicByCodes } from '@/utils/dic' 219 import { getDicByCodes } from '@/utils/dic'
223 import { formatCurrencyToChinese } from '@/utils/common' 220 import { formatCurrencyToChinese } from '@/utils/common'
@@ -226,7 +223,7 @@ import { getArea } from '@/api/credit_manage.js' @@ -226,7 +223,7 @@ import { getArea } from '@/api/credit_manage.js'
226 223
227 export default { 224 export default {
228 name: 'ModifyContractForeignUnplan', 225 name: 'ModifyContractForeignUnplan',
229 - components: { SingleSelectSheet, RelateSelectSheet, ProductRel, CitySelector }, 226 + components: { SingleSelectSheet, RelateSelectSheet, ProductRel },
230 data() { 227 data() {
231 return { 228 return {
232 id: '', 229 id: '',
@@ -263,8 +260,7 @@ export default { @@ -263,8 +260,7 @@ export default {
263 packagingRequirements: '', 260 packagingRequirements: '',
264 paymentTerms: '', 261 paymentTerms: '',
265 transportMode: '', 262 transportMode: '',
266 - destinationId: [],  
267 - destinationLabel: '', 263 + foreignDestination: '',
268 specialInstructions: '', 264 specialInstructions: '',
269 remarks: '', 265 remarks: '',
270 pieceWeightHead: '', 266 pieceWeightHead: '',
@@ -297,11 +293,6 @@ export default { @@ -297,11 +293,6 @@ export default {
297 this.loadExtraOptions() 293 this.loadExtraOptions()
298 this.loadRegionOptions() 294 this.loadRegionOptions()
299 this.loadDetail() 295 this.loadDetail()
300 - this.$nextTick(() => {  
301 - if (Array.isArray(this.form.destinationId) && this.form.destinationId.length) {  
302 - this.initDestinationLabel()  
303 - }  
304 - })  
305 }, 296 },
306 methods: { 297 methods: {
307 async loadRegionOptions() { 298 async loadRegionOptions() {
@@ -348,8 +339,7 @@ export default { @@ -348,8 +339,7 @@ export default {
348 packagingRequirements: m.packagingRequirements || '', 339 packagingRequirements: m.packagingRequirements || '',
349 paymentTerms: m.paymentTerms || '', 340 paymentTerms: m.paymentTerms || '',
350 transportMode: m.transportMode || '', 341 transportMode: m.transportMode || '',
351 - destinationId: (m.provinceId && m.cityId && m.districtId) ? [m.provinceId, m.cityId, m.districtId] : (Array.isArray(m.destinationId) ? m.destinationId : []),  
352 - destinationLabel: (m.provinceName && m.cityName && m.districtName) ? `${m.provinceName} / ${m.cityName} / ${m.districtName}` : (m.destinationLabel || ''), 342 + foreignDestination: (m.foreignDestination || ''),
353 specialInstructions: m.specialInstructions || '', 343 specialInstructions: m.specialInstructions || '',
354 remarks: m.remarks || '', 344 remarks: m.remarks || '',
355 pieceWeightHead: m.pieceWeightHead || '', 345 pieceWeightHead: m.pieceWeightHead || '',
@@ -370,20 +360,6 @@ export default { @@ -370,20 +360,6 @@ export default {
370 this.onProductsChange(lines) 360 this.onProductsChange(lines)
371 } catch (e) { } 361 } catch (e) { }
372 }, 362 },
373 - async initDestinationLabel() {  
374 - const comp = this.$refs.citySelectorRef  
375 - if (comp && typeof comp.getLabel === 'function') {  
376 - const label = await comp.getLabel()  
377 - this.form.destinationLabel = label || ''  
378 - }  
379 - },  
380 - openCitySelector() {  
381 - this.$refs.citySelectorRef && this.$refs.citySelectorRef.open()  
382 - },  
383 - onCityChange(payload) {  
384 - const label = payload && payload.label != null ? payload.label : ''  
385 - this.form.destinationLabel = label  
386 - },  
387 onProductsChange(products) { 363 onProductsChange(products) {
388 const list = Array.isArray(products) ? products : [] 364 const list = Array.isArray(products) ? products : []
389 this.newProductLineList = list 365 this.newProductLineList = list
@@ -548,12 +524,9 @@ export default { @@ -548,12 +524,9 @@ export default {
548 return out 524 return out
549 } 525 }
550 const lines = (this.newProductLineList || []).map(it => clean(it)) 526 const lines = (this.newProductLineList || []).map(it => clean(it))
551 - const { destinationLabel, destinationId, ...formForSubmit } = this.form;  
552 - const destination = destinationId && destinationId.length > 0 ? destinationId[destinationId.length - 1] : '';  
553 const payload = clean({ 527 const payload = clean({
554 - ...formForSubmit, 528 + ...this.form,
555 id: this.form.id, 529 id: this.form.id,
556 - destination,  
557 type: 'INTL_OPEN_SPEC_AGMT', 530 type: 'INTL_OPEN_SPEC_AGMT',
558 totalQuantity: this.totalQuantity, 531 totalQuantity: this.totalQuantity,
559 // totalAmountExcludingTax: this.totalAmountExcludingTax, 532 // totalAmountExcludingTax: this.totalAmountExcludingTax,
@@ -811,4 +784,4 @@ export default { @@ -811,4 +784,4 @@ export default {
811 } 784 }
812 } 785 }
813 786
814 -</style>  
  787 +</style>
  1 +<template>
  2 + <view class="page">
  3 + <scroll-view class="scroll" scroll-y>
  4 + <uni-list>
  5 + <uni-list-item title="编号">
  6 + <template v-slot:footer>
  7 + <uni-easyinput v-model="form.code" :inputBorder="false" disabled />
  8 + </template>
  9 + </uni-list-item>
  10 +
  11 + <uni-list-item class="select-item" :class="form.supplier ? 'is-filled' : 'is-empty'" clickable
  12 + @click="openSheet('supplier')" :rightText="displayLabel('supplierName')" showArrow>
  13 + <template v-slot:body>
  14 + <view class="item-title"><text class="required">*</text><text>供方</text></view>
  15 + </template>
  16 + </uni-list-item>
  17 +
  18 + <uni-list-item class="select-item" :class="form.buyer ? 'is-filled' : 'is-empty'" clickable
  19 + @click="openRelate('buyer')" :rightText="form.buyerName || '请选择需方'" showArrow>
  20 + <template v-slot:body>
  21 + <view class="item-title"><text class="required">*</text><text>需方</text></view>
  22 + </template>
  23 + </uni-list-item>
  24 +
  25 + <uni-list-item class="select-item" :class="form.stockUpCompanyId ? 'is-filled' : 'is-empty'" clickable
  26 + @click="openRelate('stockUpCompanyId')" :rightText="form.stockUpCompanyName || '请选择备货单位'" showArrow>
  27 + <template v-slot:body>
  28 + <view class="item-title"><text class="required">*</text><text>备货单位/人(生产标准)</text></view>
  29 + </template>
  30 + </uni-list-item>
  31 +
  32 + <uni-list-item class="select-item" :class="form.workshopId ? 'is-filled' : 'is-empty'" clickable
  33 + @click="openSheet('workshopId')" :rightText="form.workshopName || '请选择生产厂'" showArrow>
  34 + <template v-slot:body>
  35 + <view class="item-title"><text class="required">*</text><text>生产厂</text></view>
  36 + </template>
  37 + </uni-list-item>
  38 + <uni-list-item class="select-item" :class="form.deptName ? 'is-filled' : 'is-empty'">
  39 + <template v-slot:body>
  40 + <view class="item-title"><text class="required">*</text><text>办事处</text></view>
  41 + </template>
  42 + <template v-slot:footer>
  43 + <view class="serial-number-row">
  44 + <uni-easyinput v-model="form.deptName" :inputBorder="false" disabled />
  45 + </view>
  46 + </template>
  47 + </uni-list-item>
  48 + <uni-list-item class="select-item" :class="form.region ? 'is-filled' : 'is-empty'" clickable
  49 + @click="openSheet('region')" :rightText="displayLabel('regionName')" showArrow>
  50 + <template v-slot:body>
  51 + <view class="item-title"><text class="required">*</text><text>区域</text></view>
  52 + </template>
  53 + </uni-list-item>
  54 +
  55 + <uni-list-item title="订货日期">
  56 + <template v-slot:footer>
  57 + <uni-datetime-picker type="date" v-model="form.orderDate" />
  58 + </template>
  59 + </uni-list-item>
  60 +
  61 + <uni-list-item title="单位">
  62 + <template v-slot:footer>
  63 + <uni-easyinput v-model="form.unit" :inputBorder="false" disabled />
  64 + </template>
  65 + </uni-list-item>
  66 +
  67 + <ProductRel ref="productRel" mode="add" :deliveryDate="form.orderDate" :deliveryDateBase="form.deliveryDate"
  68 + :list="productLineList" @change="onProductsChange" :options="productList" />
  69 +
  70 + <uni-list-item title="合计金额(大写)">
  71 + <template v-slot:footer>
  72 + <uni-easyinput v-model="form.totalAmountCapital" placeholder="" :inputBorder="false" disabled />
  73 + </template>
  74 + </uni-list-item>
  75 + <uni-list-item title="交付定金、数额、时间">
  76 + <template v-slot:footer>
  77 + <uni-easyinput v-model="form.depositInfo" placeholder="请输入交付定金、数额、时间" :inputBorder="false" />
  78 + </template>
  79 + </uni-list-item>
  80 + <uni-list-item title="包装要求">
  81 + <template v-slot:footer>
  82 + <uni-easyinput v-model="form.packagingRequirements" placeholder="请输入包装要求" :inputBorder="false" />
  83 + </template>
  84 + </uni-list-item>
  85 + <uni-list-item title="付款方式、付款期限">
  86 + <template v-slot:footer>
  87 + <uni-easyinput v-model="form.paymentTerms" placeholder="请输入付款方式、付款期限" :inputBorder="false" />
  88 + </template>
  89 + </uni-list-item>
  90 + <uni-list-item title="运输方式">
  91 + <template v-slot:footer>
  92 + <uni-easyinput v-model="form.transportMode" placeholder="请输入运输方式" :inputBorder="false" />
  93 + </template>
  94 + </uni-list-item>
  95 + <uni-list-item title="目的地">
  96 + <template v-slot:footer>
  97 + <uni-easyinput v-model="form.foreignDestination" placeholder="请输入目的地" :inputBorder="false" />
  98 + </template>
  99 + </uni-list-item>
  100 +
  101 + <uni-list-item class="select-item" :class="form.includesPackagingFeeName ? 'is-filled' : 'is-empty'" clickable
  102 + @click="openSheet('includesPackagingFee')" :rightText="form.includesPackagingFeeName || '请选择'" showArrow>
  103 + <template v-slot:body>
  104 + <view class="item-title"><text>单价中是否已包含包装费</text></view>
  105 + </template>
  106 + </uni-list-item>
  107 + <uni-list-item class="select-item" :class="form.includesTransportFeeName ? 'is-filled' : 'is-empty'" clickable
  108 + @click="openSheet('includesTransportFee')" :rightText="form.includesTransportFeeName || '请选择'" showArrow>
  109 + <template v-slot:body>
  110 + <view class="item-title"><text>单价中是否已包含运费</text></view>
  111 + </template>
  112 + </uni-list-item>
  113 + <uni-list-item title="需方指定收货人">
  114 + <template v-slot:footer>
  115 + <uni-easyinput v-model="form.designatedConsignee" placeholder="请输入需方指定收货人" :inputBorder="false" />
  116 + </template>
  117 + </uni-list-item>
  118 + <uni-list-item class="select-item" :class="form.specialTermsName ? 'is-filled' : 'is-empty'" clickable
  119 + @click="openSheet('specialTerms')" :rightText="form.specialTermsName || '请选择'" showArrow>
  120 + <template v-slot:body>
  121 + <view class="item-title"><text class="required">*</text><text>特别条款要求</text></view>
  122 + </template>
  123 + </uni-list-item>
  124 + <uni-list-item class="select-item" :class="form.executionStandardName ? 'is-filled' : 'is-empty'" clickable
  125 + @click="openSheet('executionStandard')" :rightText="form.executionStandardName || '请选择'" showArrow>
  126 + <template v-slot:body>
  127 + <view class="item-title"><text>执行标准</text></view>
  128 + </template>
  129 + </uni-list-item>
  130 + <uni-list-item v-if="form.executionStandard === 'OTHER'" title="其他">
  131 + <template v-slot:footer>
  132 + <uni-easyinput v-model="form.executionStandardRemarks" placeholder="请输入其他标准备注" :inputBorder="false" />
  133 + </template>
  134 + </uni-list-item>
  135 + <uni-list-item title="特别说明" style="margin-top: 20rpx;">
  136 + <template v-slot:footer>
  137 + <uni-easyinput v-model="form.specialInstructions" placeholder="请输入特别说明" :inputBorder="false" />
  138 + </template>
  139 + </uni-list-item>
  140 + <uni-list-item title="备注">
  141 + <template v-slot:footer>
  142 + <uni-easyinput v-model="form.remarks" placeholder="请输入备注" :inputBorder="false" maxlength="2000" />
  143 + </template>
  144 + </uni-list-item>
  145 +
  146 + <view class="quality">
  147 + <image class="opCollapse" src="/static/images/title.png" />
  148 + <text class="title">具体质量要求</text>
  149 + </view>
  150 + <uni-list-item title="件重条头">
  151 + <template v-slot:footer>
  152 + <uni-easyinput v-model="form.pieceWeightHead" placeholder="请输入" :inputBorder="false" />
  153 + </template>
  154 + </uni-list-item>
  155 + <uni-list-item title="表面">
  156 + <template v-slot:footer>
  157 + <uni-easyinput v-model="form.surface" placeholder="请输入" :inputBorder="false" />
  158 + </template>
  159 + </uni-list-item>
  160 + <uni-list-item title="公差">
  161 + <template v-slot:footer>
  162 + <uni-easyinput v-model="form.tolerance" placeholder="请输入" :inputBorder="false" />
  163 + </template>
  164 + </uni-list-item>
  165 + <uni-list-item title="性能">
  166 + <template v-slot:footer>
  167 + <uni-easyinput v-model="form.performance" placeholder="请输入" :inputBorder="false" />
  168 + </template>
  169 + </uni-list-item>
  170 + <uni-list-item title="成分">
  171 + <template v-slot:footer>
  172 + <uni-easyinput v-model="form.component" placeholder="请输入" :inputBorder="false" />
  173 + </template>
  174 + </uni-list-item>
  175 + <uni-list-item title="包装">
  176 + <template v-slot:footer>
  177 + <uni-easyinput v-model="form.packaging" placeholder="请输入" :inputBorder="false" />
  178 + </template>
  179 + </uni-list-item>
  180 +
  181 + <uni-list-item title="标准合同附件" style="margin-top: 20rpx;">
  182 + <template v-slot:footer>
  183 + <FileUpload v-model="fileInfo" />
  184 + </template>
  185 + </uni-list-item>
  186 + <uni-list-item class="select-item" :class="standardStandardizedName ? 'is-filled' : 'is-empty'" clickable
  187 + @click="openSheet('standardStandardized')" :rightText="standardStandardizedName || '请选择'" showArrow>
  188 + <template v-slot:body>
  189 + <view class="item-title"><text class="required">*</text><text>合同是否规范</text></view>
  190 + </template>
  191 + </uni-list-item>
  192 +
  193 + <view class="footer">
  194 + <div class="total">
  195 + <div class="total-text">合计</div>
  196 + <div class="total-item" style="padding: 20rpx 0;">
  197 + <div class="total-item-text">数量</div>
  198 + <div class="total-item-price">{{ (totalQuantity || 0).toFixed(2) }}kg</div>
  199 + </div>
  200 + </div>
  201 + <button class="btn submit" type="primary" @click="onSubmit">提交</button>
  202 + </view>
  203 + </uni-list>
  204 + </scroll-view>
  205 +
  206 + <SingleSelectSheet :visible.sync="sheet.visible" :title="sheet.title" :options="sheet.options" v-model="sheet.value"
  207 + @confirm="onSheetConfirm" />
  208 + <RelateSelectSheet :visible.sync="relate.visible" :title="relate.title" :source="relate.source"
  209 + :display-fields="relate.display" :multiple="relate.multiple" :row-key="relate.rowKey"
  210 + :selectedKeys.sync="relate.selectedKeys" @confirm="onRelateConfirm" />
  211 + </view>
  212 +</template>
  213 +
  214 +<script>
  215 +import SingleSelectSheet from '@/components/single-select/index.vue'
  216 +import RelateSelectSheet from '@/components/relate-select/index.vue'
  217 +import ProductRel from './productRel.vue'
  218 +import FileUpload from '@/components/file-upload/index.vue'
  219 +import { getContractApi, uploadStandardContract } from '@/api/contract'
  220 +import { getDicByCodes } from '@/utils/dic'
  221 +import { formatCurrencyToChinese } from '@/utils/common'
  222 +import { workshopQueryApi } from '@/api/devManage'
  223 +import { getArea } from '@/api/credit_manage.js'
  224 +
  225 +export default {
  226 + name: 'UploadContractForeignUnplan',
  227 + components: { SingleSelectSheet, RelateSelectSheet, ProductRel, FileUpload },
  228 + data() {
  229 + return {
  230 + id: '',
  231 + uploadType: 'standard',
  232 + fileInfo: { id: '', name: '' },
  233 + standardStandardized: '',
  234 + standardStandardizedName: '',
  235 + form: {
  236 + id: '',
  237 + code: '',
  238 + supplier: '',
  239 + supplierName: '',
  240 + buyer: '',
  241 + buyerName: '',
  242 + stockUpCompanyId: '',
  243 + stockUpCompanyName: '',
  244 + workshopId: '',
  245 + workshopName: '',
  246 + region: '',
  247 + regionName: '',
  248 + deptName: '',
  249 + deptId: '',
  250 + orderDate: '',
  251 + deliveryDate: '',
  252 + designatedConsignee: '',
  253 + specialTerms: '',
  254 + specialTermsName: '',
  255 + executionStandard: '',
  256 + executionStandardName: '',
  257 + executionStandardRemarks: '',
  258 + includesPackagingFee: false,
  259 + includesPackagingFeeName: '否',
  260 + includesTransportFee: false,
  261 + includesTransportFeeName: '否',
  262 + unit: '美元、公斤、美元/公斤',
  263 + totalAmountCapital: '',
  264 + depositInfo: '',
  265 + packagingRequirements: '',
  266 + paymentTerms: '',
  267 + transportMode: '',
  268 + foreignDestination: '',
  269 + specialInstructions: '',
  270 + remarks: '',
  271 + pieceWeightHead: '',
  272 + surface: '',
  273 + tolerance: '',
  274 + performance: '',
  275 + component: '',
  276 + packaging: ''
  277 + },
  278 + supplierList: [],
  279 + specialTermsList: [],
  280 + executionStandardList: [],
  281 + yesNoList: [{ label: '是', value: true }, { label: '否', value: false }],
  282 + sheet: { visible: false, title: '请选择', field: '', options: [], value: '' },
  283 + relate: { visible: false, title: '选择', source: '', display: [], multiple: false, rowKey: 'id', selectedKeys: [], fieldKey: '' },
  284 + totalQuantity: 0,
  285 + totalAmountIncludingTax: 0,
  286 + productLineList: [],
  287 + newProductLineList: [],
  288 + productList: [],
  289 + regionOptions: []
  290 + }
  291 + },
  292 + onLoad(query) {
  293 + this.id = (query && query.id) ? query.id : ''
  294 + this.uploadType = (query && query.uploadType) ? query.uploadType : 'standard'
  295 + },
  296 + created() {
  297 + this.loadSuppliers()
  298 + this.loadExtraOptions()
  299 + this.loadRegionOptions()
  300 + this.loadDetail()
  301 + },
  302 + methods: {
  303 + async loadRegionOptions() {
  304 + try {
  305 + const res = await getArea()
  306 + const list = res.data || []
  307 + this.regionOptions = (list || []).map(it => ({ label: it.name || '', value: it.id || '' }))
  308 + } catch (e) {
  309 + this.regionOptions = []
  310 + }
  311 + },
  312 + async loadDetail() {
  313 + if (!this.id) return
  314 + try {
  315 + const res = await getContractApi(this.id)
  316 + const data = res && res.data ? res.data : {}
  317 + const includesPackagingFeeName = data.includesPackagingFeeName || (data.includesPackagingFee ? '是' : '否')
  318 + const includesTransportFeeName = data.includesTransportFeeName || (data.includesTransportFee ? '是' : '否')
  319 + const m = { ...data, includesPackagingFeeName, includesTransportFeeName }
  320 + this.form = {
  321 + ...this.form,
  322 + id: m.id || '',
  323 + code: m.code || '',
  324 + supplier: m.supplier || '',
  325 + supplierName: m.supplierName || '',
  326 + buyer: m.buyer || (m.customer && m.customer.id) || '',
  327 + buyerName: m.buyerName || (m.customer && m.customer.name) || '',
  328 + stockUpCompanyId: m.stockUpCompanyId || '',
  329 + stockUpCompanyName: m.stockUpCompanyName || '',
  330 + orderDate: m.orderDate || '',
  331 + designatedConsignee: m.designatedConsignee || '',
  332 + specialTerms: m.specialTerms || '',
  333 + specialTermsName: m.specialTermsName || '',
  334 + executionStandard: m.executionStandard || '',
  335 + executionStandardName: m.executionStandardName || '',
  336 + executionStandardRemarks: m.executionStandardRemarks || '',
  337 + includesPackagingFee: !!m.includesPackagingFee,
  338 + includesPackagingFeeName,
  339 + includesTransportFee: !!m.includesTransportFee,
  340 + includesTransportFeeName,
  341 + unit: m.unit || this.form.unit,
  342 + totalAmountCapital: m.totalAmountCapital || '',
  343 + depositInfo: m.depositInfo || '',
  344 + packagingRequirements: m.packagingRequirements || '',
  345 + paymentTerms: m.paymentTerms || '',
  346 + transportMode: m.transportMode || '',
  347 + foreignDestination: (m.foreignDestination || ''),
  348 + specialInstructions: m.specialInstructions || '',
  349 + remarks: m.remarks || '',
  350 + pieceWeightHead: m.pieceWeightHead || '',
  351 + surface: m.surface || '',
  352 + tolerance: m.tolerance || '',
  353 + performance: m.performance || '',
  354 + component: m.component || '',
  355 + packaging: m.packaging || '',
  356 + workshopId: m.workshopId || '',
  357 + workshopName: m.workshopName || '',
  358 + region: m.region || '',
  359 + regionName: m.regionName || '',
  360 + deptName: m.deptName || '',
  361 + deptId: m.deptId || ''
  362 + }
  363 + this.fileInfo = { id: m.standardFileId || '', name: m.standardFileName || '' }
  364 + this.standardStandardized = (m.standardStandardized === true || m.standardStandardized === false) ? m.standardStandardized : ''
  365 + this.standardStandardizedName = (this.standardStandardized === true) ? '是' : (this.standardStandardized === false) ? '否' : ''
  366 + const lines = Array.isArray(m.contractDistributorLineList) ? m.contractDistributorLineList : []
  367 + this.productLineList = lines
  368 + this.onProductsChange(lines)
  369 + } catch (e) { }
  370 + },
  371 + onProductsChange(products) {
  372 + const list = Array.isArray(products) ? products : []
  373 + this.newProductLineList = list
  374 + const sumQ = list.reduce((acc, it) => acc + (parseFloat(it.quantity) || 0), 0)
  375 + const sumT = list.reduce((acc, it) => acc + (parseFloat(it.totalAmount) || 0), 0)
  376 + this.totalQuantity = sumQ
  377 + this.totalAmountIncludingTax = sumT
  378 + this.form.totalAmountCapital = formatCurrencyToChinese(sumT)
  379 + },
  380 + async loadSuppliers() {
  381 + try {
  382 + const results = await getDicByCodes(['SUPPLIER'])
  383 + const items = results && results.SUPPLIER && results.SUPPLIER.data ? results.SUPPLIER.data : []
  384 + this.supplierList = items.map(it => ({ label: it.name, value: it.code }))
  385 + } catch (e) { this.supplierList = [] }
  386 + },
  387 + async loadExtraOptions() {
  388 + try {
  389 + const results = await getDicByCodes(['CONDITIONS_REQUIRED', 'APPLICABLE_STANDARD', 'CONTRACT_PRODUCT'])
  390 + const c1 = results && results.CONDITIONS_REQUIRED && results.CONDITIONS_REQUIRED.data ? results.CONDITIONS_REQUIRED.data : []
  391 + const c2 = results && results.APPLICABLE_STANDARD && results.APPLICABLE_STANDARD.data ? results.APPLICABLE_STANDARD.data : []
  392 + const c3 = results && results.CONTRACT_PRODUCT && results.CONTRACT_PRODUCT.data ? results.CONTRACT_PRODUCT.data : []
  393 + this.specialTermsList = c1.map(it => ({ label: it.name, value: it.code }))
  394 + this.executionStandardList = c2.map(it => ({ label: it.name, value: it.code }))
  395 + this.productList = c3.map(it => ({ label: it.name, value: it.code }))
  396 + } catch (e) {
  397 + this.specialTermsList = []
  398 + this.executionStandardList = []
  399 + this.productList = []
  400 + }
  401 + },
  402 + displayLabel(field) {
  403 + const m = this.form
  404 + const map = { supplierName: '请选择供方', buyerName: '请选择需方', workshopName: '请选择生产厂', regionName: '请选择区域' }
  405 + const val = m[field]
  406 + return val ? String(val) : map[field]
  407 + },
  408 + async openSheet(field) {
  409 + if (field === 'standardStandardized') {
  410 + const options = this.yesNoList
  411 + const current = this.standardStandardized
  412 + const match = (options || []).find(o => String(o.value) === String(current) || String(o.label) === String(current))
  413 + this.sheet = { ...this.sheet, visible: true, title: '合同是否规范', options, field, value: match ? match.value : '' }
  414 + return
  415 + }
  416 + const setSheet = (title, options) => {
  417 + const current = this.form[field]
  418 + const match = (options || []).find(o => String(o.label) === String(current) || String(o.value) === String(current))
  419 + this.sheet = { ...this.sheet, visible: true, title, options, field, value: match ? match.value : '' }
  420 + }
  421 + if (field === 'workshopId') {
  422 + const res = await workshopQueryApi({ pageIndex: 1, pageSize: 9999 })
  423 + const _data = res.data || {}
  424 + const list = _data.datas || (Array.isArray(_data) ? _data : [])
  425 + const opts = (list || []).map(it => ({ label: it.name, value: it.id }))
  426 + setSheet('生产厂', opts)
  427 + } else if (field === 'supplier') {
  428 + setSheet('供方', this.supplierList)
  429 + } else if (field === 'specialTerms') {
  430 + setSheet('特别条款要求', this.specialTermsList)
  431 + } else if (field === 'executionStandard') {
  432 + setSheet('执行标准', this.executionStandardList)
  433 + } else if (field === 'includesPackagingFee') {
  434 + setSheet('单价中是否已包含包装费', this.yesNoList)
  435 + } else if (field === 'includesTransportFee') {
  436 + setSheet('单价中是否已包含运费', this.yesNoList)
  437 + } else if (field === 'region') {
  438 + setSheet('区域', this.regionOptions)
  439 + }
  440 + },
  441 + onSheetConfirm({ value, label }) {
  442 + const field = this.sheet.field
  443 + if (!field) return
  444 + const v = (value === undefined || value === null) ? '' : value
  445 + if (field === 'standardStandardized') {
  446 + this.standardStandardized = v
  447 + this.standardStandardizedName = label || ''
  448 + return
  449 + }
  450 + this.form[field] = v
  451 + this.form[field + 'Name'] = label || ''
  452 + },
  453 + openRelate(fieldKey) {
  454 + let config = {}
  455 + if (fieldKey === 'buyer') {
  456 + config = { title: '需方', source: 'customer', rowKey: 'id', multiple: false, display: [{ label: '名称', field: 'name' }, { label: '编号', field: 'code' }, { label: '状态', field: 'available', format: v => (v ? '启用' : '停用') }] }
  457 + } else if (fieldKey === 'stockUpCompanyId') {
  458 + config = { title: '备货单位/人(生产标准)', source: 'customer', rowKey: 'id', multiple: false, display: [{ label: '姓名', field: 'name' }, { label: '编号', field: 'code' }, { label: '状态', field: 'available', format: v => (v ? '启用' : '停用') }] }
  459 + }
  460 + const selectedKeys = this.form[fieldKey] ? [this.form[fieldKey]] : []
  461 + this.sheet.visible = false
  462 + this.relate = { ...this.relate, title: config.title, source: config.source, display: config.display, multiple: config.multiple, rowKey: config.rowKey, selectedKeys, fieldKey }
  463 + this.$nextTick(() => { this.relate.visible = true })
  464 + },
  465 + onRelateConfirm({ items }) {
  466 + const _fieldKey = this.relate.fieldKey
  467 + const first = (items && items.length > 0) ? items[0] : null
  468 + this.form[_fieldKey] = (first && first.id) ? first.id : ''
  469 + if (_fieldKey === 'stockUpCompanyId') {
  470 + this.form.stockUpCompanyName = (first && first.name) ? first.name : ''
  471 + } else {
  472 + this.form[_fieldKey + 'Name'] = (first && first.name) ? first.name : ''
  473 + }
  474 + },
  475 + validateRequired() {
  476 + const checks = [
  477 + { key: 'code', label: '编号' },
  478 + { key: 'supplier', label: '供方' },
  479 + { key: 'buyer', label: '需方' },
  480 + { key: 'stockUpCompanyId', label: '备货单位/人(生产标准)' },
  481 + { key: 'orderDate', label: '订货日期' },
  482 + { key: 'unit', label: '单位' },
  483 + { key: 'workshopId', label: '生产厂' },
  484 + { key: 'region', label: '区域' },
  485 + { key: 'specialTerms', label: '特别条款要求' },
  486 + ]
  487 + for (const it of checks) {
  488 + const val = this.form[it.key]
  489 + const empty = (val === undefined || val === null || (typeof val === 'string' && val.trim() === '') || (typeof val === 'number' && isNaN(val)))
  490 + if (empty) { uni.showToast({ title: `请先选择${it.label}`, icon: 'none' }); return false }
  491 + }
  492 + const list = Array.isArray(this.newProductLineList) ? this.newProductLineList : []
  493 + if (list.length === 0) {
  494 + uni.showToast({ title: '请至少添加一条产品明细', icon: 'none' }); return false
  495 + }
  496 + const strEmpty = (v) => (v === undefined || v === null || (typeof v === 'string' && v.trim() === ''))
  497 + const numEmpty = (v) => (v === undefined || v === null || v === '' || (typeof v === 'number' && isNaN(v)))
  498 + for (const [idx, it] of list.entries()) {
  499 + if (
  500 + strEmpty(it.productName) ||
  501 + strEmpty(it.industry) ||
  502 + strEmpty(it.quality) ||
  503 + strEmpty(it.brand) ||
  504 + numEmpty(it.quantity) ||
  505 + numEmpty(it.unitPrice) ||
  506 + strEmpty(it.deliveryDate)
  507 + ) {
  508 + uni.showToast({ title: `第${idx + 1}条明细未完整填写`, icon: 'none' }); return false
  509 + }
  510 + }
  511 + if (this.$refs.productRel && !this.$refs.productRel.validate()) return false
  512 + return true
  513 + },
  514 + async onSubmit() {
  515 + if (!this.fileInfo.id) {
  516 + uni.showToast({ title: '请上传合同附件', icon: 'error' })
  517 + return
  518 + }
  519 + if (!this.standardStandardized && this.standardStandardized !== false) {
  520 + uni.showToast({ title: '请选择合同是否规范', icon: 'error' })
  521 + return
  522 + }
  523 + if (!this.validateRequired()) return
  524 + const confirmRes = await new Promise(resolve => {
  525 + uni.showModal({ title: '确认提交', content: '确定提交标准合同吗?', confirmText: '确定', cancelText: '取消', success: resolve })
  526 + })
  527 + if (!(confirmRes && confirmRes.confirm)) return
  528 + const clean = (obj) => {
  529 + const out = {}
  530 + Object.keys(obj || {}).forEach(k => {
  531 + const v = obj[k]
  532 + const isEmptyString = typeof v === 'string' && v.trim() === ''
  533 + const isUndef = v === undefined || v === null
  534 + const isNaNNumber = typeof v === 'number' && isNaN(v)
  535 + if (!(isEmptyString || isUndef || isNaNNumber)) out[k] = v
  536 + })
  537 + return out
  538 + }
  539 + const lines = (this.newProductLineList || []).map(it => clean(it))
  540 + const payload = clean({
  541 + ...this.form,
  542 + id: this.form.id,
  543 + type: 'INTL_OPEN_SPEC_AGMT',
  544 + totalQuantity: this.totalQuantity,
  545 + totalAmountIncludingTax: this.totalAmountIncludingTax,
  546 + contractDistributorLineList: lines,
  547 + standardFileId: this.fileInfo.id,
  548 + standardFileName: this.fileInfo.name,
  549 + standardStandardized: this.standardStandardized,
  550 + })
  551 + try {
  552 + await uploadStandardContract(payload)
  553 + uni.showToast({ title: '提交成功', icon: 'none' })
  554 + setTimeout(() => { uni.redirectTo({ url: '/pages/contract_foreign_unplan/index' }) }, 400)
  555 + } catch (e) {
  556 + uni.showToast({ title: e.msg || '提交失败', icon: 'none' })
  557 + }
  558 + }
  559 + }
  560 +}
  561 +</script>
  562 +
  563 +<style lang="scss" scoped>
  564 +.total {
  565 + .total-text {
  566 + font-weight: 600;
  567 + font-size: 32rpx;
  568 + color: rgba(0, 0, 0, 0.9);
  569 + padding-bottom: 28rpx;
  570 + border-bottom: 2rpx solid #E7E7E7;
  571 + }
  572 +
  573 + .total-item {
  574 + display: flex;
  575 + align-items: center;
  576 + }
  577 +
  578 + .total-item-text {
  579 + font-weight: 400;
  580 + font-size: 28rpx;
  581 + color: rgba(0, 0, 0, 0.6);
  582 + line-height: 32rpx;
  583 + width: 240rpx;
  584 + padding: 12rpx 0;
  585 + }
  586 +
  587 + .total-item-price {
  588 + font-weight: 600;
  589 + font-size: 32rpx;
  590 + color: rgba(0, 0, 0, 0.9);
  591 + line-height: 32rpx;
  592 + }
  593 +
  594 + .text-red {
  595 + color: #D54941;
  596 + }
  597 +}
  598 +
  599 +.page {
  600 + display: flex;
  601 + flex-direction: column;
  602 + height: 100%;
  603 +}
  604 +
  605 +.scroll {
  606 + flex: 1;
  607 + padding: 12rpx 0 392rpx !important;
  608 +}
  609 +
  610 +.footer {
  611 + z-index: 2;
  612 + position: fixed;
  613 + left: 0;
  614 + right: 0;
  615 + bottom: 0;
  616 + padding: 32rpx;
  617 + padding-bottom: calc(32rpx + env(safe-area-inset-bottom));
  618 + background: #fff;
  619 + box-shadow: 0 -8rpx 24rpx rgba(0, 0, 0, 0.06);
  620 +}
  621 +
  622 +.footer .btn {
  623 + height: 80rpx;
  624 + line-height: 80rpx;
  625 + border-radius: 12rpx;
  626 + font-size: 32rpx;
  627 +}
  628 +
  629 +.footer .submit {
  630 + background: $theme-primary;
  631 + color: #fff;
  632 +}
  633 +
  634 +.quality {
  635 + background-color: #fff;
  636 + display: flex;
  637 + align-items: center;
  638 + padding: 24rpx 32rpx;
  639 + border-bottom: 1rpx solid #f0f0f0;
  640 + margin-top: 20rpx;
  641 +
  642 + .title {
  643 + font-size: 32rpx;
  644 + color: rgba(0, 0, 0, 0.9);
  645 + font-weight: 600;
  646 + }
  647 +
  648 + .opCollapse {
  649 + color: rgba(0, 0, 0, 0.6);
  650 + width: 32rpx;
  651 + height: 28rpx;
  652 + margin-right: 16rpx;
  653 + }
  654 +}
  655 +
  656 +::v-deep .uni-list {
  657 + background: transparent;
  658 +}
  659 +
  660 +::v-deep .uni-list .uni-easyinput .uni-input-input {
  661 + color: rgba(0, 0, 0, 0.9);
  662 +}
  663 +
  664 +::v-deep .uni-list .uni-input-placeholder {
  665 + z-index: 1;
  666 +}
  667 +
  668 +::v-deep .uni-list .uni-input-input {
  669 + background-color: #ffffff;
  670 +}
  671 +
  672 +::v-deep .uni-list-item__extra-text {
  673 + font-size: 32rpx;
  674 +}
  675 +
  676 +::v-deep .uni-list-item__content-title {
  677 + font-size: 32rpx;
  678 + color: rgba(0, 0, 0, 0.9);
  679 +}
  680 +
  681 +::v-deep .uni-list-item__container {
  682 + padding: 32rpx;
  683 +}
  684 +
  685 +::v-deep .uni-list-item__container .uni-easyinput__placeholder-class {
  686 + font-size: 32rpx;
  687 + color: rgba(0, 0, 0, 0.4);
  688 +}
  689 +
  690 +::v-deep .uni-list-item__container .uni-easyinput__content {
  691 + border: none;
  692 + background-color: #ffffff !important;
  693 +}
  694 +
  695 +::v-deep .uni-list-item__container .uni-easyinput__content-input {
  696 + padding-left: 0 !important;
  697 + height: 48rpx;
  698 + line-height: 48rpx;
  699 + font-size: 32rpx;
  700 +}
  701 +
  702 +::v-deep .uni-list-item__container .item-title,
  703 +::v-deep .uni-list-item__container .uni-list-item__content {
  704 + flex: none;
  705 + min-height: 48rpx;
  706 + line-height: 48rpx;
  707 + font-size: 32rpx;
  708 + position: relative;
  709 + width: 210rpx;
  710 + margin-right: 32rpx;
  711 + color: rgba(0, 0, 0, 0.9);
  712 +}
  713 +
  714 +::v-deep .uni-list-item__container .item-title .required {
  715 + color: red;
  716 + position: absolute;
  717 + top: 50%;
  718 + transform: translateY(-50%);
  719 + left: -16rpx;
  720 +}
  721 +
  722 +::v-deep .uni-list-item.select-item.is-empty .uni-list-item__extra-text {
  723 + color: rgba(0, 0, 0, 0.4) !important;
  724 +}
  725 +
  726 +::v-deep .uni-list-item.select-item.is-filled .uni-list-item__extra-text {
  727 + color: rgba(0, 0, 0, 0.9) !important;
  728 +}
  729 +</style>
@@ -89,11 +89,9 @@ @@ -89,11 +89,9 @@
89 </template> 89 </template>
90 </uni-list-item> 90 </uni-list-item>
91 91
92 - <uni-list-item class="select-item" :class="(Array.isArray(form.destinationId) && form.destinationId.length) ? 'is-filled' : 'is-empty'" clickable  
93 - @click="openCitySelector" :rightText="form.destinationLabel || '请选择'" showArrow>  
94 - <template v-slot:body>  
95 - <view class="item-title"><text>目的地</text></view>  
96 - <CitySelector ref="citySelectorRef" v-model="form.destinationId" @change="onCityChange" /> 92 + <uni-list-item title="目的地">
  93 + <template v-slot:footer>
  94 + <uni-easyinput v-model="form.foreignDestination" placeholder="请输入目的地" :inputBorder="false" />
97 </template> 95 </template>
98 </uni-list-item> 96 </uni-list-item>
99 <uni-list-item class="select-item" :class="form.includesPackagingFeeName ? 'is-filled' : 'is-empty'" clickable 97 <uni-list-item class="select-item" :class="form.includesPackagingFeeName ? 'is-filled' : 'is-empty'" clickable
@@ -230,7 +228,6 @@ @@ -230,7 +228,6 @@
230 import SingleSelectSheet from '@/components/single-select/index.vue' 228 import SingleSelectSheet from '@/components/single-select/index.vue'
231 import RelateSelectSheet from '@/components/relate-select/index.vue' 229 import RelateSelectSheet from '@/components/relate-select/index.vue'
232 import ProductRel from './productRel.vue' 230 import ProductRel from './productRel.vue'
233 -import CitySelector from '@/components/city-selector/index.vue'  
234 import { getRetailCodeApi, createContractApi, getCustomerRemarks, getCustomerSpecificQualityRequirements, getDeptApi, getContractApi } from '@/api/contract' 231 import { getRetailCodeApi, createContractApi, getCustomerRemarks, getCustomerSpecificQualityRequirements, getDeptApi, getContractApi } from '@/api/contract'
235 import { getDicByCodes } from '@/utils/dic' 232 import { getDicByCodes } from '@/utils/dic'
236 import { formatCurrencyToChinese } from '@/utils/common' 233 import { formatCurrencyToChinese } from '@/utils/common'
@@ -239,7 +236,7 @@ import { getArea } from '@/api/credit_manage.js' @@ -239,7 +236,7 @@ import { getArea } from '@/api/credit_manage.js'
239 236
240 export default { 237 export default {
241 name: 'AddContractProcess', 238 name: 'AddContractProcess',
242 - components: { SingleSelectSheet, RelateSelectSheet, ProductRel, CitySelector }, 239 + components: { SingleSelectSheet, RelateSelectSheet, ProductRel },
243 data() { 240 data() {
244 return { 241 return {
245 copyId: '', 242 copyId: '',
@@ -266,8 +263,7 @@ export default { @@ -266,8 +263,7 @@ export default {
266 includesTransportFeeName: '否', 263 includesTransportFeeName: '否',
267 unit: '元、公斤、元/公斤', 264 unit: '元、公斤、元/公斤',
268 totalAmountCapital: '', 265 totalAmountCapital: '',
269 - destinationId: [],  
270 - destinationLabel: '', 266 + foreignDestination: '',
271 workshopIdName: '', 267 workshopIdName: '',
272 workshopId: '', 268 workshopId: '',
273 deptName: '', 269 deptName: '',
@@ -318,11 +314,6 @@ export default { @@ -318,11 +314,6 @@ export default {
318 this.loadRegionOptions() 314 this.loadRegionOptions()
319 if (!this.copyId) this.form.orderDate = this.formatDate(new Date()) 315 if (!this.copyId) this.form.orderDate = this.formatDate(new Date())
320 if (this.copyId) this.loadCopyDetail(this.copyId) 316 if (this.copyId) this.loadCopyDetail(this.copyId)
321 - this.$nextTick(() => {  
322 - if (Array.isArray(this.form.destinationId) && this.form.destinationId.length) {  
323 - this.initDestinationLabel()  
324 - }  
325 - })  
326 }, 317 },
327 watch: { 318 watch: {
328 'form.buyer': { 319 'form.buyer': {
@@ -402,8 +393,7 @@ export default { @@ -402,8 +393,7 @@ export default {
402 packagingRequirements: m.packagingRequirements || '', 393 packagingRequirements: m.packagingRequirements || '',
403 paymentTerms: m.paymentTerms || '', 394 paymentTerms: m.paymentTerms || '',
404 transportMode: m.transportMode || '', 395 transportMode: m.transportMode || '',
405 - destinationId: (m.provinceId && m.cityId && m.districtId) ? [m.provinceId, m.cityId, m.districtId] : (Array.isArray(m.destinationId) ? m.destinationId : []),  
406 - destinationLabel: (m.provinceName && m.cityName && m.districtName) ? `${m.provinceName} / ${m.cityName} / ${m.districtName}` : (m.destinationLabel || ''), 396 + foreignDestination: (m.foreignDestination || ''),
407 specialInstructions: m.specialInstructions || '', 397 specialInstructions: m.specialInstructions || '',
408 remarks: m.remarks || '', 398 remarks: m.remarks || '',
409 pieceWeightHead: m.pieceWeightHead || '', 399 pieceWeightHead: m.pieceWeightHead || '',
@@ -564,20 +554,6 @@ export default { @@ -564,20 +554,6 @@ export default {
564 const val = m[field] 554 const val = m[field]
565 return val ? String(val) : map[field] 555 return val ? String(val) : map[field]
566 }, 556 },
567 - openCitySelector() {  
568 - this.$refs.citySelectorRef && this.$refs.citySelectorRef.open()  
569 - },  
570 - async initDestinationLabel() {  
571 - const comp = this.$refs.citySelectorRef  
572 - if (comp && typeof comp.getLabel === 'function') {  
573 - const label = await comp.getLabel()  
574 - this.form.destinationLabel = label || ''  
575 - }  
576 - },  
577 - onCityChange(payload) {  
578 - const label = payload && payload.label != null ? payload.label : ''  
579 - this.form.destinationLabel = label  
580 - },  
581 async openSheet(field) { 557 async openSheet(field) {
582 const setSheet = (title, options) => { 558 const setSheet = (title, options) => {
583 const current = this.form[field] 559 const current = this.form[field]
@@ -677,13 +653,9 @@ export default { @@ -677,13 +653,9 @@ export default {
677 return out 653 return out
678 } 654 }
679 const lines = (this.productLineList || []).map(it => clean(it)) 655 const lines = (this.productLineList || []).map(it => clean(it))
680 - const { destinationLabel, destinationId, ...formForSubmit } = this.form;  
681 - // 区id  
682 - const destination = destinationId && destinationId.length > 0 ? destinationId[destinationId.length - 1] : '';  
683 const payload = clean({ 656 const payload = clean({
684 - ...formForSubmit, 657 + ...this.form,
685 operateType: isCopy ? 'COPY' : 'ADD', 658 operateType: isCopy ? 'COPY' : 'ADD',
686 - destination,  
687 type: 'PROCESS_STD_AGMT', 659 type: 'PROCESS_STD_AGMT',
688 totalQuantity: this.totalQuantity, 660 totalQuantity: this.totalQuantity,
689 totalAmountExcludingTax: this.totalAmountExcludingTax, 661 totalAmountExcludingTax: this.totalAmountExcludingTax,
@@ -38,7 +38,7 @@ statusStyl<template> @@ -38,7 +38,7 @@ statusStyl<template>
38 '-' }}</text></view> 38 '-' }}</text></view>
39 <view class="row"><text class="label">运输方式</text><text class="value">{{ detail.transportMode || '-' 39 <view class="row"><text class="label">运输方式</text><text class="value">{{ detail.transportMode || '-'
40 }}</text></view> 40 }}</text></view>
41 - <view class="row"><text class="label">目的地</text><text class="value">{{ detail.destinationLabel || '-' 41 + <view class="row"><text class="label">目的地</text><text class="value">{{ detail.foreignDestination || '-'
42 }}</text></view> 42 }}</text></view>
43 <view class="row"><text class="label">单价中是否已包含包装费</text><text class="value">{{ 43 <view class="row"><text class="label">单价中是否已包含包装费</text><text class="value">{{
44 detail.includesPackagingFeeName || '-' }}</text></view> 44 detail.includesPackagingFeeName || '-' }}</text></view>
@@ -164,8 +164,7 @@ export default { @@ -164,8 +164,7 @@ export default {
164 packagingRequirements: '', 164 packagingRequirements: '',
165 paymentTerms: '', 165 paymentTerms: '',
166 transportMode: '', 166 transportMode: '',
167 - destinationId: '',  
168 - destinationLabel: '', 167 + foreignDestination: '',
169 specialInstructions: '', 168 specialInstructions: '',
170 remarks: '', 169 remarks: '',
171 pieceWeightHead: '', 170 pieceWeightHead: '',
@@ -422,8 +421,7 @@ export default { @@ -422,8 +421,7 @@ export default {
422 regionName: data.regionName || '', 421 regionName: data.regionName || '',
423 deptName: data.deptName || '', 422 deptName: data.deptName || '',
424 includesPackagingFeeName, includesTransportFeeName, 423 includesPackagingFeeName, includesTransportFeeName,
425 - destinationId: data.provinceId && data.cityId && data.districtId ? [data.provinceId, data.cityId, data.districtId] : '',  
426 - destinationLabel: data.provinceName && data.cityName && data.districtName ? `${data.provinceName} / ${data.cityName} / ${data.districtName}` : '', 424 + foreignDestination: (data.foreignDestination || ''),
427 } 425 }
428 this.detail = await fillStandardApprovedName(this.detail) 426 this.detail = await fillStandardApprovedName(this.detail)
429 const lines = Array.isArray(data.contractStdProcessingLineList) ? data.contractStdProcessingLineList : [] 427 const lines = Array.isArray(data.contractStdProcessingLineList) ? data.contractStdProcessingLineList : []
@@ -70,11 +70,9 @@ @@ -70,11 +70,9 @@
70 <uni-easyinput v-model="form.transportMode" placeholder="请输入运输方式" :inputBorder="false" /> 70 <uni-easyinput v-model="form.transportMode" placeholder="请输入运输方式" :inputBorder="false" />
71 </template> 71 </template>
72 </uni-list-item> 72 </uni-list-item>
73 - <uni-list-item class="select-item" :class="(Array.isArray(form.destinationId) && form.destinationId.length) ? 'is-filled' : 'is-empty'" clickable  
74 - @click="openCitySelector" :rightText="form.destinationLabel || '请选择'" showArrow>  
75 - <template v-slot:body>  
76 - <view class="item-title"><text>目的地</text></view>  
77 - <CitySelector ref="citySelectorRef" v-model="form.destinationId" @change="onCityChange" /> 73 + <uni-list-item title="目的地">
  74 + <template v-slot:footer>
  75 + <uni-easyinput v-model="form.foreignDestination" placeholder="请输入目的地" :inputBorder="false" />
78 </template> 76 </template>
79 </uni-list-item> 77 </uni-list-item>
80 78
@@ -195,7 +193,6 @@ @@ -195,7 +193,6 @@
195 import SingleSelectSheet from '@/components/single-select/index.vue' 193 import SingleSelectSheet from '@/components/single-select/index.vue'
196 import RelateSelectSheet from '@/components/relate-select/index.vue' 194 import RelateSelectSheet from '@/components/relate-select/index.vue'
197 import ProductRel from './productRel.vue' 195 import ProductRel from './productRel.vue'
198 -import CitySelector from '@/components/city-selector/index.vue'  
199 import { getContractApi, updateContractApi } from '@/api/contract' 196 import { getContractApi, updateContractApi } from '@/api/contract'
200 import { getDicByCodes } from '@/utils/dic' 197 import { getDicByCodes } from '@/utils/dic'
201 import { formatCurrencyToChinese } from '@/utils/common' 198 import { formatCurrencyToChinese } from '@/utils/common'
@@ -204,7 +201,7 @@ import { getArea } from '@/api/credit_manage.js' @@ -204,7 +201,7 @@ import { getArea } from '@/api/credit_manage.js'
204 201
205 export default { 202 export default {
206 name: 'ModifyContractProcess', 203 name: 'ModifyContractProcess',
207 - components: { SingleSelectSheet, RelateSelectSheet, ProductRel, CitySelector }, 204 + components: { SingleSelectSheet, RelateSelectSheet, ProductRel },
208 data() { 205 data() {
209 return { 206 return {
210 id: '', 207 id: '',
@@ -241,8 +238,7 @@ export default { @@ -241,8 +238,7 @@ export default {
241 packagingRequirements: '', 238 packagingRequirements: '',
242 paymentTerms: '', 239 paymentTerms: '',
243 transportMode: '', 240 transportMode: '',
244 - destinationId: [],  
245 - destinationLabel: '', 241 + foreignDestination: '',
246 specialInstructions: '', 242 specialInstructions: '',
247 remarks: '', 243 remarks: '',
248 pieceWeightHead: '', 244 pieceWeightHead: '',
@@ -278,11 +274,6 @@ export default { @@ -278,11 +274,6 @@ export default {
278 this.loadExtraOptions() 274 this.loadExtraOptions()
279 this.loadRegionOptions() 275 this.loadRegionOptions()
280 this.loadDetail() 276 this.loadDetail()
281 - this.$nextTick(() => {  
282 - if (Array.isArray(this.form.destinationId) && this.form.destinationId.length) {  
283 - this.initDestinationLabel()  
284 - }  
285 - })  
286 }, 277 },
287 methods: { 278 methods: {
288 async loadRegionOptions() { 279 async loadRegionOptions() {
@@ -329,8 +320,7 @@ export default { @@ -329,8 +320,7 @@ export default {
329 packagingRequirements: m.packagingRequirements || '', 320 packagingRequirements: m.packagingRequirements || '',
330 paymentTerms: m.paymentTerms || '', 321 paymentTerms: m.paymentTerms || '',
331 transportMode: m.transportMode || '', 322 transportMode: m.transportMode || '',
332 - destinationId: (m.provinceId && m.cityId && m.districtId) ? [m.provinceId, m.cityId, m.districtId] : (Array.isArray(m.destinationId) ? m.destinationId : []),  
333 - destinationLabel: (m.provinceName && m.cityName && m.districtName) ? `${m.provinceName} / ${m.cityName} / ${m.districtName}` : (m.destinationLabel || ''), 323 + foreignDestination: (m.foreignDestination || ''),
334 specialInstructions: m.specialInstructions || '', 324 specialInstructions: m.specialInstructions || '',
335 remarks: m.remarks || '', 325 remarks: m.remarks || '',
336 pieceWeightHead: m.pieceWeightHead || '', 326 pieceWeightHead: m.pieceWeightHead || '',
@@ -351,20 +341,6 @@ export default { @@ -351,20 +341,6 @@ export default {
351 this.onProductsChange(lines) 341 this.onProductsChange(lines)
352 } catch (e) { } 342 } catch (e) { }
353 }, 343 },
354 - async initDestinationLabel() {  
355 - const comp = this.$refs.citySelectorRef  
356 - if (comp && typeof comp.getLabel === 'function') {  
357 - const label = await comp.getLabel()  
358 - this.form.destinationLabel = label || ''  
359 - }  
360 - },  
361 - openCitySelector() {  
362 - this.$refs.citySelectorRef && this.$refs.citySelectorRef.open()  
363 - },  
364 - onCityChange(payload) {  
365 - const label = payload && payload.label != null ? payload.label : ''  
366 - this.form.destinationLabel = label  
367 - },  
368 onProductsChange(products) { 344 onProductsChange(products) {
369 const list = Array.isArray(products) ? products : [] 345 const list = Array.isArray(products) ? products : []
370 this.newProductLineList = list 346 this.newProductLineList = list
@@ -511,7 +487,6 @@ export default { @@ -511,7 +487,6 @@ export default {
511 return true 487 return true
512 }, 488 },
513 async onSubmit() { 489 async onSubmit() {
514 - console.log('onSubmit__payload', payload)  
515 if (!this.validateRequired()) return 490 if (!this.validateRequired()) return
516 const confirmRes = await new Promise(resolve => { 491 const confirmRes = await new Promise(resolve => {
517 uni.showModal({ title: '提示', content: '确定保存当前加工标准合同吗?', confirmText: '确定', cancelText: '取消', success: resolve }) 492 uni.showModal({ title: '提示', content: '确定保存当前加工标准合同吗?', confirmText: '确定', cancelText: '取消', success: resolve })
@@ -529,12 +504,9 @@ export default { @@ -529,12 +504,9 @@ export default {
529 return out 504 return out
530 } 505 }
531 const lines = (this.newProductLineList || []).map(it => clean(it)) 506 const lines = (this.newProductLineList || []).map(it => clean(it))
532 - const { destinationLabel, destinationId, ...formForSubmit } = this.form;  
533 - const destination = destinationId && destinationId.length > 0 ? destinationId[destinationId.length - 1] : '';  
534 const payload = clean({ 507 const payload = clean({
535 - ...formForSubmit, 508 + ...this.form,
536 id: this.form.id, 509 id: this.form.id,
537 - destination,  
538 type: 'PROCESS_STD_AGMT', 510 type: 'PROCESS_STD_AGMT',
539 sumQuantity: this.sumQuantity, 511 sumQuantity: this.sumQuantity,
540 sumAmountExcl: this.sumAmountExcl, 512 sumAmountExcl: this.sumAmountExcl,
@@ -792,4 +764,4 @@ export default { @@ -792,4 +764,4 @@ export default {
792 } 764 }
793 } 765 }
794 766
795 -</style>  
  767 +</style>
@@ -29,7 +29,7 @@ @@ -29,7 +29,7 @@
29 '-' }}</text></view> 29 '-' }}</text></view>
30 <view class="row"><text class="label">运输方式</text><text class="value">{{ detail.transportMode || '-' 30 <view class="row"><text class="label">运输方式</text><text class="value">{{ detail.transportMode || '-'
31 }}</text></view> 31 }}</text></view>
32 - <view class="row"><text class="label">目的地</text><text class="value">{{ detail.destinationLabel || '-' 32 + <view class="row"><text class="label">目的地</text><text class="value">{{ detail.foreignDestination || '-'
33 }}</text></view> 33 }}</text></view>
34 <view class="row"><text class="label">单价中是否已包含包装费</text><text class="value">{{ 34 <view class="row"><text class="label">单价中是否已包含包装费</text><text class="value">{{
35 detail.includesPackagingFeeName || '-' }}</text></view> 35 detail.includesPackagingFeeName || '-' }}</text></view>
@@ -120,8 +120,7 @@ export default { @@ -120,8 +120,7 @@ export default {
120 packagingRequirements: '', 120 packagingRequirements: '',
121 paymentTerms: '', 121 paymentTerms: '',
122 transportMode: '', 122 transportMode: '',
123 - destinationId: '',  
124 - destinationLabel: '', 123 + foreignDestination: '',
125 specialInstructions: '', 124 specialInstructions: '',
126 remarks: '', 125 remarks: '',
127 pieceWeightHead: '', 126 pieceWeightHead: '',
@@ -155,8 +154,7 @@ export default { @@ -155,8 +154,7 @@ export default {
155 ...this.detail, 154 ...this.detail,
156 ...data, 155 ...data,
157 includesPackagingFeeName, includesTransportFeeName, 156 includesPackagingFeeName, includesTransportFeeName,
158 - destinationId: data.provinceId && data.cityId && data.districtId ? [data.provinceId, data.cityId, data.districtId] : '',  
159 - destinationLabel: data.provinceName && data.cityName && data.districtName ? `${data.provinceName} / ${data.cityName} / ${data.districtName}` : '', 157 + foreignDestination: (data.foreignDestination || ''),
160 } 158 }
161 const lines = Array.isArray(data.contractStdProcessingLineList) ? data.contractStdProcessingLineList : [] 159 const lines = Array.isArray(data.contractStdProcessingLineList) ? data.contractStdProcessingLineList : []
162 this.productList = lines 160 this.productList = lines
@@ -164,6 +162,10 @@ export default { @@ -164,6 +162,10 @@ export default {
164 this.detail = { ...this.detail } 162 this.detail = { ...this.detail }
165 this.productList = [] 163 this.productList = []
166 } 164 }
  165 + },
  166 + getFormValues() {
  167 + const m = this.detail || {}
  168 + return JSON.parse(JSON.stringify(m))
167 } 169 }
168 } 170 }
169 } 171 }
@@ -280,4 +282,4 @@ export default { @@ -280,4 +282,4 @@ export default {
280 color: rgba(0, 0, 0, 0.6); 282 color: rgba(0, 0, 0, 0.6);
281 font-size: 32rpx; 283 font-size: 32rpx;
282 } 284 }
283 -</style>  
  285 +</style>
@@ -70,11 +70,9 @@ @@ -70,11 +70,9 @@
70 <uni-easyinput v-model="form.transportMode" placeholder="请输入运输方式" :inputBorder="false" /> 70 <uni-easyinput v-model="form.transportMode" placeholder="请输入运输方式" :inputBorder="false" />
71 </template> 71 </template>
72 </uni-list-item> 72 </uni-list-item>
73 - <uni-list-item class="select-item" :class="(Array.isArray(form.destinationId) && form.destinationId.length) ? 'is-filled' : 'is-empty'" clickable  
74 - @click="openCitySelector" :rightText="form.destinationLabel || '请选择'" showArrow>  
75 - <template v-slot:body>  
76 - <view class="item-title"><text>目的地</text></view>  
77 - <CitySelector ref="citySelectorRef" v-model="form.destinationId" @change="onCityChange" /> 73 + <uni-list-item title="目的地">
  74 + <template v-slot:footer>
  75 + <uni-easyinput v-model="form.foreignDestination" placeholder="请输入目的地" :inputBorder="false" />
78 </template> 76 </template>
79 </uni-list-item> 77 </uni-list-item>
80 78
@@ -206,7 +204,6 @@ @@ -206,7 +204,6 @@
206 import SingleSelectSheet from '@/components/single-select/index.vue' 204 import SingleSelectSheet from '@/components/single-select/index.vue'
207 import RelateSelectSheet from '@/components/relate-select/index.vue' 205 import RelateSelectSheet from '@/components/relate-select/index.vue'
208 import ProductRel from './productRel.vue' 206 import ProductRel from './productRel.vue'
209 -import CitySelector from '@/components/city-selector/index.vue'  
210 import FileUpload from '@/components/file-upload/index.vue' 207 import FileUpload from '@/components/file-upload/index.vue'
211 import { getContractApi, uploadStandardContract } from '@/api/contract' 208 import { getContractApi, uploadStandardContract } from '@/api/contract'
212 import { getDicByCodes } from '@/utils/dic' 209 import { getDicByCodes } from '@/utils/dic'
@@ -216,7 +213,7 @@ import { getArea } from '@/api/credit_manage.js' @@ -216,7 +213,7 @@ import { getArea } from '@/api/credit_manage.js'
216 213
217 export default { 214 export default {
218 name: 'UploadStandardContractProcess', 215 name: 'UploadStandardContractProcess',
219 - components: { SingleSelectSheet, RelateSelectSheet, ProductRel, CitySelector, FileUpload }, 216 + components: { SingleSelectSheet, RelateSelectSheet, ProductRel, FileUpload },
220 data() { 217 data() {
221 return { 218 return {
222 id: '', 219 id: '',
@@ -253,8 +250,7 @@ export default { @@ -253,8 +250,7 @@ export default {
253 packagingRequirements: '', 250 packagingRequirements: '',
254 paymentTerms: '', 251 paymentTerms: '',
255 transportMode: '', 252 transportMode: '',
256 - destinationId: [],  
257 - destinationLabel: '', 253 + foreignDestination: '',
258 specialInstructions: '', 254 specialInstructions: '',
259 remarks: '', 255 remarks: '',
260 pieceWeightHead: '', 256 pieceWeightHead: '',
@@ -293,11 +289,6 @@ export default { @@ -293,11 +289,6 @@ export default {
293 this.loadExtraOptions() 289 this.loadExtraOptions()
294 this.loadRegionOptions() 290 this.loadRegionOptions()
295 this.loadDetail() 291 this.loadDetail()
296 - this.$nextTick(() => {  
297 - if (Array.isArray(this.form.destinationId) && this.form.destinationId.length) {  
298 - this.initDestinationLabel()  
299 - }  
300 - })  
301 }, 292 },
302 methods: { 293 methods: {
303 async loadRegionOptions() { 294 async loadRegionOptions() {
@@ -344,8 +335,7 @@ export default { @@ -344,8 +335,7 @@ export default {
344 packagingRequirements: m.packagingRequirements || '', 335 packagingRequirements: m.packagingRequirements || '',
345 paymentTerms: m.paymentTerms || '', 336 paymentTerms: m.paymentTerms || '',
346 transportMode: m.transportMode || '', 337 transportMode: m.transportMode || '',
347 - destinationId: (m.provinceId && m.cityId && m.districtId) ? [m.provinceId, m.cityId, m.districtId] : (Array.isArray(m.destinationId) ? m.destinationId : []),  
348 - destinationLabel: (m.provinceName && m.cityName && m.districtName) ? `${m.provinceName} / ${m.cityName} / ${m.districtName}` : (m.destinationLabel || ''), 338 + foreignDestination: (m.foreignDestination || ''),
349 specialInstructions: m.specialInstructions || '', 339 specialInstructions: m.specialInstructions || '',
350 remarks: m.remarks || '', 340 remarks: m.remarks || '',
351 pieceWeightHead: m.pieceWeightHead || '', 341 pieceWeightHead: m.pieceWeightHead || '',
@@ -372,20 +362,6 @@ export default { @@ -372,20 +362,6 @@ export default {
372 this.onProductsChange(lines) 362 this.onProductsChange(lines)
373 } catch (e) { } 363 } catch (e) { }
374 }, 364 },
375 - async initDestinationLabel() {  
376 - const comp = this.$refs.citySelectorRef  
377 - if (comp && typeof comp.getLabel === 'function') {  
378 - const label = await comp.getLabel()  
379 - this.form.destinationLabel = label || ''  
380 - }  
381 - },  
382 - openCitySelector() {  
383 - this.$refs.citySelectorRef && this.$refs.citySelectorRef.open()  
384 - },  
385 - onCityChange(payload) {  
386 - const label = payload && payload.label != null ? payload.label : ''  
387 - this.form.destinationLabel = label  
388 - },  
389 onProductsChange(products) { 365 onProductsChange(products) {
390 const list = Array.isArray(products) ? products : [] 366 const list = Array.isArray(products) ? products : []
391 this.newProductLineList = list 367 this.newProductLineList = list
@@ -569,12 +545,9 @@ export default { @@ -569,12 +545,9 @@ export default {
569 return out 545 return out
570 } 546 }
571 const lines = (this.newProductLineList || []).map(it => clean(it)) 547 const lines = (this.newProductLineList || []).map(it => clean(it))
572 - const { destinationLabel, destinationId, ...formForSubmit } = this.form;  
573 - const destination = destinationId && destinationId.length > 0 ? destinationId[destinationId.length - 1] : '';  
574 const payload = clean({ 548 const payload = clean({
575 - ...formForSubmit, 549 + ...this.form,
576 id: this.form.id, 550 id: this.form.id,
577 - destination,  
578 type: 'PROCESS_STD_AGMT', 551 type: 'PROCESS_STD_AGMT',
579 sumQuantity: this.totalQuantity, 552 sumQuantity: this.totalQuantity,
580 sumAmountExcl: this.totalAmountExcludingTax, 553 sumAmountExcl: this.totalAmountExcludingTax,
@@ -563,7 +563,7 @@ export default { @@ -563,7 +563,7 @@ export default {
563 }) 563 })
564 return 564 return
565 } 565 }
566 - if (!this.standardStandardized && this.standardStandardized !== false) { 566 + if (this.form.standardStandardized !== true && this.form.standardStandardized !== false) {
567 uni.showToast({ 567 uni.showToast({
568 title: '请选择合同是否规范', 568 title: '请选择合同是否规范',
569 icon: 'error' 569 icon: 'error'
@@ -596,7 +596,7 @@ export default { @@ -596,7 +596,7 @@ export default {
596 contractDistributorLineList: lines, 596 contractDistributorLineList: lines,
597 standardFileId: this.fileInfo.id, 597 standardFileId: this.fileInfo.id,
598 standardFileName: this.fileInfo.name, 598 standardFileName: this.fileInfo.name,
599 - standardStandardized: this.standardStandardized, 599 + standardStandardized: this.form.standardStandardized,
600 }) 600 })
601 601
602 uni.showModal({ 602 uni.showModal({
@@ -279,6 +279,12 @@ export default { @@ -279,6 +279,12 @@ export default {
279 visible: true, 279 visible: true,
280 variant: 'outline', 280 variant: 'outline',
281 event: 'print' 281 event: 'print'
  282 + },
  283 + {
  284 + text: '拆分',
  285 + visible: true,
  286 + variant: 'outline',
  287 + event: 'split'
282 } 288 }
283 ], 289 ],
284 uploadId: '', 290 uploadId: '',
@@ -293,6 +299,7 @@ export default { @@ -293,6 +299,7 @@ export default {
293 const a = this.detail.standardApproved || false 299 const a = this.detail.standardApproved || false
294 const e = this.detail.showExamine || false 300 const e = this.detail.showExamine || false
295 const f = this.detail.standardShowExamine || false 301 const f = this.detail.standardShowExamine || false
  302 + const g = this.detail.canSplit || false
296 return [ 303 return [
297 { ...this.buttons[0], visible: (s === 'DRAFT' && this.$auth.hasPermi('contract-manage:distribution-inventory-contract:modify')) }, 304 { ...this.buttons[0], visible: (s === 'DRAFT' && this.$auth.hasPermi('contract-manage:distribution-inventory-contract:modify')) },
298 { ...this.buttons[1], visible: (s === 'DRAFT' && this.$auth.hasPermi('contract-manage:distribution-inventory-contract:delete')) }, 305 { ...this.buttons[1], visible: (s === 'DRAFT' && this.$auth.hasPermi('contract-manage:distribution-inventory-contract:delete')) },
@@ -308,6 +315,7 @@ export default { @@ -308,6 +315,7 @@ export default {
308 { ...this.buttons[8], visible: (s === 'STANDARD' && f && a === 'AUDIT' && this.$auth.hasPermi('contract-manage:distribution-inventory-contract:standard-approve')) }, 315 { ...this.buttons[8], visible: (s === 'STANDARD' && f && a === 'AUDIT' && this.$auth.hasPermi('contract-manage:distribution-inventory-contract:standard-approve')) },
309 { ...this.buttons[12], visible: (s !== 'DELETED' && this.$auth.hasPermi('contract-manage:distribution-inventory-contract:copy')) }, 316 { ...this.buttons[12], visible: (s !== 'DELETED' && this.$auth.hasPermi('contract-manage:distribution-inventory-contract:copy')) },
310 { ...this.buttons[13], visible: true }, 317 { ...this.buttons[13], visible: true },
  318 + { ...this.buttons[14], visible: g },
311 ] 319 ]
312 } 320 }
313 }, 321 },
@@ -351,9 +359,16 @@ export default { @@ -351,9 +359,16 @@ export default {
351 url: '/pages/contract_stock/modify' + query 359 url: '/pages/contract_stock/modify' + query
352 }) 360 })
353 }, 361 },
354 - uploadContract(id, type = 'formal'){ 362 + uploadContract(id, type = 'formal') {
355 if (!id) return 363 if (!id) return
356 this.uploadId = id 364 this.uploadId = id
  365 + if ((type === 'uploadParent' || type === 'upload') && this.detail?.canEdit) {
  366 + const query = `?id=${encodeURIComponent(id)}`
  367 + uni.navigateTo({
  368 + url: '/pages/contract_stock/uploadStandard' + query
  369 + })
  370 + return
  371 + }
357 this.uploadType = type 372 this.uploadType = type
358 this.$refs.uploadPopup.open() 373 this.$refs.uploadPopup.open()
359 }, 374 },
@@ -434,8 +449,8 @@ export default { @@ -434,8 +449,8 @@ export default {
434 if (e === 'edit') return this.onEdit(btn && btn.params) 449 if (e === 'edit') return this.onEdit(btn && btn.params)
435 if (e === 'delete') return this.onDelete(btn && btn.params) 450 if (e === 'delete') return this.onDelete(btn && btn.params)
436 if (e === 'lock') return this.onLock() 451 if (e === 'lock') return this.onLock()
437 - if (e === 'upload') return this.uploadContract(this.detail.id || '')  
438 - if (e === 'uploadParent') return this.uploadContract(this.detail.parentId || '') 452 + if (e === 'upload') return this.uploadContract(this.detail.id || '', 'upload')
  453 + if (e === 'uploadParent') return this.uploadContract(this.detail.parentId || '', 'uploadParent')
439 if (e === 'uploadStandard') return this.uploadContract(this.detail.id || '', 'standard') 454 if (e === 'uploadStandard') return this.uploadContract(this.detail.id || '', 'standard')
440 if (e === 'audit1') return this.onAudit(this.detail.id || '', 'FORMAL_CONTRACT') 455 if (e === 'audit1') return this.onAudit(this.detail.id || '', 'FORMAL_CONTRACT')
441 if (e === 'audit2') return this.onAudit(this.detail.parentId || '', 'FORMAL_CONTRACT') 456 if (e === 'audit2') return this.onAudit(this.detail.parentId || '', 'FORMAL_CONTRACT')
@@ -445,6 +460,12 @@ export default { @@ -445,6 +460,12 @@ export default {
445 if (e === 'auditDetail3') return this.onAuditDetail(this.detail.id || '', 'STANDARD_CONTRACT') 460 if (e === 'auditDetail3') return this.onAuditDetail(this.detail.id || '', 'STANDARD_CONTRACT')
446 if (e === 'copy') return this.onCopy(this.detail) 461 if (e === 'copy') return this.onCopy(this.detail)
447 if (e === 'print') return this.onPrint(this.detail.id || '') 462 if (e === 'print') return this.onPrint(this.detail.id || '')
  463 + if (e === 'split') return this.onSplit(this.detail.id || '')
  464 + },
  465 + onSplit(id) {
  466 + uni.navigateTo({
  467 + url: '/pages/contract_stock/split?id=' + id || ''
  468 + })
448 }, 469 },
449 onPrint(id) { 470 onPrint(id) {
450 printFile(id) 471 printFile(id)
  1 +<template>
  2 + <view class="page">
  3 + <scroll-view class="scroll" scroll-y>
  4 + <view class="lock-page">
  5 + <view class="block" v-for="(item, idx) in items" :key="idx">
  6 + <view class="block-header">
  7 + <uni-data-checkbox
  8 + multiple
  9 + mode="default"
  10 + :localdata="[{ text: '拆分数量', value: 'LOCKED' }]"
  11 + :modelValue="item.locked ? ['LOCKED'] : []"
  12 + :disabled="true"
  13 + @change="onLockChange(idx, $event)"
  14 + />
  15 + <view class="ops" @click="toggleItem(idx)">
  16 + <image class="opIcon"
  17 + :src="item.collapsed ? '/static/images/up.png' : '/static/images/down.png'" />
  18 + <text class="opText">{{ item.collapsed ? '收起' : '展开' }}</text>
  19 + </view>
  20 + </view>
  21 +
  22 + <uni-list v-show="item.collapsed">
  23 + <uni-list-item title="产品名称">
  24 + <template v-slot:footer>
  25 + <uni-easyinput v-model="item.productName" placeholder="请输入产品名称" :clearable="false" disabled />
  26 + </template>
  27 + </uni-list-item>
  28 + <uni-list-item title="行业">
  29 + <template v-slot:footer>
  30 + <uni-easyinput v-model="item.industry" placeholder="请输入行业" :clearable="false" disabled />
  31 + </template>
  32 + </uni-list-item>
  33 + <uni-list-item title="牌号">
  34 + <template v-slot:footer>
  35 + <uni-easyinput v-model="item.brand" placeholder="请输入牌号" :clearable="false" disabled />
  36 + </template>
  37 + </uni-list-item>
  38 + <uni-list-item title="品质">
  39 + <template v-slot:footer>
  40 + <uni-easyinput v-model="item.quality" placeholder="请输入品质" :clearable="false" disabled />
  41 + </template>
  42 + </uni-list-item>
  43 + <uni-list-item title="规格(mm)">
  44 + <template v-slot:footer>
  45 + <view class="value value-spec">
  46 + <view v-if="item.thickness" class="value-spec_val">{{ item.thickness }}</view>
  47 + <view v-if="item.thickness" class="value-spec_box">
  48 + <view v-if="item.thicknessTolPos" class="value-spec_box_1">{{ item.thicknessTolPos > 0 ? '+' + item.thicknessTolPos : item.thicknessTolPos }}
  49 + </view>
  50 + <view v-if="item.thicknessTolNeg" class="value-spec_box_2">{{ item.thicknessTolNeg > 0 ? '+' + item.thicknessTolNeg : item.thicknessTolNeg }}
  51 + </view>
  52 + </view>
  53 + <view v-if="item.width" class="value-spec_val p12">*</view>
  54 + <view v-if="item.width" class="value-spec_val">{{ item.width }}</view>
  55 + <view v-if="item.width" class="value-spec_box">
  56 + <view v-if="item.widthTolPos" class="value-spec_box_1">{{ item.widthTolPos > 0 ? '+' + item.widthTolPos : item.widthTolPos }}
  57 + </view>
  58 + <view v-if="item.widthTolNeg" class="value-spec_box_2">{{ item.widthTolNeg > 0 ? '+' + item.widthTolNeg : item.widthTolNeg }}
  59 + </view>
  60 + </view>
  61 + <view v-if="item.length" class="value-spec_val p12">*</view>
  62 + <view v-if="item.length" class="value-spec_val">{{ item.length }}</view>
  63 + <view v-if="item.length" class="value-spec_box">
  64 + <view v-if="item.lengthTolPos" class="value-spec_box_1">{{ item.lengthTolPos > 0 ? '+' + item.lengthTolPos : item.lengthTolPos }}
  65 + </view>
  66 + <view v-if="item.lengthTolNeg" class="value-spec_box_2">{{ item.lengthTolNeg > 0 ? '+' + item.lengthTolNeg : item.lengthTolNeg }}
  67 + </view>
  68 + </view>
  69 + </view>
  70 + </template>
  71 + </uni-list-item>
  72 + <uni-list-item title="物料编码">
  73 + <template v-slot:footer>
  74 + <uni-easyinput v-model="item.materialCode" placeholder="请输入物料编码" :clearable="false" disabled />
  75 + </template>
  76 + </uni-list-item>
  77 + <uni-list-item title="状态">
  78 + <template v-slot:footer>
  79 + <uni-easyinput v-model="item.status" placeholder="请输入状态" :clearable="false" disabled />
  80 + </template>
  81 + </uni-list-item>
  82 + <uni-list-item title="数量">
  83 + <template v-slot:footer>
  84 + <uni-easyinput v-model="item.quantity" type="number" :inputBorder="false" disabled placeholder="不可编辑" />
  85 + </template>
  86 + </uni-list-item>
  87 + <uni-list-item title="本次锁价数量">
  88 + <template v-slot:footer>
  89 + <uni-easyinput v-model="item.currentQuantity" type="number" :inputBorder="false" placeholder="请输入本次拆分数量" @input="onImmediateChange(idx)" @blur="onNumberBlur(idx, 'currentQuantity', 3)" />
  90 + </template>
  91 + </uni-list-item>
  92 + <uni-list-item title="单价">
  93 + <template v-slot:footer>
  94 + <uni-easyinput v-model="item.unitPrice" type="digit" :inputBorder="false" disabled placeholder="不可编辑" @input="onImmediateChange(idx)" @blur="onNumberBlur(idx, 'unitPrice', 0)" />
  95 + </template>
  96 + </uni-list-item>
  97 + <uni-list-item title="不含税金额">
  98 + <template v-slot:footer>
  99 + <uni-easyinput v-model="item.amountExcludingTax" type="number" :inputBorder="false" disabled placeholder="" />
  100 + </template>
  101 + </uni-list-item>
  102 + <uni-list-item title="总金额">
  103 + <template v-slot:footer>
  104 + <uni-easyinput v-model="item.totalAmount" type="number" :inputBorder="false" disabled placeholder="" />
  105 + </template>
  106 + </uni-list-item>
  107 + <uni-list-item title="发货日期">
  108 + <template v-slot:footer>
  109 + <uni-easyinput v-model="item.deliveryDate" :inputBorder="false" disabled />
  110 + </template>
  111 + </uni-list-item>
  112 + </uni-list>
  113 +
  114 + <uni-list v-show="!item.collapsed">
  115 + <uni-list-item title="产品名称">
  116 + <template v-slot:footer>
  117 + <uni-easyinput v-model="item.productName" placeholder="请输入产品名称" :clearable="false" disabled />
  118 + </template>
  119 + </uni-list-item>
  120 + <uni-list-item title="行业">
  121 + <template v-slot:footer>
  122 + <uni-easyinput v-model="item.industry" placeholder="请输入行业" :clearable="false" disabled />
  123 + </template>
  124 + </uni-list-item>
  125 + <uni-list-item title="牌号">
  126 + <template v-slot:footer>
  127 + <uni-easyinput v-model="item.brand" placeholder="请输入牌号" :clearable="false" disabled />
  128 + </template>
  129 + </uni-list-item>
  130 +
  131 + </uni-list>
  132 + </view>
  133 + <view class="footer">
  134 + <button class="btn submit" type="primary" @click="onSubmit">提交</button>
  135 + </view>
  136 + </view>
  137 + </scroll-view>
  138 +
  139 + </view>
  140 +</template>
  141 +
  142 +<script>
  143 +import { getContractApi, splitQuantityLock } from '@/api/contract'
  144 +
  145 +export default {
  146 + name: 'ContractUnplanLock',
  147 + data() {
  148 + return {
  149 + id: '',
  150 + items: [],
  151 + planQty: 30,
  152 + }
  153 + },
  154 + onLoad(options) {
  155 + const id = options && options.id ? options.id : ''
  156 + this.id = id
  157 + this.loadDetail()
  158 + },
  159 + methods: {
  160 + onLockChange(idx, e) {
  161 + const it = this.items[idx]
  162 + if (!it) return
  163 + const arr = e && e.detail && e.detail.value ? e.detail.value : []
  164 + it.locked = Array.isArray(arr) && arr.length > 0
  165 + this.$set(this.items, idx, it)
  166 + },
  167 + async loadDetail() {
  168 + if (!this.id) return
  169 + try {
  170 + const res = await getContractApi(this.id)
  171 + const data = res && res.data ? res.data : {}
  172 + const lines = Array.isArray(data.contractDistributorLineList) ? data.contractDistributorLineList : []
  173 + const init = lines.map(v => ({
  174 + locked: true,
  175 + collapsed: true,
  176 + raw: v,
  177 + productName: v.rawProductName || v.productName || '',
  178 + industry: v.industry || '',
  179 + brand: v.rawProductGrade || v.brand || '',
  180 + quality: v.quality || '',
  181 + thickness: v.thickness || '',
  182 + thicknessTolPos: v.thicknessTolPos || '',
  183 + thicknessTolNeg: v.thicknessTolNeg || '',
  184 + width: v.width || '',
  185 + widthTolPos: v.widthTolPos || '',
  186 + widthTolNeg: v.widthTolNeg || '',
  187 + length: v.length || '',
  188 + lengthTolPos: v.lengthTolPos || '',
  189 + lengthTolNeg: v.lengthTolNeg || '',
  190 + materialCode: v.materialCode || '',
  191 + status: v.status || '',
  192 + quantity: v.productQuantity || v.quantity || '',
  193 + currentQuantity: v.currentQuantity === 0 ? 0 : (v.currentQuantity || ''),
  194 + unitPrice: v.unitPrice || '',
  195 + amountExcludingTax: v.amountExcludingTax || 0,
  196 + totalAmount: v.totalAmount || 0,
  197 + deliveryDate: v.deliveryDate || '',
  198 + specDisplay: ''
  199 + }))
  200 + this.items = init.map(it => ({ ...it, specDisplay: this.specOf(it) }))
  201 + this.recalculateAll()
  202 + } catch (e) {
  203 + this.items = []
  204 + }
  205 + },
  206 + toggleItem(idx) {
  207 + const it = this.items[idx]
  208 + if (!it) return
  209 + it.collapsed = !it.collapsed
  210 + this.$set(this.items, idx, it)
  211 + },
  212 + onImmediateChange(idx) {
  213 + this.$nextTick(() => this.recalculate(idx))
  214 + },
  215 + onNumberBlur(idx, field, digits) {
  216 + const it = this.items[idx]
  217 + if (!it) return
  218 + const raw = it[field]
  219 + if (raw === '' || raw === null || raw === undefined) {
  220 + this.$set(this.items, idx, it)
  221 + this.recalculate(idx)
  222 + return
  223 + }
  224 + const num = this.toNumber(raw)
  225 + const rounded = this.round(num, digits)
  226 + it[field] = rounded
  227 + this.$set(this.items, idx, it)
  228 + this.recalculate(idx)
  229 + },
  230 + recalculate(idx) {
  231 + const TAX_RATE = 0.13
  232 + const it = this.items[idx]
  233 + if (!it) return
  234 + const qty = this.toNumber(it.quantity)
  235 + const price = this.toNumber(it.unitPrice)
  236 + const total = this.round(qty * price, 2)
  237 + const excl = this.round(total / (1 + TAX_RATE), 2)
  238 + it.amountExcludingTax = excl
  239 + it.totalAmount = total
  240 + this.$set(this.items, idx, it)
  241 + },
  242 + recalculateAll() {
  243 + for (let i = 0; i < this.items.length; i++) this.recalculate(i)
  244 + },
  245 + toNumber(val) {
  246 + if (typeof val === 'number') return isNaN(val) ? 0 : val
  247 + const n = parseFloat(String(val).replace(/[^0-9.\-]/g, ''))
  248 + return isNaN(n) ? 0 : n
  249 + },
  250 + round(val, digits = 2) {
  251 + const n = Number(val)
  252 + if (isNaN(n)) return 0
  253 + const m = Math.pow(10, digits)
  254 + return Math.round(n * m) / m
  255 + },
  256 + specOf(item) {
  257 + const t = [item.thickness, item.thicknessTolPos, item.thicknessTolNeg].filter(Boolean).join('/ ')
  258 + const w = [item.width, item.widthTolPos, item.widthTolNeg].filter(Boolean).join('/ ')
  259 + const l = [item.length, item.lengthTolPos, item.lengthTolNeg].filter(Boolean).join('/ ')
  260 + return [t, w, l].filter(Boolean).join(' × ')
  261 + },
  262 + formatCurrency(val) {
  263 + if (val == null || val === '') return ''
  264 + const num = Number(val)
  265 + const pre = isNaN(num) ? '' : '¥'
  266 + const fixed = isNaN(num) ? String(val) : num.toFixed(2)
  267 + return `${pre}${fixed}`
  268 + },
  269 + onReset() {
  270 + this.items = this.items.map((it, i) => ({
  271 + ...it,
  272 + quantity: '',
  273 + currentQuantity: '',
  274 + unitPrice: '',
  275 + amountExcludingTax: 0
  276 + }))
  277 + },
  278 + async onSubmit() {
  279 + const selected = this.items.filter(it => it.locked).map(it => {
  280 + const raw = { ...(it.raw || {}) }
  281 + const qty = this.toNumber(it.quantity)
  282 + const curQtyRaw = it.currentQuantity
  283 + const price = this.toNumber(it.unitPrice)
  284 + const total = this.toNumber(it.totalAmount)
  285 + const excl = this.toNumber(it.amountExcludingTax)
  286 + if (Object.prototype.hasOwnProperty.call(raw, 'productQuantity')) raw.productQuantity = qty
  287 + else raw.quantity = qty
  288 + raw.currentQuantity = (curQtyRaw === '' || curQtyRaw === null || curQtyRaw === undefined) ? null : this.toNumber(curQtyRaw)
  289 + raw.unitPrice = price
  290 + raw.totalAmount = total
  291 + raw.amountExcludingTax = excl
  292 + return raw
  293 + })
  294 + if (!selected.length) {
  295 + uni.showToast({ title: '未选择任何拆分项', icon: 'none' })
  296 + return
  297 + }
  298 + const invalidQty = selected.find(r => {
  299 + const q = this.toNumber(r.currentQuantity)
  300 + return !(q > 0)
  301 + })
  302 + if (invalidQty) {
  303 + uni.showToast({ title: '请填写本次拆分数量', icon: 'none' })
  304 + return
  305 + }
  306 + this.selectedItems = selected
  307 + const payload = {
  308 + id: this.id,
  309 + contractDistributorLineList: selected
  310 + }
  311 +
  312 + uni.showModal({
  313 + title: '确认提交',
  314 + content: '确定提交拆分吗?',
  315 + success: (res) => {
  316 + if (res.confirm) {
  317 + splitQuantityLock(payload).then(() => {
  318 + uni.showToast({ title: '拆分已提交', icon: 'success' })
  319 + setTimeout(() => {
  320 + uni.navigateTo({ url: '/pages/contract_stock/index' })
  321 + }, 500)
  322 + }).catch((err) => {
  323 + uni.showToast({ title: err.msg ||'提交失败', icon: 'none' })
  324 + })
  325 + }
  326 + }
  327 + })
  328 + }
  329 + }
  330 +}
  331 +</script>
  332 +
  333 +<style lang="scss" scoped>
  334 +.page {
  335 + display: flex;
  336 + flex-direction: column;
  337 + height: 100%;
  338 +}
  339 +
  340 +.scroll {
  341 + flex: 1;
  342 + padding: 12rpx 0 392rpx !important;
  343 +}
  344 +
  345 +.header {
  346 + background-color: #fff;
  347 + display: flex;
  348 + align-items: center;
  349 + padding: 24rpx 32rpx;
  350 + border-bottom: 1rpx solid #f0f0f0;
  351 +}
  352 +
  353 +.title {
  354 + font-size: 32rpx;
  355 + color: rgba(0, 0, 0, 0.9);
  356 + font-weight: 600;
  357 +}
  358 +
  359 +.opCollapse {
  360 + width: 24rpx;
  361 + height: 24rpx;
  362 + margin-right: 16rpx;
  363 + margin-top: 8rpx;
  364 +}
  365 +
  366 +.block {
  367 + background: #fff;
  368 + margin-top: 20rpx;
  369 +}
  370 +
  371 +.block-header {
  372 + display: flex;
  373 + align-items: center;
  374 + padding: 24rpx 32rpx;
  375 + border-bottom: 1rpx solid #f0f0f0;
  376 +}
  377 +
  378 +.block-header ::v-deep .uni-data-checklist .checkbox__inner {
  379 + width: 36rpx;
  380 + height: 36rpx;
  381 +}
  382 +.block-header ::v-deep .uni-data-checklist .checklist-text {
  383 + font-size: 28rpx;
  384 + margin-left: 12rpx;
  385 +}
  386 +
  387 +.block-title {
  388 + margin-left: 12rpx;
  389 + font-size: 28rpx;
  390 + color: rgba(0, 0, 0, 0.9);
  391 +}
  392 +
  393 +.ops {
  394 + margin-left: auto;
  395 + display: flex;
  396 + align-items: center;
  397 + color: $theme-primary;
  398 + font-size: 28rpx;
  399 +}
  400 +
  401 +.opIcon {
  402 + width: 40rpx;
  403 + height: 40rpx;
  404 +}
  405 +
  406 +.opText {
  407 + margin-left: 8rpx;
  408 + color: $theme-primary;
  409 +}
  410 +
  411 +::v-deep .uni-list {
  412 + .uni-easyinput {
  413 + display: flex;
  414 +
  415 + .uni-input-input {
  416 + color: rgba(0, 0, 0, 0.9);
  417 + }
  418 + }
  419 +
  420 + .uni-input-placeholder {
  421 + z-index: 1;
  422 + }
  423 +
  424 + .uni-input-input {
  425 + background-color: #ffffff;
  426 + }
  427 +
  428 + background: transparent;
  429 +
  430 + &-item {
  431 + &__extra-text {
  432 + font-size: 32rpx;
  433 + }
  434 +
  435 + &__content-title {
  436 + font-size: 32rpx;
  437 + color: rgba(0, 0, 0, 0.9);
  438 + }
  439 +
  440 + &__container {
  441 + padding: 32rpx;
  442 +
  443 + .uni-easyinput {
  444 + &__placeholder-class {
  445 + font-size: 32rpx;
  446 + color: rgba(0, 0, 0, 0.4);
  447 + }
  448 +
  449 + &__content {
  450 + border: none;
  451 + background-color: #ffffff !important;
  452 +
  453 + &-input {
  454 + padding-left: 0 !important;
  455 + height: 48rpx;
  456 + line-height: 48rpx;
  457 + font-size: 32rpx;
  458 + }
  459 +
  460 + .content-clear-icon {
  461 + font-size: 44rpx !important;
  462 + }
  463 + }
  464 + }
  465 +
  466 + .item-title,
  467 + .uni-list-item__content {
  468 + flex: none;
  469 + min-height: 48rpx;
  470 + line-height: 48rpx;
  471 + font-size: 32rpx;
  472 + position: relative;
  473 + width: 210rpx;
  474 + margin-right: 32rpx;
  475 + color: rgba(0, 0, 0, 0.9);
  476 +
  477 + .required {
  478 + color: red;
  479 + position: absolute;
  480 + top: 50%;
  481 + transform: translateY(-50%);
  482 + left: -16rpx;
  483 + }
  484 + }
  485 + }
  486 +
  487 + &.select-item {
  488 + &.is-empty {
  489 + .uni-list-item__extra-text {
  490 + color: rgba(0, 0, 0, 0.4) !important;
  491 + }
  492 + }
  493 +
  494 + &.is-filled {
  495 + .uni-list-item__extra-text {
  496 + color: rgba(0, 0, 0, 0.9) !important;
  497 + }
  498 + }
  499 + }
  500 +
  501 + &.mgb10 {
  502 + margin-bottom: 20rpx;
  503 + }
  504 + }
  505 +}
  506 +
  507 +// ::v-deep .uni-list-item__container {
  508 +// padding: 32rpx;
  509 +// }
  510 +
  511 +::v-deep .is-disabled {
  512 + background-color: transparent !important;
  513 +}
  514 +// ::v-deep .uni-list-item__content-title {
  515 +// font-size: 28rpx;
  516 +// color: rgba(0, 0, 0, 0.9);
  517 +// }
  518 +
  519 +// ::v-deep .uni-list-item__extra-text {
  520 +// font-size: 32rpx;
  521 +// }
  522 +
  523 +::v-deep .uni-easyinput {
  524 + width: 100%;
  525 +}
  526 +
  527 +::v-deep .uni-easyinput__placeholder-class {
  528 + font-size: 32rpx;
  529 + color: rgba(0, 0, 0, 0.4);
  530 +}
  531 +
  532 +::v-deep .uni-easyinput__content {
  533 + border: none;
  534 + display: flex;
  535 +}
  536 +
  537 +::v-deep .uni-easyinput__content-input {
  538 + padding-left: 0 !important;
  539 + height: 48rpx;
  540 + line-height: 48rpx;
  541 + font-size: 32rpx;
  542 + color: rgba(0, 0, 0, 0.9);
  543 +}
  544 +
  545 +.amount-item .item-title {
  546 + display: flex;
  547 + align-items: center;
  548 +}
  549 +
  550 +.amount-row {
  551 + display: flex;
  552 + align-items: center;
  553 +}
  554 +
  555 +.amount-row .unit {
  556 + margin-left: 12rpx;
  557 + color: rgba(0, 0, 0, 0.6);
  558 +}
  559 +
  560 +.summary {
  561 + margin-top: 20rpx;
  562 + background: #fff;
  563 + padding-bottom: 12rpx;
  564 +}
  565 +
  566 +.title-header {
  567 + display: flex;
  568 + align-items: center;
  569 + padding: 20rpx 32rpx;
  570 +}
  571 +
  572 +.title-header_icon {
  573 + width: 24rpx;
  574 + height: 24rpx;
  575 + margin-right: 16rpx;
  576 +}
  577 +
  578 +.sum-card {
  579 + background: #f3f3f3;
  580 + border-radius: 16rpx;
  581 + padding: 24rpx;
  582 + margin: 0 32rpx 20rpx;
  583 +}
  584 +
  585 +.row {
  586 + display: flex;
  587 + margin-bottom: 16rpx;
  588 +}
  589 +
  590 +.row .label {
  591 + width: 140rpx;
  592 + color: rgba(0, 0, 0, 0.6);
  593 + font-size: 28rpx;
  594 +}
  595 +
  596 +.row .value {
  597 + flex: 1;
  598 + text-align: right;
  599 + color: rgba(0, 0, 0, 0.9);
  600 + font-size: 28rpx;
  601 +}
  602 +
  603 +.row .amount {
  604 + color: #D54941;
  605 +}
  606 +
  607 +.total {
  608 + .total-text {
  609 + font-weight: 600;
  610 + font-size: 32rpx;
  611 + color: rgba(0, 0, 0, 0.9);
  612 + padding-bottom: 28rpx;
  613 + border-bottom: 2rpx solid #E7E7E7;
  614 + }
  615 +
  616 + .total-item {
  617 + display: flex;
  618 + align-items: center;
  619 +
  620 + .total-item-text {
  621 + font-weight: 400;
  622 + font-size: 28rpx;
  623 + color: rgba(0, 0, 0, 0.6);
  624 + line-height: 32rpx;
  625 + width: 240rpx;
  626 + padding: 12rpx 0;
  627 + }
  628 +
  629 + .total-item-price {
  630 + font-weight: 600;
  631 + font-size: 32rpx;
  632 + color: rgba(0, 0, 0, 0.9);
  633 + line-height: 32rpx;
  634 + }
  635 +
  636 + .text-red {
  637 + color: #D54941;
  638 + }
  639 + }
  640 +
  641 +}
  642 +
  643 +.footer {
  644 + z-index: 2;
  645 + position: fixed;
  646 + left: 0;
  647 + right: 0;
  648 + bottom: 0;
  649 + padding: 32rpx;
  650 + padding-bottom: calc(32rpx + env(safe-area-inset-bottom));
  651 + background: #fff;
  652 + box-shadow: 0 -8rpx 24rpx rgba(0, 0, 0, 0.06);
  653 +
  654 + .btn {
  655 + height: 80rpx;
  656 + line-height: 80rpx;
  657 + border-radius: 12rpx;
  658 + font-size: 32rpx;
  659 + }
  660 +
  661 + .submit {
  662 + background: $theme-primary;
  663 + color: #fff;
  664 + }
  665 +}
  666 +
  667 +.btn {
  668 + height: 80rpx;
  669 + line-height: 80rpx;
  670 + border-radius: 12rpx;
  671 + font-size: 32rpx;
  672 + flex: 1;
  673 +}
  674 +
  675 +.submit {
  676 + background: $theme-primary;
  677 + color: #fff;
  678 +}
  679 +.value-spec {
  680 + height: 48rpx;
  681 + display: flex;
  682 + align-items: center;
  683 + color: #000000;
  684 + // justify-content: end;
  685 + &_box {
  686 + position: relative;
  687 + width: 60rpx;
  688 + height: 48rpx;
  689 +
  690 + &_1 {
  691 + font-size: 16rpx;
  692 + position: absolute;
  693 + top: -10rpx;
  694 + left: 0;
  695 + }
  696 +
  697 + &_2 {
  698 + font-size: 16rpx;
  699 + position: absolute;
  700 + bottom: -10rpx;
  701 + left: 0;
  702 + }
  703 + }
  704 +
  705 + &_val {
  706 + font-size: 28rpx;
  707 +
  708 + &.p12 {
  709 + padding-right: 12rpx;
  710 + }
  711 + }
  712 + }
  713 + .row-spec {
  714 + height: 60rpx;
  715 + align-items: center;
  716 + }
  717 +</style>
  1 +<template>
  2 + <view class="page">
  3 + <scroll-view class="scroll" scroll-y>
  4 + <uni-list>
  5 + <uni-list-item title="编号">
  6 + <template v-slot:footer>
  7 + <uni-easyinput v-model="form.code" :inputBorder="false" disabled />
  8 + </template>
  9 + </uni-list-item>
  10 +
  11 + <uni-list-item class="select-item" :class="form.supplier ? 'is-filled' : 'is-empty'" clickable
  12 + @click="openSheet('supplier')" :rightText="displayLabel('supplierName')" showArrow>
  13 + <template v-slot:body>
  14 + <view class="item-title"><text class="required">*</text><text>供方</text></view>
  15 + </template>
  16 + </uni-list-item>
  17 +
  18 + <uni-list-item class="select-item" :class="form.buyer ? 'is-filled' : 'is-empty'" clickable
  19 + @click="openRelate('buyer')" :rightText="form.buyerName || '请选择需方'" showArrow>
  20 + <template v-slot:body>
  21 + <view class="item-title"><text class="required">*</text><text>需方</text></view>
  22 + </template>
  23 + </uni-list-item>
  24 +
  25 + <uni-list-item class="select-item" :class="form.stockUpCompanyId ? 'is-filled' : 'is-empty'" clickable
  26 + @click="openRelate('stockUpCompanyId')" :rightText="form.stockUpCompanyName || '请选择备货单位'" showArrow>
  27 + <template v-slot:body>
  28 + <view class="item-title"><text class="required">*</text><text>备货单位/人(生产标准)</text></view>
  29 + </template>
  30 + </uni-list-item>
  31 +
  32 + <uni-list-item class="select-item" :class="form.workshopId ? 'is-filled' : 'is-empty'" clickable
  33 + @click="openSheet('workshopId')" :rightText="form.workshopName || '请选择生产厂'" showArrow>
  34 + <template v-slot:body>
  35 + <view class="item-title"><text class="required">*</text><text>生产厂</text></view>
  36 + </template>
  37 + </uni-list-item>
  38 +
  39 + <uni-list-item title="订货日期">
  40 + <template v-slot:footer>
  41 + <uni-datetime-picker type="date" v-model="form.orderDate" />
  42 + </template>
  43 + </uni-list-item>
  44 +
  45 + <uni-list-item title="单位">
  46 + <template v-slot:footer>
  47 + <uni-easyinput v-model="form.unit" :inputBorder="false" disabled />
  48 + </template>
  49 + </uni-list-item>
  50 + <uni-list-item title="办事处">
  51 + <template v-slot:footer>
  52 + <uni-easyinput v-model="form.deptName" :inputBorder="false" disabled placeholder="自动获取" />
  53 + </template>
  54 + </uni-list-item>
  55 + <uni-list-item class="select-item" :class="form.region ? 'is-filled' : 'is-empty'" clickable
  56 + @click="openSheet('region')" :rightText="displayLabel('regionName')" showArrow>
  57 + <template v-slot:body>
  58 + <view class="item-title"><text class="required">*</text><text>区域</text></view>
  59 + </template>
  60 + </uni-list-item>
  61 +
  62 + <ProductRel ref="productRel" mode="add" :deliveryDate="form.orderDate" :deliveryDateBase="form.deliveryDate"
  63 + :list="productLineList" @change="onProductsChange" :options="productList" />
  64 +
  65 + <uni-list-item title="合计人民币金额(大写)">
  66 + <template v-slot:footer>
  67 + <uni-easyinput v-model="form.totalAmountCapital" placeholder="" :inputBorder="false" disabled />
  68 + </template>
  69 + </uni-list-item>
  70 + <uni-list-item title="交付定金、数额、时间">
  71 + <template v-slot:footer>
  72 + <uni-easyinput v-model="form.depositInfo" placeholder="请输入交付定金、数额、时间" :inputBorder="false" />
  73 + </template>
  74 + </uni-list-item>
  75 + <uni-list-item title="包装要求">
  76 + <template v-slot:footer>
  77 + <uni-easyinput v-model="form.packagingRequirements" placeholder="请输入包装要求" :inputBorder="false" />
  78 + </template>
  79 + </uni-list-item>
  80 + <uni-list-item title="付款方式、付款期限">
  81 + <template v-slot:footer>
  82 + <uni-easyinput v-model="form.paymentTerms" placeholder="请输入付款方式、付款期限" :inputBorder="false" />
  83 + </template>
  84 + </uni-list-item>
  85 + <uni-list-item title="运输方式">
  86 + <template v-slot:footer>
  87 + <uni-easyinput v-model="form.transportMode" placeholder="请输入运输方式" :inputBorder="false" />
  88 + </template>
  89 + </uni-list-item>
  90 + <uni-list-item class="select-item" :class="(Array.isArray(form.destinationId) && form.destinationId.length) ? 'is-filled' : 'is-empty'" clickable
  91 + @click="openCitySelector" :rightText="form.destinationLabel || '请选择'" showArrow>
  92 + <template v-slot:body>
  93 + <view class="item-title"><text>目的地</text></view>
  94 + <CitySelector ref="citySelectorRef" v-model="form.destinationId" @change="onCityChange" />
  95 + </template>
  96 + </uni-list-item>
  97 +
  98 + <uni-list-item class="select-item" :class="form.includesPackagingFeeName ? 'is-filled' : 'is-empty'" clickable
  99 + @click="openSheet('includesPackagingFee')" :rightText="form.includesPackagingFeeName || '请选择'" showArrow>
  100 + <template v-slot:body>
  101 + <view class="item-title"><text>单价中是否已包含包装费</text></view>
  102 + </template>
  103 + </uni-list-item>
  104 + <uni-list-item class="select-item" :class="form.includesTransportFeeName ? 'is-filled' : 'is-empty'" clickable
  105 + @click="openSheet('includesTransportFee')" :rightText="form.includesTransportFeeName || '请选择'" showArrow>
  106 + <template v-slot:body>
  107 + <view class="item-title"><text>单价中是否已包含运费</text></view>
  108 + </template>
  109 + </uni-list-item>
  110 + <uni-list-item title="需方指定收货人">
  111 + <template v-slot:footer>
  112 + <uni-easyinput v-model="form.designatedConsignee" placeholder="请输入需方指定收货人" :inputBorder="false" />
  113 + </template>
  114 + </uni-list-item>
  115 +
  116 + <uni-list-item class="select-item" :class="form.specialTermsName ? 'is-filled' : 'is-empty'" clickable
  117 + @click="openSheet('specialTerms')" :rightText="form.specialTermsName || '请选择'" showArrow>
  118 + <template v-slot:body>
  119 + <view class="item-title"><text class="required">*</text><text>特别条款要求</text></view>
  120 + </template>
  121 + </uni-list-item>
  122 + <uni-list-item class="select-item" :class="form.executionStandardName ? 'is-filled' : 'is-empty'" clickable
  123 + @click="openSheet('executionStandard')" :rightText="form.executionStandardName || '请选择'" showArrow>
  124 + <template v-slot:body>
  125 + <view class="item-title"><text>执行标准</text></view>
  126 + </template>
  127 + </uni-list-item>
  128 + <uni-list-item v-if="form.executionStandard === 'OTHER'" title="其他">
  129 + <template v-slot:footer>
  130 + <uni-easyinput v-model="form.executionStandardRemarks" placeholder="请输入其他标准备注" :inputBorder="false" />
  131 + </template>
  132 + </uni-list-item>
  133 + <uni-list-item title="特别说明" style="margin-top: 20rpx;">
  134 + <template v-slot:footer>
  135 + <uni-easyinput v-model="form.specialInstructions" placeholder="请输入特别说明" :inputBorder="false" />
  136 + </template>
  137 + </uni-list-item>
  138 + <uni-list-item title="备注">
  139 + <template v-slot:footer>
  140 + <uni-easyinput v-model="form.remarks" placeholder="请输入备注" :inputBorder="false" maxlength="2000" />
  141 + </template>
  142 + </uni-list-item>
  143 +
  144 + <view class="quality">
  145 + <image class="opCollapse" src="/static/images/title.png" />
  146 + <text class="title">具体质量要求</text>
  147 + </view>
  148 + <uni-list-item title="件重条头">
  149 + <template v-slot:footer>
  150 + <uni-easyinput v-model="form.pieceWeightHead" placeholder="请输入" :inputBorder="false" />
  151 + </template>
  152 + </uni-list-item>
  153 + <uni-list-item title="表面">
  154 + <template v-slot:footer>
  155 + <uni-easyinput v-model="form.surface" placeholder="请输入" :inputBorder="false" />
  156 + </template>
  157 + </uni-list-item>
  158 + <uni-list-item title="公差">
  159 + <template v-slot:footer>
  160 + <uni-easyinput v-model="form.tolerance" placeholder="请输入" :inputBorder="false" />
  161 + </template>
  162 + </uni-list-item>
  163 + <uni-list-item title="性能">
  164 + <template v-slot:footer>
  165 + <uni-easyinput v-model="form.performance" placeholder="请输入" :inputBorder="false" />
  166 + </template>
  167 + </uni-list-item>
  168 + <uni-list-item title="成分">
  169 + <template v-slot:footer>
  170 + <uni-easyinput v-model="form.component" placeholder="请输入" :inputBorder="false" />
  171 + </template>
  172 + </uni-list-item>
  173 + <uni-list-item title="包装">
  174 + <template v-slot:footer>
  175 + <uni-easyinput v-model="form.packaging" placeholder="请输入" :inputBorder="false" />
  176 + </template>
  177 + </uni-list-item>
  178 +
  179 + <uni-list-item :title="uploadType === 'formal' ? '正式合同附件' : '标准合同附件'" style="margin-top: 20rpx;">
  180 + <template v-slot:footer>
  181 + <FileUpload v-model="fileInfo" />
  182 + </template>
  183 + </uni-list-item>
  184 + <uni-list-item class="select-item" :class="standardStandardizedName ? 'is-filled' : 'is-empty'" clickable
  185 + @click="openSheet('standardStandardized')" :rightText="standardStandardizedName || '请选择'" showArrow>
  186 + <template v-slot:body>
  187 + <view class="item-title"><text class="required">*</text><text>合同是否规范</text></view>
  188 + </template>
  189 + </uni-list-item>
  190 +
  191 + <view class="footer">
  192 + <div class="total">
  193 + <div class="total-text">合计</div>
  194 + <div class="total-item" style="padding: 20rpx 0;">
  195 + <div class="total-item-text">数量</div>
  196 + <div class="total-item-price">{{ (totalQuantity || 0).toFixed(2) }}kg</div>
  197 + </div>
  198 + </div>
  199 + <button class="btn submit" type="primary" @click="onSubmit">提交</button>
  200 + </view>
  201 + </uni-list>
  202 + </scroll-view>
  203 +
  204 + <SingleSelectSheet :visible.sync="sheet.visible" :title="sheet.title" :options="sheet.options" v-model="sheet.value"
  205 + @confirm="onSheetConfirm" />
  206 + <RelateSelectSheet :visible.sync="relate.visible" :title="relate.title" :source="relate.source"
  207 + :display-fields="relate.display" :multiple="relate.multiple" :row-key="relate.rowKey"
  208 + :selectedKeys.sync="relate.selectedKeys" @confirm="onRelateConfirm" />
  209 + </view>
  210 +</template>
  211 +
  212 +<script>
  213 +import SingleSelectSheet from '@/components/single-select/index.vue'
  214 +import RelateSelectSheet from '@/components/relate-select/index.vue'
  215 +import ProductRel from './productRel.vue'
  216 +import CitySelector from '@/components/city-selector/index.vue'
  217 +import FileUpload from '@/components/file-upload/index.vue'
  218 +import { getContractApi, uploadFormalContract, uploadStandardContract } from '@/api/contract'
  219 +import { getDicByCodes } from '@/utils/dic'
  220 +import { formatCurrencyToChinese } from '@/utils/common'
  221 +import { workshopQueryApi } from '@/api/devManage'
  222 +import { getArea } from '@/api/credit_manage.js'
  223 +
  224 +export default {
  225 + name: 'UploadContractStock',
  226 + components: { SingleSelectSheet, RelateSelectSheet, ProductRel, CitySelector, FileUpload },
  227 + data() {
  228 + return {
  229 + id: '',
  230 + uploadType: 'formal',
  231 + fileInfo: { id: '', name: '' },
  232 + standardStandardized: '',
  233 + standardStandardizedName: '',
  234 + form: {
  235 + id: '',
  236 + code: '',
  237 + supplier: '',
  238 + supplierName: '',
  239 + buyer: '',
  240 + buyerName: '',
  241 + stockUpCompanyId: '',
  242 + stockUpCompanyName: '',
  243 + workshopId: '',
  244 + workshopName: '',
  245 + deptName: '',
  246 + deptId: '',
  247 + region: '',
  248 + regionName: '',
  249 + orderDate: '',
  250 + deliveryDate: '',
  251 + designatedConsignee: '',
  252 + specialTerms: '',
  253 + specialTermsName: '',
  254 + executionStandard: '',
  255 + executionStandardName: '',
  256 + executionStandardRemarks: '',
  257 + includesPackagingFee: false,
  258 + includesPackagingFeeName: '否',
  259 + includesTransportFee: false,
  260 + includesTransportFeeName: '否',
  261 + unit: '元、公斤、元/公斤',
  262 + totalAmountCapital: '',
  263 + depositInfo: '',
  264 + packagingRequirements: '',
  265 + paymentTerms: '',
  266 + transportMode: '',
  267 + destinationId: [],
  268 + destinationLabel: '',
  269 + specialInstructions: '',
  270 + remarks: '',
  271 + pieceWeightHead: '',
  272 + surface: '',
  273 + tolerance: '',
  274 + performance: '',
  275 + component: '',
  276 + packaging: ''
  277 + },
  278 + supplierList: [],
  279 + specialTermsList: [],
  280 + executionStandardList: [],
  281 + yesNoList: [{ label: '是', value: true }, { label: '否', value: false }],
  282 + sheet: { visible: false, title: '请选择', field: '', options: [], value: '' },
  283 + relate: { visible: false, title: '选择', source: '', display: [], multiple: false, rowKey: 'id', selectedKeys: [], fieldKey: '' },
  284 + totalQuantity: 0,
  285 + totalAmountExcludingTax: 0,
  286 + totalAmountIncludingTax: 0,
  287 + productLineList: [],
  288 + newProductLineList: [],
  289 + productList: [],
  290 + regionOptions: [],
  291 + }
  292 + },
  293 + onLoad(query) {
  294 + this.id = (query && query.id) ? query.id : ''
  295 + // this.uploadType = (query && query.uploadType) ? query.uploadType : 'formal'
  296 + },
  297 + created() {
  298 + this.loadSuppliers()
  299 + this.loadExtraOptions()
  300 + this.loadDetail()
  301 + this.loadRegionOptions()
  302 + this.$nextTick(() => {
  303 + if (Array.isArray(this.form.destinationId) && this.form.destinationId.length) {
  304 + this.initDestinationLabel()
  305 + }
  306 + })
  307 + },
  308 + methods: {
  309 + async loadRegionOptions() {
  310 + try {
  311 + const res = await getArea()
  312 + const list = res.data || []
  313 + this.regionOptions = (list || []).map(it => ({ label: it.name || '', value: it.id || '' }))
  314 + } catch (e) {
  315 + this.regionOptions = []
  316 + }
  317 + },
  318 + async loadDetail() {
  319 + if (!this.id) return
  320 + try {
  321 + const res = await getContractApi(this.id)
  322 + const data = res && res.data ? res.data : {}
  323 + const includesPackagingFeeName = data.includesPackagingFeeName || (data.includesPackagingFee ? '是' : '否')
  324 + const includesTransportFeeName = data.includesTransportFeeName || (data.includesTransportFee ? '是' : '否')
  325 + const m = { ...data, includesPackagingFeeName, includesTransportFeeName }
  326 + this.form = {
  327 + ...this.form,
  328 + id: m.id || '',
  329 + code: m.code || '',
  330 + supplier: m.supplier || '',
  331 + supplierName: m.supplierName || '',
  332 + buyer: m.buyer || (m.customer && m.customer.id) || '',
  333 + buyerName: m.buyerName || (m.customer && m.customer.name) || '',
  334 + stockUpCompanyId: m.stockUpCompanyId || '',
  335 + stockUpCompanyName: m.stockUpCompanyName || '',
  336 + deptName: m.deptName || '',
  337 + deptId: m.deptId || '',
  338 + region: m.region || '',
  339 + regionName: m.regionName || '',
  340 + orderDate: m.orderDate || '',
  341 + designatedConsignee: m.designatedConsignee || '',
  342 + specialTerms: m.specialTerms || '',
  343 + specialTermsName: m.specialTermsName || '',
  344 + executionStandard: m.executionStandard || '',
  345 + executionStandardName: m.executionStandardName || '',
  346 + executionStandardRemarks: m.executionStandardRemarks || '',
  347 + includesPackagingFee: !!m.includesPackagingFee,
  348 + includesPackagingFeeName,
  349 + includesTransportFee: !!m.includesTransportFee,
  350 + includesTransportFeeName,
  351 + unit: m.unit || this.form.unit,
  352 + totalAmountCapital: m.totalAmountCapital || '',
  353 + depositInfo: m.depositInfo || '',
  354 + packagingRequirements: m.packagingRequirements || '',
  355 + paymentTerms: m.paymentTerms || '',
  356 + transportMode: m.transportMode || '',
  357 + destinationId: (m.provinceId && m.cityId && m.districtId) ? [m.provinceId, m.cityId, m.districtId] : (Array.isArray(m.destinationId) ? m.destinationId : []),
  358 + destinationLabel: (m.provinceName && m.cityName && m.districtName) ? `${m.provinceName} / ${m.cityName} / ${m.districtName}` : (m.destinationLabel || ''),
  359 + specialInstructions: m.specialInstructions || '',
  360 + remarks: m.remarks || '',
  361 + pieceWeightHead: m.pieceWeightHead || '',
  362 + surface: m.surface || '',
  363 + tolerance: m.tolerance || '',
  364 + performance: m.performance || '',
  365 + component: m.component || '',
  366 + packaging: m.packaging || '',
  367 + workshopId: m.workshopId || '',
  368 + workshopName: m.workshopName || '',
  369 + }
  370 + const fileId = this.uploadType === 'formal' ? m.formalFileId : m.standardFileId
  371 + const fileName = this.uploadType === 'formal' ? m.formalFileName : m.standardFileName
  372 + const standardized = this.uploadType === 'formal' ? m.formalStandardized : m.standardStandardized
  373 + this.fileInfo = { id: fileId || '', name: fileName || '' }
  374 + this.standardStandardized = (standardized === true || standardized === false) ? standardized : ''
  375 + this.standardStandardizedName = (this.standardStandardized === true) ? '是' : (this.standardStandardized === false) ? '否' : ''
  376 + const lines = Array.isArray(m.contractDistributorLineList) ? m.contractDistributorLineList : []
  377 + this.productLineList = lines
  378 + this.onProductsChange(lines)
  379 + } catch (e) { }
  380 + },
  381 + async initDestinationLabel() {
  382 + const comp = this.$refs.citySelectorRef
  383 + if (comp && typeof comp.getLabel === 'function') {
  384 + const label = await comp.getLabel()
  385 + this.form.destinationLabel = label || ''
  386 + }
  387 + },
  388 + openCitySelector() {
  389 + this.$refs.citySelectorRef && this.$refs.citySelectorRef.open()
  390 + },
  391 + onCityChange(payload) {
  392 + const label = payload && payload.label != null ? payload.label : ''
  393 + this.form.destinationLabel = label
  394 + },
  395 + onProductsChange(products) {
  396 + const list = Array.isArray(products) ? products : []
  397 + this.newProductLineList = list
  398 + const sumQ = list.reduce((acc, it) => acc + (parseFloat(it.quantity) || 0), 0)
  399 + const sumE = list.reduce((acc, it) => acc + (parseFloat(it.amountExcludingTax) || 0), 0)
  400 + const sumT = list.reduce((acc, it) => acc + (parseFloat(it.totalAmount) || 0), 0)
  401 + this.totalQuantity = sumQ
  402 + this.totalAmountExcludingTax = sumE
  403 + this.totalAmountIncludingTax = sumT
  404 + this.form.totalAmountCapital = formatCurrencyToChinese(sumT)
  405 + },
  406 + async loadSuppliers() {
  407 + try {
  408 + const results = await getDicByCodes(['SUPPLIER'])
  409 + const items = results && results.SUPPLIER && results.SUPPLIER.data ? results.SUPPLIER.data : []
  410 + this.supplierList = items.map(it => ({ label: it.name, value: it.code }))
  411 + } catch (e) { this.supplierList = [] }
  412 + },
  413 + async loadExtraOptions() {
  414 + try {
  415 + const results = await getDicByCodes(['CONDITIONS_REQUIRED', 'APPLICABLE_STANDARD', 'CONTRACT_PRODUCT'])
  416 + const c1 = results && results.CONDITIONS_REQUIRED && results.CONDITIONS_REQUIRED.data ? results.CONDITIONS_REQUIRED.data : []
  417 + const c2 = results && results.APPLICABLE_STANDARD && results.APPLICABLE_STANDARD.data ? results.APPLICABLE_STANDARD.data : []
  418 + const c3 = results && results.CONTRACT_PRODUCT && results.CONTRACT_PRODUCT.data ? results.CONTRACT_PRODUCT.data : []
  419 + this.specialTermsList = c1.map(it => ({ label: it.name, value: it.code }))
  420 + this.executionStandardList = c2.map(it => ({ label: it.name, value: it.code }))
  421 + this.productList = c3.map(it => ({ label: it.name, value: it.code }))
  422 + } catch (e) {
  423 + this.specialTermsList = []
  424 + this.executionStandardList = []
  425 + this.productList = []
  426 + }
  427 + },
  428 + displayLabel(field) {
  429 + const m = this.form
  430 + const map = { supplierName: '请选择供方', buyerName: '请选择需方', workshopName: '请选择生产厂', regionName: '请选择区域' }
  431 + const val = m[field]
  432 + return val ? String(val) : map[field]
  433 + },
  434 + async openSheet(field) {
  435 + if (field === 'standardStandardized') {
  436 + const options = this.yesNoList
  437 + const current = this.standardStandardized
  438 + const match = (options || []).find(o => String(o.value) === String(current) || String(o.label) === String(current))
  439 + this.sheet = { ...this.sheet, visible: true, title: '合同是否规范', options, field, value: match ? match.value : '' }
  440 + return
  441 + }
  442 + const setSheet = (title, options) => {
  443 + const current = this.form[field]
  444 + const match = (options || []).find(o => String(o.label) === String(current) || String(o.value) === String(current))
  445 + this.sheet = { ...this.sheet, visible: true, title, options, field, value: match ? match.value : '' }
  446 + }
  447 + if (field === 'workshopId') {
  448 + const res = await workshopQueryApi({ pageIndex: 1, pageSize: 9999 })
  449 + const _data = res.data || {}
  450 + const list = _data.datas || (Array.isArray(_data) ? _data : [])
  451 + const opts = (list || []).map(it => ({
  452 + label: it.name,
  453 + value: it.id
  454 + }))
  455 + setSheet('生产厂', opts)
  456 + } else if (field === 'supplier') {
  457 + setSheet('供方', this.supplierList)
  458 + } else if (field === 'specialTerms') {
  459 + setSheet('特别条款要求', this.specialTermsList)
  460 + } else if (field === 'executionStandard') {
  461 + setSheet('执行标准', this.executionStandardList)
  462 + } else if (field === 'includesPackagingFee') {
  463 + setSheet('单价中是否已包含包装费', this.yesNoList)
  464 + } else if (field === 'includesTransportFee') {
  465 + setSheet('单价中是否已包含运费', this.yesNoList)
  466 + } else if (field === 'region') {
  467 + setSheet('区域', this.regionOptions)
  468 + }
  469 + },
  470 + onSheetConfirm({ value, label }) {
  471 + const field = this.sheet.field
  472 + if (!field) return
  473 + const v = (value === undefined || value === null) ? '' : value
  474 + if (field === 'standardStandardized') {
  475 + this.standardStandardized = v
  476 + this.standardStandardizedName = label || ''
  477 + return
  478 + }
  479 + this.form[field] = v
  480 + this.form[field + 'Name'] = label || ''
  481 + },
  482 + openRelate(fieldKey) {
  483 + let config = {}
  484 + if (fieldKey === 'buyer') {
  485 + config = { title: '需方', source: 'customer', rowKey: 'id', multiple: false, display: [{ label: '名称', field: 'name' }, { label: '编号', field: 'code' }, { label: '状态', field: 'available', format: v => (v ? '启用' : '停用') }] }
  486 + } else if (fieldKey === 'stockUpCompanyId') {
  487 + config = { title: '备货单位/人(生产标准)', source: 'customer', rowKey: 'id', multiple: false, display: [{ label: '姓名', field: 'name' }, { label: '编号', field: 'code' }, { label: '状态', field: 'available', format: v => (v ? '启用' : '停用') }] }
  488 + }
  489 + const selectedKeys = this.form[fieldKey] ? [this.form[fieldKey]] : []
  490 + this.sheet.visible = false
  491 + this.relate = { ...this.relate, title: config.title, source: config.source, display: config.display, multiple: config.multiple, rowKey: config.rowKey, selectedKeys, fieldKey }
  492 + this.$nextTick(() => { this.relate.visible = true })
  493 + },
  494 + onRelateConfirm({ items }) {
  495 + const _fieldKey = this.relate.fieldKey
  496 + const first = (items && items.length > 0) ? items[0] : null
  497 + this.form[_fieldKey] = (first && first.id) ? first.id : ''
  498 + if (_fieldKey === 'stockUpCompanyId') {
  499 + this.form.stockUpCompanyName = (first && first.name) ? first.name : ''
  500 + } else {
  501 + this.form[_fieldKey + 'Name'] = (first && first.name) ? first.name : ''
  502 + }
  503 + },
  504 + validateRequired() {
  505 + const checks = [
  506 + { key: 'code', label: '编号' },
  507 + { key: 'supplier', label: '供方' },
  508 + { key: 'buyer', label: '需方' },
  509 + { key: 'orderDate', label: '订货日期' },
  510 + { key: 'unit', label: '单位' },
  511 + { key: 'workshopId', label: '生产厂' },
  512 + { key: 'specialTerms', label: '特别条款要求' },
  513 + ]
  514 + for (const it of checks) {
  515 + const val = this.form[it.key]
  516 + const empty = (val === undefined || val === null || (typeof val === 'string' && val.trim() === '') || (typeof val === 'number' && isNaN(val)))
  517 + if (empty) { uni.showToast({ title: `请先选择${it.label}`, icon: 'none' }); return false }
  518 + }
  519 + if (!this.$refs.productRel.validate()) return false
  520 + const list = Array.isArray(this.newProductLineList) ? this.newProductLineList : []
  521 + if (list.length === 0) {
  522 + uni.showToast({ title: '请至少添加一条产品明细', icon: 'none' }); return false
  523 + }
  524 + const strEmpty = (v) => (v === undefined || v === null || (typeof v === 'string' && v.trim() === ''))
  525 + const numEmpty = (v) => (v === undefined || v === null || v === '' || (typeof v === 'number' && isNaN(v)))
  526 + for (const [idx, it] of list.entries()) {
  527 + if (
  528 + strEmpty(it.productName) ||
  529 + strEmpty(it.industry) ||
  530 + strEmpty(it.quality) ||
  531 + strEmpty(it.brand) ||
  532 + numEmpty(it.quantity) ||
  533 + strEmpty(it.deliveryDate)
  534 + ) {
  535 + uni.showToast({ title: `第${idx + 1}条明细未完整填写`, icon: 'none' }); return false
  536 + }
  537 + }
  538 + return true
  539 + },
  540 + async onSubmit() {
  541 + if (!this.fileInfo.id) {
  542 + uni.showToast({ title: '请上传合同附件', icon: 'error' })
  543 + return
  544 + }
  545 + if (!this.standardStandardized && this.standardStandardized !== false) {
  546 + uni.showToast({ title: '请选择合同是否规范', icon: 'error' })
  547 + return
  548 + }
  549 + if (!this.validateRequired()) return
  550 + const confirmRes = await new Promise(resolve => {
  551 + uni.showModal({
  552 + title: '确认提交',
  553 + content: this.uploadType === 'formal' ? '确定提交正式合同吗?' : '确定提交标准合同吗?',
  554 + confirmText: '确定',
  555 + cancelText: '取消',
  556 + success: resolve
  557 + })
  558 + })
  559 + if (!(confirmRes && confirmRes.confirm)) return
  560 + const clean = (obj) => {
  561 + const out = {}
  562 + Object.keys(obj || {}).forEach(k => {
  563 + const v = obj[k]
  564 + const isEmptyString = typeof v === 'string' && v.trim() === ''
  565 + const isUndef = v === undefined || v === null
  566 + const isNaNNumber = typeof v === 'number' && isNaN(v)
  567 + if (!(isEmptyString || isUndef || isNaNNumber)) out[k] = v
  568 + })
  569 + return out
  570 + }
  571 + const lines = (this.newProductLineList || []).map(it => clean(it))
  572 + const { destinationLabel, destinationId, ...formForSubmit } = this.form
  573 + const destination = destinationId && destinationId.length > 0 ? destinationId[destinationId.length - 1] : ''
  574 + const fileIdKey = this.uploadType === 'formal' ? 'formalFileId' : 'standardFileId'
  575 + const fileNameKey = this.uploadType === 'formal' ? 'formalFileName' : 'standardFileName'
  576 + const standardizedKey = this.uploadType === 'formal' ? 'formalStandardized' : 'standardStandardized'
  577 + const payload = clean({
  578 + ...formForSubmit,
  579 + id: this.form.id,
  580 + destination,
  581 + type: 'DIST_STOCK_CONTRACT',
  582 + totalQuantity: this.totalQuantity,
  583 + totalAmountExcludingTax: this.totalAmountExcludingTax,
  584 + totalAmountIncludingTax: this.totalAmountIncludingTax,
  585 + contractDistributorLineList: lines,
  586 + [fileIdKey]: this.fileInfo.id,
  587 + [fileNameKey]: this.fileInfo.name,
  588 + [standardizedKey]: this.standardStandardized,
  589 + })
  590 + const api = this.uploadType === 'formal' ? uploadFormalContract : uploadStandardContract
  591 + try {
  592 + await uploadFormalContract(payload)
  593 + uni.showToast({ title: '提交成功', icon: 'none' })
  594 + setTimeout(() => { uni.redirectTo({ url: '/pages/contract_stock/index' }) }, 400)
  595 + } catch (e) {
  596 + uni.showToast({ title: e.msg || '提交失败', icon: 'none' })
  597 + }
  598 + }
  599 + }
  600 +}
  601 +</script>
  602 +
  603 +<style lang="scss" scoped>
  604 +.total {
  605 + .total-text {
  606 + font-weight: 600;
  607 + font-size: 32rpx;
  608 + color: rgba(0, 0, 0, 0.9);
  609 + padding-bottom: 28rpx;
  610 + border-bottom: 2rpx solid #E7E7E7;
  611 + }
  612 +
  613 + .total-item {
  614 + display: flex;
  615 + align-items: center;
  616 + }
  617 +
  618 + .total-item-text {
  619 + font-weight: 400;
  620 + font-size: 28rpx;
  621 + color: rgba(0, 0, 0, 0.6);
  622 + line-height: 32rpx;
  623 + width: 240rpx;
  624 + padding: 12rpx 0;
  625 + }
  626 +
  627 + .total-item-price {
  628 + font-weight: 600;
  629 + font-size: 32rpx;
  630 + color: rgba(0, 0, 0, 0.9);
  631 + line-height: 32rpx;
  632 + }
  633 +
  634 + .text-red {
  635 + color: #D54941;
  636 + }
  637 +}
  638 +
  639 +.page {
  640 + display: flex;
  641 + flex-direction: column;
  642 + height: 100%;
  643 +}
  644 +
  645 +.scroll {
  646 + flex: 1;
  647 + padding: 12rpx 0 392rpx !important;
  648 +}
  649 +
  650 +.footer {
  651 + z-index: 2;
  652 + position: fixed;
  653 + left: 0;
  654 + right: 0;
  655 + bottom: 0;
  656 + padding: 32rpx;
  657 + padding-bottom: calc(32rpx + env(safe-area-inset-bottom));
  658 + background: #fff;
  659 + box-shadow: 0 -8rpx 24rpx rgba(0, 0, 0, 0.06);
  660 +}
  661 +
  662 +.footer .btn {
  663 + height: 80rpx;
  664 + line-height: 80rpx;
  665 + border-radius: 12rpx;
  666 + font-size: 32rpx;
  667 +}
  668 +
  669 +.footer .submit {
  670 + background: $theme-primary;
  671 + color: #fff;
  672 +}
  673 +
  674 +.quality {
  675 + background-color: #fff;
  676 + display: flex;
  677 + align-items: center;
  678 + padding: 24rpx 32rpx;
  679 + border-bottom: 1rpx solid #f0f0f0;
  680 + margin-top: 20rpx;
  681 +
  682 + .title {
  683 + font-size: 32rpx;
  684 + color: rgba(0, 0, 0, 0.9);
  685 + font-weight: 600;
  686 + }
  687 +
  688 + .opCollapse {
  689 + color: rgba(0, 0, 0, 0.6);
  690 + width: 32rpx;
  691 + height: 28rpx;
  692 + margin-right: 16rpx;
  693 + }
  694 +}
  695 +
  696 +::v-deep .uni-list {
  697 + background: transparent;
  698 +}
  699 +
  700 +::v-deep .uni-list .uni-easyinput .uni-input-input {
  701 + color: rgba(0, 0, 0, 0.9);
  702 +}
  703 +
  704 +::v-deep .uni-list .uni-input-placeholder {
  705 + z-index: 1;
  706 +}
  707 +
  708 +::v-deep .uni-list .uni-input-input {
  709 + background-color: #ffffff;
  710 +}
  711 +
  712 +::v-deep .uni-list-item__extra-text {
  713 + font-size: 32rpx;
  714 +}
  715 +
  716 +::v-deep .uni-list-item__content-title {
  717 + font-size: 32rpx;
  718 + color: rgba(0, 0, 0, 0.9);
  719 +}
  720 +
  721 +::v-deep .uni-list-item__container {
  722 + padding: 32rpx;
  723 +}
  724 +
  725 +::v-deep .uni-list-item__container .uni-easyinput__placeholder-class {
  726 + font-size: 32rpx;
  727 + color: rgba(0, 0, 0, 0.4);
  728 +}
  729 +
  730 +::v-deep .uni-list-item__container .uni-easyinput__content {
  731 + border: none;
  732 + background-color: #ffffff !important;
  733 +}
  734 +
  735 +::v-deep .uni-list-item__container .uni-easyinput__content-input {
  736 + padding-left: 0 !important;
  737 + height: 48rpx;
  738 + line-height: 48rpx;
  739 + font-size: 32rpx;
  740 +}
  741 +
  742 +::v-deep .uni-list-item__container .item-title,
  743 +::v-deep .uni-list-item__container .uni-list-item__content {
  744 + flex: none;
  745 + min-height: 48rpx;
  746 + line-height: 48rpx;
  747 + font-size: 32rpx;
  748 + position: relative;
  749 + width: 210rpx;
  750 + margin-right: 32rpx;
  751 + color: rgba(0, 0, 0, 0.9);
  752 +}
  753 +
  754 +::v-deep .uni-list-item__container .item-title .required {
  755 + color: red;
  756 + position: absolute;
  757 + top: 50%;
  758 + transform: translateY(-50%);
  759 + left: -16rpx;
  760 +}
  761 +
  762 +::v-deep .uni-list-item.select-item.is-empty .uni-list-item__extra-text {
  763 + color: rgba(0, 0, 0, 0.4) !important;
  764 +}
  765 +
  766 +::v-deep .uni-list-item.select-item.is-filled .uni-list-item__extra-text {
  767 + color: rgba(0, 0, 0, 0.9) !important;
  768 +}
  769 +</style>
@@ -372,6 +372,13 @@ export default { @@ -372,6 +372,13 @@ export default {
372 uploadContract(id, type = 'formal') { 372 uploadContract(id, type = 'formal') {
373 if (!id) return 373 if (!id) return
374 this.uploadId = id 374 this.uploadId = id
  375 + if (type === 'standard' && this.detail?.canEdit) {
  376 + const query = `?id=${encodeURIComponent(id)}&uploadType=${encodeURIComponent(type)}`
  377 + uni.navigateTo({
  378 + url: '/pages/contract_unplan/uploadStandard' + query
  379 + })
  380 + return
  381 + }
375 this.uploadType = type 382 this.uploadType = type
376 this.$refs.uploadPopup.open() 383 this.$refs.uploadPopup.open()
377 }, 384 },
  1 +<template>
  2 + <view class="page">
  3 + <scroll-view class="scroll" scroll-y>
  4 + <uni-list>
  5 + <uni-list-item title="编号">
  6 + <template v-slot:footer>
  7 + <uni-easyinput v-model="form.code" :inputBorder="false" disabled />
  8 + </template>
  9 + </uni-list-item>
  10 +
  11 + <uni-list-item class="select-item" :class="form.supplier ? 'is-filled' : 'is-empty'" clickable
  12 + @click="openSheet('supplier')" :rightText="displayLabel('supplierName')" showArrow>
  13 + <template v-slot:body>
  14 + <view class="item-title"><text class="required">*</text><text>供方</text></view>
  15 + </template>
  16 + </uni-list-item>
  17 +
  18 + <uni-list-item class="select-item" :class="form.buyer ? 'is-filled' : 'is-empty'" clickable
  19 + @click="openRelate('buyer')" :rightText="form.buyerName || '请选择需方'" showArrow>
  20 + <template v-slot:body>
  21 + <view class="item-title"><text class="required">*</text><text>需方</text></view>
  22 + </template>
  23 + </uni-list-item>
  24 +
  25 + <uni-list-item class="select-item" :class="form.stockUpCompanyId ? 'is-filled' : 'is-empty'" clickable
  26 + @click="openRelate('stockUpCompanyId')" :rightText="form.stockUpCompanyName || '请选择备货单位'" showArrow>
  27 + <template v-slot:body>
  28 + <view class="item-title"><text class="required">*</text><text>备货单位/人(生产标准)</text></view>
  29 + </template>
  30 + </uni-list-item>
  31 +
  32 + <uni-list-item class="select-item" :class="form.workshopId ? 'is-filled' : 'is-empty'" clickable
  33 + @click="openSheet('workshopId')" :rightText="form.workshopName || '请选择生产厂'" showArrow>
  34 + <template v-slot:body>
  35 + <view class="item-title"><text class="required">*</text><text>生产厂</text></view>
  36 + </template>
  37 + </uni-list-item>
  38 +
  39 + <uni-list-item title="订货日期">
  40 + <template v-slot:footer>
  41 + <uni-datetime-picker type="date" v-model="form.orderDate" />
  42 + </template>
  43 + </uni-list-item>
  44 +
  45 + <uni-list-item title="单位">
  46 + <template v-slot:footer>
  47 + <uni-easyinput v-model="form.unit" :inputBorder="false" disabled />
  48 + </template>
  49 + </uni-list-item>
  50 + <uni-list-item title="办事处">
  51 + <template v-slot:footer>
  52 + <uni-easyinput v-model="form.deptName" :inputBorder="false" disabled placeholder="自动获取" />
  53 + </template>
  54 + </uni-list-item>
  55 + <uni-list-item class="select-item" :class="form.region ? 'is-filled' : 'is-empty'" clickable
  56 + @click="openSheet('region')" :rightText="displayLabel('regionName')" showArrow>
  57 + <template v-slot:body>
  58 + <view class="item-title"><text class="required">*</text><text>区域</text></view>
  59 + </template>
  60 + </uni-list-item>
  61 +
  62 + <ProductRel ref="productRel" mode="add" :deliveryDate="form.orderDate" :deliveryDateBase="form.deliveryDate"
  63 + :list="productLineList" @change="onProductsChange" :options="productList" />
  64 +
  65 + <uni-list-item title="合计人民币金额(大写)">
  66 + <template v-slot:footer>
  67 + <uni-easyinput v-model="form.totalAmountCapital" placeholder="" :inputBorder="false" disabled />
  68 + </template>
  69 + </uni-list-item>
  70 + <uni-list-item title="交付定金、数额、时间">
  71 + <template v-slot:footer>
  72 + <uni-easyinput v-model="form.depositInfo" placeholder="请输入交付定金、数额、时间" :inputBorder="false" />
  73 + </template>
  74 + </uni-list-item>
  75 + <uni-list-item title="包装要求">
  76 + <template v-slot:footer>
  77 + <uni-easyinput v-model="form.packagingRequirements" placeholder="请输入包装要求" :inputBorder="false" />
  78 + </template>
  79 + </uni-list-item>
  80 + <uni-list-item title="付款方式、付款期限">
  81 + <template v-slot:footer>
  82 + <uni-easyinput v-model="form.paymentTerms" placeholder="请输入付款方式、付款期限" :inputBorder="false" />
  83 + </template>
  84 + </uni-list-item>
  85 + <uni-list-item title="运输方式">
  86 + <template v-slot:footer>
  87 + <uni-easyinput v-model="form.transportMode" placeholder="请输入运输方式" :inputBorder="false" />
  88 + </template>
  89 + </uni-list-item>
  90 + <uni-list-item class="select-item"
  91 + :class="(Array.isArray(form.destinationId) && form.destinationId.length) ? 'is-filled' : 'is-empty'" clickable
  92 + @click="openCitySelector" :rightText="form.destinationLabel || '请选择'" showArrow>
  93 + <template v-slot:body>
  94 + <view class="item-title"><text>目的地</text></view>
  95 + <CitySelector ref="citySelectorRef" v-model="form.destinationId" @change="onCityChange" />
  96 + </template>
  97 + </uni-list-item>
  98 +
  99 + <uni-list-item class="select-item" :class="form.includesPackagingFeeName ? 'is-filled' : 'is-empty'" clickable
  100 + @click="openSheet('includesPackagingFee')" :rightText="form.includesPackagingFeeName || '请选择'" showArrow>
  101 + <template v-slot:body>
  102 + <view class="item-title"><text>单价中是否已包含包装费</text></view>
  103 + </template>
  104 + </uni-list-item>
  105 + <uni-list-item class="select-item" :class="form.includesTransportFeeName ? 'is-filled' : 'is-empty'" clickable
  106 + @click="openSheet('includesTransportFee')" :rightText="form.includesTransportFeeName || '请选择'" showArrow>
  107 + <template v-slot:body>
  108 + <view class="item-title"><text>单价中是否已包含运费</text></view>
  109 + </template>
  110 + </uni-list-item>
  111 + <uni-list-item title="需方指定收货人">
  112 + <template v-slot:footer>
  113 + <uni-easyinput v-model="form.designatedConsignee" placeholder="请输入需方指定收货人" :inputBorder="false" />
  114 + </template>
  115 + </uni-list-item>
  116 +
  117 + <uni-list-item class="select-item" :class="form.specialTermsName ? 'is-filled' : 'is-empty'" clickable
  118 + @click="openSheet('specialTerms')" :rightText="form.specialTermsName || '请选择'" showArrow>
  119 + <template v-slot:body>
  120 + <view class="item-title"><text class="required">*</text><text>特别条款要求</text></view>
  121 + </template>
  122 + </uni-list-item>
  123 + <uni-list-item class="select-item" :class="form.executionStandardName ? 'is-filled' : 'is-empty'" clickable
  124 + @click="openSheet('executionStandard')" :rightText="form.executionStandardName || '请选择'" showArrow>
  125 + <template v-slot:body>
  126 + <view class="item-title"><text>执行标准</text></view>
  127 + </template>
  128 + </uni-list-item>
  129 + <uni-list-item v-if="form.executionStandard === 'OTHER'" title="其他">
  130 + <template v-slot:footer>
  131 + <uni-easyinput v-model="form.executionStandardRemarks" placeholder="请输入其他标准备注" :inputBorder="false" />
  132 + </template>
  133 + </uni-list-item>
  134 + <uni-list-item title="特别说明" style="margin-top: 20rpx;">
  135 + <template v-slot:footer>
  136 + <uni-easyinput v-model="form.specialInstructions" placeholder="请输入特别说明" :inputBorder="false" />
  137 + </template>
  138 + </uni-list-item>
  139 + <uni-list-item title="备注">
  140 + <template v-slot:footer>
  141 + <uni-easyinput v-model="form.remarks" placeholder="请输入备注" :inputBorder="false" maxlength="2000" />
  142 + </template>
  143 + </uni-list-item>
  144 +
  145 + <view class="quality">
  146 + <image class="opCollapse" src="/static/images/title.png" />
  147 + <text class="title">具体质量要求</text>
  148 + </view>
  149 + <uni-list-item title="件重条头">
  150 + <template v-slot:footer>
  151 + <uni-easyinput v-model="form.pieceWeightHead" placeholder="请输入" :inputBorder="false" />
  152 + </template>
  153 + </uni-list-item>
  154 + <uni-list-item title="表面">
  155 + <template v-slot:footer>
  156 + <uni-easyinput v-model="form.surface" placeholder="请输入" :inputBorder="false" />
  157 + </template>
  158 + </uni-list-item>
  159 + <uni-list-item title="公差">
  160 + <template v-slot:footer>
  161 + <uni-easyinput v-model="form.tolerance" placeholder="请输入" :inputBorder="false" />
  162 + </template>
  163 + </uni-list-item>
  164 + <uni-list-item title="性能">
  165 + <template v-slot:footer>
  166 + <uni-easyinput v-model="form.performance" placeholder="请输入" :inputBorder="false" />
  167 + </template>
  168 + </uni-list-item>
  169 + <uni-list-item title="成分">
  170 + <template v-slot:footer>
  171 + <uni-easyinput v-model="form.component" placeholder="请输入" :inputBorder="false" />
  172 + </template>
  173 + </uni-list-item>
  174 + <uni-list-item title="包装">
  175 + <template v-slot:footer>
  176 + <uni-easyinput v-model="form.packaging" placeholder="请输入" :inputBorder="false" />
  177 + </template>
  178 + </uni-list-item>
  179 +
  180 + <uni-list-item :title="uploadType === 'formal' ? '正式合同附件' : '标准合同附件'" style="margin-top: 20rpx;">
  181 + <template v-slot:footer>
  182 + <FileUpload v-model="fileInfo" />
  183 + </template>
  184 + </uni-list-item>
  185 + <uni-list-item class="select-item" :class="standardStandardizedName ? 'is-filled' : 'is-empty'" clickable
  186 + @click="openSheet('standardStandardized')" :rightText="standardStandardizedName || '请选择'" showArrow>
  187 + <template v-slot:body>
  188 + <view class="item-title"><text class="required">*</text><text>合同是否规范</text></view>
  189 + </template>
  190 + </uni-list-item>
  191 +
  192 + <view class="footer">
  193 + <div class="total">
  194 + <div class="total-text">合计</div>
  195 + <div class="total-item" style="padding: 20rpx 0;">
  196 + <div class="total-item-text">数量</div>
  197 + <div class="total-item-price">{{ (totalQuantity || 0).toFixed(2) }}kg</div>
  198 + </div>
  199 + </div>
  200 + <button class="btn submit" type="primary" @click="onSubmit">提交</button>
  201 + </view>
  202 + </uni-list>
  203 + </scroll-view>
  204 +
  205 + <SingleSelectSheet :visible.sync="sheet.visible" :title="sheet.title" :options="sheet.options" v-model="sheet.value"
  206 + @confirm="onSheetConfirm" />
  207 + <RelateSelectSheet :visible.sync="relate.visible" :title="relate.title" :source="relate.source"
  208 + :display-fields="relate.display" :multiple="relate.multiple" :row-key="relate.rowKey"
  209 + :selectedKeys.sync="relate.selectedKeys" @confirm="onRelateConfirm" />
  210 + </view>
  211 +</template>
  212 +
  213 +<script>
  214 +import SingleSelectSheet from '@/components/single-select/index.vue'
  215 +import RelateSelectSheet from '@/components/relate-select/index.vue'
  216 +import ProductRel from './productRel.vue'
  217 +import CitySelector from '@/components/city-selector/index.vue'
  218 +import FileUpload from '@/components/file-upload/index.vue'
  219 +import { getContractApi, uploadFormalContract, uploadStandardContract } from '@/api/contract'
  220 +import { getDicByCodes } from '@/utils/dic'
  221 +import { formatCurrencyToChinese } from '@/utils/common'
  222 +import { workshopQueryApi } from '@/api/devManage'
  223 +import { getArea } from '@/api/credit_manage.js'
  224 +
  225 +export default {
  226 + name: 'UploadContractUnplan',
  227 + components: { SingleSelectSheet, RelateSelectSheet, ProductRel, CitySelector, FileUpload },
  228 + data() {
  229 + return {
  230 + id: '',
  231 + uploadType: 'formal',
  232 + fileInfo: { id: '', name: '' },
  233 + standardStandardized: '',
  234 + standardStandardizedName: '',
  235 + form: {
  236 + id: '',
  237 + code: '',
  238 + supplier: '',
  239 + supplierName: '',
  240 + buyer: '',
  241 + buyerName: '',
  242 + stockUpCompanyId: '',
  243 + stockUpCompanyName: '',
  244 + workshopId: '',
  245 + workshopName: '',
  246 + deptName: '',
  247 + deptId: '',
  248 + region: '',
  249 + regionName: '',
  250 + orderDate: '',
  251 + deliveryDate: '',
  252 + designatedConsignee: '',
  253 + specialTerms: '',
  254 + specialTermsName: '',
  255 + executionStandard: '',
  256 + executionStandardName: '',
  257 + executionStandardRemarks: '',
  258 + includesPackagingFee: false,
  259 + includesPackagingFeeName: '否',
  260 + includesTransportFee: false,
  261 + includesTransportFeeName: '否',
  262 + unit: '元、公斤、元/公斤',
  263 + totalAmountCapital: '',
  264 + depositInfo: '',
  265 + packagingRequirements: '',
  266 + paymentTerms: '',
  267 + transportMode: '',
  268 + destinationId: [],
  269 + destinationLabel: '',
  270 + specialInstructions: '',
  271 + remarks: '',
  272 + pieceWeightHead: '',
  273 + surface: '',
  274 + tolerance: '',
  275 + performance: '',
  276 + component: '',
  277 + packaging: ''
  278 + },
  279 + supplierList: [],
  280 + specialTermsList: [],
  281 + executionStandardList: [],
  282 + yesNoList: [{ label: '是', value: true }, { label: '否', value: false }],
  283 + sheet: { visible: false, title: '请选择', field: '', options: [], value: '' },
  284 + relate: { visible: false, title: '选择', source: '', display: [], multiple: false, rowKey: 'id', selectedKeys: [], fieldKey: '' },
  285 + totalQuantity: 0,
  286 + totalAmountExcludingTax: 0,
  287 + totalAmountIncludingTax: 0,
  288 + productLineList: [],
  289 + newProductLineList: [],
  290 + productList: [],
  291 + regionOptions: [],
  292 + }
  293 + },
  294 + onLoad(query) {
  295 + this.id = (query && query.id) ? query.id : ''
  296 + this.uploadType = (query && query.uploadType) ? query.uploadType : 'formal'
  297 + },
  298 + created() {
  299 + this.loadSuppliers()
  300 + this.loadExtraOptions()
  301 + this.loadDetail()
  302 + this.loadRegionOptions()
  303 + this.$nextTick(() => {
  304 + if (Array.isArray(this.form.destinationId) && this.form.destinationId.length) {
  305 + this.initDestinationLabel()
  306 + }
  307 + })
  308 + },
  309 + methods: {
  310 + async loadRegionOptions() {
  311 + try {
  312 + const res = await getArea()
  313 + const list = res.data || []
  314 + this.regionOptions = (list || []).map(it => ({ label: it.name || '', value: it.id || '' }))
  315 + } catch (e) {
  316 + this.regionOptions = []
  317 + }
  318 + },
  319 + async loadDetail() {
  320 + if (!this.id) return
  321 + try {
  322 + const res = await getContractApi(this.id)
  323 + const data = res && res.data ? res.data : {}
  324 + const includesPackagingFeeName = data.includesPackagingFeeName || (data.includesPackagingFee ? '是' : '否')
  325 + const includesTransportFeeName = data.includesTransportFeeName || (data.includesTransportFee ? '是' : '否')
  326 + const m = { ...data, includesPackagingFeeName, includesTransportFeeName }
  327 + this.form = {
  328 + ...this.form,
  329 + id: m.id || '',
  330 + code: m.code || '',
  331 + supplier: m.supplier || '',
  332 + supplierName: m.supplierName || '',
  333 + buyer: m.buyer || (m.customer && m.customer.id) || '',
  334 + buyerName: m.buyerName || (m.customer && m.customer.name) || '',
  335 + stockUpCompanyId: m.stockUpCompanyId || '',
  336 + stockUpCompanyName: m.stockUpCompanyName || '',
  337 + deptName: m.deptName || '',
  338 + deptId: m.deptId || '',
  339 + region: m.region || '',
  340 + regionName: m.regionName || '',
  341 + orderDate: m.orderDate || '',
  342 + designatedConsignee: m.designatedConsignee || '',
  343 + specialTerms: m.specialTerms || '',
  344 + specialTermsName: m.specialTermsName || '',
  345 + executionStandard: m.executionStandard || '',
  346 + executionStandardName: m.executionStandardName || '',
  347 + executionStandardRemarks: m.executionStandardRemarks || '',
  348 + includesPackagingFee: !!m.includesPackagingFee,
  349 + includesPackagingFeeName,
  350 + includesTransportFee: !!m.includesTransportFee,
  351 + includesTransportFeeName,
  352 + unit: m.unit || this.form.unit,
  353 + totalAmountCapital: m.totalAmountCapital || '',
  354 + depositInfo: m.depositInfo || '',
  355 + packagingRequirements: m.packagingRequirements || '',
  356 + paymentTerms: m.paymentTerms || '',
  357 + transportMode: m.transportMode || '',
  358 + destinationId: (m.provinceId && m.cityId && m.districtId) ? [m.provinceId, m.cityId, m.districtId] : (Array.isArray(m.destinationId) ? m.destinationId : []),
  359 + destinationLabel: (m.provinceName && m.cityName && m.districtName) ? `${m.provinceName} / ${m.cityName} / ${m.districtName}` : (m.destinationLabel || ''),
  360 + specialInstructions: m.specialInstructions || '',
  361 + remarks: m.remarks || '',
  362 + pieceWeightHead: m.pieceWeightHead || '',
  363 + surface: m.surface || '',
  364 + tolerance: m.tolerance || '',
  365 + performance: m.performance || '',
  366 + component: m.component || '',
  367 + packaging: m.packaging || '',
  368 + workshopId: m.workshopId || '',
  369 + workshopName: m.workshopName || '',
  370 + }
  371 + const fileId = this.uploadType === 'formal' ? m.formalFileId : m.standardFileId
  372 + const fileName = this.uploadType === 'formal' ? m.formalFileName : m.standardFileName
  373 + const standardized = this.uploadType === 'formal' ? m.formalStandardized : m.standardStandardized
  374 + this.fileInfo = { id: fileId || '', name: fileName || '' }
  375 + this.standardStandardized = (standardized === true || standardized === false) ? standardized : ''
  376 + this.standardStandardizedName = (this.standardStandardized === true) ? '是' : (this.standardStandardized === false) ? '否' : ''
  377 + const lines = Array.isArray(m.contractDistributorLineList) ? m.contractDistributorLineList : []
  378 + this.productLineList = lines
  379 + this.onProductsChange(lines)
  380 + } catch (e) { }
  381 + },
  382 + async initDestinationLabel() {
  383 + const comp = this.$refs.citySelectorRef
  384 + if (comp && typeof comp.getLabel === 'function') {
  385 + const label = await comp.getLabel()
  386 + this.form.destinationLabel = label || ''
  387 + }
  388 + },
  389 + openCitySelector() {
  390 + this.$refs.citySelectorRef && this.$refs.citySelectorRef.open()
  391 + },
  392 + onCityChange(payload) {
  393 + const label = payload && payload.label != null ? payload.label : ''
  394 + this.form.destinationLabel = label
  395 + },
  396 + onProductsChange(products) {
  397 + const list = Array.isArray(products) ? products : []
  398 + this.newProductLineList = list
  399 + const sumQ = list.reduce((acc, it) => acc + (parseFloat(it.quantity) || 0), 0)
  400 + const sumE = list.reduce((acc, it) => acc + (parseFloat(it.amountExcludingTax) || 0), 0)
  401 + const sumT = list.reduce((acc, it) => acc + (parseFloat(it.totalAmount) || 0), 0)
  402 + this.totalQuantity = sumQ
  403 + this.totalAmountExcludingTax = sumE
  404 + this.totalAmountIncludingTax = sumT
  405 + this.form.totalAmountCapital = formatCurrencyToChinese(sumT)
  406 + },
  407 + async loadSuppliers() {
  408 + try {
  409 + const results = await getDicByCodes(['SUPPLIER'])
  410 + const items = results && results.SUPPLIER && results.SUPPLIER.data ? results.SUPPLIER.data : []
  411 + this.supplierList = items.map(it => ({ label: it.name, value: it.code }))
  412 + } catch (e) { this.supplierList = [] }
  413 + },
  414 + async loadExtraOptions() {
  415 + try {
  416 + const results = await getDicByCodes(['CONDITIONS_REQUIRED', 'APPLICABLE_STANDARD', 'CONTRACT_PRODUCT'])
  417 + const c1 = results && results.CONDITIONS_REQUIRED && results.CONDITIONS_REQUIRED.data ? results.CONDITIONS_REQUIRED.data : []
  418 + const c2 = results && results.APPLICABLE_STANDARD && results.APPLICABLE_STANDARD.data ? results.APPLICABLE_STANDARD.data : []
  419 + const c3 = results && results.CONTRACT_PRODUCT && results.CONTRACT_PRODUCT.data ? results.CONTRACT_PRODUCT.data : []
  420 + this.specialTermsList = c1.map(it => ({ label: it.name, value: it.code }))
  421 + this.executionStandardList = c2.map(it => ({ label: it.name, value: it.code }))
  422 + this.productList = c3.map(it => ({ label: it.name, value: it.code }))
  423 + } catch (e) {
  424 + this.specialTermsList = []
  425 + this.executionStandardList = []
  426 + this.productList = []
  427 + }
  428 + },
  429 + displayLabel(field) {
  430 + const m = this.form
  431 + const map = { supplierName: '请选择供方', buyerName: '请选择需方', workshopName: '请选择生产厂', regionName: '请选择区域' }
  432 + const val = m[field]
  433 + return val ? String(val) : map[field]
  434 + },
  435 + async openSheet(field) {
  436 + if (field === 'standardStandardized') {
  437 + const options = this.yesNoList
  438 + const current = this.standardStandardized
  439 + const match = (options || []).find(o => String(o.value) === String(current) || String(o.label) === String(current))
  440 + this.sheet = { ...this.sheet, visible: true, title: '合同是否规范', options, field, value: match ? match.value : '' }
  441 + return
  442 + }
  443 + const setSheet = (title, options) => {
  444 + const current = this.form[field]
  445 + const match = (options || []).find(o => String(o.label) === String(current) || String(o.value) === String(current))
  446 + this.sheet = { ...this.sheet, visible: true, title, options, field, value: match ? match.value : '' }
  447 + }
  448 + if (field === 'workshopId') {
  449 + const res = await workshopQueryApi({ pageIndex: 1, pageSize: 9999 })
  450 + const _data = res.data || {}
  451 + const list = _data.datas || (Array.isArray(_data) ? _data : [])
  452 + const opts = (list || []).map(it => ({ label: it.name, value: it.id }))
  453 + setSheet('生产厂', opts)
  454 + } else if (field === 'supplier') {
  455 + setSheet('供方', this.supplierList)
  456 + } else if (field === 'specialTerms') {
  457 + setSheet('特别条款要求', this.specialTermsList)
  458 + } else if (field === 'executionStandard') {
  459 + setSheet('执行标准', this.executionStandardList)
  460 + } else if (field === 'includesPackagingFee') {
  461 + setSheet('单价中是否已包含包装费', this.yesNoList)
  462 + } else if (field === 'includesTransportFee') {
  463 + setSheet('单价中是否已包含运费', this.yesNoList)
  464 + } else if (field === 'region') {
  465 + setSheet('区域', this.regionOptions)
  466 + }
  467 + },
  468 + onSheetConfirm({ value, label }) {
  469 + const field = this.sheet.field
  470 + if (!field) return
  471 + const v = (value === undefined || value === null) ? '' : value
  472 + if (field === 'standardStandardized') {
  473 + this.standardStandardized = v
  474 + this.standardStandardizedName = label || ''
  475 + return
  476 + }
  477 + this.form[field] = v
  478 + this.form[field + 'Name'] = label || ''
  479 + },
  480 + openRelate(fieldKey) {
  481 + let config = {}
  482 + if (fieldKey === 'buyer') {
  483 + config = { title: '需方', source: 'customer', rowKey: 'id', multiple: false, display: [{ label: '名称', field: 'name' }, { label: '编号', field: 'code' }, { label: '状态', field: 'available', format: v => (v ? '启用' : '停用') }] }
  484 + } else if (fieldKey === 'stockUpCompanyId') {
  485 + config = { title: '备货单位/人(生产标准)', source: 'customer', rowKey: 'id', multiple: false, display: [{ label: '姓名', field: 'name' }, { label: '编号', field: 'code' }, { label: '状态', field: 'available', format: v => (v ? '启用' : '停用') }] }
  486 + }
  487 + const selectedKeys = this.form[fieldKey] ? [this.form[fieldKey]] : []
  488 + this.sheet.visible = false
  489 + this.relate = { ...this.relate, title: config.title, source: config.source, display: config.display, multiple: config.multiple, rowKey: config.rowKey, selectedKeys, fieldKey }
  490 + this.$nextTick(() => { this.relate.visible = true })
  491 + },
  492 + onRelateConfirm({ items }) {
  493 + const _fieldKey = this.relate.fieldKey
  494 + const first = (items && items.length > 0) ? items[0] : null
  495 + this.form[_fieldKey] = (first && first.id) ? first.id : ''
  496 + if (_fieldKey === 'stockUpCompanyId') {
  497 + this.form.stockUpCompanyName = (first && first.name) ? first.name : ''
  498 + } else {
  499 + this.form[_fieldKey + 'Name'] = (first && first.name) ? first.name : ''
  500 + }
  501 + },
  502 + validateRequired() {
  503 + const checks = [
  504 + { key: 'code', label: '编号' },
  505 + { key: 'supplier', label: '供方' },
  506 + { key: 'buyer', label: '需方' },
  507 + { key: 'orderDate', label: '订货日期' },
  508 + { key: 'unit', label: '单位' },
  509 + { key: 'workshopId', label: '生产厂' },
  510 + { key: 'specialTerms', label: '特别条款要求' },
  511 + ]
  512 + for (const it of checks) {
  513 + const val = this.form[it.key]
  514 + const empty = (val === undefined || val === null || (typeof val === 'string' && val.trim() === '') || (typeof val === 'number' && isNaN(val)))
  515 + if (empty) { uni.showToast({ title: `请先选择${it.label}`, icon: 'none' }); return false }
  516 + }
  517 + if (this.$refs.productRel && !this.$refs.productRel.validate()) return false
  518 + const list = Array.isArray(this.newProductLineList) ? this.newProductLineList : []
  519 + if (list.length === 0) {
  520 + uni.showToast({ title: '请至少添加一条产品明细', icon: 'none' }); return false
  521 + }
  522 + const strEmpty = (v) => (v === undefined || v === null || (typeof v === 'string' && v.trim() === ''))
  523 + const numEmpty = (v) => (v === undefined || v === null || v === '' || (typeof v === 'number' && isNaN(v)))
  524 + for (const [idx, it] of list.entries()) {
  525 + if (
  526 + strEmpty(it.productName) ||
  527 + strEmpty(it.industry) ||
  528 + strEmpty(it.quality) ||
  529 + strEmpty(it.brand) ||
  530 + numEmpty(it.quantity) ||
  531 + strEmpty(it.unitPrice) ||
  532 + strEmpty(it.deliveryDate)
  533 + ) {
  534 + uni.showToast({ title: `第${idx + 1}条明细未完整填写`, icon: 'none' }); return false
  535 + }
  536 + }
  537 + return true
  538 + },
  539 + async onSubmit() {
  540 + if (!this.fileInfo.id) {
  541 + uni.showToast({ title: '请上传合同附件', icon: 'error' })
  542 + return
  543 + }
  544 + if (!this.standardStandardized && this.standardStandardized !== false) {
  545 + uni.showToast({ title: '请选择合同是否规范', icon: 'error' })
  546 + return
  547 + }
  548 + if (!this.validateRequired()) return
  549 + const confirmRes = await new Promise(resolve => {
  550 + uni.showModal({
  551 + title: '确认提交',
  552 + content: this.uploadType === 'formal' ? '确定提交正式合同吗?' : '确定提交标准合同吗?',
  553 + confirmText: '确定',
  554 + cancelText: '取消',
  555 + success: resolve
  556 + })
  557 + })
  558 + if (!(confirmRes && confirmRes.confirm)) return
  559 + const clean = (obj) => {
  560 + const out = {}
  561 + Object.keys(obj || {}).forEach(k => {
  562 + const v = obj[k]
  563 + const isEmptyString = typeof v === 'string' && v.trim() === ''
  564 + const isUndef = v === undefined || v === null
  565 + const isNaNNumber = typeof v === 'number' && isNaN(v)
  566 + if (!(isEmptyString || isUndef || isNaNNumber)) out[k] = v
  567 + })
  568 + return out
  569 + }
  570 + const lines = (this.newProductLineList || []).map(it => clean(it))
  571 + const { destinationLabel, destinationId, ...formForSubmit } = this.form
  572 + const destination = destinationId && destinationId.length > 0 ? destinationId[destinationId.length - 1] : ''
  573 + const fileIdKey = this.uploadType === 'formal' ? 'formalFileId' : 'standardFileId'
  574 + const fileNameKey = this.uploadType === 'formal' ? 'formalFileName' : 'standardFileName'
  575 + const standardizedKey = this.uploadType === 'formal' ? 'formalStandardized' : 'standardStandardized'
  576 + const payload = clean({
  577 + ...formForSubmit,
  578 + id: this.form.id,
  579 + destination,
  580 + type: 'DRAFT_DIST_AGMT',
  581 + totalQuantity: this.totalQuantity,
  582 + totalAmountExcludingTax: this.totalAmountExcludingTax,
  583 + totalAmountIncludingTax: this.totalAmountIncludingTax,
  584 + contractDistributorLineList: lines,
  585 + [fileIdKey]: this.fileInfo.id,
  586 + [fileNameKey]: this.fileInfo.name,
  587 + [standardizedKey]: this.standardStandardized,
  588 + })
  589 + const api = this.uploadType === 'formal' ? uploadFormalContract : uploadStandardContract
  590 + try {
  591 + await api(payload)
  592 + uni.showToast({ title: '提交成功', icon: 'none' })
  593 + setTimeout(() => { uni.redirectTo({ url: '/pages/contract_unplan/index' }) }, 400)
  594 + } catch (e) {
  595 + uni.showToast({ title: e.msg || '提交失败', icon: 'none' })
  596 + }
  597 + }
  598 + }
  599 +}
  600 +</script>
  601 +
  602 +<style lang="scss" scoped>
  603 +.total {
  604 + .total-text {
  605 + font-weight: 600;
  606 + font-size: 32rpx;
  607 + color: rgba(0, 0, 0, 0.9);
  608 + padding-bottom: 28rpx;
  609 + border-bottom: 2rpx solid #E7E7E7;
  610 + }
  611 +
  612 + .total-item {
  613 + display: flex;
  614 + align-items: center;
  615 + }
  616 +
  617 + .total-item-text {
  618 + font-weight: 400;
  619 + font-size: 28rpx;
  620 + color: rgba(0, 0, 0, 0.6);
  621 + line-height: 32rpx;
  622 + width: 240rpx;
  623 + padding: 12rpx 0;
  624 + }
  625 +
  626 + .total-item-price {
  627 + font-weight: 600;
  628 + font-size: 32rpx;
  629 + color: rgba(0, 0, 0, 0.9);
  630 + line-height: 32rpx;
  631 + }
  632 +
  633 + .text-red {
  634 + color: #D54941;
  635 + }
  636 +}
  637 +
  638 +.page {
  639 + display: flex;
  640 + flex-direction: column;
  641 + height: 100%;
  642 +}
  643 +
  644 +.scroll {
  645 + flex: 1;
  646 + padding: 12rpx 0 392rpx !important;
  647 +}
  648 +
  649 +.footer {
  650 + z-index: 2;
  651 + position: fixed;
  652 + left: 0;
  653 + right: 0;
  654 + bottom: 0;
  655 + padding: 32rpx;
  656 + padding-bottom: calc(32rpx + env(safe-area-inset-bottom));
  657 + background: #fff;
  658 + box-shadow: 0 -8rpx 24rpx rgba(0, 0, 0, 0.06);
  659 +}
  660 +
  661 +.footer .btn {
  662 + height: 80rpx;
  663 + line-height: 80rpx;
  664 + border-radius: 12rpx;
  665 + font-size: 32rpx;
  666 +}
  667 +
  668 +.footer .submit {
  669 + background: $theme-primary;
  670 + color: #fff;
  671 +}
  672 +
  673 +.quality {
  674 + background-color: #fff;
  675 + display: flex;
  676 + align-items: center;
  677 + padding: 24rpx 32rpx;
  678 + border-bottom: 1rpx solid #f0f0f0;
  679 + margin-top: 20rpx;
  680 +
  681 + .title {
  682 + font-size: 32rpx;
  683 + color: rgba(0, 0, 0, 0.9);
  684 + font-weight: 600;
  685 + }
  686 +
  687 + .opCollapse {
  688 + color: rgba(0, 0, 0, 0.6);
  689 + width: 32rpx;
  690 + height: 28rpx;
  691 + margin-right: 16rpx;
  692 + }
  693 +}
  694 +
  695 +::v-deep .uni-list {
  696 + background: transparent;
  697 +}
  698 +
  699 +::v-deep .uni-list .uni-easyinput .uni-input-input {
  700 + color: rgba(0, 0, 0, 0.9);
  701 +}
  702 +
  703 +::v-deep .uni-list .uni-input-placeholder {
  704 + z-index: 1;
  705 +}
  706 +
  707 +::v-deep .uni-list .uni-input-input {
  708 + background-color: #ffffff;
  709 +}
  710 +
  711 +::v-deep .uni-list-item__extra-text {
  712 + font-size: 32rpx;
  713 +}
  714 +
  715 +::v-deep .uni-list-item__content-title {
  716 + font-size: 32rpx;
  717 + color: rgba(0, 0, 0, 0.9);
  718 +}
  719 +
  720 +::v-deep .uni-list-item__container {
  721 + padding: 32rpx;
  722 +}
  723 +
  724 +::v-deep .uni-list-item__container .uni-easyinput__placeholder-class {
  725 + font-size: 32rpx;
  726 + color: rgba(0, 0, 0, 0.4);
  727 +}
  728 +
  729 +::v-deep .uni-list-item__container .uni-easyinput__content {
  730 + border: none;
  731 + background-color: #ffffff !important;
  732 +}
  733 +
  734 +::v-deep .uni-list-item__container .uni-easyinput__content-input {
  735 + padding-left: 0 !important;
  736 + height: 48rpx;
  737 + line-height: 48rpx;
  738 + font-size: 32rpx;
  739 +}
  740 +
  741 +::v-deep .uni-list-item__container .item-title,
  742 +::v-deep .uni-list-item__container .uni-list-item__content {
  743 + flex: none;
  744 + min-height: 48rpx;
  745 + line-height: 48rpx;
  746 + font-size: 32rpx;
  747 + position: relative;
  748 + width: 210rpx;
  749 + margin-right: 32rpx;
  750 + color: rgba(0, 0, 0, 0.9);
  751 +}
  752 +
  753 +::v-deep .uni-list-item__container .item-title .required {
  754 + color: red;
  755 + position: absolute;
  756 + top: 50%;
  757 + transform: translateY(-50%);
  758 + left: -16rpx;
  759 +}
  760 +
  761 +::v-deep .uni-list-item.select-item.is-empty .uni-list-item__extra-text {
  762 + color: rgba(0, 0, 0, 0.4) !important;
  763 +}
  764 +
  765 +::v-deep .uni-list-item.select-item.is-filled .uni-list-item__extra-text {
  766 + color: rgba(0, 0, 0, 0.9) !important;
  767 +}
  768 +</style>