| | |
| | | <up-input v-model="form.supplier" |
| | | placeholder="请选择供应商" |
| | | readonly |
| | | :disabled="supplierQuantityDisabled" /> |
| | | :disabled="supplierQuantityDisabled || isReadonly" /> |
| | | <template #right> |
| | | <up-icon @click="showSupplierSheet = true" |
| | | <up-icon @click="!isReadonly && (showSupplierSheet = true)" |
| | | name="arrow-right" /> |
| | | </template> |
| | | </up-form-item> |
| | |
| | | <up-input v-model="form.productName" |
| | | placeholder="请选择产品" |
| | | readonly |
| | | @click="showProductTree = true" |
| | | :disabled="isEdit" /> |
| | | @click="!isReadonly && (showProductTree = true)" |
| | | :disabled="isEdit || isReadonly" /> |
| | | <template #right> |
| | | <up-icon @click="showProductTree = true" |
| | | <up-icon @click="!isReadonly && (showProductTree = true)" |
| | | name="arrow-right" /> |
| | | </template> |
| | | </up-form-item> |
| | |
| | | <up-input v-model="form.model" |
| | | placeholder="请选择规格型号" |
| | | readonly |
| | | :disabled="isEdit" /> |
| | | :disabled="isEdit || isReadonly" /> |
| | | <template #right> |
| | | <up-icon @click="showModelSheet = true" |
| | | <view v-if="!isEdit" |
| | | class="scan-entry" |
| | | @click.stop="scanBarcode"> |
| | | <up-icon name="scan" |
| | | size="18" |
| | | color="#3c9cff" /> |
| | | <text class="scan-entry-text">扫码</text> |
| | | </view> |
| | | <up-icon @click="!isReadonly && (showModelSheet = true)" |
| | | name="arrow-right" /> |
| | | </template> |
| | | </up-form-item> |
| | |
| | | border-bottom> |
| | | <up-input v-model="testStandardDisplay" |
| | | placeholder="请选择指标" |
| | | readonly /> |
| | | readonly |
| | | :disabled="isReadonly" /> |
| | | <template #right> |
| | | <up-icon @click="openTestStandardSheet" |
| | | name="arrow-right" /> |
| | |
| | | <up-input v-model="form.quantity" |
| | | type="number" |
| | | placeholder="请输入数量" |
| | | :disabled="supplierQuantityDisabled" /> |
| | | :disabled="supplierQuantityDisabled || isReadonly" /> |
| | | </up-form-item> |
| | | <up-form-item label="检测单位" |
| | | prop="checkCompany" |
| | | border-bottom> |
| | | <up-input v-model="form.checkCompany" |
| | | placeholder="请输入检测单位" |
| | | :disabled="isReadonly" |
| | | clearable /> |
| | | </up-form-item> |
| | | <up-form-item label="检测结果" |
| | |
| | | <up-input v-model="form.checkResult" |
| | | placeholder="请选择检测结果" |
| | | readonly |
| | | :disabled="isReadonly" |
| | | @click="showResultSheet" /> |
| | | <template #right> |
| | | <up-icon @click="showResultSheet = true" |
| | | <up-icon @click="!isReadonly && (showResultSheet = true)" |
| | | name="arrow-right" /> |
| | | </template> |
| | | </up-form-item> |
| | |
| | | <up-input v-model="form.checkName" |
| | | placeholder="请选择检验员" |
| | | readonly |
| | | :disabled="isReadonly" |
| | | @click="showInspectorSheet" /> |
| | | <template #right> |
| | | <up-icon @click="showInspectorSheet = true" |
| | | <up-icon @click="!isReadonly && (showInspectorSheet = true)" |
| | | name="arrow-right" /> |
| | | </template> |
| | | </up-form-item> |
| | |
| | | <up-input v-model="form.checkTime" |
| | | placeholder="请选择检测日期" |
| | | readonly |
| | | :disabled="isReadonly" |
| | | @click="showDatePicker" /> |
| | | <!-- <template #right> |
| | | <up-icon name="arrow-right" |
| | |
| | | <text class="step-label">检验值:</text> |
| | | <up-input v-model="item.testValue" |
| | | placeholder="请输入检验值" |
| | | :disabled="isReadonly" |
| | | clearable |
| | | border-bottom |
| | | class="step-input" /> |
| | |
| | | size="default" |
| | | @click="goBack" |
| | | class="bottom-btn"> |
| | | 取消 |
| | | {{ isReadonly ? '返回' : '取消' }} |
| | | </up-button> |
| | | <up-button type="primary" |
| | | <!-- 已提交单据只读,隐藏保存/提交 --> |
| | | <up-button v-if="!isReadonly" |
| | | type="primary" |
| | | size="default" |
| | | @click="submitForm" |
| | | :loading="loading" |
| | | class="bottom-btn"> |
| | | {{ isEdit ? '保存' : '提交' }} |
| | | 保存 |
| | | </up-button> |
| | | </view> |
| | | <!-- 日期选择器 --> |
| | |
| | | import PageHeader from "@/components/PageHeader.vue"; |
| | | import dayjs from "dayjs"; |
| | | import { getOptions } from "@/api/procurementManagement/procurementLedger.js"; |
| | | import { modelList, productTreeList } from "@/api/basicData/product.js"; |
| | | import { |
| | | modelList, |
| | | productTreeList, |
| | | modelByBarcode, |
| | | } from "@/api/basicData/product.js"; |
| | | import { |
| | | qualityInspectAdd, |
| | | qualityInspectUpdate, |
| | |
| | | return modelOptions.value.map(item => ({ |
| | | name: item.model, |
| | | value: item.id, |
| | | subname: item.barcode ? `条码:${item.barcode}` : "", |
| | | })); |
| | | }); |
| | | |
| | |
| | | return !!(v.productMainId != null || v.purchaseLedgerId != null); |
| | | }); |
| | | |
| | | // 已提交(inspectState=1)单据整体只读 |
| | | const isReadonly = computed(() => Number(form.value?.inspectState) === 1); |
| | | |
| | | // 返回上一页 |
| | | const goBack = () => { |
| | | uni.navigateBack(); |
| | |
| | | |
| | | // 显示日期选择器 |
| | | const showDatePicker = () => { |
| | | if (isReadonly.value) return; |
| | | showDate.value = true; |
| | | }; |
| | | |
| | |
| | | }); |
| | | }; |
| | | const openTestStandardSheet = () => { |
| | | console.log("openTestStandardSheet"); |
| | | if (isReadonly.value) return; |
| | | showTestStandardSheet.value = true; |
| | | }; |
| | | |
| | |
| | | } |
| | | }; |
| | | |
| | | // 获取型号列表 |
| | | // 获取型号列表(返回 Promise,便于扫码后顺序回填) |
| | | const getModels = value => { |
| | | form.value.productModelId = ""; |
| | | form.value.unit = ""; |
| | | modelOptions.value = []; |
| | | currentProductId.value = value; |
| | | form.value.productName = findNodeById(productOptions.value, value); |
| | | modelList({ id: value }).then(res => { |
| | | modelOptions.value = res; |
| | | const task = modelList({ id: value }).then(res => { |
| | | modelOptions.value = res?.data || res || []; |
| | | }); |
| | | if (currentProductId.value) { |
| | | getList(); |
| | | } |
| | | return task; |
| | | }; |
| | | |
| | | // 扫码按条码精确回填产品+规格型号 |
| | | const scanBarcode = () => { |
| | | if (isEdit.value) return; |
| | | uni.scanCode({ |
| | | scanType: ["barCode", "qrCode"], |
| | | success: async res => { |
| | | const barcode = (res.result || "").trim(); |
| | | if (!barcode) return; |
| | | uni.showLoading({ title: "匹配中...", mask: true }); |
| | | try { |
| | | const resp = await modelByBarcode({ barcode }); |
| | | const info = resp?.data || resp; |
| | | if (info && info.productId) { |
| | | // 先按 productId 联动出产品层,保证 UI 状态与手动选择一致 |
| | | await getModels(info.productId); |
| | | form.value.productId = info.productId; |
| | | form.value.productName = info.productName || form.value.productName; |
| | | form.value.productModelId = info.id; |
| | | form.value.model = info.model || ""; |
| | | form.value.unit = info.unit || ""; |
| | | } |
| | | uni.hideLoading(); |
| | | uni.showToast({ title: "已匹配规格", icon: "success" }); |
| | | } catch (e) { |
| | | // 未匹配等错误已有全局 toast,这里只恢复 loading |
| | | uni.hideLoading(); |
| | | } |
| | | }, |
| | | }); |
| | | }; |
| | | |
| | | // 获取指标列表 |
| | |
| | | // 提交表单 |
| | | const submitForm = async () => { |
| | | console.log("submitForm", form.value, tableData.value); |
| | | // 已提交单据禁止保存/提交 |
| | | if (isReadonly.value) { |
| | | showToast("检验单已提交,不允许修改"); |
| | | return; |
| | | } |
| | | try { |
| | | // await formRef.value.validate(); |
| | | if (!form.value.productModelId) { |
| | |
| | | const data = { ...form.value, qualityInspectParams: tableData.value }; |
| | | data.quantity = Number(data.quantity); |
| | | if (isEdit.value) { |
| | | const res = await qualityInspectUpdate(data); |
| | | await qualityInspectUpdate(data); |
| | | showToast("保存成功"); |
| | | setTimeout(() => { |
| | | uni.navigateBack(); |
| | | }, 1500); |
| | | } else { |
| | | const res = await qualityInspectAdd(data); |
| | | showToast("提交成功"); |
| | | // 新增仅保存草稿,正式提交在列表页「提交」按钮(会生成入库记录) |
| | | await qualityInspectAdd(data); |
| | | showToast("保存成功"); |
| | | setTimeout(() => { |
| | | uni.navigateBack(); |
| | | }, 1500); |
| | | } |
| | | } catch (error) { |
| | | console.error("表单验证失败:", error); |
| | | showToast("提交失败,请重试"); |
| | | // request.ts 已统一 toast 后端 msg,这里只记录 |
| | | console.error("提交失败:", error); |
| | | } finally { |
| | | loading.value = false; |
| | | } |
| | |
| | | <style scoped lang="scss"> |
| | | @import "@/static/scss/form-common.scss"; |
| | | |
| | | // 规格行扫码入口 |
| | | .scan-entry { |
| | | display: flex; |
| | | align-items: center; |
| | | margin-right: 8px; |
| | | |
| | | .scan-entry-text { |
| | | font-size: 13px; |
| | | color: #3c9cff; |
| | | margin-left: 2px; |
| | | } |
| | | } |
| | | |
| | | .material-inspection-add { |
| | | min-height: 100vh; |
| | | background: #f8f9fa; |