taskForm.vue 71 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948
  1. <template>
  2. <view class="">
  3. <u-sticky offset-top="50">
  4. <u-subsection fontSize='25' mode='subsection' :list="list" :current="curNow" @change="sectionChange"
  5. activeColor='#157A2C'></u-subsection>
  6. </u-sticky>
  7. <view v-show="curNow===0">
  8. <u--form style="margin: 0 20px;" labelPosition="left" :model="form" ref="uForm" labelWidth='140rpx'>
  9. <u-form-item label="收货单编码" prop="receiveNo" borderBottom>
  10. <u--input style="width: 100%;" disabled v-model="form.receiveNo"></u--input>
  11. </u-form-item>
  12. <u-form-item label="订单编码" prop="orderNo" borderBottom>
  13. <u--input style="width: 100%;" disabled v-model="form.orderNo"></u--input>
  14. </u-form-item>
  15. <u-form-item label="制单人" prop="makerName" borderBottom>
  16. <u--input style="width: 100%;" disabled v-model="form.makerName"></u--input>
  17. </u-form-item>
  18. <u-form-item label="供应商名称" prop="supplierName" borderBottom>
  19. <u--input style="width: 100%;" disabled v-model="form.supplierName"></u--input>
  20. </u-form-item>
  21. <u-form-item label="供应商联系人" prop="linkName" borderBottom>
  22. <u--input style="width: 100%;" disabled v-model="form.linkName"></u--input>
  23. </u-form-item>
  24. <u-form-item label="供应商电话" prop="linkPhone" borderBottom>
  25. <u--input style="width: 100%;" disabled v-model="form.linkPhone"></u--input>
  26. </u-form-item>
  27. <u-form-item label="车牌" prop="carNo" borderBottom>
  28. <u--input style="width: 100%;" disabled v-model="form.carNo"></u--input>
  29. </u-form-item>
  30. <u-form-item label="收货日期" prop="receiveDate" borderBottom>
  31. <u--input style="width: 100%;" disabled v-model="form.receiveDate"></u--input>
  32. </u-form-item>
  33. <u-form-item label="委外发货单编码" prop="outsourceSendCode" borderBottom>
  34. <u--input style="width: 100%;" disabled v-model="form.outsourceSendCode"></u--input>
  35. </u-form-item>
  36. <u-form-item label="附件" prop="receiveFiles" borderBottom>
  37. <fileMain v-model="form.receiveFiles" type="view"></fileMain>
  38. </u-form-item>
  39. </u--form>
  40. </view>
  41. <view v-show="curNow===1">
  42. <view v-for="(item,index) in form['productList']" :key="index">
  43. <u--form style="margin: 0 20px;" labelPosition="left" :model="form" ref="uForm" labelWidth='140rpx'>
  44. <u-row v-for="(key,index1) in tableField" :key="index1">
  45. <u-col :span="12">
  46. <u-form-item :label="key.label" prop="categoryName" borderBottom>
  47. <text>{{ key.formatter ? key.formatter(item) : (item[key.field] || '-') }}</text>
  48. </u-form-item>
  49. </u-col>
  50. </u-row>
  51. </u--form>
  52. <u-gap height="40" bgColor="#f0f0f0"></u-gap>
  53. </view>
  54. </view>
  55. <view v-show="curNow===2">
  56. <u--form style="margin: 0 20px;" labelPosition="left" :model="formData" ref="outForm" :rules="outRules" labelWidth='140rpx'>
  57. <u-form-item label="物品类型" prop="extInfo.assetType" borderBottom>
  58. <u--input style="width: 100%;" disabled v-model="formData.extInfo.assetTypeName"></u--input>
  59. </u-form-item>
  60. <u-form-item label="入库类型" prop="bizType" borderBottom>
  61. <u--input style="width: 100%;" disabled v-model="formData.bizTypeStr"></u--input>
  62. </u-form-item>
  63. <u-form-item label="单据来源" prop="sourceBizNo" borderBottom>
  64. <u--input style="width: 100%;" disabled v-model="formData.sourceBizNo"></u--input>
  65. </u-form-item>
  66. <u-form-item label="入库时间" prop="storageTime" borderBottom>
  67. <uni-datetime-picker type="datetime" v-model="formData.storageTime" />
  68. </u-form-item>
  69. <u-form-item label="入库登记人" prop="extInfo.createUserName" borderBottom>
  70. <u--input style="width: 100%;" disabled v-model="formData.extInfo.createUserName"></u--input>
  71. </u-form-item>
  72. <u-form-item label="审核人" prop="approvalUserName" borderBottom>
  73. <u--input disabled style="width: 100%;" v-model="formData.approvalUserName"></u--input>
  74. </u-form-item>
  75. <u-form-item label="备注" prop="remark" borderBottom>
  76. <u--input style="width: 100%;" v-model="formData.remark"></u--input>
  77. </u-form-item>
  78. </u--form>
  79. </view>
  80. <view class="tab-content" v-show="curNow===3">
  81. <!-- 批量操作按钮 -->
  82. <view class="batch-actions" v-if="productList.length > 0">
  83. <u-button type="success" plain size="small" text="批量保存" @click="listSaveArrs" :disabled="packingList.length > 0"></u-button>
  84. <picker v-if="packingList.length === 0" class="info-picker" :value="warehouseIndex" :range="warehouseListOption" range-key="name" @change="(e) => handleWareHouse(e, productList)">
  85. <u-button type="success" plain size="small" text="批量选择仓库" v-if="packingList.length === 0"></u-button>
  86. </picker>
  87. </view>
  88. <view v-if="productList.length === 0" class="empty-tip" style="text-align: center; color: #999; font-size: 28rpx; padding: 100rpx 0;">
  89. 暂无产品信息
  90. </view>
  91. <view v-else>
  92. <view class="product-card" v-for="(row, index) in productList" :key="index">
  93. <view class="card-header">
  94. <text class="product-name">{{ row.categoryName || '-' }}</text>
  95. <text class="product-code">{{ row.categoryCode || '-' }}</text>
  96. <!-- <text class="card-index">{{ index + 1 }}</text> -->
  97. </view>
  98. <view class="card-body">
  99. <!-- 批次号 - isSave为false时可编辑 -->
  100. <view class="info-row edit-row">
  101. <text class="info-label">批次号 <text class="required">*</text></text>
  102. <u--input v-if="!row.isSave" class="info-input" type="text" v-model="row.batchNo" placeholder="请输入批次号" />
  103. <text v-else class="info-value">{{ row.batchNo || '-' }}</text>
  104. </view>
  105. <!-- 数量 - isSave为false时可编辑 -->
  106. <view class="info-row edit-row">
  107. <text class="info-label">数量 <text class="required">*</text></text>
  108. <u--input v-if="!row.isSave" class="info-input" type="number" v-model="row.packingQuantity" placeholder="请输入数量" @input="computeNum(row, index, true)" />
  109. <text v-else class="info-value">{{ row.packingQuantity || '-' }}</text>
  110. </view>
  111. <!-- 单位选择 -->
  112. <view class="info-row edit-row">
  113. <text class="info-label">单位 <text class="required">*</text></text>
  114. <picker v-if="!row.isSave" class="info-picker" :value="row.packingUnitIndex" :range="row.packingSpecificationOption" range-key="conversionUnit" @change="(e) => onPackingUnitChange(e, row, index)">
  115. <view class="picker-value">{{ row.packingUnit || '请选择单位' }}</view>
  116. </picker>
  117. <text v-else class="info-value">{{ row.packingUnit || '-' }}</text>
  118. </view>
  119. <!-- 包装完好与否 -->
  120. <view class="info-row edit-row" v-if="isShowPackage">
  121. <text class="info-label">包装完好 <text class="required">*</text></text>
  122. <picker v-if="!row.isSave" class="info-picker" :value="row.ifPackageOkIndex" :range="packageOkOptions" range-key="label" @change="(e) => onPackageOkChange(e, row)">
  123. <view class="picker-value">{{ row.ifPackageOkLabel || '请选择' }}</view>
  124. </picker>
  125. <text v-else class="info-value">{{ row.ifPackageOk == 1 ? '是' : row.ifPackageOk == 0 ? '否' : '-' }}</text>
  126. </view>
  127. <!-- 拆包装责任人 -->
  128. <view class="info-row edit-row" v-if="isShowPackage">
  129. <text class="info-label">拆包责任人 <text class="required">*</text></text>
  130. <input v-if="!row.isSave" class="info-input" type="text" v-model="row.unpackUserName" placeholder="请选择" readonly @click="handHead(row, index)" />
  131. <text v-else class="info-value">{{ row.unpackUserName || '-' }}</text>
  132. </view>
  133. <!-- 只读字段 -->
  134. <view class="info-row">
  135. <text class="info-label">计量数量</text>
  136. <text class="info-value">{{ row.measureQuantity || '0' }}</text>
  137. </view>
  138. <view class="info-row">
  139. <text class="info-label">计量单位</text>
  140. <text class="info-value">{{ row.measureUnit || '-' }}</text>
  141. </view>
  142. <!-- 单重 -->
  143. <view class="info-row edit-row">
  144. <text class="info-label">单重</text>
  145. <u--input v-if="!row.isSave" class="info-input" type="digit" v-model="row.singleWeight" placeholder="请输入单重" :disabled="row.weightUnit == row.packingUnit" @input="inputsingleWeight(row, index)" />
  146. <text v-else class="info-value">{{ row.singleWeight || '0' }} {{ row.weightUnit || '' }}</text>
  147. </view>
  148. <!-- 总重 -->
  149. <view class="info-row edit-row">
  150. <text class="info-label">总重</text>
  151. <u--input v-if="!row.isSave" class="info-input" type="digit" v-model="row.weight" placeholder="请输入总重" :disabled="row.weightUnit == row.packingUnit" @input="inputWeight(row, index)" />
  152. <text v-else class="info-value">{{ row.weight || '0' }} {{ row.weightUnit || '' }}</text>
  153. </view>
  154. <view class="info-row">
  155. <text class="info-label">重量单位</text>
  156. <text class="info-value">{{ row.weightUnit || '-' }}</text>
  157. </view>
  158. <view class="info-row">
  159. <text class="info-label">生产要求</text>
  160. <text class="info-value">{{ row.productionRequirements || '-' }}</text>
  161. </view>
  162. <view class="info-row">
  163. <text class="info-label">包装规格</text>
  164. <text class="info-value">{{ row.packingSpecificationLabel ? row.packingSpecificationLabel.join(', ') : '-' }}</text>
  165. </view>
  166. <view class="info-row">
  167. <text class="info-label">允许拆包</text>
  168. <text class="info-value">{{ row.isUnpack == 1 ? '是' : '否' }}</text>
  169. </view>
  170. <!-- 仓库 - 必填 -->
  171. <view class="info-row edit-row">
  172. <text class="info-label">仓库 <text class="required">*</text></text>
  173. <picker v-if="!row.isSave" class="info-picker" :value="row.warehouseIndex" :range="warehouseListOption" range-key="name" @change="(e) => onWarehouseChange(e, row)">
  174. <view class="picker-value">{{ row.warehouseName || '请选择仓库' }}</view>
  175. </picker>
  176. <text v-else class="info-value" :class="{ 'red-text': !row.warehouseName }">{{ row.warehouseName || '请选择仓库' }}</text>
  177. </view>
  178. <!-- 供应商 -->
  179. <view class="info-row edit-row">
  180. <text class="info-label">供应商</text>
  181. <picker v-if="!row.isSave" class="info-picker" :value="row.supplierIndex" :range="row.supplierListOptions" range-key="name" @change="(e) => onSupplierChange(e, row)">
  182. <view class="picker-value">{{ row.supplierName || '请选择供应商' }}</view>
  183. </picker>
  184. <text v-else class="info-value">{{ row.supplierName || '-' }}</text>
  185. </view>
  186. <view class="info-row">
  187. <text class="info-label">供应商代号</text>
  188. <text class="info-value">{{ row.supplierCode || '-' }}</text>
  189. </view>
  190. <!-- 采购原因 -->
  191. <view class="info-row edit-row">
  192. <text class="info-label">采购原因</text>
  193. <u--input v-if="!row.isSave" class="info-input" type="text" v-model="row.purpose" placeholder="请输入采购原因" />
  194. <text v-else class="info-value">{{ row.purpose || '-' }}</text>
  195. </view>
  196. <view class="info-row">
  197. <text class="info-label">是否质检</text>
  198. <text class="info-value">{{ row.qualityControl == 1 ? '是' : '否' }}</text>
  199. </view>
  200. <!-- 生产日期 -->
  201. <view class="info-row edit-row">
  202. <text class="info-label">生产日期</text>
  203. <!-- <picker v-if="!row.isSave" class="info-picker" mode="date" :value="row.detailProductionDate" @change="(e) => onDateChange(e, row, 'detailProductionDate')">
  204. <view class="picker-value" :class="{ 'placeholder': !row.detailProductionDate }">{{ row.detailProductionDate || '请选择日期' }}</view>
  205. </picker> -->
  206. <uni-datetime-picker v-if="!row.isSave" type="datetime" v-model="row.detailProductionDate" />
  207. <text v-else class="info-value">{{ row.detailProductionDate || '-' }}</text>
  208. </view>
  209. <!-- 采购日期 -->
  210. <view class="info-row edit-row">
  211. <text class="info-label">采购日期</text>
  212. <!-- <picker v-if="!row.isSave" class="info-picker" mode="date" :value="row.detailPurchaseDate" @change="(e) => onDateChange(e, row, 'detailPurchaseDate')">
  213. <view class="picker-value" :class="{ 'placeholder': !row.detailPurchaseDate }">{{ row.detailPurchaseDate || '请选择日期' }}</view>
  214. </picker> -->
  215. <uni-datetime-picker v-if="!row.isSave" type="datetime" v-model="row.detailPurchaseDate" />
  216. <text v-else class="info-value">{{ row.detailPurchaseDate || '-' }}</text>
  217. </view>
  218. <!-- 失效日期 -->
  219. <view class="info-row edit-row">
  220. <text class="info-label">失效日期</text>
  221. <!-- <picker v-if="!row.isSave" class="info-picker" mode="date" :value="row.detailExpireDate" @change="(e) => onDateChange(e, row, 'detailExpireDate')">
  222. <view class="picker-value" :class="{ 'placeholder': !row.detailExpireDate }">{{ row.detailExpireDate || '请选择日期' }}</view>
  223. </picker> -->
  224. <uni-datetime-picker v-if="!row.isSave" type="datetime" v-model="row.detailExpireDate" />
  225. <text v-else class="info-value">{{ row.detailExpireDate || '-' }}</text>
  226. </view>
  227. <!-- 机型 - 多选 -->
  228. <view class="info-row edit-row">
  229. <text class="info-label">机型</text>
  230. <view v-if="!row.isSave" class="color-picker-trigger" @click="openModelPicker(row, index)">
  231. <text class="picker-value" :class="{ 'placeholder': !row.modelKey }">{{ row.modelKey || '请选择机型' }}</text>
  232. </view>
  233. <text v-else class="info-value">{{ row.modelKeyNames || '-' }}</text>
  234. </view>
  235. <!-- 颜色 - 多选 -->
  236. <view class="info-row edit-row">
  237. <text class="info-label">颜色</text>
  238. <view v-if="!row.isSave" class="color-picker-trigger" @click="openColorPicker(row, index)">
  239. <text class="picker-value" :class="{ 'placeholder': !row.colorKey }">{{ row.colorKey || '请选择颜色' }}</text>
  240. </view>
  241. <text v-else class="info-value">{{ row.colorKey || '-' }}</text>
  242. </view>
  243. </view>
  244. <view class="card-footer">
  245. <view class="action-buttons">
  246. <u-button v-if="!row.isSave" type="primary" size="small" text="保存" @click="listSave(row, index)"></u-button>
  247. <u-button v-else type="primary" size="small" text="编辑" @click="editProductList(row, index)"></u-button>
  248. <u-button type="error" size="small" text="删除" @click="listDel(row, index)"></u-button>
  249. </view>
  250. </view>
  251. </view>
  252. </view>
  253. <view class="add" @click="addProduct">
  254. <u-icon name="plus" color="#fff"></u-icon>
  255. </view>
  256. </view>
  257. <view class="tab-content" v-show="curNow===4">
  258. <!-- 包装明细 -->
  259. <view v-if="showPackingList.length > 0" class="packing-section">
  260. <view class="section-title">
  261. <text>包装明细</text>
  262. </view>
  263. <view class="packing-card" v-for="(item, index) in showPackingList" :key="'pkg-' + index">
  264. <view class="info-row">
  265. <text class="info-label">编码</text>
  266. <text class="info-value">{{ item.categoryCode || '-' }}</text>
  267. </view>
  268. <view class="info-row">
  269. <text class="info-label">名称</text>
  270. <text class="info-value">{{ item.categoryName || '-' }}</text>
  271. </view>
  272. <view class="info-row">
  273. <text class="info-label">批次号</text>
  274. <text class="info-value">{{ item.batchNo || '-' }}</text>
  275. </view>
  276. <view class="info-row">
  277. <text class="info-label">包装编码</text>
  278. <text class="info-value">{{ item.packageNo || '-' }}</text>
  279. </view>
  280. <view class="info-row">
  281. <text class="info-label">包装数量</text>
  282. <text class="info-value">{{ item.packingQuantity || '0' }} {{ item.packingUnit || '' }}</text>
  283. </view>
  284. <view class="info-row">
  285. <text class="info-label">计量数量</text>
  286. <text class="info-value">{{ item.measureQuantity || '0' }} {{ item.measureUnit || '' }}</text>
  287. </view>
  288. <view class="info-row">
  289. <text class="info-label">仓库</text>
  290. <text class="info-value">{{ item.warehouseName || '-' }}</text>
  291. </view>
  292. <view class="info-row">
  293. <text class="info-label">物料代号</text>
  294. <text class="info-value">{{ item.materielDesignation || '-' }}</text>
  295. </view>
  296. <view class="info-row">
  297. <text class="info-label">客户代号</text>
  298. <text class="info-value">{{ item.clientCode || '-' }}</text>
  299. </view>
  300. <view class="info-row">
  301. <text class="info-label">重量</text>
  302. <text class="info-value">{{ item.weight || '0' }} {{ item.weightUnit || '' }}</text>
  303. </view>
  304. <view class="info-row">
  305. <text class="info-label">生产日期</text>
  306. <text class="info-value">{{ item.productionDate || '-' }}</text>
  307. </view>
  308. <view class="info-row">
  309. <text class="info-label">采购日期</text>
  310. <text class="info-value">{{ item.purchaseDate || '-' }}</text>
  311. </view>
  312. </view>
  313. </view>
  314. </view>
  315. <!-- 选择颜色 -->
  316. <ba-tree-picker ref="colorTreePicker" :multiple="true" @select-change="onColorConfirm" title="选择颜色"
  317. :localdata="colorTreeData" valueKey="id" textKey="name" childrenKey="child" />
  318. <!-- 选择机型 -->
  319. <ba-tree-picker ref="modelTreePicker" :multiple="true" @select-change="onModelConfirm" title="选择机型"
  320. :localdata="modelTreeData" valueKey="id" textKey="name" childrenKey="child" />
  321. </view>
  322. </template>
  323. <script>
  324. import {
  325. purchaseOrderReceiveGetByIdAPI
  326. } from '@/api/wt/index.js'
  327. import { sceneState, qualityResultsOptions, qualityStatus, qualityResults } from '@/enum/dict.js'
  328. import fileMain from "@/pages/doc/index.vue"
  329. import { parameterGetByCode } from '@/api/mainData/index.js'
  330. import { getListByNameOrModeType, getCode, contactQueryByCategoryIdsAPI, getCategoryPackageDisposition, getProduceTreeByPid, warehouseDefinitionList, getAssetNum, getWarehouseList, isVerifyRepeatIsStock } from '@/api/warehouseManagement/index.js'
  331. import { mapGetters, mapActions } from 'vuex'
  332. import baTreePicker from '@/components/ba-tree-picker/ba-tree-picker.vue'
  333. import { unary } from 'lodash'
  334. export default {
  335. components: {
  336. fileMain,
  337. baTreePicker
  338. },
  339. props: {
  340. businessId: {
  341. default: ''
  342. },
  343. taskDefinitionKey: {
  344. default: ''
  345. },
  346. },
  347. computed: {
  348. ...mapGetters(['dict', 'getDict', 'getDictValue']),
  349. // 机型选项
  350. modelOptions() {
  351. return this.dict?.product_model_key || []
  352. },
  353. // 颜色选项(数组)
  354. colorOptions() {
  355. return this.dict?.product_color_key || []
  356. },
  357. // 颜色选项(树形结构,用于 ba-tree-picker)
  358. colorTreeData() {
  359. console.log('colorOptions~~~', this.colorOptions)
  360. return this.colorOptions.map(item => ({
  361. id: item.dictCode,
  362. name: item.dictValue
  363. }))
  364. },
  365. // 机型选项(数组)
  366. modelOptions() {
  367. return this.dict?.product_model_key || []
  368. },
  369. // 机型选项(树形结构,用于 ba-tree-picker)
  370. modelTreeData() {
  371. return this.modelOptions.map(item => ({
  372. id: item.dictCode,
  373. name: item.dictValue
  374. }))
  375. },
  376. list() {
  377. return this.showPackingList.length > 0 ? ['收货信息', '物品清单', '入库信息', '产品信息', '包装明细'] : ['收货信息', '物品清单', '入库信息', '产品信息']
  378. },
  379. tableField() {
  380. const priceField = [
  381. { label: '单价', field: 'singlePrice' },
  382. { label: '不含税单价', field: 'notaxSinglePrice' },
  383. { label: '折后单价', field: 'discountSinglePrice' },
  384. { label: '合计', field: 'totalPrice' },
  385. { label: '折后合计', field: 'discountTotalPrice' },
  386. ]
  387. const baseField = [
  388. { label: '名称', field: 'productName' },
  389. { label: '编码', field: 'productCode' },
  390. { label: '类型', field: 'productCategoryName' },
  391. { label: '批次号', field: 'batchNo' },
  392. { label: '规格', field: 'specification' },
  393. { label: '型号', field: 'modelType' },
  394. { label: '包装规格', field: 'packingSpecification' },
  395. { label: '供应商代号', field: 'supplierMark' },
  396. { label: '仓库名称', field: 'warehouseName' },
  397. { label: '收货数量', field: 'purchaseCount', formatter: (row) => (row.purchaseCount || '-') + row.purchaseUnit },
  398. { label: '单重', field: 'singleWeight', formatter: (row) => row.singleWeight ? row.singleWeight + ' ' + row.weightUnit : '-' },
  399. { label: '发货总重', field: 'sendTotalWeight', formatter: (row) => row.sendTotalWeight ? row.sendTotalWeight + ' ' + row.weightUnit : '-' },
  400. { label: '收货总重', field: 'receiveTotalWeight', formatter: (row) => row.receiveTotalWeight ? row.receiveTotalWeight + ' ' + row.weightUnit : '-' },
  401. { label: '增重重量', field: 'increaseTotalWeight', formatter: (row) => row.increaseTotalWeight ? row.increaseTotalWeight + ' ' + row.weightUnit : '-' },
  402. { label: '计量数量', field: 'totalCount', formatter: (row) => (row.totalCount || '-') + row.measuringUnit },
  403. { label: '是否来料检验', field: 'isComeCheck', formatter: (row) => row.isComeCheck == 1 ? '是' : '否' },
  404. ]
  405. return this.taskDefinitionKey == 'storeManagerApprove' && this.isHidePrice == 0 ? baseField : [...baseField, ...priceField]
  406. },
  407. tableField2() {
  408. return [
  409. { label: '名称', field: 'categoryName' },
  410. { label: '编码', field: 'categoryCode' },
  411. { label: '型号', field: 'categoryModel' },
  412. { label: '规格', field: 'specification' },
  413. { label: '牌号', field: 'brandNum' },
  414. { label: '批次号', field: 'batchNo' },
  415. { label: '数量', field: 'packingQuantity' },
  416. { label: '单位', field: 'packingUnit' },
  417. { label: '单重', field: 'singleWeight' },
  418. { label: '总重', field: 'weight' },
  419. { label: '重量单位', field: 'weightUnit' },
  420. { label: '供应商', field: 'supplierId' },
  421. { label: '仓库', field: 'warehouseName' },
  422. { label: '颜色', field: 'colorKey' },
  423. { label: '机型', field: 'modelKey' },
  424. { label: '采购原因', field: 'purpose' },
  425. { label: '生产日期', field: 'detailProductionDate' },
  426. { label: '采购日期', field: 'detailPurchaseDate' },
  427. { label: '失效日期', field: 'detailExpireDate' },
  428. { label: '是否质检', field: 'qualityControl' },
  429. { label: '包装规格', field: 'packingSpecificationLabel' },
  430. { label: '允许拆包', field: 'isUnpack' },
  431. { label: '计量数量', field: 'measureQuantity' },
  432. { label: '计量单位', field: 'measureUnit' },
  433. { label: '生产要求', field: 'weightUnit' },
  434. { label: '供应商名称', field: 'supplierName' },
  435. { label: '供应商代号', field: 'supplierCode' },
  436. { label: '产地', field: 'supplierCode' },
  437. ]
  438. }
  439. },
  440. data() {
  441. return {
  442. form: {},
  443. userInfo: {},
  444. formData: {
  445. bizType: '',
  446. bizTypeStr: '',
  447. storageTime: '',
  448. qualityControl: '',
  449. extInfo: {
  450. assetType: [],
  451. assetTypeName: ''
  452. }
  453. },
  454. isHidePrice: 0,
  455. warehouseIndex: 0,
  456. curNow: 0,
  457. packingSpecificationOption: [],
  458. productList: [],
  459. packingList: [],
  460. showPackingList: [],
  461. goodsLists: [],
  462. outRules: {},
  463. sceneState,
  464. qualityResultsOptions,
  465. qualityStatus,
  466. qualityResults,
  467. isWrapTable: true,
  468. pageSize: 20,
  469. pickingPageNum: 1,
  470. visibleDialog: false,
  471. title: '选择产品',
  472. loadTree: true,
  473. isShowPackage: false,
  474. packageOkOptions: [
  475. { label: '是', value: 1 },
  476. { label: '否', value: 0 }
  477. ],
  478. // colorTreeData: [], // 颜色树形数据
  479. currentColorRow: null, // 当前选择颜色的行
  480. currentColorIndex: -1, // 当前选择颜色的行索引
  481. // 机型相关
  482. currentModelRow: null, // 当前选择机型的行
  483. currentModelIndex: -1, // 当前选择机型的行索引
  484. }
  485. },
  486. beforeDestroy() {
  487. uni.$off('setSelectList')
  488. },
  489. created() {
  490. uni.$on('setSelectList', async data => {
  491. // uni.removeStorageSync('productList')
  492. console.log('setSelectList~~~', data)
  493. if (data?.length) {
  494. // 获取批次号
  495. const batchNo = await getCode('lot_number_code');
  496. // 获取供应商
  497. const supplierList = await contactQueryByCategoryIdsAPI({
  498. categoryIds: data.map((item) => item.id)
  499. });
  500. // 获取包装规格
  501. let packingSpecification = await getCategoryPackageDisposition({
  502. categoryIds: data.map((item) => item.id)
  503. });
  504. this.packingSpecificationOption = data.map((item) => {
  505. return packingSpecification
  506. .filter((ite) => item.id == ite.categoryId)
  507. .sort((a, b) => a.sort - b.sort);
  508. });
  509. const newSpecificationOption = this.packingSpecificationOption;
  510. let productList = data.map((item, index) => {
  511. // 显示规格
  512. let packingSpecificationLabel = this.packingSpecificationOption[index].map((item) => {
  513. if (item.sort > 0) {
  514. return `${item.packageCell}${item.packageUnit}/${item.conversionUnit}`;
  515. }
  516. }).filter((item) => !!item);
  517. return {
  518. index:
  519. this.productList.length - 1 > -1
  520. ? this.productList[this.productList.length - 1].index + index + 1 : this.productList.length + index,
  521. categoryId: item.id, // 物品id
  522. categoryName: item.name, // 物品名称
  523. categoryCode: item.code, // 物品编码
  524. categoryModel: item.modelType, // 物品型号
  525. specification: item.specification, // 规格
  526. modelKey: item.modelKey ? item.modelKey : '', // 机型
  527. colorKey: item.colorKey ? item.colorKey : '', // 颜色
  528. brandNum: item.brandNum, // 牌号
  529. batchNo: batchNo, // 批次号
  530. supplierListOptions: supplierList[item.id], // 供应商列表
  531. supplierId: '', // 供应商id
  532. supplierCode: item.supplierCode, // 供应商代号
  533. supplierName: item.supplierName, // 供应商名称
  534. measureType: item.measureType, // 计量类型
  535. approvalNumber: item.approvalNumber, // 批准文号
  536. packingSpecification: item.packingSpecification, // 包装规格
  537. packingSpecificationOption: newSpecificationOption[index], // 包装规格选项
  538. packingSpecificationLabel: packingSpecificationLabel, // 包装规格显示
  539. minPackingQuantity: '', // 最小包装单元数量
  540. packingQuantity: '', // 包装数量
  541. packingUnit: item.measuringUnit, // 单位
  542. packingUnitId: newSpecificationOption[index].find(
  543. (v) => v.conversionUnit == item.measuringUnit
  544. )?.id, // 单位
  545. measureQuantity: 0, // 计量数量
  546. measureUnit: item.measuringUnit, // 计量单位
  547. netWeight: item.netWeight > -1 ? item.netWeight : 0, // 净重
  548. weight: 0, // 重量
  549. singleWeight: item.measuringUnit != 'KG' ? item.netWeight : 0, // 单重
  550. pricingWay: item.pricingWay,
  551. weightUnit: item.weightUnit, // 重量单位
  552. totalMoney: item.totalPrice, // 总价
  553. unitPrice: item.unitPrice, // 单价
  554. purpose: '', // 用途
  555. isUnpack: item.isUnpack // 是否允许拆包
  556. };
  557. });
  558. this.productList = this.productList.concat(productList);
  559. }
  560. })
  561. },
  562. async mounted() {
  563. this.userInfo = uni.getStorageSync('userInfo')
  564. await this.requestDict('产地')
  565. await this.requestDict('不拆物料层规格')
  566. await this.requestDict('物品颜色')
  567. await this.requestDict('物品机型')
  568. await this.getListItems()
  569. await this.getwarehouseList()
  570. await parameterGetByCode({ code: 'eom_purchase_invoice_approval_price' }).then((res) => {
  571. this.isHidePrice = res.value;
  572. });
  573. await this.getDetailData(this.businessId);
  574. await this.getNowFormatDate();
  575. },
  576. watch: {
  577. packingList: {
  578. handler(newVal) {
  579. this.showPackingList = newVal.slice(0, this.pageSize * (this.pickingPageNum > 0 ? this.pickingPageNum : 1));
  580. this.pickingPageNum = Math.ceil(this.showPackingList.length / this.pageSize);
  581. },
  582. deep: true
  583. }
  584. },
  585. methods: {
  586. ...mapActions('dict', ['requestDict']),
  587. // 获取当前时间 YYYY-MM-DD HH:mm:ss
  588. getCurrentTime() {
  589. const now = new Date();
  590. const year = now.getFullYear();
  591. const month = String(now.getMonth() + 1).padStart(2, '0');
  592. const day = String(now.getDate()).padStart(2, '0');
  593. const hours = String(now.getHours()).padStart(2, '0');
  594. const minutes = String(now.getMinutes()).padStart(2, '0');
  595. const seconds = String(now.getSeconds()).padStart(2, '0');
  596. return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
  597. },
  598. //获取仓库
  599. async getwarehouseList() {
  600. let res = await getWarehouseList()
  601. this.warehouseListOption = res.data.map(item => {
  602. return {
  603. id: item.id,
  604. name: item.name
  605. }
  606. })
  607. },
  608. handleWareHouse(e, row) {
  609. const val = e.detail.value;
  610. const warehouseItem = this.warehouseListOption[val];
  611. if (warehouseItem) {
  612. this.productList.forEach((item, index) => {
  613. this.$set(this.productList[index], 'warehouseId', warehouseItem.id);
  614. this.$set(this.productList[index], 'warehouseName', warehouseItem.name);
  615. this.$set(this.productList[index], 'warehouseIds', [warehouseItem.id]);
  616. this.$set(this.productList[index], 'warehouseNames', [warehouseItem.name]);
  617. });
  618. }
  619. },
  620. // 获取物品列表
  621. async getListItems() {
  622. const res = await getProduceTreeByPid({});
  623. this.goodsLists = res;
  624. },
  625. sectionChange(index) {
  626. this.curNow = index;
  627. },
  628. async getDetailData(id) {
  629. const data = await purchaseOrderReceiveGetByIdAPI(id);
  630. this.form = data;
  631. this.initFormData()
  632. },
  633. initFormData() {
  634. const defaultTime = '00:00:00';
  635. this.formData.type = 1;
  636. this.formData.bizType = this.form.outsourceSendCode ? 10 : 2;
  637. const currentTime = this.getCurrentTime();
  638. if (this.formData.bizType == 2 || this.formData.bizType == 6) {
  639. this.formData.storageTime = this.form.receiveDate
  640. ? `${this.form.receiveDate} ${defaultTime}`
  641. : currentTime;
  642. } else {
  643. this.formData.storageTime = currentTime;
  644. }
  645. this.formData.bizTypeStr = sceneState.find(item => item.code == this.formData.bizType)?.label || ''
  646. if (this.form.receiveNo != null && this.form.receiveNo != '') {
  647. this.$set(this.formData, 'sourceBizNo', this.form.receiveNo);
  648. } else {
  649. uni.showToast({ title: '未获取到单据来源!', icon: 'none' });
  650. }
  651. this.formData.extInfo.createUserId = this.form.createUserId || this.userInfo.userId || '';
  652. this.formData.extInfo.createUserName = this.form.createUserName || this.userInfo.name || '';
  653. this.formData.extInfo.deliveryPhone = this.userInfo.phone || '';
  654. this.formData.createUserId = this.form.createUserId || this.userInfo.userId || '';
  655. this.formData.createUserName = this.form.createUserName || this.userInfo.name || '';
  656. this.formData.extInfo.deptName = this.form.deptName || this.userInfo.deptName || '';
  657. this.formData.approvalUserName = this.form.approvalUserName || this.userInfo.name;
  658. this.formData.approvalUserId = this.form.approvalUserId || this.userInfo.userId;
  659. if (this.form.productList?.length > 0) {
  660. let detailPurchaseDate;
  661. if (this.formData.bizType == '2' || this.formData.bizType == '10') {
  662. detailPurchaseDate = this.form.purchaseDate || `${this.form.receiveDate} ${defaultTime}`;
  663. }
  664. let codeList = this.form.productList.map((item) => item.productCode || item.categoryCode);
  665. getListByNameOrModeType({ codeList }).then(async (res) => {
  666. if (res.length <= 0) {
  667. uni.showToast({ title: '未获取到物品信息!', icon: 'none' });
  668. return;
  669. }
  670. this.formData.extInfo.assetType = Array.from(new Set(res.map((item) => item.categoryLevelPathIdParent)));
  671. this.formData.extInfo.assetTypeName = this.formData.extInfo.assetType.map(id => {
  672. const item = this.goodsLists.find(g => g.id == id);
  673. return item?.name || id;
  674. }).join(',');
  675. const batchNo1 = await getCode('lot_number_code');
  676. const supplierList = await contactQueryByCategoryIdsAPI({ categoryIds: res.map((item) => item.id) });
  677. let packingSpecification = await getCategoryPackageDisposition({ categoryIds: res.map((item) => item.id) });
  678. this.packingSpecificationOption = res.map((item) => {
  679. return packingSpecification.filter((ite) => item.id == ite.categoryId).sort((a, b) => a.sort - b.sort);
  680. });
  681. this.productList = res.map((item, index) => {
  682. let filtersItem = this.form.productList.find((detailItem) => item.code == detailItem.productCode || item.code == detailItem.categoryCode);
  683. let packingSpecificationLabel = this.packingSpecificationOption[index].map((item) => {
  684. if (item.sort > 0) {
  685. return `${item.packageCell}${item.packageUnit}/${item.conversionUnit}`;
  686. }
  687. }).filter((item) => !!item);
  688. const newSpecificationOption = this.packingSpecificationOption;
  689. let warehouseId = filtersItem.warehouseId;
  690. let warehouseName = filtersItem.warehouseName;
  691. let measureQuantity = filtersItem.totalCountNew || filtersItem.totalCount || 0;
  692. if ((filtersItem.sendTotalWeight || filtersItem.receiveTotalWeight) && item.weightUnit == item.measuringUnit) {
  693. measureQuantity = filtersItem.sendTotalWeight || filtersItem.receiveTotalWeight;
  694. }
  695. let packingQuantity = filtersItem.totalCountNew || filtersItem.purchaseCount || filtersItem.totalCount || 0;
  696. let packingUnit = filtersItem.purchaseUnit || filtersItem.measuringUnit || '';
  697. let unitPrice = filtersItem.singlePrice || 0;
  698. let pricingWay = filtersItem.pricingWay || '';
  699. let singleWeight = filtersItem.singleWeight || 0;
  700. let weight = filtersItem.sendTotalWeight || filtersItem.receiveTotalWeight || singleWeight * measureQuantity;
  701. let warehouseIds = [];
  702. let warehouseNames = [];
  703. for (let i = 0; i < filtersItem.totalCount; i++) {
  704. warehouseIds.push(filtersItem.warehouseId);
  705. warehouseNames.push(filtersItem.warehouseName);
  706. }
  707. let totalMoney = filtersItem.totalPrice || 0;
  708. let batchNo = filtersItem.batchNo || batchNo1;
  709. return {
  710. index: this.productList.length + index,
  711. categoryId: item.id,
  712. categoryName: item.name,
  713. categoryCode: item.code,
  714. categoryModel: item.modelType,
  715. specification: item.specification,
  716. brandNum: item.brandNum,
  717. batchNo: batchNo,
  718. supplierListOptions: supplierList[item.id],
  719. supplierId: this.form.supplierId,
  720. productionRequirements: filtersItem.productionRequirements,
  721. supplierCode: this.formData.bizType == 2 || this.formData.bizType == 7 ? filtersItem.supplierMark : item.supplierCode,
  722. supplierName: this.form.supplierName,
  723. approvalNumber: item.approvalNumber,
  724. packingSpecification: item.packingSpecification,
  725. packingSpecificationOption: newSpecificationOption[index],
  726. packingSpecificationLabel: packingSpecificationLabel,
  727. packingQuantity: this.form.productList[index] && this.form.productList[index].isAllPackageData == 1
  728. ? this.form.productList[index].packingCount : packingQuantity,
  729. packingUnit: this.form.productList[index] && this.form.productList[index].isAllPackageData == 1
  730. ? this.form.productList[index].packingUnit : packingUnit,
  731. measureQuantity: this.form.productList[index] && this.form.productList[index].isAllPackageData == 1
  732. ? this.form.productList[index].quantity : measureQuantity,
  733. measureUnit: this.form.productList[index] && this.form.productList[index].isAllPackageData == 1
  734. ? this.form.productList[index].measuringUnit : item.measuringUnit,
  735. packingUnitId: filtersItem.purchaseUnitId || filtersItem.saleUnitId,
  736. modelKey: filtersItem.modelKey ? filtersItem.modelKey : '',
  737. colorKey: filtersItem.colorKey ? filtersItem.colorKey : '',
  738. measureType: item.measureType,
  739. netWeight: item.netWeight > -1 ? item.netWeight : 0,
  740. singleWeight: singleWeight || 0,
  741. weight: weight || 0,
  742. weightUnit: item.weightUnit,
  743. totalMoney: totalMoney,
  744. unitPrice: item.unitPrice || unitPrice,
  745. pricingWay: pricingWay,
  746. purpose: '',
  747. detailPurchaseDate,
  748. detailExpireDate: this.form.productList.find((product) => product.productId == item.id)?.guaranteePeriodDeadline,
  749. detailProductionDate: this.form.productList.find((product) => product.productId == item.id)?.productionDate,
  750. provenance: filtersItem.provenance,
  751. isUnpack: item.isUnpack,
  752. warehouseId,
  753. warehouseName,
  754. warehouseIds,
  755. warehouseNames,
  756. qualityControl: filtersItem?.isComeCheck
  757. };
  758. });
  759. this.$nextTick(() => {
  760. this.batchSave();
  761. });
  762. });
  763. }
  764. },
  765. // 赋值入库时间
  766. getNowFormatDate() {
  767. const obj = this.getNowDate();
  768. const defaultTime = '00:00:00';
  769. const currentTime = `${obj.hour}:${obj.minute}:${obj.second}`;
  770. if (this.formData.bizType === 2 || this.formData.bizType === '2' || this.formData.bizType === 6 || this.formData.bizType === '6') {
  771. this.formData.storageTime = this.form.receiveDate
  772. ? `${this.form.receiveDate} ${defaultTime}`
  773. : `${obj.year}-${obj.month}-${obj.strDate} ${currentTime}`;
  774. } else {
  775. this.formData.storageTime = `${obj.year}-${obj.month}-${obj.strDate} ${currentTime}`;
  776. }
  777. },
  778. // 获取当前时间函数
  779. getNowDate() {
  780. let date = new Date(),
  781. obj = {
  782. year: date.getFullYear(),
  783. month: date.getMonth() + 1,
  784. strDate: date.getDate(),
  785. hour: date.getHours(),
  786. minute: date.getMinutes(),
  787. second: date.getSeconds()
  788. };
  789. Object.keys(obj).forEach((key) => {
  790. if (obj[key] < 10) obj[key] = `0${obj[key]}`;
  791. });
  792. return obj;
  793. },
  794. changeCount(number) {
  795. // 移动端兼容的数字转字符串方法,避免浮点数精度显示问题
  796. const num = Number(number || 0);
  797. return isNaN(num) ? '0' : String(num);
  798. },
  799. selectSupplier(val, row) {
  800. row.supplierId = val;
  801. row.supplierName = row.supplierListOptions.filter((item) => item.id == val)[0]?.name;
  802. row.supplierCode = row.supplierListOptions.filter((item) => item.id == val)[0]?.serialNo;
  803. },
  804. inputsingleWeight(row, index) {
  805. if (row.measureUnit == row.weightUnit) {
  806. row.weight = row.singleWeight * row.packingQuantity;
  807. row.measureQuantity = row.weight;
  808. } else {
  809. row.weight = row.singleWeight * row.measureQuantity;
  810. }
  811. },
  812. inputWeight(row, index) {
  813. if (row.measureUnit == row.weightUnit) {
  814. row.measureQuantity = row.weight;
  815. row.singleWeight = Math.trunc((row.measureQuantity / row.packingQuantity) * 10000) / 10000;
  816. } else {
  817. row.singleWeight = row.measureQuantity ? row.weight / row.measureQuantity : 0;
  818. }
  819. },
  820. // 计算最小单元数量
  821. async computeNum(row, index, isClear) {
  822. let data = row.packingSpecificationOption.find((item) => item.id == row.packingUnitId);
  823. if (data) {
  824. row.packingUnit = data.conversionUnit;
  825. }
  826. if (isClear && row.packingQuantity < 0) {
  827. this.$set(this.productList[index], 'packingQuantity', 1);
  828. }
  829. if (row.packingQuantity && row.packingUnit) {
  830. const res = await warehouseDefinitionList({});
  831. if (res.length == 1) {
  832. let name = res[0]?.factoryName + '-' + res[0]?.name;
  833. this.$set(this.productList[index], 'warehouseId', res[0].id);
  834. this.$set(this.productList[index], 'warehouseName', name);
  835. } else {
  836. this.$set(this.productList[index], 'warehouseId', '');
  837. this.$set(this.productList[index], 'warehouseName', '');
  838. }
  839. let startIndex = row.packingSpecificationOption.findIndex((ite) => {
  840. return row.measuringUnit == ite.packingUnit && ite.packingUnit != ite.conversionUnit;
  841. });
  842. let endIndex = row.packingSpecificationOption.findIndex((ite) => data.id == ite.id);
  843. let total = Number(row.packingQuantity);
  844. if (row.packingUnit == row.measureUnit && row.measureUnit == '立方' && row.netWeight) {
  845. total = Number(row.packingQuantity) * row.netWeight;
  846. } else {
  847. for (; 0 < endIndex; endIndex--) {
  848. total = this.$math.format(row.packingSpecificationOption[endIndex].packageCell * total, 14);
  849. }
  850. }
  851. row.measureQuantity = this.changeCount(total);
  852. let packingBoolen = !!this.getDict('不拆物料层规格', row.packingUnit)?.dictValue;
  853. let measureBoolen = !!this.getDict('不拆物料层规格', row.measureUnit)?.dictValue;
  854. if (packingBoolen && measureBoolen && row.packingUnit != 'L') {
  855. row.weight = total;
  856. }
  857. let weight = 0;
  858. if (row.measureUnit == row.weightUnit) {
  859. weight = row.measureQuantity;
  860. if (row.weightUnit == row.packageUnit) {
  861. row.singleWeight = 0;
  862. } else {
  863. row.singleWeight = Math.trunc((row.measureQuantity / row.packingQuantity) * 10000) / 10000;
  864. }
  865. } else if (row.singleWeight) {
  866. weight = row.measureQuantity * Number(row.singleWeight);
  867. }
  868. this.$set(this.productList[index], 'weight', weight);
  869. }
  870. },
  871. // 添加产品
  872. addProduct() {
  873. if (this.formData.extInfo.assetType.length <= 0) {
  874. return uni.showToast({ title: '请选择物品类型', icon: 'none' });
  875. }
  876. if (!this.formData.bizType) {
  877. return uni.showToast({ title: '请选择入库类型', icon: 'none' });
  878. }
  879. this.visibleDialog = true;
  880. uni.navigateTo({
  881. url: '/pages/warehouse/enterHouse/selectEnterType?assetType=' + this.formData.extInfo.assetType
  882. })
  883. },
  884. // 批量保存
  885. async batchSave() {
  886. try {
  887. for (let i = 0; i < this.productList.length; i++) {
  888. const row = this.productList[i];
  889. if (!row.isSave) {
  890. await this.listSave(row, i);
  891. }
  892. }
  893. } catch (error) {
  894. console.log('保存失败', error);
  895. }
  896. },
  897. listSave(row, index) {
  898. // 必填项校验
  899. if (!row.batchNo) {
  900. uni.showToast({ title: '请填写批次号', icon: 'none' });
  901. return;
  902. }
  903. if (!row.packingQuantity && row.packingQuantity !== 0) {
  904. uni.showToast({ title: '请填写数量', icon: 'none' });
  905. return;
  906. }
  907. if (!row.packingUnit) {
  908. uni.showToast({ title: '请选择单位', icon: 'none' });
  909. return;
  910. }
  911. if (!row.warehouseId) {
  912. uni.showToast({ title: '请选择仓库', icon: 'none' });
  913. return;
  914. }
  915. },
  916. // 物品批量保存前校验
  917. validateForm() {
  918. return new Promise((resolve, reject) => {
  919. for (let i = 0; i < this.productList.length; i++) {
  920. const row = this.productList[i];
  921. // 已保存的不需要校验
  922. if (row.isSave) continue;
  923. if (!row.batchNo) {
  924. uni.showToast({ title: `第${i + 1}行:请填写批次号`, icon: 'none' });
  925. reject(new Error('批次号必填'));
  926. return;
  927. }
  928. if (!row.packingQuantity && row.packingQuantity !== 0) {
  929. uni.showToast({ title: `第${i + 1}行:请填写数量`, icon: 'none' });
  930. reject(new Error('数量必填'));
  931. return;
  932. }
  933. if (!row.packingUnit) {
  934. uni.showToast({ title: `第${i + 1}行:请选择单位`, icon: 'none' });
  935. reject(new Error('单位必填'));
  936. return;
  937. }
  938. if (!row.warehouseId) {
  939. uni.showToast({ title: `第${i + 1}行:请选择仓库`, icon: 'none' });
  940. reject(new Error('仓库必填'));
  941. return;
  942. }
  943. }
  944. resolve();
  945. });
  946. },
  947. listSave(row, index) {
  948. // 必填项校验
  949. if (!row.batchNo) {
  950. uni.showToast({ title: '请填写批次号', icon: 'none' });
  951. return;
  952. }
  953. if (!row.packingQuantity && row.packingQuantity !== 0) {
  954. uni.showToast({ title: '请填写数量', icon: 'none' });
  955. return;
  956. }
  957. if (!row.packingUnit) {
  958. uni.showToast({ title: '请选择单位', icon: 'none' });
  959. return;
  960. }
  961. if (!row.warehouseId) {
  962. uni.showToast({ title: '请选择仓库', icon: 'none' });
  963. return;
  964. }
  965. // 判断单位和计量单位是否为不拆物料层规格
  966. let packingBoolen = !!this.getDict('不拆物料层规格', row.packingUnit)?.dictValue;
  967. let measureBoolen = !!this.getDict('不拆物料层规格', row.measureUnit)?.dictValue;
  968. let packingNum = 0;
  969. if (packingBoolen) {
  970. if (!row.isUnpack && row.packingUnit == '立方') {
  971. packingNum = 1;
  972. } else {
  973. let filterArr = row.packingSpecificationOption.filter((item) => {
  974. return item.packageUnit == row.packingUnit && item.packageUnit != item.conversionUnit;
  975. });
  976. if (filterArr?.length) {
  977. packingNum = Math.ceil(row.packingQuantity / filterArr[0].packageCell);
  978. }
  979. }
  980. }
  981. let measureNum = row.packingQuantity;
  982. let num = 0;
  983. if (measureBoolen) {
  984. let splitIndex = row.packingSpecificationOption.findIndex((item) =>
  985. item.conversionUnit == row.packingUnit && item.packageUnit != item.conversionUnit
  986. );
  987. for (; splitIndex > 1; splitIndex--) {
  988. measureNum = this.$math.format(measureNum * row.packingSpecificationOption[splitIndex].packageCell, 14);
  989. }
  990. } else {
  991. if (row.packingSpecificationOption[1]?.packageCell) {
  992. num = Math.ceil(row.measureQuantity / row.packingSpecificationOption[1]?.packageCell);
  993. } else {
  994. num = row.packingQuantity;
  995. }
  996. }
  997. if (row.packingSpecificationLabel?.length < 1) {
  998. uni.showToast({ title: '请到主数据维护包装组信息!', icon: 'none' });
  999. return;
  1000. }
  1001. // 不拆包
  1002. if (!row.isUnpack) {
  1003. if (row.packingUnit != row.measureUnit) {
  1004. getAssetNum([{ assetCode: row.categoryCode + row.index, batchNum: row.batchNo, num: row.packingQuantity }]).then(() => {});
  1005. } else {
  1006. getAssetNum([{ assetCode: row.categoryCode + row.index, batchNum: row.batchNo, num: 0 }]).then(() => {});
  1007. }
  1008. } else {
  1009. if (!packingNum) {
  1010. if (row.packingUnitId) {
  1011. let splitIndex = row.packingSpecificationOption.findIndex((item) => item.id == row.packingUnitId);
  1012. if (splitIndex == 0) {
  1013. packingNum = Math.ceil(row.measureQuantity / row.packingSpecificationOption[1]?.packageCell);
  1014. }
  1015. if (splitIndex == 1) {
  1016. packingNum = row.packingQuantity;
  1017. }
  1018. for (; splitIndex > 1; splitIndex--) {
  1019. packingNum = Math.ceil(row.packingQuantity * row.packingSpecificationOption[splitIndex].packageCell);
  1020. }
  1021. } else {
  1022. packingNum = Math.ceil(row.measureQuantity / row.packingSpecificationOption[1]?.packageCell);
  1023. }
  1024. }
  1025. getAssetNum([{ assetCode: row.categoryCode + row.index, batchNum: row.batchNo, num: packingNum }]).then(() => {});
  1026. }
  1027. this.$set(this.productList[index], 'isSave', true);
  1028. this.$set(this.productList[index], 'warehouseId', row.warehouseId);
  1029. this.$set(this.productList[index], 'warehouseName', row.warehouseName);
  1030. this.$set(this.productList[index], 'warehouseIds', row.warehouseId);
  1031. this.$set(this.productList[index], 'warehouseNames', row.warehouseName);
  1032. },
  1033. editProductList(row, index) {
  1034. this.$set(this.productList[index], 'isSave', false);
  1035. },
  1036. deleteProductList(row, index) {
  1037. uni.showModal({
  1038. title: '提示',
  1039. content: '确定删除该产品吗?',
  1040. success: (res) => {
  1041. if (res.confirm) {
  1042. this.productList.splice(index, 1);
  1043. }
  1044. }
  1045. });
  1046. },
  1047. saveProductList(row, index) {
  1048. this.listSave(row, index);
  1049. },
  1050. addStock() {
  1051. this.addProduct();
  1052. },
  1053. // 入库
  1054. async getReturnStorage() {
  1055. if (this.productList.length <= 0) {
  1056. uni.showToast({ title: '请先添加产品信息', icon: 'none' });
  1057. return;
  1058. }
  1059. let boolen = this.productList.every((item) => item.isSave);
  1060. if (!boolen) {
  1061. uni.showToast({ title: '请先保存所有产品信息', icon: 'none' });
  1062. return;
  1063. }
  1064. if (this.isShowPackage) {
  1065. const userNameLength = this.productList.filter(
  1066. (item) => !item.unpackUserName
  1067. ).length;
  1068. const packgeLength = this.productList.filter(
  1069. (item) => !item.ifPackageOk
  1070. ).length;
  1071. if (userNameLength || packgeLength) {
  1072. uni.showToast({ title: '请先填写拆包装责任人和包装完好与否', icon: 'none' });
  1073. return;
  1074. }
  1075. }
  1076. // 处理包装数据
  1077. let _packingList = [];
  1078. _packingList = this.packingList.map((packingItem) => {
  1079. let _taskId = null;
  1080. let _workOrderId = null;
  1081. // if ([1].includes(this.formData.bizType)) {
  1082. // _workOrderId = this.detailList[0]?.workOrderId;
  1083. // _taskId = this.detailList[0]?.taskId;
  1084. // } else {
  1085. _workOrderId = this.form.productList[0]?.workOrderId;
  1086. _taskId = this.form.productList[0]?.taskId;
  1087. // }
  1088. // if (packingItem.modelKey) {
  1089. // packingItem.modelKey = packingItem.modelKey.toString();
  1090. // }
  1091. // if (packingItem.colorKey) {
  1092. // packingItem.colorKey = packingItem.colorKey.toString();
  1093. // }
  1094. return {
  1095. ...packingItem,
  1096. workOrderId: _workOrderId,
  1097. taskId: _taskId,
  1098. outsourceBatchNo: this.form.productList[0]?.batchNo,
  1099. outsourceCode: this.form.productList[0]?.sourceCode,
  1100. // materialDetailList: this.materialList.filter(
  1101. // (item) => item.parentIndex === packingItem.index
  1102. // )
  1103. };
  1104. });
  1105. // 处理产品数据
  1106. this.productList = this.productList.map((productItem) => {
  1107. // if (productItem.modelKey) {
  1108. // productItem.modelKey = productItem.modelKey.toString();
  1109. // }
  1110. // if (productItem.colorKey) {
  1111. // productItem.colorKey = productItem.colorKey.toString();
  1112. // }
  1113. return {
  1114. ...productItem,
  1115. outInDetailRecordRequestList: _packingList.filter(
  1116. (item) => item.parentIndex === productItem.index
  1117. )
  1118. };
  1119. });
  1120. this.formData.outInDetailList = this.productList;
  1121. let obj = uni.$u.deepClone(this.formData);
  1122. // 处理物品类型assetType
  1123. obj.extInfo.assetType = obj.extInfo.assetType.join(',');
  1124. obj.extInfo.documentSource = this.formData.sourceBizNo;
  1125. obj.extInfo.deptName = this.formData.extInfo.deptName;
  1126. obj.extInfo.supplierName = this.form.supplierName;
  1127. obj.extInfo.deliveryPhone = this.formData.extInfo.deliveryPhone;
  1128. // 处理仓库id
  1129. let warehouseId = [];
  1130. let warehouseName = [];
  1131. let warehouseIds = this.productList.map((item) => item.warehouseIds).flat();
  1132. let warehouseNames = this.productList.map((item) => item.warehouseNames).flat();
  1133. warehouseIds.forEach((item, index) => {
  1134. if (!warehouseId.includes(item)) {
  1135. warehouseId.push(item);
  1136. warehouseName.push(warehouseNames[index]);
  1137. }
  1138. });
  1139. obj.warehouseIds = warehouseId;
  1140. obj.warehouseNames = warehouseName;
  1141. obj._packingList = _packingList;
  1142. const isVerifyData = await isVerifyRepeatIsStock({
  1143. categoryCodes: this.productList.map((item) => item.categoryCode),
  1144. batchNos: this.productList.map((item) => item.batchNo)
  1145. });
  1146. return new Promise((resolve, reject) => {
  1147. if (isVerifyData?.length) {
  1148. uni.showModal({
  1149. title: '提示',
  1150. content: `当前批次:${isVerifyData[0].batchNo},物品${isVerifyData
  1151. .map((item) => item.categoryName)
  1152. .join(',')}已有入库记录,是否继续入库!`,
  1153. confirmText: '是',
  1154. cancelText: '否',
  1155. success: (res) => {
  1156. if (res.confirm) {
  1157. resolve(obj);
  1158. } else {
  1159. resolve(false);
  1160. }
  1161. }
  1162. });
  1163. } else {
  1164. resolve(obj);
  1165. }
  1166. });
  1167. },
  1168. // 获取表数据
  1169. getTableValue() {
  1170. return new Promise(async (resolve, reject) => {
  1171. try {
  1172. const returnStorageData = await this.getReturnStorage();
  1173. resolve({
  1174. form: this.form,
  1175. returnStorageData,
  1176. });
  1177. } catch(e) {
  1178. reject(e);
  1179. }
  1180. });
  1181. },
  1182. // 单位选择变化
  1183. onPackingUnitChange(e, row, index) {
  1184. const val = e.detail.value;
  1185. const item = row.packingSpecificationOption[val];
  1186. if (item) {
  1187. row.packingUnitId = item.id;
  1188. row.packingUnit = item.conversionUnit;
  1189. this.computeNum(row, index);
  1190. }
  1191. },
  1192. // 包装完好选择变化
  1193. onPackageOkChange(e, row) {
  1194. const val = e.detail.value;
  1195. row.ifPackageOkIndex = val;
  1196. row.ifPackageOk = this.packageOkOptions[val].value;
  1197. row.ifPackageOkLabel = this.packageOkOptions[val].label;
  1198. },
  1199. // 仓库选择变化
  1200. onWarehouseChange(e, row) {
  1201. const val = e.detail.value;
  1202. const item = this.warehouseListOption[val];
  1203. if (item) {
  1204. row.warehouseId = item.id;
  1205. row.warehouseName = item.name;
  1206. row.warehouseIndex = val;
  1207. }
  1208. },
  1209. // 供应商选择变化
  1210. onSupplierChange(e, row) {
  1211. const val = e.detail.value;
  1212. const item = row.supplierListOptions[val];
  1213. if (item) {
  1214. row.supplierId = item.id;
  1215. row.supplierName = item.name;
  1216. row.supplierCode = item.serialNo;
  1217. }
  1218. },
  1219. // 打开颜色选择器
  1220. openColorPicker(row, index) {
  1221. this.currentColorRow = row;
  1222. this.currentColorIndex = index;
  1223. // 获取已选中的颜色 ID 列表
  1224. const selectedIds = row.colorKey ? row.colorKey.split(',') : [];
  1225. // 初始化选择器
  1226. this.$nextTick(() => {
  1227. const picker = this.$refs.colorTreePicker;
  1228. picker._initTree();
  1229. // 设置已选中的项
  1230. if (selectedIds.length > 0) {
  1231. picker.treeList.forEach(item => {
  1232. if (selectedIds.includes(item.id)) {
  1233. item.checkStatus = 2;
  1234. item.orCheckStatus = 2;
  1235. }
  1236. });
  1237. }
  1238. picker._show();
  1239. });
  1240. },
  1241. // 颜色选择确认
  1242. onColorConfirm(data, name, allList) {
  1243. console.log('selectedList~~~', allList)
  1244. if (allList && allList.length > 0) {
  1245. const ids = allList.map(item => item.id).join(',');
  1246. const names = allList.map(item => item.name).join(',');
  1247. // 使用 $set 确保数据更新到 productList 中
  1248. this.$set(this.productList[this.currentColorIndex], 'colorKey', ids);
  1249. // 同时更新 currentColorRow 引用
  1250. this.currentColorRow.colorKey = ids;
  1251. } else {
  1252. this.$set(this.productList[this.currentColorIndex], 'colorKey', '');
  1253. this.currentColorRow.colorKey = '';
  1254. }
  1255. },
  1256. // 打开机型选择器
  1257. openModelPicker(row, index) {
  1258. this.currentModelRow = row;
  1259. this.currentModelIndex = index;
  1260. // 获取已选中的机型 ID 列表
  1261. const selectedIds = row.modelKey ? row.modelKey.split(',') : [];
  1262. // 初始化选择器
  1263. this.$nextTick(() => {
  1264. const picker = this.$refs.modelTreePicker;
  1265. picker._initTree();
  1266. // 设置已选中的项
  1267. if (selectedIds.length > 0) {
  1268. picker.treeList.forEach(item => {
  1269. if (selectedIds.includes(item.id)) {
  1270. item.checkStatus = 2;
  1271. item.orCheckStatus = 2;
  1272. }
  1273. });
  1274. }
  1275. picker._show();
  1276. });
  1277. },
  1278. // 机型选择确认
  1279. onModelConfirm(data, name, allList) {
  1280. if (allList && allList.length > 0) {
  1281. const ids = allList.map(item => item.id).join(',');
  1282. const names = allList.map(item => item.name).join(',');
  1283. // 使用 $set 确保数据更新到 productList 中
  1284. this.$set(this.productList[this.currentModelIndex], 'modelKey', ids);
  1285. // 同时更新 currentModelRow 引用
  1286. this.currentModelRow.modelKey = ids;
  1287. } else {
  1288. this.$set(this.productList[this.currentModelIndex], 'modelKey', '');
  1289. this.currentModelRow.modelKey = '';
  1290. }
  1291. },
  1292. // 日期选择变化
  1293. onDateChange(e, row, field) {
  1294. row[field] = e.detail.value;
  1295. },
  1296. //入库明细删除
  1297. listDel(row, index) {
  1298. this.productList.splice(index, 1);
  1299. this.deletePackingAndMaterial(row);
  1300. },
  1301. // 根据产品信息删除包装和物料
  1302. deletePackingAndMaterial(row) {
  1303. // 删除包装(去掉不相同的包装)
  1304. this.packingList = this.packingList.filter(
  1305. (item) => item.parentIndex !== row.index
  1306. );
  1307. this.showPackingList = this.showPackingList.filter(
  1308. (item) => item.parentIndex !== row.index
  1309. );
  1310. this.pickingPageNum = Math.ceil(
  1311. this.showPackingList.length / this.pageSize
  1312. );
  1313. // 删除物料(获取相同物料)
  1314. // let packingIndexs = this.packingList.map((item) => item.index);
  1315. // this.materialList = this.materialList.filter((item) =>
  1316. // packingIndexs.includes(item.parentIndex)
  1317. // // );
  1318. // this.showMaterialList = this.showMaterialList.filter((item) =>
  1319. // packingIndexs.includes(item.parentIndex)
  1320. // );
  1321. // this.materielPageNum = Math.ceil(
  1322. // this.showMaterialList.length / this.pageSize
  1323. // );
  1324. },
  1325. // 产品批量保存
  1326. async listSaveArrs() {
  1327. this.validateForm()
  1328. .then(async () => {
  1329. // 批量获取包装编码并处理
  1330. let packingCodePrams = this.productList.map((row) => {
  1331. // 判断单位和计量单位是否为不拆物料层规格
  1332. let packingBoolen = !!this.getDict(
  1333. '不拆物料层规格',
  1334. row.packingUnit
  1335. ).dictValue;
  1336. let measureBoolen = !!this.getDict(
  1337. '不拆物料层规格',
  1338. row.measureUnit
  1339. ).dictValue;
  1340. let num = 0;
  1341. if (packingBoolen) {
  1342. let filterArr = row.packingSpecificationOption.filter(
  1343. (item) => {
  1344. return (
  1345. item.packageUnit == row.packingUnit &&
  1346. item.packageUnit != item.conversionUnit
  1347. );
  1348. }
  1349. );
  1350. num = Math.ceil(row.packingQuantity / filterArr[0].packageCell);
  1351. }
  1352. if (row.isSave) {
  1353. return {};
  1354. } else {
  1355. // 处理单位为KG类的情况
  1356. if (packingBoolen) {
  1357. return {
  1358. assetCode: row.categoryCode + row.index,
  1359. batchNum: row.batchNo,
  1360. num
  1361. };
  1362. } else {
  1363. if (row.isUnpack == 1) {
  1364. if (measureBoolen) {
  1365. // 处理单位不为KG类,计量单位为KG类的情况
  1366. let num = row.packingQuantity;
  1367. let splitIndex = row.packingSpecificationOption.findIndex(
  1368. (item) =>
  1369. item.conversionUnit == row.packingUnit &&
  1370. item.packageUnit != item.conversionUnit
  1371. );
  1372. for (; splitIndex > 1; splitIndex--) {
  1373. num = this.$math.format(
  1374. num *
  1375. row.packingSpecificationOption[splitIndex]
  1376. .packageCell,
  1377. 14
  1378. );
  1379. }
  1380. return {
  1381. assetCode: row.categoryCode + row.index,
  1382. batchNum: row.batchNo,
  1383. num
  1384. };
  1385. } else {
  1386. // 处理拆包到最小包装单元数量的情况
  1387. return {
  1388. assetCode: row.categoryCode + row.index,
  1389. batchNum: row.batchNo,
  1390. num: row.measureQuantity
  1391. };
  1392. }
  1393. } else {
  1394. return {
  1395. assetCode: row.categoryCode + row.index,
  1396. batchNum: row.batchNo,
  1397. num
  1398. };
  1399. }
  1400. }
  1401. }
  1402. });
  1403. console.log('packingCodePrams', packingCodePrams);
  1404. let filterPackingCodePrams = packingCodePrams.filter(
  1405. (item) => item.assetCode
  1406. );
  1407. console.log('filterPackingCodePrams', filterPackingCodePrams);
  1408. let { data } = await getAssetNum(filterPackingCodePrams);
  1409. let packingCodeList = [];
  1410. packingCodePrams.forEach((item, index) => {
  1411. packingCodeList[index] = data.filter(
  1412. (ite) => ite.assetCode == item.assetCode
  1413. );
  1414. });
  1415. // 批量生成包装
  1416. this.productList.map((row, index) => {
  1417. if (!row.isSave) {
  1418. this.generateWrappers(row, index, packingCodeList[index]);
  1419. this.$set(this.productList[index], 'isSave', true);
  1420. }
  1421. });
  1422. // 加载虚拟列表数据(分页)
  1423. // this.pickingFetchData();
  1424. // this.materielFetchData();
  1425. })
  1426. .catch((err) => {
  1427. console.log(err);
  1428. });
  1429. },
  1430. // 生成包装
  1431. generateWrappers(row, productIndex, packingCodeList) {
  1432. console.log(packingCodeList, 'packingCodeList', row.measureType);
  1433. if (!row.measureType)
  1434. return uni.showToast({
  1435. title: '请到主数据维计量类型!',
  1436. icon: 'none'
  1437. });
  1438. console.log('包装数据--------', row);
  1439. // console.log('包装规格----', row.packingSpecificationOption);
  1440. console.log('计量单位----', row.measureUnit);
  1441. let packingList = [];
  1442. // let obj = this.getNowDate();
  1443. let productionDate = row.detailProductionDate || '';
  1444. let purchaseDate = row.detailPurchaseDate || '';
  1445. let expireDate = row.detailExpireDate || '';
  1446. console.log(expireDate, 'expireDate');
  1447. console.log(
  1448. this.formData.bizType,
  1449. 'bizTypebizTypebizTypebizTypebizTypebizTypebizTypebizTypebizTypebizTypebizType'
  1450. );
  1451. if (this.formData.bizType == '1') {
  1452. // 生产入库
  1453. productionDate = this.getNowDate();
  1454. // this.curDateType = 'productionDate';
  1455. }
  1456. // 判断单位和计量单位是否为不拆物料层规格
  1457. let packingBoolen = !!this.getDict('不拆物料层规格', row.packingUnit).dictValue;
  1458. let measureBoolen = !!this.getDict('不拆物料层规格', row.measureUnit).dictValue;
  1459. let num = row.packingQuantity;
  1460. let filterArr = [];
  1461. // 处理单位为KG类的情况
  1462. if (packingBoolen) {
  1463. console.log(
  1464. packingBoolen,
  1465. 'packingBoolenpackingBoolenpackingBoolenpackingBoolenpackingBoolenpackingBoolen'
  1466. );
  1467. if (!row.isUnpack && row.packingUnit == '立方') {
  1468. num = 1;
  1469. } else {
  1470. filterArr = row.packingSpecificationOption.filter((item) => {
  1471. return (
  1472. item.packageUnit == row.packingUnit &&
  1473. item.packageUnit != item.conversionUnit
  1474. );
  1475. });
  1476. num = Math.ceil(row.packingQuantity / filterArr[0]?.packageCell);
  1477. }
  1478. } else {
  1479. // if (row.isUnpack == 1) {
  1480. if (measureBoolen) {
  1481. // 处理单位不为KG类,计量单位为KG类的情况
  1482. let splitIndex = row.packingSpecificationOption.findIndex(
  1483. (item) =>
  1484. item.conversionUnit == row.packingUnit &&
  1485. item.packageUnit != item.conversionUnit
  1486. );
  1487. for (; splitIndex > 1; splitIndex--) {
  1488. num = this.$math.format(
  1489. num * row.packingSpecificationOption[splitIndex].packageCell,
  1490. 14
  1491. );
  1492. }
  1493. } else {
  1494. if (row.packingSpecificationOption[1]?.packageCell) {
  1495. num = Math.ceil(
  1496. row.measureQuantity /
  1497. row.packingSpecificationOption[1]?.packageCell
  1498. );
  1499. filterArr = row.packingSpecificationOption.filter((item) => {
  1500. return (
  1501. item.packageUnit == row.packingUnit &&
  1502. item.packageUnit != item.conversionUnit
  1503. );
  1504. });
  1505. }
  1506. }
  1507. }
  1508. console.log('num-----------', num);
  1509. for (let index = 0; index < packingCodeList.length; index++) {
  1510. let measureQuantity = 1;
  1511. let packingQuantity = 1;
  1512. let packingUnit = row.packingUnit;
  1513. // 处理单位为KG类,计算每桶KG值
  1514. if (packingBoolen) {
  1515. measureQuantity = Number(row.packingQuantity) > this.$math.format(filterArr[0].packageCell * (index + 1), 14) ? filterArr[0].packageCell : Numbe(row.packingQuantity) - this.$math.format(filterArr[0].packageCell * index, 14);
  1516. console.log(measureQuantity, 'measureQuantit1111y');
  1517. } else {
  1518. console.log('1 拆--------', measureBoolen);
  1519. //计量单位等于重量单位并且有总重 计量数量=总重/包装数
  1520. if (row.weightUnit == row.measureUnit && row.weight) {
  1521. measureQuantity = Math.trunc((row.weight / packingCodeList.length) * 10000) / 10000;
  1522. } else if (measureBoolen) {
  1523. let splitIndex = row.packingSpecificationOption.findIndex((item) =>
  1524. item.conversionUnit == row.packingUnit &&
  1525. item.packageUnit != item.conversionUnit
  1526. );
  1527. for (; splitIndex > 0; splitIndex--) {
  1528. measureQuantity = this.$math.format(
  1529. measureQuantity *
  1530. row.packingSpecificationOption[splitIndex].packageCell,
  1531. 14
  1532. );
  1533. }
  1534. } else {
  1535. measureQuantity = row.packingSpecificationOption[1].packageCell;
  1536. }
  1537. console.log(measureQuantity, 'measureQuantity');
  1538. }
  1539. let clientCode = '';
  1540. if (this.bizType == 2) {
  1541. clientCode = row?.customerMark;
  1542. } else if (this.bizType != 2) {
  1543. clientCode = row.extInfo?.clientCode;
  1544. }
  1545. console.log(filterArr[0], 'filterArr[0]');
  1546. let status = null;
  1547. if (row.qualityControl == 1) {
  1548. status = 0;
  1549. } else {
  1550. status = 2;
  1551. }
  1552. let item = {
  1553. index: row.index + '-' + index, // 包装索引
  1554. warehouseId: row.warehouseId, // 仓库id
  1555. warehouseName: row.warehouseName, // 仓库名称
  1556. categoryName: row.categoryName, // 产品名称
  1557. categoryCode: row.categoryCode, // 产品编码
  1558. categoryModel: row.categoryModel, // 物品型号
  1559. specification: row.specification, // 规格
  1560. supplierCode: row.supplierCode, // 供应商编码
  1561. supplierName: row.supplierName, // 供应商名称
  1562. brandNum: row.brandNum, // 牌号
  1563. parentIndex: row.index, // 产品索引
  1564. batchNo: row.batchNo, // 批次号
  1565. packageNo: packingCodeList[index]?.onlyCode, // 包装编码
  1566. packingQuantity: packingQuantity, // 包装数量
  1567. modelKey: row.modelKey, // 机型
  1568. colorKey: row.colorKey, //颜色
  1569. measureQuantity: measureQuantity, // 计量数量
  1570. measureUnit: row.isUnpack
  1571. ? measureBoolen
  1572. ? row.packingSpecificationOption[1]
  1573. ? row.packingSpecificationOption[1].packageUnit
  1574. : row.packingSpecificationOption[0].packageUnit
  1575. : row.measureUnit
  1576. : row.measureUnit, // 计量单位
  1577. weight: 0, // 重量
  1578. packingSpecificationOption: row.packingSpecificationOption, // 包装规格
  1579. weightUnit: row.weightUnit, // 重量单位
  1580. netWeight: row.netWeight, // 净重
  1581. barcodes: '', // 发货条码
  1582. clientCode: clientCode, // 客户代号
  1583. materielDesignation: row.extInfo ? row.extInfo.materielCode : '', // 物料代号
  1584. engrave: '', // 刻码
  1585. isUnpack: row.isUnpack, // 是否允许拆包
  1586. productionDate: productionDate, // 生产日期
  1587. purchaseDate: purchaseDate, // 采购时间
  1588. expireDate: expireDate, //失效日期
  1589. result: 1, // 结果(1合格 2不合格)
  1590. qualityControl: row.qualityControl,
  1591. status: status // 状态(0=未质检 1待检 2已检)
  1592. };
  1593. if (row.isUnpack) {
  1594. // 第二层条件: packingBoolen
  1595. if (packingBoolen) {
  1596. // 空值保护: 确保 filterArr[0] 存在
  1597. item.packingUnit = row.packingSpecificationOption[1].conversionUnit;
  1598. } else {
  1599. // 第三层条件: measureBoolen
  1600. if (measureBoolen) {
  1601. // 处理 packingSpecificationOption 的索引
  1602. const option =
  1603. row.packingSpecificationOption?.[1] ||
  1604. row.packingSpecificationOption?.[0];
  1605. item.packingUnit = option?.conversionUnit;
  1606. } else {
  1607. item.packingUnit =
  1608. row.packingSpecificationOption[1].conversionUnit;
  1609. }
  1610. }
  1611. }
  1612. let outBoolen = !!this.getDict('不拆物料层规格', item.measureUnit).dictValue;
  1613. //计量单位等于重量单位
  1614. if (row.weightUnit == row.measureUnit) {
  1615. item.weight = item.measureQuantity
  1616. ? Number(item.measureQuantity)
  1617. : 0;
  1618. } else if (outBoolen) {
  1619. // 计量单位为KG类,直接替换
  1620. item.weight = item.measureQuantity
  1621. ? Number(item.measureQuantity)
  1622. : 0;
  1623. } else {
  1624. console.log('计量单位为不为KG类======================');
  1625. // 计量单位为不为KG类,重新统计计算
  1626. let inBoolen = !!this.getDict('不拆物料层规格', item.packingSpecificationOption[0].packageUnit).dictValue;
  1627. let startIndex = item.packingSpecificationOption.findIndex(
  1628. (ite) => {
  1629. return (
  1630. item.measureUnit == ite.packingUnit &&
  1631. ite.packingUnit != ite.conversionUnit
  1632. );
  1633. }
  1634. );
  1635. let endIndex = item.packingSpecificationOption.findIndex(
  1636. (ite) => item.packingUnit == ite.conversionUnit
  1637. );
  1638. if (measureBoolen) {
  1639. let total = item.packingQuantity ? Number(item.packingQuantity) : 0;
  1640. for (; startIndex < endIndex; endIndex--) {
  1641. total = this.$math.format(item.packingSpecificationOption[endIndex].packageCell * total, 14);
  1642. }
  1643. if (inBoolen) {
  1644. // 第二层为KG类
  1645. item.weight = total ? Number(total) : 0;
  1646. } else {
  1647. // 第二层不为KG类
  1648. item.weight = this.$math.format(total * item.netWeight, 14);
  1649. }
  1650. } else if (!measureBoolen) {
  1651. if (inBoolen) {
  1652. // 第二层为KG类
  1653. item.weight = item.measureQuantity ? Number(item.measureQuantity) : 0;
  1654. } else {
  1655. // 第二层不为KG类
  1656. if (row.singleWeight && item.measureQuantity) {
  1657. item.weight = Number(item.measureQuantity) * Number(row.singleWeight);
  1658. } else {
  1659. item.weight = 0;
  1660. }
  1661. }
  1662. }
  1663. }
  1664. packingList.push(item);
  1665. console.log(
  1666. packingList,
  1667. 'packingList!!!!!!!!!!!!!!!!!!拆'
  1668. );
  1669. }
  1670. // 单独点击保存并插入对应位置(包装)
  1671. if (productIndex == 0) {
  1672. this.packingList.splice(productIndex, 0, ...packingList);
  1673. } else {
  1674. let packingIndex = this.packingList.findLastIndex(
  1675. (item) =>
  1676. item.parentIndex == this.productList[productIndex - 1].index
  1677. );
  1678. this.packingList.splice(packingIndex + 1, 0, ...packingList);
  1679. }
  1680. let remainder = 0;
  1681. if (row.weightUnit != row.measureUnit) {
  1682. remainder =
  1683. row.measureQuantity %
  1684. row.packingSpecificationOption[1]?.packageCell;
  1685. }
  1686. if (remainder > 0) {
  1687. let onlyCode = packingCodeList[packingCodeList.length - 1]?.onlyCode;
  1688. let index = this.packingList.findIndex(
  1689. (packingItem) => packingItem.packageNo == onlyCode
  1690. );
  1691. this.$set(this.packingList[index], 'measureQuantity', remainder);
  1692. if (row.singleWeight) {
  1693. this.$set(
  1694. this.packingList[index],
  1695. 'weight',
  1696. row.singleWeight * remainder
  1697. );
  1698. }
  1699. }
  1700. },
  1701. }
  1702. }
  1703. </script>
  1704. <style scoped>
  1705. .add {
  1706. width: 96rpx;
  1707. height: 96rpx;
  1708. border-radius: 48rpx;
  1709. background: #3c9cff;
  1710. position: fixed;
  1711. bottom: 100rpx;
  1712. right: 24rpx;
  1713. display: flex;
  1714. align-items: center;
  1715. justify-content: center;
  1716. z-index: 99;
  1717. }
  1718. /* 产品卡片样式 */
  1719. .product-card {
  1720. background: #fff;
  1721. margin: 20rpx;
  1722. border-radius: 12rpx;
  1723. padding: 24rpx;
  1724. box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.08);
  1725. }
  1726. .card-header {
  1727. display: flex;
  1728. justify-content: space-between;
  1729. align-items: center;
  1730. padding-bottom: 20rpx;
  1731. border-bottom: 1rpx solid #eee;
  1732. margin-bottom: 20rpx;
  1733. }
  1734. .product-name {
  1735. font-size: 28rpx;
  1736. font-weight: bold;
  1737. color: #333;
  1738. }
  1739. .product-code {
  1740. font-size: 26rpx;
  1741. color: #333;
  1742. }
  1743. .card-body {
  1744. padding: 0;
  1745. }
  1746. .info-row {
  1747. display: flex;
  1748. justify-content: space-between;
  1749. align-items: center;
  1750. padding: 16rpx 0;
  1751. border-bottom: 1rpx solid #f5f5f5;
  1752. }
  1753. .info-row:last-child {
  1754. border-bottom: none;
  1755. }
  1756. .info-label {
  1757. font-size: 28rpx;
  1758. color: #666;
  1759. min-width: 160rpx;
  1760. }
  1761. .info-value {
  1762. font-size: 28rpx;
  1763. color: #333;
  1764. text-align: right;
  1765. flex: 1;
  1766. }
  1767. .red-text {
  1768. color: #ff0000 !important;
  1769. }
  1770. .card-footer {
  1771. margin-top: 20rpx;
  1772. padding-top: 20rpx;
  1773. border-top: 1rpx solid #eee;
  1774. }
  1775. .action-buttons {
  1776. display: flex;
  1777. gap: 20rpx;
  1778. }
  1779. /* 包装明细样式 */
  1780. .packing-section {
  1781. margin-top: 40rpx;
  1782. padding: 0 20rpx;
  1783. }
  1784. .section-title {
  1785. font-size: 32rpx;
  1786. font-weight: bold;
  1787. color: #333;
  1788. padding: 20rpx 0;
  1789. }
  1790. .packing-card {
  1791. background: #fff;
  1792. border-radius: 12rpx;
  1793. padding: 24rpx;
  1794. margin-bottom: 20rpx;
  1795. box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.08);
  1796. }
  1797. /* 批量操作按钮 */
  1798. .batch-actions {
  1799. display: flex;
  1800. gap: 20rpx;
  1801. padding: 20rpx;
  1802. background: #f8f8f8;
  1803. margin-bottom: 20rpx;
  1804. }
  1805. /* 卡片序号 */
  1806. .card-index {
  1807. font-size: 24rpx;
  1808. color: #999;
  1809. background: #f0f0f0;
  1810. padding: 4rpx 16rpx;
  1811. border-radius: 20rpx;
  1812. }
  1813. /* 编辑行样式 */
  1814. .edit-row {
  1815. background: #fafafa;
  1816. }
  1817. /* 必填标识 */
  1818. .required {
  1819. color: #ff0000;
  1820. }
  1821. /* 输入框样式 */
  1822. .info-input {
  1823. flex: 1;
  1824. text-align: right;
  1825. font-size: 28rpx;
  1826. color: #333;
  1827. padding: 8rpx 0;
  1828. }
  1829. /* picker选择器样式 */
  1830. .info-picker {
  1831. flex: 1;
  1832. /* text-align: right; */
  1833. }
  1834. .picker-value {
  1835. font-size: 28rpx;
  1836. color: #333;
  1837. padding: 16rpx 32rpx 16rpx 16rpx;
  1838. /* background: #f0f0f0; */
  1839. border-radius: 8rpx;
  1840. display: inline-block;
  1841. min-width: 160rpx;
  1842. /* text-align: center; */
  1843. position: relative;
  1844. width: 100%;
  1845. border: 1rpx solid #dadbde;
  1846. }
  1847. .picker-value::after {
  1848. content: '';
  1849. position: absolute;
  1850. right: 8rpx;
  1851. top: 50%;
  1852. transform: translateY(-50%);
  1853. border: 8rpx solid transparent;
  1854. border-top-color: #666;
  1855. }
  1856. .picker-value.placeholder {
  1857. color: #999;
  1858. /* background: #e8e8e8; */
  1859. }
  1860. /* 仓库选择样式 */
  1861. .warehouse-select {
  1862. flex: 1;
  1863. text-align: right;
  1864. padding: 8rpx 0;
  1865. }
  1866. /* 多选组件样式 */
  1867. .multi-select-container {
  1868. flex: 1;
  1869. display: flex;
  1870. flex-wrap: wrap;
  1871. gap: 16rpx;
  1872. padding: 8rpx 0;
  1873. }
  1874. .multi-select-item {
  1875. display: flex;
  1876. align-items: center;
  1877. gap: 8rpx;
  1878. background: #f0f0f0;
  1879. padding: 8rpx 16rpx;
  1880. border-radius: 8rpx;
  1881. font-size: 24rpx;
  1882. }
  1883. .multi-select-label {
  1884. color: #333;
  1885. }
  1886. /* 颜色选择器触发器样式 */
  1887. .color-picker-trigger {
  1888. flex: 1;
  1889. display: flex;
  1890. justify-content: flex-end;
  1891. }
  1892. </style>