Forráskód Böngészése

Merge branch 'master' of http://110.41.163.243:9980/kd-aiot/aiot-app

yusheng 1 hónapja
szülő
commit
8d0ccfe035
2 módosított fájl, 365 hozzáadás és 229 törlés
  1. 2 1
      enum/dict.js
  2. 363 228
      pages/home/wt/components/purchaseReceiving/taskForm.vue

+ 2 - 1
enum/dict.js

@@ -13,7 +13,8 @@ export default {
   计量单位: "measuring_uint",
   销售类型: "order_type",
   记录规则类型: 'record_sheet',
-  表计类型: 'meter_type'
+  表计类型: 'meter_type',
+  不拆物料层规格: 'material_layer',
 
 };
 export const numberList = [

+ 363 - 228
pages/home/wt/components/purchaseReceiving/taskForm.vue

@@ -84,7 +84,7 @@
 			<!-- 批量操作按钮 -->
 			<view class="batch-actions" v-if="productList.length > 0">
 				<u-button type="success" plain size="small" text="批量保存" @click="listSaveArrs" :disabled="packingList.length > 0"></u-button>
-				<picker v-if="packingList.length === 0" class="info-picker" :value="warehouseIndex" :range="warehouseListOption" range-key="name" @change="(e) => handleWareHouse(e, productList)">
+				<picker v-if="packingList.length === 0" class="info-picker" :value="warehouseIndex" :range="warehouseListOption" range-key="name" @change="handleWareHouse">
 					<u-button type="success" plain size="small" text="批量选择仓库" v-if="packingList.length === 0"></u-button>
 				</picker>
 			</view>
@@ -123,7 +123,7 @@
 						<!-- 包装完好与否 -->
 						<view class="info-row edit-row" v-if="isShowPackage">
 							<text class="info-label">包装完好 <text class="required">*</text></text>
-							<picker v-if="!row.isSave" class="info-picker" :value="row.ifPackageOkIndex" :range="packageOkOptions" range-key="label" @change="(e) => onPackageOkChange(e, row)">
+							<picker v-if="!row.isSave" class="info-picker" :value="row.ifPackageOkIndex" :range="packageOkOptions" range-key="label" @change="(e) => onPackageOkChange(e, index)">
 								<view class="picker-value">{{ row.ifPackageOkLabel || '请选择' }}</view>
 							</picker>
 							<text v-else class="info-value">{{ row.ifPackageOk == 1 ? '是' : row.ifPackageOk == 0 ? '否' : '-' }}</text>
@@ -174,7 +174,7 @@
 						<!-- 仓库 - 必填 -->
 						<view class="info-row edit-row">
 							<text class="info-label">仓库 <text class="required">*</text></text>
-							<picker v-if="!row.isSave" class="info-picker" :value="row.warehouseIndex" :range="warehouseListOption" range-key="name" @change="(e) => onWarehouseChange(e, row)">
+							<picker v-if="!row.isSave" class="info-picker" :value="row.warehouseIndex" :range="warehouseListOption" range-key="name" @change="(e) => onWarehouseChange(e, index)">
 								<view class="picker-value">{{ row.warehouseName || '请选择仓库' }}</view>
 							</picker>
 							<text v-else class="info-value" :class="{ 'red-text': !row.warehouseName }">{{ row.warehouseName || '请选择仓库' }}</text>
@@ -182,7 +182,7 @@
 						<!-- 供应商 -->
 						<view class="info-row edit-row">
 							<text class="info-label">供应商</text>
-							<picker v-if="!row.isSave" class="info-picker" :value="row.supplierIndex" :range="row.supplierListOptions" range-key="name" @change="(e) => onSupplierChange(e, row)">
+							<picker v-if="!row.isSave" class="info-picker" :value="row.supplierIndex" :range="row.supplierListOptions" range-key="name" @change="(e) => onSupplierChange(e, index)">
 								<view class="picker-value">{{ row.supplierName || '请选择供应商' }}</view>
 							</picker>
 							<text v-else class="info-value">{{ row.supplierName || '-' }}</text>
@@ -262,10 +262,8 @@
 		<view class="tab-content" v-show="curNow===4">
 			<!-- 包装明细 -->
 			<view v-if="showPackingList.length > 0" class="packing-section">
-				<view class="section-title">
-					<text>包装明细</text>
-				</view>
-				<view class="packing-card" v-for="(item, index) in showPackingList" :key="'pkg-' + index">
+				<view class="packing-card" v-for="(item, idx) in showPackingList" :key="'pkg-' + idx">
+					<!-- <view class="card_title">包装 {{ idx + 1 }}</view> -->
 					<view class="info-row">
 						<text class="info-label">编码</text>
 						<text class="info-value">{{ item.categoryCode || '-' }}</text>
@@ -284,35 +282,100 @@
 					</view>
 					<view class="info-row">
 						<text class="info-label">包装数量</text>
-						<text class="info-value">{{ item.packingQuantity || '0' }} {{ item.packingUnit || '' }}</text>
+						<text class="info-value">{{ formatPackingValue(item.packingQuantity, item.packingUnit) }}</text>
 					</view>
-					<view class="info-row">
+					<view class="info-row edit-row">
 						<text class="info-label">计量数量</text>
-						<text class="info-value">{{ item.measureQuantity || '0' }} {{ item.measureUnit || '' }}</text>
+						<u--input class="info-input" type="digit" v-model="item.measureQuantity" placeholder="请输入计量数量" />
+					</view>
+					<view class="info-row">
+						<text class="info-label">计量单位</text>
+						<text class="info-value">{{ item.measureUnit || '-' }}</text>
 					</view>
 					<view class="info-row">
 						<text class="info-label">仓库</text>
 						<text class="info-value">{{ item.warehouseName || '-' }}</text>
 					</view>
-					<view class="info-row">
+					<view class="info-row edit-row">
 						<text class="info-label">物料代号</text>
-						<text class="info-value">{{ item.materielDesignation || '-' }}</text>
+						<u--input class="info-input" type="text" v-model="item.materielDesignation" placeholder="请输入物料代号" />
 					</view>
-					<view class="info-row">
+					<view class="info-row edit-row">
 						<text class="info-label">客户代号</text>
-						<text class="info-value">{{ item.clientCode || '-' }}</text>
+						<u--input class="info-input" type="text" v-model="item.clientCode" placeholder="请输入客户代号" />
 					</view>
 					<view class="info-row">
+						<text class="info-label">牌号</text>
+						<text class="info-value">{{ item.brandNum || '-' }}</text>
+					</view>
+					<!-- 机型 - 单选 -->
+					<view class="info-row edit-row">
+						<text class="info-label">机型</text>
+						<picker class="info-picker" mode="selector" :value="item.modelIndex" :range="modelOptions" range-key="dictValue" @change="(e) => onPackingModelChange(e, item)">
+							<view class="picker-value">{{ item.modelKeyName || '请选择机型' }}</view>
+						</picker>
+					</view>
+					<!-- 颜色 - 单选 -->
+					<view class="info-row edit-row">
+						<text class="info-label">颜色</text>
+						<picker class="info-picker" mode="selector" :value="item.colorIndex" :range="colorOptions" range-key="dictValue" @change="(e) => onPackingColorChange(e, item)">
+							<view class="picker-value">{{ item.colorKeyName || '请选择颜色' }}</view>
+						</picker>
+					</view>
+					<view class="info-row edit-row">
+						<text class="info-label">发货条码</text>
+						 <text class="info-value">{{ item.barcodes || '-' }}</text>
+					</view>
+					<view class="info-row edit-row">
+						<text class="info-label">刻码</text>
+						<u--input class="info-input" type="text" v-model="item.engrave" placeholder="请输入刻码" />
+					</view>
+					<view class="info-row edit-row">
 						<text class="info-label">重量</text>
-						<text class="info-value">{{ item.weight || '0' }} {{ item.weightUnit || '' }}</text>
+						<u--input class="info-input" type="digit" v-model="item.weight" placeholder="请输入重量" />
+						<text class="info-unit">{{ item.weightUnit || '' }}</text>
 					</view>
 					<view class="info-row">
-						<text class="info-label">生产日期</text>
-						<text class="info-value">{{ item.productionDate || '-' }}</text>
+						<text class="info-label">供应商</text>
+						<text class="info-value">{{ item.supplierName || '-' }}</text>
+					</view>
+					<view class="info-row">
+						<text class="info-label">供应商代号</text>
+						<text class="info-value">{{ item.supplierCode || '-' }}</text>
+					</view>
+					<view class="info-row">
+						<text class="info-label">序列号</text>
+						<text class="info-value">{{ item.serialNo || '-' }}</text>
+					</view>
+					<view class="info-row">
+						<text class="info-label">是否质检</text>
+						<text class="info-value">{{ item.qualityControl == 1 ? '是' : '否' }}</text>
 					</view>
 					<view class="info-row">
+						<text class="info-label">质检状态</text>
+						<text class="info-value">{{ qualityStatus[item.status] || '-' }}</text>
+					</view>
+					<!-- 质检结果 - 单选 -->
+					<view class="info-row edit-row">
+						<text class="info-label">质检结果</text>
+						<picker class="info-picker" mode="selector" :value="getResultIndex(item.result)" :range="qualityResultsOptions" range-key="label" @change="(e) => onPackingResultChange(e, item)">
+							<view class="picker-value">{{ qualityResults[item.result] || '请选择' }}</view>
+						</picker>
+					</view>
+					<!-- 生产日期 -->
+					<view class="info-row edit-row">
+						<text class="info-label">生产日期</text>
+						<uni-datetime-picker type="date" v-model="item.productionDate" />
+					</view>
+					<!-- 采购日期 -->
+					<view class="info-row edit-row">
 						<text class="info-label">采购日期</text>
-						<text class="info-value">{{ item.purchaseDate || '-' }}</text>
+						<uni-datetime-picker type="date" v-model="item.purchaseDate" />
+					</view>
+					<!-- 失效日期 -->
+					<view class="info-row edit-row">
+						<text class="info-label">失效日期</text>
+						<uni-datetime-picker type="date" v-model="item.expireDate" />
 					</view>
 				</view>
 			</view>
@@ -324,12 +387,32 @@
 	import {
 		purchaseOrderReceiveGetByIdAPI
 	} from '@/api/wt/index.js'
-	import { sceneState, qualityResultsOptions, qualityStatus, qualityResults } from '@/enum/dict.js'
+	import { sceneState } from '@/enum/dict.js'
 	import fileMain from "@/pages/doc/index.vue"
 	import { parameterGetByCode } from '@/api/mainData/index.js'
 	import { getListByNameOrModeType, getCode, contactQueryByCategoryIdsAPI, getCategoryPackageDisposition, getProduceTreeByPid, warehouseDefinitionList, getAssetNum, getWarehouseList, isVerifyRepeatIsStock } from '@/api/warehouseManagement/index.js'
 	import { mapGetters, mapActions } from 'vuex'
 	import { unary } from 'lodash'
+
+	// 质检结果映射
+	const qualityResults = {
+		1: '合格',
+		2: '不合格',
+	};
+
+	// 质检状态映射
+	const qualityStatus = {
+		0: '未质检',
+		1: '待检',
+		2: '已质检',
+	};
+
+	// 质检结果 picker 选项
+	const qualityResultsOptions = [
+		{ value: 1, label: '合格' },
+		{ value: 2, label: '不合格' },
+	];
+
 	export default {
 		components: {
 			fileMain
@@ -511,6 +594,7 @@
 							batchNo: batchNo, // 批次号
 							supplierListOptions: supplierList[item.id], // 供应商列表
 							supplierId: '', // 供应商id
+							supplierIndex: -1, // 供应商索引
 							supplierCode: item.supplierCode, // 供应商代号
 							supplierName: item.supplierName, // 供应商名称
 							measureType: item.measureType, // 计量类型
@@ -534,7 +618,13 @@
 							totalMoney: item.totalPrice, // 总价
 							unitPrice: item.unitPrice, // 单价
 							purpose: '', // 用途
-							isUnpack: item.isUnpack // 是否允许拆包
+							isUnpack: item.isUnpack, // 是否允许拆包
+							warehouseIndex: -1, // 仓库索引
+							packingUnitIndex: newSpecificationOption[index]?.findIndex(v => v.conversionUnit == item.measuringUnit) ?? -1, // 单位索引
+							isSave: false, // 是否已保存
+							ifPackageOk: '', // 包装完好
+							ifPackageOkIndex: -1, // 包装完好索引
+							ifPackageOkLabel: '' // 包装完好标签
 						};
 					});
 					this.productList = this.productList.concat(productList);
@@ -588,8 +678,9 @@
 					}
 				})
 			},
-			handleWareHouse(e, row) {
-				const val = e.detail.value;
+			handleWareHouse(e) {
+				const val = Number(e.detail.value);
+				this.warehouseIndex = val;
 				const warehouseItem = this.warehouseListOption[val];
 				if (warehouseItem) {
 					this.productList.forEach((item, index) => {
@@ -597,6 +688,7 @@
 						this.$set(this.productList[index], 'warehouseName', warehouseItem.name);
 						this.$set(this.productList[index], 'warehouseIds', [warehouseItem.id]);
 						this.$set(this.productList[index], 'warehouseNames', [warehouseItem.name]);
+						this.$set(this.productList[index], 'warehouseIndex', val);
 					});
 				}
 			},
@@ -665,25 +757,35 @@
 						const supplierList = await contactQueryByCategoryIdsAPI({ categoryIds: res.map((item) => item.id) });
 						let packingSpecification = await getCategoryPackageDisposition({ categoryIds: res.map((item) => item.id) });
 
+						// 构建包装规格数组(按 res 顺序)和查找表(按 categoryId)
 						this.packingSpecificationOption = res.map((item) => {
 							return packingSpecification.filter((ite) => item.id == ite.categoryId).sort((a, b) => a.sort - b.sort);
 						});
+						const packingSpecMap = {};
+						res.forEach((item, idx) => {
+							packingSpecMap[item.id] = this.packingSpecificationOption[idx];
+						});
 
-						this.productList = res.map((item, index) => {
-							let filtersItem = this.form.productList.find((detailItem) => item.code == detailItem.productCode || item.code == detailItem.categoryCode);
+						// 以 form.productList 为主循环,通过 res 适配补充品类字段
+						this.productList = this.form.productList.map((formItem, index) => {
+							let categoryItem = res.find(
+								(r) => r.code === (formItem.productCode || formItem.categoryCode)
+							);
+							if (!categoryItem) return null;
 
-							let packingSpecificationLabel = this.packingSpecificationOption[index].map((item) => {
+							let filtersItem = formItem;
+
+							const categorySpecs = packingSpecMap[categoryItem.id] || [];
+							let packingSpecificationLabel = categorySpecs.map((item) => {
 								if (item.sort > 0) {
 									return `${item.packageCell}${item.packageUnit}/${item.conversionUnit}`;
 								}
 							}).filter((item) => !!item);
 
-							const newSpecificationOption = this.packingSpecificationOption;
-
 							let warehouseId = filtersItem.warehouseId;
 							let warehouseName = filtersItem.warehouseName;
 							let measureQuantity = filtersItem.totalCountNew || filtersItem.totalCount || 0;
-							if ((filtersItem.sendTotalWeight || filtersItem.receiveTotalWeight) && item.weightUnit == item.measuringUnit) {
+							if ((filtersItem.sendTotalWeight || filtersItem.receiveTotalWeight) && categoryItem.weightUnit == categoryItem.measuringUnit) {
 								measureQuantity = filtersItem.sendTotalWeight || filtersItem.receiveTotalWeight;
 							}
 							let packingQuantity = filtersItem.totalCountNew || filtersItem.purchaseCount || filtersItem.totalCount || 0;
@@ -703,54 +805,65 @@
 
 							return {
 								index: this.productList.length + index,
-								categoryId: item.id,
-								categoryName: item.name,
-								categoryCode: item.code,
-								categoryModel: item.modelType,
-								specification: item.specification,
-								brandNum: item.brandNum,
+								categoryId: categoryItem.id,
+								categoryName: categoryItem.name,
+								categoryCode: categoryItem.code,
+								categoryModel: categoryItem.modelType,
+								specification: categoryItem.specification,
+								brandNum: categoryItem.brandNum,
 								batchNo: batchNo,
-								supplierListOptions: supplierList[item.id],
+								supplierListOptions: supplierList[categoryItem.id],
 								supplierId: this.form.supplierId,
+								supplierIndex: this.form.supplierId ? (supplierList[categoryItem.id]?.findIndex(s => s.id == this.form.supplierId) ?? -1) : -1,
 								productionRequirements: filtersItem.productionRequirements,
-								supplierCode: this.formData.bizType == 2 || this.formData.bizType == 7 ? filtersItem.supplierMark : item.supplierCode,
+								supplierCode: this.formData.bizType == 2 || this.formData.bizType == 7 ? filtersItem.supplierMark : categoryItem.supplierCode,
 								supplierName: this.form.supplierName,
-								approvalNumber: item.approvalNumber,
-								packingSpecification: item.packingSpecification,
-								packingSpecificationOption: newSpecificationOption[index],
+								approvalNumber: categoryItem.approvalNumber,
+								packingSpecification: categoryItem.packingSpecification,
+								packingSpecificationOption: categorySpecs,
 								packingSpecificationLabel: packingSpecificationLabel,
-								packingQuantity: this.form.productList[index] && this.form.productList[index].isAllPackageData == 1
-									? this.form.productList[index].packingCount : packingQuantity,
-								packingUnit: this.form.productList[index] && this.form.productList[index].isAllPackageData == 1
-									? this.form.productList[index].packingUnit : packingUnit,
-								measureQuantity: this.form.productList[index] && this.form.productList[index].isAllPackageData == 1
-									? this.form.productList[index].quantity : measureQuantity,
-								measureUnit: this.form.productList[index] && this.form.productList[index].isAllPackageData == 1
-									? this.form.productList[index].measuringUnit : item.measuringUnit,
+								packingQuantity: filtersItem?.isAllPackageData == 1
+									? filtersItem.packingCount : packingQuantity,
+								packingUnit: filtersItem?.isAllPackageData == 1
+									? filtersItem.packingUnit : packingUnit,
+								measureQuantity: filtersItem?.isAllPackageData == 1
+									? filtersItem.quantity : measureQuantity,
+								measureUnit: filtersItem?.isAllPackageData == 1
+									? filtersItem.measuringUnit : categoryItem.measuringUnit,
 								packingUnitId: filtersItem.purchaseUnitId || filtersItem.saleUnitId,
 								modelKey: filtersItem.modelKey ? filtersItem.modelKey : '',
+								modelKeyName: filtersItem.modelKey ? (this.modelOptions.find(o => o.dictCode === filtersItem.modelKey)?.dictValue || '') : '',
+								modelIndex: filtersItem.modelKey ? this.modelOptions.findIndex(o => o.dictCode === filtersItem.modelKey) : -1,
 								colorKey: filtersItem.colorKey ? filtersItem.colorKey : '',
-								measureType: item.measureType,
-								netWeight: item.netWeight > -1 ? item.netWeight : 0,
+								colorKeyName: filtersItem.colorKey ? (this.colorOptions.find(o => o.dictCode === filtersItem.colorKey)?.dictValue || '') : '',
+								colorIndex: filtersItem.colorKey ? this.colorOptions.findIndex(o => o.dictCode === filtersItem.colorKey) : -1,
+								measureType: categoryItem.measureType,
+								netWeight: categoryItem.netWeight > -1 ? categoryItem.netWeight : 0,
 								singleWeight: singleWeight || 0,
 								weight: weight || 0,
-								weightUnit: item.weightUnit,
+								weightUnit: categoryItem.weightUnit,
 								totalMoney: totalMoney,
-								unitPrice: item.unitPrice || unitPrice,
+								unitPrice: categoryItem.unitPrice || unitPrice,
 								pricingWay: pricingWay,
 								purpose: '',
 								detailPurchaseDate,
-								detailExpireDate: this.form.productList.find((product) => product.productId == item.id)?.guaranteePeriodDeadline,
-								detailProductionDate: this.form.productList.find((product) => product.productId == item.id)?.productionDate,
+								detailExpireDate: filtersItem?.guaranteePeriodDeadline,
+								detailProductionDate: filtersItem?.productionDate,
 								provenance: filtersItem.provenance,
-								isUnpack: item.isUnpack,
+								isUnpack: categoryItem.isUnpack,
 								warehouseId,
 								warehouseName,
 								warehouseIds,
 								warehouseNames,
+								warehouseIndex: this.warehouseListOption?.findIndex(w => w.id == warehouseId) ?? -1,
+								packingUnitIndex: categorySpecs?.findIndex(v => v.id == (filtersItem.purchaseUnitId || filtersItem.saleUnitId)) ?? -1,
+								isSave: false,
+								ifPackageOk: '',
+								ifPackageOkIndex: -1,
+								ifPackageOkLabel: '',
 								qualityControl: filtersItem?.isComeCheck
 							};
-						});
+						}).filter(Boolean);
 						
 						this.$nextTick(() => {
 							this.batchSave();
@@ -793,6 +906,11 @@
 				const num = Number(number || 0);
 				return isNaN(num) ? '0' : String(num);
 			},
+			// 格式化包装数量/计量数量/重量(带单位)
+			formatPackingValue(value, unit) {
+				if (value === null || value === undefined || value === '') return '-';
+				return this.changeCount(value) + ' ' + (unit || '');
+			},
 			selectSupplier(val, row) {
 				row.supplierId = val;
 				row.supplierName = row.supplierListOptions.filter((item) => item.id == val)[0]?.name;
@@ -800,72 +918,70 @@
 			},
 			inputsingleWeight(row, index) {
 				if (row.measureUnit == row.weightUnit) {
-					row.weight = row.singleWeight * row.packingQuantity;
-					row.measureQuantity = row.weight;
+					this.$set(this.productList[index], 'weight', row.singleWeight * row.packingQuantity);
+					this.$set(this.productList[index], 'measureQuantity', row.weight);
 				} else {
-					row.weight = row.singleWeight * row.measureQuantity;
+					this.$set(this.productList[index], 'weight', row.singleWeight * row.measureQuantity);
 				}
 			},
 			inputWeight(row, index) {
 				if (row.measureUnit == row.weightUnit) {
-					row.measureQuantity = row.weight;
-					row.singleWeight = Math.trunc((row.measureQuantity / row.packingQuantity) * 10000) / 10000;
+					this.$set(this.productList[index], 'measureQuantity', row.weight);
+					this.$set(this.productList[index], 'singleWeight', Math.trunc((row.measureQuantity / row.packingQuantity) * 10000) / 10000);
 				} else {
-					row.singleWeight = row.measureQuantity ? row.weight / row.measureQuantity : 0;
+					this.$set(this.productList[index], 'singleWeight', row.measureQuantity ? row.weight / row.measureQuantity : 0);
 				}
 			},
 			// 计算最小单元数量
 			async computeNum(row, index, isClear) {
 				let data = row.packingSpecificationOption.find((item) => item.id == row.packingUnitId);
 				if (data) {
-					row.packingUnit = data.conversionUnit;
+					this.$set(this.productList[index], 'packingUnit', data.conversionUnit);
 				}
-				
+
 				if (isClear && row.packingQuantity < 0) {
 					this.$set(this.productList[index], 'packingQuantity', 1);
 				}
-				
+
 				if (row.packingQuantity && row.packingUnit) {
 					const res = await warehouseDefinitionList({});
 					if (res.length == 1) {
 						let name = res[0]?.factoryName + '-' + res[0]?.name;
 						this.$set(this.productList[index], 'warehouseId', res[0].id);
 						this.$set(this.productList[index], 'warehouseName', name);
+						this.$set(this.productList[index], 'warehouseIndex', this.warehouseListOption?.findIndex(w => w.id == res[0].id) ?? -1);
 					} else {
 						this.$set(this.productList[index], 'warehouseId', '');
 						this.$set(this.productList[index], 'warehouseName', '');
 					}
-					
-					let startIndex = row.packingSpecificationOption.findIndex((ite) => {
-						return row.measuringUnit == ite.packingUnit && ite.packingUnit != ite.conversionUnit;
-					});
+
 					let endIndex = row.packingSpecificationOption.findIndex((ite) => data.id == ite.id);
-					
+
 					let total = Number(row.packingQuantity);
 					if (row.packingUnit == row.measureUnit && row.measureUnit == '立方' && row.netWeight) {
 						total = Number(row.packingQuantity) * row.netWeight;
 					} else {
 						for (; 0 < endIndex; endIndex--) {
-							total = this.$math.format(row.packingSpecificationOption[endIndex].packageCell * total, 14);
+							total = row.packingSpecificationOption[endIndex].packageCell * total;
 						}
 					}
-					
-					row.measureQuantity = this.changeCount(total);
-					
+
+					this.$set(this.productList[index], 'measureQuantity', this.changeCount(total));
+
 					let packingBoolen = !!this.getDict('不拆物料层规格', row.packingUnit)?.dictValue;
 					let measureBoolen = !!this.getDict('不拆物料层规格', row.measureUnit)?.dictValue;
-					
+
 					if (packingBoolen && measureBoolen && row.packingUnit != 'L') {
-						row.weight = total;
+						this.$set(this.productList[index], 'weight', total);
 					}
-					
+
 					let weight = 0;
 					if (row.measureUnit == row.weightUnit) {
 						weight = row.measureQuantity;
 						if (row.weightUnit == row.packageUnit) {
-							row.singleWeight = 0;
+							this.$set(this.productList[index], 'singleWeight', 0);
 						} else {
-							row.singleWeight = Math.trunc((row.measureQuantity / row.packingQuantity) * 10000) / 10000;
+							this.$set(this.productList[index], 'singleWeight', Math.trunc((row.measureQuantity / row.packingQuantity) * 10000) / 10000);
 						}
 					} else if (row.singleWeight) {
 						weight = row.measureQuantity * Number(row.singleWeight);
@@ -899,51 +1015,58 @@
 					console.log('保存失败', error);
 				}
 			},
-			listSave(row, index) {
-				// 必填项校验
+			// 单行校验
+			validateSingleRow(row, rowNum) {
 				if (!row.batchNo) {
-					uni.showToast({ title: '请填写批次号', icon: 'none' });
-					return;
+					uni.showToast({ title: rowNum !== undefined ? `第${rowNum}行:请填写批次号` : '请填写批次号', icon: 'none' });
+					return false;
 				}
 				if (!row.packingQuantity && row.packingQuantity !== 0) {
-					uni.showToast({ title: '请填写数量', icon: 'none' });
-					return;
+					uni.showToast({ title: rowNum !== undefined ? `第${rowNum}行:请填写数量` : '请填写数量', icon: 'none' });
+					return false;
 				}
 				if (!row.packingUnit) {
-					uni.showToast({ title: '请选择单位', icon: 'none' });
-					return;
+					uni.showToast({ title: rowNum !== undefined ? `第${rowNum}行:请选择单位` : '请选择单位', icon: 'none' });
+					return false;
 				}
 				if (!row.warehouseId) {
-					uni.showToast({ title: '请选择仓库', icon: 'none' });
-					return;
+					uni.showToast({ title: rowNum !== undefined ? `第${rowNum}行:请选择仓库` : '请选择仓库', icon: 'none' });
+					return false;
+				}
+				return true;
+			},
+			// 计算包装参数(提取重复的 packingBoolen/measureBoolen/num 逻辑)
+			computePackagingParams(row) {
+				const packingBoolen = !!this.getDict('不拆物料层规格', row.packingUnit)?.dictValue;
+				const measureBoolen = !!this.getDict('不拆物料层规格', row.measureUnit)?.dictValue;
+				let num = row.packingQuantity;
+				// 处理单位为KG类的情况
+				if (packingBoolen) {
+					const filterArr = row.packingSpecificationOption?.filter((item) => {
+						return item.packageUnit == row.packingUnit && item.packageUnit != item.conversionUnit;
+					});
+					if (filterArr?.length) {
+						num = Math.ceil(row.packingQuantity / filterArr[0].packageCell);
+					}
+				} else if (measureBoolen) {
+					// 处理单位不为KG类,计量单位为KG类的情况
+					let splitIndex = row.packingSpecificationOption?.findIndex((item) =>
+						item.conversionUnit == row.packingUnit && item.packageUnit != item.conversionUnit
+					);
+					for (; splitIndex > 1; splitIndex--) {
+						num = num * row.packingSpecificationOption[splitIndex].packageCell;
+					}
 				}
+				return { packingBoolen, measureBoolen, num };
 			},
 			// 物品批量保存前校验
 			validateForm() {
 				return new Promise((resolve, reject) => {
 					for (let i = 0; i < this.productList.length; i++) {
 						const row = this.productList[i];
-						// 已保存的不需要校验
 						if (row.isSave) continue;
-
-						if (!row.batchNo) {
-							uni.showToast({ title: `第${i + 1}行:请填写批次号`, icon: 'none' });
-							reject(new Error('批次号必填'));
-							return;
-						}
-						if (!row.packingQuantity && row.packingQuantity !== 0) {
-							uni.showToast({ title: `第${i + 1}行:请填写数量`, icon: 'none' });
-							reject(new Error('数量必填'));
-							return;
-						}
-						if (!row.packingUnit) {
-							uni.showToast({ title: `第${i + 1}行:请选择单位`, icon: 'none' });
-							reject(new Error('单位必填'));
-							return;
-						}
-						if (!row.warehouseId) {
-							uni.showToast({ title: `第${i + 1}行:请选择仓库`, icon: 'none' });
-							reject(new Error('仓库必填'));
+						if (!this.validateSingleRow(row, i + 1)) {
+							reject(new Error('校验不通过'));
 							return;
 						}
 					}
@@ -952,20 +1075,7 @@
 			},
 			listSave(row, index) {
 				// 必填项校验
-				if (!row.batchNo) {
-					uni.showToast({ title: '请填写批次号', icon: 'none' });
-					return;
-				}
-				if (!row.packingQuantity && row.packingQuantity !== 0) {
-					uni.showToast({ title: '请填写数量', icon: 'none' });
-					return;
-				}
-				if (!row.packingUnit) {
-					uni.showToast({ title: '请选择单位', icon: 'none' });
-					return;
-				}
-				if (!row.warehouseId) {
-					uni.showToast({ title: '请选择仓库', icon: 'none' });
+				if (!this.validateSingleRow(row)) {
 					return;
 				}
 
@@ -994,7 +1104,7 @@
 						item.conversionUnit == row.packingUnit && item.packageUnit != item.conversionUnit
 					);
 					for (; splitIndex > 1; splitIndex--) {
-						measureNum = this.$math.format(measureNum * row.packingSpecificationOption[splitIndex].packageCell, 14);
+						measureNum = measureNum * row.packingSpecificationOption[splitIndex].packageCell;
 					}
 				} else {
 					if (row.packingSpecificationOption[1]?.packageCell) {
@@ -1033,7 +1143,9 @@
 							packingNum = Math.ceil(row.measureQuantity / row.packingSpecificationOption[1]?.packageCell);
 						}
 					}
-					getAssetNum([{ assetCode: row.categoryCode + row.index, batchNum: row.batchNo, num: packingNum }]).then(() => {});
+				getAssetNum([{ assetCode: row.categoryCode + row.index, batchNum: row.batchNo, num: packingNum }]).then((res) => {
+					this.generateWrappers(row, index, res.data || []);
+				});
 				}
 				
 				this.$set(this.productList[index], 'isSave', true);
@@ -1197,39 +1309,46 @@
 			},
 			// 单位选择变化
 			onPackingUnitChange(e, row, index) {
-				const val = e.detail.value;
+				const val = Number(e.detail.value);
 				const item = row.packingSpecificationOption[val];
 				if (item) {
-					row.packingUnitId = item.id;
-					row.packingUnit = item.conversionUnit;
+					this.$set(this.productList[index], 'packingUnitId', item.id);
+					this.$set(this.productList[index], 'packingUnit', item.conversionUnit);
+					this.$set(this.productList[index], 'packingUnitIndex', val);
 					this.computeNum(row, index);
 				}
 			},
 			// 包装完好选择变化
-			onPackageOkChange(e, row) {
-				const val = e.detail.value;
-				row.ifPackageOkIndex = val;
-				row.ifPackageOk = this.packageOkOptions[val].value;
-				row.ifPackageOkLabel = this.packageOkOptions[val].label;
+			onPackageOkChange(e, index) {
+				const val = Number(e.detail.value);
+				const item = this.packageOkOptions[val];
+				if (item) {
+					this.$set(this.productList[index], 'ifPackageOkIndex', val);
+					this.$set(this.productList[index], 'ifPackageOk', item.value);
+					this.$set(this.productList[index], 'ifPackageOkLabel', item.label);
+				}
 			},
 			// 仓库选择变化
-			onWarehouseChange(e, row) {
-				const val = e.detail.value;
+			onWarehouseChange(e, index) {
+				const val = Number(e.detail.value);
 				const item = this.warehouseListOption[val];
 				if (item) {
-					row.warehouseId = item.id;
-					row.warehouseName = item.name;
-					row.warehouseIndex = val;
+					this.$set(this.productList[index], 'warehouseId', item.id);
+					this.$set(this.productList[index], 'warehouseName', item.name);
+					this.$set(this.productList[index], 'warehouseIndex', val);
+					this.$set(this.productList[index], 'warehouseIds', [item.id]);
+					this.$set(this.productList[index], 'warehouseNames', [item.name]);
 				}
 			},
 			// 供应商选择变化
-			onSupplierChange(e, row) {
-				const val = e.detail.value;
-				const item = row.supplierListOptions[val];
+			onSupplierChange(e, index) {
+				const val = Number(e.detail.value);
+				const item = this.productList[index].supplierListOptions[val];
 				if (item) {
-					row.supplierId = item.id;
-					row.supplierName = item.name;
-					row.supplierCode = item.serialNo;
+					this.$set(this.productList[index], 'supplierId', item.id);
+					this.$set(this.productList[index], 'supplierName', item.name);
+					this.$set(this.productList[index], 'supplierCode', item.serialNo);
+					this.$set(this.productList[index], 'supplierIndex', val);
 				}
 			},
 			// 颜色选择变化
@@ -1248,14 +1367,46 @@
 				const item = this.modelOptions[val];
 				if (item) {
 					this.$set(this.productList[index], 'modelKey', item.dictCode);
-					this.$set(this.productList[index], 'modelKeyName', item.dictValue);
-					this.$set(this.productList[index], 'modelIndex', val);
-				}
-			},
-			// 日期选择变化
-			onDateChange(e, row, field) {
-				row[field] = e.detail.value;
-			},
+				this.$set(this.productList[index], 'modelKeyName', item.dictValue);
+				this.$set(this.productList[index], 'modelIndex', val);
+			}
+		},
+		// 包装明细-颜色选择变化
+		onPackingColorChange(e, packingItem) {
+			const val = Number(e.detail.value);
+			const item = this.colorOptions[val];
+			if (item) {
+				this.$set(packingItem, 'colorKey', item.dictCode);
+				this.$set(packingItem, 'colorKeyName', item.dictValue);
+				this.$set(packingItem, 'colorIndex', val);
+			}
+		},
+		// 包装明细-机型选择变化
+		onPackingModelChange(e, packingItem) {
+			const val = Number(e.detail.value);
+			const item = this.modelOptions[val];
+			if (item) {
+				this.$set(packingItem, 'modelKey', item.dictCode);
+				this.$set(packingItem, 'modelKeyName', item.dictValue);
+				this.$set(packingItem, 'modelIndex', val);
+			}
+		},
+		// 包装明细-质检结果选择变化
+		onPackingResultChange(e, packingItem) {
+			const val = Number(e.detail.value);
+			const item = this.qualityResultsOptions[val];
+			if (item) {
+				this.$set(packingItem, 'result', item.value);
+			}
+		},
+		// 获取质检结果的 picker index
+		getResultIndex(result) {
+			return this.qualityResultsOptions.findIndex(o => o.value === result);
+		},
+		// 日期选择变化
+		onDateChange(e, row, field) {
+			row[field] = e.detail.value;
+		},
 			 //入库明细删除
 			listDel(row, index) {
 				this.productList.splice(index, 1);
@@ -1291,75 +1442,39 @@
 				.then(async () => {
 					// 批量获取包装编码并处理
 					let packingCodePrams = this.productList.map((row) => {
-					// 判断单位和计量单位是否为不拆物料层规格
-					let packingBoolen = !!this.getDict(
-						'不拆物料层规格',
-						row.packingUnit
-					).dictValue;
-					let measureBoolen = !!this.getDict(
-						'不拆物料层规格',
-						row.measureUnit
-					).dictValue;
-					let num = 0;
+					if (row.isSave) return {};
+					const { packingBoolen, measureBoolen, num: baseNum } = this.computePackagingParams(row);
+					let num = baseNum;
+					// 处理单位为KG类的情况
 					if (packingBoolen) {
-						let filterArr = row.packingSpecificationOption.filter(
-						(item) => {
-							return (
-							item.packageUnit == row.packingUnit &&
-							item.packageUnit != item.conversionUnit
-							);
-						}
-						);
-						num = Math.ceil(row.packingQuantity / filterArr[0].packageCell);
-					}
-					if (row.isSave) {
-						return {};
-					} else {
-						// 处理单位为KG类的情况
-						if (packingBoolen) {
 						return {
 							assetCode: row.categoryCode + row.index,
 							batchNum: row.batchNo,
 							num
 						};
-						} else {
+					} else {
 						if (row.isUnpack == 1) {
 							if (measureBoolen) {
-							// 处理单位不为KG类,计量单位为KG类的情况
-							let num = row.packingQuantity;
-							let splitIndex = row.packingSpecificationOption.findIndex(
-								(item) =>
-								item.conversionUnit == row.packingUnit &&
-								item.packageUnit != item.conversionUnit
-							);
-							for (; splitIndex > 1; splitIndex--) {
-								num = this.$math.format(
-								num *
-									row.packingSpecificationOption[splitIndex]
-									.packageCell,
-								14
-								);
+								// 处理单位不为KG类,计量单位为KG类的情况
+								return {
+									assetCode: row.categoryCode + row.index,
+									batchNum: row.batchNo,
+									num: baseNum
+								};
+							} else {
+								// 处理拆包到最小包装单元数量的情况
+								return {
+									assetCode: row.categoryCode + row.index,
+									batchNum: row.batchNo,
+									num: row.measureQuantity
+								};
 							}
+						} else {
 							return {
 								assetCode: row.categoryCode + row.index,
 								batchNum: row.batchNo,
 								num
 							};
-							} else {
-							// 处理拆包到最小包装单元数量的情况
-							return {
-								assetCode: row.categoryCode + row.index,
-								batchNum: row.batchNo,
-								num: row.measureQuantity
-							};
-							}
-						} else {
-							return {
-							assetCode: row.categoryCode + row.index,
-							batchNum: row.batchNo,
-							num
-							};
-						}
 						}
 					}
 					});
@@ -1399,6 +1514,7 @@
 					title: '请到主数据维计量类型!',
 					icon: 'none'
 				});
+				if (!packingCodeList?.length) return;
 
 				console.log('包装数据--------', row);
 				// console.log('包装规格----', row.packingSpecificationOption);
@@ -1423,6 +1539,8 @@
 				let packingBoolen = !!this.getDict('不拆物料层规格', row.packingUnit).dictValue;
 				let measureBoolen = !!this.getDict('不拆物料层规格', row.measureUnit).dictValue;
 
+				console.log('packingBoolen', packingBoolen, measureBoolen);
+
 				let num = row.packingQuantity;
 				let filterArr = [];
 				// 处理单位为KG类的情况
@@ -1452,10 +1570,7 @@
 								item.packageUnit != item.conversionUnit
 						);
 						for (; splitIndex > 1; splitIndex--) {
-							num = this.$math.format(
-								num * row.packingSpecificationOption[splitIndex].packageCell,
-								14
-							);
+							num = num * row.packingSpecificationOption[splitIndex].packageCell;
 						}
 					} else {
 						if (row.packingSpecificationOption[1]?.packageCell) {
@@ -1481,7 +1596,7 @@
 
 					// 处理单位为KG类,计算每桶KG值
 					if (packingBoolen) {
-						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);
+						measureQuantity = Number(row.packingQuantity) > filterArr[0].packageCell * (index + 1) ? filterArr[0].packageCell : Number(row.packingQuantity) - filterArr[0].packageCell * index;
 						console.log(measureQuantity, 'measureQuantit1111y');
 					} else {
 						console.log('1 拆--------', measureBoolen);
@@ -1495,11 +1610,8 @@
 								item.packageUnit != item.conversionUnit
 							);
 							for (; splitIndex > 0; splitIndex--) {
-								measureQuantity = this.$math.format(
-									measureQuantity *
-										row.packingSpecificationOption[splitIndex].packageCell,
-									14
-								);
+								measureQuantity = measureQuantity *
+									row.packingSpecificationOption[splitIndex].packageCell;
 							}
 						} else {
 							measureQuantity = row.packingSpecificationOption[1].packageCell;
@@ -1535,8 +1647,13 @@
 						batchNo: row.batchNo, // 批次号
 						packageNo: packingCodeList[index]?.onlyCode, // 包装编码
 						packingQuantity: packingQuantity, // 包装数量
+						packingUnit: row.packingUnit, // 包装单位(默认)
 						modelKey: row.modelKey, // 机型
+						modelKeyName: row.modelKey ? (this.modelOptions.find(o => o.dictCode === row.modelKey)?.dictValue || '') : '',
+						modelIndex: row.modelKey ? this.modelOptions.findIndex(o => o.dictCode === row.modelKey) : -1,
 						colorKey: row.colorKey, //颜色
+						colorKeyName: row.colorKey ? (this.colorOptions.find(o => o.dictCode === row.colorKey)?.dictValue || '') : '',
+						colorIndex: row.colorKey ? this.colorOptions.findIndex(o => o.dictCode === row.colorKey) : -1,
 						measureQuantity: measureQuantity, // 计量数量
 						measureUnit: row.isUnpack
 						? measureBoolen
@@ -1557,6 +1674,7 @@
 						productionDate: productionDate, // 生产日期
 						purchaseDate: purchaseDate, // 采购时间
 						expireDate: expireDate, //失效日期
+						serialNo: '', // 序列号
 						result: 1, // 结果(1合格 2不合格)
 						qualityControl: row.qualityControl,
 						status: status // 状态(0=未质检 1待检 2已检)
@@ -1612,14 +1730,14 @@
 						if (measureBoolen) {
 							let total = item.packingQuantity ? Number(item.packingQuantity) : 0;
 							for (; startIndex < endIndex; endIndex--) {
-								total = this.$math.format(item.packingSpecificationOption[endIndex].packageCell * total, 14);
+								total = item.packingSpecificationOption[endIndex].packageCell * total;
 							}
 							if (inBoolen) {
 								// 第二层为KG类
 								item.weight = total ? Number(total) : 0;
 							} else {
 								// 第二层不为KG类
-								item.weight = this.$math.format(total * item.netWeight, 14);
+								item.weight = total * item.netWeight;
 							}
 						} else if (!measureBoolen) {
 							if (inBoolen) {
@@ -1659,18 +1777,20 @@
 						row.packingSpecificationOption[1]?.packageCell;
 				}
 
-				if (remainder > 0) {
+				if (remainder > 0 && packingCodeList?.length) {
 					let onlyCode = packingCodeList[packingCodeList.length - 1]?.onlyCode;
-					let index = this.packingList.findIndex(
+					let idx = this.packingList.findIndex(
 						(packingItem) => packingItem.packageNo == onlyCode
 					);
-					this.$set(this.packingList[index], 'measureQuantity', remainder);
-					if (row.singleWeight) {
-						this.$set(
-							this.packingList[index],
-							'weight',
-							row.singleWeight * remainder
-						);
+					if (idx !== -1) {
+						this.$set(this.packingList[idx], 'measureQuantity', remainder);
+						if (row.singleWeight) {
+							this.$set(
+								this.packingList[idx],
+								'weight',
+								row.singleWeight * remainder
+							);
+						}
 					}
 				}
 
@@ -1772,6 +1892,21 @@
 	margin-bottom: 20rpx;
 	box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.08);
 }
+/* 包装卡片标题 */
+.card_title {
+	font-size: 30rpx;
+	font-weight: bold;
+	color: #1890FF;
+	padding-bottom: 16rpx;
+	border-bottom: 1rpx solid #eee;
+	margin-bottom: 16rpx;
+}
+/* 单位后缀 */
+.info-unit {
+	font-size: 26rpx;
+	color: #999;
+	margin-left: 8rpx;
+}
 /* 批量操作按钮 */
 .batch-actions {
 	display: flex;