From 97586104d7808d8ea8fb5f3e5d4c60e2a7943667 Mon Sep 17 00:00:00 2001
From: yuan <123@>
Date: 星期六, 23 五月 2026 17:51:51 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/dev_pro_河南鹤壁' into dev_pro_河南鹤壁
---
src/views/equipmentManagement/inspectionManagement/components/uploadFiles.vue | 1194 ++++++++++++++++++++++++++++++-----------------------------
1 files changed, 603 insertions(+), 591 deletions(-)
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>
--
Gitblit v1.9.3