From 868b2427b516407e191db620f81451107525c8de Mon Sep 17 00:00:00 2001
From: gongchunyi <deslre0381@gmail.com>
Date: 星期六, 23 五月 2026 15:20:25 +0800
Subject: [PATCH] Merge branch 'dev_pro_河南鹤壁' of http://114.132.189.42:9002/r/product-inventory-management into dev_pro_河南鹤壁
---
src/views/procurementManagement/procurementLedger/index.vue | 12
src/views/procurementManagement/procurementLedger/detail.vue | 4
src/views/collaborativeApproval/approvalProcess/index.vue | 53 +
src/views/procurementManagement/purchaseReturnOrder/New.vue | 22
src/views/collaborativeApproval/approvalProcess/components/infoFormDia.vue | 47 +
vite.config.js | 2
src/views/equipmentManagement/inspectionManagement/index.vue | 18
src/views/equipmentManagement/inspectionManagement/components/uploadFiles.vue | 1194 ++++++++++++++++++++-------------------
src/views/equipmentManagement/inspectionManagement/components/viewFiles.vue | 417 ++++++------
9 files changed, 931 insertions(+), 838 deletions(-)
diff --git a/src/views/collaborativeApproval/approvalProcess/components/infoFormDia.vue b/src/views/collaborativeApproval/approvalProcess/components/infoFormDia.vue
index 5bd7a3e..bacdebd 100644
--- a/src/views/collaborativeApproval/approvalProcess/components/infoFormDia.vue
+++ b/src/views/collaborativeApproval/approvalProcess/components/infoFormDia.vue
@@ -85,6 +85,35 @@
</el-form-item>
</el-col>
</el-row>
+ <!-- 鍑哄樊鏃堕棿锛堜粎褰� approveType 涓� 3 鏃舵樉绀猴級 -->
+ <el-row :gutter="30" v-if="props.approveType == 3">
+ <el-col :span="12">
+ <el-form-item label="鍑哄樊寮�濮嬫椂闂达細" prop="startDateTime">
+ <el-date-picker
+ v-model="form.startDateTime"
+ type="datetime"
+ placeholder="璇烽�夋嫨寮�濮嬫椂闂�"
+ value-format="YYYY-MM-DD HH:mm"
+ format="YYYY-MM-DD HH:mm"
+ clearable
+ style="width: 100%"
+ />
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="鍑哄樊缁撴潫鏃堕棿锛�" prop="endDateTime">
+ <el-date-picker
+ v-model="form.endDateTime"
+ type="datetime"
+ placeholder="璇烽�夋嫨缁撴潫鏃堕棿"
+ value-format="YYYY-MM-DD HH:mm"
+ format="YYYY-MM-DD HH:mm"
+ clearable
+ style="width: 100%"
+ />
+ </el-form-item>
+ </el-col>
+ </el-row>
<!-- 鍑哄樊鍦扮偣锛堜粎褰� approveType 涓� 3 鏃舵樉绀猴級 -->
<el-row v-if="props.approveType == 3">
<el-col :span="24">
@@ -152,6 +181,8 @@
startDate: "", // 璇峰亣寮�濮嬫椂闂�
endDate: "", // 璇峰亣缁撴潫鏃堕棿
price: null, // 鎶ラ攢閲戦
+ startDateTime: "", // 鍑哄樊寮�濮嬫椂闂�
+ endDateTime: "", // 鍑哄樊缁撴潫鏃堕棿
location: "", // 鍑哄樊鍦扮偣
storageBlobDTOS: []
},
@@ -163,6 +194,8 @@
startDate: [{ required: true, message: "璇烽�夋嫨璇峰亣寮�濮嬫椂闂�", trigger: "change" }],
endDate: [{ required: true, message: "璇烽�夋嫨璇峰亣缁撴潫鏃堕棿", trigger: "change" }],
price: [{ required: true, message: "璇疯緭鍏ユ姤閿�閲戦", trigger: "blur" }],
+ startDateTime: [{ required: true, message: "璇烽�夋嫨鍑哄樊寮�濮嬫椂闂�", trigger: "change" }],
+ endDateTime: [{ required: true, message: "璇烽�夋嫨鍑哄樊缁撴潫鏃堕棿", trigger: "change" }],
location: [{ required: true, message: "璇疯緭鍏ュ嚭宸湴鐐�", trigger: "blur" }],
},
});
@@ -257,8 +290,20 @@
return
}
}
- // 褰� approveType 涓� 3 鏃讹紝鏍¢獙鍑哄樊鍦扮偣
+ // 褰� approveType 涓� 3 鏃讹紝鏍¢獙鍑哄樊鏃堕棿鍜屽湴鐐�
if (props.approveType == 3) {
+ if (!form.value.startDateTime) {
+ proxy.$modal.msgError("璇烽�夋嫨鍑哄樊寮�濮嬫椂闂达紒")
+ return
+ }
+ if (!form.value.endDateTime) {
+ proxy.$modal.msgError("璇烽�夋嫨鍑哄樊缁撴潫鏃堕棿锛�")
+ return
+ }
+ if (new Date(form.value.endDateTime) < new Date(form.value.startDateTime)) {
+ proxy.$modal.msgError("鍑哄樊缁撴潫鏃堕棿涓嶈兘鏃╀簬寮�濮嬫椂闂达紒")
+ return
+ }
if (!form.value.location || form.value.location.trim() === '') {
proxy.$modal.msgError("璇疯緭鍏ュ嚭宸湴鐐癸紒")
return
diff --git a/src/views/collaborativeApproval/approvalProcess/index.vue b/src/views/collaborativeApproval/approvalProcess/index.vue
index 11a2869..158916c 100644
--- a/src/views/collaborativeApproval/approvalProcess/index.vue
+++ b/src/views/collaborativeApproval/approvalProcess/index.vue
@@ -207,6 +207,7 @@
// 鍔ㄦ�佽〃鏍煎垪閰嶇疆锛屾牴鎹鎵圭被鍨嬬敓鎴愬垪
const tableColumnCopy = computed(() => {
const isLeaveType = currentApproveType.value === 2; // 璇峰亣绠$悊
+ const isBusinessTripType = currentApproveType.value === 3; // 鍑哄樊绠$悊
const isReimburseType = currentApproveType.value === 4; // 鎶ラ攢绠$悊
const isQuotationType = currentApproveType.value === 6; // 鎶ヤ环瀹℃壒
const isPurchaseType = currentApproveType.value === 5; // 閲囪喘瀹℃壒
@@ -274,20 +275,32 @@
width: 120
});
}
+
+ // 璇峰亣绠$悊锛氬紑濮嬫棩鏈� / 缁撴潫鏃ユ湡
+ if (isLeaveType) {
+ baseColumns.push(
+ { label: "寮�濮嬫棩鏈�", prop: "startDate", width: 120 },
+ { label: "缁撴潫鏃ユ湡", prop: "endDate", width: 120 }
+ );
+ }
- // 鏃ユ湡鍒楋紙鏍规嵁绫诲瀷鍔ㄦ�侀厤缃級
- baseColumns.push(
- {
- label: isLeaveType ? "寮�濮嬫棩鏈�" : "鐢宠鏃ユ湡",
- prop: isLeaveType ? "startDate" : "approveTime",
- width: 200
- },
- {
- label: "缁撴潫鏃ユ湡",
- prop: isLeaveType ? "endDate" : "approveOverTime",
- width: 120
- }
- );
+ // 鍑哄樊绠$悊锛氬紑濮嬫椂闂� / 缁撴潫鏃堕棿锛堜笉鍚锛�
+ if (isBusinessTripType) {
+ baseColumns.push(
+ {
+ label: "寮�濮嬫椂闂�",
+ prop: "startDateTime",
+ width: 180,
+ formatData: (val) => val ? val.substring(0, 16) : ''
+ },
+ {
+ label: "缁撴潫鏃堕棿",
+ prop: "endDateTime",
+ width: 180,
+ formatData: (val) => val ? val.substring(0, 16) : ''
+ }
+ );
+ }
// 褰撳墠瀹℃壒浜哄垪
baseColumns.push({
@@ -295,6 +308,20 @@
prop: "approveUserCurrentName",
width: 120
});
+
+ // 鐢宠鏃堕棿 - 鎵�鏈夌被鍨嬮兘鏄剧ず
+ baseColumns.push({
+ label: "鐢宠鏃堕棿",
+ prop: "approveTime",
+ width: 180,
+ });
+
+ // 瀹℃壒鏃堕棿 - 鎵�鏈夌被鍨嬮兘鏄剧ず
+ baseColumns.push({
+ label: "瀹℃壒鏃堕棿",
+ prop: "approveOverTime",
+ width: 180,
+ });
// 鎿嶄綔鍒�
const actionOperations = [
diff --git a/src/views/equipmentManagement/inspectionManagement/components/uploadFiles.vue b/src/views/equipmentManagement/inspectionManagement/components/uploadFiles.vue
index 36256c8..9abd042 100644
--- a/src/views/equipmentManagement/inspectionManagement/components/uploadFiles.vue
+++ b/src/views/equipmentManagement/inspectionManagement/components/uploadFiles.vue
@@ -1,117 +1,131 @@
<template>
- <FormDialog
- v-model="dialogVisible"
- title="涓婁紶宸℃璁板綍"
- width="980px"
- @close="handleClose"
- @cancel="handleClose"
- >
+ <FormDialog v-model="dialogVisible"
+ :title="operationType === 'view' ? '宸℃璁板綍璇︽儏' : '涓婁紶宸℃璁板綍'"
+ width="980px"
+ :operation-type="operationType"
+ @close="handleClose"
+ @cancel="handleClose">
<main class="upload-content">
- <el-card v-if="taskInfo" class="section-card">
- <el-descriptions :column="1" border>
+ <el-card v-if="taskInfo"
+ class="section-card">
+ <el-descriptions :column="2"
+ border>
<el-descriptions-item label="宸℃浠诲姟鍚嶇О">
{{ taskInfo.taskName || "-" }}
</el-descriptions-item>
<el-descriptions-item label="宸℃椤圭洰">
{{ taskInfo.inspectionProject || "-" }}
</el-descriptions-item>
+ <el-descriptions-item label="鎵ц宸℃浜�">
+ <template v-if="formattedInspector && formattedInspector.length">
+ <el-tag v-for="tag in formattedInspector"
+ :key="tag"
+ size="small"
+ style="margin-right: 4px">
+ {{ tag }}
+ </el-tag>
+ </template>
+ <span v-else>--</span>
+ </el-descriptions-item>
+ <el-descriptions-item label="棰戞">
+ {{ formatFrequencyType(taskInfo.frequencyType) || "-" }}
+ </el-descriptions-item>
+ <el-descriptions-item label="寮�濮嬫棩鏈熶笌鏃堕棿">
+ {{ formatFrequencyDetail(taskInfo.frequencyDetail) || "-" }}
+ </el-descriptions-item>
+ <el-descriptions-item label="鐧昏浜�">
+ {{ taskInfo.registrant || "-" }}
+ </el-descriptions-item>
+ <el-descriptions-item label="鐧昏鏃ユ湡">
+ {{ formatDateTime(taskInfo.createTime) || "-" }}
+ </el-descriptions-item>
<el-descriptions-item label="澶囨敞">
{{ taskInfo.remarks || "-" }}
</el-descriptions-item>
</el-descriptions>
</el-card>
-
<el-card class="section-card">
<h3>宸℃鐘舵��</h3>
- <el-radio-group v-model="hasException">
+ <el-radio-group v-model="hasException"
+ :disabled="operationType === 'view'">
<el-radio-button :value="false">姝e父</el-radio-button>
<el-radio-button :value="true">瀛樺湪寮傚父</el-radio-button>
</el-radio-group>
</el-card>
-
- <el-card v-if="hasException === true" class="section-card">
+ <el-card v-if="hasException === true"
+ class="section-card">
<h3>寮傚父鎻忚堪</h3>
- <el-input
- v-model="abnormalDescription"
- type="textarea"
- maxlength="500"
- show-word-limit
- :rows="4"
- placeholder="璇锋弿杩板紓甯告儏鍐�..."
- />
+ <el-input v-model="abnormalDescription"
+ type="textarea"
+ maxlength="500"
+ show-word-limit
+ :rows="4"
+ :disabled="operationType === 'view'"
+ placeholder="璇锋弿杩板紓甯告儏鍐�..." />
</el-card>
-
- <el-card v-if="hasException === true" class="section-card">
- <el-tabs v-model="currentUploadType">
- <el-tab-pane label="鐢熶骇鍓�" name="before" />
- <el-tab-pane label="鐢熶骇涓�" name="after" />
- <el-tab-pane label="鐢熶骇鍚�" name="issue" />
- </el-tabs>
-
- <div class="upload-buttons">
- <el-upload
- :show-file-list="false"
- :http-request="uploadFile"
- :disabled="getCurrentFiles().length >= uploadConfig.limit || uploading"
- accept="image/*"
- >
- <el-button type="primary" :loading="uploading">
- <el-icon><Camera /></el-icon>
+ <el-card v-if="hasException === true"
+ class="section-card">
+ <div class="upload-buttons"
+ v-if="operationType !== 'view'">
+ <el-upload :show-file-list="false"
+ :http-request="uploadFile"
+ :disabled="beforeModelValue.length >= uploadConfig.limit || uploading"
+ accept="image/*">
+ <el-button type="primary"
+ :loading="uploading">
+ <el-icon>
+ <Camera />
+ </el-icon>
閫夋嫨鍥剧墖
</el-button>
</el-upload>
-
- <el-upload
- :show-file-list="false"
- :http-request="uploadFile"
- :disabled="getCurrentFiles().length >= uploadConfig.limit || uploading"
- accept="video/*"
- >
- <el-button type="success" :loading="uploading">
- <el-icon><VideoCamera /></el-icon>
+ <el-upload :show-file-list="false"
+ :http-request="uploadFile"
+ :disabled="beforeModelValue.length >= uploadConfig.limit || uploading"
+ accept="video/*">
+ <el-button type="success"
+ :loading="uploading">
+ <el-icon>
+ <VideoCamera />
+ </el-icon>
閫夋嫨瑙嗛
</el-button>
</el-upload>
</div>
-
- <el-progress
- v-if="uploading"
- :percentage="uploadProgress"
- class="upload-progress"
- />
-
- <div v-if="getCurrentFiles().length" class="file-list">
- <div
- v-for="(file, index) in getCurrentFiles()"
- :key="file.uid || file.id || index"
- class="file-item"
- >
+ <el-progress v-if="uploading"
+ :percentage="uploadProgress"
+ class="upload-progress" />
+ <div v-if="beforeModelValue.length"
+ class="file-list">
+ <div v-for="(file, index) in beforeModelValue"
+ :key="file.uid || file.id || index"
+ class="file-item">
<div class="file-preview-container">
- <el-image
- v-if="file.type === 'image' || !file.type"
- :src="file.url || file.tempFilePath || file.path || file.downloadUrl"
- fit="cover"
- class="file-preview"
- :preview-src-list="[file.url || file.tempFilePath || file.path || file.downloadUrl]"
- preview-teleported
- />
-
- <div v-else class="video-preview" @click="previewVideo(file)">
- <el-icon><VideoCamera /></el-icon>
+ <el-image v-if="file.type === 'image' || !file.type"
+ :src="file.url || file.tempFilePath || file.path || file.downloadUrl"
+ fit="cover"
+ class="file-preview"
+ :preview-src-list="[file.url || file.tempFilePath || file.path || file.downloadUrl]"
+ preview-teleported />
+ <div v-else
+ class="video-preview"
+ @click="previewVideo(file)">
+ <el-icon>
+ <VideoCamera />
+ </el-icon>
<span>瑙嗛</span>
</div>
-
- <el-button
- class="delete-btn"
- type="danger"
- circle
- size="small"
- @click="removeFile(index)"
- >
- <el-icon><Close /></el-icon>
+ <el-button class="delete-btn"
+ type="danger"
+ circle
+ size="small"
+ v-if="operationType !== 'view'"
+ @click="removeFile(index)">
+ <el-icon>
+ <Close />
+ </el-icon>
</el-button>
</div>
-
<div class="file-info">
<div class="file-name">
{{ file.bucketFilename || file.name || (file.type === "image" ? "鍥剧墖" : "瑙嗛") }}
@@ -120,561 +134,559 @@
</div>
</div>
</div>
-
- <el-empty
- v-else
- :description="`璇烽�夋嫨瑕佷笂浼犵殑${getUploadTypeText()}鍥剧墖鎴栬棰慲"
- />
-
- <el-alert
- class="upload-summary"
- type="info"
- :closable="false"
- :title="`鐢熶骇鍓嶏細${beforeModelValue.length}涓枃浠� | 鐢熶骇涓細${afterModelValue.length}涓枃浠� | 鐢熶骇鍚庯細${issueModelValue.length}涓枃浠禶"
- />
+ <el-empty v-else
+ :description="operationType === 'view' ? '鏆傛棤寮傚父鐓х墖鎴栬棰�' : '璇烽�夋嫨瑕佷笂浼犵殑宸℃鍥剧墖鎴栬棰�'" />
</el-card>
-
- <el-result
- v-if="hasException === false"
- icon="success"
- title="璁惧杩愯姝e父"
- sub-title="鏃犻渶涓婁紶鐓х墖"
- />
+ <el-result v-if="hasException === false"
+ icon="success"
+ title="璁惧杩愯姝e父"
+ :sub-title="operationType === 'view' ? '' : '鏃犻渶涓婁紶鐓х墖'" />
</main>
-
<template #footer>
<footer class="footer-buttons">
- <el-button type="primary" @click="submitUpload">鎻愪氦</el-button>
- <el-button v-if="hasException === true" type="warning" @click="goToRepair">
+ <el-button type="primary"
+ v-if="operationType !== 'view'"
+ @click="submitUpload">鎻愪氦</el-button>
+ <el-button v-if="hasException === true && operationType !== 'view'"
+ type="warning"
+ @click="goToRepair">
鏂板鎶ヤ慨
</el-button>
- <el-button @click="handleClose">鍙栨秷</el-button>
+ <el-button @click="handleClose">{{ operationType === 'view' ? '鍏抽棴' : '鍙栨秷' }}</el-button>
</footer>
</template>
</FormDialog>
-
- <el-dialog
- v-model="showVideoDialog"
- :title="currentVideoFile?.originalFilename || currentVideoFile?.name || '瑙嗛棰勮'"
- width="720px"
- >
- <video
- v-if="currentVideoFile"
- :src="currentVideoFile.url || currentVideoFile.downloadUrl"
- class="video-player"
- controls
- autoplay
- />
+ <el-dialog v-model="showVideoDialog"
+ :title="currentVideoFile?.originalFilename || currentVideoFile?.name || '瑙嗛棰勮'"
+ width="720px">
+ <video v-if="currentVideoFile"
+ :src="currentVideoFile.url || currentVideoFile.downloadUrl"
+ class="video-player"
+ controls
+ autoplay />
</el-dialog>
</template>
<script setup>
-import { computed, ref } from "vue";
-import { useRouter } from "vue-router";
-import { ElLoading, ElMessage, ElMessageBox } from "element-plus";
-import { Camera, Close, VideoCamera } from "@element-plus/icons-vue";
-import axios from "axios";
-import FormDialog from "@/components/Dialog/FormDialog.vue";
-import { uploadInspectionTask } from "@/api/inspectionManagement/index.js";
-import { getToken } from "@/utils/auth";
+ import { computed, ref } from "vue";
+ import { useRouter } from "vue-router";
+ import { ElLoading, ElMessage, ElMessageBox } from "element-plus";
+ import { Camera, Close, VideoCamera } from "@element-plus/icons-vue";
+ import axios from "axios";
+ import dayjs from "dayjs";
+ import FormDialog from "@/components/Dialog/FormDialog.vue";
+ import { uploadInspectionTask } from "@/api/inspectionManagement/index.js";
+ import { getToken } from "@/utils/auth";
-const emit = defineEmits(["closeDia", "success"]);
-const router = useRouter();
+ const emit = defineEmits(["closeDia", "success"]);
+ const router = useRouter();
-const dialogVisible = ref(false);
-const taskInfo = ref(null);
-const uploading = ref(false);
-const uploadProgress = ref(0);
+ const dialogVisible = ref(false);
+ const taskInfo = ref(null);
+ const uploading = ref(false);
+ const uploadProgress = ref(0);
+ const operationType = ref("add"); // add, view
-const beforeModelValue = ref([]);
-const afterModelValue = ref([]);
-const issueModelValue = ref([]);
+ const beforeModelValue = ref([]);
-const currentUploadType = ref("before");
-const hasException = ref(null);
-const abnormalDescription = ref("");
-
-const showVideoDialog = ref(false);
-const currentVideoFile = ref(null);
-
-const uploadConfig = {
- action: "/common/upload",
- limit: 10,
- fileSize: 50,
- fileType: ["jpg", "jpeg", "png", "mp4", "mov"],
-};
-
-const uploadFileUrl = computed(
- () => `${import.meta.env.VITE_APP_BASE_API}${uploadConfig.action}`
-);
-
-const processFileUrl = fileUrl => {
- if (!fileUrl) return "";
-
- let currentUrl = String(fileUrl);
- if (currentUrl.includes("\\")) {
- const uploadsIndex = currentUrl.toLowerCase().indexOf("uploads");
- if (uploadsIndex > -1) {
- currentUrl = `/${currentUrl.substring(uploadsIndex).replace(/\\/g, "/")}`;
- } else {
- const fileName = currentUrl.split("\\").pop();
- currentUrl = `/uploads/${fileName}`;
+ const formattedInspector = computed(() => {
+ if (!taskInfo.value?.inspector) return [];
+ if (Array.isArray(taskInfo.value.inspector)) return taskInfo.value.inspector;
+ if (typeof taskInfo.value.inspector === "string") {
+ return taskInfo.value.inspector
+ .split(",")
+ .map(s => s.trim())
+ .filter(s => s);
}
- }
-
- if (currentUrl && !currentUrl.startsWith("http")) {
- if (!currentUrl.startsWith("/")) {
- currentUrl = `/${currentUrl}`;
- }
- currentUrl = __BASE_API__ + currentUrl;
- }
-
- return currentUrl;
-};
-
-const normalizeList = (list, fileType) => {
- if (!Array.isArray(list)) return [];
-
- return list.filter(Boolean).map(item => {
- let currentType = item.type;
- if (!currentType && item.contentType) {
- currentType = item.contentType.startsWith("video") ? "video" : "image";
- } else if (!currentType) {
- currentType = fileType || "image";
- }
-
- return {
- ...item,
- url: processFileUrl(item.url || item.previewURL || item.downloadUrl || item.path || ""),
- downloadUrl: processFileUrl(
- item.downloadUrl || item.url || item.previewURL || item.path || ""
- ),
- name: item.name || item.originalFilename || item.bucketFilename,
- tempId: item.tempId || item.id || item.tempFileId,
- tempFileId: item.tempFileId || item.tempId || item.id,
- size: item.size || item.byteSize || 0,
- type: currentType,
- status: "success",
- uid: item.uid || `${Date.now()}-${Math.random()}`,
- };
- });
-};
-
-const resetState = () => {
- taskInfo.value = null;
- beforeModelValue.value = [];
- afterModelValue.value = [];
- issueModelValue.value = [];
- currentUploadType.value = "before";
- hasException.value = null;
- abnormalDescription.value = "";
- uploading.value = false;
- uploadProgress.value = 0;
- showVideoDialog.value = false;
- currentVideoFile.value = null;
-};
-
-const openDialog = row => {
- const raw = JSON.parse(JSON.stringify(row?.__raw || row || {}));
- taskInfo.value = raw;
-
- beforeModelValue.value = normalizeList(
- raw.commonFileListBeforeVO || raw.commonFileListBefore || [],
- "image"
- );
- afterModelValue.value = normalizeList(
- raw.commonFileListVO || raw.commonFileList || [],
- "image"
- );
- issueModelValue.value = normalizeList(
- raw.commonFileListAfterVO || raw.commonFileListAfter || [],
- "image"
- );
-
- abnormalDescription.value = raw.abnormalDescription || "";
-
- if (raw.hasException !== undefined && raw.hasException !== null) {
- hasException.value = raw.hasException;
- } else if (raw.inspectionResult !== undefined && raw.inspectionResult !== null) {
- hasException.value = String(raw.inspectionResult) === "0";
- } else {
- hasException.value = null;
- }
-
- if (
- hasException.value !== true &&
- (beforeModelValue.value.length || afterModelValue.value.length || issueModelValue.value.length)
- ) {
- hasException.value = true;
- }
-
- dialogVisible.value = true;
-};
-
-const handleClose = () => {
- dialogVisible.value = false;
- resetState();
- emit("closeDia");
-};
-
-const getCurrentFiles = () => {
- if (currentUploadType.value === "before") return beforeModelValue.value;
- if (currentUploadType.value === "after") return afterModelValue.value;
- if (currentUploadType.value === "issue") return issueModelValue.value;
- return [];
-};
-
-const getUploadTypeText = () => {
- if (currentUploadType.value === "before") return "鐢熶骇鍓�";
- if (currentUploadType.value === "after") return "鐢熶骇涓�";
- if (currentUploadType.value === "issue") return "鐢熶骇鍚�";
- return "";
-};
-
-const getTabType = () => {
- if (currentUploadType.value === "before") return 10;
- if (currentUploadType.value === "after") return 11;
- if (currentUploadType.value === "issue") return 12;
- return 10;
-};
-
-const previewVideo = file => {
- currentVideoFile.value = file;
- showVideoDialog.value = true;
-};
-
-const uploadFile = async uploadRequest => {
- const rawFile = uploadRequest.file;
-
- if (getCurrentFiles().length >= uploadConfig.limit) {
- ElMessage.warning(`鏈�澶氬彧鑳介�夋嫨${uploadConfig.limit}涓枃浠禶);
- return;
- }
-
- const ext = rawFile.name.split(".").pop()?.toLowerCase();
- if (!uploadConfig.fileType.includes(ext)) {
- ElMessage.warning(`鏂囦欢鏍煎紡涓嶆敮鎸侊紝璇蜂笂浼� ${uploadConfig.fileType.join("/")} 鏍煎紡`);
- return;
- }
-
- if (rawFile.size > uploadConfig.fileSize * 1024 * 1024) {
- ElMessage.warning(`鏂囦欢澶у皬涓嶈兘瓒呰繃 ${uploadConfig.fileSize}MB`);
- return;
- }
-
- const token = getToken();
- if (!token) {
- ElMessage.warning("鐢ㄦ埛鏈櫥褰�");
- return;
- }
-
- const formData = new FormData();
- formData.append("files", rawFile);
- formData.append("type", getTabType());
-
- uploading.value = true;
- uploadProgress.value = 0;
-
- try {
- const { data } = await axios.post(uploadFileUrl.value, formData, {
- headers: {
- Authorization: `Bearer ${token}`,
- "Content-Type": "multipart/form-data",
- },
- onUploadProgress: event => {
- if (event.total) {
- uploadProgress.value = Math.round((event.loaded / event.total) * 100);
- }
- },
- });
-
- if (data.code !== 200) {
- ElMessage.error(data.msg || "涓婁紶澶辫触");
- return;
- }
-
- const resultData = Array.isArray(data.data) ? data.data[0] : data.data;
- const finalUrl = processFileUrl(
- resultData.url || resultData.previewURL || resultData.downloadUrl || ""
- );
- const finalName = resultData.name || resultData.originalFilename || resultData.bucketFilename;
- const finalId = resultData.tempId || resultData.id || resultData.tempFileId;
-
- const uploadedFile = {
- ...resultData,
- url: finalUrl,
- downloadUrl: finalUrl,
- name: finalName,
- tempId: finalId,
- tempFileId: resultData.tempFileId || finalId,
- size: rawFile.size || resultData.size || resultData.byteSize || 0,
- type: rawFile.type?.startsWith("video") ? "video" : "image",
- status: "success",
- uid: `${Date.now()}-${Math.random()}`,
- };
-
- getCurrentFiles().push(uploadedFile);
- ElMessage.success("涓婁紶鎴愬姛");
- } catch (error) {
- ElMessage.error(error?.message || "涓婁紶澶辫触");
- } finally {
- uploading.value = false;
- }
-};
-
-const buildFileItem = item => ({
- id: item?.id,
- tempId: item?.tempId,
- tempFileId: item?.tempFileId,
- url: item?.downloadUrl || item?.url || "",
- downloadUrl: item?.downloadUrl || item?.url || "",
- name: item?.name,
- bucketFilename: item?.bucketFilename || item?.name,
- originalFilename: item?.originalFilename || item?.name,
- size: item?.size || 0,
- byteSize: item?.byteSize || item?.size || 0,
- contentType: item?.contentType || "",
- type: item?.type,
-});
-
-const submitUpload = async () => {
- if (hasException.value === null) {
- ElMessage.warning("璇烽�夋嫨宸℃鐘舵��");
- return;
- }
-
- if (hasException.value === true) {
- const totalFiles =
- beforeModelValue.value.length +
- afterModelValue.value.length +
- issueModelValue.value.length;
-
- if (!totalFiles) {
- ElMessage.warning("璇蜂笂浼犲紓甯哥収鐗囨垨瑙嗛");
- return;
- }
-
- if (!abnormalDescription.value.trim()) {
- ElMessage.warning("璇峰~鍐欏紓甯告弿杩�");
- return;
- }
- }
-
- const loading = ElLoading.service({
- text: "鎻愪氦涓�...",
- background: "rgba(0, 0, 0, 0.3)",
+ return [taskInfo.value.inspector];
});
- try {
- const allFiles = [
- ...beforeModelValue.value,
- ...afterModelValue.value,
- ...issueModelValue.value,
- ];
-
- const tempFileIds = allFiles
- .map(item => item?.tempId ?? item?.tempFileId ?? item?.id)
- .filter(Boolean);
-
- const {
- createTime,
- updateTime,
- storageBlobDTO,
- commonFileListAfterVO,
- commonFileListVO,
- commonFileListBeforeVO,
- commonFileListAfter,
- commonFileList,
- commonFileListBefore,
- __raw,
- ...baseTaskInfo
- } = taskInfo.value || {};
-
- const submitData = {
- ...baseTaskInfo,
- commonFileListBeforeDTO: beforeModelValue.value.map(buildFileItem),
- commonFileListDTO: afterModelValue.value.map(buildFileItem),
- commonFileListAfterDTO: issueModelValue.value.map(buildFileItem),
- hasException: hasException.value,
- inspectionResult: hasException.value ? 0 : 1,
- abnormalDescription: abnormalDescription.value,
- tempFileIds,
+ const formatFrequencyType = type => {
+ const mapping = {
+ DAILY: "姣忔棩",
+ WEEKLY: "姣忓懆",
+ MONTHLY: "姣忔湀",
+ QUARTERLY: "瀛e害",
};
-
- const result = await uploadInspectionTask(submitData);
-
- if (result && (result.code === 200 || result.success)) {
- ElMessage.success("鎻愪氦鎴愬姛");
- dialogVisible.value = false;
- resetState();
- emit("success");
- emit("closeDia");
- } else {
- ElMessage.error(result?.msg || result?.message || "鎻愪氦澶辫触");
- }
- } catch (error) {
- ElMessage.error(error?.message || "鎻愪氦澶辫触");
- } finally {
- loading.close();
- }
-};
-
-const removeFile = async index => {
- try {
- await ElMessageBox.confirm("纭畾瑕佸垹闄よ繖涓枃浠跺悧锛�", "纭鍒犻櫎", {
- type: "warning",
- });
- getCurrentFiles().splice(index, 1);
- } catch {}
-};
-
-const goToRepair = () => {
- const taskData = {
- taskId: taskInfo.value?.taskId || taskInfo.value?.id,
- taskName: taskInfo.value?.taskName,
- inspectionLocation: taskInfo.value?.inspectionLocation,
- inspector: taskInfo.value?.inspector,
- hasException: hasException.value,
- inspectionResult: hasException.value ? 0 : 1,
- commonFileListBeforeDTO: beforeModelValue.value.map(buildFileItem),
- commonFileListDTO: afterModelValue.value.map(buildFileItem),
- commonFileListAfterDTO: issueModelValue.value.map(buildFileItem),
- uploadedFiles: {
- before: beforeModelValue.value,
- after: afterModelValue.value,
- issue: issueModelValue.value,
- },
+ return mapping[type] || type;
};
- sessionStorage.setItem("repairTaskInfo", JSON.stringify(taskData));
- router.push("/equipmentManagement/repair/add");
-};
+ const formatFrequencyDetail = detail => {
+ if (typeof detail !== "string") return detail;
+ const replacements = {
+ MON: "鍛ㄤ竴",
+ TUE: "鍛ㄤ簩",
+ WED: "鍛ㄤ笁",
+ THU: "鍛ㄥ洓",
+ FRI: "鍛ㄤ簲",
+ SAT: "鍛ㄥ叚",
+ SUN: "鍛ㄦ棩",
+ };
+ return detail.replace(
+ /MON|TUE|WED|THU|FRI|SAT|SUN/g,
+ match => replacements[match]
+ );
+ };
-const formatFileSize = size => {
- if (!size) return "0 B";
+ const formatDateTime = date => {
+ if (!date) return "-";
+ return dayjs(date).format("YYYY-MM-DD HH:mm:ss");
+ };
- const units = ["B", "KB", "MB", "GB"];
- let index = 0;
- let fileSize = size;
+ const hasException = ref(null);
+ const abnormalDescription = ref("");
- while (fileSize >= 1024 && index < units.length - 1) {
- fileSize /= 1024;
- index += 1;
- }
+ const showVideoDialog = ref(false);
+ const currentVideoFile = ref(null);
- return `${fileSize.toFixed(2)} ${units[index]}`;
-};
+ const uploadConfig = {
+ action: "/common/upload",
+ limit: 10,
+ fileSize: 50,
+ fileType: ["jpg", "jpeg", "png", "mp4", "mov"],
+ };
-defineExpose({
- openDialog,
-});
+ const uploadFileUrl = computed(
+ () => `${import.meta.env.VITE_APP_BASE_API}${uploadConfig.action}`
+ );
+
+ const processFileUrl = fileUrl => {
+ if (!fileUrl) return "";
+
+ let currentUrl = String(fileUrl);
+ if (currentUrl.includes("\\")) {
+ const uploadsIndex = currentUrl.toLowerCase().indexOf("uploads");
+ if (uploadsIndex > -1) {
+ currentUrl = `/${currentUrl.substring(uploadsIndex).replace(/\\/g, "/")}`;
+ } else {
+ const fileName = currentUrl.split("\\").pop();
+ currentUrl = `/uploads/${fileName}`;
+ }
+ }
+
+ if (currentUrl && !currentUrl.startsWith("http")) {
+ if (!currentUrl.startsWith("/")) {
+ currentUrl = `/${currentUrl}`;
+ }
+ currentUrl = __BASE_API__ + currentUrl;
+ }
+
+ return currentUrl;
+ };
+
+ const normalizeList = (list, fileType) => {
+ if (!Array.isArray(list)) return [];
+
+ return list.filter(Boolean).map(item => {
+ let currentType = item.type;
+ if (!currentType && item.contentType) {
+ currentType = item.contentType.startsWith("video") ? "video" : "image";
+ } else if (!currentType) {
+ currentType = fileType || "image";
+ }
+
+ return {
+ ...item,
+ url: processFileUrl(
+ item.url || item.previewURL || item.downloadUrl || item.path || ""
+ ),
+ downloadUrl: processFileUrl(
+ item.downloadUrl || item.url || item.previewURL || item.path || ""
+ ),
+ name: item.name || item.originalFilename || item.bucketFilename,
+ tempId: item.tempId || item.id || item.tempFileId,
+ tempFileId: item.tempFileId || item.tempId || item.id,
+ size: item.size || item.byteSize || 0,
+ type: currentType,
+ status: "success",
+ uid: item.uid || `${Date.now()}-${Math.random()}`,
+ };
+ });
+ };
+
+ const resetState = () => {
+ taskInfo.value = null;
+ beforeModelValue.value = [];
+ hasException.value = null;
+ abnormalDescription.value = "";
+ uploading.value = false;
+ uploadProgress.value = 0;
+ showVideoDialog.value = false;
+ currentVideoFile.value = null;
+ operationType.value = "add";
+ };
+
+ const openDialog = (type, row) => {
+ operationType.value = type || "add";
+ const raw = JSON.parse(JSON.stringify(row?.__raw || row || {}));
+ taskInfo.value = raw;
+
+ beforeModelValue.value = normalizeList(
+ raw.commonFileListBeforeVO || raw.commonFileListBefore || [],
+ "image"
+ );
+
+ abnormalDescription.value = raw.abnormalDescription || "";
+
+ if (raw.hasException !== undefined && raw.hasException !== null) {
+ hasException.value = raw.hasException;
+ } else if (
+ raw.inspectionResult !== undefined &&
+ raw.inspectionResult !== null
+ ) {
+ hasException.value = String(raw.inspectionResult) === "0";
+ } else {
+ hasException.value = null;
+ }
+
+ if (hasException.value !== true && beforeModelValue.value.length) {
+ hasException.value = true;
+ }
+
+ dialogVisible.value = true;
+ };
+
+ const handleClose = () => {
+ dialogVisible.value = false;
+ resetState();
+ emit("closeDia");
+ };
+
+ const previewVideo = file => {
+ currentVideoFile.value = file;
+ showVideoDialog.value = true;
+ };
+
+ const uploadFile = async uploadRequest => {
+ const rawFile = uploadRequest.file;
+
+ if (beforeModelValue.value.length >= uploadConfig.limit) {
+ ElMessage.warning(`鏈�澶氬彧鑳介�夋嫨${uploadConfig.limit}涓枃浠禶);
+ return;
+ }
+
+ const ext = rawFile.name.split(".").pop()?.toLowerCase();
+ if (!uploadConfig.fileType.includes(ext)) {
+ ElMessage.warning(
+ `鏂囦欢鏍煎紡涓嶆敮鎸侊紝璇蜂笂浼� ${uploadConfig.fileType.join("/")} 鏍煎紡`
+ );
+ return;
+ }
+
+ if (rawFile.size > uploadConfig.fileSize * 1024 * 1024) {
+ ElMessage.warning(`鏂囦欢澶у皬涓嶈兘瓒呰繃 ${uploadConfig.fileSize}MB`);
+ return;
+ }
+
+ const token = getToken();
+ if (!token) {
+ ElMessage.warning("鐢ㄦ埛鏈櫥褰�");
+ return;
+ }
+
+ const formData = new FormData();
+ formData.append("files", rawFile);
+ formData.append("type", 10); // 鐢熶骇鍓嶅浐瀹氫负10
+
+ uploading.value = true;
+ uploadProgress.value = 0;
+
+ try {
+ const { data } = await axios.post(uploadFileUrl.value, formData, {
+ headers: {
+ Authorization: `Bearer ${token}`,
+ "Content-Type": "multipart/form-data",
+ },
+ onUploadProgress: event => {
+ if (event.total) {
+ uploadProgress.value = Math.round((event.loaded / event.total) * 100);
+ }
+ },
+ });
+
+ if (data.code !== 200) {
+ ElMessage.error(data.msg || "涓婁紶澶辫触");
+ return;
+ }
+
+ const resultData = Array.isArray(data.data) ? data.data[0] : data.data;
+ const finalUrl = processFileUrl(
+ resultData.url || resultData.previewURL || resultData.downloadUrl || ""
+ );
+ const finalName =
+ resultData.name ||
+ resultData.originalFilename ||
+ resultData.bucketFilename;
+ const finalId = resultData.tempId || resultData.id || resultData.tempFileId;
+
+ const uploadedFile = {
+ ...resultData,
+ url: finalUrl,
+ downloadUrl: finalUrl,
+ name: finalName,
+ tempId: finalId,
+ tempFileId: resultData.tempFileId || finalId,
+ size: rawFile.size || resultData.size || resultData.byteSize || 0,
+ type: rawFile.type?.startsWith("video") ? "video" : "image",
+ status: "success",
+ uid: `${Date.now()}-${Math.random()}`,
+ };
+
+ beforeModelValue.value.push(uploadedFile);
+ ElMessage.success("涓婁紶鎴愬姛");
+ } catch (error) {
+ ElMessage.error(error?.message || "涓婁紶澶辫触");
+ } finally {
+ uploading.value = false;
+ }
+ };
+
+ const buildFileItem = item => ({
+ id: item?.id,
+ tempId: item?.tempId,
+ tempFileId: item?.tempFileId,
+ url: item?.downloadUrl || item?.url || "",
+ downloadUrl: item?.downloadUrl || item?.url || "",
+ name: item?.name,
+ bucketFilename: item?.bucketFilename || item?.name,
+ originalFilename: item?.originalFilename || item?.name,
+ size: item?.size || 0,
+ byteSize: item?.byteSize || item?.size || 0,
+ contentType: item?.contentType || "",
+ type: item?.type,
+ });
+
+ const submitUpload = async () => {
+ if (hasException.value === null) {
+ ElMessage.warning("璇烽�夋嫨宸℃鐘舵��");
+ return;
+ }
+
+ if (hasException.value === true) {
+ const totalFiles = beforeModelValue.value.length;
+
+ if (!totalFiles) {
+ ElMessage.warning("璇蜂笂浼犲紓甯哥収鐗囨垨瑙嗛");
+ return;
+ }
+
+ if (!abnormalDescription.value.trim()) {
+ ElMessage.warning("璇峰~鍐欏紓甯告弿杩�");
+ return;
+ }
+ }
+
+ const loading = ElLoading.service({
+ text: "鎻愪氦涓�...",
+ background: "rgba(0, 0, 0, 0.3)",
+ });
+
+ try {
+ const allFiles = [...beforeModelValue.value];
+
+ const tempFileIds = allFiles
+ .map(item => item?.tempId ?? item?.tempFileId ?? item?.id)
+ .filter(Boolean);
+
+ const {
+ createTime,
+ updateTime,
+ storageBlobDTO,
+ commonFileListAfterVO,
+ commonFileListVO,
+ commonFileListBeforeVO,
+ commonFileListAfter,
+ commonFileList,
+ commonFileListBefore,
+ __raw,
+ ...baseTaskInfo
+ } = taskInfo.value || {};
+
+ const submitData = {
+ ...baseTaskInfo,
+ commonFileListBeforeDTO: beforeModelValue.value.map(buildFileItem),
+ commonFileListDTO: [],
+ commonFileListAfterDTO: [],
+ hasException: hasException.value,
+ inspectionResult: hasException.value ? 0 : 1,
+ abnormalDescription: abnormalDescription.value,
+ tempFileIds,
+ };
+
+ const result = await uploadInspectionTask(submitData);
+
+ if (result && (result.code === 200 || result.success)) {
+ ElMessage.success("鎻愪氦鎴愬姛");
+ dialogVisible.value = false;
+ resetState();
+ emit("success");
+ emit("closeDia");
+ } else {
+ ElMessage.error(result?.msg || result?.message || "鎻愪氦澶辫触");
+ }
+ } catch (error) {
+ ElMessage.error(error?.message || "鎻愪氦澶辫触");
+ } finally {
+ loading.close();
+ }
+ };
+
+ const removeFile = async index => {
+ try {
+ await ElMessageBox.confirm("纭畾瑕佸垹闄よ繖涓枃浠跺悧锛�", "纭鍒犻櫎", {
+ type: "warning",
+ });
+ beforeModelValue.value.splice(index, 1);
+ } catch {}
+ };
+
+ const goToRepair = () => {
+ const taskData = {
+ taskId: taskInfo.value?.taskId || taskInfo.value?.id,
+ taskName: taskInfo.value?.taskName,
+ inspectionLocation: taskInfo.value?.inspectionLocation,
+ inspector: taskInfo.value?.inspector,
+ hasException: hasException.value,
+ inspectionResult: hasException.value ? 0 : 1,
+ commonFileListBeforeDTO: beforeModelValue.value.map(buildFileItem),
+ commonFileListDTO: [],
+ commonFileListAfterDTO: [],
+ uploadedFiles: {
+ before: beforeModelValue.value,
+ after: [],
+ issue: [],
+ },
+ };
+
+ sessionStorage.setItem("repairTaskInfo", JSON.stringify(taskData));
+ router.push("/equipmentManagement/repair/add");
+ };
+
+ const formatFileSize = size => {
+ if (!size) return "0 B";
+
+ const units = ["B", "KB", "MB", "GB"];
+ let index = 0;
+ let fileSize = size;
+
+ while (fileSize >= 1024 && index < units.length - 1) {
+ fileSize /= 1024;
+ index += 1;
+ }
+
+ return `${fileSize.toFixed(2)} ${units[index]}`;
+ };
+
+ defineExpose({
+ openDialog,
+ });
</script>
<style scoped>
-.inspection-upload-page {
- min-height: 70vh;
- background: #f5f7fa;
- padding: 20px 20px 90px;
- box-sizing: border-box;
-}
+ .inspection-upload-page {
+ min-height: 70vh;
+ background: #f5f7fa;
+ padding: 20px 20px 90px;
+ box-sizing: border-box;
+ }
-.upload-content {
- max-width: 960px;
- margin: 20px auto 0;
-}
+ .upload-content {
+ max-width: 960px;
+ margin: 20px auto 0;
+ }
-.section-card {
- margin-bottom: 16px;
-}
+ .section-card {
+ margin-bottom: 16px;
+ }
-.section-card h3 {
- margin: 0 0 16px;
- font-size: 16px;
-}
+ .section-card h3 {
+ margin: 0 0 16px;
+ font-size: 16px;
+ }
-.upload-buttons {
- display: flex;
- gap: 12px;
- margin: 16px 0;
-}
+ .upload-buttons {
+ display: flex;
+ gap: 12px;
+ margin: 16px 0;
+ }
-.upload-progress {
- margin-bottom: 16px;
-}
+ .upload-progress {
+ margin-bottom: 16px;
+ }
-.file-list {
- display: grid;
- grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
- gap: 12px;
-}
+ .file-list {
+ display: grid;
+ grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
+ gap: 12px;
+ }
-.file-preview-container {
- position: relative;
- aspect-ratio: 1;
- border-radius: 8px;
- overflow: hidden;
- background: #f2f3f5;
-}
+ .file-preview-container {
+ position: relative;
+ aspect-ratio: 1;
+ border-radius: 8px;
+ overflow: hidden;
+ background: #f2f3f5;
+ }
-.file-preview {
- width: 100%;
- height: 100%;
-}
+ .file-preview {
+ width: 100%;
+ height: 100%;
+ }
-.video-preview {
- width: 100%;
- height: 100%;
- background: #303133;
- color: #fff;
- display: flex;
- gap: 6px;
- align-items: center;
- justify-content: center;
- cursor: pointer;
-}
+ .video-preview {
+ width: 100%;
+ height: 100%;
+ background: #303133;
+ color: #fff;
+ display: flex;
+ gap: 6px;
+ align-items: center;
+ justify-content: center;
+ cursor: pointer;
+ }
-.delete-btn {
- position: absolute;
- top: 6px;
- right: 6px;
-}
+ .delete-btn {
+ position: absolute;
+ top: 6px;
+ right: 6px;
+ }
-.file-info {
- margin-top: 6px;
- font-size: 12px;
-}
+ .file-info {
+ margin-top: 6px;
+ font-size: 12px;
+ }
-.file-name {
- color: #606266;
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
-}
+ .file-name {
+ color: #606266;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ }
-.file-size {
- color: #909399;
- margin-top: 2px;
-}
+ .file-size {
+ color: #909399;
+ margin-top: 2px;
+ }
-.upload-summary {
- margin-top: 16px;
-}
+ .upload-summary {
+ margin-top: 16px;
+ }
-.footer-buttons {
- position: sticky;
- left: 0;
- right: 0;
- bottom: 0;
- padding: 14px 20px 0;
- background: #f5f7fa;
- display: flex;
- justify-content: center;
- gap: 12px;
-}
+ .footer-buttons {
+ position: sticky;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ padding: 14px 20px 0;
+ background: #f5f7fa;
+ display: flex;
+ justify-content: center;
+ gap: 12px;
+ }
-.video-player {
- width: 100%;
- max-height: 70vh;
- background: #000;
-}
+ .video-player {
+ width: 100%;
+ max-height: 70vh;
+ background: #000;
+ }
</style>
diff --git a/src/views/equipmentManagement/inspectionManagement/components/viewFiles.vue b/src/views/equipmentManagement/inspectionManagement/components/viewFiles.vue
index b5604fe..1aac0bf 100644
--- a/src/views/equipmentManagement/inspectionManagement/components/viewFiles.vue
+++ b/src/views/equipmentManagement/inspectionManagement/components/viewFiles.vue
@@ -1,37 +1,35 @@
<template>
<div>
- <el-dialog title="鏌ョ湅闄勪欢" v-model="dialogVisitable" width="800px" @close="cancel">
+ <el-dialog title="鏌ョ湅闄勪欢"
+ v-model="dialogVisitable"
+ width="800px"
+ @close="cancel">
<div class="upload-container">
<div class="form-container">
- <div class="title">鐢熶骇鍓�</div>
-
+ <div class="title">鍥剧墖鍒楄〃</div>
<div class="media-list">
- <img
- v-for="(item, index) in beforeProductionImgs"
- :key="`before-img-${index}`"
- :src="item"
- alt=""
- class="media-image"
- @click="showMedia(beforeProductionImgs, index, 'image')"
- />
+ <img v-for="(item, index) in beforeProductionImgs"
+ :key="`before-img-${index}`"
+ :src="item"
+ alt=""
+ class="media-image"
+ @click="showMedia(beforeProductionImgs, index, 'image')" />
</div>
-
<div class="media-list">
- <div
- v-for="(videoUrl, index) in beforeProductionVideos"
- :key="`before-video-${index}`"
- class="video-item"
- @click="showMedia(beforeProductionVideos, index, 'video')"
- >
+ <div v-for="(videoUrl, index) in beforeProductionVideos"
+ :key="`before-video-${index}`"
+ class="video-item"
+ @click="showMedia(beforeProductionVideos, index, 'video')">
<div class="video-thumb">
- <img src="@/assets/images/video.png" alt="鎾斁" class="video-icon" />
+ <img src="@/assets/images/video.png"
+ alt="鎾斁"
+ class="video-icon" />
</div>
<div class="video-text">鐐瑰嚮鎾斁</div>
</div>
</div>
</div>
-
- <div class="form-container">
+ <!-- <div class="form-container">
<div class="title">鐢熶骇涓�</div>
<div class="media-list">
@@ -87,22 +85,25 @@
<div class="video-text">鐐瑰嚮鎾斁</div>
</div>
</div>
- </div>
+ </div> -->
</div>
</el-dialog>
-
- <div v-if="isMediaViewerVisible" class="media-viewer-overlay" @click.self="closeMediaViewer">
- <div class="media-viewer-content" @click.stop>
- <vue-easy-lightbox
- v-if="mediaType === 'image'"
- :visible="isMediaViewerVisible"
- :imgs="mediaList"
- :index="currentMediaIndex"
- @hide="closeMediaViewer"
- />
-
- <div v-else-if="mediaType === 'video'" class="video-player-wrap">
- <video :src="mediaList[currentMediaIndex]" autoplay controls class="video-player" />
+ <div v-if="isMediaViewerVisible"
+ class="media-viewer-overlay"
+ @click.self="closeMediaViewer">
+ <div class="media-viewer-content"
+ @click.stop>
+ <vue-easy-lightbox v-if="mediaType === 'image'"
+ :visible="isMediaViewerVisible"
+ :imgs="mediaList"
+ :index="currentMediaIndex"
+ @hide="closeMediaViewer" />
+ <div v-else-if="mediaType === 'video'"
+ class="video-player-wrap">
+ <video :src="mediaList[currentMediaIndex]"
+ autoplay
+ controls
+ class="video-player" />
</div>
</div>
</div>
@@ -110,215 +111,215 @@
</template>
<script setup>
-import { ref } from "vue";
-import VueEasyLightbox from "vue-easy-lightbox";
+ import { ref } from "vue";
+ import VueEasyLightbox from "vue-easy-lightbox";
-const dialogVisitable = ref(false);
+ const dialogVisitable = ref(false);
-const beforeProductionImgs = ref([]);
-const afterProductionImgs = ref([]);
-const productionIssuesImgs = ref([]);
+ const beforeProductionImgs = ref([]);
+ const afterProductionImgs = ref([]);
+ const productionIssuesImgs = ref([]);
-const beforeProductionVideos = ref([]);
-const afterProductionVideos = ref([]);
-const productionIssuesVideos = ref([]);
+ const beforeProductionVideos = ref([]);
+ const afterProductionVideos = ref([]);
+ const productionIssuesVideos = ref([]);
-const isMediaViewerVisible = ref(false);
-const currentMediaIndex = ref(0);
-const mediaList = ref([]);
-const mediaType = ref("image");
+ const isMediaViewerVisible = ref(false);
+ const currentMediaIndex = ref(0);
+ const mediaList = ref([]);
+ const mediaType = ref("image");
-const processFileUrl = fileUrl => {
- if (!fileUrl) return "";
+ const processFileUrl = fileUrl => {
+ if (!fileUrl) return "";
- let currentUrl = String(fileUrl);
- if (currentUrl.includes("\\")) {
- const uploadsIndex = currentUrl.toLowerCase().indexOf("uploads");
- if (uploadsIndex > -1) {
- currentUrl = `/${currentUrl.substring(uploadsIndex).replace(/\\/g, "/")}`;
- } else {
- const fileName = currentUrl.split("\\").pop();
- currentUrl = `/uploads/${fileName}`;
+ let currentUrl = String(fileUrl);
+ if (currentUrl.includes("\\")) {
+ const uploadsIndex = currentUrl.toLowerCase().indexOf("uploads");
+ if (uploadsIndex > -1) {
+ currentUrl = `/${currentUrl.substring(uploadsIndex).replace(/\\/g, "/")}`;
+ } else {
+ const fileName = currentUrl.split("\\").pop();
+ currentUrl = `/uploads/${fileName}`;
+ }
}
- }
- if (currentUrl && !currentUrl.startsWith("http")) {
- if (!currentUrl.startsWith("/")) {
- currentUrl = `/${currentUrl}`;
+ if (currentUrl && !currentUrl.startsWith("http")) {
+ if (!currentUrl.startsWith("/")) {
+ currentUrl = `/${currentUrl}`;
+ }
+ currentUrl = __BASE_API__ + currentUrl;
}
- currentUrl = __BASE_API__ + currentUrl;
- }
- return currentUrl;
-};
+ return currentUrl;
+ };
-const processItems = items => {
- const images = [];
- const videos = [];
+ const processItems = items => {
+ const images = [];
+ const videos = [];
- if (!Array.isArray(items)) {
+ if (!Array.isArray(items)) {
+ return { images, videos };
+ }
+
+ items.forEach(item => {
+ if (!item) return;
+
+ const fileUrl = processFileUrl(
+ item.previewURL || item.url || item.downloadUrl || item.path || ""
+ );
+ const contentType = String(item.contentType || "").toLowerCase();
+
+ if (!fileUrl) return;
+
+ if (contentType.startsWith("video/")) {
+ videos.push(fileUrl);
+ return;
+ }
+
+ images.push(fileUrl);
+ });
+
return { images, videos };
- }
+ };
- items.forEach(item => {
- if (!item) return;
-
- const fileUrl = processFileUrl(
- item.previewURL || item.url || item.downloadUrl || item.path || ""
+ const openDialog = row => {
+ const { images: beforeImgs, videos: beforeVids } = processItems(
+ row.commonFileListBeforeVO || []
);
- const contentType = String(item.contentType || "").toLowerCase();
+ const { images: afterImgs, videos: afterVids } = processItems(
+ row.commonFileListVO || []
+ );
+ const { images: issueImgs, videos: issueVids } = processItems(
+ row.commonFileListAfterVO || []
+ );
- if (!fileUrl) return;
+ beforeProductionImgs.value = beforeImgs;
+ beforeProductionVideos.value = beforeVids;
+ afterProductionImgs.value = afterImgs;
+ afterProductionVideos.value = afterVids;
+ productionIssuesImgs.value = issueImgs;
+ productionIssuesVideos.value = issueVids;
+ dialogVisitable.value = true;
+ };
- if (contentType.startsWith("video/")) {
- videos.push(fileUrl);
- return;
- }
+ const showMedia = (items, index, type) => {
+ mediaList.value = items;
+ currentMediaIndex.value = index;
+ mediaType.value = type;
+ isMediaViewerVisible.value = true;
+ };
- images.push(fileUrl);
- });
+ const closeMediaViewer = () => {
+ isMediaViewerVisible.value = false;
+ mediaList.value = [];
+ mediaType.value = "image";
+ };
- return { images, videos };
-};
+ const cancel = () => {
+ dialogVisitable.value = false;
+ };
-const openDialog = row => {
- const { images: beforeImgs, videos: beforeVids } = processItems(
- row.commonFileListBeforeVO || []
- );
- const { images: afterImgs, videos: afterVids } = processItems(
- row.commonFileListVO || []
- );
- const { images: issueImgs, videos: issueVids } = processItems(
- row.commonFileListAfterVO || []
- );
-
- beforeProductionImgs.value = beforeImgs;
- beforeProductionVideos.value = beforeVids;
- afterProductionImgs.value = afterImgs;
- afterProductionVideos.value = afterVids;
- productionIssuesImgs.value = issueImgs;
- productionIssuesVideos.value = issueVids;
- dialogVisitable.value = true;
-};
-
-const showMedia = (items, index, type) => {
- mediaList.value = items;
- currentMediaIndex.value = index;
- mediaType.value = type;
- isMediaViewerVisible.value = true;
-};
-
-const closeMediaViewer = () => {
- isMediaViewerVisible.value = false;
- mediaList.value = [];
- mediaType.value = "image";
-};
-
-const cancel = () => {
- dialogVisitable.value = false;
-};
-
-defineExpose({ openDialog });
+ defineExpose({ openDialog });
</script>
<style scoped lang="scss">
-.upload-container {
- display: flex;
- flex-direction: column;
- align-items: center;
- padding: 20px;
- border: 1px solid #dcdfe6;
- box-sizing: border-box;
+ .upload-container {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ padding: 20px;
+ border: 1px solid #dcdfe6;
+ box-sizing: border-box;
- .form-container {
- flex: 1;
- width: 100%;
- margin-bottom: 20px;
+ .form-container {
+ flex: 1;
+ width: 100%;
+ margin-bottom: 20px;
+ }
}
-}
-.title {
- font-size: 14px;
- color: #165dff;
- line-height: 20px;
- font-weight: 600;
- padding-left: 10px;
- position: relative;
- margin: 6px 0;
+ .title {
+ font-size: 14px;
+ color: #165dff;
+ line-height: 20px;
+ font-weight: 600;
+ padding-left: 10px;
+ position: relative;
+ margin: 6px 0;
- &::before {
- content: "";
- position: absolute;
- left: 0;
- top: 3px;
- width: 4px;
- height: 14px;
- background-color: #165dff;
+ &::before {
+ content: "";
+ position: absolute;
+ left: 0;
+ top: 3px;
+ width: 4px;
+ height: 14px;
+ background-color: #165dff;
+ }
}
-}
-.media-list {
- display: flex;
- flex-wrap: wrap;
-}
+ .media-list {
+ display: flex;
+ flex-wrap: wrap;
+ }
-.media-image {
- max-width: 100px;
- height: 100px;
- margin: 5px;
- cursor: pointer;
-}
+ .media-image {
+ max-width: 100px;
+ height: 100px;
+ margin: 5px;
+ cursor: pointer;
+ }
-.video-item {
- position: relative;
- margin: 10px;
- cursor: pointer;
-}
+ .video-item {
+ position: relative;
+ margin: 10px;
+ cursor: pointer;
+ }
-.video-thumb {
- width: 160px;
- height: 90px;
- background-color: #333;
- display: flex;
- align-items: center;
- justify-content: center;
-}
+ .video-thumb {
+ width: 160px;
+ height: 90px;
+ background-color: #333;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ }
-.video-icon {
- width: 30px;
- height: 30px;
- opacity: 0.8;
-}
+ .video-icon {
+ width: 30px;
+ height: 30px;
+ opacity: 0.8;
+ }
-.video-text {
- text-align: center;
- font-size: 12px;
- color: #666;
-}
+ .video-text {
+ text-align: center;
+ font-size: 12px;
+ color: #666;
+ }
-.media-viewer-overlay {
- position: fixed;
- inset: 0;
- background-color: rgba(0, 0, 0, 0.8);
- z-index: 9999;
- display: flex;
- align-items: center;
- justify-content: center;
-}
+ .media-viewer-overlay {
+ position: fixed;
+ inset: 0;
+ background-color: rgba(0, 0, 0, 0.8);
+ z-index: 9999;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ }
-.media-viewer-content {
- position: relative;
- max-width: 90vw;
- max-height: 90vh;
- overflow: hidden;
-}
+ .media-viewer-content {
+ position: relative;
+ max-width: 90vw;
+ max-height: 90vh;
+ overflow: hidden;
+ }
-.video-player-wrap {
- position: relative;
-}
+ .video-player-wrap {
+ position: relative;
+ }
-.video-player {
- max-width: 90vw;
- max-height: 80vh;
-}
+ .video-player {
+ max-width: 90vw;
+ max-height: 80vh;
+ }
</style>
diff --git a/src/views/equipmentManagement/inspectionManagement/index.vue b/src/views/equipmentManagement/inspectionManagement/index.vue
index 8c0d52c..088618e 100644
--- a/src/views/equipmentManagement/inspectionManagement/index.vue
+++ b/src/views/equipmentManagement/inspectionManagement/index.vue
@@ -231,6 +231,12 @@
operation: operations
.map(op => {
switch (op) {
+ case "view":
+ return {
+ name: "璇︽儏",
+ clickFun: openViewDialog,
+ color: "#409EFF",
+ };
case "edit":
return {
name: "缂栬緫",
@@ -273,14 +279,14 @@
];
operationsArr.value = ["edit"];
} else if (value === "task") {
- const operationColumn = getOperationColumn(["upload", "viewFile"]);
+ const operationColumn = getOperationColumn(["view", "upload", "viewFile"]);
// 宸℃璁板綍涓嶅睍绀�"鏄惁鍚敤"鍒�
const taskColumns = columns.value.filter(col => col.prop !== "isEnabled");
tableColumns.value = [
...taskColumns,
...(operationColumn ? [operationColumn] : []),
];
- operationsArr.value = ["upload", "viewFile"];
+ operationsArr.value = ["view", "upload", "viewFile"];
}
pageNum.value = 1;
pageSize.value = 10;
@@ -377,7 +383,13 @@
const openUploadDialog = row => {
nextTick(() => {
- uploadFiles.value?.openDialog(row);
+ uploadFiles.value?.openDialog("add", row);
+ });
+ };
+
+ const openViewDialog = row => {
+ nextTick(() => {
+ uploadFiles.value?.openDialog("view", row);
});
};
diff --git a/src/views/procurementManagement/procurementLedger/detail.vue b/src/views/procurementManagement/procurementLedger/detail.vue
index c1dd275..37b7fdb 100644
--- a/src/views/procurementManagement/procurementLedger/detail.vue
+++ b/src/views/procurementManagement/procurementLedger/detail.vue
@@ -7,7 +7,7 @@
<span class="readonly-text">{{ form.purchaseContractNumber || '--' }}</span>
</el-form-item>
</el-col>
- <el-col :span="12">
+ <el-col v-if="showSalesContractBinding" :span="12">
<el-form-item label="閿�鍞悎鍚屽彿锛�">
<span class="readonly-text">{{ form.salesContractNo || '--' }}</span>
</el-form-item>
@@ -129,6 +129,8 @@
import { getPurchaseById } from "@/api/procurementManagement/procurementLedger"
const visible = ref(false)
+// 鏄惁鏄剧ず閿�鍞悎鍚屽彿缁戝畾
+const showSalesContractBinding = false
const form = ref({})
const productData = ref([])
const fileList = ref([])
diff --git a/src/views/procurementManagement/procurementLedger/index.vue b/src/views/procurementManagement/procurementLedger/index.vue
index e4328aa..9bbe87e 100644
--- a/src/views/procurementManagement/procurementLedger/index.vue
+++ b/src/views/procurementManagement/procurementLedger/index.vue
@@ -11,7 +11,7 @@
<el-input v-model="searchForm.purchaseContractNumber" style="width: 240px" placeholder="璇疯緭鍏�"
@change="handleQuery" clearable :prefix-icon="Search" />
</el-form-item>
- <el-form-item label="閿�鍞悎鍚屽彿锛�">
+ <el-form-item v-if="showSalesContractBinding" label="閿�鍞悎鍚屽彿锛�">
<el-input v-model="searchForm.salesContractNo" placeholder="璇疯緭鍏�" clearable prefix-icon="Search"
@change="handleQuery" />
</el-form-item>
@@ -76,7 +76,7 @@
</el-table-column>
<el-table-column align="center" label="搴忓彿" type="index" width="60" />
<el-table-column label="閲囪喘鍚堝悓鍙�" prop="purchaseContractNumber" width="160" show-overflow-tooltip />
- <el-table-column label="閿�鍞悎鍚屽彿" prop="salesContractNo" width="160" show-overflow-tooltip />
+ <el-table-column v-if="showSalesContractBinding" label="閿�鍞悎鍚屽彿" prop="salesContractNo" width="160" show-overflow-tooltip />
<el-table-column label="渚涘簲鍟嗗悕绉�" prop="supplierName" width="160" show-overflow-tooltip />
<el-table-column label="椤圭洰鍚嶇О" prop="projectName" width="320" show-overflow-tooltip />
<el-table-column label="瀹℃壒鐘舵��" prop="approvalStatus" width="100" show-overflow-tooltip>
@@ -124,7 +124,7 @@
<el-input v-model="form.purchaseContractNumber" placeholder="璇疯緭鍏�" clearable />
</el-form-item>
</el-col>
- <el-col :span="12">
+ <el-col v-if="showSalesContractBinding" :span="12">
<el-form-item label="閿�鍞悎鍚屽彿锛�" prop="salesLedgerId">
<el-select v-model="form.salesLedgerId" placeholder="璇烽�夋嫨" filterable clearable @change="salesLedgerChange">
<el-option v-for="item in salesContractList" :key="item.id" :label="item.salesContractNo" :value="item.id" />
@@ -439,6 +439,9 @@
import FileUpload from "@/components/AttachmentUpload/file/index.vue";
const userStore = useUserStore();
+
+// 鏄惁鏄剧ず閿�鍞悎鍚屽彿缁戝畾
+const showSalesContractBinding = false;
// 璁㈠崟瀹℃壒鐘舵�佹樉绀烘枃鏈�
const approvalStatusText = {
@@ -1034,7 +1037,6 @@
if (form.value.salesLedgerId == -1) {
form.value.salesLedgerId = null;
}
- console.log(form.value, "form.value===========");
dialogFormVisible.value = true;
} catch (error) {
console.error("鎵撳紑琛ㄥ崟澶辫触:", error);
@@ -1536,9 +1538,7 @@
};
// 閿�鍞悎鍚岄�夋嫨鏀瑰彉鏂规硶
const salesLedgerChange = async row => {
- console.log("row", row);
var index = salesContractList.value.findIndex(item => item.id == row);
- console.log("index", index);
if (index > -1) {
await querygProductInfoByContractNo();
}
diff --git a/src/views/procurementManagement/purchaseReturnOrder/New.vue b/src/views/procurementManagement/purchaseReturnOrder/New.vue
index 2c6801d..9474b11 100644
--- a/src/views/procurementManagement/purchaseReturnOrder/New.vue
+++ b/src/views/procurementManagement/purchaseReturnOrder/New.vue
@@ -3,8 +3,10 @@
<el-dialog
v-model="isShow"
title="鏂板閲囪喘閫�璐�"
- width="1600"
+ width="70%"
+ top="3vh"
@close="closeModal"
+ class="purchase-return-dialog"
>
<el-form label-width="140px" :model="formState" label-position="top" ref="formRef" :inline="true">
<div class="section-title">
@@ -221,19 +223,19 @@
<el-input style="width: 240px" v-model="formState.remark" :rows="1" type="textarea" placeholder="璇疯緭鍏ュ娉�"/>
</el-form-item>
- <div style="margin: 20px 0;">
+ <div style="margin:20px 0;min-width:0;">
<div class="section-title">
<span class="title-dot"></span>
<span class="title-text">浜у搧鍒楄〃</span>
</div>
- <el-button type="primary" size="small" style="margin-bottom: 20px" @click="isShowProductsModal = true" :disabled="!formState.purchaseLedgerId">娣诲姞浜у搧</el-button>
- <div class="product-table-scroll">
- <el-table class="product-table-inner"
+ <el-button type="primary" size="small" style="margin-bottom:20px" @click="isShowProductsModal = true" :disabled="!formState.purchaseLedgerId">娣诲姞浜у搧</el-button>
+ <el-table
:data="formState.purchaseReturnOrderProductsDtos"
border
max-height="400"
show-summary
- :summary-method="summarizeChildrenTable">
+ :summary-method="summarizeChildrenTable"
+ style="width:100%;min-width:0;">
<el-table-column align="center"
type="selection"
width="55" />
@@ -324,7 +326,6 @@
</template>
</el-table-column>
</el-table>
- </div>
</div>
<div class="section-title">
@@ -803,12 +804,5 @@
margin-right: 8px;
}
-.product-table-scroll {
- width: 100%;
- overflow-x: auto;
-}
-.product-table-inner {
- min-width: 1280px;
-}
</style>
\ No newline at end of file
diff --git a/vite.config.js b/vite.config.js
index 03311be..fcc019d 100644
--- a/vite.config.js
+++ b/vite.config.js
@@ -12,7 +12,7 @@
: env.VITE_BASE_API;
const javaUrl =
env.VITE_APP_ENV === "development"
- ? "http://1.15.17.182:9049"
+ ? "http://1.15.17.182:9048"
: env.VITE_JAVA_API;
return {
define:{
--
Gitblit v1.9.3