已修改19个文件
1194 ■■■■ 文件已修改
src/api/consumablesLogistics/consumablesInRecord.js 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/consumablesLogistics/consumablesOutRecord.js 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/inventoryManagement/stockInRecord.js 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/inventoryManagement/stockOut.js 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/consumablesLogistics/dispatchLog/Record.vue 131 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/consumablesLogistics/receiptManagement/Record.vue 128 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/consumablesLogistics/stockManagement/New.vue 118 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/consumablesLogistics/stockManagement/Qualified.vue 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/consumablesLogistics/stockManagement/Subtract.vue 125 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/index.vue 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/inventoryManagement/dispatchLog/Record.vue 178 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/inventoryManagement/receiptManagement/Record.vue 170 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/inventoryManagement/stockManagement/Qualified.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/inventoryManagement/stockManagement/Subtract.vue 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/qualityManagement/nonconformingManagement/components/formDia.vue 199 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/qualityManagement/nonconformingManagement/index.vue 35 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/qualityManagement/rawMaterial/components/formDia.vue 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/qualityManagement/rawMaterial/index.vue 40 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
vite.config.js 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/consumablesLogistics/consumablesInRecord.js
@@ -17,6 +17,15 @@
    });
};
// 编辑耗材入库(仅用于台账编辑)
export const editStockInStock = (data) => {
    return request({
        url: "/consumablesInRecord/editStockInStock",
        method: "post",
        data,
    });
};
export const batchDeleteConsumablesInRecords = (ids) => {
    return request({
        url: "/consumablesInRecord",
src/api/consumablesLogistics/consumablesOutRecord.js
@@ -17,3 +17,12 @@
        data: ids,
    });
};
// 编辑耗材出库(仅用于台账编辑)
export const editStockOut = (data) => {
    return request({
        url: "/consumablesOutRecord/editStockOut",
        method: "post",
        data,
    });
};
src/api/inventoryManagement/stockInRecord.js
@@ -18,6 +18,15 @@
    });
};
// 编辑入库(用于库存台账编辑)
export const editStockInStock = (data) => {
    return request({
        url: "/stockInRecord/editStockInStock",
        method: "post",
        data,
    });
};
export const batchDeleteStockInRecords = (ids) => {
    return request({
        url: "/stockInRecord",
src/api/inventoryManagement/stockOut.js
@@ -17,3 +17,12 @@
        data: ids,
    });
}
// 编辑出库(库存台账编辑)
export const editStockOut = (data) => {
    return request({
        url: "/stockOutRecord/editStockOut",
        method: "post",
        data,
    });
}
src/views/consumablesLogistics/dispatchLog/Record.vue
@@ -28,7 +28,12 @@
            </div>
            <div>
                <el-button @click="handleOut">导出</el-button>
                <el-button type="danger" plain @click="handleDelete">删除</el-button>
                <el-button
                    type="danger"
                    plain
                    @click="handleDelete"
                    v-if="hasCDispatchCancel"
                >删除</el-button>
                <!-- <el-button type="primary" plain @click="handlePrint">打印</el-button> -->
            </div>
        </div>
@@ -72,20 +77,30 @@
                    show-overflow-tooltip
                />
                <el-table-column
                    label="出库数量"
                    prop="stockOutNum"
                    label="数量"
                    prop="qualitity"
                    show-overflow-tooltip
                />
                <el-table-column
                    label="净重(吨)"
                    prop="netWeight"
                <!-- <el-table-column
                    label="采购员"
                    prop="purchaser"
                    show-overflow-tooltip
                />
                /> -->
                <el-table-column
                    label="出库人"
                    prop="createBy"
                    show-overflow-tooltip
                />
                <el-table-column label="操作" width="160" align="center">
                    <template #default="scope">
                        <el-button
                            v-if="hasCDispatchEdit"
                            type="primary"
                            size="mini"
                            @click="handleEdit(scope.row)"
                        >编辑</el-button>
                    </template>
                </el-table-column>
        <!-- <el-table-column label="来源"
                         prop="recordType"
                         show-overflow-tooltip>
@@ -93,20 +108,7 @@
            {{ getRecordType(scope.row.recordType) }}
          </template>
        </el-table-column> -->
        <el-table-column
            label="车牌"
            prop="licensePlateNo"
            show-overflow-tooltip
        />
        <el-table-column label="操作"
                         width="120"
                         align="center">
          <template #default="scope">
            <el-button type="primary"
                       size="mini"
                       @click="handlePreview(scope.row)">导出过磅单</el-button>
          </template>
        </el-table-column>
        <!-- 不再展示过磅相关字段与导出操作 -->
            </el-table>
            <pagination
                v-show="total > 0"
@@ -118,21 +120,66 @@
            />
        </div>
    </div>
    <el-dialog
        title="编辑出库信息"
        v-model="isShowEditModal"
        width="600px"
    >
        <el-form
            ref="editFormRef"
            :model="editForm"
            label-width="90px"
        >
            <el-form-item
                label="数量"
                prop="qualitity"
                :rules="[{ required: true, message: '请输入数量', trigger: ['blur', 'change'] }]"
            >
                <el-input-number
                    v-model="editForm.qualitity"
                    :min="0"
                    :step="1"
                    :precision="0"
                    controls-position="right"
                    style="width: 100%"
                    placeholder="请输入数量"
                />
            </el-form-item>
            <el-form-item
                label="采购员"
                prop="purchaser"
                :rules="[{ required: true, message: '请输入采购员', trigger: ['blur', 'change'] }]"
            >
                <el-input
                    v-model="editForm.purchaser"
                    placeholder="请输入采购员"
                />
            </el-form-item>
        </el-form>
        <template #footer>
            <el-button @click="closeEditModal">取消</el-button>
            <el-button type="primary" @click="handleEditSubmit">确定</el-button>
        </template>
    </el-dialog>
</template>
<script setup>
import pagination from "@/components/PIMTable/Pagination.vue";
import { ref, reactive, toRefs, getCurrentInstance } from "vue";
import { ref, reactive, toRefs, getCurrentInstance, computed } from "vue";
import { ElMessageBox } from "element-plus";
import useUserStore from "@/store/modules/user";
import { getCurrentDate } from "@/utils/index.js";
import {
    getConsumablesOutRecordPage,
    delConsumablesOutRecord,
    editStockOut,
} from "@/api/consumablesLogistics/consumablesOutRecord.js";
import {
  findAllQualifiedStockOutRecordTypeOptions, findAllUnQualifiedStockOutRecordTypeOptions,
} from "@/api/basicData/enum.js";
import { checkPermi } from "@/utils/permission.js";
const userStore = useUserStore();
const { proxy } = getCurrentInstance();
@@ -155,6 +202,46 @@
  }
})
const hasCDispatchEdit = computed(() => checkPermi(['c_dispatch_edit']));
const hasCDispatchCancel = computed(() => checkPermi(['c_dispatch_cancel']));
// 编辑弹框数据
const isShowEditModal = ref(false);
const editFormRef = ref();
const editForm = reactive({
    id: undefined,
    qualitity: undefined,
    purchaser: "",
});
const handleEdit = (row) => {
    editForm.id = row.id;
    editForm.qualitity = row.qualitity;
    editForm.purchaser = row.purchaser ?? "";
    isShowEditModal.value = true;
};
const closeEditModal = () => {
    isShowEditModal.value = false;
    editForm.id = undefined;
    editForm.qualitity = undefined;
    editForm.purchaser = "";
    editFormRef.value?.clearValidate?.();
};
const handleEditSubmit = () => {
    editFormRef.value?.validate?.((valid) => {
        if (!valid) return;
        editStockOut({ ...editForm }).then(() => {
            closeEditModal();
            proxy.$modal.msgSuccess("编辑成功");
            getList();
        });
    });
};
// 打印相关
const printPreviewVisible = ref(false);
const printData = ref([]);
src/views/consumablesLogistics/receiptManagement/Record.vue
@@ -34,7 +34,8 @@
        <el-button @click="handleOut">导出</el-button>
        <el-button type="danger"
                   plain
                   @click="handleDelete">删除
                   @click="handleDelete"
                   v-if="hasCReceiptCancel">删除
        </el-button>
      </div>
    </div>
@@ -70,24 +71,11 @@
        <el-table-column label="单位"
                         prop="unit"
                         show-overflow-tooltip/>
        <el-table-column label="入库数量"
                         prop="stockInNum"
        <el-table-column label="数量"
                         prop="qualitity"
                         show-overflow-tooltip/>
        <el-table-column label="车牌号"
                         prop="licensePlateNo"
                         v-if="type === '0'"
                         show-overflow-tooltip/>
        <el-table-column label="毛重(吨)"
                         prop="grossWeight"
                         v-if="type === '0'"
                         show-overflow-tooltip/>
        <el-table-column label="皮重(吨)"
                         prop="tareWeight"
                         v-if="type === '0'"
                         show-overflow-tooltip/>
        <el-table-column label="净重(吨)"
                         prop="netWeight"
                         v-if="type === '0'"
        <el-table-column label="采购员"
                         prop="purchaser"
                         show-overflow-tooltip/>
        <el-table-column label="入库人"
                         prop="createBy"
@@ -99,21 +87,25 @@
            {{ getRecordType(scope.row.recordType) }}
          </template>
        </el-table-column> -->
        <el-table-column label="过磅日期"
                         prop="weighingDate"
                         v-if="type === '0'"
                         show-overflow-tooltip/>
        <el-table-column label="过磅员"
                         prop="weighingOperator"
                         v-if="type === '0'"
                         show-overflow-tooltip/>
        <el-table-column label="操作"
        <!-- <el-table-column label="操作"
                         width="120"
                         align="center">
          <template #default="scope">
            <el-button type="primary"
                       size="mini"
                       @click="handlePreview(scope.row)">导出过磅单</el-button>
          </template>
        </el-table-column> -->
        <el-table-column label="操作"
                         width="120"
                         align="center">
          <template #default="scope">
            <el-button
              v-if="hasCReceiptEdit"
              type="primary"
              size="mini"
              @click="handleEdit(scope.row)"
            >编辑</el-button>
          </template>
        </el-table-column>
      </el-table>
@@ -127,6 +119,51 @@
      </div>
    </div>
  </div>
  <el-dialog
    v-model="isShowEditModal"
    title="编辑入库"
    width="600"
    @close="closeEditModal"
  >
    <el-form
      label-width="100px"
      :model="editForm"
      label-position="top"
      ref="editFormRef"
    >
      <el-form-item
        label="数量"
        prop="qualitity"
        :rules="[{ required: true, message: '请输入数量', trigger: ['blur', 'change'] }]"
      >
        <el-input-number
          v-model="editForm.qualitity"
          :min="0"
          :step="1"
          :precision="0"
          controls-position="right"
          style="width: 100%"
          placeholder="请输入数量"
        />
      </el-form-item>
      <el-form-item
        label="采购员"
        prop="purchaser"
        :rules="[{ required: true, message: '请输入采购员', trigger: ['blur', 'change'] }]"
      >
        <el-input v-model="editForm.purchaser" placeholder="请输入采购员" />
      </el-form-item>
    </el-form>
    <template #footer>
      <div class="dialog-footer">
        <el-button type="primary" @click="handleEditSubmit">确认</el-button>
        <el-button @click="closeEditModal">取消</el-button>
      </div>
    </template>
  </el-dialog>
</template>
<script setup>
@@ -137,15 +174,18 @@
  toRefs,
  onMounted,
  getCurrentInstance,
  computed,
} from "vue";
import {ElMessageBox} from "element-plus";
import {
  getConsumablesInRecordListPage,
  batchDeleteConsumablesInRecords,
  editStockInStock,
} from "@/api/consumablesLogistics/consumablesInRecord.js";
import {
  findAllQualifiedStockInRecordTypeOptions, findAllUnQualifiedStockInRecordTypeOptions,
} from "@/api/basicData/enum.js";
import { checkPermi } from "@/utils/permission.js";
const {proxy} = getCurrentInstance();
@@ -156,6 +196,9 @@
    default: '0'
  }
})
const hasCReceiptEdit = computed(() => checkPermi(['c_receipt_edit']));
const hasCReceiptCancel = computed(() => checkPermi(['c_receipt_cancel']));
const tableData = ref([]);
const selectedRows = ref([]);
@@ -274,6 +317,37 @@
      });
};
// 编辑耗材入库
const isShowEditModal = ref(false);
const editFormRef = ref(null);
const editForm = ref({});
const handleEdit = (row) => {
  editForm.value = {
    id: row.id,
    qualitity: row.qualitity,
    purchaser: row.purchaser,
  };
  isShowEditModal.value = true;
};
const closeEditModal = () => {
  isShowEditModal.value = false;
  editForm.value = {};
  editFormRef.value?.clearValidate?.();
};
const handleEditSubmit = () => {
  editFormRef.value?.validate?.((valid) => {
    if (!valid) return;
    editStockInStock(editForm.value).then(() => {
      closeEditModal();
      proxy.$modal.msgSuccess("编辑成功");
      getList();
    });
  });
};
onMounted(() => {
  getList();
  fetchStockRecordTypeOptions();
src/views/consumablesLogistics/stockManagement/New.vue
@@ -37,85 +37,30 @@
          <el-input v-model="formState.unit"  disabled />
        </el-form-item>
        <!-- productType === 0:原材料 -->
        <el-form-item
            v-if="type === 'qualified' && formState.productType === 0"
            label="车牌号"
            prop="licensePlateNo"
            :rules="[{ required: true, message: '请输入车牌号', trigger: ['blur','change'] }]"
        >
          <el-input v-model="formState.licensePlateNo" />
        </el-form-item>
        <el-form-item
            v-if="type === 'qualified' && formState.productType === 0"
            label="毛重(吨)"
            prop="grossWeight"
            :rules="[{ required: true, message: '请输入毛重', trigger: ['blur','change'] }]"
            v-if="type === 'qualified'"
            label="数量"
            prop="qualitity"
            :rules="[{ required: true, message: '请输入数量', trigger: ['blur', 'change'] }]"
        >
          <el-input-number
              v-model="formState.grossWeight"
              :step="0.01"
              v-model="formState.qualitity"
              :min="0"
              :step="1"
              :precision="0"
              style="width: 100%"
              @change="computeNetWeight"
              controls-position="right"
              placeholder="请输入数量"
          />
        </el-form-item>
        <el-form-item
            v-if="type === 'qualified' && formState.productType === 0"
            label="皮重(吨)"
            prop="tareWeight"
            :rules="[{ required: true, message: '请输入皮重', trigger: ['blur','change'] }]"
            v-if="type === 'qualified'"
            label="采购员"
            prop="purchaser"
            :rules="[{ required: true, message: '请输入采购员', trigger: ['blur', 'change'] }]"
        >
          <el-input-number
              v-model="formState.tareWeight"
              :step="0.01"
              :min="0"
              style="width: 100%"
              @change="computeNetWeight"
          />
        </el-form-item>
        <el-form-item
            v-if="type === 'qualified' && formState.productType === 0"
            label="净重(吨)"
            prop="netWeight"
            :rules="[{ required: true, message: '请先输入毛重和皮重自动计算净重', trigger: ['blur','change'] }]"
        >
          <el-input-number
              v-model="formState.netWeight"
              :step="0.01"
              :min="0"
              style="width: 100%"
              disabled
          />
        </el-form-item>
        <el-form-item
            v-if="type === 'qualified' && formState.productType === 0"
            label="过磅日期"
            prop="weighingDate"
            :rules="[{ required: true, message: '请选择过磅日期', trigger: 'change' }]"
        >
          <el-date-picker
              style="width: 100%"
              v-model="formState.weighingDate"
              value-format="YYYY-MM-DD HH:mm:ss"
              format="YYYY-MM-DD HH:mm:ss"
              type="datetime"
              placeholder="请选择过磅日期"
              clearable
          />
        </el-form-item>
        <el-form-item
            v-if="type === 'qualified' && formState.productType === 0"
            label="过磅员"
            prop="weighingOperator"
            :rules="[{ required: true, message: '请输入过磅员', trigger: ['blur','change'] }]"
        >
          <el-input v-model="formState.weighingOperator" />
          <el-input v-model="formState.purchaser" placeholder="请输入采购员" />
        </el-form-item>
        <el-form-item label="备注" prop="remark">
@@ -169,13 +114,8 @@
  productModelName: "",
  unit: "",
  productType: undefined,
  // 过磅相关字段(仅原材料合格品使用)
  licensePlateNo: "",
  grossWeight: undefined,
  tareWeight: undefined,
  netWeight: undefined,
  weighingDate: undefined,
  weighingOperator: "",
  qualitity: undefined,
  purchaser: "",
  remark: '',
});
@@ -193,23 +133,24 @@
let { proxy } = getCurrentInstance()
const closeModal = () => {
  // 重置表单数据
  formState.value = {
    productId: undefined,
    productModelId: undefined,
    productName: "",
    productModelName: "",
    description: '',
    unit: "",
    productType: undefined,
    qualitity: undefined,
    purchaser: "",
    remark: '',
  };
  isShow.value = false;
};
// 产品选择处理
const handleProductSelect = async (products) => {
  formState.value.weighingDate = undefined;
  formState.value.grossWeight = undefined;
  formState.value.tareWeight = undefined;
  formState.value.netWeight = undefined;
  formState.value.qualitity = undefined;
  formState.value.purchaser = "";
  if (products && products.length > 0) {
    const product = products[0];
    formState.value.productId = product.productId;
@@ -221,19 +162,6 @@
    showProductSelectDialog.value = false;
    // 触发表单验证更新
    proxy.$refs["formRef"]?.validateField('productModelId');
  }
};
// 净重 = 毛重 - 皮重
const computeNetWeight = () => {
  const { grossWeight, tareWeight } = formState.value;
  if (grossWeight != null && tareWeight != null) {
    const net = Number(grossWeight) - Number(tareWeight);
    // 保留两位小数,且不为负
    const safeNet = Number(net.toFixed(2));
    formState.value.netWeight = safeNet > 0 ? safeNet : 0;
  } else {
    formState.value.netWeight = undefined;
  }
};
src/views/consumablesLogistics/stockManagement/Qualified.vue
@@ -27,10 +27,8 @@
        <el-table-column label="产品大类" prop="productName" show-overflow-tooltip />
        <el-table-column label="规格型号" prop="model" show-overflow-tooltip />
        <el-table-column label="单位" prop="unit" show-overflow-tooltip />
        <el-table-column label="库存数量" prop="qualitity" show-overflow-tooltip />
        <el-table-column label="冻结数量" prop="lockedQuantity" show-overflow-tooltip />
        <!-- <el-table-column label="库存预警数量" prop="warnNum"  show-overflow-tooltip /> -->
        <el-table-column label="净重(吨)" prop="netWeight"  show-overflow-tooltip />
        <el-table-column label="数量" prop="qualitity" show-overflow-tooltip />
        <!-- <el-table-column label="采购员" prop="purchaser" show-overflow-tooltip /> -->
        <el-table-column label="备注" prop="remark"  show-overflow-tooltip />
        <el-table-column label="最近更新时间" prop="updateTime" show-overflow-tooltip />
        <el-table-column fixed="right" label="操作" min-width="60" align="center">
src/views/consumablesLogistics/stockManagement/Subtract.vue
@@ -38,71 +38,19 @@
        </el-form-item>
        <el-form-item
            label="车牌号"
            prop="licensePlateNo"
        >
          <el-input v-model="formState.licensePlateNo" />
        </el-form-item>
        <el-form-item
            label="毛重(吨)"
            prop="grossWeight"
            label="数量"
            prop="qualitity"
            :rules="[{ required: true, message: '请输入数量', trigger: ['blur', 'change'] }]"
        >
          <el-input-number
              v-model="formState.grossWeight"
              :step="0.01"
              v-model="formState.qualitity"
              :min="0"
              :step="1"
              :precision="0"
              style="width: 100%"
              @change="computeNetWeight"
              controls-position="right"
              placeholder="请输入数量"
          />
        </el-form-item>
        <el-form-item
            label="皮重(吨)"
            prop="tareWeight"
        >
          <el-input-number
              v-model="formState.tareWeight"
              :step="0.01"
              :min="0"
              style="width: 100%"
              @change="computeNetWeight"
          />
        </el-form-item>
        <el-form-item
            label="净重(吨)"
            prop="netWeight"
        >
          <el-input-number
              v-model="formState.netWeight"
              :step="0.01"
              :min="0"
              style="width: 100%"
              disabled
          />
        </el-form-item>
        <el-form-item
            label="过磅日期"
            prop="weighingDate"
        >
          <el-date-picker
              style="width: 100%"
              v-model="formState.weighingDate"
              value-format="YYYY-MM-DD HH:mm:ss"
              format="YYYY-MM-DD HH:mm:ss"
              type="datetime"
              placeholder="请选择过磅日期"
              clearable
          />
        </el-form-item>
        <el-form-item
            label="过磅员"
            prop="weighingOperator"
        >
          <el-input v-model="formState.weighingOperator" />
        </el-form-item>
        <el-form-item label="备注" prop="remark">
@@ -154,15 +102,6 @@
  initFormData()
})
const isRawMaterial = computed(() => {
  return props.record.parentName === '原材料';
})
const ledgerNetWeight = computed(() => {
  const n = Number(props.record?.netWeight ?? 0);
  return Number.isFinite(n) ? n : 0;
});
const initFormData = () => {
  if (props.record) {
    formState.value = {
@@ -178,13 +117,7 @@
  productName: "",
  model: "",
  unit: "",
  // 过磅相关字段
  licensePlateNo: "",
  grossWeight: undefined,
  tareWeight: undefined,
  netWeight: undefined,
  weighingDate: undefined,
  weighingOperator: "",
  qualitity: undefined,
  remark: '',
});
@@ -209,40 +142,10 @@
    productName: "",
    model: "",
    unit: "",
    licensePlateNo: "",
    grossWeight: undefined,
    tareWeight: undefined,
    netWeight: undefined,
    weighingDate: undefined,
    weighingOperator: "",
    qualitity: undefined,
    remark: '',
  };
  isShow.value = false;
};
// 净重 = 毛重 - 皮重
const computeNetWeight = () => {
  const { grossWeight, tareWeight } = formState.value;
  if (grossWeight != null && tareWeight != null) {
    const net = Number(grossWeight) - Number(tareWeight);
    const safeNet = Number(net.toFixed(2));
    const computedNet = safeNet > 0 ? safeNet : 0;
    const maxNet = ledgerNetWeight.value;
    if (Number.isFinite(maxNet) && maxNet > 0 && computedNet > maxNet) {
      const cappedNet = Number(maxNet.toFixed(2));
      formState.value.netWeight = cappedNet;
      // 同步毛重,保持:净重 = 毛重 - 皮重
      const tare = Number(tareWeight);
      if (Number.isFinite(tare)) {
        formState.value.grossWeight = Number((tare + cappedNet).toFixed(2));
      }
      proxy?.$modal?.msgWarning?.(`领用净重不能超过台账净重(${maxNet.toFixed(2)} 吨)`);
      return;
    }
    formState.value.netWeight = computedNet;
  } else {
    formState.value.netWeight = undefined;
  }
};
// 产品选择处理
@@ -273,10 +176,10 @@
        proxy.$modal.msgError("请选择规格");
        return;
      }
      const maxNet = ledgerNetWeight.value;
      const usedNet = Number(formState.value.netWeight ?? 0);
      if (Number.isFinite(maxNet) && maxNet > 0 && Number.isFinite(usedNet) && usedNet > maxNet) {
        proxy.$modal.msgError(`领用净重不能超过台账净重(${maxNet.toFixed(2)} 吨)`);
      const availableQty = Number(props.record?.qualitity ?? 0);
      const useQty = Number(formState.value.qualitity ?? 0);
      if (Number.isFinite(availableQty) && Number.isFinite(useQty) && useQty > availableQty) {
        proxy.$modal.msgError(`领用数量不能超过库存数量(${availableQty})`);
        return;
      }
      if (props.type === 'qualified') {
src/views/index.vue
@@ -243,7 +243,7 @@
const barSeries1 = ref([
  {
    name: '原材料不合格数',
    name: '入厂不合格数',
    type: 'bar',
    barGap: 0,
    emphasis: {
@@ -252,7 +252,7 @@
    data: []
  },
  {
    name: '过程不合格数',
    name: '车间不合格数',
    type: 'bar',
    emphasis: {
      focus: 'series'
@@ -284,7 +284,7 @@
}
const barLegend = {
  show: true,
  data: ['原材料不合格数', '过程不合格数', '出厂不合格数']
  data: ['入厂不合格数', '车间不合格数', '出厂不合格数']
}
const barLegend1 = {
  show: true,
src/views/inventoryManagement/dispatchLog/Record.vue
@@ -28,7 +28,7 @@
            </div>
            <div>
                <el-button @click="handleOut">导出</el-button>
                <el-button type="danger" plain @click="handleDelete">删除</el-button>
                <el-button type="danger" plain @click="handleDelete" v-if="hasDispatchCancel">删除</el-button>
                <!-- <el-button type="primary" plain @click="handlePrint">打印</el-button> -->
            </div>
        </div>
@@ -71,11 +71,11 @@
                    prop="unit"
                    show-overflow-tooltip
                />
                <el-table-column
                <!-- <el-table-column
                    label="出库数量"
                    prop="stockOutNum"
                    show-overflow-tooltip
                />
                /> -->
                <el-table-column
                    label="车牌号"
                    prop="licensePlateNo"
@@ -119,15 +119,128 @@
            show-overflow-tooltip
        />
        <el-table-column label="操作"
                         width="120"
                         width="260"
                         align="center">
          <template #default="scope">
            <el-button type="primary"
                       size="mini"
                       @click="handlePreview(scope.row)">导出过磅单</el-button>
            <el-button
              v-if="scope.row.recordType === '0' && hasDispatchEdit"
              type="primary"
              size="mini"
              @click="handleEdit(scope.row)"
            >编辑</el-button>
            <el-button
              v-if="scope.row.recordType === '0'"
              type="primary"
              size="mini"
              @click="handlePreview(scope.row)"
            >导出过磅单</el-button>
          </template>
        </el-table-column>
        </el-table-column>
            </el-table>
      <el-dialog
        v-model="isShowEditModal"
        title="编辑出库"
        width="800"
        @close="closeEditModal"
      >
        <el-form label-width="140px" :model="editForm" label-position="top" ref="editFormRef">
          <!-- <el-form-item
            label="出库数量"
            prop="stockOutNum"
          >
            <el-input-number
              v-model="editForm.stockOutNum"
              :min="0"
              :step="1"
              :precision="0"
              controls-position="right"
              style="width: 100%"
              disabled
            />
          </el-form-item> -->
          <el-form-item
            label="车牌号"
            prop="licensePlateNo"
            :rules="[{ required: true, message: '请输入车牌号', trigger: ['blur','change'] }]"
          >
            <el-input v-model="editForm.licensePlateNo" />
          </el-form-item>
          <el-form-item
            label="毛重(吨)"
            prop="grossWeight"
            :rules="[{ required: true, message: '请输入毛重', trigger: ['blur','change'] }]"
          >
            <el-input-number
              v-model="editForm.grossWeight"
              :step="0.01"
              :min="0"
              style="width: 100%"
              @change="computeNetWeightEdit"
            />
          </el-form-item>
          <el-form-item
            label="皮重(吨)"
            prop="tareWeight"
            :rules="[{ required: true, message: '请输入皮重', trigger: ['blur','change'] }]"
          >
            <el-input-number
              v-model="editForm.tareWeight"
              :step="0.01"
              :min="0"
              style="width: 100%"
              @change="computeNetWeightEdit"
            />
          </el-form-item>
          <el-form-item
            label="净重(吨)"
            prop="netWeight"
            :rules="[{ required: true, message: '净重由毛重和皮重自动计算', trigger: ['blur','change'] }]"
          >
            <el-input-number
              v-model="editForm.netWeight"
              :step="0.01"
              :min="0"
              style="width: 100%"
              disabled
            />
          </el-form-item>
          <el-form-item
            label="过磅日期"
            prop="weighingDate"
            :rules="[{ required: true, message: '请选择过磅日期', trigger: 'change' }]"
          >
            <el-date-picker
              style="width: 100%"
              v-model="editForm.weighingDate"
              value-format="YYYY-MM-DD HH:mm:ss"
              format="YYYY-MM-DD HH:mm:ss"
              type="datetime"
              placeholder="请选择过磅日期"
              clearable
            />
          </el-form-item>
          <el-form-item
            label="过磅员"
            prop="weighingOperator"
            :rules="[{ required: true, message: '请输入过磅员', trigger: ['blur','change'] }]"
          >
            <el-input v-model="editForm.weighingOperator" />
          </el-form-item>
        </el-form>
        <template #footer>
          <div class="dialog-footer">
            <el-button type="primary" @click="handleEditSubmit">确认</el-button>
            <el-button @click="closeEditModal">取消</el-button>
          </div>
        </template>
      </el-dialog>
            <pagination
                v-show="total > 0"
                :total="total"
@@ -142,13 +255,15 @@
<script setup>
import pagination from "@/components/PIMTable/Pagination.vue";
import { ref } from "vue";
import { ref, computed } from "vue";
import { ElMessageBox } from "element-plus";
import useUserStore from "@/store/modules/user";
import { getCurrentDate } from "@/utils/index.js";
import { checkPermi } from "@/utils/permission.js";
import {
    getStockOutPage,
    delStockOut,
  editStockOut,
} from "@/api/inventoryManagement/stockOut.js";
import {
  findAllQualifiedStockOutRecordTypeOptions, findAllUnQualifiedStockOutRecordTypeOptions,
@@ -174,6 +289,9 @@
    default: '0'
  }
})
const hasDispatchEdit = computed(() => checkPermi(['dispatch_edit']));
const hasDispatchCancel = computed(() => checkPermi(['dispatch_cancel']));
// 打印相关
const printPreviewVisible = ref(false);
@@ -248,6 +366,48 @@
  proxy.$download.name(row.weighbridgeDocPath);
}
// 编辑出库
const isShowEditModal = ref(false);
const editFormRef = ref(null);
const editForm = ref({});
// 毛重 - 皮重 计算净重(保留两位小数,且不为负)
const computeNetWeightEdit = () => {
  const gross = Number(editForm.value?.grossWeight ?? NaN);
  const tare = Number(editForm.value?.tareWeight ?? NaN);
  if (Number.isFinite(gross) && Number.isFinite(tare)) {
    const net = gross - tare;
    const safeNet = Number(net.toFixed(2));
    editForm.value.netWeight = safeNet > 0 ? safeNet : 0;
  } else {
    editForm.value.netWeight = undefined;
  }
};
const handleEdit = (row) => {
  editForm.value = { ...row };
  computeNetWeightEdit();
  isShowEditModal.value = true;
};
const closeEditModal = () => {
  isShowEditModal.value = false;
  editForm.value = {};
  editFormRef.value?.clearValidate?.();
};
const handleEditSubmit = () => {
  editFormRef.value?.validate?.((valid) => {
    if (!valid) return;
    const { stockOutNum, ...payload } = editForm.value || {};
    editStockOut(payload).then(() => {
      closeEditModal();
      proxy.$modal.msgSuccess("编辑成功");
      getList();
    });
  });
};
// 导出
const handleOut = () => {
    ElMessageBox.confirm("是否确认导出?", "导出", {
src/views/inventoryManagement/receiptManagement/Record.vue
@@ -34,7 +34,8 @@
        <el-button @click="handleOut">导出</el-button>
        <el-button type="danger"
                   plain
                   @click="handleDelete">删除
                   @click="handleDelete"
                   v-if="hasReceiptCancel">删除
        </el-button>
      </div>
    </div>
@@ -74,9 +75,9 @@
        <el-table-column label="单位"
                         prop="unit"
                         show-overflow-tooltip/>
        <el-table-column label="入库数量"
        <!-- <el-table-column label="入库数量"
                         prop="stockInNum"
                         show-overflow-tooltip/>
                         show-overflow-tooltip/> -->
        <el-table-column label="车牌号"
                         prop="licensePlateNo"
                         v-if="type === '0'"
@@ -112,9 +113,14 @@
                         v-if="type === '0'"
                         show-overflow-tooltip/>
        <el-table-column label="操作"
                         width="120"
                         width="260"
                         align="center">
          <template #default="scope">
            <el-button v-if="scope.row.recordType === '0' && hasReceiptEdit"
              type="primary"
              size="mini"
              @click="handleEdit(scope.row)"
            >编辑</el-button>
            <el-button v-if="scope.row.recordType === '0'"
                       type="primary"
                       size="mini"
@@ -122,6 +128,112 @@
          </template>
        </el-table-column>
      </el-table>
      <el-dialog
        v-model="isShowEditModal"
        title="编辑入库"
        width="800"
        @close="closeEditModal"
      >
        <el-form label-width="140px" :model="editForm" label-position="top" ref="editFormRef">
          <!-- <el-form-item
            label="入库数量"
            prop="stockInNum"
          >
            <el-input-number
              v-model="editForm.stockInNum"
              :min="0"
              :step="1"
              :precision="0"
              controls-position="right"
              style="width: 100%"
              disabled
            />
          </el-form-item> -->
          <template v-if="type === '0'">
            <el-form-item
              label="车牌号"
              prop="licensePlateNo"
              :rules="[{ required: true, message: '请输入车牌号', trigger: ['blur', 'change'] }]"
            >
              <el-input v-model="editForm.licensePlateNo" />
            </el-form-item>
            <el-form-item
              label="毛重(吨)"
              prop="grossWeight"
              :rules="[{ required: true, message: '请输入毛重', trigger: ['blur', 'change'] }]"
            >
              <el-input-number
                v-model="editForm.grossWeight"
                :step="0.01"
                :min="0"
                style="width: 100%"
                @change="computeNetWeightEdit"
              />
            </el-form-item>
            <el-form-item
              label="皮重(吨)"
              prop="tareWeight"
              :rules="[{ required: true, message: '请输入皮重', trigger: ['blur', 'change'] }]"
            >
              <el-input-number
                v-model="editForm.tareWeight"
                :step="0.01"
                :min="0"
                style="width: 100%"
                @change="computeNetWeightEdit"
              />
            </el-form-item>
            <el-form-item
              label="净重(吨)"
              prop="netWeight"
              :rules="[{ required: true, message: '请输入净重', trigger: ['blur', 'change'] }]"
            >
              <el-input-number
                v-model="editForm.netWeight"
                :step="0.01"
                :min="0"
                style="width: 100%"
                disabled
              />
            </el-form-item>
            <el-form-item
              label="过磅日期"
              prop="weighingDate"
              :rules="[{ required: true, message: '请选择过磅日期', trigger: 'change' }]"
            >
              <el-date-picker
                style="width: 100%"
                v-model="editForm.weighingDate"
                value-format="YYYY-MM-DD HH:mm:ss"
                format="YYYY-MM-DD HH:mm:ss"
                type="datetime"
                placeholder="请选择过磅日期"
                clearable
              />
            </el-form-item>
            <el-form-item
              label="过磅员"
              prop="weighingOperator"
              :rules="[{ required: true, message: '请输入过磅员', trigger: ['blur', 'change'] }]"
            >
              <el-input v-model="editForm.weighingOperator" />
            </el-form-item>
          </template>
        </el-form>
        <template #footer>
          <div class="dialog-footer">
            <el-button type="primary" @click="handleEditSubmit">确认</el-button>
            <el-button @click="closeEditModal">取消</el-button>
          </div>
        </template>
      </el-dialog>
      <div style="margin-top: 12px; display: flex; justify-content: flex-end;">
        <pagination v-show="total > 0"
                    :total="total"
@@ -142,11 +254,14 @@
  toRefs,
  onMounted,
  getCurrentInstance,
  computed,
} from "vue";
import {ElMessageBox} from "element-plus";
import { checkPermi } from "@/utils/permission.js";
import {
  getStockInRecordListPage,
  batchDeleteStockInRecords,
  editStockInStock,
} from "@/api/inventoryManagement/stockInRecord.js";
import {
  findAllQualifiedStockInRecordTypeOptions, findAllUnQualifiedStockInRecordTypeOptions,
@@ -161,6 +276,9 @@
    default: '0'
  }
})
const hasReceiptEdit = computed(() => checkPermi(['receipt_edit']));
const hasReceiptCancel = computed(() => checkPermi(['receipt_cancel']));
const tableData = ref([]);
const selectedRows = ref([]);
@@ -240,6 +358,50 @@
  proxy.$download.name(row.weighbridgeDocPath);
}
// 编辑
const isShowEditModal = ref(false);
const editFormRef = ref(null);
const editForm = ref({});
// 毛重 - 皮重 计算净重(保留两位小数,且不为负)
const computeNetWeightEdit = () => {
  const gross = Number(editForm.value?.grossWeight ?? NaN);
  const tare = Number(editForm.value?.tareWeight ?? NaN);
  if (Number.isFinite(gross) && Number.isFinite(tare)) {
    const net = gross - tare;
    const safeNet = Number(net.toFixed(2));
    editForm.value.netWeight = safeNet > 0 ? safeNet : 0;
  } else {
    editForm.value.netWeight = undefined;
  }
};
const handleEdit = (row) => {
  editForm.value = { ...row };
  if (props.type === '0') {
    computeNetWeightEdit();
  }
  isShowEditModal.value = true;
};
const closeEditModal = () => {
  isShowEditModal.value = false;
  editForm.value = {};
  // 清理表单校验状态(有 ref 时)
  editFormRef.value?.clearValidate?.();
};
const handleEditSubmit = () => {
  editFormRef.value?.validate?.((valid) => {
    if (!valid) return;
    editStockInStock(editForm.value).then(() => {
      closeEditModal();
      proxy.$modal.msgSuccess("编辑成功");
      getList();
    });
  });
};
// 导出
const handleOut = () => {
  ElMessageBox.confirm("是否确认导出?", "导出", {
src/views/inventoryManagement/stockManagement/Qualified.vue
@@ -30,7 +30,7 @@
        <el-table-column label="库存数量" prop="qualitity" show-overflow-tooltip />
        <el-table-column label="冻结数量" prop="lockedQuantity" show-overflow-tooltip />
        <!-- <el-table-column label="库存预警数量" prop="warnNum"  show-overflow-tooltip /> -->
        <el-table-column label="净重(吨)" prop="netWeight"  show-overflow-tooltip />
        <!-- <el-table-column label="净重(吨)" prop="netWeight"  show-overflow-tooltip /> -->
        <el-table-column label="备注" prop="remark"  show-overflow-tooltip />
        <el-table-column label="最近更新时间" prop="updateTime" show-overflow-tooltip />
        <el-table-column fixed="right" label="操作" min-width="60" align="center">
src/views/inventoryManagement/stockManagement/Subtract.vue
@@ -40,6 +40,7 @@
        <el-form-item
            label="车牌号"
            prop="licensePlateNo"
            :rules="[{ required: true, message: '请输入车牌号', trigger: ['blur','change'] }]"
        >
          <el-input v-model="formState.licensePlateNo" />
        </el-form-item>
@@ -47,6 +48,7 @@
        <el-form-item
            label="毛重(吨)"
            prop="grossWeight"
            :rules="[{ required: true, message: '请输入毛重', trigger: ['blur','change'] }]"
        >
          <el-input-number
              v-model="formState.grossWeight"
@@ -60,6 +62,7 @@
        <el-form-item
            label="皮重(吨)"
            prop="tareWeight"
            :rules="[{ required: true, message: '请输入皮重', trigger: ['blur','change'] }]"
        >
          <el-input-number
              v-model="formState.tareWeight"
@@ -73,6 +76,7 @@
        <el-form-item
            label="净重(吨)"
            prop="netWeight"
            :rules="[{ required: true, message: '净重由毛重和皮重自动计算', trigger: ['blur','change'] }]"
        >
          <el-input-number
              v-model="formState.netWeight"
@@ -86,6 +90,7 @@
        <el-form-item
            label="过磅日期"
            prop="weighingDate"
            :rules="[{ required: true, message: '请选择过磅日期', trigger: 'change' }]"
        >
          <el-date-picker
              style="width: 100%"
@@ -101,6 +106,7 @@
        <el-form-item
            label="过磅员"
            prop="weighingOperator"
            :rules="[{ required: true, message: '请输入过磅员', trigger: ['blur','change'] }]"
        >
          <el-input v-model="formState.weighingOperator" />
        </el-form-item>
@@ -168,6 +174,8 @@
    formState.value = {
      ...props.record,
    }
    // 初始化时也触发一次净重计算,避免接口回填后净重为空
    computeNetWeight()
  }
}
src/views/qualityManagement/nonconformingManagement/components/formDia.vue
@@ -11,6 +11,7 @@
          <el-col :span="12">
            <el-form-item label="产品名称:" prop="productId">
              <el-tree-select
                  v-if="operationType !== 'edit'"
                  v-model="form.productId"
                  placeholder="请选择"
                  clearable
@@ -18,7 +19,13 @@
                  @change="getModels"
                  :data="productOptions"
                  :render-after-expand="false"
                  :disabled="operationType === 'edit'"
                  style="width: 100%"
              />
              <!-- 编辑态:不依赖下拉选项回显,直接展示文本 -->
              <el-input
                  v-else
                  v-model="form.productName"
                  disabled
                  style="width: 100%"
              />
            </el-form-item>
@@ -26,16 +33,28 @@
          <el-col :span="12">
            <el-form-item label="规格型号:" prop="productModelId">
              <el-select
                  v-if="operationType !== 'edit'"
                  v-model="form.productModelId"
                  placeholder="请选择"
                  clearable
                  :disabled="operationType === 'edit'"
                  filterable
                  readonly
                  @change="handleChangeModel"
              >
                <el-option v-for="item in modelOptions" :key="item.id" :label="item.model" :value="item.id" />
                <el-option
                    v-for="item in modelOptions"
                    :key="item.id"
                    :label="item.model"
                    :value="item.id"
                />
              </el-select>
              <!-- 编辑态:不展示规格型号列表,直接展示文本 -->
              <el-input
                  v-else
                  v-model="form.model"
                  disabled
                  style="width: 100%"
              />
            </el-form-item>
          </el-col>
        </el-row>
@@ -187,7 +206,7 @@
  },
  rules: {
    checkTime: [{ required: true, message: "请选择检测日期", trigger: "change" }],
    checkUserName: [{ required: true, message: "请选择检验员", trigger: "change" }],
    checkName: [{ required: true, message: "请选择检验员", trigger: "change" }],
    productId: [{ required: true, message: "请选择产品名称", trigger: "change" }],
    productModelId: [{ required: true, message: "请选择规格型号", trigger: "change" }],
    batchNo: [{ required: true, message: "请输入批号", trigger: "blur" }],
@@ -203,27 +222,114 @@
const modelOptions = ref([])
// 打开弹框
const openDialog = (type, row) => {
const openDialog = async (type, row) => {
  operationType.value = type;
  userListNoPage().then(res => {
    userList.value = res.data || [];
  })
  dialogFormVisible.value = true;
  form.value = {}
  getProductOptions();
  // 编辑态不校验规格型号(prop 仍绑定 productModelId,但编辑态改为文本展示)
  data.rules.productModelId = [
    {
      required: type !== "edit",
      message: "请选择规格型号",
      trigger: "change",
    },
  ];
  // 先加载下拉选项,确保编辑数据可以正确匹配回显
  const userRes = await userListNoPage();
  userList.value = userRes.data || [];
  await getProductOptions();
  // 处理结果默认“报废”,且不可选择其它项
  form.value.dealResult = getScrapDealResultValue();
  if (operationType.value === 'edit') {
    getQualityUnqualifiedInfo(row.id).then(res => {
      const { inspectState, ...rest } = (res.data || {})
      form.value = { ...rest, dealResult: getScrapDealResultValue() }
    })
    const fallback = row || {};
    const res = await getQualityUnqualifiedInfo(fallback.id);
    const { inspectState, ...rest } = res.data || {};
    // 先用列表行数据把“必回显字段”直接填上,避免详情接口字段名不一致导致全空。
    const productName = rest?.productName ?? fallback?.productName;
    const modelName = rest?.model ?? fallback?.model;
    const checkTypeValue = rest?.checkType ?? fallback?.checkType;
    const checkNameValue =
      rest?.checkName ??
      rest?.checkUserName ??
      fallback?.checkName ??
      fallback?.checkUserName;
    const productId =
      rest?.productId ??
      findProductIdByLabel(productOptions.value, productName);
    // 先回填字段(productModelId 需要依赖 modelOptions,稍后再补)
    const normalizedProductId = normalizeProductIdByOptions(productId);
    // 编辑态产品名称展示只展示 label,避免树组件回显依赖 value 匹配
    const productNameLabel =
      rest?.productName ??
      fallback?.productName ??
      findNodeById(productOptions.value, normalizedProductId) ??
      productName;
    form.value = {
      ...rest,
      productName: productNameLabel,
      productId: normalizedProductId,
      productModelId: rest?.productModelId ?? undefined,
      model: rest?.model ?? fallback?.model,
      unit: rest?.unit ?? fallback?.unit,
      batchNo: rest?.batchNo ?? fallback?.batchNo ?? "",
      checkType:
        checkTypeValue === undefined || checkTypeValue === null
          ? undefined
          : Number(checkTypeValue),
      checkName: checkNameValue ?? "",
      checkTime: rest?.checkTime ?? fallback?.checkTime ?? "",
      defectivePhenomena:
        rest?.defectivePhenomena ?? fallback?.defectivePhenomena ?? "",
      dealName: rest?.dealName ?? fallback?.dealName ?? "",
      dealTime: rest?.dealTime ?? fallback?.dealTime ?? "",
      dealResult: getScrapDealResultValue(),
    };
    // 规格型号下拉需要依赖 productId
    await loadModelsForProductId(form.value.productId);
    // 规格型号回显(如详情没给 productModelId,就用 model 名称反查)
    if (!form.value.productModelId) {
      form.value.productModelId = findModelIdByModel(
        modelOptions.value,
        modelName
      );
    }
    // 根据 productModelId 回填 model/unit
    if (form.value.productModelId) {
      form.value.productModelId = normalizeModelIdByOptions(form.value.productModelId);
      handleChangeModel(form.value.productModelId);
    } else if (modelName) {
      // productModelId 仍然拿不到时,至少保证 model/unit 文本回显
      const matched =
        (modelOptions.value || []).find((m) => {
          const model = String(m?.model ?? "");
          const id = String(m?.id ?? "");
          const target = String(modelName ?? "");
          return model === target || id === target;
        }) ?? null;
      if (matched) {
        form.value.model = matched.model ?? form.value.model;
        form.value.unit = matched.unit ?? form.value.unit;
      } else {
        form.value.model = modelName;
      }
    }
  }
}
const getProductOptions = () => {
  productTreeList().then((res) => {
    productOptions.value = convertIdToValue(res);
  });
const getProductOptions = async () => {
  const res = await productTreeList();
  productOptions.value = convertIdToValue(res);
};
const getModels = (value) => {
  form.value.productName = findNodeById(productOptions.value, value);
@@ -236,9 +342,41 @@
  })
};
// 编辑模式/或任意需要时:只拉取规格型号列表,不清空已回填的字段
const loadModelsForProductId = async (productId) => {
  if (!productId) return;
  const res = await modelList({ id: productId });
  modelOptions.value = res || [];
  // 让单位/型号等字段保持与当前 productModelId 一致
  if (form.value.productModelId) {
    form.value.productModelId = normalizeModelIdByOptions(form.value.productModelId);
    handleChangeModel(form.value.productModelId);
  }
};
const handleChangeModel = (value) => {
  form.value.model = modelOptions.value.find(item => item.id == value)?.model || '';
  form.value.unit = modelOptions.value.find(item => item.id == value)?.unit || '';
};
// 解决回显时类型不一致导致 el-tree-select / el-select 只显示 value(id)
const normalizeProductIdByOptions = (productId) => {
  if (productId === undefined || productId === null) return productId;
  const target = String(productId);
  const stack = Array.isArray(productOptions.value) ? [...productOptions.value] : [];
  while (stack.length) {
    const node = stack.shift();
    if (node && String(node?.value ?? "") === target) return node?.value;
    if (node?.children?.length) stack.push(...node.children);
  }
  return productId;
};
const normalizeModelIdByOptions = (modelId) => {
  if (modelId === undefined || modelId === null) return modelId;
  const target = String(modelId);
  return (modelOptions.value || []).find((m) => String(m?.id ?? "") === target)?.id ?? modelId;
};
const findNodeById = (nodes, productId) => {
  for (let i = 0; i < nodes.length; i++) {
@@ -254,6 +392,33 @@
  }
  return null; // 没有找到节点,返回null
};
// 根据树节点 label 回填 value(编辑回显兜底用)
const findProductIdByLabel = (nodes, label) => {
  const target = String(label ?? "");
  if (!target) return undefined;
  const stack = Array.isArray(nodes) ? [...nodes] : [];
  while (stack.length) {
    const node = stack.shift();
    if (node && String(node?.label ?? "") === target) return node?.value;
    if (node?.children?.length) stack.push(...node.children);
  }
  return undefined;
};
// 根据规格型号名称反查 id(编辑回显兜底用)
const findModelIdByModel = (models, model) => {
  const target = String(model ?? "");
  if (!target) return undefined;
  return (
    (models || []).find((m) => {
      const mModel = String(m?.model ?? "");
      const mId = String(m?.id ?? "");
      return mModel === target || mId === target;
    })?.id
  );
};
function convertIdToValue(data) {
  return data.map((item) => {
    const { id, children, ...rest } = item;
src/views/qualityManagement/nonconformingManagement/index.vue
@@ -37,7 +37,12 @@
      <div>
        <el-button type="primary" @click="openForm('add')">新增</el-button>
        <el-button @click="handleOut">导出</el-button>
        <el-button type="danger" plain @click="handleDelete">删除</el-button>
        <el-button
            type="danger"
            plain
            @click="handleDelete"
            v-if="hasNonconformingCancel"
        >删除</el-button>
      </div>
    </div>
    <div class="table_list">
@@ -60,12 +65,13 @@
<script setup>
import { Search } from "@element-plus/icons-vue";
import {onMounted, ref} from "vue";
import { onMounted, ref, computed } from "vue";
import FormDia from "@/views/qualityManagement/nonconformingManagement/components/formDia.vue";
import {ElMessageBox} from "element-plus";
import {qualityUnqualifiedDel, qualityUnqualifiedListPage} from "@/api/qualityManagement/nonconformingManagement.js";
import InspectionFormDia from "@/views/qualityManagement/nonconformingManagement/components/inspectionFormDia.vue";
import dayjs from "dayjs";
import { checkPermi } from "@/utils/permission.js";
const data = reactive({
  searchForm: {
@@ -78,6 +84,10 @@
  },
});
const { searchForm } = toRefs(data);
const hasNonconformingEdit = computed(() => checkPermi(["nonconforming_edit"]));
const hasNonconformingCancel = computed(() => checkPermi(["nonconforming_cancel"]));
const tableColumn = ref([
  {
    label: "检测日期",
@@ -154,6 +164,23 @@
    prop: "dealTime",
    width: 120
  },
  {
    dataType: "action",
    label: "操作",
    align: "center",
    fixed: "right",
    width: 180,
    operation: [
      {
        name: "编辑",
        type: "text",
        showHide: (row) => hasNonconformingEdit.value,
        clickFun: (row) => {
          openForm("edit", row);
        },
      },
    ],
  },
]);
const tableData = ref([]);
const selectedRows = ref([]);
@@ -206,10 +233,6 @@
// 打开弹框
const openForm = (type, row) => {
  if (type !== 'add' && row?.inspectState === 1) {
    proxy.$modal.msgWarning("已处理的数据不能再编辑");
    return;
  }
  nextTick(() => {
    formDia.value?.openDialog(type, row)
  })
src/views/qualityManagement/rawMaterial/components/formDia.vue
@@ -203,6 +203,14 @@
const currentProductId = ref(0);
const modelOptions = ref([]);
const getTodayStr = () => {
  const now = new Date();
  const y = now.getFullYear();
  const m = String(now.getMonth() + 1).padStart(2, "0");
  const d = String(now.getDate()).padStart(2, "0");
  return `${y}-${m}-${d}`;
};
// 打开弹框
const openDialog = async (type, row) => {
  operationType.value = type;
@@ -211,7 +219,7 @@
  })
  // 先重置表单数据(保持字段完整,避免弹窗首次渲染时触发必填红框“闪一下”)
  form.value = {
    checkTime: "",
    checkTime: getTodayStr(),
    supplier: "",
    productName: "",
    productId: "",
src/views/qualityManagement/rawMaterial/index.vue
@@ -45,7 +45,7 @@
      <div>
        <el-button type="primary" @click="openForm('add')">新增</el-button>
        <el-button @click="handleOut">导出</el-button>
        <el-button type="danger" plain @click="handleDelete">删除</el-button>
        <el-button type="danger" plain @click="handleDelete" v-if="hasRawCancel">删除</el-button>
      </div>
    </div>
    <div class="table_list">
@@ -86,7 +86,7 @@
</template>
<script setup>
import {onMounted, ref, reactive, toRefs, getCurrentInstance, nextTick} from "vue";
import {onMounted, ref, reactive, toRefs, getCurrentInstance, nextTick, computed} from "vue";
import InspectionFormDia from "@/views/qualityManagement/rawMaterial/components/inspectionFormDia.vue";
import FormDia from "@/views/qualityManagement/rawMaterial/components/formDia.vue";
import {ElMessageBox} from "element-plus";
@@ -99,6 +99,7 @@
  findRawMaterialListPage,
  submitRawMaterial, updateCheckUserName,downloadRawMaterial
} from "@/api/qualityManagement/rawMaterial.js";
import { checkPermi } from "@/utils/permission.js";
const data = reactive({
  searchForm: {
@@ -114,6 +115,8 @@
  },
});
const {searchForm, rules} = toRefs(data);
const hasRawCancel = computed(() => checkPermi(["raw_cancel"]));
const tableColumn = ref([
  {
    label: "检测日期",
@@ -190,11 +193,6 @@
        disabled: (row) => {
          // 已提交则禁用
          if (row.inspectState == 1) return true;
          // 如果检验员有值,只有当前登录用户能编辑
          if (row.checkUserName) {
            return row.checkUserName !== userStore.nickName;
          }
          return false;
        }
      },
      {
@@ -216,20 +214,20 @@
          return false;
        }
      },
      {
        name: "分配检验员",
        type: "text",
        clickFun: (row) => {
          if (!row.checkUserName) {
            open(row)
          } else {
            proxy.$modal.msgError("检验员已存在");
          }
        },
        disabled: (row) => {
          return row.inspectState === 1 || row.checkUserName || row.checkUserName !== '';
        }
      },
      // {
      //   name: "分配检验员",
      //   type: "text",
      //   clickFun: (row) => {
      //     if (!row.checkUserName) {
      //       open(row)
      //     } else {
      //       proxy.$modal.msgError("检验员已存在");
      //     }
      //   },
      //   disabled: (row) => {
      //     return row.inspectState === 1 || row.checkUserName || row.checkUserName !== '';
      //   }
      // },
      {
        name: "下载",
        type: "text",
vite.config.js
@@ -51,7 +51,7 @@
    },
    // vite 相关配置
    server: {
      port: 80,
      port: 8001,
      host: true,
      open: true,
      proxy: {