更新质量管理模块,新增合格数量和不合格数量字段,修改数量标签为总数量,计算合格率展示
| | |
| | | placeholder="请输入单位" |
| | | disabled /> |
| | | </up-form-item> |
| | | <up-form-item label="数量" |
| | | <up-form-item label="总数量" |
| | | prop="quantity" |
| | | required |
| | | border-bottom> |
| | | <up-input v-model="form.quantity" |
| | | type="number" |
| | | placeholder="请输入数量" |
| | | placeholder="请输入总数量" |
| | | :disabled="processQuantityDisabled" /> |
| | | </up-form-item> |
| | | <up-form-item label="合格数量" |
| | | prop="qualifiedQuantity" |
| | | required |
| | | border-bottom> |
| | | <up-input v-model="form.qualifiedQuantity" |
| | | type="number" |
| | | placeholder="请输入合格数量" |
| | | clearable /> |
| | | </up-form-item> |
| | | <up-form-item label="不合格数量" |
| | | prop="unqualifiedQuantity" |
| | | required |
| | | border-bottom> |
| | | <up-input v-model="form.unqualifiedQuantity" |
| | | type="number" |
| | | placeholder="请输入不合格数量" |
| | | clearable /> |
| | | </up-form-item> |
| | | <up-form-item label="检测单位" |
| | | prop="checkCompany" |
| | |
| | | <up-input v-model="form.checkCompany" |
| | | placeholder="请输入检测单位" |
| | | clearable /> |
| | | </up-form-item> |
| | | <up-form-item label="检测结果" |
| | | prop="checkResult" |
| | | required |
| | | border-bottom> |
| | | <up-input v-model="form.checkResult" |
| | | placeholder="请选择检测结果" |
| | | readonly |
| | | @click="showResultSheet" /> |
| | | <template #right> |
| | | <up-icon @click="showResultSheet = true" |
| | | name="arrow-right" /> |
| | | </template> |
| | | </up-form-item> |
| | | <up-form-item label="检验员" |
| | | prop="checkName" |
| | |
| | | @select="selectModel" |
| | | @close="showModelSheet = false" |
| | | title="选择规格型号" /> |
| | | <!-- 检测结果选择 --> |
| | | <up-action-sheet :show="showResultSheet" |
| | | :actions="resultSheetOptions" |
| | | @select="selectResult" |
| | | @close="showResultSheet = false" |
| | | title="选择检测结果" /> |
| | | <!-- 检验员选择 --> |
| | | <up-action-sheet :show="showInspectorSheet" |
| | | :actions="userSheetOptions" |
| | |
| | | const showProductTree = ref(false); |
| | | // 规格型号选择 |
| | | const showModelSheet = ref(false); |
| | | // 检测结果选择 |
| | | const showResultSheet = ref(false); |
| | | // 检验员选择 |
| | | const showInspectorSheet = ref(false); |
| | | // 指标选择 |
| | |
| | | testStandardId: "", |
| | | unit: "", |
| | | quantity: "", |
| | | qualifiedQuantity: "", |
| | | unqualifiedQuantity: "", |
| | | checkCompany: "", |
| | | checkResult: "", |
| | | productMainId: null, |
| | | purchaseLedgerId: null, |
| | | }); |
| | |
| | | const modelOptions = ref([]); |
| | | // 检验员列表 |
| | | const userList = ref([]); |
| | | // 检测结果选项 |
| | | const resultOptions = ref([ |
| | | { label: "合格", value: "合格" }, |
| | | { label: "不合格", value: "不合格" }, |
| | | ]); |
| | | // 指标选项 |
| | | const testStandardOptions = ref([]); |
| | | // 当前产品ID |
| | |
| | | return modelOptions.value.map(item => ({ |
| | | name: item.model, |
| | | value: item.id, |
| | | })); |
| | | }); |
| | | |
| | | const resultSheetOptions = computed(() => { |
| | | return resultOptions.value.map(item => ({ |
| | | name: item.label, |
| | | value: item.value, |
| | | })); |
| | | }); |
| | | |
| | |
| | | ], |
| | | unit: [{ required: false, message: "请输入", trigger: "blur" }], |
| | | quantity: [{ required: true, message: "请输入", trigger: "blur" }], |
| | | checkCompany: [{ required: false, message: "请输入", trigger: "blur" }], |
| | | checkResult: [ |
| | | { required: true, message: "请选择检测结果", trigger: "change" }, |
| | | qualifiedQuantity: [ |
| | | { required: true, message: "请输入合格数量", trigger: "blur" }, |
| | | ], |
| | | unqualifiedQuantity: [ |
| | | { required: true, message: "请输入不合格数量", trigger: "blur" }, |
| | | ], |
| | | checkCompany: [{ required: false, message: "请输入", trigger: "blur" }], |
| | | }; |
| | | |
| | | // 是否为编辑模式 |
| | |
| | | modelOptions.value.find(item => item.id == value)?.model || ""; |
| | | form.value.unit = |
| | | modelOptions.value.find(item => item.id == value)?.unit || ""; |
| | | }; |
| | | |
| | | // 选择检测结果 |
| | | const selectResult = e => { |
| | | form.value.checkResult = e.value; |
| | | showResultSheet.value = false; |
| | | }; |
| | | |
| | | // 选择检验员 |
| | |
| | | // showToast("请选择工序"); |
| | | // return; |
| | | // } |
| | | if (!form.value.quantity) { |
| | | showToast("请输入数量"); |
| | | if (!form.value.quantity && form.value.quantity !== 0) { |
| | | showToast("请输入总数量"); |
| | | return; |
| | | } |
| | | if ( |
| | | form.value.qualifiedQuantity === "" || |
| | | form.value.qualifiedQuantity === undefined |
| | | ) { |
| | | showToast("请输入合格数量"); |
| | | return; |
| | | } |
| | | if ( |
| | | form.value.unqualifiedQuantity === "" || |
| | | form.value.unqualifiedQuantity === undefined |
| | | ) { |
| | | showToast("请输入不合格数量"); |
| | | return; |
| | | } |
| | | const qty = Number(form.value.quantity); |
| | | const qf = Number(form.value.qualifiedQuantity); |
| | | const uq = Number(form.value.unqualifiedQuantity); |
| | | if (Number.isNaN(qty) || qty < 0) { |
| | | showToast("总数量格式不正确"); |
| | | return; |
| | | } |
| | | if (Number.isNaN(qf) || qf < 0 || Number.isNaN(uq) || uq < 0) { |
| | | showToast("合格/不合格数量格式不正确"); |
| | | return; |
| | | } |
| | | if (qf + uq !== qty) { |
| | | showToast("合格数量与不合格数量之和须等于总数量"); |
| | | return; |
| | | } |
| | | if (!form.value.productId) { |
| | | showToast("请选择产品"); |
| | | return; |
| | | } |
| | | if (!form.value.checkResult) { |
| | | showToast("请选择检测结果"); |
| | | return; |
| | | } |
| | | |
| | |
| | | } |
| | | |
| | | const data = { ...form.value, qualityInspectParams: tableData.value }; |
| | | data.quantity = Number(data.quantity); |
| | | data.quantity = qty; |
| | | data.qualifiedQuantity = qf; |
| | | data.unqualifiedQuantity = uq; |
| | | if (isEdit.value) { |
| | | const res = await qualityInspectUpdate(data); |
| | | showToast("保存成功"); |
| | |
| | | testStandardId: "", |
| | | unit: "", |
| | | quantity: "", |
| | | qualifiedQuantity: "", |
| | | unqualifiedQuantity: "", |
| | | checkCompany: "", |
| | | checkResult: "", |
| | | productMainId: null, |
| | | purchaseLedgerId: null, |
| | | }; |
| | |
| | | testStandardId: "1", |
| | | unit: "kg", |
| | | quantity: 1000, |
| | | qualifiedQuantity: 1000, |
| | | unqualifiedQuantity: 0, |
| | | checkCompany: "第三方检测机构", |
| | | checkResult: "合格", |
| | | productMainId: null, |
| | | purchaseLedgerId: null, |
| | | }; |
| | |
| | | testStandardId: "", |
| | | unit: "", |
| | | quantity: "", |
| | | qualifiedQuantity: "", |
| | | unqualifiedQuantity: "", |
| | | checkCompany: "", |
| | | checkResult: "", |
| | | productMainId: null, |
| | | purchaseLedgerId: null, |
| | | }; |
| | |
| | | </view> |
| | | <text class="header-title">{{ detailData.productName || '-' }}</text> |
| | | <view class="status-tags"> |
| | | <u-tag :type="getTagType(detailData.checkResult)" |
| | | <u-tag :type="getPassRateTagType(detailData.passRate)" |
| | | size="small" |
| | | class="status-tag"> |
| | | {{ detailData.checkResult || '-' }} |
| | | 合格率 {{ formatPassRate(detailData.passRate) }} |
| | | </u-tag> |
| | | <u-tag :type="getStateTagType(detailData.inspectState)" |
| | | size="small" |
| | |
| | | <text class="detail-value">{{ detailData.unit || '-' }}</text> |
| | | </view> |
| | | <view class="detail-row"> |
| | | <text class="detail-label">数量</text> |
| | | <text class="detail-value">{{ detailData.quantity || 0 }}</text> |
| | | <text class="detail-label">总数量</text> |
| | | <text class="detail-value">{{ detailData.quantity ?? '-' }}</text> |
| | | </view> |
| | | <view class="detail-row"> |
| | | <text class="detail-label">合格数量</text> |
| | | <text class="detail-value">{{ detailData.qualifiedQuantity ?? '-' }}</text> |
| | | </view> |
| | | <view class="detail-row"> |
| | | <text class="detail-label">不合格数量</text> |
| | | <text class="detail-value">{{ detailData.unqualifiedQuantity ?? '-' }}</text> |
| | | </view> |
| | | <view class="detail-row"> |
| | | <text class="detail-label">合格率</text> |
| | | <text class="detail-value">{{ formatPassRate(detailData.passRate) }}</text> |
| | | </view> |
| | | <view class="detail-row"> |
| | | <text class="detail-label">检测单位</text> |
| | |
| | | return dayjs(date).format("YYYY-MM-DD"); |
| | | }; |
| | | |
| | | // 获取标签类型 |
| | | const getTagType = result => { |
| | | switch (result) { |
| | | case "合格": |
| | | return "success"; |
| | | case "不合格": |
| | | return "error"; |
| | | default: |
| | | return "info"; |
| | | } |
| | | const formatPassRate = val => { |
| | | if (val === null || val === undefined || val === "") return "-"; |
| | | const n = Number(val); |
| | | if (Number.isNaN(n)) return String(val); |
| | | if (n > 0 && n <= 1) return `${(n * 100).toFixed(1)}%`; |
| | | return `${Number.isInteger(n) ? n : Number(n.toFixed(1))}%`; |
| | | }; |
| | | |
| | | const getPassRateTagType = val => { |
| | | if (val === null || val === undefined || val === "") return "info"; |
| | | let n = Number(val); |
| | | if (Number.isNaN(n)) return "info"; |
| | | if (n > 0 && n <= 1) n *= 100; |
| | | if (n >= 100) return "success"; |
| | | if (n >= 60) return "warning"; |
| | | return "error"; |
| | | }; |
| | | |
| | | // 获取状态标签类型 |
| | |
| | | </view> |
| | | </view> |
| | | <view class="status-tags"> |
| | | <u-tag :type="getTagType(item.checkResult)" |
| | | v-if="item.checkResult!=null" |
| | | <u-tag :type="getPassRateTagType(item.passRate)" |
| | | v-if="item.passRate != null && item.passRate !== ''" |
| | | size="mini" |
| | | class="status-tag"> |
| | | {{ item.checkResult }} |
| | | {{ formatPassRate(item.passRate) }} |
| | | </u-tag> |
| | | <u-tag :type="getStateTagType(item.inspectState)" |
| | | size="mini" |
| | |
| | | <text class="detail-value">{{ item.checkName || '-' }}</text> |
| | | </view> |
| | | <view class="detail-row"> |
| | | <text class="detail-label">数量</text> |
| | | <text class="detail-label">总数量</text> |
| | | <text class="detail-value">{{ item.quantity || 0 }} {{ item.unit || '' }}</text> |
| | | </view> |
| | | <view class="detail-row"> |
| | | <text class="detail-label">合格数量</text> |
| | | <text class="detail-value">{{ item.qualifiedQuantity ?? '-' }}</text> |
| | | </view> |
| | | <view class="detail-row"> |
| | | <text class="detail-label">不合格数量</text> |
| | | <text class="detail-value">{{ item.unqualifiedQuantity ?? '-' }}</text> |
| | | </view> |
| | | <view class="detail-row"> |
| | | <text class="detail-label">检测单位</text> |
| | |
| | | return inspectState ? "checkmark-circle" : "time"; |
| | | }; |
| | | |
| | | // 获取标签类型 |
| | | const getTagType = checkResult => { |
| | | if (checkResult === "合格") return "success"; |
| | | if (checkResult === "不合格") return "error"; |
| | | return "default"; |
| | | const formatPassRate = val => { |
| | | if (val === null || val === undefined || val === "") return "-"; |
| | | const n = Number(val); |
| | | if (Number.isNaN(n)) return String(val); |
| | | if (n > 0 && n <= 1) return `${(n * 100).toFixed(1)}%`; |
| | | return `${Number.isInteger(n) ? n : Number(n.toFixed(1))}%`; |
| | | }; |
| | | |
| | | const getPassRateTagType = val => { |
| | | if (val === null || val === undefined || val === "") return "default"; |
| | | let n = Number(val); |
| | | if (Number.isNaN(n)) return "default"; |
| | | if (n > 0 && n <= 1) n *= 100; |
| | | if (n >= 100) return "success"; |
| | | if (n >= 60) return "warning"; |
| | | return "error"; |
| | | }; |
| | | |
| | | const isFullPassByPassRate = item => { |
| | | const v = item.passRate; |
| | | if (v === null || v === undefined || v === "") return false; |
| | | const n = Number(v); |
| | | if (Number.isNaN(n)) return false; |
| | | if (n > 0 && n <= 1) return n >= 1; |
| | | return n >= 100; |
| | | }; |
| | | |
| | | // 获取状态标签类型 |
| | |
| | | item => !item.inspectState |
| | | ).length; |
| | | qualifiedCount.value = inspectionList.value.filter( |
| | | item => item.checkResult === "合格" |
| | | isFullPassByPassRate |
| | | ).length; |
| | | }) |
| | | .catch(err => { |
| | |
| | | placeholder="请输入单位" |
| | | disabled /> |
| | | </up-form-item> |
| | | <up-form-item label="数量" |
| | | <up-form-item label="总数量" |
| | | prop="quantity" |
| | | required |
| | | border-bottom> |
| | | <up-input v-model="form.quantity" |
| | | type="number" |
| | | placeholder="请输入数量" |
| | | placeholder="请输入总数量" |
| | | :disabled="supplierQuantityDisabled" /> |
| | | </up-form-item> |
| | | <up-form-item label="合格数量" |
| | | prop="qualifiedQuantity" |
| | | required |
| | | border-bottom> |
| | | <up-input v-model="form.qualifiedQuantity" |
| | | type="number" |
| | | placeholder="请输入合格数量" |
| | | clearable /> |
| | | </up-form-item> |
| | | <up-form-item label="不合格数量" |
| | | prop="unqualifiedQuantity" |
| | | required |
| | | border-bottom> |
| | | <up-input v-model="form.unqualifiedQuantity" |
| | | type="number" |
| | | placeholder="请输入不合格数量" |
| | | clearable /> |
| | | </up-form-item> |
| | | <up-form-item label="检测单位" |
| | | prop="checkCompany" |
| | |
| | | <up-input v-model="form.checkCompany" |
| | | placeholder="请输入检测单位" |
| | | clearable /> |
| | | </up-form-item> |
| | | <up-form-item label="检测结果" |
| | | prop="checkResult" |
| | | required |
| | | border-bottom> |
| | | <up-input v-model="form.checkResult" |
| | | placeholder="请选择检测结果" |
| | | readonly |
| | | @click="showResultSheet" /> |
| | | <template #right> |
| | | <up-icon @click="showResultSheet = true" |
| | | name="arrow-right" /> |
| | | </template> |
| | | </up-form-item> |
| | | <up-form-item label="检验员" |
| | | prop="checkName" |
| | |
| | | @select="selectModel" |
| | | @close="showModelSheet = false" |
| | | title="选择规格型号" /> |
| | | <!-- 检测结果选择 --> |
| | | <up-action-sheet :show="showResultSheet" |
| | | :actions="resultSheetOptions" |
| | | @select="selectResult" |
| | | @close="showResultSheet = false" |
| | | title="选择检测结果" /> |
| | | <!-- 检验员选择 --> |
| | | <up-action-sheet :show="showInspectorSheet" |
| | | :actions="userSheetOptions" |
| | |
| | | const showProductTree = ref(false); |
| | | // 规格型号选择 |
| | | const showModelSheet = ref(false); |
| | | // 检测结果选择 |
| | | const showResultSheet = ref(false); |
| | | // 检验员选择 |
| | | const showInspectorSheet = ref(false); |
| | | // 指标选择 |
| | |
| | | testStandardId: "", |
| | | unit: "", |
| | | quantity: "", |
| | | qualifiedQuantity: "", |
| | | unqualifiedQuantity: "", |
| | | checkCompany: "", |
| | | checkResult: "", |
| | | productMainId: null, |
| | | purchaseLedgerId: null, |
| | | }); |
| | |
| | | const modelOptions = ref([]); |
| | | // 检验员列表 |
| | | const userList = ref([]); |
| | | // 检测结果选项 |
| | | const resultOptions = ref([ |
| | | { label: "合格", value: "合格" }, |
| | | { label: "不合格", value: "不合格" }, |
| | | ]); |
| | | // 指标选项 |
| | | const testStandardOptions = ref([]); |
| | | // 当前产品ID |
| | |
| | | return modelOptions.value.map(item => ({ |
| | | name: item.model, |
| | | value: item.id, |
| | | })); |
| | | }); |
| | | |
| | | const resultSheetOptions = computed(() => { |
| | | return resultOptions.value.map(item => ({ |
| | | name: item.label, |
| | | value: item.value, |
| | | })); |
| | | }); |
| | | |
| | |
| | | ], |
| | | unit: [{ required: false, message: "请输入", trigger: "blur" }], |
| | | quantity: [{ required: true, message: "请输入", trigger: "blur" }], |
| | | checkCompany: [{ required: false, message: "请输入", trigger: "blur" }], |
| | | checkResult: [ |
| | | { required: true, message: "请选择检测结果", trigger: "change" }, |
| | | qualifiedQuantity: [ |
| | | { required: true, message: "请输入合格数量", trigger: "blur" }, |
| | | ], |
| | | unqualifiedQuantity: [ |
| | | { required: true, message: "请输入不合格数量", trigger: "blur" }, |
| | | ], |
| | | checkCompany: [{ required: false, message: "请输入", trigger: "blur" }], |
| | | }; |
| | | |
| | | // 是否为编辑模式 |
| | |
| | | modelOptions.value.find(item => item.id == value)?.model || ""; |
| | | form.value.unit = |
| | | modelOptions.value.find(item => item.id == value)?.unit || ""; |
| | | }; |
| | | |
| | | // 选择检测结果 |
| | | const selectResult = e => { |
| | | form.value.checkResult = e.value; |
| | | showResultSheet.value = false; |
| | | }; |
| | | |
| | | // 选择检验员 |
| | |
| | | showToast("请选择供应商"); |
| | | return; |
| | | } |
| | | if (!form.value.quantity) { |
| | | showToast("请输入数量"); |
| | | if (!form.value.quantity && form.value.quantity !== 0) { |
| | | showToast("请输入总数量"); |
| | | return; |
| | | } |
| | | if ( |
| | | form.value.qualifiedQuantity === "" || |
| | | form.value.qualifiedQuantity === undefined |
| | | ) { |
| | | showToast("请输入合格数量"); |
| | | return; |
| | | } |
| | | if ( |
| | | form.value.unqualifiedQuantity === "" || |
| | | form.value.unqualifiedQuantity === undefined |
| | | ) { |
| | | showToast("请输入不合格数量"); |
| | | return; |
| | | } |
| | | const qty = Number(form.value.quantity); |
| | | const qf = Number(form.value.qualifiedQuantity); |
| | | const uq = Number(form.value.unqualifiedQuantity); |
| | | if (Number.isNaN(qty) || qty < 0) { |
| | | showToast("总数量格式不正确"); |
| | | return; |
| | | } |
| | | if (Number.isNaN(qf) || qf < 0 || Number.isNaN(uq) || uq < 0) { |
| | | showToast("合格/不合格数量格式不正确"); |
| | | return; |
| | | } |
| | | if (qf + uq !== qty) { |
| | | showToast("合格数量与不合格数量之和须等于总数量"); |
| | | return; |
| | | } |
| | | if (!form.value.productId) { |
| | | showToast("请选择产品"); |
| | | return; |
| | | } |
| | | if (!form.value.checkResult) { |
| | | showToast("请选择检测结果"); |
| | | return; |
| | | } |
| | | |
| | |
| | | } |
| | | |
| | | const data = { ...form.value, qualityInspectParams: tableData.value }; |
| | | data.quantity = Number(data.quantity); |
| | | data.quantity = qty; |
| | | data.qualifiedQuantity = qf; |
| | | data.unqualifiedQuantity = uq; |
| | | if (isEdit.value) { |
| | | const res = await qualityInspectUpdate(data); |
| | | showToast("保存成功"); |
| | |
| | | testStandardId: "", |
| | | unit: "", |
| | | quantity: "", |
| | | qualifiedQuantity: "", |
| | | unqualifiedQuantity: "", |
| | | checkCompany: "", |
| | | checkResult: "", |
| | | productMainId: null, |
| | | purchaseLedgerId: null, |
| | | }; |
| | |
| | | testStandardId: "1", |
| | | unit: "kg", |
| | | quantity: 1000, |
| | | qualifiedQuantity: 1000, |
| | | unqualifiedQuantity: 0, |
| | | checkCompany: "第三方检测机构", |
| | | checkResult: "合格", |
| | | productMainId: null, |
| | | purchaseLedgerId: null, |
| | | }; |
| | |
| | | testStandardId: "", |
| | | unit: "", |
| | | quantity: "", |
| | | qualifiedQuantity: "", |
| | | unqualifiedQuantity: "", |
| | | checkCompany: "", |
| | | checkResult: "", |
| | | productMainId: null, |
| | | purchaseLedgerId: null, |
| | | }; |
| | |
| | | </view> |
| | | <text class="header-title">{{ detailData.productName || '-' }}</text> |
| | | <view class="status-tags"> |
| | | <u-tag :type="getTagType(detailData.checkResult)" |
| | | <u-tag :type="getPassRateTagType(detailData.passRate)" |
| | | size="small" |
| | | class="status-tag"> |
| | | {{ detailData.checkResult || '-' }} |
| | | 合格率 {{ formatPassRate(detailData.passRate) }} |
| | | </u-tag> |
| | | <u-tag :type="getStateTagType(detailData.inspectState)" |
| | | size="small" |
| | |
| | | <text class="detail-value">{{ detailData.unit || '-' }}</text> |
| | | </view> |
| | | <view class="detail-row"> |
| | | <text class="detail-label">数量</text> |
| | | <text class="detail-value">{{ detailData.quantity || 0 }}</text> |
| | | <text class="detail-label">总数量</text> |
| | | <text class="detail-value">{{ detailData.quantity ?? '-' }}</text> |
| | | </view> |
| | | <view class="detail-row"> |
| | | <text class="detail-label">合格数量</text> |
| | | <text class="detail-value">{{ detailData.qualifiedQuantity ?? '-' }}</text> |
| | | </view> |
| | | <view class="detail-row"> |
| | | <text class="detail-label">不合格数量</text> |
| | | <text class="detail-value">{{ detailData.unqualifiedQuantity ?? '-' }}</text> |
| | | </view> |
| | | <view class="detail-row"> |
| | | <text class="detail-label">合格率</text> |
| | | <text class="detail-value">{{ formatPassRate(detailData.passRate) }}</text> |
| | | </view> |
| | | <view class="detail-row"> |
| | | <text class="detail-label">检测单位</text> |
| | |
| | | return dayjs(date).format("YYYY-MM-DD"); |
| | | }; |
| | | |
| | | // 获取标签类型 |
| | | const getTagType = result => { |
| | | switch (result) { |
| | | case "合格": |
| | | return "success"; |
| | | case "不合格": |
| | | return "error"; |
| | | default: |
| | | return "info"; |
| | | } |
| | | // 格式化合格率(支持 0–1 小数或百分数) |
| | | const formatPassRate = val => { |
| | | if (val === null || val === undefined || val === "") return "-"; |
| | | const n = Number(val); |
| | | if (Number.isNaN(n)) return String(val); |
| | | if (n > 0 && n <= 1) return `${(n * 100).toFixed(1)}%`; |
| | | return `${Number.isInteger(n) ? n : Number(n.toFixed(1))}%`; |
| | | }; |
| | | |
| | | const getPassRateTagType = val => { |
| | | if (val === null || val === undefined || val === "") return "info"; |
| | | let n = Number(val); |
| | | if (Number.isNaN(n)) return "info"; |
| | | if (n > 0 && n <= 1) n *= 100; |
| | | if (n >= 100) return "success"; |
| | | if (n >= 60) return "warning"; |
| | | return "error"; |
| | | }; |
| | | |
| | | // 获取状态标签类型 |
| | |
| | | </view> |
| | | </view> |
| | | <view class="status-tags"> |
| | | <u-tag :type="getTagType(item.checkResult)" |
| | | v-if="item.checkResult!=null" |
| | | <u-tag :type="getPassRateTagType(item.passRate)" |
| | | v-if="item.passRate != null && item.passRate !== ''" |
| | | size="mini" |
| | | class="status-tag"> |
| | | {{ item.checkResult }} |
| | | {{ formatPassRate(item.passRate) }} |
| | | </u-tag> |
| | | <u-tag :type="getStateTagType(item.inspectState)" |
| | | size="mini" |
| | |
| | | <text class="detail-value">{{ item.checkName || '-' }}</text> |
| | | </view> |
| | | <view class="detail-row"> |
| | | <text class="detail-label">数量</text> |
| | | <text class="detail-label">总数量</text> |
| | | <text class="detail-value">{{ item.quantity || 0 }} {{ item.unit || '' }}</text> |
| | | </view> |
| | | <view class="detail-row"> |
| | | <text class="detail-label">合格数量</text> |
| | | <text class="detail-value">{{ item.qualifiedQuantity ?? '-' }}</text> |
| | | </view> |
| | | <view class="detail-row"> |
| | | <text class="detail-label">不合格数量</text> |
| | | <text class="detail-value">{{ item.unqualifiedQuantity ?? '-' }}</text> |
| | | </view> |
| | | <view class="detail-row"> |
| | | <text class="detail-label">检测单位</text> |
| | |
| | | return inspectState ? "checkmark-circle" : "time"; |
| | | }; |
| | | |
| | | // 获取标签类型 |
| | | const getTagType = checkResult => { |
| | | if (checkResult === "合格") return "success"; |
| | | if (checkResult === "不合格") return "error"; |
| | | return "default"; |
| | | const formatPassRate = val => { |
| | | if (val === null || val === undefined || val === "") return "-"; |
| | | const n = Number(val); |
| | | if (Number.isNaN(n)) return String(val); |
| | | if (n > 0 && n <= 1) return `${(n * 100).toFixed(1)}%`; |
| | | return `${Number.isInteger(n) ? n : Number(n.toFixed(1))}%`; |
| | | }; |
| | | |
| | | const getPassRateTagType = val => { |
| | | if (val === null || val === undefined || val === "") return "default"; |
| | | let n = Number(val); |
| | | if (Number.isNaN(n)) return "default"; |
| | | if (n > 0 && n <= 1) n *= 100; |
| | | if (n >= 100) return "success"; |
| | | if (n >= 60) return "warning"; |
| | | return "error"; |
| | | }; |
| | | |
| | | const isFullPassByPassRate = item => { |
| | | const v = item.passRate; |
| | | if (v === null || v === undefined || v === "") return false; |
| | | const n = Number(v); |
| | | if (Number.isNaN(n)) return false; |
| | | if (n > 0 && n <= 1) return n >= 1; |
| | | return n >= 100; |
| | | }; |
| | | |
| | | // 获取状态标签类型 |
| | |
| | | item => !item.inspectState |
| | | ).length; |
| | | qualifiedCount.value = inspectionList.value.filter( |
| | | item => item.checkResult === "合格" |
| | | isFullPassByPassRate |
| | | ).length; |
| | | }) |
| | | .catch(err => { |
| | |
| | | placeholder="请输入单位" |
| | | disabled /> |
| | | </up-form-item> |
| | | <up-form-item label="数量" |
| | | <up-form-item label="总数量" |
| | | prop="quantity" |
| | | required |
| | | border-bottom> |
| | | <up-input v-model="form.quantity" |
| | | type="number" |
| | | placeholder="请输入数量" |
| | | placeholder="请输入总数量" |
| | | :disabled="processQuantityDisabled" /> |
| | | </up-form-item> |
| | | <up-form-item label="合格数量" |
| | | prop="qualifiedQuantity" |
| | | required |
| | | border-bottom> |
| | | <up-input v-model="form.qualifiedQuantity" |
| | | type="number" |
| | | placeholder="请输入合格数量" |
| | | clearable /> |
| | | </up-form-item> |
| | | <up-form-item label="不合格数量" |
| | | prop="unqualifiedQuantity" |
| | | required |
| | | border-bottom> |
| | | <up-input v-model="form.unqualifiedQuantity" |
| | | type="number" |
| | | placeholder="请输入不合格数量" |
| | | clearable /> |
| | | </up-form-item> |
| | | <up-form-item label="检测单位" |
| | | prop="checkCompany" |
| | |
| | | <up-input v-model="form.checkCompany" |
| | | placeholder="请输入检测单位" |
| | | clearable /> |
| | | </up-form-item> |
| | | <up-form-item label="检测结果" |
| | | prop="checkResult" |
| | | required |
| | | border-bottom> |
| | | <up-input v-model="form.checkResult" |
| | | placeholder="请选择检测结果" |
| | | readonly |
| | | @click="showResultSheet" /> |
| | | <template #right> |
| | | <up-icon @click="showResultSheet = true" |
| | | name="arrow-right" /> |
| | | </template> |
| | | </up-form-item> |
| | | <up-form-item label="检验员" |
| | | prop="checkName" |
| | |
| | | @select="selectModel" |
| | | @close="showModelSheet = false" |
| | | title="选择规格型号" /> |
| | | <!-- 检测结果选择 --> |
| | | <up-action-sheet :show="showResultSheet" |
| | | :actions="resultSheetOptions" |
| | | @select="selectResult" |
| | | @close="showResultSheet = false" |
| | | title="选择检测结果" /> |
| | | <!-- 检验员选择 --> |
| | | <up-action-sheet :show="showInspectorSheet" |
| | | :actions="userSheetOptions" |
| | |
| | | const showProductTree = ref(false); |
| | | // 规格型号选择 |
| | | const showModelSheet = ref(false); |
| | | // 检测结果选择 |
| | | const showResultSheet = ref(false); |
| | | // 检验员选择 |
| | | const showInspectorSheet = ref(false); |
| | | // 指标选择 |
| | |
| | | testStandardId: "", |
| | | unit: "", |
| | | quantity: "", |
| | | qualifiedQuantity: "", |
| | | unqualifiedQuantity: "", |
| | | checkCompany: "", |
| | | checkResult: "", |
| | | productMainId: null, |
| | | purchaseLedgerId: null, |
| | | }); |
| | |
| | | const modelOptions = ref([]); |
| | | // 检验员列表 |
| | | const userList = ref([]); |
| | | // 检测结果选项 |
| | | const resultOptions = ref([ |
| | | { label: "合格", value: "合格" }, |
| | | { label: "不合格", value: "不合格" }, |
| | | ]); |
| | | // 指标选项 |
| | | const testStandardOptions = ref([]); |
| | | // 当前产品ID |
| | |
| | | return modelOptions.value.map(item => ({ |
| | | name: item.model, |
| | | value: item.id, |
| | | })); |
| | | }); |
| | | |
| | | const resultSheetOptions = computed(() => { |
| | | return resultOptions.value.map(item => ({ |
| | | name: item.label, |
| | | value: item.value, |
| | | })); |
| | | }); |
| | | |
| | |
| | | ], |
| | | unit: [{ required: false, message: "请输入", trigger: "blur" }], |
| | | quantity: [{ required: true, message: "请输入", trigger: "blur" }], |
| | | checkCompany: [{ required: false, message: "请输入", trigger: "blur" }], |
| | | checkResult: [ |
| | | { required: true, message: "请选择检测结果", trigger: "change" }, |
| | | qualifiedQuantity: [ |
| | | { required: true, message: "请输入合格数量", trigger: "blur" }, |
| | | ], |
| | | unqualifiedQuantity: [ |
| | | { required: true, message: "请输入不合格数量", trigger: "blur" }, |
| | | ], |
| | | checkCompany: [{ required: false, message: "请输入", trigger: "blur" }], |
| | | }; |
| | | |
| | | // 是否为编辑模式 |
| | |
| | | modelOptions.value.find(item => item.id == value)?.model || ""; |
| | | form.value.unit = |
| | | modelOptions.value.find(item => item.id == value)?.unit || ""; |
| | | }; |
| | | |
| | | // 选择检测结果 |
| | | const selectResult = e => { |
| | | form.value.checkResult = e.value; |
| | | showResultSheet.value = false; |
| | | }; |
| | | |
| | | // 选择检验员 |
| | |
| | | showToast("请选择工序"); |
| | | return; |
| | | } |
| | | if (!form.value.quantity) { |
| | | showToast("请输入数量"); |
| | | if (!form.value.quantity && form.value.quantity !== 0) { |
| | | showToast("请输入总数量"); |
| | | return; |
| | | } |
| | | if ( |
| | | form.value.qualifiedQuantity === "" || |
| | | form.value.qualifiedQuantity === undefined |
| | | ) { |
| | | showToast("请输入合格数量"); |
| | | return; |
| | | } |
| | | if ( |
| | | form.value.unqualifiedQuantity === "" || |
| | | form.value.unqualifiedQuantity === undefined |
| | | ) { |
| | | showToast("请输入不合格数量"); |
| | | return; |
| | | } |
| | | const qty = Number(form.value.quantity); |
| | | const qf = Number(form.value.qualifiedQuantity); |
| | | const uq = Number(form.value.unqualifiedQuantity); |
| | | if (Number.isNaN(qty) || qty < 0) { |
| | | showToast("总数量格式不正确"); |
| | | return; |
| | | } |
| | | if (Number.isNaN(qf) || qf < 0 || Number.isNaN(uq) || uq < 0) { |
| | | showToast("合格/不合格数量格式不正确"); |
| | | return; |
| | | } |
| | | if (qf + uq !== qty) { |
| | | showToast("合格数量与不合格数量之和须等于总数量"); |
| | | return; |
| | | } |
| | | if (!form.value.productId) { |
| | | showToast("请选择产品"); |
| | | return; |
| | | } |
| | | if (!form.value.checkResult) { |
| | | showToast("请选择检测结果"); |
| | | return; |
| | | } |
| | | |
| | |
| | | } |
| | | |
| | | const data = { ...form.value, qualityInspectParams: tableData.value }; |
| | | data.quantity = Number(data.quantity); |
| | | data.quantity = qty; |
| | | data.qualifiedQuantity = qf; |
| | | data.unqualifiedQuantity = uq; |
| | | if (isEdit.value) { |
| | | const res = await qualityInspectUpdate(data); |
| | | showToast("保存成功"); |
| | |
| | | testStandardId: "", |
| | | unit: "", |
| | | quantity: "", |
| | | qualifiedQuantity: "", |
| | | unqualifiedQuantity: "", |
| | | checkCompany: "", |
| | | checkResult: "", |
| | | productMainId: null, |
| | | purchaseLedgerId: null, |
| | | }; |
| | |
| | | testStandardId: "1", |
| | | unit: "kg", |
| | | quantity: 1000, |
| | | qualifiedQuantity: 1000, |
| | | unqualifiedQuantity: 0, |
| | | checkCompany: "第三方检测机构", |
| | | checkResult: "合格", |
| | | productMainId: null, |
| | | purchaseLedgerId: null, |
| | | }; |
| | |
| | | testStandardId: "", |
| | | unit: "", |
| | | quantity: "", |
| | | qualifiedQuantity: "", |
| | | unqualifiedQuantity: "", |
| | | checkCompany: "", |
| | | checkResult: "", |
| | | productMainId: null, |
| | | purchaseLedgerId: null, |
| | | }; |
| | |
| | | </view> |
| | | <text class="header-title">{{ detailData.productName || '-' }}</text> |
| | | <view class="status-tags"> |
| | | <u-tag :type="getTagType(detailData.checkResult)" |
| | | <u-tag :type="getPassRateTagType(detailData.passRate)" |
| | | size="small" |
| | | class="status-tag"> |
| | | {{ detailData.checkResult || '-' }} |
| | | 合格率 {{ formatPassRate(detailData.passRate) }} |
| | | </u-tag> |
| | | <u-tag :type="getStateTagType(detailData.inspectState)" |
| | | size="small" |
| | |
| | | <text class="detail-value">{{ detailData.unit || '-' }}</text> |
| | | </view> |
| | | <view class="detail-row"> |
| | | <text class="detail-label">数量</text> |
| | | <text class="detail-value">{{ detailData.quantity || 0 }}</text> |
| | | <text class="detail-label">总数量</text> |
| | | <text class="detail-value">{{ detailData.quantity ?? '-' }}</text> |
| | | </view> |
| | | <view class="detail-row"> |
| | | <text class="detail-label">合格数量</text> |
| | | <text class="detail-value">{{ detailData.qualifiedQuantity ?? '-' }}</text> |
| | | </view> |
| | | <view class="detail-row"> |
| | | <text class="detail-label">不合格数量</text> |
| | | <text class="detail-value">{{ detailData.unqualifiedQuantity ?? '-' }}</text> |
| | | </view> |
| | | <view class="detail-row"> |
| | | <text class="detail-label">合格率</text> |
| | | <text class="detail-value">{{ formatPassRate(detailData.passRate) }}</text> |
| | | </view> |
| | | <view class="detail-row"> |
| | | <text class="detail-label">检测单位</text> |
| | |
| | | return dayjs(date).format("YYYY-MM-DD"); |
| | | }; |
| | | |
| | | // 获取标签类型 |
| | | const getTagType = result => { |
| | | switch (result) { |
| | | case "合格": |
| | | return "success"; |
| | | case "不合格": |
| | | return "error"; |
| | | default: |
| | | return "info"; |
| | | } |
| | | const formatPassRate = val => { |
| | | if (val === null || val === undefined || val === "") return "-"; |
| | | const n = Number(val); |
| | | if (Number.isNaN(n)) return String(val); |
| | | if (n > 0 && n <= 1) return `${(n * 100).toFixed(1)}%`; |
| | | return `${Number.isInteger(n) ? n : Number(n.toFixed(1))}%`; |
| | | }; |
| | | |
| | | const getPassRateTagType = val => { |
| | | if (val === null || val === undefined || val === "") return "info"; |
| | | let n = Number(val); |
| | | if (Number.isNaN(n)) return "info"; |
| | | if (n > 0 && n <= 1) n *= 100; |
| | | if (n >= 100) return "success"; |
| | | if (n >= 60) return "warning"; |
| | | return "error"; |
| | | }; |
| | | |
| | | // 获取状态标签类型 |
| | |
| | | </view> |
| | | </view> |
| | | <view class="status-tags"> |
| | | <u-tag :type="getTagType(item.checkResult)" |
| | | v-if="item.checkResult!=null" |
| | | <u-tag :type="getPassRateTagType(item.passRate)" |
| | | v-if="item.passRate != null && item.passRate !== ''" |
| | | size="mini" |
| | | class="status-tag"> |
| | | {{ item.checkResult }} |
| | | {{ formatPassRate(item.passRate) }} |
| | | </u-tag> |
| | | <u-tag :type="getStateTagType(item.inspectState)" |
| | | size="mini" |
| | |
| | | <text class="detail-value">{{ item.checkName || '-' }}</text> |
| | | </view> |
| | | <view class="detail-row"> |
| | | <text class="detail-label">数量</text> |
| | | <text class="detail-label">总数量</text> |
| | | <text class="detail-value">{{ item.quantity || 0 }} {{ item.unit || '' }}</text> |
| | | </view> |
| | | <view class="detail-row"> |
| | | <text class="detail-label">合格数量</text> |
| | | <text class="detail-value">{{ item.qualifiedQuantity ?? '-' }}</text> |
| | | </view> |
| | | <view class="detail-row"> |
| | | <text class="detail-label">不合格数量</text> |
| | | <text class="detail-value">{{ item.unqualifiedQuantity ?? '-' }}</text> |
| | | </view> |
| | | <view class="detail-row"> |
| | | <text class="detail-label">检测单位</text> |
| | |
| | | return inspectState ? "checkmark-circle" : "time"; |
| | | }; |
| | | |
| | | // 获取标签类型 |
| | | const getTagType = checkResult => { |
| | | if (checkResult === "合格") return "success"; |
| | | if (checkResult === "不合格") return "error"; |
| | | return "default"; |
| | | const formatPassRate = val => { |
| | | if (val === null || val === undefined || val === "") return "-"; |
| | | const n = Number(val); |
| | | if (Number.isNaN(n)) return String(val); |
| | | if (n > 0 && n <= 1) return `${(n * 100).toFixed(1)}%`; |
| | | return `${Number.isInteger(n) ? n : Number(n.toFixed(1))}%`; |
| | | }; |
| | | |
| | | const getPassRateTagType = val => { |
| | | if (val === null || val === undefined || val === "") return "default"; |
| | | let n = Number(val); |
| | | if (Number.isNaN(n)) return "default"; |
| | | if (n > 0 && n <= 1) n *= 100; |
| | | if (n >= 100) return "success"; |
| | | if (n >= 60) return "warning"; |
| | | return "error"; |
| | | }; |
| | | |
| | | const isFullPassByPassRate = item => { |
| | | const v = item.passRate; |
| | | if (v === null || v === undefined || v === "") return false; |
| | | const n = Number(v); |
| | | if (Number.isNaN(n)) return false; |
| | | if (n > 0 && n <= 1) return n >= 1; |
| | | return n >= 100; |
| | | }; |
| | | |
| | | // 获取状态标签类型 |
| | |
| | | item => !item.inspectState |
| | | ).length; |
| | | qualifiedCount.value = inspectionList.value.filter( |
| | | item => item.checkResult === "合格" |
| | | isFullPassByPassRate |
| | | ).length; |
| | | }) |
| | | .catch(err => { |