Commit 6450cb832a8f4d83c17c44b7bce1add790deffd7

Authored by 史婷婷
2 parents 119a3cb2 79549efe

Merge branch 'cjerp-1.0' of http://gitlab.qgutech.com/zhuyuanliang/erp-mobile into cjerp-1.0

Too many changes to show.

To preserve performance only 36 of 37 files are displayed.

... ... @@ -5,6 +5,7 @@ export const statusStyle = [
5 5 { color: '#2BA471', bgColor:'#E3F9E9',text: '审核通过' },
6 6 { color: '#D54941', bgColor:'#FFF0ED',text: '已驳回' },
7 7 { color: '#3D48A3', bgColor:'#F2F3FF',text: '审核中' },
  8 + { color: '#000', bgColor:'#F2F3FF',text: '已取消' },
8 9 ];
9 10
10 11 export const statusMap = {
... ...
... ... @@ -129,7 +129,7 @@
129 129 </uni-list-item>
130 130 <uni-list-item title="发货日期">
131 131 <template v-slot:footer>
132   - <uni-datetime-picker type="date" v-model="item.orderDate" @change="onDateChange(idx, $event)" />
  132 + <uni-datetime-picker type="date" v-model="item.deliveryDate" @change="onDateChange(idx, $event)" />
133 133 </template>
134 134 </uni-list-item>
135 135 </uni-list>
... ... @@ -151,7 +151,30 @@
151 151 <view class="row"><text class="label">行业</text><text class="value">{{ item.industry }}</text></view>
152 152 <view class="row"><text class="label">牌号</text><text class="value">{{ item.brand }}</text></view>
153 153 <view class="row"><text class="label">品质</text><text class="value">{{ item.quality }}</text></view>
154   - <view class="row"><text class="label">规格</text><text class="value">{{ item.specDisplay }}</text></view>
  154 + <!-- 厚(公差) * 宽(公差) * 长(公差) -->
  155 + <view class="row row-spec"><text class="label">规格(mm)</text>
  156 + <view class="value value-spec">
  157 + <view v-if="item.thickness" class="value-spec_val">{{ item.thickness }}</view>
  158 + <view v-if="item.thickness" class="value-spec_box">
  159 + <view v-if="item.thicknessTolPos" class="value-spec_box_1">+{{ item.thicknessTolPos }}
  160 + </view>
  161 + <view v-if="item.thicknessTolNeg" class="value-spec_box_2">-{{ item.thicknessTolNeg }}
  162 + </view>
  163 + </view>
  164 + <view v-if="item.width" class="value-spec_val p12">*</view>
  165 + <view v-if="item.width" class="value-spec_val">{{ item.width }}</view>
  166 + <view v-if="item.width" class="value-spec_box">
  167 + <view v-if="item.widthTolPos" class="value-spec_box_1">+{{ item.widthTolPos }}</view>
  168 + <view v-if="item.widthTolNeg" class="value-spec_box_2">-{{ item.widthTolNeg }}</view>
  169 + </view>
  170 + <view v-if="item.length" class="value-spec_val p12">*</view>
  171 + <view v-if="item.length" class="value-spec_val">{{ item.length }}</view>
  172 + <view v-if="item.length" class="value-spec_box">
  173 + <view v-if="item.lengthTolPos" class="value-spec_box_1">+{{ item.lengthTolPos }}</view>
  174 + <view v-if="item.lengthTolNeg" class="value-spec_box_2">-{{ item.lengthTolNeg }}</view>
  175 + </view>
  176 + </view>
  177 + </view>
155 178 <view class="row"><text class="label">状态</text><text class="value">{{ item.status }}</text></view>
156 179 <view class="row"><text class="label">数量</text><text class="value">{{ item.quantity }}</text></view>
157 180 <view class="row"><text class="label">单价</text><text class="value">{{ formatCurrency(item.unitPrice)
... ... @@ -162,7 +185,7 @@
162 185 }}</text></view>
163 186 <view class="row"><text class="label">总金额</text><text class="value">{{ formatCurrency(item.totalAmount)
164 187 }}</text></view>
165   - <view class="row"><text class="label">发货日期</text><text class="value">{{ item.orderDate }}</text></view>
  188 + <view class="row"><text class="label">发货日期</text><text class="value">{{ item.deliveryDate }}</text></view>
166 189 </view>
167 190 </view>
168 191 <SingleSelectSheet :visible.sync="sheet.visible" :title="sheet.title" :options="sheet.options" v-model="sheet.value" @confirm="onProductConfirm" />
... ... @@ -176,7 +199,7 @@ export default {
176 199 mode: { type: String, default: 'add' },
177 200 list: { type: Array, default: () => [] },
178 201 max: { type: Number, default: 8 },
179   - orderDateBase: { type: String, default: '' },
  202 + deliveryDateBase: { type: String, default: '' },
180 203 options: { type: Array, default: () => [] }
181 204 },
182 205 components: { SingleSelectSheet },
... ... @@ -218,7 +241,7 @@ export default {
218 241 },
219 242 methods: {
220 243 defaultItem() {
221   - return { productId: '', productName: '', industry: '', brand: '', quality: '', thickness: '', thicknessTolPos: '', thicknessTolNeg: '', width: '', widthTolPos: '', widthTolNeg: '', length: '', lengthTolPos: '', lengthTolNeg: '', status: '', quantity: '', unitPrice: '', amountExcludingTax: 0, totalAmount: 0, orderDate: '' }
  244 + return { productId: '', productName: '', industry: '', brand: '', quality: '', thickness: '', thicknessTolPos: '', thicknessTolNeg: '', width: '', widthTolPos: '', widthTolNeg: '', length: '', lengthTolPos: '', lengthTolNeg: '', status: '', quantity: '', unitPrice: '', amountExcludingTax: 0, totalAmount: 0, deliveryDate: '' }
222 245 },
223 246 onImmediateChange(idx) {
224 247 this.$nextTick(() => this.recalculate(idx))
... ... @@ -319,15 +342,15 @@ export default {
319 342 onDateChange(idx, e) {
320 343 const it = this.items[idx]
321 344 if (!it) return
322   - const val = typeof e === 'string' ? e : (e && e.detail && e.detail.value) ? e.detail.value : it.orderDate
  345 + const val = typeof e === 'string' ? e : (e && e.detail && e.detail.value) ? e.detail.value : it.deliveryDate
323 346 const dateStr = String(val).slice(0, 10)
324   - const base = this.orderDateBase ? new Date(this.orderDateBase) : null
  347 + const base = this.deliveryDateBase ? new Date(this.deliveryDateBase) : null
325 348 const d = new Date(dateStr)
326 349 if (base && !isNaN(d.getTime()) && d.getTime() < base.getTime()) {
327 350 uni.showToast({ title: '发货日期不得早于订货日期', icon: 'none' })
328   - it.orderDate = this.orderDateBase
  351 + it.deliveryDate = this.deliveryDateBase
329 352 } else {
330   - it.orderDate = dateStr
  353 + it.deliveryDate = dateStr
331 354 }
332 355 this.$set(this.items, idx, it)
333 356 },
... ... @@ -500,8 +523,46 @@ export default {
500 523
501 524 .value {
502 525 flex: 1;
503   - text-align: right;
  526 + // text-align: right;
504 527 color: rgba(0, 0, 0, 0.9);
505 528 font-size: 28rpx;
506 529 }
  530 + .value-spec {
  531 + height: 48rpx;
  532 + display: flex;
  533 + align-items: center;
  534 + color: #000000;
  535 + // justify-content: end;
  536 + &_box {
  537 + position: relative;
  538 + width: 60rpx;
  539 + height: 48rpx;
  540 +
  541 + &_1 {
  542 + font-size: 16rpx;
  543 + position: absolute;
  544 + top: -10rpx;
  545 + left: 0;
  546 + }
  547 +
  548 + &_2 {
  549 + font-size: 16rpx;
  550 + position: absolute;
  551 + bottom: -10rpx;
  552 + left: 0;
  553 + }
  554 + }
  555 +
  556 + &_val {
  557 + font-size: 28rpx;
  558 +
  559 + &.p12 {
  560 + padding-right: 12rpx;
  561 + }
  562 + }
  563 + }
  564 + .row-spec {
  565 + height: 60rpx;
  566 + align-items: center;
  567 + }
507 568 </style>
... ...
... ... @@ -39,7 +39,7 @@
39 39 <view class="item-title"><text class="required">*</text><text>生产厂</text></view>
40 40 </template>
41 41 </uni-list-item>
42   - <ProductRel mode="add" :orderDateBase="form.orderDate" @change="onProductsChange" :options="productList" />
  42 + <ProductRel mode="add" :deliveryDateBase="form.deliveryDate" @change="onProductsChange" :options="productList" />
43 43 <uni-list-item title="合计人民币金额(大写)">
44 44 <template v-slot:footer>
45 45 <uni-easyinput v-model="form.totalAmountCapital" placeholder="自动计算" :inputBorder="false" disabled />
... ... @@ -92,33 +92,25 @@
92 92 :inputBorder="false" />
93 93 </template>
94 94 </uni-list-item>
95   - <view class="group">
96   - <view class="group-title">特别条款要求</view>
97   - <view class="radio-list">
98   - <view v-for="(opt, i) in specialTermsList" :key="'cr-' + i" class="radio-item"
99   - @click="onRadioSelect('specialTerms', 'specialTermsName', opt)">
100   - <view :class="['radio', { checked: form.specialTerms === opt.value }]" />
101   - <text class="label">{{ opt.label }}</text>
102   - </view>
103   - </view>
104   - </view>
105   - <view class="group">
106   - <view class="group-title">执行标准</view>
107   - <view class="radio-list">
108   - <view v-for="(opt, i) in executionStandardList" :key="'es-' + i" class="radio-item"
109   - @click="onRadioSelect('executionStandard', 'executionStandardName', opt)">
110   - <view :class="['radio', { checked: form.executionStandard === opt.value }]" />
111   - <text class="label">{{ opt.label }}</text>
112   - </view>
113   - </view>
114   - </view>
  95 + <uni-list-item class="select-item" :class="form.specialTermsName ? 'is-filled' : 'is-empty'" clickable
  96 + @click="openSheet('specialTerms')" :rightText="form.specialTermsName || '请选择'" showArrow>
  97 + <template v-slot:body>
  98 + <view class="item-title"><text class="required">*</text><text>特别条款要求</text></view>
  99 + </template>
  100 + </uni-list-item>
  101 + <uni-list-item class="select-item" :class="form.executionStandardName ? 'is-filled' : 'is-empty'" clickable
  102 + @click="openSheet('executionStandard')" :rightText="form.executionStandardName || '请选择'" showArrow>
  103 + <template v-slot:body>
  104 + <view class="item-title"><text>执行标准</text></view>
  105 + </template>
  106 + </uni-list-item>
115 107 <uni-list-item v-if="form.executionStandard === 'OTHER'" title="其他">
116 108 <template v-slot:footer>
117 109 <uni-easyinput v-model="form.executionStandardRemarks" placeholder="请输入其他标准备注"
118 110 :inputBorder="false" />
119 111 </template>
120 112 </uni-list-item>
121   - <uni-list-item title="特别说明">
  113 + <uni-list-item title="特别说明" style="margin-top: 20rpx;">
122 114 <template v-slot:footer>
123 115 <uni-easyinput v-model="form.specialInstructions" placeholder="请输入特别说明" :inputBorder="false" />
124 116 </template>
... ... @@ -181,7 +173,7 @@
181 173 数量
182 174 </div>
183 175 <div class="total-item-price">
184   - {{ (sumQuantity || 0).toFixed(2) }}t
  176 + {{ (totalQuantity || 0).toFixed(2) }}kg
185 177 </div>
186 178 </div>
187 179 <div class="total-item">
... ... @@ -189,7 +181,7 @@
189 181 不含税金额
190 182 </div>
191 183 <div class="total-item-price text-red">
192   - ¥{{ (sumAmountExcl || 0).toFixed(2) }}
  184 + ¥{{ (totalAmountExcludingTax || 0).toFixed(2) }}
193 185 </div>
194 186 </div>
195 187 <div class="total-item">
... ... @@ -197,7 +189,7 @@
197 189 总金额
198 190 </div>
199 191 <div class="total-item-price text-red">
200   - ¥{{ (sumTotal || 0).toFixed(2) }}
  192 + ¥{{ (totalAmountIncludingTax || 0).toFixed(2) }}
201 193 </div>
202 194 </div>
203 195 </div>
... ... @@ -233,6 +225,7 @@ export default {
233 225 buyer: '',
234 226 buyerName: '',
235 227 orderDate: '',
  228 + deliveryDate: '',
236 229 designatedConsignee: '',
237 230 specialTerms: '',
238 231 specialTermsName: '',
... ... @@ -263,9 +256,9 @@ export default {
263 256 yesNoList: [{ label: '是', value: true }, { label: '否', value: false }],
264 257 sheet: { visible: false, title: '请选择', field: '', options: [], value: '' },
265 258 relate: { visible: false, title: '选择', source: '', display: [], multiple: false, rowKey: 'id', selectedKeys: [], fieldKey: '' },
266   - sumQuantity: 0,
267   - sumAmountExcl: 0,
268   - sumTotal: 0,
  259 + totalQuantity: 0,
  260 + totalAmountExcludingTax: 0,
  261 + totalAmountIncludingTax: 0,
269 262 productLineList: [],
270 263 productList: [],
271 264 customerRemarks: [],
... ... @@ -367,9 +360,9 @@ export default {
367 360 const sumQ = list.reduce((acc, it) => acc + (parseFloat(it.quantity) || 0), 0)
368 361 const sumE = list.reduce((acc, it) => acc + (parseFloat(it.amountExcludingTax) || 0), 0)
369 362 const sumT = list.reduce((acc, it) => acc + (parseFloat(it.totalAmount) || 0), 0)
370   - this.sumQuantity = sumQ
371   - this.sumAmountExcl = sumE
372   - this.sumTotal = sumT
  363 + this.totalQuantity = sumQ
  364 + this.totalAmountExcludingTax = sumE
  365 + this.totalAmountIncludingTax = sumT
373 366 this.form.totalAmountCapital = formatCurrencyToChinese(sumT)
374 367 this.productLineList = list
375 368 },
... ... @@ -445,6 +438,10 @@ export default {
445 438 setSheet('生产厂', opts)
446 439 } else if (field === 'supplier') {
447 440 setSheet('供方', this.supplierList)
  441 + } else if (field === 'specialTerms') {
  442 + setSheet('特别条款要求', this.specialTermsList)
  443 + } else if (field === 'executionStandard') {
  444 + setSheet('执行标准', this.executionStandardList)
448 445 } else if (field === 'includesPackagingFee') {
449 446 setSheet('单价中是否已包含包装费', this.yesNoList)
450 447 } else if (field === 'includesTransportFee') {
... ... @@ -515,9 +512,9 @@ export default {
515 512 ...formForSubmit,
516 513 destination,
517 514 type: 'INTL_STD_CONTRACT',
518   - sumQuantity: this.sumQuantity,
519   - sumAmountExcl: this.sumAmountExcl,
520   - sumTotal: this.sumTotal,
  515 + totalQuantity: this.totalQuantity,
  516 + totalAmountExcludingTax: this.totalAmountExcludingTax,
  517 + totalAmountIncludingTax: this.totalAmountIncludingTax,
521 518 contractDistributorLineList: lines
522 519 })
523 520 console.log('onSubmit__payload', payload)
... ... @@ -536,18 +533,31 @@ export default {
536 533 { key: 'supplier', label: '供方' },
537 534 { key: 'buyer', label: '需方' },
538 535 { key: 'orderDate', label: '订货日期' },
  536 + { key: 'unit', label: '单位' },
539 537 { key: 'workshopId', label: '生产厂' },
  538 + { key: 'specialTerms', label: '特别条款要求' },
540 539 ]
541 540 for (const it of checks) {
542 541 const val = this.form[it.key]
543 542 const empty = (val === undefined || val === null || (typeof val === 'string' && val.trim() === '') || (typeof val === 'number' && isNaN(val)))
544 543 if (empty) { uni.showToast({ title: `请先选择${it.label}`, icon: 'none' }); return false }
545 544 }
546   - if (!Array.isArray(this.productLineList) || this.productLineList.length === 0) {
  545 + const list = Array.isArray(this.productLineList) ? this.productLineList : []
  546 + if (list.length === 0) {
547 547 uni.showToast({ title: '请至少添加一条产品明细', icon: 'none' }); return false
548 548 }
549   - for (const [idx, it] of this.productLineList.entries()) {
550   - if (!it.productName || !it.quantity || !it.unitPrice) {
  549 + const strEmpty = (v) => (v === undefined || v === null || (typeof v === 'string' && v.trim() === ''))
  550 + const numEmpty = (v) => (v === undefined || v === null || v === '' || (typeof v === 'number' && isNaN(v)))
  551 + for (const [idx, it] of list.entries()) {
  552 + if (
  553 + strEmpty(it.productName) ||
  554 + strEmpty(it.industry) ||
  555 + strEmpty(it.quality) ||
  556 + strEmpty(it.brand) ||
  557 + numEmpty(it.quantity) ||
  558 + numEmpty(it.unitPrice) ||
  559 + strEmpty(it.deliveryDate)
  560 + ) {
551 561 uni.showToast({ title: `第${idx + 1}条明细未完整填写`, icon: 'none' }); return false
552 562 }
553 563 }
... ... @@ -575,7 +585,7 @@ export default {
575 585 color: rgba(0, 0, 0, 0.6);
576 586 line-height: 32rpx;
577 587 width: 240rpx;
578   - padding: 24rpx 0;
  588 + padding: 12rpx 0;
579 589 }
580 590 .total-item-price {
581 591 font-weight: 600;
... ... @@ -597,7 +607,7 @@ export default {
597 607
598 608 .scroll {
599 609 flex: 1;
600   - padding: 12rpx 0 480rpx !important;
  610 + padding: 12rpx 0 392rpx !important;
601 611 }
602 612
603 613 .footer {
... ...
... ... @@ -40,9 +40,7 @@
40 40 <uni-easyinput v-model="form.unit" :inputBorder="false" disabled />
41 41 </template>
42 42 </uni-list-item>
43   -
44   - <ProductRel mode="add" :orderDateBase="form.orderDate" :list="productLineList" @change="onProductsChange" :options="productList" />
45   -
  43 + <ProductRel mode="add" :deliveryDateBase="form.deliveryDate" :list="productLineList" @change="onProductsChange" :options="productList" />
46 44 <uni-list-item title="合计人民币金额(大写)">
47 45 <template v-slot:footer>
48 46 <uni-easyinput v-model="form.totalAmountCapital" placeholder="自动计算" :inputBorder="false"
... ... @@ -98,34 +96,25 @@
98 96 :inputBorder="false" />
99 97 </template>
100 98 </uni-list-item>
101   -
102   - <view class="group">
103   - <view class="group-title">特别条款要求</view>
104   - <view class="radio-list">
105   - <view v-for="(opt, i) in specialTermsList" :key="'cr-' + i" class="radio-item"
106   - @click="onRadioSelect('specialTerms', 'specialTermsName', opt)">
107   - <view :class="['radio', { checked: form.specialTerms === opt.value }]" />
108   - <text class="label">{{ opt.label }}</text>
109   - </view>
110   - </view>
111   - </view>
112   - <view class="group">
113   - <view class="group-title">执行标准</view>
114   - <view class="radio-list">
115   - <view v-for="(opt, i) in executionStandardList" :key="'es-' + i" class="radio-item"
116   - @click="onRadioSelect('executionStandard', 'executionStandardName', opt)">
117   - <view :class="['radio', { checked: form.executionStandard === opt.value }]" />
118   - <text class="label">{{ opt.label }}</text>
119   - </view>
120   - </view>
121   - </view>
  99 + <uni-list-item class="select-item" :class="form.specialTermsName ? 'is-filled' : 'is-empty'" clickable
  100 + @click="openSheet('specialTerms')" :rightText="form.specialTermsName || '请选择'" showArrow>
  101 + <template v-slot:body>
  102 + <view class="item-title"><text class="required">*</text><text>特别条款要求</text></view>
  103 + </template>
  104 + </uni-list-item>
  105 + <uni-list-item class="select-item" :class="form.executionStandardName ? 'is-filled' : 'is-empty'" clickable
  106 + @click="openSheet('executionStandard')" :rightText="form.executionStandardName || '请选择'" showArrow>
  107 + <template v-slot:body>
  108 + <view class="item-title"><text>执行标准</text></view>
  109 + </template>
  110 + </uni-list-item>
122 111 <uni-list-item v-if="form.executionStandard === 'OTHER'" title="其他">
123 112 <template v-slot:footer>
124 113 <uni-easyinput v-model="form.executionStandardRemarks" placeholder="请输入其他标准备注"
125 114 :inputBorder="false" />
126 115 </template>
127 116 </uni-list-item>
128   - <uni-list-item title="特别说明">
  117 + <uni-list-item title="特别说明" style="margin-top: 20rpx;">
129 118 <template v-slot:footer>
130 119 <uni-easyinput v-model="form.specialInstructions" placeholder="请输入特别说明" :inputBorder="false" />
131 120 </template>
... ... @@ -177,15 +166,15 @@
177 166 <div class="total-text">合计</div>
178 167 <div class="total-item">
179 168 <div class="total-item-text">数量</div>
180   - <div class="total-item-price">{{ (sumQuantity || 0).toFixed(2) }}t</div>
  169 + <div class="total-item-price">{{ (totalQuantity || 0).toFixed(2) }}kg</div>
181 170 </div>
182 171 <div class="total-item">
183 172 <div class="total-item-text">不含税金额</div>
184   - <div class="total-item-price text-red">¥{{ (sumAmountExcl || 0).toFixed(2) }}</div>
  173 + <div class="total-item-price text-red">¥{{ (totalAmountExcludingTax || 0).toFixed(2) }}</div>
185 174 </div>
186 175 <div class="total-item">
187 176 <div class="total-item-text">总金额</div>
188   - <div class="total-item-price text-red">¥{{ (sumTotal || 0).toFixed(2) }}</div>
  177 + <div class="total-item-price text-red">¥{{ (totalAmountIncludingTax || 0).toFixed(2) }}</div>
189 178 </div>
190 179 </div>
191 180 <button class="btn submit" type="primary" @click="onSubmit">保存</button>
... ... @@ -223,6 +212,7 @@ export default {
223 212 workshopId: '',
224 213 workshopName: '',
225 214 orderDate: '',
  215 + deliveryDate: '',
226 216 designatedConsignee: '',
227 217 specialTerms: '',
228 218 specialTermsName: '',
... ... @@ -256,9 +246,9 @@ export default {
256 246 yesNoList: [{ label: '是', value: true }, { label: '否', value: false }],
257 247 sheet: { visible: false, title: '请选择', field: '', options: [], value: '' },
258 248 relate: { visible: false, title: '选择', source: '', display: [], multiple: false, rowKey: 'id', selectedKeys: [], fieldKey: '' },
259   - sumQuantity: 0,
260   - sumAmountExcl: 0,
261   - sumTotal: 0,
  249 + totalQuantity: 0,
  250 + totalAmountExcludingTax: 0,
  251 + totalAmountIncludingTax: 0,
262 252 productLineList: [],
263 253 newProductLineList: [],
264 254 productList: []
... ... @@ -349,9 +339,9 @@ export default {
349 339 const sumQ = list.reduce((acc, it) => acc + (parseFloat(it.quantity) || 0), 0)
350 340 const sumE = list.reduce((acc, it) => acc + (parseFloat(it.amountExcludingTax) || 0), 0)
351 341 const sumT = list.reduce((acc, it) => acc + (parseFloat(it.totalAmount) || 0), 0)
352   - this.sumQuantity = sumQ
353   - this.sumAmountExcl = sumE
354   - this.sumTotal = sumT
  342 + this.totalQuantity = sumQ
  343 + this.totalAmountExcludingTax = sumE
  344 + this.totalAmountIncludingTax = sumT
355 345 this.form.totalAmountCapital = formatCurrencyToChinese(sumT)
356 346 },
357 347 async loadSuppliers() {
... ... @@ -399,6 +389,10 @@ export default {
399 389 setSheet('生产厂', opts)
400 390 } else if (field === 'supplier') {
401 391 setSheet('供方', this.supplierList)
  392 + } else if (field === 'specialTerms') {
  393 + setSheet('特别条款要求', this.specialTermsList)
  394 + } else if (field === 'executionStandard') {
  395 + setSheet('执行标准', this.executionStandardList)
402 396 } else if (field === 'includesPackagingFee') {
403 397 setSheet('单价中是否已包含包装费', this.yesNoList)
404 398 } else if (field === 'includesTransportFee') {
... ... @@ -443,18 +437,32 @@ export default {
443 437 { key: 'supplier', label: '供方' },
444 438 { key: 'buyer', label: '需方' },
445 439 { key: 'orderDate', label: '订货日期' },
  440 + { key: 'unit', label: '单位' },
446 441 { key: 'workshopId', label: '生产厂' },
  442 + { key: 'specialTerms', label: '特别条款要求' },
447 443 ]
448 444 for (const it of checks) {
449 445 const val = this.form[it.key]
450 446 const empty = (val === undefined || val === null || (typeof val === 'string' && val.trim() === '') || (typeof val === 'number' && isNaN(val)))
451 447 if (empty) { uni.showToast({ title: `请先选择${it.label}`, icon: 'none' }); return false }
452 448 }
453   - if (!Array.isArray(this.productLineList) || this.productLineList.length === 0) {
  449 + const list = Array.isArray(this.newProductLineList) ? this.newProductLineList : []
  450 + if (list.length === 0) {
454 451 uni.showToast({ title: '请至少添加一条产品明细', icon: 'none' }); return false
455 452 }
456   - for (const [idx, it] of this.productLineList.entries()) {
457   - if (!it.productName || !it.quantity || !it.unitPrice) {
  453 + const strEmpty = (v) => (v === undefined || v === null || (typeof v === 'string' && v.trim() === ''))
  454 + const numEmpty = (v) => (v === undefined || v === null || v === '' || (typeof v === 'number' && isNaN(v)))
  455 + for (const [idx, it] of list.entries()) {
  456 + console.log('it111', it)
  457 + if (
  458 + strEmpty(it.productName) ||
  459 + strEmpty(it.industry) ||
  460 + strEmpty(it.quality) ||
  461 + strEmpty(it.brand) ||
  462 + numEmpty(it.quantity) ||
  463 + numEmpty(it.unitPrice) ||
  464 + strEmpty(it.deliveryDate)
  465 + ) {
458 466 uni.showToast({ title: `第${idx + 1}条明细未完整填写`, icon: 'none' }); return false
459 467 }
460 468 }
... ... @@ -479,25 +487,25 @@ export default {
479 487 return out
480 488 }
481 489 const lines = (this.newProductLineList || []).map(it => clean(it))
482   - const { destinationLabel, destinationId, ...formForSubmit } = this.form;
483   - const destination = destinationId && destinationId.length > 0 ? destinationId[destinationId.length - 1] : '';
484   - const payload = clean({
485   - ...formForSubmit,
486   - id: this.form.id,
487   - destination,
488   - type: 'INTL_STD_CONTRACT',
489   - sumQuantity: this.sumQuantity,
490   - sumAmountExcl: this.sumAmountExcl,
491   - sumTotal: this.sumTotal,
492   - contractDistributorLineList: lines
493   - })
494   - try {
495   - await updateContractApi(payload)
496   - uni.showToast({ title: '保存成功', icon: 'none' })
497   - setTimeout(() => { uni.redirectTo({ url: '/pages/contract_foreign_std/index' }) }, 400)
498   - } catch (e) {
499   - uni.showToast({ title: '提交失败', icon: 'none' })
500   - }
  490 + const { destinationLabel, destinationId, ...formForSubmit } = this.form;
  491 + const destination = destinationId && destinationId.length > 0 ? destinationId[destinationId.length - 1] : '';
  492 + const payload = clean({
  493 + ...formForSubmit,
  494 + id: this.form.id,
  495 + destination,
  496 + type: 'INTL_STD_CONTRACT',
  497 + totalQuantity: this.totalQuantity,
  498 + totalAmountExcludingTax: this.totalAmountExcludingTax,
  499 + totalAmountIncludingTax: this.totalAmountIncludingTax,
  500 + contractDistributorLineList: lines
  501 + })
  502 + try {
  503 + await updateContractApi(payload)
  504 + uni.showToast({ title: '保存成功', icon: 'none' })
  505 + setTimeout(() => { uni.redirectTo({ url: '/pages/contract_foreign_std/index' }) }, 400)
  506 + } catch (e) {
  507 + uni.showToast({ title: '提交失败', icon: 'none' })
  508 + }
501 509 }
502 510 }
503 511 }
... ... @@ -524,7 +532,7 @@ export default {
524 532 color: rgba(0, 0, 0, 0.6);
525 533 line-height: 32rpx;
526 534 width: 240rpx;
527   - padding: 24rpx 0;
  535 + padding: 12rpx 0;
528 536 }
529 537
530 538 .total-item-price {
... ... @@ -547,7 +555,7 @@ export default {
547 555
548 556 .scroll {
549 557 flex: 1;
550   - padding: 12rpx 0 480rpx !important;
  558 + padding: 12rpx 0 392rpx !important;
551 559 }
552 560
553 561 .footer {
... ...
... ... @@ -55,51 +55,51 @@
55 55 </uni-list-item>
56 56 <uni-list-item title="厚度">
57 57 <template v-slot:footer>
58   - <uni-easyinput v-model="item.thickness" :inputBorder="false" placeholder="请输入厚度" />
  58 + <uni-easyinput type="digit" v-model="item.thickness" :inputBorder="false" placeholder="请输入厚度" @input="onNonNegativeInput(idx, 'thickness')" @blur="onNonNegativeBlur(idx, 'thickness', 2)" />
59 59 </template>
60 60 </uni-list-item>
61 61 <uni-list-item title="厚度公差(单项+)">
62 62 <template v-slot:footer>
63   - <uni-easyinput v-model="item.thicknessTolPos" :inputBorder="false"
64   - placeholder="请输入厚度公差(单项+)" />
  63 + <uni-easyinput type="digit" v-model="item.thicknessTolPos" :inputBorder="false"
  64 + placeholder="请输入厚度公差(单项+)" @input="onNonNegativeInput(idx, 'thicknessTolPos')" @blur="onNonNegativeBlur(idx, 'thicknessTolPos', 2)" />
65 65 </template>
66 66 </uni-list-item>
67 67 <uni-list-item title="厚度公差(单项-)">
68 68 <template v-slot:footer>
69   - <uni-easyinput v-model="item.thicknessTolNeg" :inputBorder="false"
70   - placeholder="请输入厚度公差(单项-)" />
  69 + <uni-easyinput type="digit" v-model="item.thicknessTolNeg" :inputBorder="false"
  70 + placeholder="请输入厚度公差(单项-)" @input="onNonNegativeInput(idx, 'thicknessTolNeg')" @blur="onNonNegativeBlur(idx, 'thicknessTolNeg', 2)" />
71 71 </template>
72 72 </uni-list-item>
73 73 <uni-list-item title="宽度">
74 74 <template v-slot:footer>
75   - <uni-easyinput v-model="item.width" :inputBorder="false" placeholder="请输入宽度" />
  75 + <uni-easyinput type="digit" v-model="item.width" :inputBorder="false" placeholder="请输入宽度" @input="onNonNegativeInput(idx, 'width')" @blur="onNonNegativeBlur(idx, 'width', 2)" />
76 76 </template>
77 77 </uni-list-item>
78 78 <uni-list-item title="宽度公差(单项+)">
79 79 <template v-slot:footer>
80   - <uni-easyinput v-model="item.widthTolPos" :inputBorder="false" placeholder="请输入宽度公差(单项+)" />
  80 + <uni-easyinput type="digit" v-model="item.widthTolPos" :inputBorder="false" placeholder="请输入宽度公差(单项+)" @input="onNonNegativeInput(idx, 'widthTolPos')" @blur="onNonNegativeBlur(idx, 'widthTolPos', 2)" />
81 81 </template>
82 82 </uni-list-item>
83 83 <uni-list-item title="宽度公差(单项-)">
84 84 <template v-slot:footer>
85   - <uni-easyinput v-model="item.widthTolNeg" :inputBorder="false" placeholder="请输入宽度公差(单项-)" />
  85 + <uni-easyinput type="digit" v-model="item.widthTolNeg" :inputBorder="false" placeholder="请输入宽度公差(单项-)" @input="onNonNegativeInput(idx, 'widthTolNeg')" @blur="onNonNegativeBlur(idx, 'widthTolNeg', 2)" />
86 86 </template>
87 87 </uni-list-item>
88 88 <uni-list-item title="长度">
89 89 <template v-slot:footer>
90   - <uni-easyinput v-model="item.length" :inputBorder="false" placeholder="请输入长度" />
  90 + <uni-easyinput type="digit" v-model="item.length" :inputBorder="false" placeholder="请输入长度" @input="onNonNegativeInput(idx, 'length')" @blur="onNonNegativeBlur(idx, 'length', 2)" />
91 91 </template>
92 92 </uni-list-item>
93 93 <uni-list-item title="长度公差(单项+)">
94 94 <template v-slot:footer>
95   - <uni-easyinput v-model="item.lengthTolPos" :inputBorder="false"
96   - placeholder="请输入长度公差(单项+)" />
  95 + <uni-easyinput type="digit" v-model="item.lengthTolPos" :inputBorder="false"
  96 + placeholder="请输入长度公差(单项+)" @input="onNonNegativeInput(idx, 'lengthTolPos')" @blur="onNonNegativeBlur(idx, 'lengthTolPos', 2)" />
97 97 </template>
98 98 </uni-list-item>
99 99 <uni-list-item title="长度公差(单项-)">
100 100 <template v-slot:footer>
101   - <uni-easyinput v-model="item.lengthTolNeg" :inputBorder="false"
102   - placeholder="请输入长度公差(单项-)" />
  101 + <uni-easyinput type="digit" v-model="item.lengthTolNeg" :inputBorder="false"
  102 + placeholder="请输入长度公差(单项-)" @input="onNonNegativeInput(idx, 'lengthTolNeg')" @blur="onNonNegativeBlur(idx, 'lengthTolNeg', 2)" />
103 103 </template>
104 104 </uni-list-item>
105 105 <uni-list-item title="状态">
... ... @@ -109,12 +109,12 @@
109 109 </uni-list-item>
110 110 <uni-list-item title="数量">
111 111 <template v-slot:footer>
112   - <uni-easyinput v-model="item.quantity" type="number" :inputBorder="false" placeholder="请输入数量" @input="onImmediateChange(idx)" @blur="onNumberBlur(idx, 'quantity', 0)" />
  112 + <uni-easyinput v-model="item.quantity" type="digit" :inputBorder="false" placeholder="请输入数量kg" @input="onNonNegativeInput(idx, 'quantity')" @blur="onNonNegativeBlur(idx, 'quantity', 2)" />
113 113 </template>
114 114 </uni-list-item>
115 115 <uni-list-item title="单价">
116 116 <template v-slot:footer>
117   - <uni-easyinput v-model="item.unitPrice" disabled type="number" :inputBorder="false" placeholder="请输入单价" @input="onImmediateChange(idx)" @blur="onNumberBlur(idx, 'unitPrice', 0)" />
  117 + <uni-easyinput v-model="item.unitPrice" type="digit" :inputBorder="false" placeholder="请输入销售价格" @input="onNonNegativeInput(idx, 'unitPrice')" @blur="onNonNegativeBlur(idx, 'unitPrice', 2)" />
118 118 </template>
119 119 </uni-list-item>
120 120 <uni-list-item title="外贸加工费">
... ... @@ -134,7 +134,7 @@
134 134 </uni-list-item>
135 135 <uni-list-item title="发货日期">
136 136 <template v-slot:footer>
137   - <uni-datetime-picker type="date" v-model="item.orderDate" @change="onDateChange(idx, $event)" />
  137 + <uni-datetime-picker type="date" v-model="item.deliveryDate" @change="onDateChange(idx, $event)" />
138 138 </template>
139 139 </uni-list-item>
140 140 </uni-list>
... ... @@ -156,7 +156,30 @@
156 156 <view class="row"><text class="label">行业</text><text class="value">{{ item.industry }}</text></view>
157 157 <view class="row"><text class="label">牌号</text><text class="value">{{ item.brand }}</text></view>
158 158 <view class="row"><text class="label">品质</text><text class="value">{{ item.quality }}</text></view>
159   - <view class="row"><text class="label">规格</text><text class="value">{{ item.specDisplay }}</text></view>
  159 + <!-- 厚(公差) * 宽(公差) * 长(公差) -->
  160 + <view class="row row-spec"><text class="label">规格(mm)</text>
  161 + <view class="value value-spec">
  162 + <view v-if="item.thickness" class="value-spec_val">{{ item.thickness }}</view>
  163 + <view v-if="item.thickness" class="value-spec_box">
  164 + <view v-if="item.thicknessTolPos" class="value-spec_box_1">+{{ item.thicknessTolPos }}
  165 + </view>
  166 + <view v-if="item.thicknessTolNeg" class="value-spec_box_2">-{{ item.thicknessTolNeg }}
  167 + </view>
  168 + </view>
  169 + <view v-if="item.width" class="value-spec_val p12">*</view>
  170 + <view v-if="item.width" class="value-spec_val">{{ item.width }}</view>
  171 + <view v-if="item.width" class="value-spec_box">
  172 + <view v-if="item.widthTolPos" class="value-spec_box_1">+{{ item.widthTolPos }}</view>
  173 + <view v-if="item.widthTolNeg" class="value-spec_box_2">-{{ item.widthTolNeg }}</view>
  174 + </view>
  175 + <view v-if="item.length" class="value-spec_val p12">*</view>
  176 + <view v-if="item.length" class="value-spec_val">{{ item.length }}</view>
  177 + <view v-if="item.length" class="value-spec_box">
  178 + <view v-if="item.lengthTolPos" class="value-spec_box_1">+{{ item.lengthTolPos }}</view>
  179 + <view v-if="item.lengthTolNeg" class="value-spec_box_2">-{{ item.lengthTolNeg }}</view>
  180 + </view>
  181 + </view>
  182 + </view>
160 183 <view class="row"><text class="label">状态</text><text class="value">{{ item.status }}</text></view>
161 184 <view class="row"><text class="label">数量</text><text class="value">{{ item.quantity }}</text></view>
162 185 <view class="row"><text class="label">单价</text><text class="value">{{ formatCurrency(item.unitPrice)
... ... @@ -167,7 +190,7 @@
167 190 }}</text></view>
168 191 <view class="row"><text class="label">总金额</text><text class="value">{{ formatCurrency(item.totalAmount)
169 192 }}</text></view>
170   - <view class="row"><text class="label">发货日期</text><text class="value">{{ item.orderDate }}</text></view>
  193 + <view class="row"><text class="label">发货日期</text><text class="value">{{ item.deliveryDate }}</text></view>
171 194 </view>
172 195 </view>
173 196 <SingleSelectSheet :visible.sync="sheet.visible" :title="sheet.title" :options="sheet.options" v-model="sheet.value" @confirm="onProductConfirm" />
... ... @@ -181,7 +204,7 @@ export default {
181 204 mode: { type: String, default: 'add' },
182 205 list: { type: Array, default: () => [] },
183 206 max: { type: Number, default: 8 },
184   - orderDateBase: { type: String, default: '' },
  207 + deliveryDateBase: { type: String, default: '' },
185 208 options: { type: Array, default: () => [] }
186 209 },
187 210 components: { SingleSelectSheet },
... ... @@ -223,10 +246,18 @@ export default {
223 246 },
224 247 methods: {
225 248 defaultItem() {
226   - return { productId: '', productName: '', industry: '', brand: '', quality: '', thickness: '', thicknessTolPos: '', thicknessTolNeg: '', width: '', widthTolPos: '', widthTolNeg: '', length: '', lengthTolPos: '', lengthTolNeg: '', status: '', quantity: '', unitPrice: '', processingFee: undefined, amountExcludingTax: 0, totalAmount: 0, orderDate: '' }
  249 + return { productId: '', productName: '', industry: '', brand: '', quality: '', thickness: '', thicknessTolPos: '', thicknessTolNeg: '', width: '', widthTolPos: '', widthTolNeg: '', length: '', lengthTolPos: '', lengthTolNeg: '',processingFee: undefined, status: '', quantity: '', unitPrice: '', amountExcludingTax: 0, totalAmount: 0, deliveryDate: '' }
227 250 },
228   - onImmediateChange(idx) {
229   - this.$nextTick(() => this.recalculate(idx))
  251 + onNonNegativeInput(idx, field) {
  252 + const it = this.items[idx]
  253 + if (!it) return
  254 + let v = String(it[field] != null ? it[field] : '')
  255 + v = v.replace(/[^0-9.]/g, '')
  256 + v = v.replace(/(\..*)\./g, '$1')
  257 + if (v.startsWith('.')) v = '0' + v
  258 + it[field] = v
  259 + this.$set(this.items, idx, it)
  260 + if (field === 'quantity' || field === 'unitPrice') this.$nextTick(() => this.recalculate(idx))
230 261 },
231 262 toNumber(val) {
232 263 if (typeof val === 'number') return isNaN(val) ? 0 : val
... ... @@ -239,21 +270,21 @@ export default {
239 270 const m = Math.pow(10, digits)
240 271 return Math.round(n * m) / m
241 272 },
242   - onNumberBlur(idx, field, digits) {
  273 + onNonNegativeBlur(idx, field, digits) {
243 274 const it = this.items[idx]
244 275 if (!it) return
245 276 const raw = it[field]
246   - // 如果为空则保持为空,不自动置为0,仅重新计算依赖字段
247 277 if (raw === '' || raw === null || raw === undefined) {
248 278 this.$set(this.items, idx, it)
249   - this.recalculate(idx)
  279 + if (field === 'quantity' || field === 'unitPrice') this.recalculate(idx)
250 280 return
251 281 }
252   - const num = this.toNumber(raw)
  282 + let num = this.toNumber(raw)
  283 + if (isNaN(num) || num < 0) num = 0
253 284 const rounded = this.round(num, digits)
254 285 it[field] = rounded
255 286 this.$set(this.items, idx, it)
256   - this.recalculate(idx)
  287 + if (field === 'quantity' || field === 'unitPrice') this.recalculate(idx)
257 288 },
258 289 formatCurrency(val) {
259 290 if (val == null || val === '') return ''
... ... @@ -324,15 +355,15 @@ export default {
324 355 onDateChange(idx, e) {
325 356 const it = this.items[idx]
326 357 if (!it) return
327   - const val = typeof e === 'string' ? e : (e && e.detail && e.detail.value) ? e.detail.value : it.orderDate
  358 + const val = typeof e === 'string' ? e : (e && e.detail && e.detail.value) ? e.detail.value : it.deliveryDate
328 359 const dateStr = String(val).slice(0, 10)
329   - const base = this.orderDateBase ? new Date(this.orderDateBase) : null
  360 + const base = this.deliveryDateBase ? new Date(this.deliveryDateBase) : null
330 361 const d = new Date(dateStr)
331 362 if (base && !isNaN(d.getTime()) && d.getTime() < base.getTime()) {
332 363 uni.showToast({ title: '发货日期不得早于订货日期', icon: 'none' })
333   - it.orderDate = this.orderDateBase
  364 + it.deliveryDate = this.deliveryDateBase
334 365 } else {
335   - it.orderDate = dateStr
  366 + it.deliveryDate = dateStr
336 367 }
337 368 this.$set(this.items, idx, it)
338 369 },
... ... @@ -388,12 +419,13 @@ export default {
388 419 height: 40rpx;
389 420 }
390 421
391   - .opCollapse {
392   - color: rgba(0, 0, 0, 0.6);
393   - width: 32rpx;
394   - height: 28rpx;
395   - margin-right: 16rpx;
396   - }
  422 +.opCollapse {
  423 + color: rgba(0, 0, 0, 0.6);
  424 + width: 32rpx;
  425 + height: 28rpx;
  426 + margin-right: 16rpx;
  427 + margin-top: 8rpx;
  428 +}
397 429
398 430
399 431 .block {
... ... @@ -504,8 +536,46 @@ export default {
504 536
505 537 .value {
506 538 flex: 1;
507   - text-align: right;
  539 + // text-align: right;
508 540 color: rgba(0, 0, 0, 0.9);
509 541 font-size: 28rpx;
510 542 }
  543 + .value-spec {
  544 + height: 48rpx;
  545 + display: flex;
  546 + align-items: center;
  547 + color: #000000;
  548 + // justify-content: end;
  549 + &_box {
  550 + position: relative;
  551 + width: 60rpx;
  552 + height: 48rpx;
  553 +
  554 + &_1 {
  555 + font-size: 16rpx;
  556 + position: absolute;
  557 + top: -10rpx;
  558 + left: 0;
  559 + }
  560 +
  561 + &_2 {
  562 + font-size: 16rpx;
  563 + position: absolute;
  564 + bottom: -10rpx;
  565 + left: 0;
  566 + }
  567 + }
  568 +
  569 + &_val {
  570 + font-size: 28rpx;
  571 +
  572 + &.p12 {
  573 + padding-right: 12rpx;
  574 + }
  575 + }
  576 + }
  577 + .row-spec {
  578 + height: 60rpx;
  579 + align-items: center;
  580 + }
511 581 </style>
... ...
... ... @@ -39,7 +39,7 @@
39 39 <view class="item-title"><text class="required">*</text><text>生产厂</text></view>
40 40 </template>
41 41 </uni-list-item>
42   - <ProductRel mode="add" :orderDateBase="form.orderDate" @change="onProductsChange" :options="productList" />
  42 + <ProductRel mode="add" :deliveryDateBase="form.deliveryDate" @change="onProductsChange" :options="productList" />
43 43 <uni-list-item title="合计人民币金额(大写)">
44 44 <template v-slot:footer>
45 45 <uni-easyinput v-model="form.totalAmountCapital" placeholder="自动计算" :inputBorder="false" disabled />
... ... @@ -92,33 +92,25 @@
92 92 :inputBorder="false" />
93 93 </template>
94 94 </uni-list-item>
95   - <view class="group">
96   - <view class="group-title">特别条款要求</view>
97   - <view class="radio-list">
98   - <view v-for="(opt, i) in specialTermsList" :key="'cr-' + i" class="radio-item"
99   - @click="onRadioSelect('specialTerms', 'specialTermsName', opt)">
100   - <view :class="['radio', { checked: form.specialTerms === opt.value }]" />
101   - <text class="label">{{ opt.label }}</text>
102   - </view>
103   - </view>
104   - </view>
105   - <view class="group">
106   - <view class="group-title">执行标准</view>
107   - <view class="radio-list">
108   - <view v-for="(opt, i) in executionStandardList" :key="'es-' + i" class="radio-item"
109   - @click="onRadioSelect('executionStandard', 'executionStandardName', opt)">
110   - <view :class="['radio', { checked: form.executionStandard === opt.value }]" />
111   - <text class="label">{{ opt.label }}</text>
112   - </view>
113   - </view>
114   - </view>
  95 + <uni-list-item class="select-item" :class="form.specialTermsName ? 'is-filled' : 'is-empty'" clickable
  96 + @click="openSheet('specialTerms')" :rightText="form.specialTermsName || '请选择'" showArrow>
  97 + <template v-slot:body>
  98 + <view class="item-title"><text class="required">*</text><text>特别条款要求</text></view>
  99 + </template>
  100 + </uni-list-item>
  101 + <uni-list-item class="select-item" :class="form.executionStandardName ? 'is-filled' : 'is-empty'" clickable
  102 + @click="openSheet('executionStandard')" :rightText="form.executionStandardName || '请选择'" showArrow>
  103 + <template v-slot:body>
  104 + <view class="item-title"><text>执行标准</text></view>
  105 + </template>
  106 + </uni-list-item>
115 107 <uni-list-item v-if="form.executionStandard === 'OTHER'" title="其他">
116 108 <template v-slot:footer>
117 109 <uni-easyinput v-model="form.executionStandardRemarks" placeholder="请输入其他标准备注"
118 110 :inputBorder="false" />
119 111 </template>
120 112 </uni-list-item>
121   - <uni-list-item title="特别说明">
  113 + <uni-list-item title="特别说明" style="margin-top: 20rpx;">
122 114 <template v-slot:footer>
123 115 <uni-easyinput v-model="form.specialInstructions" placeholder="请输入特别说明" :inputBorder="false" />
124 116 </template>
... ... @@ -181,7 +173,7 @@
181 173 数量
182 174 </div>
183 175 <div class="total-item-price">
184   - {{ (sumQuantity || 0).toFixed(2) }}t
  176 + {{ (totalQuantity || 0).toFixed(2) }}kg
185 177 </div>
186 178 </div>
187 179 <div class="total-item">
... ... @@ -189,7 +181,7 @@
189 181 不含税金额
190 182 </div>
191 183 <div class="total-item-price text-red">
192   - ¥{{ (sumAmountExcl || 0).toFixed(2) }}
  184 + ¥{{ (totalAmountExcludingTax || 0).toFixed(2) }}
193 185 </div>
194 186 </div>
195 187 <div class="total-item">
... ... @@ -197,7 +189,7 @@
197 189 总金额
198 190 </div>
199 191 <div class="total-item-price text-red">
200   - ¥{{ (sumTotal || 0).toFixed(2) }}
  192 + ¥{{ (totalAmountIncludingTax || 0).toFixed(2) }}
201 193 </div>
202 194 </div>
203 195 </div>
... ... @@ -233,6 +225,7 @@ export default {
233 225 buyer: '',
234 226 buyerName: '',
235 227 orderDate: '',
  228 + deliveryDate: '',
236 229 designatedConsignee: '',
237 230 specialTerms: '',
238 231 specialTermsName: '',
... ... @@ -263,9 +256,9 @@ export default {
263 256 yesNoList: [{ label: '是', value: true }, { label: '否', value: false }],
264 257 sheet: { visible: false, title: '请选择', field: '', options: [], value: '' },
265 258 relate: { visible: false, title: '选择', source: '', display: [], multiple: false, rowKey: 'id', selectedKeys: [], fieldKey: '' },
266   - sumQuantity: 0,
267   - sumAmountExcl: 0,
268   - sumTotal: 0,
  259 + totalQuantity: 0,
  260 + totalAmountExcludingTax: 0,
  261 + totalAmountIncludingTax: 0,
269 262 productLineList: [],
270 263 productList: [],
271 264 customerRemarks: [],
... ... @@ -369,9 +362,9 @@ export default {
369 362 const sumQ = list.reduce((acc, it) => acc + (parseFloat(it.quantity) || 0), 0)
370 363 const sumE = list.reduce((acc, it) => acc + (parseFloat(it.amountExcludingTax) || 0), 0)
371 364 const sumT = list.reduce((acc, it) => acc + (parseFloat(it.totalAmount) || 0), 0)
372   - this.sumQuantity = sumQ
373   - this.sumAmountExcl = sumE
374   - this.sumTotal = sumT
  365 + this.totalQuantity = sumQ
  366 + this.totalAmountExcludingTax = sumE
  367 + this.totalAmountIncludingTax = sumT
375 368 this.form.totalAmountCapital = formatCurrencyToChinese(sumT)
376 369 this.productLineList = list
377 370 },
... ... @@ -447,6 +440,10 @@ export default {
447 440 setSheet('生产厂', opts)
448 441 } else if (field === 'supplier') {
449 442 setSheet('供方', this.supplierList)
  443 + } else if (field === 'specialTerms') {
  444 + setSheet('特别条款要求', this.specialTermsList)
  445 + } else if (field === 'executionStandard') {
  446 + setSheet('执行标准', this.executionStandardList)
450 447 } else if (field === 'includesPackagingFee') {
451 448 setSheet('单价中是否已包含包装费', this.yesNoList)
452 449 } else if (field === 'includesTransportFee') {
... ... @@ -517,9 +514,9 @@ export default {
517 514 ...formForSubmit,
518 515 destination,
519 516 type: 'INTL_INVENTORY_AGMT',
520   - sumQuantity: this.sumQuantity,
521   - sumAmountExcl: this.sumAmountExcl,
522   - sumTotal: this.sumTotal,
  517 + totalQuantity: this.totalQuantity,
  518 + totalAmountExcludingTax: this.totalAmountExcludingTax,
  519 + totalAmountIncludingTax: this.totalAmountIncludingTax,
523 520 contractDistributorLineList: lines
524 521 })
525 522 console.log('onSubmit__payload', payload)
... ... @@ -538,18 +535,30 @@ export default {
538 535 { key: 'supplier', label: '供方' },
539 536 { key: 'buyer', label: '需方' },
540 537 { key: 'orderDate', label: '订货日期' },
  538 + { key: 'unit', label: '单位' },
541 539 { key: 'workshopId', label: '生产厂' },
  540 + { key: 'specialTerms', label: '特别条款要求' },
542 541 ]
543 542 for (const it of checks) {
544 543 const val = this.form[it.key]
545 544 const empty = (val === undefined || val === null || (typeof val === 'string' && val.trim() === '') || (typeof val === 'number' && isNaN(val)))
546 545 if (empty) { uni.showToast({ title: `请先选择${it.label}`, icon: 'none' }); return false }
547 546 }
548   - if (!Array.isArray(this.productLineList) || this.productLineList.length === 0) {
  547 + const list = Array.isArray(this.productLineList) ? this.productLineList : []
  548 + if (list.length === 0) {
549 549 uni.showToast({ title: '请至少添加一条产品明细', icon: 'none' }); return false
550 550 }
551   - for (const [idx, it] of this.productLineList.entries()) {
552   - if (!it.productName || !it.quantity || !it.unitPrice) {
  551 + const strEmpty = (v) => (v === undefined || v === null || (typeof v === 'string' && v.trim() === ''))
  552 + const numEmpty = (v) => (v === undefined || v === null || v === '' || (typeof v === 'number' && isNaN(v)))
  553 + for (const [idx, it] of list.entries()) {
  554 + if (
  555 + strEmpty(it.productName) ||
  556 + strEmpty(it.industry) ||
  557 + strEmpty(it.quality) ||
  558 + strEmpty(it.brand) ||
  559 + numEmpty(it.quantity) ||
  560 + strEmpty(it.deliveryDate)
  561 + ) {
553 562 uni.showToast({ title: `第${idx + 1}条明细未完整填写`, icon: 'none' }); return false
554 563 }
555 564 }
... ... @@ -577,7 +586,7 @@ export default {
577 586 color: rgba(0, 0, 0, 0.6);
578 587 line-height: 32rpx;
579 588 width: 240rpx;
580   - padding: 24rpx 0;
  589 + padding: 12rpx 0;
581 590 }
582 591 .total-item-price {
583 592 font-weight: 600;
... ... @@ -599,7 +608,7 @@ export default {
599 608
600 609 .scroll {
601 610 flex: 1;
602   - padding: 12rpx 0 480rpx !important;
  611 + padding: 12rpx 0 392rpx !important;
603 612 }
604 613
605 614 .footer {
... ...
... ... @@ -53,13 +53,13 @@
53 53 }}</text></view>
54 54 </view>
55 55
56   - <view class="section" v-if="status === 'STANDARD'">
  56 + <view class="section" v-if="detail.status === 'STANDARD'">
57 57 <view class="row"><text class="label">规范性合同</text><text class="value" style="color: #3D48A3;">{{
58 58 detail.standardFileName || '-' }}</text></view>
59 59 <view class="row"><text class="label">合同是否规范</text><text class="value">{{
60 60 detail.standardStandardized ? '是' : '否' }}</text></view>
61 61 </view>
62   - <view class="section" v-if="status === 'FORMAL'">
  62 + <view class="section" v-if="detail.status === 'FORMAL'">
63 63 <view class="row"><text class="label">规范性合同</text><text class="value" style="color: #3D48A3;">{{
64 64 detail.formalFileName || '-' }}</text></view>
65 65 <view class="row"><text class="label">合同是否规范</text><text class="value">{{ detail.formalStandardized
... ...
... ... @@ -61,7 +61,9 @@
61 61 <text>订单总额</text><text class="amount" :style="{ color: '#b67a76' }">{{ item.totalAmountIncludingTax ? '¥' : '' }}{{ formatAmount(item.totalAmountIncludingTax) || '-' }}</text>
62 62 </view>
63 63 <view class="info-row" v-if="item.status === 'STANDARD' || item.status === 'FORMAL'">
64   - <text>{{ item.status === 'STANDARD' ? '标准合同' : '正式合同' }}规范性审核状态</text><span class="info-status" :style="item.standardApprovedName ? getStatusCss(item.standardApprovedName) : ''">{{ item.standardApprovedName || '-' }}</span>
  64 + <text>{{ item.status === 'STANDARD' ? '标准合同' : '正式合同' }}规范性审核状态</text>
  65 + <span v-if="item.status === 'STANDARD' ? item.standardApprovedName : item.formalApprovedName" class="info-status" :style="getStatusCss(item.status === 'STANDARD' ? item.standardApprovedName : item.formalApprovedName)">{{ item.status === 'STANDARD' ? item.standardApprovedName : item.formalApprovedName }}</span>
  66 + <span v-else>-</span>
65 67 </view>
66 68 <view class="info-row">
67 69 <text>订货日期</text><text>{{ item.orderDate }}</text>
... ...
... ... @@ -108,7 +108,7 @@
108 108 数量
109 109 </div>
110 110 <div class="total-item-price">
111   - {{ (sumQuantity || 0).toFixed(2) }}t
  111 + {{ (totalQuantity || 0).toFixed(2) }}t
112 112 </div>
113 113 </div>
114 114 <div class="total-item">
... ... @@ -116,7 +116,7 @@
116 116 不含税金额
117 117 </div>
118 118 <div class="total-item-price text-red">
119   - ¥{{ (sumAmountExcl || 0).toFixed(2) }}
  119 + ¥{{ (totalAmountExcludingTax || 0).toFixed(2) }}
120 120 </div>
121 121 </div>
122 122 <div class="total-item">
... ... @@ -124,7 +124,7 @@
124 124 总金额
125 125 </div>
126 126 <div class="total-item-price text-red">
127   - ¥{{ (sumTotal || 0).toFixed(2) }}
  127 + ¥{{ (totalAmountIncludingTax || 0).toFixed(2) }}
128 128 </div>
129 129 </div>
130 130 </div>
... ... @@ -147,15 +147,15 @@ export default {
147 147 }
148 148 },
149 149 computed: {
150   - sumQuantity() {
  150 + totalQuantity() {
151 151 const qty = this.items.filter(it => it.locked).reduce((p, c) => p + this.toNumber(c.quantity), 0)
152 152 return this.round(qty, 2)
153 153 },
154   - sumAmountExcl() {
  154 + totalAmountExcludingTax() {
155 155 const sum = this.items.filter(it => it.locked).reduce((p, c) => p + this.toNumber(c.amountExcludingTax), 0)
156 156 return this.round(sum, 2)
157 157 },
158   - sumTotal() { return this.totalAmount },
  158 + totalAmountIncludingTax() { return this.totalAmount },
159 159 totalAmount() {
160 160 let sum = 0
161 161 for (const it of this.items) {
... ... @@ -325,9 +325,9 @@ export default {
325 325 const payload = {
326 326 id: this.id,
327 327 totalAmountCapital: formatCurrencyToChinese(this.sumTotal),
328   - totalAmountExcludingTax: this.sumAmountExcl,
329   - totalAmountIncludingTax: this.sumTotal,
330   - totalQuantity: this.sumQuantity,
  328 + totalAmountExcludingTax: this.totalAmountExcludingTax,
  329 + totalAmountIncludingTax: this.totalAmountIncludingTax,
  330 + totalQuantity: this.totalQuantity,
331 331 type:'INTL_INVENTORY_AGMT',
332 332 contractDistributorLineList: selected
333 333 }
... ... @@ -362,7 +362,7 @@ export default {
362 362
363 363 .scroll {
364 364 flex: 1;
365   - padding: 12rpx 0 480rpx !important;
  365 + padding: 12rpx 0 392rpx !important;
366 366 }
367 367
368 368 .header {
... ... @@ -646,7 +646,7 @@ export default {
646 646 color: rgba(0, 0, 0, 0.6);
647 647 line-height: 32rpx;
648 648 width: 240rpx;
649   - padding: 24rpx 0;
  649 + padding: 12rpx 0;
650 650 }
651 651
652 652 .total-item-price {
... ...
... ... @@ -41,7 +41,7 @@
41 41 </template>
42 42 </uni-list-item>
43 43
44   - <ProductRel mode="add" :orderDateBase="form.orderDate" :list="productLineList" @change="onProductsChange" :options="productList" />
  44 + <ProductRel mode="add" :deliveryDateBase="form.deliveryDate" :list="productLineList" @change="onProductsChange" :options="productList" />
45 45
46 46 <uni-list-item title="合计人民币金额(大写)">
47 47 <template v-slot:footer>
... ... @@ -98,34 +98,25 @@
98 98 :inputBorder="false" />
99 99 </template>
100 100 </uni-list-item>
101   -
102   - <view class="group">
103   - <view class="group-title">特别条款要求</view>
104   - <view class="radio-list">
105   - <view v-for="(opt, i) in specialTermsList" :key="'cr-' + i" class="radio-item"
106   - @click="onRadioSelect('specialTerms', 'specialTermsName', opt)">
107   - <view :class="['radio', { checked: form.specialTerms === opt.value }]" />
108   - <text class="label">{{ opt.label }}</text>
109   - </view>
110   - </view>
111   - </view>
112   - <view class="group">
113   - <view class="group-title">执行标准</view>
114   - <view class="radio-list">
115   - <view v-for="(opt, i) in executionStandardList" :key="'es-' + i" class="radio-item"
116   - @click="onRadioSelect('executionStandard', 'executionStandardName', opt)">
117   - <view :class="['radio', { checked: form.executionStandard === opt.value }]" />
118   - <text class="label">{{ opt.label }}</text>
119   - </view>
120   - </view>
121   - </view>
  101 + <uni-list-item class="select-item" :class="form.specialTermsName ? 'is-filled' : 'is-empty'" clickable
  102 + @click="openSheet('specialTerms')" :rightText="form.specialTermsName || '请选择'" showArrow>
  103 + <template v-slot:body>
  104 + <view class="item-title"><text class="required">*</text><text>特别条款要求</text></view>
  105 + </template>
  106 + </uni-list-item>
  107 + <uni-list-item class="select-item" :class="form.executionStandardName ? 'is-filled' : 'is-empty'" clickable
  108 + @click="openSheet('executionStandard')" :rightText="form.executionStandardName || '请选择'" showArrow>
  109 + <template v-slot:body>
  110 + <view class="item-title"><text>执行标准</text></view>
  111 + </template>
  112 + </uni-list-item>
122 113 <uni-list-item v-if="form.executionStandard === 'OTHER'" title="其他">
123 114 <template v-slot:footer>
124 115 <uni-easyinput v-model="form.executionStandardRemarks" placeholder="请输入其他标准备注"
125 116 :inputBorder="false" />
126 117 </template>
127 118 </uni-list-item>
128   - <uni-list-item title="特别说明">
  119 + <uni-list-item title="特别说明" style="margin-top: 20rpx;">
129 120 <template v-slot:footer>
130 121 <uni-easyinput v-model="form.specialInstructions" placeholder="请输入特别说明" :inputBorder="false" />
131 122 </template>
... ... @@ -177,15 +168,15 @@
177 168 <div class="total-text">合计</div>
178 169 <div class="total-item">
179 170 <div class="total-item-text">数量</div>
180   - <div class="total-item-price">{{ (sumQuantity || 0).toFixed(2) }}t</div>
  171 + <div class="total-item-price">{{ (totalQuantity || 0).toFixed(2) }}kg</div>
181 172 </div>
182 173 <div class="total-item">
183 174 <div class="total-item-text">不含税金额</div>
184   - <div class="total-item-price text-red">¥{{ (sumAmountExcl || 0).toFixed(2) }}</div>
  175 + <div class="total-item-price text-red">¥{{ (totalAmountExcludingTax || 0).toFixed(2) }}</div>
185 176 </div>
186 177 <div class="total-item">
187 178 <div class="total-item-text">总金额</div>
188   - <div class="total-item-price text-red">¥{{ (sumTotal || 0).toFixed(2) }}</div>
  179 + <div class="total-item-price text-red">¥{{ (totalAmountIncludingTax || 0).toFixed(2) }}</div>
189 180 </div>
190 181 </div>
191 182 <button class="btn submit" type="primary" @click="onSubmit">保存</button>
... ... @@ -223,6 +214,7 @@ export default {
223 214 workshopId: '',
224 215 workshopName: '',
225 216 orderDate: '',
  217 + deliveryDate: '',
226 218 designatedConsignee: '',
227 219 specialTerms: '',
228 220 specialTermsName: '',
... ... @@ -256,9 +248,9 @@ export default {
256 248 yesNoList: [{ label: '是', value: true }, { label: '否', value: false }],
257 249 sheet: { visible: false, title: '请选择', field: '', options: [], value: '' },
258 250 relate: { visible: false, title: '选择', source: '', display: [], multiple: false, rowKey: 'id', selectedKeys: [], fieldKey: '' },
259   - sumQuantity: 0,
260   - sumAmountExcl: 0,
261   - sumTotal: 0,
  251 + totalQuantity: 0,
  252 + totalAmountExcludingTax: 0,
  253 + totalAmountIncludingTax: 0,
262 254 productLineList: [],
263 255 newProductLineList: [],
264 256 productList: []
... ... @@ -349,9 +341,9 @@ export default {
349 341 const sumQ = list.reduce((acc, it) => acc + (parseFloat(it.quantity) || 0), 0)
350 342 const sumE = list.reduce((acc, it) => acc + (parseFloat(it.amountExcludingTax) || 0), 0)
351 343 const sumT = list.reduce((acc, it) => acc + (parseFloat(it.totalAmount) || 0), 0)
352   - this.sumQuantity = sumQ
353   - this.sumAmountExcl = sumE
354   - this.sumTotal = sumT
  344 + this.totalQuantity = sumQ
  345 + this.totalAmountExcludingTax = sumE
  346 + this.totalAmountIncludingTax = sumT
355 347 this.form.totalAmountCapital = formatCurrencyToChinese(sumT)
356 348 },
357 349 async loadSuppliers() {
... ... @@ -399,6 +391,10 @@ export default {
399 391 setSheet('生产厂', opts)
400 392 } else if (field === 'supplier') {
401 393 setSheet('供方', this.supplierList)
  394 + } else if (field === 'specialTerms') {
  395 + setSheet('特别条款要求', this.specialTermsList)
  396 + } else if (field === 'executionStandard') {
  397 + setSheet('执行标准', this.executionStandardList)
402 398 } else if (field === 'includesPackagingFee') {
403 399 setSheet('单价中是否已包含包装费', this.yesNoList)
404 400 } else if (field === 'includesTransportFee') {
... ... @@ -443,18 +439,30 @@ export default {
443 439 { key: 'supplier', label: '供方' },
444 440 { key: 'buyer', label: '需方' },
445 441 { key: 'orderDate', label: '订货日期' },
  442 + { key: 'unit', label: '单位' },
446 443 { key: 'workshopId', label: '生产厂' },
  444 + { key: 'specialTerms', label: '特别条款要求' },
447 445 ]
448 446 for (const it of checks) {
449 447 const val = this.form[it.key]
450 448 const empty = (val === undefined || val === null || (typeof val === 'string' && val.trim() === '') || (typeof val === 'number' && isNaN(val)))
451 449 if (empty) { uni.showToast({ title: `请先选择${it.label}`, icon: 'none' }); return false }
452 450 }
453   - if (!Array.isArray(this.productLineList) || this.productLineList.length === 0) {
  451 + const list = Array.isArray(this.newProductLineList) ? this.newProductLineList : []
  452 + if (list.length === 0) {
454 453 uni.showToast({ title: '请至少添加一条产品明细', icon: 'none' }); return false
455 454 }
456   - for (const [idx, it] of this.productLineList.entries()) {
457   - if (!it.productName || !it.quantity || !it.unitPrice) {
  455 + const strEmpty = (v) => (v === undefined || v === null || (typeof v === 'string' && v.trim() === ''))
  456 + const numEmpty = (v) => (v === undefined || v === null || v === '' || (typeof v === 'number' && isNaN(v)))
  457 + for (const [idx, it] of list.entries()) {
  458 + if (
  459 + strEmpty(it.productName) ||
  460 + strEmpty(it.industry) ||
  461 + strEmpty(it.quality) ||
  462 + strEmpty(it.brand) ||
  463 + numEmpty(it.quantity) ||
  464 + strEmpty(it.deliveryDate)
  465 + ) {
458 466 uni.showToast({ title: `第${idx + 1}条明细未完整填写`, icon: 'none' }); return false
459 467 }
460 468 }
... ... @@ -486,9 +494,9 @@ export default {
486 494 id: this.form.id,
487 495 destination,
488 496 type: 'INTL_INVENTORY_AGMT',
489   - sumQuantity: this.sumQuantity,
490   - sumAmountExcl: this.sumAmountExcl,
491   - sumTotal: this.sumTotal,
  497 + totalQuantity: this.totalQuantity,
  498 + totalAmountExcludingTax: this.totalAmountExcludingTax,
  499 + totalAmountIncludingTax: this.totalAmountIncludingTax,
492 500 contractDistributorLineList: lines
493 501 })
494 502 try {
... ... @@ -524,7 +532,7 @@ export default {
524 532 color: rgba(0, 0, 0, 0.6);
525 533 line-height: 32rpx;
526 534 width: 240rpx;
527   - padding: 24rpx 0;
  535 + padding: 12rpx 0;
528 536 }
529 537
530 538 .total-item-price {
... ... @@ -547,7 +555,7 @@ export default {
547 555
548 556 .scroll {
549 557 flex: 1;
550   - padding: 12rpx 0 480rpx !important;
  558 + padding: 12rpx 0 392rpx !important;
551 559 }
552 560
553 561 .footer {
... ...
... ... @@ -55,51 +55,51 @@
55 55 </uni-list-item>
56 56 <uni-list-item title="厚度">
57 57 <template v-slot:footer>
58   - <uni-easyinput v-model="item.thickness" :inputBorder="false" placeholder="请输入厚度" />
  58 + <uni-easyinput type="digit" v-model="item.thickness" :inputBorder="false" placeholder="请输入厚度" @input="onNonNegativeInput(idx, 'thickness')" @blur="onNonNegativeBlur(idx, 'thickness', 2)" />
59 59 </template>
60 60 </uni-list-item>
61 61 <uni-list-item title="厚度公差(单项+)">
62 62 <template v-slot:footer>
63   - <uni-easyinput v-model="item.thicknessTolPos" :inputBorder="false"
64   - placeholder="请输入厚度公差(单项+)" />
  63 + <uni-easyinput type="digit" v-model="item.thicknessTolPos" :inputBorder="false"
  64 + placeholder="请输入厚度公差(单项+)" @input="onNonNegativeInput(idx, 'thicknessTolPos')" @blur="onNonNegativeBlur(idx, 'thicknessTolPos', 2)" />
65 65 </template>
66 66 </uni-list-item>
67 67 <uni-list-item title="厚度公差(单项-)">
68 68 <template v-slot:footer>
69   - <uni-easyinput v-model="item.thicknessTolNeg" :inputBorder="false"
70   - placeholder="请输入厚度公差(单项-)" />
  69 + <uni-easyinput type="digit" v-model="item.thicknessTolNeg" :inputBorder="false"
  70 + placeholder="请输入厚度公差(单项-)" @input="onNonNegativeInput(idx, 'thicknessTolNeg')" @blur="onNonNegativeBlur(idx, 'thicknessTolNeg', 2)" />
71 71 </template>
72 72 </uni-list-item>
73 73 <uni-list-item title="宽度">
74 74 <template v-slot:footer>
75   - <uni-easyinput v-model="item.width" :inputBorder="false" placeholder="请输入宽度" />
  75 + <uni-easyinput type="digit" v-model="item.width" :inputBorder="false" placeholder="请输入宽度" @input="onNonNegativeInput(idx, 'width')" @blur="onNonNegativeBlur(idx, 'width', 2)" />
76 76 </template>
77 77 </uni-list-item>
78 78 <uni-list-item title="宽度公差(单项+)">
79 79 <template v-slot:footer>
80   - <uni-easyinput v-model="item.widthTolPos" :inputBorder="false" placeholder="请输入宽度公差(单项+)" />
  80 + <uni-easyinput type="digit" v-model="item.widthTolPos" :inputBorder="false" placeholder="请输入宽度公差(单项+)" @input="onNonNegativeInput(idx, 'widthTolPos')" @blur="onNonNegativeBlur(idx, 'widthTolPos', 2)" />
81 81 </template>
82 82 </uni-list-item>
83 83 <uni-list-item title="宽度公差(单项-)">
84 84 <template v-slot:footer>
85   - <uni-easyinput v-model="item.widthTolNeg" :inputBorder="false" placeholder="请输入宽度公差(单项-)" />
  85 + <uni-easyinput type="digit" v-model="item.widthTolNeg" :inputBorder="false" placeholder="请输入宽度公差(单项-)" @input="onNonNegativeInput(idx, 'widthTolNeg')" @blur="onNonNegativeBlur(idx, 'widthTolNeg', 2)" />
86 86 </template>
87 87 </uni-list-item>
88 88 <uni-list-item title="长度">
89 89 <template v-slot:footer>
90   - <uni-easyinput v-model="item.length" :inputBorder="false" placeholder="请输入长度" />
  90 + <uni-easyinput type="digit" v-model="item.length" :inputBorder="false" placeholder="请输入长度" @input="onNonNegativeInput(idx, 'length')" @blur="onNonNegativeBlur(idx, 'length', 2)" />
91 91 </template>
92 92 </uni-list-item>
93 93 <uni-list-item title="长度公差(单项+)">
94 94 <template v-slot:footer>
95   - <uni-easyinput v-model="item.lengthTolPos" :inputBorder="false"
96   - placeholder="请输入长度公差(单项+)" />
  95 + <uni-easyinput type="digit" v-model="item.lengthTolPos" :inputBorder="false"
  96 + placeholder="请输入长度公差(单项+)" @input="onNonNegativeInput(idx, 'lengthTolPos')" @blur="onNonNegativeBlur(idx, 'lengthTolPos', 2)" />
97 97 </template>
98 98 </uni-list-item>
99 99 <uni-list-item title="长度公差(单项-)">
100 100 <template v-slot:footer>
101   - <uni-easyinput v-model="item.lengthTolNeg" :inputBorder="false"
102   - placeholder="请输入长度公差(单项-)" />
  101 + <uni-easyinput type="digit" v-model="item.lengthTolNeg" :inputBorder="false"
  102 + placeholder="请输入长度公差(单项-)" @input="onNonNegativeInput(idx, 'lengthTolNeg')" @blur="onNonNegativeBlur(idx, 'lengthTolNeg', 2)" />
103 103 </template>
104 104 </uni-list-item>
105 105 <uni-list-item title="状态">
... ... @@ -109,7 +109,7 @@
109 109 </uni-list-item>
110 110 <uni-list-item title="数量">
111 111 <template v-slot:footer>
112   - <uni-easyinput v-model="item.quantity" type="number" :inputBorder="false" placeholder="请输入数量" @input="onImmediateChange(idx)" @blur="onNumberBlur(idx, 'quantity', 0)" />
  112 + <uni-easyinput v-model="item.quantity" type="digit" :inputBorder="false" placeholder="请输入数量" @input="onNonNegativeInput(idx, 'quantity')" @blur="onNonNegativeBlur(idx, 'quantity', 2)" />
113 113 </template>
114 114 </uni-list-item>
115 115 <uni-list-item title="单价">
... ... @@ -134,7 +134,7 @@
134 134 </uni-list-item>
135 135 <uni-list-item title="发货日期">
136 136 <template v-slot:footer>
137   - <uni-datetime-picker type="date" v-model="item.orderDate" @change="onDateChange(idx, $event)" />
  137 + <uni-datetime-picker type="date" v-model="item.deliveryDate" @change="onDateChange(idx, $event)" />
138 138 </template>
139 139 </uni-list-item>
140 140 </uni-list>
... ... @@ -156,7 +156,30 @@
156 156 <view class="row"><text class="label">行业</text><text class="value">{{ item.industry }}</text></view>
157 157 <view class="row"><text class="label">牌号</text><text class="value">{{ item.brand }}</text></view>
158 158 <view class="row"><text class="label">品质</text><text class="value">{{ item.quality }}</text></view>
159   - <view class="row"><text class="label">规格</text><text class="value">{{ item.specDisplay }}</text></view>
  159 + <!-- 厚(公差) * 宽(公差) * 长(公差) -->
  160 + <view class="row row-spec"><text class="label">规格(mm)</text>
  161 + <view class="value value-spec">
  162 + <view v-if="item.thickness" class="value-spec_val">{{ item.thickness }}</view>
  163 + <view v-if="item.thickness" class="value-spec_box">
  164 + <view v-if="item.thicknessTolPos" class="value-spec_box_1">+{{ item.thicknessTolPos }}
  165 + </view>
  166 + <view v-if="item.thicknessTolNeg" class="value-spec_box_2">-{{ item.thicknessTolNeg }}
  167 + </view>
  168 + </view>
  169 + <view v-if="item.width" class="value-spec_val p12">*</view>
  170 + <view v-if="item.width" class="value-spec_val">{{ item.width }}</view>
  171 + <view v-if="item.width" class="value-spec_box">
  172 + <view v-if="item.widthTolPos" class="value-spec_box_1">+{{ item.widthTolPos }}</view>
  173 + <view v-if="item.widthTolNeg" class="value-spec_box_2">-{{ item.widthTolNeg }}</view>
  174 + </view>
  175 + <view v-if="item.length" class="value-spec_val p12">*</view>
  176 + <view v-if="item.length" class="value-spec_val">{{ item.length }}</view>
  177 + <view v-if="item.length" class="value-spec_box">
  178 + <view v-if="item.lengthTolPos" class="value-spec_box_1">+{{ item.lengthTolPos }}</view>
  179 + <view v-if="item.lengthTolNeg" class="value-spec_box_2">-{{ item.lengthTolNeg }}</view>
  180 + </view>
  181 + </view>
  182 + </view>
160 183 <view class="row"><text class="label">状态</text><text class="value">{{ item.status }}</text></view>
161 184 <view class="row"><text class="label">数量</text><text class="value">{{ item.quantity }}</text></view>
162 185 <view class="row"><text class="label">单价</text><text class="value">{{ formatCurrency(item.unitPrice)
... ... @@ -167,7 +190,7 @@
167 190 }}</text></view>
168 191 <view class="row"><text class="label">总金额</text><text class="value">{{ formatCurrency(item.totalAmount)
169 192 }}</text></view>
170   - <view class="row"><text class="label">发货日期</text><text class="value">{{ item.orderDate }}</text></view>
  193 + <view class="row"><text class="label">发货日期</text><text class="value">{{ item.deliveryDate }}</text></view>
171 194 </view>
172 195 </view>
173 196 <SingleSelectSheet :visible.sync="sheet.visible" :title="sheet.title" :options="sheet.options" v-model="sheet.value" @confirm="onProductConfirm" />
... ... @@ -181,7 +204,7 @@ export default {
181 204 mode: { type: String, default: 'add' },
182 205 list: { type: Array, default: () => [] },
183 206 max: { type: Number, default: 8 },
184   - orderDateBase: { type: String, default: '' },
  207 + deliveryDateBase: { type: String, default: '' },
185 208 options: { type: Array, default: () => [] }
186 209 },
187 210 components: { SingleSelectSheet },
... ... @@ -223,7 +246,18 @@ export default {
223 246 },
224 247 methods: {
225 248 defaultItem() {
226   - return { productId: '', productName: '', industry: '', brand: '', quality: '', thickness: '', thicknessTolPos: '', thicknessTolNeg: '', width: '', widthTolPos: '', widthTolNeg: '', length: '', lengthTolPos: '', lengthTolNeg: '', status: '', quantity: '', unitPrice: '', processingFee: undefined, amountExcludingTax: 0, totalAmount: 0, orderDate: '' }
  249 + return { productId: '', productName: '', industry: '', brand: '', quality: '', thickness: '', thicknessTolPos: '', thicknessTolNeg: '', width: '', widthTolPos: '', widthTolNeg: '', length: '', lengthTolPos: '', lengthTolNeg: '', status: '', quantity: '', unitPrice: '', processingFee: undefined, amountExcludingTax: 0, totalAmount: 0, deliveryDate: '' }
  250 + },
  251 + onNonNegativeInput(idx, field) {
  252 + const it = this.items[idx]
  253 + if (!it) return
  254 + let v = String(it[field] != null ? it[field] : '')
  255 + v = v.replace(/[^0-9.]/g, '')
  256 + v = v.replace(/(\..*)\./g, '$1')
  257 + if (v.startsWith('.')) v = '0' + v
  258 + it[field] = v
  259 + this.$set(this.items, idx, it)
  260 + if (field === 'quantity' || field === 'unitPrice') this.$nextTick(() => this.recalculate(idx))
227 261 },
228 262 onImmediateChange(idx) {
229 263 this.$nextTick(() => this.recalculate(idx))
... ... @@ -239,21 +273,21 @@ export default {
239 273 const m = Math.pow(10, digits)
240 274 return Math.round(n * m) / m
241 275 },
242   - onNumberBlur(idx, field, digits) {
  276 + onNonNegativeBlur(idx, field, digits) {
243 277 const it = this.items[idx]
244 278 if (!it) return
245 279 const raw = it[field]
246   - // 如果为空则保持为空,不自动置为0,仅重新计算依赖字段
247 280 if (raw === '' || raw === null || raw === undefined) {
248 281 this.$set(this.items, idx, it)
249   - this.recalculate(idx)
  282 + if (field === 'quantity' || field === 'unitPrice') this.recalculate(idx)
250 283 return
251 284 }
252   - const num = this.toNumber(raw)
  285 + let num = this.toNumber(raw)
  286 + if (isNaN(num) || num < 0) num = 0
253 287 const rounded = this.round(num, digits)
254 288 it[field] = rounded
255 289 this.$set(this.items, idx, it)
256   - this.recalculate(idx)
  290 + if (field === 'quantity' || field === 'unitPrice') this.recalculate(idx)
257 291 },
258 292 formatCurrency(val) {
259 293 if (val == null || val === '') return ''
... ... @@ -324,15 +358,15 @@ export default {
324 358 onDateChange(idx, e) {
325 359 const it = this.items[idx]
326 360 if (!it) return
327   - const val = typeof e === 'string' ? e : (e && e.detail && e.detail.value) ? e.detail.value : it.orderDate
  361 + const val = typeof e === 'string' ? e : (e && e.detail && e.detail.value) ? e.detail.value : it.deliveryDate
328 362 const dateStr = String(val).slice(0, 10)
329   - const base = this.orderDateBase ? new Date(this.orderDateBase) : null
  363 + const base = this.deliveryDateBase ? new Date(this.deliveryDateBase) : null
330 364 const d = new Date(dateStr)
331 365 if (base && !isNaN(d.getTime()) && d.getTime() < base.getTime()) {
332 366 uni.showToast({ title: '发货日期不得早于订货日期', icon: 'none' })
333   - it.orderDate = this.orderDateBase
  367 + it.deliveryDate = this.deliveryDateBase
334 368 } else {
335   - it.orderDate = dateStr
  369 + it.deliveryDate = dateStr
336 370 }
337 371 this.$set(this.items, idx, it)
338 372 },
... ... @@ -505,8 +539,46 @@ export default {
505 539
506 540 .value {
507 541 flex: 1;
508   - text-align: right;
  542 + // text-align: right;
509 543 color: rgba(0, 0, 0, 0.9);
510 544 font-size: 28rpx;
511 545 }
  546 + .value-spec {
  547 + height: 48rpx;
  548 + display: flex;
  549 + align-items: center;
  550 + color: #000000;
  551 + // justify-content: end;
  552 + &_box {
  553 + position: relative;
  554 + width: 60rpx;
  555 + height: 48rpx;
  556 +
  557 + &_1 {
  558 + font-size: 16rpx;
  559 + position: absolute;
  560 + top: -10rpx;
  561 + left: 0;
  562 + }
  563 +
  564 + &_2 {
  565 + font-size: 16rpx;
  566 + position: absolute;
  567 + bottom: -10rpx;
  568 + left: 0;
  569 + }
  570 + }
  571 +
  572 + &_val {
  573 + font-size: 28rpx;
  574 +
  575 + &.p12 {
  576 + padding-right: 12rpx;
  577 + }
  578 + }
  579 + }
  580 + .row-spec {
  581 + height: 60rpx;
  582 + align-items: center;
  583 + }
512 584 </style>
... ...
... ... @@ -39,7 +39,7 @@
39 39 <view class="item-title"><text class="required">*</text><text>生产厂</text></view>
40 40 </template>
41 41 </uni-list-item>
42   - <ProductRel mode="add" :orderDateBase="form.orderDate" @change="onProductsChange" :options="productList" />
  42 + <ProductRel mode="add" :deliveryDateBase="form.deliveryDate" @change="onProductsChange" :options="productList" />
43 43 <uni-list-item title="合计人民币金额(大写)">
44 44 <template v-slot:footer>
45 45 <uni-easyinput v-model="form.totalAmountCapital" placeholder="自动计算" :inputBorder="false" disabled />
... ... @@ -92,33 +92,25 @@
92 92 :inputBorder="false" />
93 93 </template>
94 94 </uni-list-item>
95   - <view class="group">
96   - <view class="group-title">特别条款要求</view>
97   - <view class="radio-list">
98   - <view v-for="(opt, i) in specialTermsList" :key="'cr-' + i" class="radio-item"
99   - @click="onRadioSelect('specialTerms', 'specialTermsName', opt)">
100   - <view :class="['radio', { checked: form.specialTerms === opt.value }]" />
101   - <text class="label">{{ opt.label }}</text>
102   - </view>
103   - </view>
104   - </view>
105   - <view class="group">
106   - <view class="group-title">执行标准</view>
107   - <view class="radio-list">
108   - <view v-for="(opt, i) in executionStandardList" :key="'es-' + i" class="radio-item"
109   - @click="onRadioSelect('executionStandard', 'executionStandardName', opt)">
110   - <view :class="['radio', { checked: form.executionStandard === opt.value }]" />
111   - <text class="label">{{ opt.label }}</text>
112   - </view>
113   - </view>
114   - </view>
  95 + <uni-list-item class="select-item" :class="form.specialTermsName ? 'is-filled' : 'is-empty'" clickable
  96 + @click="openSheet('specialTerms')" :rightText="form.specialTermsName || '请选择'" showArrow>
  97 + <template v-slot:body>
  98 + <view class="item-title"><text class="required">*</text><text>特别条款要求</text></view>
  99 + </template>
  100 + </uni-list-item>
  101 + <uni-list-item class="select-item" :class="form.executionStandardName ? 'is-filled' : 'is-empty'" clickable
  102 + @click="openSheet('executionStandard')" :rightText="form.executionStandardName || '请选择'" showArrow>
  103 + <template v-slot:body>
  104 + <view class="item-title"><text>执行标准</text></view>
  105 + </template>
  106 + </uni-list-item>
115 107 <uni-list-item v-if="form.executionStandard === 'OTHER'" title="其他">
116 108 <template v-slot:footer>
117 109 <uni-easyinput v-model="form.executionStandardRemarks" placeholder="请输入其他标准备注"
118 110 :inputBorder="false" />
119 111 </template>
120 112 </uni-list-item>
121   - <uni-list-item title="特别说明">
  113 + <uni-list-item title="特别说明" style="margin-top: 20rpx;">
122 114 <template v-slot:footer>
123 115 <uni-easyinput v-model="form.specialInstructions" placeholder="请输入特别说明" :inputBorder="false" />
124 116 </template>
... ... @@ -180,8 +172,8 @@
180 172 <div class="total-item-text">
181 173 数量
182 174 </div>
183   - <div class="total-item-price">
184   - {{ (sumQuantity || 0).toFixed(2) }}t
  175 + <div class="total-item-price">
  176 + {{ (totalQuantity || 0).toFixed(2) }}kg
185 177 </div>
186 178 </div>
187 179 <div class="total-item">
... ... @@ -189,7 +181,7 @@
189 181 不含税金额
190 182 </div>
191 183 <div class="total-item-price text-red">
192   - ¥{{ (sumAmountExcl || 0).toFixed(2) }}
  184 + ¥{{ (totalAmountExcludingTax || 0).toFixed(2) }}
193 185 </div>
194 186 </div>
195 187 <div class="total-item">
... ... @@ -197,7 +189,7 @@
197 189 总金额
198 190 </div>
199 191 <div class="total-item-price text-red">
200   - ¥{{ (sumTotal || 0).toFixed(2) }}
  192 + ¥{{ (totalAmountIncludingTax || 0).toFixed(2) }}
201 193 </div>
202 194 </div>
203 195 </div>
... ... @@ -233,6 +225,7 @@ export default {
233 225 buyer: '',
234 226 buyerName: '',
235 227 orderDate: '',
  228 + deliveryDate: '',
236 229 designatedConsignee: '',
237 230 specialTerms: '',
238 231 specialTermsName: '',
... ... @@ -263,9 +256,9 @@ export default {
263 256 yesNoList: [{ label: '是', value: true }, { label: '否', value: false }],
264 257 sheet: { visible: false, title: '请选择', field: '', options: [], value: '' },
265 258 relate: { visible: false, title: '选择', source: '', display: [], multiple: false, rowKey: 'id', selectedKeys: [], fieldKey: '' },
266   - sumQuantity: 0,
267   - sumAmountExcl: 0,
268   - sumTotal: 0,
  259 + totalQuantity: 0,
  260 + totalAmountExcludingTax: 0,
  261 + totalAmountIncludingTax: 0,
269 262 productLineList: [],
270 263 productList: [],
271 264 customerRemarks: [],
... ... @@ -368,9 +361,9 @@ export default {
368 361 const sumQ = list.reduce((acc, it) => acc + (parseFloat(it.quantity) || 0), 0)
369 362 const sumE = list.reduce((acc, it) => acc + (parseFloat(it.amountExcludingTax) || 0), 0)
370 363 const sumT = list.reduce((acc, it) => acc + (parseFloat(it.totalAmount) || 0), 0)
371   - this.sumQuantity = sumQ
372   - this.sumAmountExcl = sumE
373   - this.sumTotal = sumT
  364 + this.totalQuantity = sumQ
  365 + this.totalAmountExcludingTax = sumE
  366 + this.totalAmountIncludingTax = sumT
374 367 this.form.totalAmountCapital = formatCurrencyToChinese(sumT)
375 368 this.productLineList = list
376 369 },
... ... @@ -446,6 +439,10 @@ export default {
446 439 setSheet('生产厂', opts)
447 440 } else if (field === 'supplier') {
448 441 setSheet('供方', this.supplierList)
  442 + } else if (field === 'specialTerms') {
  443 + setSheet('特别条款要求', this.specialTermsList)
  444 + } else if (field === 'executionStandard') {
  445 + setSheet('执行标准', this.executionStandardList)
449 446 } else if (field === 'includesPackagingFee') {
450 447 setSheet('单价中是否已包含包装费', this.yesNoList)
451 448 } else if (field === 'includesTransportFee') {
... ... @@ -516,9 +513,9 @@ export default {
516 513 ...formForSubmit,
517 514 destination,
518 515 type: 'INTL_OPEN_SPEC_AGMT',
519   - sumQuantity: this.sumQuantity,
520   - sumAmountExcl: this.sumAmountExcl,
521   - sumTotal: this.sumTotal,
  516 + totalQuantity: this.totalQuantity,
  517 + totalAmountExcludingTax: this.totalAmountExcludingTax,
  518 + totalAmountIncludingTax: this.totalAmountIncludingTax,
522 519 contractDistributorLineList: lines
523 520 })
524 521 console.log('onSubmit__payload', payload)
... ... @@ -537,18 +534,31 @@ export default {
537 534 { key: 'supplier', label: '供方' },
538 535 { key: 'buyer', label: '需方' },
539 536 { key: 'orderDate', label: '订货日期' },
  537 + { key: 'unit', label: '单位' },
540 538 { key: 'workshopId', label: '生产厂' },
  539 + { key: 'specialTerms', label: '特别条款要求' },
541 540 ]
542 541 for (const it of checks) {
543 542 const val = this.form[it.key]
544 543 const empty = (val === undefined || val === null || (typeof val === 'string' && val.trim() === '') || (typeof val === 'number' && isNaN(val)))
545 544 if (empty) { uni.showToast({ title: `请先选择${it.label}`, icon: 'none' }); return false }
546 545 }
547   - if (!Array.isArray(this.productLineList) || this.productLineList.length === 0) {
  546 + const list = Array.isArray(this.productLineList) ? this.productLineList : []
  547 + if (list.length === 0) {
548 548 uni.showToast({ title: '请至少添加一条产品明细', icon: 'none' }); return false
549 549 }
550   - for (const [idx, it] of this.productLineList.entries()) {
551   - if (!it.productName || !it.quantity || !it.unitPrice) {
  550 + const strEmpty = (v) => (v === undefined || v === null || (typeof v === 'string' && v.trim() === ''))
  551 + const numEmpty = (v) => (v === undefined || v === null || v === '' || (typeof v === 'number' && isNaN(v)))
  552 + for (const [idx, it] of list.entries()) {
  553 + if (
  554 + strEmpty(it.productName) ||
  555 + strEmpty(it.industry) ||
  556 + strEmpty(it.quality) ||
  557 + strEmpty(it.brand) ||
  558 + numEmpty(it.quantity) ||
  559 + numEmpty(it.unitPrice) ||
  560 + strEmpty(it.deliveryDate)
  561 + ) {
552 562 uni.showToast({ title: `第${idx + 1}条明细未完整填写`, icon: 'none' }); return false
553 563 }
554 564 }
... ... @@ -576,7 +586,7 @@ export default {
576 586 color: rgba(0, 0, 0, 0.6);
577 587 line-height: 32rpx;
578 588 width: 240rpx;
579   - padding: 24rpx 0;
  589 + padding: 12rpx 0;
580 590 }
581 591 .total-item-price {
582 592 font-weight: 600;
... ... @@ -598,7 +608,7 @@ export default {
598 608
599 609 .scroll {
600 610 flex: 1;
601   - padding: 12rpx 0 480rpx !important;
  611 + padding: 12rpx 0 392rpx !important;
602 612 }
603 613
604 614 .footer {
... ...
... ... @@ -53,7 +53,7 @@
53 53 }}</text></view>
54 54 </view>
55 55
56   - <view class="section">
  56 + <view class="section" v-if="detail.status === 'STANDARD'">
57 57 <view class="row"><text class="label">规范性合同</text><text class="value" style="color: #3D48A3;">{{
58 58 detail.standardFileName || '-'
59 59 }}</text></view>
... ... @@ -61,7 +61,7 @@
61 61 detail.standardStandardized ? '是' : '否'
62 62 }}</text></view>
63 63 </view>
64   - <view class="section" v-if="status === 'FORMAL'">
  64 + <view class="section" v-if="detail.status === 'FORMAL'">
65 65 <view class="row"><text class="label">规范性合同</text><text class="value" style="color: #3D48A3;">{{
66 66 detail.formalFileName || '-' }}</text></view>
67 67 <view class="row"><text class="label">合同是否规范</text><text class="value">{{ detail.formalStandardized
... ...
... ... @@ -61,7 +61,9 @@
61 61 <text>订单总额</text><text class="amount" :style="{ color: '#b67a76' }">{{ item.totalAmountIncludingTax ? '¥' : '' }}{{ formatAmount(item.totalAmountIncludingTax) || '-' }}</text>
62 62 </view>
63 63 <view class="info-row" v-if="item.status === 'STANDARD' || item.status === 'FORMAL'">
64   - <text>{{ item.status === 'STANDARD' ? '标准合同' : '正式合同' }}规范性审核状态</text><span class="info-status" :style="item.standardApprovedName ? getStatusCss(item.standardApprovedName) : ''">{{ item.standardApprovedName || '-' }}</span>
  64 + <text>{{ item.status === 'STANDARD' ? '标准合同' : '正式合同' }}规范性审核状态</text>
  65 + <span v-if="item.status === 'STANDARD' ? item.standardApprovedName : item.formalApprovedName" class="info-status" :style="getStatusCss(item.status === 'STANDARD' ? item.standardApprovedName : item.formalApprovedName)">{{ item.status === 'STANDARD' ? item.standardApprovedName : item.formalApprovedName }}</span>
  66 + <span v-else>-</span>
65 67 </view>
66 68 <view class="info-row">
67 69 <text>订货日期</text><text>{{ item.orderDate }}</text>
... ...
... ... @@ -107,7 +107,7 @@
107 107 数量
108 108 </div>
109 109 <div class="total-item-price">
110   - {{ (sumQuantity || 0).toFixed(2) }}t
  110 + {{ (totalQuantity || 0).toFixed(2) }}kg
111 111 </div>
112 112 </div>
113 113 <div class="total-item">
... ... @@ -115,7 +115,7 @@
115 115 不含税金额
116 116 </div>
117 117 <div class="total-item-price text-red">
118   - ¥{{ (sumAmountExcl || 0).toFixed(2) }}
  118 + ¥{{ (totalAmountExcludingTax || 0).toFixed(2) }}
119 119 </div>
120 120 </div>
121 121 <div class="total-item">
... ... @@ -123,7 +123,7 @@
123 123 总金额
124 124 </div>
125 125 <div class="total-item-price text-red">
126   - ¥{{ (sumTotal || 0).toFixed(2) }}
  126 + ¥{{ (totalAmountIncludingTax || 0).toFixed(2) }}
127 127 </div>
128 128 </div>
129 129 </div>
... ... @@ -146,15 +146,15 @@ export default {
146 146 }
147 147 },
148 148 computed: {
149   - sumQuantity() {
  149 + totalQuantity() {
150 150 const qty = this.items.filter(it => it.locked).reduce((p, c) => p + this.toNumber(c.quantity), 0)
151 151 return this.round(qty, 2)
152 152 },
153   - sumAmountExcl() {
  153 + totalAmountExcludingTax() {
154 154 const sum = this.items.filter(it => it.locked).reduce((p, c) => p + this.toNumber(c.amountExcludingTax), 0)
155 155 return this.round(sum, 2)
156 156 },
157   - sumTotal() { return this.totalAmount },
  157 + totalAmountIncludingTax() { return this.totalAmount },
158 158 totalAmount() {
159 159 let sum = 0
160 160 for (const it of this.items) {
... ... @@ -325,9 +325,9 @@ export default {
325 325 const payload = {
326 326 id: this.id,
327 327 totalAmountCapital: formatCurrencyToChinese(this.sumTotal),
328   - totalAmountExcludingTax: this.sumAmountExcl,
329   - totalAmountIncludingTax: this.sumTotal,
330   - totalQuantity: this.sumQuantity,
  328 + totalAmountExcludingTax: this.totalAmountExcludingTax,
  329 + totalAmountIncludingTax: this.totalAmountIncludingTax,
  330 + totalQuantity: this.totalQuantity,
331 331 type:'INTL_OPEN_SPEC_AGMT',
332 332 contractDistributorLineList: selected
333 333 }
... ... @@ -362,7 +362,7 @@ export default {
362 362
363 363 .scroll {
364 364 flex: 1;
365   - padding: 12rpx 0 480rpx !important;
  365 + padding: 12rpx 0 392rpx !important;
366 366 }
367 367
368 368 .header {
... ... @@ -646,7 +646,7 @@ export default {
646 646 color: rgba(0, 0, 0, 0.6);
647 647 line-height: 32rpx;
648 648 width: 240rpx;
649   - padding: 24rpx 0;
  649 + padding: 12rpx 0;
650 650 }
651 651
652 652 .total-item-price {
... ...
... ... @@ -41,7 +41,7 @@
41 41 </template>
42 42 </uni-list-item>
43 43
44   - <ProductRel mode="add" :orderDateBase="form.orderDate" :list="productLineList" @change="onProductsChange" :options="productList" />
  44 + <ProductRel mode="add" :deliveryDateBase="form.deliveryDate" :list="productLineList" @change="onProductsChange" :options="productList" />
45 45
46 46 <uni-list-item title="合计人民币金额(大写)">
47 47 <template v-slot:footer>
... ... @@ -98,34 +98,25 @@
98 98 :inputBorder="false" />
99 99 </template>
100 100 </uni-list-item>
101   -
102   - <view class="group">
103   - <view class="group-title">特别条款要求</view>
104   - <view class="radio-list">
105   - <view v-for="(opt, i) in specialTermsList" :key="'cr-' + i" class="radio-item"
106   - @click="onRadioSelect('specialTerms', 'specialTermsName', opt)">
107   - <view :class="['radio', { checked: form.specialTerms === opt.value }]" />
108   - <text class="label">{{ opt.label }}</text>
109   - </view>
110   - </view>
111   - </view>
112   - <view class="group">
113   - <view class="group-title">执行标准</view>
114   - <view class="radio-list">
115   - <view v-for="(opt, i) in executionStandardList" :key="'es-' + i" class="radio-item"
116   - @click="onRadioSelect('executionStandard', 'executionStandardName', opt)">
117   - <view :class="['radio', { checked: form.executionStandard === opt.value }]" />
118   - <text class="label">{{ opt.label }}</text>
119   - </view>
120   - </view>
121   - </view>
  101 + <uni-list-item class="select-item" :class="form.specialTermsName ? 'is-filled' : 'is-empty'" clickable
  102 + @click="openSheet('specialTerms')" :rightText="form.specialTermsName || '请选择'" showArrow>
  103 + <template v-slot:body>
  104 + <view class="item-title"><text class="required">*</text><text>特别条款要求</text></view>
  105 + </template>
  106 + </uni-list-item>
  107 + <uni-list-item class="select-item" :class="form.executionStandardName ? 'is-filled' : 'is-empty'" clickable
  108 + @click="openSheet('executionStandard')" :rightText="form.executionStandardName || '请选择'" showArrow>
  109 + <template v-slot:body>
  110 + <view class="item-title"><text>执行标准</text></view>
  111 + </template>
  112 + </uni-list-item>
122 113 <uni-list-item v-if="form.executionStandard === 'OTHER'" title="其他">
123 114 <template v-slot:footer>
124 115 <uni-easyinput v-model="form.executionStandardRemarks" placeholder="请输入其他标准备注"
125 116 :inputBorder="false" />
126 117 </template>
127 118 </uni-list-item>
128   - <uni-list-item title="特别说明">
  119 + <uni-list-item title="特别说明" style="margin-top: 20rpx;">
129 120 <template v-slot:footer>
130 121 <uni-easyinput v-model="form.specialInstructions" placeholder="请输入特别说明" :inputBorder="false" />
131 122 </template>
... ... @@ -177,15 +168,15 @@
177 168 <div class="total-text">合计</div>
178 169 <div class="total-item">
179 170 <div class="total-item-text">数量</div>
180   - <div class="total-item-price">{{ (sumQuantity || 0).toFixed(2) }}t</div>
  171 + <div class="total-item-price">{{ (totalQuantity || 0).toFixed(2) }}kg</div>
181 172 </div>
182 173 <div class="total-item">
183 174 <div class="total-item-text">不含税金额</div>
184   - <div class="total-item-price text-red">¥{{ (sumAmountExcl || 0).toFixed(2) }}</div>
  175 + <div class="total-item-price text-red">¥{{ (totalAmountExcludingTax || 0).toFixed(2) }}</div>
185 176 </div>
186 177 <div class="total-item">
187 178 <div class="total-item-text">总金额</div>
188   - <div class="total-item-price text-red">¥{{ (sumTotal || 0).toFixed(2) }}</div>
  179 + <div class="total-item-price text-red">¥{{ (totalAmountIncludingTax || 0).toFixed(2) }}</div>
189 180 </div>
190 181 </div>
191 182 <button class="btn submit" type="primary" @click="onSubmit">保存</button>
... ... @@ -223,6 +214,7 @@ export default {
223 214 workshopId: '',
224 215 workshopName: '',
225 216 orderDate: '',
  217 + deliveryDate: '',
226 218 designatedConsignee: '',
227 219 specialTerms: '',
228 220 specialTermsName: '',
... ... @@ -256,9 +248,9 @@ export default {
256 248 yesNoList: [{ label: '是', value: true }, { label: '否', value: false }],
257 249 sheet: { visible: false, title: '请选择', field: '', options: [], value: '' },
258 250 relate: { visible: false, title: '选择', source: '', display: [], multiple: false, rowKey: 'id', selectedKeys: [], fieldKey: '' },
259   - sumQuantity: 0,
260   - sumAmountExcl: 0,
261   - sumTotal: 0,
  251 + totalQuantity: 0,
  252 + totalAmountExcludingTax: 0,
  253 + totalAmountIncludingTax: 0,
262 254 productLineList: [],
263 255 newProductLineList: [],
264 256 productList: []
... ... @@ -349,9 +341,9 @@ export default {
349 341 const sumQ = list.reduce((acc, it) => acc + (parseFloat(it.quantity) || 0), 0)
350 342 const sumE = list.reduce((acc, it) => acc + (parseFloat(it.amountExcludingTax) || 0), 0)
351 343 const sumT = list.reduce((acc, it) => acc + (parseFloat(it.totalAmount) || 0), 0)
352   - this.sumQuantity = sumQ
353   - this.sumAmountExcl = sumE
354   - this.sumTotal = sumT
  344 + this.totalQuantity = sumQ
  345 + this.totalAmountExcludingTax = sumE
  346 + this.totalAmountIncludingTax = sumT
355 347 this.form.totalAmountCapital = formatCurrencyToChinese(sumT)
356 348 },
357 349 async loadSuppliers() {
... ... @@ -399,6 +391,10 @@ export default {
399 391 setSheet('生产厂', opts)
400 392 } else if (field === 'supplier') {
401 393 setSheet('供方', this.supplierList)
  394 + } else if (field === 'specialTerms') {
  395 + setSheet('特别条款要求', this.specialTermsList)
  396 + } else if (field === 'executionStandard') {
  397 + setSheet('执行标准', this.executionStandardList)
402 398 } else if (field === 'includesPackagingFee') {
403 399 setSheet('单价中是否已包含包装费', this.yesNoList)
404 400 } else if (field === 'includesTransportFee') {
... ... @@ -443,18 +439,31 @@ export default {
443 439 { key: 'supplier', label: '供方' },
444 440 { key: 'buyer', label: '需方' },
445 441 { key: 'orderDate', label: '订货日期' },
  442 + { key: 'unit', label: '单位' },
446 443 { key: 'workshopId', label: '生产厂' },
  444 + { key: 'specialTerms', label: '特别条款要求' },
447 445 ]
448 446 for (const it of checks) {
449 447 const val = this.form[it.key]
450 448 const empty = (val === undefined || val === null || (typeof val === 'string' && val.trim() === '') || (typeof val === 'number' && isNaN(val)))
451 449 if (empty) { uni.showToast({ title: `请先选择${it.label}`, icon: 'none' }); return false }
452 450 }
453   - if (!Array.isArray(this.productLineList) || this.productLineList.length === 0) {
  451 + const list = Array.isArray(this.newProductLineList) ? this.newProductLineList : []
  452 + if (list.length === 0) {
454 453 uni.showToast({ title: '请至少添加一条产品明细', icon: 'none' }); return false
455 454 }
456   - for (const [idx, it] of this.productLineList.entries()) {
457   - if (!it.productName || !it.quantity || !it.unitPrice) {
  455 + const strEmpty = (v) => (v === undefined || v === null || (typeof v === 'string' && v.trim() === ''))
  456 + const numEmpty = (v) => (v === undefined || v === null || v === '' || (typeof v === 'number' && isNaN(v)))
  457 + for (const [idx, it] of list.entries()) {
  458 + if (
  459 + strEmpty(it.productName) ||
  460 + strEmpty(it.industry) ||
  461 + strEmpty(it.quality) ||
  462 + strEmpty(it.brand) ||
  463 + numEmpty(it.quantity) ||
  464 + strEmpty(it.unitPrice) ||
  465 + strEmpty(it.deliveryDate)
  466 + ) {
458 467 uni.showToast({ title: `第${idx + 1}条明细未完整填写`, icon: 'none' }); return false
459 468 }
460 469 }
... ... @@ -486,9 +495,9 @@ export default {
486 495 id: this.form.id,
487 496 destination,
488 497 type: 'INTL_OPEN_SPEC_AGMT',
489   - sumQuantity: this.sumQuantity,
490   - sumAmountExcl: this.sumAmountExcl,
491   - sumTotal: this.sumTotal,
  498 + totalQuantity: this.totalQuantity,
  499 + totalAmountExcludingTax: this.totalAmountExcludingTax,
  500 + totalAmountIncludingTax: this.totalAmountIncludingTax,
492 501 contractDistributorLineList: lines
493 502 })
494 503 try {
... ... @@ -524,7 +533,7 @@ export default {
524 533 color: rgba(0, 0, 0, 0.6);
525 534 line-height: 32rpx;
526 535 width: 240rpx;
527   - padding: 24rpx 0;
  536 + padding: 12rpx 0;
528 537 }
529 538
530 539 .total-item-price {
... ... @@ -547,7 +556,7 @@ export default {
547 556
548 557 .scroll {
549 558 flex: 1;
550   - padding: 12rpx 0 480rpx !important;
  559 + padding: 12rpx 0 392rpx !important;
551 560 }
552 561
553 562 .footer {
... ...
... ... @@ -55,51 +55,51 @@
55 55 </uni-list-item>
56 56 <uni-list-item title="厚度">
57 57 <template v-slot:footer>
58   - <uni-easyinput v-model="item.thickness" :inputBorder="false" placeholder="请输入厚度" />
  58 + <uni-easyinput type="digit" v-model="item.thickness" :inputBorder="false" placeholder="请输入厚度" @input="onNonNegativeInput(idx, 'thickness')" @blur="onNonNegativeBlur(idx, 'thickness', 2)" />
59 59 </template>
60 60 </uni-list-item>
61 61 <uni-list-item title="厚度公差(单项+)">
62 62 <template v-slot:footer>
63   - <uni-easyinput v-model="item.thicknessTolPos" :inputBorder="false"
64   - placeholder="请输入厚度公差(单项+)" />
  63 + <uni-easyinput type="digit" v-model="item.thicknessTolPos" :inputBorder="false"
  64 + placeholder="请输入厚度公差(单项+)" @input="onNonNegativeInput(idx, 'thicknessTolPos')" @blur="onNonNegativeBlur(idx, 'thicknessTolPos', 2)" />
65 65 </template>
66 66 </uni-list-item>
67 67 <uni-list-item title="厚度公差(单项-)">
68 68 <template v-slot:footer>
69   - <uni-easyinput v-model="item.thicknessTolNeg" :inputBorder="false"
70   - placeholder="请输入厚度公差(单项-)" />
  69 + <uni-easyinput type="digit" v-model="item.thicknessTolNeg" :inputBorder="false"
  70 + placeholder="请输入厚度公差(单项-)" @input="onNonNegativeInput(idx, 'thicknessTolNeg')" @blur="onNonNegativeBlur(idx, 'thicknessTolNeg', 2)" />
71 71 </template>
72 72 </uni-list-item>
73 73 <uni-list-item title="宽度">
74 74 <template v-slot:footer>
75   - <uni-easyinput v-model="item.width" :inputBorder="false" placeholder="请输入宽度" />
  75 + <uni-easyinput type="digit" v-model="item.width" :inputBorder="false" placeholder="请输入宽度" @input="onNonNegativeInput(idx, 'width')" @blur="onNonNegativeBlur(idx, 'width', 2)" />
76 76 </template>
77 77 </uni-list-item>
78 78 <uni-list-item title="宽度公差(单项+)">
79 79 <template v-slot:footer>
80   - <uni-easyinput v-model="item.widthTolPos" :inputBorder="false" placeholder="请输入宽度公差(单项+)" />
  80 + <uni-easyinput type="digit" v-model="item.widthTolPos" :inputBorder="false" placeholder="请输入宽度公差(单项+)" @input="onNonNegativeInput(idx, 'widthTolPos')" @blur="onNonNegativeBlur(idx, 'widthTolPos', 2)" />
81 81 </template>
82 82 </uni-list-item>
83 83 <uni-list-item title="宽度公差(单项-)">
84 84 <template v-slot:footer>
85   - <uni-easyinput v-model="item.widthTolNeg" :inputBorder="false" placeholder="请输入宽度公差(单项-)" />
  85 + <uni-easyinput type="digit" v-model="item.widthTolNeg" :inputBorder="false" placeholder="请输入宽度公差(单项-)" @input="onNonNegativeInput(idx, 'widthTolNeg')" @blur="onNonNegativeBlur(idx, 'widthTolNeg', 2)" />
86 86 </template>
87 87 </uni-list-item>
88 88 <uni-list-item title="长度">
89 89 <template v-slot:footer>
90   - <uni-easyinput v-model="item.length" :inputBorder="false" placeholder="请输入长度" />
  90 + <uni-easyinput type="digit" v-model="item.length" :inputBorder="false" placeholder="请输入长度" @input="onNonNegativeInput(idx, 'length')" @blur="onNonNegativeBlur(idx, 'length', 2)" />
91 91 </template>
92 92 </uni-list-item>
93 93 <uni-list-item title="长度公差(单项+)">
94 94 <template v-slot:footer>
95   - <uni-easyinput v-model="item.lengthTolPos" :inputBorder="false"
96   - placeholder="请输入长度公差(单项+)" />
  95 + <uni-easyinput type="digit" v-model="item.lengthTolPos" :inputBorder="false"
  96 + placeholder="请输入长度公差(单项+)" @input="onNonNegativeInput(idx, 'lengthTolPos')" @blur="onNonNegativeBlur(idx, 'lengthTolPos', 2)" />
97 97 </template>
98 98 </uni-list-item>
99 99 <uni-list-item title="长度公差(单项-)">
100 100 <template v-slot:footer>
101   - <uni-easyinput v-model="item.lengthTolNeg" :inputBorder="false"
102   - placeholder="请输入长度公差(单项-)" />
  101 + <uni-easyinput type="digit" v-model="item.lengthTolNeg" :inputBorder="false"
  102 + placeholder="请输入长度公差(单项-)" @input="onNonNegativeInput(idx, 'lengthTolNeg')" @blur="onNonNegativeBlur(idx, 'lengthTolNeg', 2)" />
103 103 </template>
104 104 </uni-list-item>
105 105 <uni-list-item title="状态">
... ... @@ -109,12 +109,17 @@
109 109 </uni-list-item>
110 110 <uni-list-item title="数量">
111 111 <template v-slot:footer>
112   - <uni-easyinput v-model="item.quantity" type="number" :inputBorder="false" placeholder="请输入数量" @input="onImmediateChange(idx)" @blur="onNumberBlur(idx, 'quantity', 0)" />
  112 + <uni-easyinput v-model="item.quantity" type="digit" :inputBorder="false" placeholder="请输入数量kg" @input="onNonNegativeInput(idx, 'quantity')" @blur="onNonNegativeBlur(idx, 'quantity', 2)" />
113 113 </template>
114 114 </uni-list-item>
115 115 <uni-list-item title="单价">
116 116 <template v-slot:footer>
117   - <uni-easyinput v-model="item.unitPrice" type="number" :inputBorder="false" placeholder="请输入单价" @input="onImmediateChange(idx)" @blur="onNumberBlur(idx, 'unitPrice', 0)" />
  117 + <uni-easyinput v-model="item.unitPrice" type="digit" :inputBorder="false" placeholder="请输入销售价格" @input="onNonNegativeInput(idx, 'unitPrice')" @blur="onNonNegativeBlur(idx, 'unitPrice', 2)" />
  118 + </template>
  119 + </uni-list-item>
  120 + <uni-list-item title="外贸加工费">
  121 + <template v-slot:footer>
  122 + <uni-easyinput v-model="item.processingFee" type="number" :inputBorder="false" placeholder="请输入外贸加工费" />
118 123 </template>
119 124 </uni-list-item>
120 125 <uni-list-item title="不含税金额">
... ... @@ -129,7 +134,7 @@
129 134 </uni-list-item>
130 135 <uni-list-item title="发货日期">
131 136 <template v-slot:footer>
132   - <uni-datetime-picker type="date" v-model="item.orderDate" @change="onDateChange(idx, $event)" />
  137 + <uni-datetime-picker type="date" v-model="item.deliveryDate" @change="onDateChange(idx, $event)" />
133 138 </template>
134 139 </uni-list-item>
135 140 </uni-list>
... ... @@ -151,7 +156,30 @@
151 156 <view class="row"><text class="label">行业</text><text class="value">{{ item.industry }}</text></view>
152 157 <view class="row"><text class="label">牌号</text><text class="value">{{ item.brand }}</text></view>
153 158 <view class="row"><text class="label">品质</text><text class="value">{{ item.quality }}</text></view>
154   - <view class="row"><text class="label">规格</text><text class="value">{{ item.specDisplay }}</text></view>
  159 + <!-- 厚(公差) * 宽(公差) * 长(公差) -->
  160 + <view class="row row-spec"><text class="label">规格(mm)</text>
  161 + <view class="value value-spec">
  162 + <view v-if="item.thickness" class="value-spec_val">{{ item.thickness }}</view>
  163 + <view v-if="item.thickness" class="value-spec_box">
  164 + <view v-if="item.thicknessTolPos" class="value-spec_box_1">+{{ item.thicknessTolPos }}
  165 + </view>
  166 + <view v-if="item.thicknessTolNeg" class="value-spec_box_2">-{{ item.thicknessTolNeg }}
  167 + </view>
  168 + </view>
  169 + <view v-if="item.width" class="value-spec_val p12">*</view>
  170 + <view v-if="item.width" class="value-spec_val">{{ item.width }}</view>
  171 + <view v-if="item.width" class="value-spec_box">
  172 + <view v-if="item.widthTolPos" class="value-spec_box_1">+{{ item.widthTolPos }}</view>
  173 + <view v-if="item.widthTolNeg" class="value-spec_box_2">-{{ item.widthTolNeg }}</view>
  174 + </view>
  175 + <view v-if="item.length" class="value-spec_val p12">*</view>
  176 + <view v-if="item.length" class="value-spec_val">{{ item.length }}</view>
  177 + <view v-if="item.length" class="value-spec_box">
  178 + <view v-if="item.lengthTolPos" class="value-spec_box_1">+{{ item.lengthTolPos }}</view>
  179 + <view v-if="item.lengthTolNeg" class="value-spec_box_2">-{{ item.lengthTolNeg }}</view>
  180 + </view>
  181 + </view>
  182 + </view>
155 183 <view class="row"><text class="label">状态</text><text class="value">{{ item.status }}</text></view>
156 184 <view class="row"><text class="label">数量</text><text class="value">{{ item.quantity }}</text></view>
157 185 <view class="row"><text class="label">单价</text><text class="value">{{ formatCurrency(item.unitPrice)
... ... @@ -162,7 +190,7 @@
162 190 }}</text></view>
163 191 <view class="row"><text class="label">总金额</text><text class="value">{{ formatCurrency(item.totalAmount)
164 192 }}</text></view>
165   - <view class="row"><text class="label">发货日期</text><text class="value">{{ item.orderDate }}</text></view>
  193 + <view class="row"><text class="label">发货日期</text><text class="value">{{ item.deliveryDate }}</text></view>
166 194 </view>
167 195 </view>
168 196 <SingleSelectSheet :visible.sync="sheet.visible" :title="sheet.title" :options="sheet.options" v-model="sheet.value" @confirm="onProductConfirm" />
... ... @@ -176,7 +204,7 @@ export default {
176 204 mode: { type: String, default: 'add' },
177 205 list: { type: Array, default: () => [] },
178 206 max: { type: Number, default: 8 },
179   - orderDateBase: { type: String, default: '' },
  207 + deliveryDateBase: { type: String, default: '' },
180 208 options: { type: Array, default: () => [] }
181 209 },
182 210 components: { SingleSelectSheet },
... ... @@ -218,10 +246,18 @@ export default {
218 246 },
219 247 methods: {
220 248 defaultItem() {
221   - return { productId: '', productName: '', industry: '', brand: '', quality: '', thickness: '', thicknessTolPos: '', thicknessTolNeg: '', width: '', widthTolPos: '', widthTolNeg: '', length: '', lengthTolPos: '', lengthTolNeg: '', status: '', quantity: '', unitPrice: '', amountExcludingTax: 0, totalAmount: 0, orderDate: '' }
  249 + return { productId: '', productName: '', industry: '', brand: '', quality: '', thickness: '', thicknessTolPos: '', thicknessTolNeg: '', width: '', widthTolPos: '', widthTolNeg: '', length: '', lengthTolPos: '', lengthTolNeg: '', status: '', quantity: '', unitPrice: '', amountExcludingTax: 0, totalAmount: 0, deliveryDate: '' }
222 250 },
223   - onImmediateChange(idx) {
224   - this.$nextTick(() => this.recalculate(idx))
  251 + onNonNegativeInput(idx, field) {
  252 + const it = this.items[idx]
  253 + if (!it) return
  254 + let v = String(it[field] != null ? it[field] : '')
  255 + v = v.replace(/[^0-9.]/g, '')
  256 + v = v.replace(/(\..*)\./g, '$1')
  257 + if (v.startsWith('.')) v = '0' + v
  258 + it[field] = v
  259 + this.$set(this.items, idx, it)
  260 + if (field === 'quantity' || field === 'unitPrice') this.$nextTick(() => this.recalculate(idx))
225 261 },
226 262 toNumber(val) {
227 263 if (typeof val === 'number') return isNaN(val) ? 0 : val
... ... @@ -234,21 +270,21 @@ export default {
234 270 const m = Math.pow(10, digits)
235 271 return Math.round(n * m) / m
236 272 },
237   - onNumberBlur(idx, field, digits) {
  273 + onNonNegativeBlur(idx, field, digits) {
238 274 const it = this.items[idx]
239 275 if (!it) return
240 276 const raw = it[field]
241   - // 如果为空则保持为空,不自动置为0,仅重新计算依赖字段
242 277 if (raw === '' || raw === null || raw === undefined) {
243 278 this.$set(this.items, idx, it)
244   - this.recalculate(idx)
  279 + if (field === 'quantity' || field === 'unitPrice') this.recalculate(idx)
245 280 return
246 281 }
247   - const num = this.toNumber(raw)
  282 + let num = this.toNumber(raw)
  283 + if (isNaN(num) || num < 0) num = 0
248 284 const rounded = this.round(num, digits)
249 285 it[field] = rounded
250 286 this.$set(this.items, idx, it)
251   - this.recalculate(idx)
  287 + if (field === 'quantity' || field === 'unitPrice') this.recalculate(idx)
252 288 },
253 289 formatCurrency(val) {
254 290 if (val == null || val === '') return ''
... ... @@ -319,15 +355,15 @@ export default {
319 355 onDateChange(idx, e) {
320 356 const it = this.items[idx]
321 357 if (!it) return
322   - const val = typeof e === 'string' ? e : (e && e.detail && e.detail.value) ? e.detail.value : it.orderDate
  358 + const val = typeof e === 'string' ? e : (e && e.detail && e.detail.value) ? e.detail.value : it.deliveryDate
323 359 const dateStr = String(val).slice(0, 10)
324   - const base = this.orderDateBase ? new Date(this.orderDateBase) : null
  360 + const base = this.deliveryDateBase ? new Date(this.deliveryDateBase) : null
325 361 const d = new Date(dateStr)
326 362 if (base && !isNaN(d.getTime()) && d.getTime() < base.getTime()) {
327 363 uni.showToast({ title: '发货日期不得早于订货日期', icon: 'none' })
328   - it.orderDate = this.orderDateBase
  364 + it.deliveryDate = this.deliveryDateBase
329 365 } else {
330   - it.orderDate = dateStr
  366 + it.deliveryDate = dateStr
331 367 }
332 368 this.$set(this.items, idx, it)
333 369 },
... ... @@ -500,8 +536,46 @@ export default {
500 536
501 537 .value {
502 538 flex: 1;
503   - text-align: right;
  539 + // text-align: right;
504 540 color: rgba(0, 0, 0, 0.9);
505 541 font-size: 28rpx;
506 542 }
  543 + .value-spec {
  544 + height: 48rpx;
  545 + display: flex;
  546 + align-items: center;
  547 + color: #000000;
  548 + // justify-content: end;
  549 + &_box {
  550 + position: relative;
  551 + width: 60rpx;
  552 + height: 48rpx;
  553 +
  554 + &_1 {
  555 + font-size: 16rpx;
  556 + position: absolute;
  557 + top: -10rpx;
  558 + left: 0;
  559 + }
  560 +
  561 + &_2 {
  562 + font-size: 16rpx;
  563 + position: absolute;
  564 + bottom: -10rpx;
  565 + left: 0;
  566 + }
  567 + }
  568 +
  569 + &_val {
  570 + font-size: 28rpx;
  571 +
  572 + &.p12 {
  573 + padding-right: 12rpx;
  574 + }
  575 + }
  576 + }
  577 + .row-spec {
  578 + height: 60rpx;
  579 + align-items: center;
  580 + }
507 581 </style>
... ...
... ... @@ -24,7 +24,7 @@
24 24 <text>框架合同编号</text><text>{{ item.code }}</text>
25 25 </view>
26 26 <view class="info-row">
27   - <text>是否签订</text><text>{{ item.hasFrameworkAgreement }}</text>
  27 + <text>是否签订</text><text>{{ item.hasFrameworkAgreement ? '是' : '否' }}</text>
28 28 </view>
29 29 <view class="info-row">
30 30 <text>品种</text><text>{{ item.materialTypeName }}</text>
... ...
... ... @@ -39,7 +39,7 @@
39 39 <view class="item-title"><text class="required">*</text><text>生产厂</text></view>
40 40 </template>
41 41 </uni-list-item>
42   - <!-- <ProductRel mode="add" :orderDateBase="form.orderDate" @change="onProductsChange" :options="productList" :rawToProdRatioList="rawToProdRatioList" /> -->
  42 + <ProductRel mode="add" :deliveryDateBase="form.deliveryDate" @change="onProductsChange" :options="productList" :rawToProdRatioList="rawToProdRatioList" />
43 43 <uni-list-item title="合计人民币金额(大写)">
44 44 <template v-slot:footer>
45 45 <uni-easyinput v-model="form.totalAmountCapital" placeholder="自动计算" :inputBorder="false" disabled />
... ... @@ -92,33 +92,25 @@
92 92 :inputBorder="false" />
93 93 </template>
94 94 </uni-list-item>
95   - <view class="group">
96   - <view class="group-title">特别条款要求</view>
97   - <view class="radio-list">
98   - <view v-for="(opt, i) in specialTermsList" :key="'cr-' + i" class="radio-item"
99   - @click="onRadioSelect('specialTerms', 'specialTermsName', opt)">
100   - <view :class="['radio', { checked: form.specialTerms === opt.value }]" />
101   - <text class="label">{{ opt.label }}</text>
102   - </view>
103   - </view>
104   - </view>
105   - <view class="group">
106   - <view class="group-title">执行标准</view>
107   - <view class="radio-list">
108   - <view v-for="(opt, i) in executionStandardList" :key="'es-' + i" class="radio-item"
109   - @click="onRadioSelect('executionStandard', 'executionStandardName', opt)">
110   - <view :class="['radio', { checked: form.executionStandard === opt.value }]" />
111   - <text class="label">{{ opt.label }}</text>
112   - </view>
113   - </view>
114   - </view>
  95 + <uni-list-item class="select-item" :class="form.specialTermsName ? 'is-filled' : 'is-empty'" clickable
  96 + @click="openSheet('specialTerms')" :rightText="form.specialTermsName || '请选择'" showArrow>
  97 + <template v-slot:body>
  98 + <view class="item-title"><text class="required">*</text><text>特别条款要求</text></view>
  99 + </template>
  100 + </uni-list-item>
  101 + <uni-list-item class="select-item" :class="form.executionStandardName ? 'is-filled' : 'is-empty'" clickable
  102 + @click="openSheet('executionStandard')" :rightText="form.executionStandardName || '请选择'" showArrow>
  103 + <template v-slot:body>
  104 + <view class="item-title"><text>执行标准</text></view>
  105 + </template>
  106 + </uni-list-item>
115 107 <uni-list-item v-if="form.executionStandard === 'OTHER'" title="其他">
116 108 <template v-slot:footer>
117 109 <uni-easyinput v-model="form.executionStandardRemarks" placeholder="请输入其他标准备注"
118 110 :inputBorder="false" />
119 111 </template>
120 112 </uni-list-item>
121   - <uni-list-item title="特别说明">
  113 + <uni-list-item title="特别说明" style="margin-top: 20rpx;">
122 114 <template v-slot:footer>
123 115 <uni-easyinput v-model="form.specialInstructions" placeholder="请输入特别说明" :inputBorder="false" />
124 116 </template>
... ... @@ -181,7 +173,7 @@
181 173 数量
182 174 </div>
183 175 <div class="total-item-price">
184   - {{ (sumQuantity || 0).toFixed(2) }}t
  176 + {{ (totalQuantity || 0).toFixed(2) }}kg
185 177 </div>
186 178 </div>
187 179 <div class="total-item">
... ... @@ -189,7 +181,7 @@
189 181 不含税金额
190 182 </div>
191 183 <div class="total-item-price text-red">
192   - ¥{{ (sumAmountExcl || 0).toFixed(2) }}
  184 + ¥{{ (totalAmountExcludingTax || 0).toFixed(2) }}
193 185 </div>
194 186 </div>
195 187 <div class="total-item">
... ... @@ -197,7 +189,7 @@
197 189 总金额
198 190 </div>
199 191 <div class="total-item-price text-red">
200   - ¥{{ (sumTotal || 0).toFixed(2) }}
  192 + ¥{{ (totalAmountIncludingTax || 0).toFixed(2) }}
201 193 </div>
202 194 </div>
203 195 </div>
... ... @@ -214,7 +206,7 @@
214 206 <script>
215 207 import SingleSelectSheet from '@/components/single-select/index.vue'
216 208 import RelateSelectSheet from '@/components/relate-select/index.vue'
217   -//import ProductRel from './productRel.vue'
  209 +import ProductRel from './productRel.vue'
218 210 import CitySelector from '@/components/city-selector/index.vue'
219 211 import { getRetailCodeApi, createContractApi, getCustomerRemarks,getCustomerSpecificQualityRequirements } from '@/api/contract'
220 212 import { getDicByCodes } from '@/utils/dic'
... ... @@ -223,7 +215,7 @@ import { workshopQueryApi } from '@/api/devManage'
223 215
224 216 export default {
225 217 name: 'AddContractProcess',
226   - components: { SingleSelectSheet, RelateSelectSheet, /* ProductRel, */ CitySelector },
  218 + components: { SingleSelectSheet, RelateSelectSheet, ProductRel, CitySelector },
227 219 data() {
228 220 return {
229 221 form: {
... ... @@ -233,6 +225,7 @@ export default {
233 225 buyer: '',
234 226 buyerName: '',
235 227 orderDate: '',
  228 + deliveryDate: '',
236 229 designatedConsignee: '',
237 230 specialTerms: '',
238 231 specialTermsName: '',
... ... @@ -263,9 +256,9 @@ export default {
263 256 yesNoList: [{ label: '是', value: true }, { label: '否', value: false }],
264 257 sheet: { visible: false, title: '请选择', field: '', options: [], value: '' },
265 258 relate: { visible: false, title: '选择', source: '', display: [], multiple: false, rowKey: 'id', selectedKeys: [], fieldKey: '' },
266   - sumQuantity: 0,
267   - sumAmountExcl: 0,
268   - sumTotal: 0,
  259 + totalQuantity: 0,
  260 + totalAmountExcludingTax: 0,
  261 + totalAmountIncludingTax: 0,
269 262 productLineList: [],
270 263 productList: [],
271 264 rawToProdRatioList: [],
... ... @@ -366,12 +359,12 @@ export default {
366 359 },
367 360 onProductsChange(products) {
368 361 const list = Array.isArray(products) ? products : []
369   - const sumQ = list.reduce((acc, it) => acc + (parseFloat(it.quantity) || 0), 0)
  362 + const sumQ = list.reduce((acc, it) => acc + (parseFloat(it.productQuantity) || 0), 0)
370 363 const sumE = list.reduce((acc, it) => acc + (parseFloat(it.amountExcludingTax) || 0), 0)
371 364 const sumT = list.reduce((acc, it) => acc + (parseFloat(it.totalAmount) || 0), 0)
372   - this.sumQuantity = sumQ
373   - this.sumAmountExcl = sumE
374   - this.sumTotal = sumT
  365 + this.totalQuantity = sumQ
  366 + this.totalAmountExcludingTax = sumE
  367 + this.totalAmountIncludingTax = sumT
375 368 this.form.totalAmountCapital = formatCurrencyToChinese(sumT)
376 369 this.productLineList = list
377 370 },
... ... @@ -450,6 +443,10 @@ export default {
450 443 setSheet('生产厂', opts)
451 444 } else if (field === 'supplier') {
452 445 setSheet('承揽方', this.supplierList)
  446 + } else if (field === 'specialTerms') {
  447 + setSheet('特别条款要求', this.specialTermsList)
  448 + } else if (field === 'executionStandard') {
  449 + setSheet('执行标准', this.executionStandardList)
453 450 } else if (field === 'includesPackagingFee') {
454 451 setSheet('单价中是否已包含包装费', this.yesNoList)
455 452 } else if (field === 'includesTransportFee') {
... ... @@ -520,10 +517,15 @@ export default {
520 517 ...formForSubmit,
521 518 destination,
522 519 type: 'PROCESS_STD_AGMT',
523   - sumQuantity: this.sumQuantity,
524   - sumAmountExcl: this.sumAmountExcl,
525   - sumTotal: this.sumTotal,
526   - contractDistributorLineList: lines
  520 + totalQuantity: this.totalQuantity,
  521 + totalAmountExcludingTax: this.totalAmountExcludingTax,
  522 + totalAmountIncludingTax: this.totalAmountIncludingTax,
  523 + contractStdProcessingLineList: lines.map(it => ({
  524 + ...it,
  525 + productId: it.rawProductId || '',
  526 + productName: it.rawProductName || '',
  527 + productGrade: it.rawProductGrade || '',
  528 + }))
527 529 })
528 530 console.log('onSubmit__payload', payload)
529 531
... ... @@ -542,17 +544,30 @@ export default {
542 544 { key: 'buyer', label: '定作方' },
543 545 { key: 'orderDate', label: '订货日期' },
544 546 { key: 'workshopId', label: '生产厂' },
  547 + { key: 'unit', label: '单位' },
  548 + { key: 'specialTerms', label: '特别条款要求' },
545 549 ]
546 550 for (const it of checks) {
547 551 const val = this.form[it.key]
548 552 const empty = (val === undefined || val === null || (typeof val === 'string' && val.trim() === '') || (typeof val === 'number' && isNaN(val)))
549 553 if (empty) { uni.showToast({ title: `请先选择${it.label}`, icon: 'none' }); return false }
550 554 }
551   - if (!Array.isArray(this.productLineList) || this.productLineList.length === 0) {
  555 + const list = Array.isArray(this.productLineList) ? this.productLineList : []
  556 + if (list.length === 0) {
552 557 uni.showToast({ title: '请至少添加一条产品明细', icon: 'none' }); return false
553 558 }
554   - for (const [idx, it] of this.productLineList.entries()) {
555   - if (!it.productName || !it.quantity || !it.unitPrice) {
  559 + const strEmpty = (v) => (v === undefined || v === null || (typeof v === 'string' && v.trim() === ''))
  560 + const numEmpty = (v) => (v === undefined || v === null || v === '' || (typeof v === 'number' && isNaN(v)))
  561 + for (const [idx, it] of list.entries()) {
  562 + if (
  563 + strEmpty(it.rawProductName) ||
  564 + strEmpty(it.industry) ||
  565 + strEmpty(it.quality) ||
  566 + strEmpty(it.rawProductGrade) ||
  567 + numEmpty(it.productQuantity) ||
  568 + numEmpty(it.unitPrice) ||
  569 + strEmpty(it.deliveryDate)
  570 + ) {
556 571 uni.showToast({ title: `第${idx + 1}条明细未完整填写`, icon: 'none' }); return false
557 572 }
558 573 }
... ... @@ -580,7 +595,7 @@ export default {
580 595 color: rgba(0, 0, 0, 0.6);
581 596 line-height: 32rpx;
582 597 width: 240rpx;
583   - padding: 24rpx 0;
  598 + padding: 12rpx 0;
584 599 }
585 600 .total-item-price {
586 601 font-weight: 600;
... ... @@ -602,7 +617,7 @@ export default {
602 617
603 618 .scroll {
604 619 flex: 1;
605   - padding: 12rpx 0 480rpx !important;
  620 + padding: 12rpx 0 392rpx !important;
606 621 }
607 622
608 623 .footer {
... ...
... ... @@ -206,7 +206,7 @@ export default {
206 206 if (!this.batchMode) this.selectedKeys = []
207 207 },
208 208 onAdd() {
209   - uni.showToast({ title: '点击新增', icon: 'none' })
  209 + uni.navigateTo({ url: '/pages/contract_process/add' })
210 210 },
211 211 fetchList({ pageIndex, pageSize, query, extra }) {
212 212 console.log('fetchList', pageIndex, pageSize, query, extra)
... ...
... ... @@ -41,7 +41,7 @@
41 41 </template>
42 42 </uni-list-item>
43 43
44   - <ProductRel mode="add" :orderDateBase="form.orderDate" :list="productLineList" @change="onProductsChange" :options="productList" />
  44 + <ProductRel mode="add" :deliveryDateBase="form.deliveryDate" :list="productLineList" @change="onProductsChange" :options="productList" />
45 45
46 46 <uni-list-item title="合计人民币金额(大写)">
47 47 <template v-slot:footer>
... ... @@ -99,33 +99,25 @@
99 99 </template>
100 100 </uni-list-item>
101 101
102   - <view class="group">
103   - <view class="group-title">特别条款要求</view>
104   - <view class="radio-list">
105   - <view v-for="(opt, i) in specialTermsList" :key="'cr-' + i" class="radio-item"
106   - @click="onRadioSelect('specialTerms', 'specialTermsName', opt)">
107   - <view :class="['radio', { checked: form.specialTerms === opt.value }]" />
108   - <text class="label">{{ opt.label }}</text>
109   - </view>
110   - </view>
111   - </view>
112   - <view class="group">
113   - <view class="group-title">执行标准</view>
114   - <view class="radio-list">
115   - <view v-for="(opt, i) in executionStandardList" :key="'es-' + i" class="radio-item"
116   - @click="onRadioSelect('executionStandard', 'executionStandardName', opt)">
117   - <view :class="['radio', { checked: form.executionStandard === opt.value }]" />
118   - <text class="label">{{ opt.label }}</text>
119   - </view>
120   - </view>
121   - </view>
  102 + <uni-list-item class="select-item" :class="form.specialTermsName ? 'is-filled' : 'is-empty'" clickable
  103 + @click="openSheet('specialTerms')" :rightText="form.specialTermsName || '请选择'" showArrow>
  104 + <template v-slot:body>
  105 + <view class="item-title"><text class="required">*</text><text>特别条款要求</text></view>
  106 + </template>
  107 + </uni-list-item>
  108 + <uni-list-item class="select-item" :class="form.executionStandardName ? 'is-filled' : 'is-empty'" clickable
  109 + @click="openSheet('executionStandard')" :rightText="form.executionStandardName || '请选择'" showArrow>
  110 + <template v-slot:body>
  111 + <view class="item-title"><text>执行标准</text></view>
  112 + </template>
  113 + </uni-list-item>
122 114 <uni-list-item v-if="form.executionStandard === 'OTHER'" title="其他">
123 115 <template v-slot:footer>
124 116 <uni-easyinput v-model="form.executionStandardRemarks" placeholder="请输入其他标准备注"
125 117 :inputBorder="false" />
126 118 </template>
127 119 </uni-list-item>
128   - <uni-list-item title="特别说明">
  120 + <uni-list-item title="特别说明" style="margin-top: 20rpx;">
129 121 <template v-slot:footer>
130 122 <uni-easyinput v-model="form.specialInstructions" placeholder="请输入特别说明" :inputBorder="false" />
131 123 </template>
... ... @@ -177,15 +169,15 @@
177 169 <div class="total-text">合计</div>
178 170 <div class="total-item">
179 171 <div class="total-item-text">数量</div>
180   - <div class="total-item-price">{{ (sumQuantity || 0).toFixed(2) }}t</div>
  172 + <div class="total-item-price">{{ (totalQuantity || 0).toFixed(2) }}kg</div>
181 173 </div>
182 174 <div class="total-item">
183 175 <div class="total-item-text">不含税金额</div>
184   - <div class="total-item-price text-red">¥{{ (sumAmountExcl || 0).toFixed(2) }}</div>
  176 + <div class="total-item-price text-red">¥{{ (totalAmountExcludingTax || 0).toFixed(2) }}</div>
185 177 </div>
186 178 <div class="total-item">
187 179 <div class="total-item-text">总金额</div>
188   - <div class="total-item-price text-red">¥{{ (sumTotal || 0).toFixed(2) }}</div>
  180 + <div class="total-item-price text-red">¥{{ (totalAmountIncludingTax || 0).toFixed(2) }}</div>
189 181 </div>
190 182 </div>
191 183 <button class="btn submit" type="primary" @click="onSubmit">保存</button>
... ... @@ -223,6 +215,7 @@ export default {
223 215 workshopId: '',
224 216 workshopName: '',
225 217 orderDate: '',
  218 + deliveryDate: '',
226 219 designatedConsignee: '',
227 220 specialTerms: '',
228 221 specialTermsName: '',
... ... @@ -256,9 +249,9 @@ export default {
256 249 yesNoList: [{ label: '是', value: true }, { label: '否', value: false }],
257 250 sheet: { visible: false, title: '请选择', field: '', options: [], value: '' },
258 251 relate: { visible: false, title: '选择', source: '', display: [], multiple: false, rowKey: 'id', selectedKeys: [], fieldKey: '' },
259   - sumQuantity: 0,
260   - sumAmountExcl: 0,
261   - sumTotal: 0,
  252 + totalQuantity: 0,
  253 + totalAmountExcludingTax: 0,
  254 + totalAmountIncludingTax: 0,
262 255 productLineList: [],
263 256 newProductLineList: [],
264 257 productList: [],
... ... @@ -325,7 +318,7 @@ export default {
325 318 workshopId: m.workshopId || '',
326 319 workshopName: m.workshopName || '',
327 320 }
328   - const lines = Array.isArray(m.contractDistributorLineList) ? m.contractDistributorLineList : []
  321 + const lines = Array.isArray(m.contractStdProcessingLineList) ? m.contractStdProcessingLineList : []
329 322 this.productLineList = lines
330 323 this.onProductsChange(lines)
331 324 } catch (e) { }
... ... @@ -347,12 +340,12 @@ export default {
347 340 onProductsChange(products) {
348 341 const list = Array.isArray(products) ? products : []
349 342 this.newProductLineList = list
350   - const sumQ = list.reduce((acc, it) => acc + (parseFloat(it.quantity) || 0), 0)
  343 + const sumQ = list.reduce((acc, it) => acc + (parseFloat(it.productQuantity) || 0), 0)
351 344 const sumE = list.reduce((acc, it) => acc + (parseFloat(it.amountExcludingTax) || 0), 0)
352 345 const sumT = list.reduce((acc, it) => acc + (parseFloat(it.totalAmount) || 0), 0)
353   - this.sumQuantity = sumQ
354   - this.sumAmountExcl = sumE
355   - this.sumTotal = sumT
  346 + this.totalQuantity = sumQ
  347 + this.totalAmountExcludingTax = sumE
  348 + this.totalAmountIncludingTax = sumT
356 349 this.form.totalAmountCapital = formatCurrencyToChinese(sumT)
357 350 },
358 351 async loadSuppliers() {
... ... @@ -403,6 +396,10 @@ export default {
403 396 setSheet('生产厂', opts)
404 397 } else if (field === 'supplier') {
405 398 setSheet('承揽方', this.supplierList)
  399 + } else if (field === 'specialTerms') {
  400 + setSheet('特别条款要求', this.specialTermsList)
  401 + } else if (field === 'executionStandard') {
  402 + setSheet('执行标准', this.executionStandardList)
406 403 } else if (field === 'includesPackagingFee') {
407 404 setSheet('单价中是否已包含包装费', this.yesNoList)
408 405 } else if (field === 'includesTransportFee') {
... ... @@ -448,17 +445,30 @@ export default {
448 445 { key: 'buyer', label: '定作方' },
449 446 { key: 'orderDate', label: '订货日期' },
450 447 { key: 'workshopId', label: '生产厂' },
  448 + { key: 'unit', label: '单位' },
  449 + { key: 'specialTerms', label: '特别条款要求' },
451 450 ]
452 451 for (const it of checks) {
453 452 const val = this.form[it.key]
454 453 const empty = (val === undefined || val === null || (typeof val === 'string' && val.trim() === '') || (typeof val === 'number' && isNaN(val)))
455 454 if (empty) { uni.showToast({ title: `请先选择${it.label}`, icon: 'none' }); return false }
456 455 }
457   - if (!Array.isArray(this.productLineList) || this.productLineList.length === 0) {
  456 + const list = Array.isArray(this.newProductLineList) ? this.newProductLineList : []
  457 + if (list.length === 0) {
458 458 uni.showToast({ title: '请至少添加一条产品明细', icon: 'none' }); return false
459 459 }
460   - for (const [idx, it] of this.productLineList.entries()) {
461   - if (!it.productName || !it.quantity || !it.unitPrice) {
  460 + const strEmpty = (v) => (v === undefined || v === null || (typeof v === 'string' && v.trim() === ''))
  461 + const numEmpty = (v) => (v === undefined || v === null || v === '' || (typeof v === 'number' && isNaN(v)))
  462 + for (const [idx, it] of list.entries()) {
  463 + if (
  464 + strEmpty(it.productName) ||
  465 + strEmpty(it.industry) ||
  466 + strEmpty(it.quality) ||
  467 + strEmpty(it.brand) ||
  468 + numEmpty(it.productQuantity) ||
  469 + strEmpty(it.unitPrice) ||
  470 + strEmpty(it.deliveryDate)
  471 + ) {
462 472 uni.showToast({ title: `第${idx + 1}条明细未完整填写`, icon: 'none' }); return false
463 473 }
464 474 }
... ... @@ -493,7 +503,7 @@ export default {
493 503 sumQuantity: this.sumQuantity,
494 504 sumAmountExcl: this.sumAmountExcl,
495 505 sumTotal: this.sumTotal,
496   - contractDistributorLineList: lines
  506 + contractStdProcessingLineList: lines
497 507 })
498 508 try {
499 509 await updateContractApi(payload)
... ... @@ -528,7 +538,7 @@ export default {
528 538 color: rgba(0, 0, 0, 0.6);
529 539 line-height: 32rpx;
530 540 width: 240rpx;
531   - padding: 24rpx 0;
  541 + padding: 12rpx 0;
532 542 }
533 543
534 544 .total-item-price {
... ... @@ -551,7 +561,7 @@ export default {
551 561
552 562 .scroll {
553 563 flex: 1;
554   - padding: 12rpx 0 480rpx !important;
  564 + padding: 12rpx 0 392rpx !important;
555 565 }
556 566
557 567 .footer {
... ...
... ... @@ -38,7 +38,7 @@
38 38 <view class="item-title"><text>原材料名称</text></view>
39 39 </template>
40 40 </uni-list-item>
41   - <uni-list-item title="原材料牌号">
  41 + <uni-list-item title="原材料牌号">
42 42 <template v-slot:footer>
43 43 <uni-easyinput v-model="item.rawProductGrade" :inputBorder="false" placeholder="请输入原材料牌号" />
44 44 </template>
... ... @@ -71,61 +71,61 @@
71 71
72 72 <uni-list-item title="厚度">
73 73 <template v-slot:footer>
74   - <uni-easyinput v-model="item.thickness" :inputBorder="false" placeholder="请输入厚度" />
  74 + <uni-easyinput type="digit" v-model="item.thickness" :inputBorder="false" placeholder="请输入厚度" @input="onNonNegativeInput(idx, 'thickness')" @blur="onNonNegativeBlur(idx, 'thickness', 2)" />
75 75 </template>
76 76 </uni-list-item>
77 77 <uni-list-item title="厚度公差(单项+)">
78 78 <template v-slot:footer>
79   - <uni-easyinput v-model="item.thicknessTolPos" :inputBorder="false"
80   - placeholder="请输入厚度公差(单项+)" />
  79 + <uni-easyinput type="digit" v-model="item.thicknessTolPos" :inputBorder="false"
  80 + placeholder="请输入厚度公差(单项+)" @input="onNonNegativeInput(idx, 'thicknessTolPos')" @blur="onNonNegativeBlur(idx, 'thicknessTolPos', 2)" />
81 81 </template>
82 82 </uni-list-item>
83 83 <uni-list-item title="厚度公差(单项-)">
84 84 <template v-slot:footer>
85   - <uni-easyinput v-model="item.thicknessTolNeg" :inputBorder="false"
86   - placeholder="请输入厚度公差(单项-)" />
  85 + <uni-easyinput type="digit" v-model="item.thicknessTolNeg" :inputBorder="false"
  86 + placeholder="请输入厚度公差(单项-)" @input="onNonNegativeInput(idx, 'thicknessTolNeg')" @blur="onNonNegativeBlur(idx, 'thicknessTolNeg', 2)" />
87 87 </template>
88 88 </uni-list-item>
89 89 <uni-list-item title="宽度">
90 90 <template v-slot:footer>
91   - <uni-easyinput v-model="item.width" :inputBorder="false" placeholder="请输入宽度" />
  91 + <uni-easyinput type="digit" v-model="item.width" :inputBorder="false" placeholder="请输入宽度" @input="onNonNegativeInput(idx, 'width')" @blur="onNonNegativeBlur(idx, 'width', 2)" />
92 92 </template>
93 93 </uni-list-item>
94 94 <uni-list-item title="宽度公差(单项+)">
95 95 <template v-slot:footer>
96   - <uni-easyinput v-model="item.widthTolPos" :inputBorder="false" placeholder="请输入宽度公差(单项+)" />
  96 + <uni-easyinput type="digit" v-model="item.widthTolPos" :inputBorder="false" placeholder="请输入宽度公差(单项+)" @input="onNonNegativeInput(idx, 'widthTolPos')" @blur="onNonNegativeBlur(idx, 'widthTolPos', 2)" />
97 97 </template>
98 98 </uni-list-item>
99 99 <uni-list-item title="宽度公差(单项-)">
100 100 <template v-slot:footer>
101   - <uni-easyinput v-model="item.widthTolNeg" :inputBorder="false" placeholder="请输入宽度公差(单项-)" />
  101 + <uni-easyinput type="digit" v-model="item.widthTolNeg" :inputBorder="false" placeholder="请输入宽度公差(单项-)" @input="onNonNegativeInput(idx, 'widthTolNeg')" @blur="onNonNegativeBlur(idx, 'widthTolNeg', 2)" />
102 102 </template>
103 103 </uni-list-item>
104 104 <uni-list-item title="长度">
105 105 <template v-slot:footer>
106   - <uni-easyinput v-model="item.length" :inputBorder="false" placeholder="请输入长度" />
  106 + <uni-easyinput type="digit" v-model="item.length" :inputBorder="false" placeholder="请输入长度" @input="onNonNegativeInput(idx, 'length')" @blur="onNonNegativeBlur(idx, 'length', 2)" />
107 107 </template>
108 108 </uni-list-item>
109 109 <uni-list-item title="长度公差(单项+)">
110 110 <template v-slot:footer>
111   - <uni-easyinput v-model="item.lengthTolPos" :inputBorder="false"
112   - placeholder="请输入长度公差(单项+)" />
  111 + <uni-easyinput type="digit" v-model="item.lengthTolPos" :inputBorder="false"
  112 + placeholder="请输入长度公差(单项+)" @input="onNonNegativeInput(idx, 'lengthTolPos')" @blur="onNonNegativeBlur(idx, 'lengthTolPos', 2)" />
113 113 </template>
114 114 </uni-list-item>
115 115 <uni-list-item title="长度公差(单项-)">
116 116 <template v-slot:footer>
117   - <uni-easyinput v-model="item.lengthTolNeg" :inputBorder="false"
118   - placeholder="请输入长度公差(单项-)" />
  117 + <uni-easyinput type="digit" v-model="item.lengthTolNeg" :inputBorder="false"
  118 + placeholder="请输入长度公差(单项-)" @input="onNonNegativeInput(idx, 'lengthTolNeg')" @blur="onNonNegativeBlur(idx, 'lengthTolNeg', 2)" />
119 119 </template>
120 120 </uni-list-item>
121 121 <uni-list-item title="定做物数量">
122 122 <template v-slot:footer>
123   - <uni-easyinput v-model="item.productQuantity" type="number" :inputBorder="false" placeholder="请输入数量" @input="onImmediateChange(idx)" @blur="onNumberBlur(idx, 'productQuantity', 0)" />
  123 + <uni-easyinput v-model="item.productQuantity" type="digit" :inputBorder="false" placeholder="请输入数量kg" @input="onNonNegativeInput(idx, 'productQuantity')" @blur="onNonNegativeBlur(idx, 'productQuantity', 2)" />
124 124 </template>
125 125 </uni-list-item>
126 126 <uni-list-item title="加工费单价">
127 127 <template v-slot:footer>
128   - <uni-easyinput v-model="item.unitPrice" type="number" :inputBorder="false" placeholder="请输入单价" @input="onImmediateChange(idx)" @blur="onNumberBlur(idx, 'unitPrice', 0)" />
  128 + <uni-easyinput v-model="item.unitPrice" type="digit" :inputBorder="false" placeholder="请输入销售价格" @input="onNonNegativeInput(idx, 'unitPrice')" @blur="onNonNegativeBlur(idx, 'unitPrice', 2)" />
129 129 </template>
130 130 </uni-list-item>
131 131 <uni-list-item title="不含税金额">
... ... @@ -140,7 +140,7 @@
140 140 </uni-list-item>
141 141 <uni-list-item title="发货日期">
142 142 <template v-slot:footer>
143   - <uni-datetime-picker type="date" v-model="item.orderDate" @change="onDateChange(idx, $event)" />
  143 + <uni-datetime-picker type="date" v-model="item.deliveryDate" @change="onDateChange(idx, $event)" />
144 144 </template>
145 145 </uni-list-item>
146 146 </uni-list>
... ... @@ -164,7 +164,30 @@
164 164 <view class="row"><text class="label">原材料到产品的转换比例</text><text class="value">{{ item.rawToProdRatioName }}</text></view>
165 165 <view class="row"><text class="label">行业</text><text class="value">{{ item.industry }}</text></view>
166 166 <view class="row"><text class="label">品质</text><text class="value">{{ item.quality }}</text></view>
167   - <view class="row"><text class="label">规格</text><text class="value">{{ item.specDisplay }}</text></view>
  167 + <!-- 厚(公差) * 宽(公差) * 长(公差) -->
  168 + <view class="row row-spec"><text class="label">规格(mm)</text>
  169 + <view class="value value-spec">
  170 + <view v-if="item.thickness" class="value-spec_val">{{ item.thickness }}</view>
  171 + <view v-if="item.thickness" class="value-spec_box">
  172 + <view v-if="item.thicknessTolPos" class="value-spec_box_1">+{{ item.thicknessTolPos }}
  173 + </view>
  174 + <view v-if="item.thicknessTolNeg" class="value-spec_box_2">-{{ item.thicknessTolNeg }}
  175 + </view>
  176 + </view>
  177 + <view v-if="item.width" class="value-spec_val p12">*</view>
  178 + <view v-if="item.width" class="value-spec_val">{{ item.width }}</view>
  179 + <view v-if="item.width" class="value-spec_box">
  180 + <view v-if="item.widthTolPos" class="value-spec_box_1">+{{ item.widthTolPos }}</view>
  181 + <view v-if="item.widthTolNeg" class="value-spec_box_2">-{{ item.widthTolNeg }}</view>
  182 + </view>
  183 + <view v-if="item.length" class="value-spec_val p12">*</view>
  184 + <view v-if="item.length" class="value-spec_val">{{ item.length }}</view>
  185 + <view v-if="item.length" class="value-spec_box">
  186 + <view v-if="item.lengthTolPos" class="value-spec_box_1">+{{ item.lengthTolPos }}</view>
  187 + <view v-if="item.lengthTolNeg" class="value-spec_box_2">-{{ item.lengthTolNeg }}</view>
  188 + </view>
  189 + </view>
  190 + </view>
168 191 <view class="row"><text class="label">定做物数量</text><text class="value">{{ item.productQuantity }}</text></view>
169 192 <view class="row"><text class="label">加工费单价</text><text class="value">{{ formatCurrency(item.unitPrice)
170 193 }}</text>
... ... @@ -174,7 +197,7 @@
174 197 }}</text></view>
175 198 <view class="row"><text class="label">总金额</text><text class="value">{{ formatCurrency(item.totalAmount)
176 199 }}</text></view>
177   - <view class="row"><text class="label">发货日期</text><text class="value">{{ item.orderDate }}</text></view>
  200 + <view class="row"><text class="label">发货日期</text><text class="value">{{ item.deliveryDate }}</text></view>
178 201 </view>
179 202 </view>
180 203 <SingleSelectSheet :visible.sync="sheet.visible" :title="sheet.title" :options="sheet.options" v-model="sheet.value" @confirm="onProductConfirm" />
... ... @@ -188,7 +211,7 @@ export default {
188 211 mode: { type: String, default: 'add' },
189 212 list: { type: Array, default: () => [] },
190 213 max: { type: Number, default: 8 },
191   - orderDateBase: { type: String, default: '' },
  214 + deliveryDateBase: { type: String, default: '' },
192 215 options: { type: Array, default: () => [] },
193 216 rawToProdRatioList: { type: Array, default: () => [] }
194 217 },
... ... @@ -239,7 +262,34 @@ export default {
239 262 },
240 263 methods: {
241 264 defaultItem() {
242   - return { rawProductId: '', rawProductName: '', rawProductGrade: '', industry: '',materialProductRatioRemarks:'', supplyTime: '存料加工', materialProductRatio: '', rawToProdRatioName: '', quality: '', thickness: '', thicknessTolPos: '', thicknessTolNeg: '', width: '', widthTolPos: '', widthTolNeg: '', length: '', lengthTolPos: '', lengthTolNeg: '', productQuantity: '', unitPrice: '', amountExcludingTax: 0, totalAmount: 0, orderDate: '' }
  265 + return { rawProductId: '', rawProductName: '', rawProductGrade: '', industry: '',materialProductRatioRemarks:'', supplyTime: '存料加工', materialProductRatio: '', rawToProdRatioName: '', quality: '', thickness: '', thicknessTolPos: '', thicknessTolNeg: '', width: '', widthTolPos: '', widthTolNeg: '', length: '', lengthTolPos: '', lengthTolNeg: '', productQuantity: '', unitPrice: '', amountExcludingTax: 0, totalAmount: 0, deliveryDate: '' }
  266 + },
  267 + onNonNegativeInput(idx, field) {
  268 + const it = this.items[idx]
  269 + if (!it) return
  270 + let v = String(it[field] != null ? it[field] : '')
  271 + v = v.replace(/[^0-9.]/g, '')
  272 + v = v.replace(/(\..*)\./g, '$1')
  273 + if (v.startsWith('.')) v = '0' + v
  274 + it[field] = v
  275 + this.$set(this.items, idx, it)
  276 + if (field === 'productQuantity' || field === 'unitPrice') this.$nextTick(() => this.recalculate(idx))
  277 + },
  278 + onNonNegativeBlur(idx, field, digits) {
  279 + const it = this.items[idx]
  280 + if (!it) return
  281 + const raw = it[field]
  282 + if (raw === '' || raw === null || raw === undefined) {
  283 + this.$set(this.items, idx, it)
  284 + if (field === 'productQuantity' || field === 'unitPrice') this.recalculate(idx)
  285 + return
  286 + }
  287 + let num = this.toNumber(raw)
  288 + if (isNaN(num) || num < 0) num = 0
  289 + const rounded = this.round(num, digits)
  290 + it[field] = rounded
  291 + this.$set(this.items, idx, it)
  292 + if (field === 'productQuantity' || field === 'unitPrice') this.recalculate(idx)
243 293 },
244 294 onImmediateChange(idx) {
245 295 this.$nextTick(() => this.recalculate(idx))
... ... @@ -351,15 +401,15 @@ export default {
351 401 onDateChange(idx, e) {
352 402 const it = this.items[idx]
353 403 if (!it) return
354   - const val = typeof e === 'string' ? e : (e && e.detail && e.detail.value) ? e.detail.value : it.orderDate
  404 + const val = typeof e === 'string' ? e : (e && e.detail && e.detail.value) ? e.detail.value : it.deliveryDate
355 405 const dateStr = String(val).slice(0, 10)
356   - const base = this.orderDateBase ? new Date(this.orderDateBase) : null
  406 + const base = this.deliveryDateBase ? new Date(this.deliveryDateBase) : null
357 407 const d = new Date(dateStr)
358 408 if (base && !isNaN(d.getTime()) && d.getTime() < base.getTime()) {
359 409 uni.showToast({ title: '发货日期不得早于订货日期', icon: 'none' })
360   - it.orderDate = this.orderDateBase
  410 + it.deliveryDate = this.deliveryDateBase
361 411 } else {
362   - it.orderDate = dateStr
  412 + it.deliveryDate = dateStr
363 413 }
364 414 this.$set(this.items, idx, it)
365 415 },
... ... @@ -532,8 +582,45 @@ export default {
532 582
533 583 .value {
534 584 flex: 1;
535   - text-align: right;
536 585 color: rgba(0, 0, 0, 0.9);
537 586 font-size: 28rpx;
538 587 }
  588 + .value-spec {
  589 + height: 48rpx;
  590 + display: flex;
  591 + align-items: center;
  592 + color: #000000;
  593 + // justify-content: end;
  594 + &_box {
  595 + position: relative;
  596 + width: 60rpx;
  597 + height: 48rpx;
  598 +
  599 + &_1 {
  600 + font-size: 16rpx;
  601 + position: absolute;
  602 + top: -10rpx;
  603 + left: 0;
  604 + }
  605 +
  606 + &_2 {
  607 + font-size: 16rpx;
  608 + position: absolute;
  609 + bottom: -10rpx;
  610 + left: 0;
  611 + }
  612 + }
  613 +
  614 + &_val {
  615 + font-size: 28rpx;
  616 +
  617 + &.p12 {
  618 + padding-right: 12rpx;
  619 + }
  620 + }
  621 + }
  622 + .row-spec {
  623 + height: 60rpx;
  624 + align-items: center;
  625 + }
539 626 </style>
... ...
... ... @@ -39,7 +39,7 @@
39 39 <view class="item-title"><text class="required">*</text><text>生产厂</text></view>
40 40 </template>
41 41 </uni-list-item>
42   - <ProductRel mode="add" :orderDateBase="form.orderDate" @change="onProductsChange" :options="productList" />
  42 + <ProductRel mode="add" :deliveryDateBase="form.deliveryDate" @change="onProductsChange" :options="productList" />
43 43 <uni-list-item title="合计人民币金额(大写)">
44 44 <template v-slot:footer>
45 45 <uni-easyinput v-model="form.totalAmountCapital" placeholder="自动计算" :inputBorder="false" disabled />
... ... @@ -92,33 +92,25 @@
92 92 :inputBorder="false" />
93 93 </template>
94 94 </uni-list-item>
95   - <view class="group">
96   - <view class="group-title">特别条款要求</view>
97   - <view class="radio-list">
98   - <view v-for="(opt, i) in specialTermsList" :key="'cr-' + i" class="radio-item"
99   - @click="onRadioSelect('specialTerms', 'specialTermsName', opt)">
100   - <view :class="['radio', { checked: form.specialTerms === opt.value }]" />
101   - <text class="label">{{ opt.label }}</text>
102   - </view>
103   - </view>
104   - </view>
105   - <view class="group">
106   - <view class="group-title">执行标准</view>
107   - <view class="radio-list">
108   - <view v-for="(opt, i) in executionStandardList" :key="'es-' + i" class="radio-item"
109   - @click="onRadioSelect('executionStandard', 'executionStandardName', opt)">
110   - <view :class="['radio', { checked: form.executionStandard === opt.value }]" />
111   - <text class="label">{{ opt.label }}</text>
112   - </view>
113   - </view>
114   - </view>
  95 + <uni-list-item class="select-item" :class="form.specialTermsName ? 'is-filled' : 'is-empty'" clickable
  96 + @click="openSheet('specialTerms')" :rightText="form.specialTermsName || '请选择'" showArrow>
  97 + <template v-slot:body>
  98 + <view class="item-title"><text class="required">*</text><text>特别条款要求</text></view>
  99 + </template>
  100 + </uni-list-item>
  101 + <uni-list-item class="select-item" :class="form.executionStandardName ? 'is-filled' : 'is-empty'" clickable
  102 + @click="openSheet('executionStandard')" :rightText="form.executionStandardName || '请选择'" showArrow>
  103 + <template v-slot:body>
  104 + <view class="item-title"><text>执行标准</text></view>
  105 + </template>
  106 + </uni-list-item>
115 107 <uni-list-item v-if="form.executionStandard === 'OTHER'" title="其他">
116 108 <template v-slot:footer>
117 109 <uni-easyinput v-model="form.executionStandardRemarks" placeholder="请输入其他标准备注"
118 110 :inputBorder="false" />
119 111 </template>
120 112 </uni-list-item>
121   - <uni-list-item title="特别说明">
  113 + <uni-list-item title="特别说明" style="margin-top: 20rpx;">
122 114 <template v-slot:footer>
123 115 <uni-easyinput v-model="form.specialInstructions" placeholder="请输入特别说明" :inputBorder="false" />
124 116 </template>
... ... @@ -181,7 +173,7 @@
181 173 数量
182 174 </div>
183 175 <div class="total-item-price">
184   - {{ (sumQuantity || 0).toFixed(2) }}t
  176 + {{ (totalQuantity || 0).toFixed(2) }}kg
185 177 </div>
186 178 </div>
187 179 <div class="total-item">
... ... @@ -189,7 +181,7 @@
189 181 不含税金额
190 182 </div>
191 183 <div class="total-item-price text-red">
192   - ¥{{ (sumAmountExcl || 0).toFixed(2) }}
  184 + ¥{{ (totalAmountExcludingTax || 0).toFixed(2) }}
193 185 </div>
194 186 </div>
195 187 <div class="total-item">
... ... @@ -197,7 +189,7 @@
197 189 总金额
198 190 </div>
199 191 <div class="total-item-price text-red">
200   - ¥{{ (sumTotal || 0).toFixed(2) }}
  192 + ¥{{ (totalAmountIncludingTax || 0).toFixed(2) }}
201 193 </div>
202 194 </div>
203 195 </div>
... ... @@ -233,6 +225,7 @@ export default {
233 225 buyer: '',
234 226 buyerName: '',
235 227 orderDate: '',
  228 + deliveryDate: '',
236 229 designatedConsignee: '',
237 230 specialTerms: '',
238 231 specialTermsName: '',
... ... @@ -263,9 +256,9 @@ export default {
263 256 yesNoList: [{ label: '是', value: true }, { label: '否', value: false }],
264 257 sheet: { visible: false, title: '请选择', field: '', options: [], value: '' },
265 258 relate: { visible: false, title: '选择', source: '', display: [], multiple: false, rowKey: 'id', selectedKeys: [], fieldKey: '' },
266   - sumQuantity: 0,
267   - sumAmountExcl: 0,
268   - sumTotal: 0,
  259 + totalQuantity: 0,
  260 + totalAmountExcludingTax: 0,
  261 + totalAmountIncludingTax: 0,
269 262 productLineList: [],
270 263 productList: [],
271 264 customerRemarks: [],
... ... @@ -369,9 +362,9 @@ export default {
369 362 const sumQ = list.reduce((acc, it) => acc + (parseFloat(it.quantity) || 0), 0)
370 363 const sumE = list.reduce((acc, it) => acc + (parseFloat(it.amountExcludingTax) || 0), 0)
371 364 const sumT = list.reduce((acc, it) => acc + (parseFloat(it.totalAmount) || 0), 0)
372   - this.sumQuantity = sumQ
373   - this.sumAmountExcl = sumE
374   - this.sumTotal = sumT
  365 + this.totalQuantity = sumQ
  366 + this.totalAmountExcludingTax = sumE
  367 + this.totalAmountIncludingTax = sumT
375 368 this.form.totalAmountCapital = formatCurrencyToChinese(sumT)
376 369 this.productLineList = list
377 370 },
... ... @@ -447,6 +440,10 @@ export default {
447 440 setSheet('生产厂', opts)
448 441 } else if (field === 'supplier') {
449 442 setSheet('供方', this.supplierList)
  443 + } else if (field === 'specialTerms') {
  444 + setSheet('特别条款要求', this.specialTermsList)
  445 + } else if (field === 'executionStandard') {
  446 + setSheet('执行标准', this.executionStandardList)
450 447 } else if (field === 'includesPackagingFee') {
451 448 setSheet('单价中是否已包含包装费', this.yesNoList)
452 449 } else if (field === 'includesTransportFee') {
... ... @@ -517,9 +514,9 @@ export default {
517 514 ...formForSubmit,
518 515 destination,
519 516 type: 'DISTRIB_STD',
520   - sumQuantity: this.sumQuantity,
521   - sumAmountExcl: this.sumAmountExcl,
522   - sumTotal: this.sumTotal,
  517 + totalQuantity: this.totalQuantity,
  518 + totalAmountExcludingTax: this.totalAmountExcludingTax,
  519 + totalAmountIncludingTax: this.totalAmountIncludingTax,
523 520 contractDistributorLineList: lines
524 521 })
525 522 console.log('onSubmit__payload', payload)
... ... @@ -538,18 +535,31 @@ export default {
538 535 { key: 'supplier', label: '供方' },
539 536 { key: 'buyer', label: '需方' },
540 537 { key: 'orderDate', label: '订货日期' },
  538 + { key: 'unit', label: '单位' },
541 539 { key: 'workshopId', label: '生产厂' },
  540 + { key: 'specialTerms', label: '特别条款要求' },
542 541 ]
543 542 for (const it of checks) {
544 543 const val = this.form[it.key]
545 544 const empty = (val === undefined || val === null || (typeof val === 'string' && val.trim() === '') || (typeof val === 'number' && isNaN(val)))
546 545 if (empty) { uni.showToast({ title: `请先选择${it.label}`, icon: 'none' }); return false }
547 546 }
548   - if (!Array.isArray(this.productLineList) || this.productLineList.length === 0) {
  547 + const list = Array.isArray(this.productLineList) ? this.productLineList : []
  548 + if (list.length === 0) {
549 549 uni.showToast({ title: '请至少添加一条产品明细', icon: 'none' }); return false
550 550 }
551   - for (const [idx, it] of this.productLineList.entries()) {
552   - if (!it.productName || !it.quantity || !it.unitPrice) {
  551 + const strEmpty = (v) => (v === undefined || v === null || (typeof v === 'string' && v.trim() === ''))
  552 + const numEmpty = (v) => (v === undefined || v === null || v === '' || (typeof v === 'number' && isNaN(v)))
  553 + for (const [idx, it] of list.entries()) {
  554 + if (
  555 + strEmpty(it.productName) ||
  556 + strEmpty(it.industry) ||
  557 + strEmpty(it.quality) ||
  558 + strEmpty(it.brand) ||
  559 + numEmpty(it.quantity) ||
  560 + numEmpty(it.unitPrice) ||
  561 + strEmpty(it.deliveryDate)
  562 + ) {
553 563 uni.showToast({ title: `第${idx + 1}条明细未完整填写`, icon: 'none' }); return false
554 564 }
555 565 }
... ... @@ -577,7 +587,7 @@ export default {
577 587 color: rgba(0, 0, 0, 0.6);
578 588 line-height: 32rpx;
579 589 width: 240rpx;
580   - padding: 24rpx 0;
  590 + padding: 12rpx 0;
581 591 }
582 592 .total-item-price {
583 593 font-weight: 600;
... ... @@ -599,7 +609,7 @@ export default {
599 609
600 610 .scroll {
601 611 flex: 1;
602   - padding: 12rpx 0 480rpx !important;
  612 + padding: 12rpx 0 392rpx !important;
603 613 }
604 614
605 615 .footer {
... ...
... ... @@ -41,7 +41,7 @@
41 41 </template>
42 42 </uni-list-item>
43 43
44   - <ProductRel mode="add" :orderDateBase="form.orderDate" :list="productLineList" @change="onProductsChange" :options="productList" />
  44 + <ProductRel mode="add" :deliveryDateBase="form.deliveryDate" :list="productLineList" @change="onProductsChange" :options="productList" />
45 45
46 46 <uni-list-item title="合计人民币金额(大写)">
47 47 <template v-slot:footer>
... ... @@ -99,33 +99,25 @@
99 99 </template>
100 100 </uni-list-item>
101 101
102   - <view class="group">
103   - <view class="group-title">特别条款要求</view>
104   - <view class="radio-list">
105   - <view v-for="(opt, i) in specialTermsList" :key="'cr-' + i" class="radio-item"
106   - @click="onRadioSelect('specialTerms', 'specialTermsName', opt)">
107   - <view :class="['radio', { checked: form.specialTerms === opt.value }]" />
108   - <text class="label">{{ opt.label }}</text>
109   - </view>
110   - </view>
111   - </view>
112   - <view class="group">
113   - <view class="group-title">执行标准</view>
114   - <view class="radio-list">
115   - <view v-for="(opt, i) in executionStandardList" :key="'es-' + i" class="radio-item"
116   - @click="onRadioSelect('executionStandard', 'executionStandardName', opt)">
117   - <view :class="['radio', { checked: form.executionStandard === opt.value }]" />
118   - <text class="label">{{ opt.label }}</text>
119   - </view>
120   - </view>
121   - </view>
  102 + <uni-list-item class="select-item" :class="form.specialTermsName ? 'is-filled' : 'is-empty'" clickable
  103 + @click="openSheet('specialTerms')" :rightText="form.specialTermsName || '请选择'" showArrow>
  104 + <template v-slot:body>
  105 + <view class="item-title"><text class="required">*</text><text>特别条款要求</text></view>
  106 + </template>
  107 + </uni-list-item>
  108 + <uni-list-item class="select-item" :class="form.executionStandardName ? 'is-filled' : 'is-empty'" clickable
  109 + @click="openSheet('executionStandard')" :rightText="form.executionStandardName || '请选择'" showArrow>
  110 + <template v-slot:body>
  111 + <view class="item-title"><text>执行标准</text></view>
  112 + </template>
  113 + </uni-list-item>
122 114 <uni-list-item v-if="form.executionStandard === 'OTHER'" title="其他">
123 115 <template v-slot:footer>
124 116 <uni-easyinput v-model="form.executionStandardRemarks" placeholder="请输入其他标准备注"
125 117 :inputBorder="false" />
126 118 </template>
127 119 </uni-list-item>
128   - <uni-list-item title="特别说明">
  120 + <uni-list-item title="特别说明" style="margin-top: 20rpx;">
129 121 <template v-slot:footer>
130 122 <uni-easyinput v-model="form.specialInstructions" placeholder="请输入特别说明" :inputBorder="false" />
131 123 </template>
... ... @@ -177,15 +169,15 @@
177 169 <div class="total-text">合计</div>
178 170 <div class="total-item">
179 171 <div class="total-item-text">数量</div>
180   - <div class="total-item-price">{{ (sumQuantity || 0).toFixed(2) }}t</div>
  172 + <div class="total-item-price">{{ (totalQuantity || 0).toFixed(2) }}kg</div>
181 173 </div>
182 174 <div class="total-item">
183 175 <div class="total-item-text">不含税金额</div>
184   - <div class="total-item-price text-red">¥{{ (sumAmountExcl || 0).toFixed(2) }}</div>
  176 + <div class="total-item-price text-red">¥{{ (totalAmountExcludingTax || 0).toFixed(2) }}</div>
185 177 </div>
186 178 <div class="total-item">
187 179 <div class="total-item-text">总金额</div>
188   - <div class="total-item-price text-red">¥{{ (sumTotal || 0).toFixed(2) }}</div>
  180 + <div class="total-item-price text-red">¥{{ (totalAmountIncludingTax || 0).toFixed(2) }}</div>
189 181 </div>
190 182 </div>
191 183 <button class="btn submit" type="primary" @click="onSubmit">保存</button>
... ... @@ -223,6 +215,7 @@ export default {
223 215 workshopId: '',
224 216 workshopName: '',
225 217 orderDate: '',
  218 + deliveryDate: '',
226 219 designatedConsignee: '',
227 220 specialTerms: '',
228 221 specialTermsName: '',
... ... @@ -256,9 +249,9 @@ export default {
256 249 yesNoList: [{ label: '是', value: true }, { label: '否', value: false }],
257 250 sheet: { visible: false, title: '请选择', field: '', options: [], value: '' },
258 251 relate: { visible: false, title: '选择', source: '', display: [], multiple: false, rowKey: 'id', selectedKeys: [], fieldKey: '' },
259   - sumQuantity: 0,
260   - sumAmountExcl: 0,
261   - sumTotal: 0,
  252 + totalQuantity: 0,
  253 + totalAmountExcludingTax: 0,
  254 + totalAmountIncludingTax: 0,
262 255 productLineList: [],
263 256 newProductLineList: [],
264 257 productList: []
... ... @@ -349,9 +342,9 @@ export default {
349 342 const sumQ = list.reduce((acc, it) => acc + (parseFloat(it.quantity) || 0), 0)
350 343 const sumE = list.reduce((acc, it) => acc + (parseFloat(it.amountExcludingTax) || 0), 0)
351 344 const sumT = list.reduce((acc, it) => acc + (parseFloat(it.totalAmount) || 0), 0)
352   - this.sumQuantity = sumQ
353   - this.sumAmountExcl = sumE
354   - this.sumTotal = sumT
  345 + this.totalQuantity = sumQ
  346 + this.totalAmountExcludingTax = sumE
  347 + this.totalAmountIncludingTax = sumT
355 348 this.form.totalAmountCapital = formatCurrencyToChinese(sumT)
356 349 },
357 350 async loadSuppliers() {
... ... @@ -399,6 +392,10 @@ export default {
399 392 setSheet('生产厂', opts)
400 393 } else if (field === 'supplier') {
401 394 setSheet('供方', this.supplierList)
  395 + } else if (field === 'specialTerms') {
  396 + setSheet('特别条款要求', this.specialTermsList)
  397 + } else if (field === 'executionStandard') {
  398 + setSheet('执行标准', this.executionStandardList)
402 399 } else if (field === 'includesPackagingFee') {
403 400 setSheet('单价中是否已包含包装费', this.yesNoList)
404 401 } else if (field === 'includesTransportFee') {
... ... @@ -443,18 +440,32 @@ export default {
443 440 { key: 'supplier', label: '供方' },
444 441 { key: 'buyer', label: '需方' },
445 442 { key: 'orderDate', label: '订货日期' },
  443 + { key: 'unit', label: '单位' },
446 444 { key: 'workshopId', label: '生产厂' },
  445 + { key: 'specialTerms', label: '特别条款要求' },
447 446 ]
448 447 for (const it of checks) {
449 448 const val = this.form[it.key]
450 449 const empty = (val === undefined || val === null || (typeof val === 'string' && val.trim() === '') || (typeof val === 'number' && isNaN(val)))
451 450 if (empty) { uni.showToast({ title: `请先选择${it.label}`, icon: 'none' }); return false }
452 451 }
453   - if (!Array.isArray(this.productLineList) || this.productLineList.length === 0) {
  452 + const list = Array.isArray(this.newProductLineList) ? this.newProductLineList : []
  453 + if (list.length === 0) {
454 454 uni.showToast({ title: '请至少添加一条产品明细', icon: 'none' }); return false
455 455 }
456   - for (const [idx, it] of this.productLineList.entries()) {
457   - if (!it.productName || !it.quantity || !it.unitPrice) {
  456 + const strEmpty = (v) => (v === undefined || v === null || (typeof v === 'string' && v.trim() === ''))
  457 + const numEmpty = (v) => (v === undefined || v === null || v === '' || (typeof v === 'number' && isNaN(v)))
  458 + for (const [idx, it] of list.entries()) {
  459 + console.log('it111', it)
  460 + if (
  461 + strEmpty(it.productName) ||
  462 + strEmpty(it.industry) ||
  463 + strEmpty(it.quality) ||
  464 + strEmpty(it.brand) ||
  465 + numEmpty(it.quantity) ||
  466 + numEmpty(it.unitPrice) ||
  467 + strEmpty(it.deliveryDate)
  468 + ) {
458 469 uni.showToast({ title: `第${idx + 1}条明细未完整填写`, icon: 'none' }); return false
459 470 }
460 471 }
... ... @@ -486,9 +497,9 @@ export default {
486 497 id: this.form.id,
487 498 destination,
488 499 type: 'DISTRIB_STD',
489   - sumQuantity: this.sumQuantity,
490   - sumAmountExcl: this.sumAmountExcl,
491   - sumTotal: this.sumTotal,
  500 + totalQuantity: this.totalQuantity,
  501 + totalAmountExcludingTax: this.totalAmountExcludingTax,
  502 + totalAmountIncludingTax: this.totalAmountIncludingTax,
492 503 contractDistributorLineList: lines
493 504 })
494 505 try {
... ... @@ -524,7 +535,7 @@ export default {
524 535 color: rgba(0, 0, 0, 0.6);
525 536 line-height: 32rpx;
526 537 width: 240rpx;
527   - padding: 24rpx 0;
  538 + padding: 12rpx 0;
528 539 }
529 540
530 541 .total-item-price {
... ... @@ -547,7 +558,7 @@ export default {
547 558
548 559 .scroll {
549 560 flex: 1;
550   - padding: 12rpx 0 480rpx !important;
  561 + padding: 12rpx 0 392rpx !important;
551 562 }
552 563
553 564 .footer {
... ... @@ -742,4 +753,4 @@ export default {
742 753 }
743 754 }
744 755
745   -</style>
\ No newline at end of file
  756 +</style>
... ...
... ... @@ -55,51 +55,51 @@
55 55 </uni-list-item>
56 56 <uni-list-item title="厚度">
57 57 <template v-slot:footer>
58   - <uni-easyinput v-model="item.thickness" :inputBorder="false" placeholder="请输入厚度" />
  58 + <uni-easyinput type="digit" v-model="item.thickness" :inputBorder="false" placeholder="请输入厚度" @input="onNonNegativeInput(idx, 'thickness')" @blur="onNonNegativeBlur(idx, 'thickness', 2)" />
59 59 </template>
60 60 </uni-list-item>
61 61 <uni-list-item title="厚度公差(单项+)">
62 62 <template v-slot:footer>
63   - <uni-easyinput v-model="item.thicknessTolPos" :inputBorder="false"
64   - placeholder="请输入厚度公差(单项+)" />
  63 + <uni-easyinput type="digit" v-model="item.thicknessTolPos" :inputBorder="false"
  64 + placeholder="请输入厚度公差(单项+)" @input="onNonNegativeInput(idx, 'thicknessTolPos')" @blur="onNonNegativeBlur(idx, 'thicknessTolPos', 2)" />
65 65 </template>
66 66 </uni-list-item>
67 67 <uni-list-item title="厚度公差(单项-)">
68 68 <template v-slot:footer>
69   - <uni-easyinput v-model="item.thicknessTolNeg" :inputBorder="false"
70   - placeholder="请输入厚度公差(单项-)" />
  69 + <uni-easyinput type="digit" v-model="item.thicknessTolNeg" :inputBorder="false"
  70 + placeholder="请输入厚度公差(单项-)" @input="onNonNegativeInput(idx, 'thicknessTolNeg')" @blur="onNonNegativeBlur(idx, 'thicknessTolNeg', 2)" />
71 71 </template>
72 72 </uni-list-item>
73 73 <uni-list-item title="宽度">
74 74 <template v-slot:footer>
75   - <uni-easyinput v-model="item.width" :inputBorder="false" placeholder="请输入宽度" />
  75 + <uni-easyinput type="digit" v-model="item.width" :inputBorder="false" placeholder="请输入宽度" @input="onNonNegativeInput(idx, 'width')" @blur="onNonNegativeBlur(idx, 'width', 2)" />
76 76 </template>
77 77 </uni-list-item>
78 78 <uni-list-item title="宽度公差(单项+)">
79 79 <template v-slot:footer>
80   - <uni-easyinput v-model="item.widthTolPos" :inputBorder="false" placeholder="请输入宽度公差(单项+)" />
  80 + <uni-easyinput type="digit" v-model="item.widthTolPos" :inputBorder="false" placeholder="请输入宽度公差(单项+)" @input="onNonNegativeInput(idx, 'widthTolPos')" @blur="onNonNegativeBlur(idx, 'widthTolPos', 2)" />
81 81 </template>
82 82 </uni-list-item>
83 83 <uni-list-item title="宽度公差(单项-)">
84 84 <template v-slot:footer>
85   - <uni-easyinput v-model="item.widthTolNeg" :inputBorder="false" placeholder="请输入宽度公差(单项-)" />
  85 + <uni-easyinput type="digit" v-model="item.widthTolNeg" :inputBorder="false" placeholder="请输入宽度公差(单项-)" @input="onNonNegativeInput(idx, 'widthTolNeg')" @blur="onNonNegativeBlur(idx, 'widthTolNeg', 2)" />
86 86 </template>
87 87 </uni-list-item>
88 88 <uni-list-item title="长度">
89 89 <template v-slot:footer>
90   - <uni-easyinput v-model="item.length" :inputBorder="false" placeholder="请输入长度" />
  90 + <uni-easyinput type="digit" v-model="item.length" :inputBorder="false" placeholder="请输入长度" @input="onNonNegativeInput(idx, 'length')" @blur="onNonNegativeBlur(idx, 'length', 2)" />
91 91 </template>
92 92 </uni-list-item>
93 93 <uni-list-item title="长度公差(单项+)">
94 94 <template v-slot:footer>
95   - <uni-easyinput v-model="item.lengthTolPos" :inputBorder="false"
96   - placeholder="请输入长度公差(单项+)" />
  95 + <uni-easyinput type="digit" v-model="item.lengthTolPos" :inputBorder="false"
  96 + placeholder="请输入长度公差(单项+)" @input="onNonNegativeInput(idx, 'lengthTolPos')" @blur="onNonNegativeBlur(idx, 'lengthTolPos', 2)" />
97 97 </template>
98 98 </uni-list-item>
99 99 <uni-list-item title="长度公差(单项-)">
100 100 <template v-slot:footer>
101   - <uni-easyinput v-model="item.lengthTolNeg" :inputBorder="false"
102   - placeholder="请输入长度公差(单项-)" />
  101 + <uni-easyinput type="digit" v-model="item.lengthTolNeg" :inputBorder="false"
  102 + placeholder="请输入长度公差(单项-)" @input="onNonNegativeInput(idx, 'lengthTolNeg')" @blur="onNonNegativeBlur(idx, 'lengthTolNeg', 2)" />
103 103 </template>
104 104 </uni-list-item>
105 105 <uni-list-item title="状态">
... ... @@ -107,14 +107,14 @@
107 107 <uni-easyinput v-model="item.status" :inputBorder="false" placeholder="请输入状态" />
108 108 </template>
109 109 </uni-list-item>
110   - <uni-list-item title="数量">
  110 + <uni-list-item title="数量kg">
111 111 <template v-slot:footer>
112   - <uni-easyinput v-model="item.quantity" type="number" :inputBorder="false" placeholder="请输入数量" @input="onImmediateChange(idx)" @blur="onNumberBlur(idx, 'quantity', 0)" />
  112 + <uni-easyinput v-model="item.quantity" type="digit" :inputBorder="false" placeholder="请输入数量kg" @input="onNonNegativeInput(idx, 'quantity')" @blur="onNonNegativeBlur(idx, 'quantity', 2)" />
113 113 </template>
114 114 </uni-list-item>
115   - <uni-list-item title="单价">
  115 + <uni-list-item title="销售价格">
116 116 <template v-slot:footer>
117   - <uni-easyinput v-model="item.unitPrice" type="number" :inputBorder="false" placeholder="请输入单价" @input="onImmediateChange(idx)" @blur="onNumberBlur(idx, 'unitPrice', 0)" />
  117 + <uni-easyinput v-model="item.unitPrice" type="digit" :inputBorder="false" placeholder="请输入销售价格" @input="onNonNegativeInput(idx, 'unitPrice')" @blur="onNonNegativeBlur(idx, 'unitPrice', 2)" />
118 118 </template>
119 119 </uni-list-item>
120 120 <uni-list-item title="不含税金额">
... ... @@ -129,7 +129,7 @@
129 129 </uni-list-item>
130 130 <uni-list-item title="发货日期">
131 131 <template v-slot:footer>
132   - <uni-datetime-picker type="date" v-model="item.orderDate" @change="onDateChange(idx, $event)" />
  132 + <uni-datetime-picker type="date" v-model="item.deliveryDate" @change="onDateChange(idx, $event)" />
133 133 </template>
134 134 </uni-list-item>
135 135 </uni-list>
... ... @@ -151,7 +151,30 @@
151 151 <view class="row"><text class="label">行业</text><text class="value">{{ item.industry }}</text></view>
152 152 <view class="row"><text class="label">牌号</text><text class="value">{{ item.brand }}</text></view>
153 153 <view class="row"><text class="label">品质</text><text class="value">{{ item.quality }}</text></view>
154   - <view class="row"><text class="label">规格</text><text class="value">{{ item.specDisplay }}</text></view>
  154 + <!-- 厚(公差) * 宽(公差) * 长(公差) -->
  155 + <view class="row row-spec"><text class="label">规格(mm)</text>
  156 + <view class="value value-spec">
  157 + <view v-if="item.thickness" class="value-spec_val">{{ item.thickness }}</view>
  158 + <view v-if="item.thickness" class="value-spec_box">
  159 + <view v-if="item.thicknessTolPos" class="value-spec_box_1">+{{ item.thicknessTolPos }}
  160 + </view>
  161 + <view v-if="item.thicknessTolNeg" class="value-spec_box_2">-{{ item.thicknessTolNeg }}
  162 + </view>
  163 + </view>
  164 + <view v-if="item.width" class="value-spec_val p12">*</view>
  165 + <view v-if="item.width" class="value-spec_val">{{ item.width }}</view>
  166 + <view v-if="item.width" class="value-spec_box">
  167 + <view v-if="item.widthTolPos" class="value-spec_box_1">+{{ item.widthTolPos }}</view>
  168 + <view v-if="item.widthTolNeg" class="value-spec_box_2">-{{ item.widthTolNeg }}</view>
  169 + </view>
  170 + <view v-if="item.length" class="value-spec_val p12">*</view>
  171 + <view v-if="item.length" class="value-spec_val">{{ item.length }}</view>
  172 + <view v-if="item.length" class="value-spec_box">
  173 + <view v-if="item.lengthTolPos" class="value-spec_box_1">+{{ item.lengthTolPos }}</view>
  174 + <view v-if="item.lengthTolNeg" class="value-spec_box_2">-{{ item.lengthTolNeg }}</view>
  175 + </view>
  176 + </view>
  177 + </view>
155 178 <view class="row"><text class="label">状态</text><text class="value">{{ item.status }}</text></view>
156 179 <view class="row"><text class="label">数量</text><text class="value">{{ item.quantity }}</text></view>
157 180 <view class="row"><text class="label">单价</text><text class="value">{{ formatCurrency(item.unitPrice)
... ... @@ -162,7 +185,7 @@
162 185 }}</text></view>
163 186 <view class="row"><text class="label">总金额</text><text class="value">{{ formatCurrency(item.totalAmount)
164 187 }}</text></view>
165   - <view class="row"><text class="label">发货日期</text><text class="value">{{ item.orderDate }}</text></view>
  188 + <view class="row"><text class="label">发货日期</text><text class="value">{{ item.deliveryDate }}</text></view>
166 189 </view>
167 190 </view>
168 191 <SingleSelectSheet :visible.sync="sheet.visible" :title="sheet.title" :options="sheet.options" v-model="sheet.value" @confirm="onProductConfirm" />
... ... @@ -176,7 +199,7 @@ export default {
176 199 mode: { type: String, default: 'add' },
177 200 list: { type: Array, default: () => [] },
178 201 max: { type: Number, default: 8 },
179   - orderDateBase: { type: String, default: '' },
  202 + deliveryDateBase: { type: String, default: '' },
180 203 options: { type: Array, default: () => [] }
181 204 },
182 205 components: { SingleSelectSheet },
... ... @@ -218,10 +241,18 @@ export default {
218 241 },
219 242 methods: {
220 243 defaultItem() {
221   - return { productId: '', productName: '', industry: '', brand: '', quality: '', thickness: '', thicknessTolPos: '', thicknessTolNeg: '', width: '', widthTolPos: '', widthTolNeg: '', length: '', lengthTolPos: '', lengthTolNeg: '', status: '', quantity: '', unitPrice: '', amountExcludingTax: 0, totalAmount: 0, orderDate: '' }
  244 + return { productId: '', productName: '', industry: '', brand: '', quality: '', thickness: '', thicknessTolPos: '', thicknessTolNeg: '', width: '', widthTolPos: '', widthTolNeg: '', length: '', lengthTolPos: '', lengthTolNeg: '', status: '', quantity: '', unitPrice: '', amountExcludingTax: 0, totalAmount: 0, deliveryDate: '' }
222 245 },
223   - onImmediateChange(idx) {
224   - this.$nextTick(() => this.recalculate(idx))
  246 + onNonNegativeInput(idx, field) {
  247 + const it = this.items[idx]
  248 + if (!it) return
  249 + let v = String(it[field] != null ? it[field] : '')
  250 + v = v.replace(/[^0-9.]/g, '')
  251 + v = v.replace(/(\..*)\./g, '$1')
  252 + if (v.startsWith('.')) v = '0' + v
  253 + it[field] = v
  254 + this.$set(this.items, idx, it)
  255 + if (field === 'quantity' || field === 'unitPrice') this.$nextTick(() => this.recalculate(idx))
225 256 },
226 257 toNumber(val) {
227 258 if (typeof val === 'number') return isNaN(val) ? 0 : val
... ... @@ -234,21 +265,21 @@ export default {
234 265 const m = Math.pow(10, digits)
235 266 return Math.round(n * m) / m
236 267 },
237   - onNumberBlur(idx, field, digits) {
  268 + onNonNegativeBlur(idx, field, digits) {
238 269 const it = this.items[idx]
239 270 if (!it) return
240 271 const raw = it[field]
241   - // 如果为空则保持为空,不自动置为0,仅重新计算依赖字段
242 272 if (raw === '' || raw === null || raw === undefined) {
243 273 this.$set(this.items, idx, it)
244   - this.recalculate(idx)
  274 + if (field === 'quantity' || field === 'unitPrice') this.recalculate(idx)
245 275 return
246 276 }
247   - const num = this.toNumber(raw)
  277 + let num = this.toNumber(raw)
  278 + if (isNaN(num) || num < 0) num = 0
248 279 const rounded = this.round(num, digits)
249 280 it[field] = rounded
250 281 this.$set(this.items, idx, it)
251   - this.recalculate(idx)
  282 + if (field === 'quantity' || field === 'unitPrice') this.recalculate(idx)
252 283 },
253 284 formatCurrency(val) {
254 285 if (val == null || val === '') return ''
... ... @@ -319,15 +350,15 @@ export default {
319 350 onDateChange(idx, e) {
320 351 const it = this.items[idx]
321 352 if (!it) return
322   - const val = typeof e === 'string' ? e : (e && e.detail && e.detail.value) ? e.detail.value : it.orderDate
  353 + const val = typeof e === 'string' ? e : (e && e.detail && e.detail.value) ? e.detail.value : it.deliveryDate
323 354 const dateStr = String(val).slice(0, 10)
324   - const base = this.orderDateBase ? new Date(this.orderDateBase) : null
  355 + const base = this.deliveryDateBase ? new Date(this.deliveryDateBase) : null
325 356 const d = new Date(dateStr)
326 357 if (base && !isNaN(d.getTime()) && d.getTime() < base.getTime()) {
327 358 uni.showToast({ title: '发货日期不得早于订货日期', icon: 'none' })
328   - it.orderDate = this.orderDateBase
  359 + it.deliveryDate = this.deliveryDateBase
329 360 } else {
330   - it.orderDate = dateStr
  361 + it.deliveryDate = dateStr
331 362 }
332 363 this.$set(this.items, idx, it)
333 364 },
... ... @@ -500,8 +531,46 @@ export default {
500 531
501 532 .value {
502 533 flex: 1;
503   - text-align: right;
  534 + // text-align: right;
504 535 color: rgba(0, 0, 0, 0.9);
505 536 font-size: 28rpx;
506 537 }
  538 + .value-spec {
  539 + height: 48rpx;
  540 + display: flex;
  541 + align-items: center;
  542 + color: #000000;
  543 + // justify-content: end;
  544 + &_box {
  545 + position: relative;
  546 + width: 60rpx;
  547 + height: 48rpx;
  548 +
  549 + &_1 {
  550 + font-size: 16rpx;
  551 + position: absolute;
  552 + top: -10rpx;
  553 + left: 0;
  554 + }
  555 +
  556 + &_2 {
  557 + font-size: 16rpx;
  558 + position: absolute;
  559 + bottom: -10rpx;
  560 + left: 0;
  561 + }
  562 + }
  563 +
  564 + &_val {
  565 + font-size: 28rpx;
  566 +
  567 + &.p12 {
  568 + padding-right: 12rpx;
  569 + }
  570 + }
  571 + }
  572 + .row-spec {
  573 + height: 60rpx;
  574 + align-items: center;
  575 + }
507 576 </style>
... ...
... ... @@ -39,7 +39,7 @@
39 39 <view class="item-title"><text class="required">*</text><text>生产厂</text></view>
40 40 </template>
41 41 </uni-list-item>
42   - <ProductRel mode="add" :orderDateBase="form.orderDate" @change="onProductsChange" :options="productList" />
  42 + <ProductRel mode="add" :deliveryDateBase="form.deliveryDate" @change="onProductsChange" :options="productList" />
43 43 <uni-list-item title="合计人民币金额(大写)">
44 44 <template v-slot:footer>
45 45 <uni-easyinput v-model="form.totalAmountCapital" placeholder="自动计算" :inputBorder="false" disabled />
... ... @@ -92,33 +92,25 @@
92 92 :inputBorder="false" />
93 93 </template>
94 94 </uni-list-item>
95   - <view class="group">
96   - <view class="group-title">特别条款要求</view>
97   - <view class="radio-list">
98   - <view v-for="(opt, i) in specialTermsList" :key="'cr-' + i" class="radio-item"
99   - @click="onRadioSelect('specialTerms', 'specialTermsName', opt)">
100   - <view :class="['radio', { checked: form.specialTerms === opt.value }]" />
101   - <text class="label">{{ opt.label }}</text>
102   - </view>
103   - </view>
104   - </view>
105   - <view class="group">
106   - <view class="group-title">执行标准</view>
107   - <view class="radio-list">
108   - <view v-for="(opt, i) in executionStandardList" :key="'es-' + i" class="radio-item"
109   - @click="onRadioSelect('executionStandard', 'executionStandardName', opt)">
110   - <view :class="['radio', { checked: form.executionStandard === opt.value }]" />
111   - <text class="label">{{ opt.label }}</text>
112   - </view>
113   - </view>
114   - </view>
  95 + <uni-list-item class="select-item" :class="form.specialTermsName ? 'is-filled' : 'is-empty'" clickable
  96 + @click="openSheet('specialTerms')" :rightText="form.specialTermsName || '请选择'" showArrow>
  97 + <template v-slot:body>
  98 + <view class="item-title"><text class="required">*</text><text>特别条款要求</text></view>
  99 + </template>
  100 + </uni-list-item>
  101 + <uni-list-item class="select-item" :class="form.executionStandardName ? 'is-filled' : 'is-empty'" clickable
  102 + @click="openSheet('executionStandard')" :rightText="form.executionStandardName || '请选择'" showArrow>
  103 + <template v-slot:body>
  104 + <view class="item-title"><text>执行标准</text></view>
  105 + </template>
  106 + </uni-list-item>
115 107 <uni-list-item v-if="form.executionStandard === 'OTHER'" title="其他">
116 108 <template v-slot:footer>
117 109 <uni-easyinput v-model="form.executionStandardRemarks" placeholder="请输入其他标准备注"
118 110 :inputBorder="false" />
119 111 </template>
120 112 </uni-list-item>
121   - <uni-list-item title="特别说明">
  113 + <uni-list-item title="特别说明" style="margin-top: 20rpx;">
122 114 <template v-slot:footer>
123 115 <uni-easyinput v-model="form.specialInstructions" placeholder="请输入特别说明" :inputBorder="false" />
124 116 </template>
... ... @@ -181,7 +173,7 @@
181 173 数量
182 174 </div>
183 175 <div class="total-item-price">
184   - {{ (sumQuantity || 0).toFixed(2) }}t
  176 + {{ (totalQuantity || 0).toFixed(2) }}kg
185 177 </div>
186 178 </div>
187 179 <div class="total-item">
... ... @@ -189,7 +181,7 @@
189 181 不含税金额
190 182 </div>
191 183 <div class="total-item-price text-red">
192   - ¥{{ (sumAmountExcl || 0).toFixed(2) }}
  184 + ¥{{ (totalAmountExcludingTax || 0).toFixed(2) }}
193 185 </div>
194 186 </div>
195 187 <div class="total-item">
... ... @@ -197,7 +189,7 @@
197 189 总金额
198 190 </div>
199 191 <div class="total-item-price text-red">
200   - ¥{{ (sumTotal || 0).toFixed(2) }}
  192 + ¥{{ (totalAmountIncludingTax || 0).toFixed(2) }}
201 193 </div>
202 194 </div>
203 195 </div>
... ... @@ -233,6 +225,7 @@ export default {
233 225 buyer: '',
234 226 buyerName: '',
235 227 orderDate: '',
  228 + deliveryDate: '',
236 229 designatedConsignee: '',
237 230 specialTerms: '',
238 231 specialTermsName: '',
... ... @@ -263,9 +256,9 @@ export default {
263 256 yesNoList: [{ label: '是', value: true }, { label: '否', value: false }],
264 257 sheet: { visible: false, title: '请选择', field: '', options: [], value: '' },
265 258 relate: { visible: false, title: '选择', source: '', display: [], multiple: false, rowKey: 'id', selectedKeys: [], fieldKey: '' },
266   - sumQuantity: 0,
267   - sumAmountExcl: 0,
268   - sumTotal: 0,
  259 + totalQuantity: 0,
  260 + totalAmountExcludingTax: 0,
  261 + totalAmountIncludingTax: 0,
269 262 productLineList: [],
270 263 productList: [],
271 264 customerRemarks: [],
... ... @@ -368,9 +361,9 @@ export default {
368 361 const sumQ = list.reduce((acc, it) => acc + (parseFloat(it.quantity) || 0), 0)
369 362 const sumE = list.reduce((acc, it) => acc + (parseFloat(it.amountExcludingTax) || 0), 0)
370 363 const sumT = list.reduce((acc, it) => acc + (parseFloat(it.totalAmount) || 0), 0)
371   - this.sumQuantity = sumQ
372   - this.sumAmountExcl = sumE
373   - this.sumTotal = sumT
  364 + this.totalQuantity = sumQ
  365 + this.totalAmountExcludingTax = sumE
  366 + this.totalAmountIncludingTax = sumT
374 367 this.form.totalAmountCapital = formatCurrencyToChinese(sumT)
375 368 this.productLineList = list
376 369 },
... ... @@ -446,6 +439,10 @@ export default {
446 439 setSheet('生产厂', opts)
447 440 } else if (field === 'supplier') {
448 441 setSheet('供方', this.supplierList)
  442 + } else if (field === 'specialTerms') {
  443 + setSheet('特别条款要求', this.specialTermsList)
  444 + } else if (field === 'executionStandard') {
  445 + setSheet('执行标准', this.executionStandardList)
449 446 } else if (field === 'includesPackagingFee') {
450 447 setSheet('单价中是否已包含包装费', this.yesNoList)
451 448 } else if (field === 'includesTransportFee') {
... ... @@ -516,9 +513,9 @@ export default {
516 513 ...formForSubmit,
517 514 destination,
518 515 type: 'DIST_STOCK_CONTRACT',
519   - sumQuantity: this.sumQuantity,
520   - sumAmountExcl: this.sumAmountExcl,
521   - sumTotal: this.sumTotal,
  516 + totalQuantity: this.totalQuantity,
  517 + totalAmountExcludingTax: this.totalAmountExcludingTax,
  518 + totalAmountIncludingTax: this.totalAmountIncludingTax,
522 519 contractDistributorLineList: lines
523 520 })
524 521 console.log('onSubmit__payload', payload)
... ... @@ -537,18 +534,30 @@ export default {
537 534 { key: 'supplier', label: '供方' },
538 535 { key: 'buyer', label: '需方' },
539 536 { key: 'orderDate', label: '订货日期' },
  537 + { key: 'unit', label: '单位' },
540 538 { key: 'workshopId', label: '生产厂' },
  539 + { key: 'specialTerms', label: '特别条款要求' },
541 540 ]
542 541 for (const it of checks) {
543 542 const val = this.form[it.key]
544 543 const empty = (val === undefined || val === null || (typeof val === 'string' && val.trim() === '') || (typeof val === 'number' && isNaN(val)))
545 544 if (empty) { uni.showToast({ title: `请先选择${it.label}`, icon: 'none' }); return false }
546 545 }
547   - if (!Array.isArray(this.productLineList) || this.productLineList.length === 0) {
  546 + const list = Array.isArray(this.productLineList) ? this.productLineList : []
  547 + if (list.length === 0) {
548 548 uni.showToast({ title: '请至少添加一条产品明细', icon: 'none' }); return false
549 549 }
550   - for (const [idx, it] of this.productLineList.entries()) {
551   - if (!it.productName || !it.quantity || !it.unitPrice) {
  550 + const strEmpty = (v) => (v === undefined || v === null || (typeof v === 'string' && v.trim() === ''))
  551 + const numEmpty = (v) => (v === undefined || v === null || v === '' || (typeof v === 'number' && isNaN(v)))
  552 + for (const [idx, it] of list.entries()) {
  553 + if (
  554 + strEmpty(it.productName) ||
  555 + strEmpty(it.industry) ||
  556 + strEmpty(it.quality) ||
  557 + strEmpty(it.brand) ||
  558 + numEmpty(it.quantity) ||
  559 + strEmpty(it.deliveryDate)
  560 + ) {
552 561 uni.showToast({ title: `第${idx + 1}条明细未完整填写`, icon: 'none' }); return false
553 562 }
554 563 }
... ... @@ -576,7 +585,7 @@ export default {
576 585 color: rgba(0, 0, 0, 0.6);
577 586 line-height: 32rpx;
578 587 width: 240rpx;
579   - padding: 24rpx 0;
  588 + padding: 12rpx 0;
580 589 }
581 590 .total-item-price {
582 591 font-weight: 600;
... ... @@ -598,7 +607,7 @@ export default {
598 607
599 608 .scroll {
600 609 flex: 1;
601   - padding: 12rpx 0 480rpx !important;
  610 + padding: 12rpx 0 392rpx !important;
602 611 }
603 612
604 613 .footer {
... ...
... ... @@ -52,13 +52,13 @@
52 52 }}</text></view>
53 53 </view>
54 54
55   - <view class="section">
  55 + <view class="section" v-if="detail.status === 'STANDARD'">
56 56 <view class="row"><text class="label">规范性合同</text><text class="value" style="color: #3D48A3;">{{ detail.standardFileName || '-'
57 57 }}</text></view>
58 58 <view class="row"><text class="label">合同是否规范</text><text class="value">{{ detail.standardStandardized ? '是' : '否'
59 59 }}</text></view>
60 60 </view>
61   - <view class="section" v-if="status === 'FORMAL'">
  61 + <view class="section" v-if="detail.status === 'FORMAL'">
62 62 <view class="row"><text class="label">规范性合同</text><text class="value" style="color: #3D48A3;">{{ detail.formalFileName || '-' }}</text></view>
63 63 <view class="row"><text class="label">合同是否规范</text><text class="value">{{ detail.formalStandardized ? '是' : '否' }}</text></view>
64 64 </view>
... ...
... ... @@ -61,7 +61,9 @@
61 61 <text>订单总额</text><text class="amount" :style="{ color: '#b67a76' }">¥{{ formatAmount(item.totalAmountIncludingTax) }}</text>
62 62 </view>
63 63 <view class="info-row" v-if="item.status === 'STANDARD' || item.status === 'FORMAL'">
64   - <text>{{ item.status === 'STANDARD' ? '标准合同' : '正式合同' }}规范性审核状态</text><span class="info-status" :style="getStatusCss(item.standardApprovedName)">{{ item.standardApprovedName }}</span>
  64 + <text>{{ item.status === 'STANDARD' ? '标准合同' : '正式合同' }}规范性审核状态</text>
  65 + <span v-if="item.status === 'STANDARD' ? item.standardApprovedName : item.formalApprovedName" class="info-status" :style="getStatusCss(item.status === 'STANDARD' ? item.standardApprovedName : item.formalApprovedName)">{{ item.status === 'STANDARD' ? item.standardApprovedName : item.formalApprovedName }}</span>
  66 + <span v-else>-</span>
65 67 </view>
66 68 <view class="info-row">
67 69 <text>订货日期</text><text>{{ item.orderDate }}</text>
... ... @@ -244,7 +246,7 @@ export default {
244 246 const list = Array.isArray(this.statusStyle) ? this.statusStyle : []
245 247 const found = list.find(it => it && it.text === name) || {}
246 248 return {
247   - color: found.color || '#000',
  249 + color: found.color || '#fff',
248 250 backgroundColor: found.bgColor || '#000'
249 251 }
250 252 }
... ...
... ... @@ -108,7 +108,7 @@
108 108 数量
109 109 </div>
110 110 <div class="total-item-price">
111   - {{ (sumQuantity || 0).toFixed(2) }}t
  111 + {{ (totalQuantity || 0).toFixed(2) }}t
112 112 </div>
113 113 </div>
114 114 <div class="total-item">
... ... @@ -116,7 +116,7 @@
116 116 不含税金额
117 117 </div>
118 118 <div class="total-item-price text-red">
119   - ¥{{ (sumAmountExcl || 0).toFixed(2) }}
  119 + ¥{{ (totalAmountExcludingTax || 0).toFixed(2) }}
120 120 </div>
121 121 </div>
122 122 <div class="total-item">
... ... @@ -124,7 +124,7 @@
124 124 总金额
125 125 </div>
126 126 <div class="total-item-price text-red">
127   - ¥{{ (sumTotal || 0).toFixed(2) }}
  127 + ¥{{ (totalAmountIncludingTax || 0).toFixed(2) }}
128 128 </div>
129 129 </div>
130 130 </div>
... ... @@ -147,15 +147,15 @@ export default {
147 147 }
148 148 },
149 149 computed: {
150   - sumQuantity() {
  150 + totalQuantity() {
151 151 const qty = this.items.filter(it => it.locked).reduce((p, c) => p + this.toNumber(c.quantity), 0)
152 152 return this.round(qty, 2)
153 153 },
154   - sumAmountExcl() {
  154 + totalAmountExcludingTax() {
155 155 const sum = this.items.filter(it => it.locked).reduce((p, c) => p + this.toNumber(c.amountExcludingTax), 0)
156 156 return this.round(sum, 2)
157 157 },
158   - sumTotal() { return this.totalAmount },
  158 + totalAmountIncludingTax() { return this.totalAmount },
159 159 totalAmount() {
160 160 let sum = 0
161 161 for (const it of this.items) {
... ... @@ -325,9 +325,9 @@ export default {
325 325 const payload = {
326 326 id: this.id,
327 327 totalAmountCapital: formatCurrencyToChinese(this.sumTotal),
328   - totalAmountExcludingTax: this.sumAmountExcl,
329   - totalAmountIncludingTax: this.sumTotal,
330   - totalQuantity: this.sumQuantity,
  328 + totalAmountExcludingTax: this.totalAmountExcludingTax,
  329 + totalAmountIncludingTax: this.totalAmountIncludingTax,
  330 + totalQuantity: this.totalQuantity,
331 331 type:'DIST_STOCK_CONTRACT',
332 332 contractDistributorLineList: selected
333 333 }
... ... @@ -362,7 +362,7 @@ export default {
362 362
363 363 .scroll {
364 364 flex: 1;
365   - padding: 12rpx 0 480rpx !important;
  365 + padding: 12rpx 0 392rpx !important;
366 366 }
367 367
368 368 .header {
... ... @@ -646,7 +646,7 @@ export default {
646 646 color: rgba(0, 0, 0, 0.6);
647 647 line-height: 32rpx;
648 648 width: 240rpx;
649   - padding: 24rpx 0;
  649 + padding: 12rpx 0;
650 650 }
651 651
652 652 .total-item-price {
... ...
... ... @@ -41,7 +41,7 @@
41 41 </template>
42 42 </uni-list-item>
43 43
44   - <ProductRel mode="add" :orderDateBase="form.orderDate" :list="productLineList" @change="onProductsChange" :options="productList" />
  44 + <ProductRel mode="add" :deliveryDateBase="form.deliveryDate" :list="productLineList" @change="onProductsChange" :options="productList" />
45 45
46 46 <uni-list-item title="合计人民币金额(大写)">
47 47 <template v-slot:footer>
... ... @@ -99,33 +99,25 @@
99 99 </template>
100 100 </uni-list-item>
101 101
102   - <view class="group">
103   - <view class="group-title">特别条款要求</view>
104   - <view class="radio-list">
105   - <view v-for="(opt, i) in specialTermsList" :key="'cr-' + i" class="radio-item"
106   - @click="onRadioSelect('specialTerms', 'specialTermsName', opt)">
107   - <view :class="['radio', { checked: form.specialTerms === opt.value }]" />
108   - <text class="label">{{ opt.label }}</text>
109   - </view>
110   - </view>
111   - </view>
112   - <view class="group">
113   - <view class="group-title">执行标准</view>
114   - <view class="radio-list">
115   - <view v-for="(opt, i) in executionStandardList" :key="'es-' + i" class="radio-item"
116   - @click="onRadioSelect('executionStandard', 'executionStandardName', opt)">
117   - <view :class="['radio', { checked: form.executionStandard === opt.value }]" />
118   - <text class="label">{{ opt.label }}</text>
119   - </view>
120   - </view>
121   - </view>
  102 + <uni-list-item class="select-item" :class="form.specialTermsName ? 'is-filled' : 'is-empty'" clickable
  103 + @click="openSheet('specialTerms')" :rightText="form.specialTermsName || '请选择'" showArrow>
  104 + <template v-slot:body>
  105 + <view class="item-title"><text class="required">*</text><text>特别条款要求</text></view>
  106 + </template>
  107 + </uni-list-item>
  108 + <uni-list-item class="select-item" :class="form.executionStandardName ? 'is-filled' : 'is-empty'" clickable
  109 + @click="openSheet('executionStandard')" :rightText="form.executionStandardName || '请选择'" showArrow>
  110 + <template v-slot:body>
  111 + <view class="item-title"><text>执行标准</text></view>
  112 + </template>
  113 + </uni-list-item>
122 114 <uni-list-item v-if="form.executionStandard === 'OTHER'" title="其他">
123 115 <template v-slot:footer>
124 116 <uni-easyinput v-model="form.executionStandardRemarks" placeholder="请输入其他标准备注"
125 117 :inputBorder="false" />
126 118 </template>
127 119 </uni-list-item>
128   - <uni-list-item title="特别说明">
  120 + <uni-list-item title="特别说明" style="margin-top: 20rpx;">
129 121 <template v-slot:footer>
130 122 <uni-easyinput v-model="form.specialInstructions" placeholder="请输入特别说明" :inputBorder="false" />
131 123 </template>
... ... @@ -177,15 +169,15 @@
177 169 <div class="total-text">合计</div>
178 170 <div class="total-item">
179 171 <div class="total-item-text">数量</div>
180   - <div class="total-item-price">{{ (sumQuantity || 0).toFixed(2) }}t</div>
  172 + <div class="total-item-price">{{ (totalQuantity || 0).toFixed(2) }}kg</div>
181 173 </div>
182 174 <div class="total-item">
183 175 <div class="total-item-text">不含税金额</div>
184   - <div class="total-item-price text-red">¥{{ (sumAmountExcl || 0).toFixed(2) }}</div>
  176 + <div class="total-item-price text-red">¥{{ (totalAmountExcludingTax || 0).toFixed(2) }}</div>
185 177 </div>
186 178 <div class="total-item">
187 179 <div class="total-item-text">总金额</div>
188   - <div class="total-item-price text-red">¥{{ (sumTotal || 0).toFixed(2) }}</div>
  180 + <div class="total-item-price text-red">¥{{ (totalAmountIncludingTax || 0).toFixed(2) }}</div>
189 181 </div>
190 182 </div>
191 183 <button class="btn submit" type="primary" @click="onSubmit">保存</button>
... ... @@ -223,6 +215,7 @@ export default {
223 215 workshopId: '',
224 216 workshopName: '',
225 217 orderDate: '',
  218 + deliveryDate: '',
226 219 designatedConsignee: '',
227 220 specialTerms: '',
228 221 specialTermsName: '',
... ... @@ -256,9 +249,9 @@ export default {
256 249 yesNoList: [{ label: '是', value: true }, { label: '否', value: false }],
257 250 sheet: { visible: false, title: '请选择', field: '', options: [], value: '' },
258 251 relate: { visible: false, title: '选择', source: '', display: [], multiple: false, rowKey: 'id', selectedKeys: [], fieldKey: '' },
259   - sumQuantity: 0,
260   - sumAmountExcl: 0,
261   - sumTotal: 0,
  252 + totalQuantity: 0,
  253 + totalAmountExcludingTax: 0,
  254 + totalAmountIncludingTax: 0,
262 255 productLineList: [],
263 256 newProductLineList: [],
264 257 productList: []
... ... @@ -349,9 +342,9 @@ export default {
349 342 const sumQ = list.reduce((acc, it) => acc + (parseFloat(it.quantity) || 0), 0)
350 343 const sumE = list.reduce((acc, it) => acc + (parseFloat(it.amountExcludingTax) || 0), 0)
351 344 const sumT = list.reduce((acc, it) => acc + (parseFloat(it.totalAmount) || 0), 0)
352   - this.sumQuantity = sumQ
353   - this.sumAmountExcl = sumE
354   - this.sumTotal = sumT
  345 + this.totalQuantity = sumQ
  346 + this.totalAmountExcludingTax = sumE
  347 + this.totalAmountIncludingTax = sumT
355 348 this.form.totalAmountCapital = formatCurrencyToChinese(sumT)
356 349 },
357 350 async loadSuppliers() {
... ... @@ -399,6 +392,10 @@ export default {
399 392 setSheet('生产厂', opts)
400 393 } else if (field === 'supplier') {
401 394 setSheet('供方', this.supplierList)
  395 + } else if (field === 'specialTerms') {
  396 + setSheet('特别条款要求', this.specialTermsList)
  397 + } else if (field === 'executionStandard') {
  398 + setSheet('执行标准', this.executionStandardList)
402 399 } else if (field === 'includesPackagingFee') {
403 400 setSheet('单价中是否已包含包装费', this.yesNoList)
404 401 } else if (field === 'includesTransportFee') {
... ... @@ -443,18 +440,30 @@ export default {
443 440 { key: 'supplier', label: '供方' },
444 441 { key: 'buyer', label: '需方' },
445 442 { key: 'orderDate', label: '订货日期' },
  443 + { key: 'unit', label: '单位' },
446 444 { key: 'workshopId', label: '生产厂' },
  445 + { key: 'specialTerms', label: '特别条款要求' },
447 446 ]
448 447 for (const it of checks) {
449 448 const val = this.form[it.key]
450 449 const empty = (val === undefined || val === null || (typeof val === 'string' && val.trim() === '') || (typeof val === 'number' && isNaN(val)))
451 450 if (empty) { uni.showToast({ title: `请先选择${it.label}`, icon: 'none' }); return false }
452 451 }
453   - if (!Array.isArray(this.productLineList) || this.productLineList.length === 0) {
  452 + const list = Array.isArray(this.newProductLineList) ? this.newProductLineList : []
  453 + if (list.length === 0) {
454 454 uni.showToast({ title: '请至少添加一条产品明细', icon: 'none' }); return false
455 455 }
456   - for (const [idx, it] of this.productLineList.entries()) {
457   - if (!it.productName || !it.quantity) {
  456 + const strEmpty = (v) => (v === undefined || v === null || (typeof v === 'string' && v.trim() === ''))
  457 + const numEmpty = (v) => (v === undefined || v === null || v === '' || (typeof v === 'number' && isNaN(v)))
  458 + for (const [idx, it] of list.entries()) {
  459 + if (
  460 + strEmpty(it.productName) ||
  461 + strEmpty(it.industry) ||
  462 + strEmpty(it.quality) ||
  463 + strEmpty(it.brand) ||
  464 + numEmpty(it.quantity) ||
  465 + strEmpty(it.deliveryDate)
  466 + ) {
458 467 uni.showToast({ title: `第${idx + 1}条明细未完整填写`, icon: 'none' }); return false
459 468 }
460 469 }
... ... @@ -486,9 +495,9 @@ export default {
486 495 id: this.form.id,
487 496 destination,
488 497 type: 'DIST_STOCK_CONTRACT',
489   - sumQuantity: this.sumQuantity,
490   - sumAmountExcl: this.sumAmountExcl,
491   - sumTotal: this.sumTotal,
  498 + totalQuantity: this.totalQuantity,
  499 + totalAmountExcludingTax: this.totalAmountExcludingTax,
  500 + totalAmountIncludingTax: this.totalAmountIncludingTax,
492 501 contractDistributorLineList: lines
493 502 })
494 503 try {
... ... @@ -524,7 +533,7 @@ export default {
524 533 color: rgba(0, 0, 0, 0.6);
525 534 line-height: 32rpx;
526 535 width: 240rpx;
527   - padding: 24rpx 0;
  536 + padding: 12rpx 0;
528 537 }
529 538
530 539 .total-item-price {
... ... @@ -547,7 +556,7 @@ export default {
547 556
548 557 .scroll {
549 558 flex: 1;
550   - padding: 12rpx 0 480rpx !important;
  559 + padding: 12rpx 0 392rpx !important;
551 560 }
552 561
553 562 .footer {
... ... @@ -742,4 +751,4 @@ export default {
742 751 }
743 752 }
744 753
745   -</style>
\ No newline at end of file
  754 +</style>
... ...
... ... @@ -55,51 +55,51 @@
55 55 </uni-list-item>
56 56 <uni-list-item title="厚度">
57 57 <template v-slot:footer>
58   - <uni-easyinput v-model="item.thickness" :inputBorder="false" placeholder="请输入厚度" />
  58 + <uni-easyinput type="digit" v-model="item.thickness" :inputBorder="false" placeholder="请输入厚度" @input="onNonNegativeInput(idx, 'thickness')" @blur="onNonNegativeBlur(idx, 'thickness', 2)" />
59 59 </template>
60 60 </uni-list-item>
61 61 <uni-list-item title="厚度公差(单项+)">
62 62 <template v-slot:footer>
63   - <uni-easyinput v-model="item.thicknessTolPos" :inputBorder="false"
64   - placeholder="请输入厚度公差(单项+)" />
  63 + <uni-easyinput type="digit" v-model="item.thicknessTolPos" :inputBorder="false"
  64 + placeholder="请输入厚度公差(单项+)" @input="onNonNegativeInput(idx, 'thicknessTolPos')" @blur="onNonNegativeBlur(idx, 'thicknessTolPos', 2)" />
65 65 </template>
66 66 </uni-list-item>
67 67 <uni-list-item title="厚度公差(单项-)">
68 68 <template v-slot:footer>
69   - <uni-easyinput v-model="item.thicknessTolNeg" :inputBorder="false"
70   - placeholder="请输入厚度公差(单项-)" />
  69 + <uni-easyinput type="digit" v-model="item.thicknessTolNeg" :inputBorder="false"
  70 + placeholder="请输入厚度公差(单项-)" @input="onNonNegativeInput(idx, 'thicknessTolNeg')" @blur="onNonNegativeBlur(idx, 'thicknessTolNeg', 2)" />
71 71 </template>
72 72 </uni-list-item>
73 73 <uni-list-item title="宽度">
74 74 <template v-slot:footer>
75   - <uni-easyinput v-model="item.width" :inputBorder="false" placeholder="请输入宽度" />
  75 + <uni-easyinput type="digit" v-model="item.width" :inputBorder="false" placeholder="请输入宽度" @input="onNonNegativeInput(idx, 'width')" @blur="onNonNegativeBlur(idx, 'width', 2)" />
76 76 </template>
77 77 </uni-list-item>
78 78 <uni-list-item title="宽度公差(单项+)">
79 79 <template v-slot:footer>
80   - <uni-easyinput v-model="item.widthTolPos" :inputBorder="false" placeholder="请输入宽度公差(单项+)" />
  80 + <uni-easyinput type="digit" v-model="item.widthTolPos" :inputBorder="false" placeholder="请输入宽度公差(单项+)" @input="onNonNegativeInput(idx, 'widthTolPos')" @blur="onNonNegativeBlur(idx, 'widthTolPos', 2)" />
81 81 </template>
82 82 </uni-list-item>
83 83 <uni-list-item title="宽度公差(单项-)">
84 84 <template v-slot:footer>
85   - <uni-easyinput v-model="item.widthTolNeg" :inputBorder="false" placeholder="请输入宽度公差(单项-)" />
  85 + <uni-easyinput type="digit" v-model="item.widthTolNeg" :inputBorder="false" placeholder="请输入宽度公差(单项-)" @input="onNonNegativeInput(idx, 'widthTolNeg')" @blur="onNonNegativeBlur(idx, 'widthTolNeg', 2)" />
86 86 </template>
87 87 </uni-list-item>
88 88 <uni-list-item title="长度">
89 89 <template v-slot:footer>
90   - <uni-easyinput v-model="item.length" :inputBorder="false" placeholder="请输入长度" />
  90 + <uni-easyinput type="digit" v-model="item.length" :inputBorder="false" placeholder="请输入长度" @input="onNonNegativeInput(idx, 'length')" @blur="onNonNegativeBlur(idx, 'length', 2)" />
91 91 </template>
92 92 </uni-list-item>
93 93 <uni-list-item title="长度公差(单项+)">
94 94 <template v-slot:footer>
95   - <uni-easyinput v-model="item.lengthTolPos" :inputBorder="false"
96   - placeholder="请输入长度公差(单项+)" />
  95 + <uni-easyinput type="digit" v-model="item.lengthTolPos" :inputBorder="false"
  96 + placeholder="请输入长度公差(单项+)" @input="onNonNegativeInput(idx, 'lengthTolPos')" @blur="onNonNegativeBlur(idx, 'lengthTolPos', 2)" />
97 97 </template>
98 98 </uni-list-item>
99 99 <uni-list-item title="长度公差(单项-)">
100 100 <template v-slot:footer>
101   - <uni-easyinput v-model="item.lengthTolNeg" :inputBorder="false"
102   - placeholder="请输入长度公差(单项-)" />
  101 + <uni-easyinput type="digit" v-model="item.lengthTolNeg" :inputBorder="false"
  102 + placeholder="请输入长度公差(单项-)" @input="onNonNegativeInput(idx, 'lengthTolNeg')" @blur="onNonNegativeBlur(idx, 'lengthTolNeg', 2)" />
103 103 </template>
104 104 </uni-list-item>
105 105 <uni-list-item title="状态">
... ... @@ -109,12 +109,12 @@
109 109 </uni-list-item>
110 110 <uni-list-item title="数量">
111 111 <template v-slot:footer>
112   - <uni-easyinput v-model="item.quantity" type="number" :inputBorder="false" placeholder="请输入数量" @input="onImmediateChange(idx)" @blur="onNumberBlur(idx, 'quantity', 0)" />
  112 + <uni-easyinput v-model="item.quantity" type="digit" :inputBorder="false" placeholder="请输入数量kg" @input="onNonNegativeInput(idx, 'quantity')" @blur="onNonNegativeBlur(idx, 'quantity', 2)" />
113 113 </template>
114 114 </uni-list-item>
115 115 <uni-list-item title="单价">
116 116 <template v-slot:footer>
117   - <uni-easyinput v-model="item.unitPrice" type="number" :inputBorder="false" placeholder="-" @input="onImmediateChange(idx)" @blur="onNumberBlur(idx, 'unitPrice', 0)" disabled />
  117 + <uni-easyinput v-model="item.unitPrice" type="digit" :inputBorder="false" disabled placeholder="请输入销售价格" @input="onNonNegativeInput(idx, 'unitPrice')" @blur="onNonNegativeBlur(idx, 'unitPrice', 2)" />
118 118 </template>
119 119 </uni-list-item>
120 120 <uni-list-item title="不含税金额">
... ... @@ -129,7 +129,7 @@
129 129 </uni-list-item>
130 130 <uni-list-item title="发货日期">
131 131 <template v-slot:footer>
132   - <uni-datetime-picker type="date" v-model="item.orderDate" @change="onDateChange(idx, $event)" />
  132 + <uni-datetime-picker type="date" v-model="item.deliveryDate" @change="onDateChange(idx, $event)" />
133 133 </template>
134 134 </uni-list-item>
135 135 </uni-list>
... ... @@ -151,7 +151,30 @@
151 151 <view class="row"><text class="label">行业</text><text class="value">{{ item.industry }}</text></view>
152 152 <view class="row"><text class="label">牌号</text><text class="value">{{ item.brand }}</text></view>
153 153 <view class="row"><text class="label">品质</text><text class="value">{{ item.quality }}</text></view>
154   - <view class="row"><text class="label">规格</text><text class="value">{{ item.specDisplay }}</text></view>
  154 + <!-- 厚(公差) * 宽(公差) * 长(公差) -->
  155 + <view class="row row-spec"><text class="label">规格(mm)</text>
  156 + <view class="value value-spec">
  157 + <view v-if="item.thickness" class="value-spec_val">{{ item.thickness }}</view>
  158 + <view v-if="item.thickness" class="value-spec_box">
  159 + <view v-if="item.thicknessTolPos" class="value-spec_box_1">+{{ item.thicknessTolPos }}
  160 + </view>
  161 + <view v-if="item.thicknessTolNeg" class="value-spec_box_2">-{{ item.thicknessTolNeg }}
  162 + </view>
  163 + </view>
  164 + <view v-if="item.width" class="value-spec_val p12">*</view>
  165 + <view v-if="item.width" class="value-spec_val">{{ item.width }}</view>
  166 + <view v-if="item.width" class="value-spec_box">
  167 + <view v-if="item.widthTolPos" class="value-spec_box_1">+{{ item.widthTolPos }}</view>
  168 + <view v-if="item.widthTolNeg" class="value-spec_box_2">-{{ item.widthTolNeg }}</view>
  169 + </view>
  170 + <view v-if="item.length" class="value-spec_val p12">*</view>
  171 + <view v-if="item.length" class="value-spec_val">{{ item.length }}</view>
  172 + <view v-if="item.length" class="value-spec_box">
  173 + <view v-if="item.lengthTolPos" class="value-spec_box_1">+{{ item.lengthTolPos }}</view>
  174 + <view v-if="item.lengthTolNeg" class="value-spec_box_2">-{{ item.lengthTolNeg }}</view>
  175 + </view>
  176 + </view>
  177 + </view>
155 178 <view class="row"><text class="label">状态</text><text class="value">{{ item.status }}</text></view>
156 179 <view class="row"><text class="label">数量</text><text class="value">{{ item.quantity }}</text></view>
157 180 <view class="row"><text class="label">单价</text><text class="value">{{ formatCurrency(item.unitPrice)
... ... @@ -162,7 +185,7 @@
162 185 }}</text></view>
163 186 <view class="row"><text class="label">总金额</text><text class="value">{{ formatCurrency(item.totalAmount)
164 187 }}</text></view>
165   - <view class="row"><text class="label">发货日期</text><text class="value">{{ item.orderDate }}</text></view>
  188 + <view class="row"><text class="label">发货日期</text><text class="value">{{ item.deliveryDate }}</text></view>
166 189 </view>
167 190 </view>
168 191 <SingleSelectSheet :visible.sync="sheet.visible" :title="sheet.title" :options="sheet.options" v-model="sheet.value" @confirm="onProductConfirm" />
... ... @@ -176,7 +199,7 @@ export default {
176 199 mode: { type: String, default: 'add' },
177 200 list: { type: Array, default: () => [] },
178 201 max: { type: Number, default: 8 },
179   - orderDateBase: { type: String, default: '' },
  202 + deliveryDateBase: { type: String, default: '' },
180 203 options: { type: Array, default: () => [] }
181 204 },
182 205 components: { SingleSelectSheet },
... ... @@ -218,10 +241,18 @@ export default {
218 241 },
219 242 methods: {
220 243 defaultItem() {
221   - return { productId: '', productName: '', industry: '', brand: '', quality: '', thickness: '', thicknessTolPos: '', thicknessTolNeg: '', width: '', widthTolPos: '', widthTolNeg: '', length: '', lengthTolPos: '', lengthTolNeg: '', status: '', quantity: '', unitPrice: '', amountExcludingTax: 0, totalAmount: 0, orderDate: '' }
  244 + return { productId: '', productName: '', industry: '', brand: '', quality: '', thickness: '', thicknessTolPos: '', thicknessTolNeg: '', width: '', widthTolPos: '', widthTolNeg: '', length: '', lengthTolPos: '', lengthTolNeg: '', status: '', quantity: '', unitPrice: '', amountExcludingTax: 0, totalAmount: 0, deliveryDate: '' }
222 245 },
223   - onImmediateChange(idx) {
224   - this.$nextTick(() => this.recalculate(idx))
  246 + onNonNegativeInput(idx, field) {
  247 + const it = this.items[idx]
  248 + if (!it) return
  249 + let v = String(it[field] != null ? it[field] : '')
  250 + v = v.replace(/[^0-9.]/g, '')
  251 + v = v.replace(/(\..*)\./g, '$1')
  252 + if (v.startsWith('.')) v = '0' + v
  253 + it[field] = v
  254 + this.$set(this.items, idx, it)
  255 + if (field === 'quantity' || field === 'unitPrice') this.$nextTick(() => this.recalculate(idx))
225 256 },
226 257 toNumber(val) {
227 258 if (typeof val === 'number') return isNaN(val) ? 0 : val
... ... @@ -234,21 +265,21 @@ export default {
234 265 const m = Math.pow(10, digits)
235 266 return Math.round(n * m) / m
236 267 },
237   - onNumberBlur(idx, field, digits) {
  268 + onNonNegativeBlur(idx, field, digits) {
238 269 const it = this.items[idx]
239 270 if (!it) return
240 271 const raw = it[field]
241   - // 如果为空则保持为空,不自动置为0,仅重新计算依赖字段
242 272 if (raw === '' || raw === null || raw === undefined) {
243 273 this.$set(this.items, idx, it)
244   - this.recalculate(idx)
  274 + if (field === 'quantity' || field === 'unitPrice') this.recalculate(idx)
245 275 return
246 276 }
247   - const num = this.toNumber(raw)
  277 + let num = this.toNumber(raw)
  278 + if (isNaN(num) || num < 0) num = 0
248 279 const rounded = this.round(num, digits)
249 280 it[field] = rounded
250 281 this.$set(this.items, idx, it)
251   - this.recalculate(idx)
  282 + if (field === 'quantity' || field === 'unitPrice') this.recalculate(idx)
252 283 },
253 284 formatCurrency(val) {
254 285 if (val == null || val === '') return ''
... ... @@ -319,15 +350,15 @@ export default {
319 350 onDateChange(idx, e) {
320 351 const it = this.items[idx]
321 352 if (!it) return
322   - const val = typeof e === 'string' ? e : (e && e.detail && e.detail.value) ? e.detail.value : it.orderDate
  353 + const val = typeof e === 'string' ? e : (e && e.detail && e.detail.value) ? e.detail.value : it.deliveryDate
323 354 const dateStr = String(val).slice(0, 10)
324   - const base = this.orderDateBase ? new Date(this.orderDateBase) : null
  355 + const base = this.deliveryDateBase ? new Date(this.deliveryDateBase) : null
325 356 const d = new Date(dateStr)
326 357 if (base && !isNaN(d.getTime()) && d.getTime() < base.getTime()) {
327 358 uni.showToast({ title: '发货日期不得早于订货日期', icon: 'none' })
328   - it.orderDate = this.orderDateBase
  359 + it.deliveryDate = this.deliveryDateBase
329 360 } else {
330   - it.orderDate = dateStr
  361 + it.deliveryDate = dateStr
331 362 }
332 363 this.$set(this.items, idx, it)
333 364 },
... ... @@ -500,8 +531,46 @@ export default {
500 531
501 532 .value {
502 533 flex: 1;
503   - text-align: right;
  534 + // text-align: right;
504 535 color: rgba(0, 0, 0, 0.9);
505 536 font-size: 28rpx;
506 537 }
  538 + .value-spec {
  539 + height: 48rpx;
  540 + display: flex;
  541 + align-items: center;
  542 + color: #000000;
  543 + // justify-content: end;
  544 + &_box {
  545 + position: relative;
  546 + width: 60rpx;
  547 + height: 48rpx;
  548 +
  549 + &_1 {
  550 + font-size: 16rpx;
  551 + position: absolute;
  552 + top: -10rpx;
  553 + left: 0;
  554 + }
  555 +
  556 + &_2 {
  557 + font-size: 16rpx;
  558 + position: absolute;
  559 + bottom: -10rpx;
  560 + left: 0;
  561 + }
  562 + }
  563 +
  564 + &_val {
  565 + font-size: 28rpx;
  566 +
  567 + &.p12 {
  568 + padding-right: 12rpx;
  569 + }
  570 + }
  571 + }
  572 + .row-spec {
  573 + height: 60rpx;
  574 + align-items: center;
  575 + }
507 576 </style>
... ...
... ... @@ -39,7 +39,7 @@
39 39 <view class="item-title"><text class="required">*</text><text>生产厂</text></view>
40 40 </template>
41 41 </uni-list-item>
42   - <ProductRel mode="add" :orderDateBase="form.orderDate" @change="onProductsChange" :options="productList" />
  42 + <ProductRel mode="add" :deliveryDateBase="form.deliveryDate" @change="onProductsChange" :options="productList" />
43 43 <uni-list-item title="合计人民币金额(大写)">
44 44 <template v-slot:footer>
45 45 <uni-easyinput v-model="form.totalAmountCapital" placeholder="自动计算" :inputBorder="false" disabled />
... ... @@ -92,33 +92,25 @@
92 92 :inputBorder="false" />
93 93 </template>
94 94 </uni-list-item>
95   - <view class="group">
96   - <view class="group-title">特别条款要求</view>
97   - <view class="radio-list">
98   - <view v-for="(opt, i) in specialTermsList" :key="'cr-' + i" class="radio-item"
99   - @click="onRadioSelect('specialTerms', 'specialTermsName', opt)">
100   - <view :class="['radio', { checked: form.specialTerms === opt.value }]" />
101   - <text class="label">{{ opt.label }}</text>
102   - </view>
103   - </view>
104   - </view>
105   - <view class="group">
106   - <view class="group-title">执行标准</view>
107   - <view class="radio-list">
108   - <view v-for="(opt, i) in executionStandardList" :key="'es-' + i" class="radio-item"
109   - @click="onRadioSelect('executionStandard', 'executionStandardName', opt)">
110   - <view :class="['radio', { checked: form.executionStandard === opt.value }]" />
111   - <text class="label">{{ opt.label }}</text>
112   - </view>
113   - </view>
114   - </view>
  95 + <uni-list-item class="select-item" :class="form.specialTermsName ? 'is-filled' : 'is-empty'" clickable
  96 + @click="openSheet('specialTerms')" :rightText="form.specialTermsName || '请选择'" showArrow>
  97 + <template v-slot:body>
  98 + <view class="item-title"><text class="required">*</text><text>特别条款要求</text></view>
  99 + </template>
  100 + </uni-list-item>
  101 + <uni-list-item class="select-item" :class="form.executionStandardName ? 'is-filled' : 'is-empty'" clickable
  102 + @click="openSheet('executionStandard')" :rightText="form.executionStandardName || '请选择'" showArrow>
  103 + <template v-slot:body>
  104 + <view class="item-title"><text>执行标准</text></view>
  105 + </template>
  106 + </uni-list-item>
115 107 <uni-list-item v-if="form.executionStandard === 'OTHER'" title="其他">
116 108 <template v-slot:footer>
117 109 <uni-easyinput v-model="form.executionStandardRemarks" placeholder="请输入其他标准备注"
118 110 :inputBorder="false" />
119 111 </template>
120 112 </uni-list-item>
121   - <uni-list-item title="特别说明">
  113 + <uni-list-item title="特别说明" style="margin-top: 20rpx;">
122 114 <template v-slot:footer>
123 115 <uni-easyinput v-model="form.specialInstructions" placeholder="请输入特别说明" :inputBorder="false" />
124 116 </template>
... ... @@ -180,8 +172,8 @@
180 172 <div class="total-item-text">
181 173 数量
182 174 </div>
183   - <div class="total-item-price">
184   - {{ (sumQuantity || 0).toFixed(2) }}t
  175 + <div class="total-item-price">
  176 + {{ (totalQuantity || 0).toFixed(2) }}kg
185 177 </div>
186 178 </div>
187 179 <div class="total-item">
... ... @@ -189,7 +181,7 @@
189 181 不含税金额
190 182 </div>
191 183 <div class="total-item-price text-red">
192   - ¥{{ (sumAmountExcl || 0).toFixed(2) }}
  184 + ¥{{ (totalAmountExcludingTax || 0).toFixed(2) }}
193 185 </div>
194 186 </div>
195 187 <div class="total-item">
... ... @@ -197,7 +189,7 @@
197 189 总金额
198 190 </div>
199 191 <div class="total-item-price text-red">
200   - ¥{{ (sumTotal || 0).toFixed(2) }}
  192 + ¥{{ (totalAmountIncludingTax || 0).toFixed(2) }}
201 193 </div>
202 194 </div>
203 195 </div>
... ... @@ -233,6 +225,7 @@ export default {
233 225 buyer: '',
234 226 buyerName: '',
235 227 orderDate: '',
  228 + deliveryDate: '',
236 229 designatedConsignee: '',
237 230 specialTerms: '',
238 231 specialTermsName: '',
... ... @@ -263,9 +256,9 @@ export default {
263 256 yesNoList: [{ label: '是', value: true }, { label: '否', value: false }],
264 257 sheet: { visible: false, title: '请选择', field: '', options: [], value: '' },
265 258 relate: { visible: false, title: '选择', source: '', display: [], multiple: false, rowKey: 'id', selectedKeys: [], fieldKey: '' },
266   - sumQuantity: 0,
267   - sumAmountExcl: 0,
268   - sumTotal: 0,
  259 + totalQuantity: 0,
  260 + totalAmountExcludingTax: 0,
  261 + totalAmountIncludingTax: 0,
269 262 productLineList: [],
270 263 productList: [],
271 264 customerRemarks: [],
... ... @@ -368,9 +361,9 @@ export default {
368 361 const sumQ = list.reduce((acc, it) => acc + (parseFloat(it.quantity) || 0), 0)
369 362 const sumE = list.reduce((acc, it) => acc + (parseFloat(it.amountExcludingTax) || 0), 0)
370 363 const sumT = list.reduce((acc, it) => acc + (parseFloat(it.totalAmount) || 0), 0)
371   - this.sumQuantity = sumQ
372   - this.sumAmountExcl = sumE
373   - this.sumTotal = sumT
  364 + this.totalQuantity = sumQ
  365 + this.totalAmountExcludingTax = sumE
  366 + this.totalAmountIncludingTax = sumT
374 367 this.form.totalAmountCapital = formatCurrencyToChinese(sumT)
375 368 this.productLineList = list
376 369 },
... ... @@ -446,6 +439,10 @@ export default {
446 439 setSheet('生产厂', opts)
447 440 } else if (field === 'supplier') {
448 441 setSheet('供方', this.supplierList)
  442 + } else if (field === 'specialTerms') {
  443 + setSheet('特别条款要求', this.specialTermsList)
  444 + } else if (field === 'executionStandard') {
  445 + setSheet('执行标准', this.executionStandardList)
449 446 } else if (field === 'includesPackagingFee') {
450 447 setSheet('单价中是否已包含包装费', this.yesNoList)
451 448 } else if (field === 'includesTransportFee') {
... ... @@ -516,9 +513,9 @@ export default {
516 513 ...formForSubmit,
517 514 destination,
518 515 type: 'DRAFT_DIST_AGMT',
519   - sumQuantity: this.sumQuantity,
520   - sumAmountExcl: this.sumAmountExcl,
521   - sumTotal: this.sumTotal,
  516 + totalQuantity: this.totalQuantity,
  517 + totalAmountExcludingTax: this.totalAmountExcludingTax,
  518 + totalAmountIncludingTax: this.totalAmountIncludingTax,
522 519 contractDistributorLineList: lines
523 520 })
524 521 console.log('onSubmit__payload', payload)
... ... @@ -537,18 +534,31 @@ export default {
537 534 { key: 'supplier', label: '供方' },
538 535 { key: 'buyer', label: '需方' },
539 536 { key: 'orderDate', label: '订货日期' },
  537 + { key: 'unit', label: '单位' },
540 538 { key: 'workshopId', label: '生产厂' },
  539 + { key: 'specialTerms', label: '特别条款要求' },
541 540 ]
542 541 for (const it of checks) {
543 542 const val = this.form[it.key]
544 543 const empty = (val === undefined || val === null || (typeof val === 'string' && val.trim() === '') || (typeof val === 'number' && isNaN(val)))
545 544 if (empty) { uni.showToast({ title: `请先选择${it.label}`, icon: 'none' }); return false }
546 545 }
547   - if (!Array.isArray(this.productLineList) || this.productLineList.length === 0) {
  546 + const list = Array.isArray(this.productLineList) ? this.productLineList : []
  547 + if (list.length === 0) {
548 548 uni.showToast({ title: '请至少添加一条产品明细', icon: 'none' }); return false
549 549 }
550   - for (const [idx, it] of this.productLineList.entries()) {
551   - if (!it.productName || !it.quantity || !it.unitPrice) {
  550 + const strEmpty = (v) => (v === undefined || v === null || (typeof v === 'string' && v.trim() === ''))
  551 + const numEmpty = (v) => (v === undefined || v === null || v === '' || (typeof v === 'number' && isNaN(v)))
  552 + for (const [idx, it] of list.entries()) {
  553 + if (
  554 + strEmpty(it.productName) ||
  555 + strEmpty(it.industry) ||
  556 + strEmpty(it.quality) ||
  557 + strEmpty(it.brand) ||
  558 + numEmpty(it.quantity) ||
  559 + numEmpty(it.unitPrice) ||
  560 + strEmpty(it.deliveryDate)
  561 + ) {
552 562 uni.showToast({ title: `第${idx + 1}条明细未完整填写`, icon: 'none' }); return false
553 563 }
554 564 }
... ... @@ -576,7 +586,7 @@ export default {
576 586 color: rgba(0, 0, 0, 0.6);
577 587 line-height: 32rpx;
578 588 width: 240rpx;
579   - padding: 24rpx 0;
  589 + padding: 12rpx 0;
580 590 }
581 591 .total-item-price {
582 592 font-weight: 600;
... ... @@ -598,7 +608,7 @@ export default {
598 608
599 609 .scroll {
600 610 flex: 1;
601   - padding: 12rpx 0 480rpx !important;
  611 + padding: 12rpx 0 392rpx !important;
602 612 }
603 613
604 614 .footer {
... ...
... ... @@ -53,7 +53,7 @@
53 53 }}</text></view>
54 54 </view>
55 55
56   - <view class="section">
  56 + <view class="section" v-if="detail.status === 'STANDARD'">
57 57 <view class="row"><text class="label">规范性合同</text><text class="value" style="color: #3D48A3;">{{
58 58 detail.standardFileName || '-'
59 59 }}</text></view>
... ... @@ -61,7 +61,7 @@
61 61 detail.standardStandardized ? '是' : '否'
62 62 }}</text></view>
63 63 </view>
64   - <view class="section" v-if="status === 'FORMAL'">
  64 + <view class="section" v-if="detail.status === 'FORMAL'">
65 65 <view class="row"><text class="label">规范性合同</text><text class="value" style="color: #3D48A3;">{{
66 66 detail.formalFileName || '-' }}</text></view>
67 67 <view class="row"><text class="label">合同是否规范</text><text class="value">{{ detail.formalStandardized
... ... @@ -114,7 +114,7 @@
114 114 </template>
115 115
116 116 <script>
117   -import { getContractApi, deleteContractApi, uploadFormalContract, statusStyle } from '@/api/contract'
  117 +import { getContractApi, deleteContractApi, uploadFormalContract, statusStyle, uploadStandardContract } from '@/api/contract'
118 118 import ProductRel from './productRel.vue'
119 119 import DetailButtons from '@/components/detail-buttons/index.vue'
120 120 import FileUpload from '@/components/file-upload/index.vue'
... ...
... ... @@ -61,7 +61,9 @@
61 61 <text>订单总额</text><text class="amount" :style="{ color: '#b67a76' }">{{ item.totalAmountIncludingTax ? '¥' : '' }}{{ formatAmount(item.totalAmountIncludingTax) || '-' }}</text>
62 62 </view>
63 63 <view class="info-row" v-if="item.status === 'STANDARD' || item.status === 'FORMAL'">
64   - <text>{{ item.status === 'STANDARD' ? '标准合同' : '正式合同' }}规范性审核状态</text><span class="info-status" :style="item.standardApprovedName ? getStatusCss(item.standardApprovedName) : ''">{{ item.standardApprovedName || '-' }}</span>
  64 + <text>{{ item.status === 'STANDARD' ? '标准合同' : '正式合同' }}规范性审核状态</text>
  65 + <span v-if="item.status === 'STANDARD' ? item.standardApprovedName : item.formalApprovedName" class="info-status" :style="getStatusCss(item.status === 'STANDARD' ? item.standardApprovedName : item.formalApprovedName)">{{ item.status === 'STANDARD' ? item.standardApprovedName : item.formalApprovedName }}</span>
  66 + <span v-else>-</span>
65 67 </view>
66 68 <view class="info-row">
67 69 <text>订货日期</text><text>{{ item.orderDate }}</text>
... ...
... ... @@ -107,7 +107,7 @@
107 107 数量
108 108 </div>
109 109 <div class="total-item-price">
110   - {{ (sumQuantity || 0).toFixed(2) }}t
  110 + {{ (totalQuantity || 0).toFixed(2) }}kg
111 111 </div>
112 112 </div>
113 113 <div class="total-item">
... ... @@ -115,7 +115,7 @@
115 115 不含税金额
116 116 </div>
117 117 <div class="total-item-price text-red">
118   - ¥{{ (sumAmountExcl || 0).toFixed(2) }}
  118 + ¥{{ (totalAmountExcludingTax || 0).toFixed(2) }}
119 119 </div>
120 120 </div>
121 121 <div class="total-item">
... ... @@ -123,7 +123,7 @@
123 123 总金额
124 124 </div>
125 125 <div class="total-item-price text-red">
126   - ¥{{ (sumTotal || 0).toFixed(2) }}
  126 + ¥{{ (totalAmountIncludingTax || 0).toFixed(2) }}
127 127 </div>
128 128 </div>
129 129 </div>
... ... @@ -146,15 +146,15 @@ export default {
146 146 }
147 147 },
148 148 computed: {
149   - sumQuantity() {
  149 + totalQuantity() {
150 150 const qty = this.items.filter(it => it.locked).reduce((p, c) => p + this.toNumber(c.quantity), 0)
151 151 return this.round(qty, 2)
152 152 },
153   - sumAmountExcl() {
  153 + totalAmountExcludingTax() {
154 154 const sum = this.items.filter(it => it.locked).reduce((p, c) => p + this.toNumber(c.amountExcludingTax), 0)
155 155 return this.round(sum, 2)
156 156 },
157   - sumTotal() { return this.totalAmount },
  157 + totalAmountIncludingTax() { return this.totalAmount },
158 158 totalAmount() {
159 159 let sum = 0
160 160 for (const it of this.items) {
... ... @@ -325,9 +325,9 @@ export default {
325 325 const payload = {
326 326 id: this.id,
327 327 totalAmountCapital: formatCurrencyToChinese(this.sumTotal),
328   - totalAmountExcludingTax: this.sumAmountExcl,
329   - totalAmountIncludingTax: this.sumTotal,
330   - totalQuantity: this.sumQuantity,
  328 + totalAmountExcludingTax: this.totalAmountExcludingTax,
  329 + totalAmountIncludingTax: this.totalAmountIncludingTax,
  330 + totalQuantity: this.totalQuantity,
331 331 type:'DRAFT_DIST_AGMT',
332 332 contractDistributorLineList: selected
333 333 }
... ... @@ -362,7 +362,7 @@ export default {
362 362
363 363 .scroll {
364 364 flex: 1;
365   - padding: 12rpx 0 480rpx !important;
  365 + padding: 12rpx 0 392rpx !important;
366 366 }
367 367
368 368 .header {
... ... @@ -646,7 +646,7 @@ export default {
646 646 color: rgba(0, 0, 0, 0.6);
647 647 line-height: 32rpx;
648 648 width: 240rpx;
649   - padding: 24rpx 0;
  649 + padding: 12rpx 0;
650 650 }
651 651
652 652 .total-item-price {
... ...
... ... @@ -41,7 +41,7 @@
41 41 </template>
42 42 </uni-list-item>
43 43
44   - <ProductRel mode="add" :orderDateBase="form.orderDate" :list="productLineList" @change="onProductsChange" :options="productList" />
  44 + <ProductRel mode="add" :deliveryDateBase="form.deliveryDate" :list="productLineList" @change="onProductsChange" :options="productList" />
45 45
46 46 <uni-list-item title="合计人民币金额(大写)">
47 47 <template v-slot:footer>
... ... @@ -99,33 +99,25 @@
99 99 </template>
100 100 </uni-list-item>
101 101
102   - <view class="group">
103   - <view class="group-title">特别条款要求</view>
104   - <view class="radio-list">
105   - <view v-for="(opt, i) in specialTermsList" :key="'cr-' + i" class="radio-item"
106   - @click="onRadioSelect('specialTerms', 'specialTermsName', opt)">
107   - <view :class="['radio', { checked: form.specialTerms === opt.value }]" />
108   - <text class="label">{{ opt.label }}</text>
109   - </view>
110   - </view>
111   - </view>
112   - <view class="group">
113   - <view class="group-title">执行标准</view>
114   - <view class="radio-list">
115   - <view v-for="(opt, i) in executionStandardList" :key="'es-' + i" class="radio-item"
116   - @click="onRadioSelect('executionStandard', 'executionStandardName', opt)">
117   - <view :class="['radio', { checked: form.executionStandard === opt.value }]" />
118   - <text class="label">{{ opt.label }}</text>
119   - </view>
120   - </view>
121   - </view>
  102 + <uni-list-item class="select-item" :class="form.specialTermsName ? 'is-filled' : 'is-empty'" clickable
  103 + @click="openSheet('specialTerms')" :rightText="form.specialTermsName || '请选择'" showArrow>
  104 + <template v-slot:body>
  105 + <view class="item-title"><text class="required">*</text><text>特别条款要求</text></view>
  106 + </template>
  107 + </uni-list-item>
  108 + <uni-list-item class="select-item" :class="form.executionStandardName ? 'is-filled' : 'is-empty'" clickable
  109 + @click="openSheet('executionStandard')" :rightText="form.executionStandardName || '请选择'" showArrow>
  110 + <template v-slot:body>
  111 + <view class="item-title"><text>执行标准</text></view>
  112 + </template>
  113 + </uni-list-item>
122 114 <uni-list-item v-if="form.executionStandard === 'OTHER'" title="其他">
123 115 <template v-slot:footer>
124 116 <uni-easyinput v-model="form.executionStandardRemarks" placeholder="请输入其他标准备注"
125 117 :inputBorder="false" />
126 118 </template>
127 119 </uni-list-item>
128   - <uni-list-item title="特别说明">
  120 + <uni-list-item title="特别说明" style="margin-top: 20rpx;">
129 121 <template v-slot:footer>
130 122 <uni-easyinput v-model="form.specialInstructions" placeholder="请输入特别说明" :inputBorder="false" />
131 123 </template>
... ... @@ -177,15 +169,15 @@
177 169 <div class="total-text">合计</div>
178 170 <div class="total-item">
179 171 <div class="total-item-text">数量</div>
180   - <div class="total-item-price">{{ (sumQuantity || 0).toFixed(2) }}t</div>
  172 + <div class="total-item-price">{{ (totalQuantity || 0).toFixed(2) }}kg</div>
181 173 </div>
182 174 <div class="total-item">
183 175 <div class="total-item-text">不含税金额</div>
184   - <div class="total-item-price text-red">¥{{ (sumAmountExcl || 0).toFixed(2) }}</div>
  176 + <div class="total-item-price text-red">¥{{ (totalAmountExcludingTax || 0).toFixed(2) }}</div>
185 177 </div>
186 178 <div class="total-item">
187 179 <div class="total-item-text">总金额</div>
188   - <div class="total-item-price text-red">¥{{ (sumTotal || 0).toFixed(2) }}</div>
  180 + <div class="total-item-price text-red">¥{{ (totalAmountIncludingTax || 0).toFixed(2) }}</div>
189 181 </div>
190 182 </div>
191 183 <button class="btn submit" type="primary" @click="onSubmit">保存</button>
... ... @@ -223,6 +215,7 @@ export default {
223 215 workshopId: '',
224 216 workshopName: '',
225 217 orderDate: '',
  218 + deliveryDate: '',
226 219 designatedConsignee: '',
227 220 specialTerms: '',
228 221 specialTermsName: '',
... ... @@ -256,9 +249,9 @@ export default {
256 249 yesNoList: [{ label: '是', value: true }, { label: '否', value: false }],
257 250 sheet: { visible: false, title: '请选择', field: '', options: [], value: '' },
258 251 relate: { visible: false, title: '选择', source: '', display: [], multiple: false, rowKey: 'id', selectedKeys: [], fieldKey: '' },
259   - sumQuantity: 0,
260   - sumAmountExcl: 0,
261   - sumTotal: 0,
  252 + totalQuantity: 0,
  253 + totalAmountExcludingTax: 0,
  254 + totalAmountIncludingTax: 0,
262 255 productLineList: [],
263 256 newProductLineList: [],
264 257 productList: []
... ... @@ -349,9 +342,9 @@ export default {
349 342 const sumQ = list.reduce((acc, it) => acc + (parseFloat(it.quantity) || 0), 0)
350 343 const sumE = list.reduce((acc, it) => acc + (parseFloat(it.amountExcludingTax) || 0), 0)
351 344 const sumT = list.reduce((acc, it) => acc + (parseFloat(it.totalAmount) || 0), 0)
352   - this.sumQuantity = sumQ
353   - this.sumAmountExcl = sumE
354   - this.sumTotal = sumT
  345 + this.totalQuantity = sumQ
  346 + this.totalAmountExcludingTax = sumE
  347 + this.totalAmountIncludingTax = sumT
355 348 this.form.totalAmountCapital = formatCurrencyToChinese(sumT)
356 349 },
357 350 async loadSuppliers() {
... ... @@ -399,6 +392,10 @@ export default {
399 392 setSheet('生产厂', opts)
400 393 } else if (field === 'supplier') {
401 394 setSheet('供方', this.supplierList)
  395 + } else if (field === 'specialTerms') {
  396 + setSheet('特别条款要求', this.specialTermsList)
  397 + } else if (field === 'executionStandard') {
  398 + setSheet('执行标准', this.executionStandardList)
402 399 } else if (field === 'includesPackagingFee') {
403 400 setSheet('单价中是否已包含包装费', this.yesNoList)
404 401 } else if (field === 'includesTransportFee') {
... ... @@ -439,22 +436,35 @@ export default {
439 436 },
440 437 validateRequired() {
441 438 const checks = [
442   - { key: 'code', label: '编号' },
  439 + { key: 'code', label: '编号' },
443 440 { key: 'supplier', label: '供方' },
444 441 { key: 'buyer', label: '需方' },
445 442 { key: 'orderDate', label: '订货日期' },
  443 + { key: 'unit', label: '单位' },
446 444 { key: 'workshopId', label: '生产厂' },
  445 + { key: 'specialTerms', label: '特别条款要求' },
447 446 ]
448 447 for (const it of checks) {
449 448 const val = this.form[it.key]
450 449 const empty = (val === undefined || val === null || (typeof val === 'string' && val.trim() === '') || (typeof val === 'number' && isNaN(val)))
451 450 if (empty) { uni.showToast({ title: `请先选择${it.label}`, icon: 'none' }); return false }
452 451 }
453   - if (!Array.isArray(this.productLineList) || this.productLineList.length === 0) {
  452 + const list = Array.isArray(this.newProductLineList) ? this.newProductLineList : []
  453 + if (list.length === 0) {
454 454 uni.showToast({ title: '请至少添加一条产品明细', icon: 'none' }); return false
455 455 }
456   - for (const [idx, it] of this.productLineList.entries()) {
457   - if (!it.productName || !it.quantity || !it.unitPrice) {
  456 + const strEmpty = (v) => (v === undefined || v === null || (typeof v === 'string' && v.trim() === ''))
  457 + const numEmpty = (v) => (v === undefined || v === null || v === '' || (typeof v === 'number' && isNaN(v)))
  458 + for (const [idx, it] of list.entries()) {
  459 + if (
  460 + strEmpty(it.productName) ||
  461 + strEmpty(it.industry) ||
  462 + strEmpty(it.quality) ||
  463 + strEmpty(it.brand) ||
  464 + numEmpty(it.quantity) ||
  465 + strEmpty(it.unitPrice) ||
  466 + strEmpty(it.deliveryDate)
  467 + ) {
458 468 uni.showToast({ title: `第${idx + 1}条明细未完整填写`, icon: 'none' }); return false
459 469 }
460 470 }
... ... @@ -486,9 +496,9 @@ export default {
486 496 id: this.form.id,
487 497 destination,
488 498 type: 'DRAFT_DIST_AGMT',
489   - sumQuantity: this.sumQuantity,
490   - sumAmountExcl: this.sumAmountExcl,
491   - sumTotal: this.sumTotal,
  499 + totalQuantity: this.totalQuantity,
  500 + totalAmountExcludingTax: this.totalAmountExcludingTax,
  501 + totalAmountIncludingTax: this.totalAmountIncludingTax,
492 502 contractDistributorLineList: lines
493 503 })
494 504 try {
... ... @@ -524,7 +534,7 @@ export default {
524 534 color: rgba(0, 0, 0, 0.6);
525 535 line-height: 32rpx;
526 536 width: 240rpx;
527   - padding: 24rpx 0;
  537 + padding: 12rpx 0;
528 538 }
529 539
530 540 .total-item-price {
... ... @@ -547,7 +557,7 @@ export default {
547 557
548 558 .scroll {
549 559 flex: 1;
550   - padding: 12rpx 0 480rpx !important;
  560 + padding: 12rpx 0 392rpx !important;
551 561 }
552 562
553 563 .footer {
... ...