Commit c4f3d3a1a342bf08563d75633c4b31ebdf86b872

Authored by gesilong
1 parent 232949c0

commit:修复bug

@@ -184,6 +184,7 @@ export default { @@ -184,6 +184,7 @@ export default {
184 var aStatus = String(f.approvalStatus != null ? f.approvalStatus : '') 184 var aStatus = String(f.approvalStatus != null ? f.approvalStatus : '')
185 var SC = this.PROCESS_STATUS_CODE 185 var SC = this.PROCESS_STATUS_CODE
186 var inStatus = function (codes) { return codes.indexOf(ps) >= 0 } 186 var inStatus = function (codes) { return codes.indexOf(ps) >= 0 }
  187 + console.log(SC,inStatus([SC.TO_SUBMIT_REVIEW, SC.AUDIT, SC.COMPLETED, SC.REFUSE]),'SC')
187 var perms = { 188 var perms = {
188 supplement: this.hasPerm('plan-manage:domestic-plan:supple'), 189 supplement: this.hasPerm('plan-manage:domestic-plan:supple'),
189 generateContract: this.hasPerm('plan-manage:domestic-plan:do'), 190 generateContract: this.hasPerm('plan-manage:domestic-plan:do'),
@@ -211,7 +212,7 @@ export default { @@ -211,7 +212,7 @@ export default {
211 print: inStatus([SC.TO_SUBMIT_REVIEW, SC.AUDIT, SC.COMPLETED, SC.ABORTED, SC.REFUSE]) && perms.print, 212 print: inStatus([SC.TO_SUBMIT_REVIEW, SC.AUDIT, SC.COMPLETED, SC.ABORTED, SC.REFUSE]) && perms.print,
212 generate: !!f.showGenerateBuyoutApply && inStatus([SC.TO_SUBMIT_REVIEW, SC.AUDIT, SC.COMPLETED]) && perms.generate, 213 generate: !!f.showGenerateBuyoutApply && inStatus([SC.TO_SUBMIT_REVIEW, SC.AUDIT, SC.COMPLETED]) && perms.generate,
213 cancel: !!f.showAbolishBuyoutApply && inStatus([SC.TO_SUBMIT_REVIEW, SC.AUDIT, SC.COMPLETED]) && perms.cancel, 214 cancel: !!f.showAbolishBuyoutApply && inStatus([SC.TO_SUBMIT_REVIEW, SC.AUDIT, SC.COMPLETED]) && perms.cancel,
214 - look: inStatus([SC.TO_SUBMIT_REVIEW, SC.AUDIT, SC.COMPLETED, SC.REFUSE]) && perms.look, 215 + look: inStatus([SC.TO_SUBMIT_REVIEW, SC.AUDIT, SC.COMPLETED, SC.REFUSE, SC.ABORTED]) && perms.look,
215 // uploadAttachment: inStatus([SC.COMPLETED]) && !!this.planRoleFlags.isPlanner && perms.uploadAttachment 216 // uploadAttachment: inStatus([SC.COMPLETED]) && !!this.planRoleFlags.isPlanner && perms.uploadAttachment
216 } 217 }
217 var out = [] 218 var out = []
@@ -60,6 +60,7 @@ @@ -60,6 +60,7 @@
60 placeholder="请输入实际采购价" 60 placeholder="请输入实际采购价"
61 @input="onNonNegativeInput(idx, 'actualPurchasePrice')" 61 @input="onNonNegativeInput(idx, 'actualPurchasePrice')"
62 @blur="onNonNegativeBlur(idx, 'actualPurchasePrice', 2)" 62 @blur="onNonNegativeBlur(idx, 'actualPurchasePrice', 2)"
  63 + @change="recalcAll(idx)"
63 /> 64 />
64 </template> 65 </template>
65 <text v-else class="lock-value">{{ formatTextNumber(item.actualPurchasePrice) }}</text> 66 <text v-else class="lock-value">{{ formatTextNumber(item.actualPurchasePrice) }}</text>
@@ -91,17 +92,7 @@ @@ -91,17 +92,7 @@
91 </uni-list-item> 92 </uni-list-item>
92 <uni-list-item title="买断料预计损耗"> 93 <uni-list-item title="买断料预计损耗">
93 <template v-slot:footer> 94 <template v-slot:footer>
94 - <template v-if="!isSelectWorkshop && !isSupplement">  
95 - <uni-easyinput  
96 - v-model="item.estimatedLoss"  
97 - type="digit"  
98 - :inputBorder="false"  
99 - placeholder="请输入预计损耗"  
100 - @input="onNonNegativeInput(idx, 'estimatedLoss')"  
101 - @blur="onNonNegativeBlur(idx, 'estimatedLoss', 2)"  
102 - />  
103 - </template>  
104 - <text v-else class="lock-value">{{ formatTextNumber(item.estimatedLoss) }}</text> 95 + <text class="lock-value">{{ formatTextNumber(item.estimatedLoss) }}</text>
105 </template> 96 </template>
106 </uni-list-item> 97 </uni-list-item>
107 <uni-list-item title="申请损耗(%)"> 98 <uni-list-item title="申请损耗(%)">
@@ -114,6 +105,7 @@ @@ -114,6 +105,7 @@
114 placeholder="请输入申请损耗" 105 placeholder="请输入申请损耗"
115 @input="onNonNegativeInput(idx, 'applicationAttrition')" 106 @input="onNonNegativeInput(idx, 'applicationAttrition')"
116 @blur="onNonNegativeBlur(idx, 'applicationAttrition', 2)" 107 @blur="onNonNegativeBlur(idx, 'applicationAttrition', 2)"
  108 + @change="recalcAll(idx)"
117 /> 109 />
118 </template> 110 </template>
119 <text v-else class="lock-value">{{ formatTextNumber(item.applicationAttrition) }}</text> 111 <text v-else class="lock-value">{{ formatTextNumber(item.applicationAttrition) }}</text>
@@ -208,7 +200,8 @@ export default { @@ -208,7 +200,8 @@ export default {
208 items: [], 200 items: [],
209 collapsedView: false, 201 collapsedView: false,
210 sheet: { visible: false, title: '请选择', options: [], value: '', idx: -1, type: '' }, 202 sheet: { visible: false, title: '请选择', options: [], value: '', idx: -1, type: '' },
211 - _initialized: false 203 + _initialized: false,
  204 + _emitSuppressed: false
212 } 205 }
213 }, 206 },
214 computed: { 207 computed: {
@@ -240,18 +233,29 @@ export default { @@ -240,18 +233,29 @@ export default {
240 }, 233 },
241 list: { 234 list: {
242 handler(v) { 235 handler(v) {
  236 + if (this._emitSuppressed) return
  237 + this._emitSuppressed = true
243 this._initialized = false 238 this._initialized = false
244 this.initItems() 239 this.initItems()
245 var self = this 240 var self = this
246 - this.$nextTick(function () { self._initialized = true }) 241 + this.$nextTick(function () {
  242 + self._initialized = true
  243 + self.recalcAllItems()
  244 + self.$nextTick(function () { self._emitSuppressed = false })
  245 + })
247 }, 246 },
248 immediate: false 247 immediate: false
249 } 248 }
250 }, 249 },
251 created() { 250 created() {
  251 + this._emitSuppressed = true
252 this.initItems() 252 this.initItems()
253 var self = this 253 var self = this
254 - this.$nextTick(function () { self._initialized = true }) 254 + this.$nextTick(function () {
  255 + self._initialized = true
  256 + self.recalcAllItems()
  257 + self.$nextTick(function () { self._emitSuppressed = false })
  258 + })
255 }, 259 },
256 methods: { 260 methods: {
257 initItems() { 261 initItems() {
@@ -296,7 +300,8 @@ export default { @@ -296,7 +300,8 @@ export default {
296 estimatedLoss: '', 300 estimatedLoss: '',
297 applicationAttrition: '', 301 applicationAttrition: '',
298 workshopId: '', 302 workshopId: '',
299 - workshopName: '' 303 + workshopName: '',
  304 + fixedLossRate: ''
300 } 305 }
301 }, 306 },
302 onNonNegativeInput(idx, field) { 307 onNonNegativeInput(idx, field) {
@@ -328,12 +333,71 @@ export default { @@ -328,12 +333,71 @@ export default {
328 return 333 return
329 } 334 }
330 var val = parseFloat(raw) 335 var val = parseFloat(raw)
331 - if (isNaN(val)) val = 0 336 + if (isNaN(val)) {
  337 + it[field] = ''
  338 + this.$set(this.items, idx, it)
  339 + return
  340 + }
332 var m = Math.pow(10, digits) 341 var m = Math.pow(10, digits)
333 var rounded = Math.round(val * m) / m 342 var rounded = Math.round(val * m) / m
334 it[field] = rounded 343 it[field] = rounded
335 this.$set(this.items, idx, it) 344 this.$set(this.items, idx, it)
336 }, 345 },
  346 + getProductOption(productId) {
  347 + var pid = productId != null ? String(productId) : ''
  348 + if (!pid) return null
  349 + var pOpts = Array.isArray(this.productOptions) ? this.productOptions : []
  350 + for (var i = 0; i < pOpts.length; i++) {
  351 + var o = pOpts[i]
  352 + var id = o.id != null ? String(o.id) : (o.productId != null ? String(o.productId) : (o.value != null ? String(o.value) : ''))
  353 + if (id === pid) return o
  354 + }
  355 + return null
  356 + },
  357 + round2(v) {
  358 + var n = Number(v)
  359 + if (isNaN(n)) return ''
  360 + return Math.round(n * 100) / 100
  361 + },
  362 + recalcAll(idx) {
  363 + var it = this.items[idx]
  364 + if (!it) return
  365 + var priceRaw = it.actualPurchasePrice
  366 + var price = parseFloat(priceRaw)
  367 + var priceIsNumber = priceRaw !== '' && priceRaw != null && !isNaN(price)
  368 + var estimatedLoss = ''
  369 + if (priceIsNumber) {
  370 + var app = it.applicationAttrition
  371 + var appNum = parseFloat(app)
  372 + var appHasVal = app !== '' && app != null && !isNaN(appNum)
  373 + if (appHasVal) {
  374 + estimatedLoss = this.round2(price * appNum / 100)
  375 + } else {
  376 + var pOpt = this.getProductOption(it.productId)
  377 + var fixedRate = null
  378 + if (pOpt) {
  379 + fixedRate = pOpt.fixedLossRate != null ? pOpt.fixedLossRate : (pOpt.lossRate != null ? pOpt.lossRate : (pOpt.attritionRate != null ? pOpt.attritionRate : null))
  380 + }
  381 + var fixedNum = parseFloat(fixedRate)
  382 + if (!isNaN(fixedNum)) {
  383 + estimatedLoss = this.round2(price * fixedNum / 100)
  384 + } else if (it.fixedLossRate != null && it.fixedLossRate !== '') {
  385 + var fallbackNum = parseFloat(it.fixedLossRate)
  386 + if (!isNaN(fallbackNum)) {
  387 + estimatedLoss = this.round2(price * fallbackNum / 100)
  388 + }
  389 + }
  390 + }
  391 + }
  392 + it.estimatedLoss = estimatedLoss
  393 + this.$set(this.items, idx, it)
  394 + },
  395 + recalcAllItems() {
  396 + var len = (this.items || []).length
  397 + for (var i = 0; i < len; i++) {
  398 + this.recalcAll(i)
  399 + }
  400 + },
337 onAdd() { 401 onAdd() {
338 if (this.items.length >= this.max) { 402 if (this.items.length >= this.max) {
339 uni.showToast({ title: '最多' + this.max + '条明细', icon: 'none' }) 403 uni.showToast({ title: '最多' + this.max + '条明细', icon: 'none' })
@@ -378,6 +442,14 @@ export default { @@ -378,6 +442,14 @@ export default {
378 if (type === 'product') { 442 if (type === 'product') {
379 this.$set(it, 'productId', value) 443 this.$set(it, 'productId', value)
380 this.$set(it, 'productName', label) 444 this.$set(it, 'productName', label)
  445 + var pOpt = this.getProductOption(value)
  446 + if (pOpt) {
  447 + var rate = pOpt.fixedLossRate != null ? pOpt.fixedLossRate : (pOpt.lossRate != null ? pOpt.lossRate : (pOpt.attritionRate != null ? pOpt.attritionRate : ''))
  448 + this.$set(it, 'fixedLossRate', rate != null ? rate : '')
  449 + } else {
  450 + this.$set(it, 'fixedLossRate', '')
  451 + }
  452 + this.recalcAll(idx)
381 } else if (type === 'workshop') { 453 } else if (type === 'workshop') {
382 this.$set(it, 'workshopId', value) 454 this.$set(it, 'workshopId', value)
383 this.$set(it, 'workshopName', label) 455 this.$set(it, 'workshopName', label)
@@ -385,12 +457,14 @@ export default { @@ -385,12 +457,14 @@ export default {
385 }, 457 },
386 emitChange() { 458 emitChange() {
387 if (!this._initialized) return 459 if (!this._initialized) return
  460 + if (this._emitSuppressed) return
388 var list = (this.items || []).map(function (it) { 461 var list = (this.items || []).map(function (it) {
389 var c = Object.assign({}, it) 462 var c = Object.assign({}, it)
390 var key = c._key 463 var key = c._key
391 delete c._key 464 delete c._key
392 delete c.collapsed 465 delete c.collapsed
393 delete c._selected 466 delete c._selected
  467 + delete c.fixedLossRate
394 if (!c.itemId) c.itemId = key 468 if (!c.itemId) c.itemId = key
395 return c 469 return c
396 }) 470 })
@@ -79,9 +79,9 @@ @@ -79,9 +79,9 @@
79 </template> 79 </template>
80 </uni-list-item> 80 </uni-list-item>
81 81
82 - <uni-list-item title="漆损率(%)"> 82 + <uni-list-item title="漆损">
83 <template v-slot:footer> 83 <template v-slot:footer>
84 - <uni-easyinput v-model="paintLossRatioDisplay" :inputBorder="false" disabled placeholder="-" /> 84 + <uni-easyinput v-model="totalPaintDamageRatio" :inputBorder="false" disabled placeholder="-" />
85 </template> 85 </template>
86 </uni-list-item> 86 </uni-list-item>
87 87
@@ -129,7 +129,7 @@ @@ -129,7 +129,7 @@
129 </uni-list-item> 129 </uni-list-item>
130 <uni-list-item title="漆损率(%)"> 130 <uni-list-item title="漆损率(%)">
131 <template v-slot:footer> 131 <template v-slot:footer>
132 - <text class="readonly-text">{{ formatNumberText(item.paintLossRatio, 4) }}</text> 132 + <text class="readonly-text">{{ formatNumberText(item.paintDamageRatio, 4) }}</text>
133 </template> 133 </template>
134 </uni-list-item> 134 </uni-list-item>
135 <uni-list-item title="是否带漆"> 135 <uni-list-item title="是否带漆">
@@ -178,7 +178,7 @@ export default { @@ -178,7 +178,7 @@ export default {
178 oilWaterDesc: '', 178 oilWaterDesc: '',
179 loadingFee: '', 179 loadingFee: '',
180 buyoutReason: '', 180 buyoutReason: '',
181 - paintLossRatio: '' 181 + paintDamageRatio: ''
182 }, 182 },
183 lineList: [] 183 lineList: []
184 } 184 }
@@ -209,8 +209,8 @@ export default { @@ -209,8 +209,8 @@ export default {
209 var v = this.toNumber(this.main.loadingFee) 209 var v = this.toNumber(this.main.loadingFee)
210 return v === 0 ? '0.00' : v.toFixed(2) 210 return v === 0 ? '0.00' : v.toFixed(2)
211 }, 211 },
212 - paintLossRatioDisplay() {  
213 - var v = this.toNumber(this.main.paintLossRatio) 212 + totalPaintDamageRatio() {
  213 + var v = this.toNumber(this.main.paintDamageRatio)
214 if (v === 0) return '0.0000' 214 if (v === 0) return '0.0000'
215 return v ? v.toFixed(4) : '' 215 return v ? v.toFixed(4) : ''
216 }, 216 },
@@ -223,7 +223,7 @@ export default { @@ -223,7 +223,7 @@ export default {
223 for (var i = 0; i < withPaintList.length; i++) { 223 for (var i = 0; i < withPaintList.length; i++) {
224 var r = withPaintList[i] 224 var r = withPaintList[i]
225 var qty = this.toNumber(r.quantity) 225 var qty = this.toNumber(r.quantity)
226 - var ratio = this.toNumber(r.paintLossRatio) / 100 226 + var ratio = this.toNumber(r.paintDamageRatio) / 100
227 if (ratio < 0) ratio = 0 227 if (ratio < 0) ratio = 0
228 if (ratio >= 1) ratio = 0.9999 228 if (ratio >= 1) ratio = 0.9999
229 totalQty += qty 229 totalQty += qty
@@ -300,10 +300,10 @@ export default { @@ -300,10 +300,10 @@ export default {
300 } 300 }
301 return null 301 return null
302 }, 302 },
303 - getPaintLossRatioFromBreed(productId, fallbackRatio) { 303 + getPaintDamageRatioFromBreed(productId, fallbackRatio) {
304 var opt = this.findBreedOption(productId) 304 var opt = this.findBreedOption(productId)
305 if (opt) { 305 if (opt) {
306 - var keys = ['paintLossRatio', 'paintLossRate', 'lossRatio', 'lacquerLossRatio'] 306 + var keys = ['paintDamageRatio', 'paintLossRate', 'lossRatio', 'lacquerLossRatio']
307 for (var i = 0; i < keys.length; i++) { 307 for (var i = 0; i < keys.length; i++) {
308 if (opt[keys[i]] != null && opt[keys[i]] !== '') { 308 if (opt[keys[i]] != null && opt[keys[i]] !== '') {
309 var n = Number(opt[keys[i]]) 309 var n = Number(opt[keys[i]])
@@ -317,8 +317,8 @@ export default { @@ -317,8 +317,8 @@ export default {
317 } 317 }
318 return 0 318 return 0
319 }, 319 },
320 - isWithPaintByBreed(productId, productName, breedPaintLossRatio) {  
321 - if (breedPaintLossRatio > 0) return true 320 + isWithPaintByBreed(productId, productName, breedPaintDamageRatio) {
  321 + if (breedPaintDamageRatio > 0) return true
322 var name = String(productName || '') 322 var name = String(productName || '')
323 var tags = ['带漆', '漆', '漆包', '油漆', '喷漆', '覆漆'] 323 var tags = ['带漆', '漆', '漆包', '油漆', '喷漆', '覆漆']
324 for (var i = 0; i < tags.length; i++) { 324 for (var i = 0; i < tags.length; i++) {
@@ -366,7 +366,7 @@ export default { @@ -366,7 +366,7 @@ export default {
366 var oilWaterDesc = this.pickValue(b, ['oilWaterDesc'], '') 366 var oilWaterDesc = this.pickValue(b, ['oilWaterDesc'], '')
367 var loadingFee = this.pickValue(b, ['loadingFee'], '') 367 var loadingFee = this.pickValue(b, ['loadingFee'], '')
368 var buyoutReason = this.pickValue(b, ['buyoutReason'], '') 368 var buyoutReason = this.pickValue(b, ['buyoutReason'], '')
369 - var paintLossRatio = this.pickValue(b, ['paintLossRatio'], '') 369 + var paintDamageRatio = this.pickValue(b, ['paintDamageRatio', 'paintLoss'], '')
370 this.main = { 370 this.main = {
371 code: code, 371 code: code,
372 supplierName: supplierName, 372 supplierName: supplierName,
@@ -384,7 +384,7 @@ export default { @@ -384,7 +384,7 @@ export default {
384 oilWaterDesc: oilWaterDesc, 384 oilWaterDesc: oilWaterDesc,
385 loadingFee: loadingFee, 385 loadingFee: loadingFee,
386 buyoutReason: buyoutReason, 386 buyoutReason: buyoutReason,
387 - paintLossRatio: paintLossRatio 387 + paintDamageRatio: paintDamageRatio
388 } 388 }
389 }, 389 },
390 buildLineList(buyout) { 390 buildLineList(buyout) {
@@ -394,7 +394,7 @@ export default { @@ -394,7 +394,7 @@ export default {
394 lines = bLines 394 lines = bLines
395 var shippingCost = this.toNumber(this.main.shippingCost) 395 var shippingCost = this.toNumber(this.main.shippingCost)
396 var loadingFee = this.toNumber(this.main.loadingFee) 396 var loadingFee = this.toNumber(this.main.loadingFee)
397 - var defaultPaintLossRatio = this.toNumber(this.main.paintLossRatio) 397 + var defaultPaintDamageRatio = this.toNumber(this.main.paintDamageRatio)
398 this.lineList = lines.map(function (r, i) { 398 this.lineList = lines.map(function (r, i) {
399 var row = r || {} 399 var row = r || {}
400 var productId = self.pickValue(row, ['productId', 'breedId'], '') 400 var productId = self.pickValue(row, ['productId', 'breedId'], '')
@@ -407,9 +407,11 @@ export default { @@ -407,9 +407,11 @@ export default {
407 var coordinationRange = self.pickValue(row, ['coordinationRange'], '') 407 var coordinationRange = self.pickValue(row, ['coordinationRange'], '')
408 var applicationAttrition = self.pickValue(row, ['applicationAttrition'], '') 408 var applicationAttrition = self.pickValue(row, ['applicationAttrition'], '')
409 var workshopName = self.pickValue(row, ['workshopName', 'workshopIdName'], '') 409 var workshopName = self.pickValue(row, ['workshopName', 'workshopIdName'], '')
410 - var breedPaintLossRatio = self.getPaintLossRatioFromBreed(productId, defaultPaintLossRatio)  
411 - var withPaint = self.isWithPaintByBreed(productId, productName, breedPaintLossRatio)  
412 - var ratio = withPaint ? breedPaintLossRatio : 0 410 + var rowPaintDamageRatio = self.pickValue(row, ['paintDamageRatio', 'paintLoss'], null)
  411 + var hasRowRatio = rowPaintDamageRatio != null && rowPaintDamageRatio !== '' && !isNaN(Number(rowPaintDamageRatio))
  412 + var breedPaintDamageRatio = self.getPaintDamageRatioFromBreed(productId, defaultPaintDamageRatio)
  413 + var withPaint = hasRowRatio ? (Number(rowPaintDamageRatio) > 0) : self.isWithPaintByBreed(productId, productName, breedPaintDamageRatio)
  414 + var ratio = hasRowRatio ? Number(rowPaintDamageRatio) : (withPaint ? breedPaintDamageRatio : 0)
413 var ratioFrac = ratio / 100 415 var ratioFrac = ratio / 100
414 if (ratioFrac < 0) ratioFrac = 0 416 if (ratioFrac < 0) ratioFrac = 0
415 if (ratioFrac >= 1) ratioFrac = 0.9999 417 if (ratioFrac >= 1) ratioFrac = 0.9999
@@ -430,7 +432,7 @@ export default { @@ -430,7 +432,7 @@ export default {
430 estimatedLoss: estimatedLoss, 432 estimatedLoss: estimatedLoss,
431 applicationAttrition: applicationAttrition, 433 applicationAttrition: applicationAttrition,
432 workshopName: workshopName, 434 workshopName: workshopName,
433 - paintLossRatio: ratio, 435 + paintDamageRatio: ratio,
434 withPaint: !!withPaint, 436 withPaint: !!withPaint,
435 pureCopperPrice: pureCopperPrice 437 pureCopperPrice: pureCopperPrice
436 } 438 }
@@ -66,6 +66,7 @@ @@ -66,6 +66,7 @@
66 placeholder="请输入实际采购价" 66 placeholder="请输入实际采购价"
67 @input="onNonNegativeInput(idx, 'actualPurchasePrice')" 67 @input="onNonNegativeInput(idx, 'actualPurchasePrice')"
68 @blur="onNonNegativeBlur(idx, 'actualPurchasePrice', 2)" 68 @blur="onNonNegativeBlur(idx, 'actualPurchasePrice', 2)"
  69 + @change="recalcAll(idx)"
69 /> 70 />
70 </template> 71 </template>
71 </uni-list-item> 72 </uni-list-item>
@@ -91,14 +92,7 @@ @@ -91,14 +92,7 @@
91 </view> 92 </view>
92 </template> 93 </template>
93 <template v-slot:footer> 94 <template v-slot:footer>
94 - <uni-easyinput  
95 - v-model="item.estimatedLoss"  
96 - type="digit"  
97 - :inputBorder="false"  
98 - placeholder="请输入预计损耗"  
99 - @input="onNonNegativeInput(idx, 'estimatedLoss')"  
100 - @blur="onNonNegativeBlur(idx, 'estimatedLoss', 2)"  
101 - /> 95 + <text class="lock-value">{{ formatTextNumber(item.estimatedLoss) }}</text>
102 </template> 96 </template>
103 </uni-list-item> 97 </uni-list-item>
104 <uni-list-item> 98 <uni-list-item>
@@ -115,6 +109,7 @@ @@ -115,6 +109,7 @@
115 placeholder="请输入申请损耗" 109 placeholder="请输入申请损耗"
116 @input="onNonNegativeInput(idx, 'applicationAttrition')" 110 @input="onNonNegativeInput(idx, 'applicationAttrition')"
117 @blur="onNonNegativeBlur(idx, 'applicationAttrition', 2)" 111 @blur="onNonNegativeBlur(idx, 'applicationAttrition', 2)"
  112 + @change="recalcAll(idx)"
118 /> 113 />
119 </template> 114 </template>
120 </uni-list-item> 115 </uni-list-item>
@@ -180,7 +175,8 @@ export default { @@ -180,7 +175,8 @@ export default {
180 return { 175 return {
181 items: [], 176 items: [],
182 sheet: { visible: false, title: '请选择', options: [], value: '', idx: -1, type: '' }, 177 sheet: { visible: false, title: '请选择', options: [], value: '', idx: -1, type: '' },
183 - _initialized: false 178 + _initialized: false,
  179 + _emitSuppressed: false
184 } 180 }
185 }, 181 },
186 computed: { 182 computed: {
@@ -211,18 +207,29 @@ export default { @@ -211,18 +207,29 @@ export default {
211 }, 207 },
212 list: { 208 list: {
213 handler() { 209 handler() {
  210 + if (this._emitSuppressed) return
  211 + this._emitSuppressed = true
214 this._initialized = false 212 this._initialized = false
215 this.initItems() 213 this.initItems()
216 var self = this 214 var self = this
217 - this.$nextTick(function () { self._initialized = true }) 215 + this.$nextTick(function () {
  216 + self._initialized = true
  217 + self.recalcAllItems()
  218 + self.$nextTick(function () { self._emitSuppressed = false })
  219 + })
218 }, 220 },
219 immediate: false 221 immediate: false
220 } 222 }
221 }, 223 },
222 created() { 224 created() {
  225 + this._emitSuppressed = true
223 this.initItems() 226 this.initItems()
224 var self = this 227 var self = this
225 - this.$nextTick(function () { self._initialized = true }) 228 + this.$nextTick(function () {
  229 + self._initialized = true
  230 + self.recalcAllItems()
  231 + self.$nextTick(function () { self._emitSuppressed = false })
  232 + })
226 }, 233 },
227 methods: { 234 methods: {
228 initItems() { 235 initItems() {
@@ -268,7 +275,8 @@ export default { @@ -268,7 +275,8 @@ export default {
268 estimatedLoss: '', 275 estimatedLoss: '',
269 applicationAttrition: '', 276 applicationAttrition: '',
270 workshopId: '', 277 workshopId: '',
271 - workshopName: '' 278 + workshopName: '',
  279 + fixedLossRate: ''
272 } 280 }
273 }, 281 },
274 onNonNegativeInput(idx, field) { 282 onNonNegativeInput(idx, field) {
@@ -289,12 +297,71 @@ export default { @@ -289,12 +297,71 @@ export default {
289 return 297 return
290 } 298 }
291 var val = parseFloat(raw) 299 var val = parseFloat(raw)
292 - if (isNaN(val)) val = 0 300 + if (isNaN(val)) {
  301 + it[field] = ''
  302 + this.$set(this.items, idx, it)
  303 + return
  304 + }
293 var m = Math.pow(10, digits) 305 var m = Math.pow(10, digits)
294 var rounded = Math.round(val * m) / m 306 var rounded = Math.round(val * m) / m
295 it[field] = rounded 307 it[field] = rounded
296 this.$set(this.items, idx, it) 308 this.$set(this.items, idx, it)
297 }, 309 },
  310 + getProductOption(productId) {
  311 + var pid = productId != null ? String(productId) : ''
  312 + if (!pid) return null
  313 + var pOpts = Array.isArray(this.productOptions) ? this.productOptions : []
  314 + for (var i = 0; i < pOpts.length; i++) {
  315 + var o = pOpts[i]
  316 + var id = o.id != null ? String(o.id) : (o.productId != null ? String(o.productId) : (o.value != null ? String(o.value) : ''))
  317 + if (id === pid) return o
  318 + }
  319 + return null
  320 + },
  321 + round2(v) {
  322 + var n = Number(v)
  323 + if (isNaN(n)) return ''
  324 + return Math.round(n * 100) / 100
  325 + },
  326 + recalcAll(idx) {
  327 + var it = this.items[idx]
  328 + if (!it) return
  329 + var priceRaw = it.actualPurchasePrice
  330 + var price = parseFloat(priceRaw)
  331 + var priceIsNumber = priceRaw !== '' && priceRaw != null && !isNaN(price)
  332 + var estimatedLoss = ''
  333 + if (priceIsNumber) {
  334 + var app = it.applicationAttrition
  335 + var appNum = parseFloat(app)
  336 + var appHasVal = app !== '' && app != null && !isNaN(appNum)
  337 + if (appHasVal) {
  338 + estimatedLoss = this.round2(price * appNum / 100)
  339 + } else {
  340 + var pOpt = this.getProductOption(it.productId)
  341 + var fixedRate = null
  342 + if (pOpt) {
  343 + fixedRate = pOpt.fixedLossRate != null ? pOpt.fixedLossRate : (pOpt.lossRate != null ? pOpt.lossRate : (pOpt.attritionRate != null ? pOpt.attritionRate : null))
  344 + }
  345 + var fixedNum = parseFloat(fixedRate)
  346 + if (!isNaN(fixedNum)) {
  347 + estimatedLoss = this.round2(price * fixedNum / 100)
  348 + } else if (it.fixedLossRate != null && it.fixedLossRate !== '') {
  349 + var fallbackNum = parseFloat(it.fixedLossRate)
  350 + if (!isNaN(fallbackNum)) {
  351 + estimatedLoss = this.round2(price * fallbackNum / 100)
  352 + }
  353 + }
  354 + }
  355 + }
  356 + it.estimatedLoss = estimatedLoss
  357 + this.$set(this.items, idx, it)
  358 + },
  359 + recalcAllItems() {
  360 + var len = (this.items || []).length
  361 + for (var i = 0; i < len; i++) {
  362 + this.recalcAll(i)
  363 + }
  364 + },
298 onAdd() { 365 onAdd() {
299 if (this.items.length >= this.max) { 366 if (this.items.length >= this.max) {
300 uni.showToast({ title: '最多' + this.max + '条明细', icon: 'none' }) 367 uni.showToast({ title: '最多' + this.max + '条明细', icon: 'none' })
@@ -331,6 +398,14 @@ export default { @@ -331,6 +398,14 @@ export default {
331 if (type === 'product') { 398 if (type === 'product') {
332 this.$set(it, 'productId', value) 399 this.$set(it, 'productId', value)
333 this.$set(it, 'productName', label) 400 this.$set(it, 'productName', label)
  401 + var pOpt = this.getProductOption(value)
  402 + if (pOpt) {
  403 + var rate = pOpt.fixedLossRate != null ? pOpt.fixedLossRate : (pOpt.lossRate != null ? pOpt.lossRate : (pOpt.attritionRate != null ? pOpt.attritionRate : ''))
  404 + this.$set(it, 'fixedLossRate', rate != null ? rate : '')
  405 + } else {
  406 + this.$set(it, 'fixedLossRate', '')
  407 + }
  408 + this.recalcAll(idx)
334 } 409 }
335 }, 410 },
336 fillLineNames() { 411 fillLineNames() {
@@ -366,12 +441,14 @@ export default { @@ -366,12 +441,14 @@ export default {
366 }, 441 },
367 emitChange() { 442 emitChange() {
368 if (!this._initialized) return 443 if (!this._initialized) return
  444 + if (this._emitSuppressed) return
369 var list = (this.items || []).map(function (it) { 445 var list = (this.items || []).map(function (it) {
370 var c = Object.assign({}, it) 446 var c = Object.assign({}, it)
371 var key = c._key 447 var key = c._key
372 delete c._key 448 delete c._key
373 delete c.collapsed 449 delete c.collapsed
374 delete c._selected 450 delete c._selected
  451 + delete c.fixedLossRate
375 if (!c.itemId) c.itemId = key 452 if (!c.itemId) c.itemId = key
376 return c 453 return c
377 }) 454 })
@@ -398,7 +475,6 @@ export default { @@ -398,7 +475,6 @@ export default {
398 { key: 'materialType', title: '料型' }, 475 { key: 'materialType', title: '料型' },
399 { key: 'quantity', title: '数量' }, 476 { key: 'quantity', title: '数量' },
400 { key: 'actualPurchasePrice', title: '实际采购价' }, 477 { key: 'actualPurchasePrice', title: '实际采购价' },
401 - { key: 'estimatedLoss', title: '买断料预计损耗' },  
402 { key: 'applicationAttrition', title: '申请损耗' } 478 { key: 'applicationAttrition', title: '申请损耗' }
403 ] 479 ]
404 for (var i = 0; i < items.length; i++) { 480 for (var i = 0; i < items.length; i++) {
@@ -339,7 +339,11 @@ export default { @@ -339,7 +339,11 @@ export default {
339 return 339 return
340 } 340 }
341 var val = parseFloat(raw) 341 var val = parseFloat(raw)
342 - if (isNaN(val)) val = 0 342 + if (isNaN(val)) {
  343 + it[field] = ''
  344 + this.$set(this.items, idx, it)
  345 + return
  346 + }
343 var m = Math.pow(10, digits) 347 var m = Math.pow(10, digits)
344 var rounded = Math.round(val * m) / m 348 var rounded = Math.round(val * m) / m
345 it[field] = rounded 349 it[field] = rounded
@@ -423,6 +427,11 @@ export default { @@ -423,6 +427,11 @@ export default {
423 var fixedNum = parseFloat(fixedRate) 427 var fixedNum = parseFloat(fixedRate)
424 if (!isNaN(fixedNum)) { 428 if (!isNaN(fixedNum)) {
425 estimatedLoss = this.round2(actualPrice * fixedNum / 100) 429 estimatedLoss = this.round2(actualPrice * fixedNum / 100)
  430 + } else if (it.fixedLossRate != null && it.fixedLossRate !== '') {
  431 + var fallbackNum = parseFloat(it.fixedLossRate)
  432 + if (!isNaN(fallbackNum)) {
  433 + estimatedLoss = this.round2(actualPrice * fallbackNum / 100)
  434 + }
426 } 435 }
427 } 436 }
428 } 437 }
@@ -496,6 +505,8 @@ export default { @@ -496,6 +505,8 @@ export default {
496 if (pOpt) { 505 if (pOpt) {
497 var rate = pOpt.fixedLossRate != null ? pOpt.fixedLossRate : (pOpt.lossRate != null ? pOpt.lossRate : (pOpt.attritionRate != null ? pOpt.attritionRate : '')) 506 var rate = pOpt.fixedLossRate != null ? pOpt.fixedLossRate : (pOpt.lossRate != null ? pOpt.lossRate : (pOpt.attritionRate != null ? pOpt.attritionRate : ''))
498 this.$set(it, 'fixedLossRate', rate != null ? rate : '') 507 this.$set(it, 'fixedLossRate', rate != null ? rate : '')
  508 + } else {
  509 + this.$set(it, 'fixedLossRate', '')
499 } 510 }
500 this.recalcAll(idx) 511 this.recalcAll(idx)
501 } else if (type === 'workshop') { 512 } else if (type === 'workshop') {