From c94826da81b6ebed4a62ed44f6e6bc30cb65f467 Mon Sep 17 00:00:00 2001
From: gongchunyi <deslre0381@gmail.com>
Date: 星期日, 21 六月 2026 10:39:24 +0800
Subject: [PATCH] fix: 已审核订单的分页组件不展示
---
src/views/equipmentManagement/ledger/Form.vue | 359 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
1 files changed, 343 insertions(+), 16 deletions(-)
diff --git a/src/views/equipmentManagement/ledger/Form.vue b/src/views/equipmentManagement/ledger/Form.vue
index 108dbe4..98e735a 100644
--- a/src/views/equipmentManagement/ledger/Form.vue
+++ b/src/views/equipmentManagement/ledger/Form.vue
@@ -1,5 +1,5 @@
<template>
- <el-form :model="form" label-width="100px" :rules="formRules" ref="formRef">
+ <el-form :model="form" label-width="120px" :rules="formRules" ref="formRef">
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="璁惧鍚嶇О" prop="deviceName">
@@ -8,12 +8,51 @@
</el-col>
<el-col :span="12">
<el-form-item label="瑙勬牸鍨嬪彿" prop="deviceModel">
- <el-input v-model="form.deviceModel" :disabled="(form.deviceModel != null && operationType === 'edit')" placeholder="璇疯緭鍏ヨ鏍煎瀷鍙�" />
+ <el-input v-model="form.deviceModel" placeholder="璇疯緭鍏ヨ鏍煎瀷鍙�" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="璁惧鍝佺墝" prop="deviceBrand">
<el-input v-model="form.deviceBrand" placeholder="璇疯緭鍏ヨ澶囧搧鐗�" />
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="璁惧绫诲瀷" prop="type">
+ <el-select
+ v-model="form.type"
+ placeholder="璇烽�夋嫨鎴栬緭鍏ヨ澶囩被鍨�"
+ clearable
+ filterable
+ allow-create
+ default-first-option
+ style="width: 100%"
+ @change="handleDeviceTypeChange"
+ >
+ <el-option
+ v-for="item in deviceTypeOptions"
+ :key="item"
+ :label="item"
+ :value="item"
+ />
+ </el-select>
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="宸ュ簭" prop="productProcessId">
+ <el-select
+ v-model="form.productProcessId"
+ placeholder="璇烽�夋嫨宸ュ簭"
+ clearable
+ filterable
+ style="width: 100%"
+ >
+ <el-option
+ v-for="item in processOptions"
+ :key="item.value"
+ :label="item.label"
+ :value="item.value"
+ />
+ </el-select>
</el-form-item>
</el-col>
<el-col :span="12">
@@ -32,14 +71,26 @@
</el-form-item>
</el-col>
<el-col :span="12">
- <el-form-item label="鍚敤鎶樻棫" prop="enableDepreciation">
- <el-switch v-model="form.enableDepreciation" :active-value="true" :inactive-value="false" />
+ <el-form-item label="鍚敤鎶樻棫" prop="isDepr">
+ <el-switch v-model="form.isDepr" :active-value="1" :inactive-value="2" />
+ </el-form-item>
+ </el-col>
+ <el-col :span="12" v-if="form.isDepr === 1">
+ <el-form-item label="姣忓勾鎶樻棫閲戦" prop="annualDepreciationAmount">
+ <el-input-number
+ :step="0.01"
+ :min="0"
+ style="width: 100%"
+ v-model="form.annualDepreciationAmount"
+ placeholder="璇疯緭鍏ユ瘡骞存姌鏃ч噾棰�"
+ />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="鏁伴噺" prop="number">
- <el-input-number :step="0.01" :min="0" style="width: 100%"
+ <el-input-number :min="1" style="width: 100%"
v-model="form.number"
+ disabled
placeholder="璇疯緭鍏ユ暟閲�"
@change="mathNum"
/>
@@ -81,7 +132,9 @@
@change="mathNum"
>
<el-option label="1" :value="1" />
+ <el-option label="3" :value="3" />
<el-option label="6" :value="6" />
+ <el-option label="9" :value="9" />
<el-option label="13" :value="13" />
</el-select>
</el-form-item>
@@ -114,53 +167,137 @@
/>
</el-form-item>
</el-col>
+ <el-col :span="12">
+ <el-form-item label="棰勮杩愯鏃堕棿" prop="planRuntimeTime">
+ <el-date-picker
+ style="width: 100%"
+ v-model="form.planRuntimeTime"
+ format="YYYY-MM-DD"
+ value-format="YYYY-MM-DD"
+ type="date"
+ placeholder="璇烽�夋嫨褰曞叆鏃ユ湡"
+ clearable
+ />
+ </el-form-item>
+ </el-col>
+ <el-col :span="24">
+ <el-form-item label="璁惧鍥剧墖" prop="deviceImage">
+ <div v-if="displayedExistingProblems.length" class="problem-existing-wrap">
+ <div v-for="img in displayedExistingProblems" :key="img.id" class="problem-thumb">
+ <el-image :src="img.url" fit="cover" class="problem-thumb-img" @click="previewProblem(img.url)" />
+ <el-icon class="problem-thumb-remove" @click.stop="markProblemRemove(img.id)"><Close /></el-icon>
+ </div>
+ </div>
+ <el-upload
+ class="repair-attachment-upload"
+ v-model:file-list="attachmentFileList"
+ drag
+ multiple
+ :auto-upload="false"
+ :limit="9"
+ accept="image/png,image/jpeg,image/jpg"
+ :before-upload="beforeUpload"
+ >
+ <el-icon class="repair-upload-icon"><UploadFilled /></el-icon>
+ <div class="el-upload__text">灏嗘枃浠舵嫋鍒版澶勶紝鎴� <em>鐐瑰嚮閫夋嫨鏂囦欢</em></div>
+ <template #tip>
+ <div class="el-upload__tip">
+ 鏀寔 png / jpg / jpeg锛屽崟寮犱笉瓒呰繃 50MB锛屾渶澶� 9 寮�
+ </div>
+ </template>
+ </el-upload>
+ </el-form-item>
+ </el-col>
</el-row>
</el-form>
</template>
<script setup>
import useFormData from "@/hooks/useFormData";
-// import useUserStore from "@/store/modules/user";
-import { getLedgerById } from "@/api/equipmentManagement/ledger";
+import { getLedgerById, getLedgerFileList, uploadLedgerFile, deleteLedgerFile } from "@/api/equipmentManagement/ledger";
+import { processList } from "@/api/productionManagement/productionProcess";
import dayjs from "dayjs";
import {
calculateTaxIncludeTotalPrice,
calculateTaxExclusiveTotalPrice,
} from "@/utils/summarizeTable";
import { ElMessage } from "element-plus";
-import {ref} from "vue";
+import { ref, onMounted, getCurrentInstance } from "vue";
+import { UploadFilled, Close } from "@element-plus/icons-vue";
+import { getToken } from "@/utils/auth";
defineOptions({
name: "璁惧鍙拌处琛ㄥ崟",
});
const formRef = ref(null);
const operationType = ref('');
+// 璁惧绫诲瀷鍥哄畾閫夐」
+const deviceTypeOptions = ref([
+ '鐢熶骇璁惧',
+ '鍔炲叕璁惧',
+ '妫�娴嬭澶�',
+ '杩愯緭璁惧',
+ '鍏朵粬璁惧'
+]);
+const processOptions = ref([]);
const formRules = {
deviceName: [{ required: true, trigger: "blur", message: "璇疯緭鍏�" }],
deviceModel: [{ required: true, trigger: "blur", message: "璇疯緭鍏�" }],
+ type: [{ required: true, trigger: "change", message: "璇烽�夋嫨鎴栬緭鍏ヨ澶囩被鍨�" }],
supplierName: [{ required: true, trigger: "blur", message: "璇疯緭鍏�" }],
unit: [{ required: true, trigger: "blur", message: "璇疯緭鍏�" }],
number: [{ required: true, trigger: "blur", message: "璇疯緭鍏�" }],
taxIncludingPriceUnit: [{ required: true, trigger: "blur", message: "璇疯緭鍏�" }],
taxRate: [{ required: true, trigger: "change", message: "璇疯緭鍏�" }],
+ planRuntimeTime: [{ required: true, trigger: "change", message: "璇烽�夋嫨" }],
+ annualDepreciationAmount: [
+ {
+ validator: (rule, value, callback) => {
+ if (form.isDepr === 1 && (value === undefined || value === null || value === '')) {
+ callback(new Error('鍚敤鎶樻棫鏃讹紝璇疯緭鍏ユ瘡骞存姌鏃ч噾棰�'));
+ } else {
+ callback();
+ }
+ },
+ trigger: "blur"
+ }
+ ],
}
const { form, resetForm } = useFormData({
deviceName: undefined, // 璁惧鍚嶇О
deviceModel: undefined, // 瑙勬牸鍨嬪彿
deviceBrand: undefined, // 璁惧鍝佺墝
+ type: undefined, // 璁惧绫诲瀷
+ productProcessId: undefined, // 宸ュ簭ID
supplierName: undefined, // 渚涘簲鍟�
storageLocation: undefined, // 瀛樻斁浣嶇疆
- enableDepreciation: false, // 鏄惁鍚敤鎶樻棫
+ isDepr: 2, // 鏄惁鍚敤鎶樻棫 1-鏄� 2-鍚�
+ annualDepreciationAmount: undefined, // 姣忓勾鎶樻棫閲戦
unit: undefined, // 鍗曚綅
- number: undefined, // 鏁伴噺
+ number: 1, // 鏁伴噺
taxIncludingPriceUnit: undefined, // 鍚◣鍗曚环
taxIncludingPriceTotal: undefined, // 鍚◣鎬讳环
taxRate: undefined, // 绋庣巼
unTaxIncludingPriceTotal: undefined, // 涓嶅惈绋庢�讳环
// createUser: useUserStore().nickName, // 褰曞叆浜�
createTime: dayjs().format("YYYY-MM-DD HH:mm:ss"), // 褰曞叆鏃ユ湡
+ planRuntimeTime: dayjs().format("YYYY-MM-DD"), // 褰曞叆鏃ユ湡
});
+
+const attachmentFileList = ref([]);
+const existingProblemImages = ref([]);
+const pendingRemoveProblemIds = ref([]);
+
+const displayedExistingProblems = computed(() =>
+ existingProblemImages.value.filter((img) => !pendingRemoveProblemIds.value.includes(img.id))
+);
+
+const markProblemRemove = (fileId) => {
+ if (!pendingRemoveProblemIds.value.includes(fileId)) {
+ pendingRemoveProblemIds.value.push(fileId);
+ }
+};
const loadForm = async (id) => {
if (id) {
@@ -171,26 +308,88 @@
form.deviceName = data.deviceName;
form.deviceModel = data.deviceModel;
form.deviceBrand = data.deviceBrand;
+ form.type = data.type;
+ const processName = data.productProcessName || data.processName || data.process;
+ form.productProcessId = data.productProcessId;
+ if (!form.productProcessId && processName) {
+ const matched = processOptions.value.find(item => item.label === processName);
+ form.productProcessId = matched?.value;
+ }
+ ensureProcessOptionExists(form.productProcessId, processName);
form.supplierName = data.supplierName;
form.storageLocation = data.storageLocation;
- form.enableDepreciation = data.enableDepreciation;
+ form.isDepr = data.isDepr;
+ form.annualDepreciationAmount = data.annualDepreciationAmount;
form.unit = data.unit;
- form.number = data.number;
+ form.number = 1;
form.taxIncludingPriceUnit = data.taxIncludingPriceUnit;
form.taxIncludingPriceTotal = data.taxIncludingPriceTotal;
form.taxRate = data.taxRate;
form.unTaxIncludingPriceTotal = data.unTaxIncludingPriceTotal;
form.createTime = data.createTime;
+ // 棰勮杩愯鏃堕棿锛氬悗绔繑鍥炲悗杞负 YYYY-MM-DD 浠ヤ究鏃ユ湡閫夋嫨鍣ㄦ纭睍绀�
+ if (data.planRuntimeTime) {
+ form.planRuntimeTime = dayjs(data.planRuntimeTime).format('YYYY-MM-DD');
+ } else {
+ form.planRuntimeTime = undefined;
+ }
+ }
+
+ existingProblemImages.value = [];
+ pendingRemoveProblemIds.value = [];
+ attachmentFileList.value = [];
+ if (id) {
+ try {
+ const res = await getLedgerFileList(id);
+ const list = Array.isArray(res?.data) ? res.data : [];
+ existingProblemImages.value = list.map((item) => ({
+ id: item.id,
+ name: item.name,
+ url: getFileAccessUrl(item),
+ }));
+ } catch {
+ existingProblemImages.value = [];
+ }
+ }
+};
+
+const ensureProcessOptionExists = (id, name) => {
+ if (!id) return;
+ if (!processOptions.value.some(item => item.value === id)) {
+ processOptions.value.push({
+ value: id,
+ label: name || `${id}`,
+ });
+ }
+};
+
+const getProcessOptions = async () => {
+ try {
+ const { code, data } = await processList({});
+ if (code === 200 && Array.isArray(data)) {
+ processOptions.value = data
+ .filter(item => item?.id !== undefined && item?.id !== null)
+ .map(item => ({
+ value: item.id,
+ label: item?.name || `${item.id}`,
+ }));
+ ensureProcessOptionExists(form.productProcessId);
+ }
+ } catch (error) {
+ processOptions.value = [];
+ }
+};
+
+const handleDeviceTypeChange = (value) => {
+ // 濡傛灉杈撳叆鐨勬柊鍊间笉鍦ㄥ浐瀹氶�夐」涓紝鍒欐坊鍔犲埌閫夐」鍒楄〃
+ if (value && !deviceTypeOptions.value.includes(value)) {
+ deviceTypeOptions.value.push(value);
}
};
const mathNum = () => {
if (!form.taxIncludingPriceUnit) {
ElMessage.error("璇疯緭鍏ュ崟浠�");
- return;
- }
- if (!form.number) {
- ElMessage.error("璇疯緭鍏ユ暟閲�");
return;
}
form.taxIncludingPriceTotal = calculateTaxIncludeTotalPrice(
@@ -216,6 +415,81 @@
clearValidate();
};
+onMounted(() => {
+ getProcessOptions();
+});
+
+const uploadUrl = ref(import.meta.env.VITE_APP_BASE_API + "/common/upload");
+const headers = ref({ Authorization: "Bearer " + getToken() });
+const ATTACH_MAX_MB = 50;
+
+const beforeUpload = (rawFile) => {
+ const okType = ["image/jpeg", "image/jpg", "image/png"].includes(rawFile.type);
+ if (!okType) {
+ ElMessage.error("鍙兘涓婁紶 png / jpg / jpeg 鍥剧墖");
+ return false;
+ }
+ const maxBytes = ATTACH_MAX_MB * 1024 * 1024;
+ if (rawFile.size > maxBytes) {
+ ElMessage.error(`鍗曚釜鏂囦欢涓嶈兘瓒呰繃 ${ATTACH_MAX_MB}MB`);
+ return false;
+ }
+ return true;
+};
+
+const submitFiles = async (ledgerId) => {
+ for (const fileId of pendingRemoveProblemIds.value) {
+ await deleteLedgerFile(fileId);
+ }
+ pendingRemoveProblemIds.value = [];
+
+ const rows = attachmentFileList.value || [];
+ const files = rows.map((f) => f.raw).filter(Boolean);
+ if (!files.length || ledgerId == null) return;
+
+ for (const file of files) {
+ const fd = new FormData();
+ fd.append("file", file);
+ fd.append("deviceLedgerId", String(ledgerId));
+ // 16 is the FileNameType for EQUIPMENT_LEDGER that we added
+ fd.append("fileType", "16");
+ const res = await uploadLedgerFile(fd);
+ if (res.code !== 200) {
+ throw new Error(res.msg || "闄勪欢涓婁紶澶辫触");
+ }
+ }
+ attachmentFileList.value = [];
+};
+
+const getFileAccessUrl = (file = {}) => {
+ let raw = file?.link || file?.url || "";
+ if (String(raw).startsWith("http")) return raw;
+ const javaApi = getCurrentInstance()?.proxy?.javaApi || import.meta.env.VITE_APP_BASE_API || "/dev-api";
+ let fileUrl = raw;
+ if (fileUrl.indexOf("\\") > -1) {
+ const lowerPath = fileUrl.toLowerCase();
+ const uploadPathIndex = lowerPath.indexOf("uploadpath");
+ if (uploadPathIndex > -1) {
+ fileUrl = fileUrl.substring(uploadPathIndex).replace(/\\/g, "/");
+ } else {
+ fileUrl = fileUrl.replace(/\\/g, "/");
+ }
+ }
+ fileUrl = fileUrl.replace(/^\/?uploadPath/, "/profile");
+ if (fileUrl.startsWith("upload/")) {
+ fileUrl = "/profile/" + fileUrl;
+ }
+ if (!fileUrl.startsWith("http")) {
+ if (!fileUrl.startsWith("/")) fileUrl = "/" + fileUrl;
+ fileUrl = javaApi + fileUrl;
+ }
+ return fileUrl;
+};
+
+const previewProblem = (url) => {
+ window.open(url, "_blank");
+};
+
defineExpose({
form,
loadForm,
@@ -223,5 +497,58 @@
clearValidate,
resetFormAndValidate,
formRef,
+ submitFiles,
});
</script>
+
+<style lang="scss" scoped>
+.repair-attachment-upload {
+ width: 100%;
+ :deep(.el-upload) {
+ width: 100%;
+ }
+ :deep(.el-upload-dragger) {
+ width: 100%;
+ padding: 24px 16px;
+ }
+}
+.repair-upload-icon {
+ font-size: 48px;
+ color: var(--el-color-primary);
+ margin-bottom: 8px;
+}
+
+.problem-existing-wrap {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 10px;
+ margin-bottom: 12px;
+}
+
+.problem-thumb {
+ position: relative;
+ width: 88px;
+ height: 88px;
+ border-radius: 6px;
+ overflow: hidden;
+ border: 1px solid var(--el-border-color);
+}
+
+.problem-thumb-img {
+ width: 100%;
+ height: 100%;
+ cursor: pointer;
+}
+
+.problem-thumb-remove {
+ position: absolute;
+ top: 2px;
+ right: 2px;
+ font-size: 16px;
+ color: #fff;
+ background: rgba(0, 0, 0, 0.45);
+ border-radius: 50%;
+ padding: 2px;
+ cursor: pointer;
+}
+</style>
--
Gitblit v1.9.3