From 9069f337c18c44406c5d841d2354193c61988bd9 Mon Sep 17 00:00:00 2001
From: yyb <995253665@qq.com>
Date: 星期四, 23 四月 2026 13:05:19 +0800
Subject: [PATCH] 新增报修图片管理功能,包括图片上传、删除和列表查询,优化报修页面的图片处理逻辑
---
src/api/equipmentManagement/repair.js | 24 ++++
src/pages/equipmentManagement/repair/index.vue | 3
src/pages/equipmentManagement/repair/add.vue | 318 ++++++++++++++++++++++++++++++++++++++++++++++++++--
3 files changed, 328 insertions(+), 17 deletions(-)
diff --git a/src/api/equipmentManagement/repair.js b/src/api/equipmentManagement/repair.js
index 927d5fb..6b19027 100644
--- a/src/api/equipmentManagement/repair.js
+++ b/src/api/equipmentManagement/repair.js
@@ -76,4 +76,28 @@
method: "get",
params,
});
+};
+
+/**
+ * @desc 鏌ヨ鎶ヤ慨鍥剧墖鍒楄〃
+ * @param {鎶ヤ慨id} id
+ * @returns
+ */
+export const getRepairFileList = (id) => {
+ return request({
+ url: `/device/repair/file/${id}`,
+ method: "get",
+ });
+};
+
+/**
+ * @desc 鍒犻櫎鎶ヤ慨鍥剧墖
+ * @param {鏂囦欢id} fileId
+ * @returns
+ */
+export const delRepairFile = (fileId) => {
+ return request({
+ url: `/device/repair/file/${fileId}`,
+ method: "delete",
+ });
};
\ No newline at end of file
diff --git a/src/pages/equipmentManagement/repair/add.vue b/src/pages/equipmentManagement/repair/add.vue
index 71de940..5ff1828 100644
--- a/src/pages/equipmentManagement/repair/add.vue
+++ b/src/pages/equipmentManagement/repair/add.vue
@@ -80,6 +80,34 @@
count
maxlength="200" />
</u-form-item>
+ <u-form-item label="鏁呴殰鍥剧墖"
+ border-bottom>
+ <view class="repair-image-upload">
+ <u-button type="primary"
+ @click="chooseRepairImage"
+ :loading="uploading"
+ :disabled="uploading">
+ {{ uploading ? "涓婁紶涓�..." : "涓婁紶鏁呴殰鍥剧墖" }}
+ </u-button>
+ <view v-if="repairImageList.length"
+ class="repair-image-list">
+ <view v-for="(file, index) in repairImageList"
+ :key="file.id || index"
+ class="repair-image-item">
+ <image :src="normalizeFileUrl(file.url || file.tempFilePath)"
+ mode="aspectFill"
+ class="repair-image-preview"
+ @click="previewRepairImage(index)" />
+ <view class="repair-image-delete"
+ @click="removeRepairImage(file, index)">
+ <u-icon name="close"
+ size="12"
+ color="#fff" />
+ </view>
+ </view>
+ </view>
+ </view>
+ </u-form-item>
</u-cell-group>
<!-- 鎻愪氦鎸夐挳 -->
<view class="footer-btns">
@@ -108,12 +136,16 @@
<script setup>
import { ref, computed, onMounted, onUnmounted } from "vue";
- import { onShow } from "@dcloudio/uni-app";
+ import { onLoad, onShow } from "@dcloudio/uni-app";
import PageHeader from "@/components/PageHeader.vue";
+ import config from "@/config";
+ import { getToken } from "@/utils/auth";
import { getDeviceLedger } from "@/api/equipmentManagement/ledger";
import {
addRepair,
+ delRepairFile,
editRepair,
+ getRepairFileList,
getRepairById,
} from "@/api/equipmentManagement/repair";
import dayjs from "dayjs";
@@ -136,6 +168,10 @@
const showDevice = ref(false);
const showDate = ref(false);
const pickerDateValue = ref(Date.now());
+ const uploading = ref(false);
+ const repairImageList = ref([]);
+ const currentRepairId = ref(undefined);
+ const pageInited = ref(false);
// 璁惧閫夐」
const deviceOptions = ref([]);
@@ -171,6 +207,200 @@
repairName: undefined, // 鎶ヤ慨浜�
remark: undefined, // 鏁呴殰鐜拌薄
});
+
+ const normalizeFileUrl = (rawUrl = "") => {
+ let fileUrl = rawUrl || "";
+ const javaApi = config.baseUrl;
+ const localPrefixes = ["wxfile://", "file://", "content://", "blob:", "data:"];
+
+ if (localPrefixes.some(prefix => fileUrl.startsWith(prefix))) {
+ return fileUrl;
+ }
+
+ if (fileUrl && 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 && !fileUrl.startsWith("http")) {
+ if (!fileUrl.startsWith("/")) fileUrl = "/" + fileUrl;
+ fileUrl = javaApi + fileUrl;
+ }
+
+ return fileUrl;
+ };
+
+ const normalizeId = raw => {
+ if (raw === null || raw === undefined) return undefined;
+ const val = String(raw).trim();
+ if (!val || val === "undefined" || val === "null") return undefined;
+ return val;
+ };
+
+ const resolveRepairId = () => {
+ const pages = getCurrentPages();
+ const currentPage = pages[pages.length - 1] || {};
+ const routeId = normalizeId(currentPage?.options?.id);
+ const memoryId = normalizeId(currentRepairId.value);
+ const storageId = normalizeId(uni.getStorageSync("repairId"));
+ return memoryId || routeId || storageId;
+ };
+
+ const getPageId = () => {
+ const id = resolveRepairId();
+ currentRepairId.value = id;
+ return id;
+ };
+
+ const fetchRepairFileList = async id => {
+ if (!id) {
+ repairImageList.value = [];
+ return;
+ }
+ try {
+ const { code, data } = await getRepairFileList(id);
+ if (code === 200) {
+ repairImageList.value = Array.isArray(data) ? data : [];
+ } else {
+ repairImageList.value = [];
+ }
+ } catch (e) {
+ repairImageList.value = [];
+ }
+ };
+
+ const chooseRepairImage = () => {
+ uni.chooseImage({
+ count: 9,
+ sizeType: ["original", "compressed"],
+ sourceType: ["album", "camera"],
+ success: res => {
+ const id = getPageId();
+ const files = res.tempFiles || [];
+ if (!files.length) return;
+ if (id) {
+ uploadRepairImages(files, id);
+ return;
+ }
+ if (operationType.value === "edit") {
+ showToast("鏈幏鍙栧埌鎶ヤ慨ID锛岃杩斿洖鍒楄〃鍚庨噸璇�");
+ return;
+ }
+ // 鏂板妯″紡涓存椂涓婁紶锛氬厛鏈湴鏆傚瓨锛屼繚瀛樻姤淇悗鍐嶈嚜鍔ㄤ笂浼犵粦瀹�
+ const tempItems = files.map((file, idx) => {
+ const filePath = file.path || file.tempFilePath;
+ return {
+ id: `temp_${Date.now()}_${idx}`,
+ url: filePath,
+ tempFilePath: filePath,
+ name: file.name || `temp_${Date.now()}_${idx}.jpg`,
+ isTemp: true,
+ };
+ });
+ repairImageList.value = [...repairImageList.value, ...tempItems];
+ showToast("宸蹭复鏃舵坊鍔狅紝淇濆瓨鎶ヤ慨鍚庤嚜鍔ㄤ笂浼�");
+ },
+ fail: () => {
+ showToast("閫夋嫨鍥剧墖澶辫触");
+ },
+ });
+ };
+
+ const uploadRepairImages = async (files, repairId) => {
+ const commonId = normalizeId(repairId);
+ if (!commonId) {
+ showToast("鏈幏鍙栧埌鎶ヤ慨ID锛屼笂浼犲け璐�");
+ return;
+ }
+ const token = getToken();
+ if (!token) {
+ showToast("鐧诲綍宸插け鏁堬紝璇烽噸鏂扮櫥褰�");
+ return;
+ }
+ uploading.value = true;
+ try {
+ for (const file of files) {
+ const filePath = file.path || file.tempFilePath;
+ if (!filePath) continue;
+ await new Promise((resolve, reject) => {
+ uni.uploadFile({
+ url: `${config.baseUrl}/device/repair/uploadFile`,
+ filePath,
+ name: "file",
+ formData: {
+ deviceRepairId: commonId,
+ type: 13,
+ },
+ header: {
+ Authorization: `Bearer ${token}`,
+ },
+ success: uploadRes => {
+ try {
+ const parsed = JSON.parse(uploadRes.data || "{}");
+ if (uploadRes.statusCode === 200 && parsed.code === 200) {
+ resolve(parsed);
+ } else {
+ reject(new Error(parsed.msg || "涓婁紶澶辫触"));
+ }
+ } catch (err) {
+ reject(new Error("涓婁紶鍝嶅簲瑙f瀽澶辫触"));
+ }
+ },
+ fail: () => reject(new Error("涓婁紶澶辫触")),
+ });
+ });
+ }
+ showToast("涓婁紶鎴愬姛");
+ await fetchRepairFileList(commonId);
+ } catch (e) {
+ showToast(e?.message || "涓婁紶澶辫触");
+ } finally {
+ uploading.value = false;
+ }
+ };
+
+ const previewRepairImage = index => {
+ const urls = repairImageList.value
+ .map(item => normalizeFileUrl(item.url || item.tempFilePath))
+ .filter(Boolean);
+ if (!urls.length) return;
+ uni.previewImage({
+ urls,
+ current: urls[index] || urls[0],
+ });
+ };
+
+ const removeRepairImage = (file, index) => {
+ if (!file?.id || file?.isTemp) {
+ repairImageList.value.splice(index, 1);
+ return;
+ }
+ uni.showModal({
+ title: "鎻愮ず",
+ content: "纭鍒犻櫎璇ュ浘鐗囧悧锛�",
+ success: async res => {
+ if (!res.confirm) return;
+ try {
+ const { code } = await delRepairFile(file.id);
+ if (code === 200) {
+ repairImageList.value.splice(index, 1);
+ showToast("鍒犻櫎鎴愬姛");
+ } else {
+ showToast("鍒犻櫎澶辫触");
+ }
+ } catch (e) {
+ showToast("鍒犻櫎澶辫触");
+ }
+ },
+ });
+ };
// 鎶ヤ慨鐘舵�侀�夐」
const repairStatusOptions = ref([
@@ -222,6 +452,7 @@
form.value.repairTime = dayjs(data.repairTime).format("YYYY-MM-DD");
form.value.repairName = data.repairName;
form.value.remark = data.remark;
+ await fetchRepairFileList(id);
repairStatusText.value =
repairStatusOptions.value.find(item => item.value == data.status)
?.name || "";
@@ -327,15 +558,23 @@
showDate.value = false;
};
+ onLoad(options => {
+ const routeId = normalizeId(options?.id);
+ const storageId = normalizeId(uni.getStorageSync("repairId"));
+ const id = routeId || storageId;
+ currentRepairId.value = id || undefined;
+ pageInited.value = true;
+ });
+
onShow(() => {
- // 椤甸潰鏄剧ず鏃惰幏鍙栧弬鏁�
+ // onLoad 宸叉嬁鍒� id 鍚庯紝鍐嶆寜褰撳墠 id 鍒濆鍖栭〉闈�
+ if (!pageInited.value) return;
getPageParams();
});
onMounted(() => {
- // 椤甸潰鍔犺浇鏃惰幏鍙栬澶囧垪琛ㄥ拰鍙傛暟
+ // 椤甸潰鍔犺浇鏃跺厛鑾峰彇璁惧鍒楄〃
loadDeviceName();
- getPageParams();
});
// 缁勪欢鍗歌浇鏃舵竻鐞嗗畾鏃跺櫒
@@ -376,11 +615,28 @@
// 鍑嗗鎻愪氦鏁版嵁
const submitData = { ...form.value };
- const { code } = id
+ const result = id
? await editRepair({ id: id, ...submitData })
: await addRepair(submitData);
+ const { code, data } = result || {};
if (code == 200) {
+ // 鏂板鍦烘櫙锛氫复鏃跺浘鐗囧湪淇濆瓨鎴愬姛鍚庤嚜鍔ㄤ笂浼犲苟缁戝畾鏂版姤淇崟
+ if (!id) {
+ const newId = data?.id || data?.repairId || data;
+ if (newId) {
+ currentRepairId.value = newId;
+ const tempFiles = repairImageList.value
+ .filter(item => item?.isTemp && (item.tempFilePath || item.url))
+ .map(item => ({
+ path: item.tempFilePath || item.url,
+ tempFilePath: item.tempFilePath || item.url,
+ }));
+ if (tempFiles.length) {
+ await uploadRepairImages(tempFiles, newId);
+ }
+ }
+ }
showToast(`${id ? "缂栬緫" : "鏂板"}鎶ヤ慨鎴愬姛`);
setTimeout(() => {
uni.navigateBack();
@@ -402,26 +658,19 @@
// 鑾峰彇椤甸潰鍙傛暟
const getPageParams = () => {
- // 浣跨敤uni.getStorageSync鑾峰彇id
- const id = uni.getStorageSync("repairId");
+ const id = resolveRepairId();
+ currentRepairId.value = id || undefined;
// 鏍规嵁鏄惁鏈塱d鍙傛暟鏉ュ垽鏂槸鏂板杩樻槸缂栬緫
if (id) {
// 缂栬緫妯″紡锛岃幏鍙栬鎯�
loadForm(id);
- // 鍙�夛細鑾峰彇鍚庢竻闄ゅ瓨鍌ㄧ殑id锛岄伩鍏嶅奖鍝嶅悗缁搷浣�
- uni.removeStorageSync("repairId");
} else {
// 鏂板妯″紡
+ currentRepairId.value = undefined;
+ repairImageList.value = [];
loadForm();
}
- };
-
- // 鑾峰彇椤甸潰ID
- const getPageId = () => {
- // 浣跨敤uni.getStorageSync鑾峰彇id
- const id = uni.getStorageSync("repairId");
- return id;
};
</script>
@@ -486,4 +735,41 @@
margin-left: 8px;
cursor: pointer;
}
+
+ .repair-image-upload {
+ width: 100%;
+ }
+
+ .repair-image-list {
+ margin-top: 12px;
+ display: flex;
+ flex-wrap: wrap;
+ gap: 10px;
+ }
+
+ .repair-image-item {
+ position: relative;
+ width: 80px;
+ height: 80px;
+ }
+
+ .repair-image-preview {
+ width: 80px;
+ height: 80px;
+ border-radius: 6px;
+ background: #f5f5f5;
+ }
+
+ .repair-image-delete {
+ position: absolute;
+ top: -6px;
+ right: -6px;
+ width: 18px;
+ height: 18px;
+ border-radius: 50%;
+ background: rgba(0, 0, 0, 0.65);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ }
</style>
\ No newline at end of file
diff --git a/src/pages/equipmentManagement/repair/index.vue b/src/pages/equipmentManagement/repair/index.vue
index e280595..a3c1eba 100644
--- a/src/pages/equipmentManagement/repair/index.vue
+++ b/src/pages/equipmentManagement/repair/index.vue
@@ -199,6 +199,7 @@
// 鏂板鎶ヤ慨 - 璺宠浆鍒版姤淇〉闈�
const addRepair = () => {
+ uni.removeStorageSync("repairId");
uni.navigateTo({
url: "/pages/equipmentManagement/repair/add",
});
@@ -210,7 +211,7 @@
// 浣跨敤uni.setStorageSync瀛樺偍id
uni.setStorageSync("repairId", id);
uni.navigateTo({
- url: "/pages/equipmentManagement/repair/add",
+ url: `/pages/equipmentManagement/repair/add?id=${id}`,
});
};
--
Gitblit v1.9.3