From 991f6f78fccb86b2718ab96969a69304daafe2b4 Mon Sep 17 00:00:00 2001
From: spring <2396852758@qq.com>
Date: 星期一, 03 十一月 2025 17:32:50 +0800
Subject: [PATCH] fix: 完成巡查
---
src/pages/production/twist/attachment/index.vue | 403 ++++++++++++++++++++++++++++++++++++++++++++-------------
1 files changed, 311 insertions(+), 92 deletions(-)
diff --git a/src/pages/production/twist/attachment/index.vue b/src/pages/production/twist/attachment/index.vue
index e6c26f5..0d17e10 100644
--- a/src/pages/production/twist/attachment/index.vue
+++ b/src/pages/production/twist/attachment/index.vue
@@ -17,26 +17,54 @@
<view class="attachment-list">
<wd-status-tip v-if="attachmentList.length === 0" image="content" tip="鏆傛棤闄勪欢" />
- <wd-card
- v-for="item in attachmentList"
- :key="item.id"
- type="rectangle"
- custom-class="attachment-card"
- :border="false"
- >
- <view class="attachment-item" @click="previewAttachment(item)">
- <view class="attachment-info">
- <view class="attachment-name">{{ item.bucketFileName || item.name }}</view>
- <view class="attachment-meta">
- <text class="file-type">{{ getFileType(item.bucketFileName) }}</text>
- <text class="upload-time">{{ formatTime(item.createTime) }}</text>
+ <view v-for="item in attachmentList" :key="item.id" class="attachment-card">
+ <view class="media-wrapper" @click="previewAttachment(item)">
+ <!-- 鍥剧墖棰勮 -->
+ <template v-if="isImageType(item.url)">
+ <image
+ v-if="!item.loadError"
+ :src="getFullUrl(item.url)"
+ mode="aspectFill"
+ class="media-preview"
+ @error="onImageError(item)"
+ @load="onImageLoad(item)"
+ />
+ <!-- 鍥剧墖鍔犺浇澶辫触鏄剧ず榛樿鍥炬爣 -->
+ <view v-else class="file-icon-wrapper">
+ <wd-icon name="picture" size="48px" color="#ccc" />
+ <text class="file-name error-text">鍔犺浇澶辫触</text>
</view>
+ </template>
+
+ <!-- 瑙嗛棰勮 -->
+ <template v-else-if="isVideoType(item.url)">
+ <video
+ v-if="!item.loadError"
+ :src="getFullUrl(item.url)"
+ class="media-preview"
+ :controls="false"
+ :show-center-play-btn="false"
+ @error="onVideoError(item)"
+ />
+ <!-- 瑙嗛鍔犺浇澶辫触鏄剧ず榛樿鍥炬爣 -->
+ <view v-else class="file-icon-wrapper">
+ <wd-icon name="video" size="48px" color="#ccc" />
+ <text class="file-name error-text">鍔犺浇澶辫触</text>
+ </view>
+ </template>
+
+ <!-- 鍏朵粬鏂囦欢绫诲瀷鏄剧ず鍥炬爣 -->
+ <view v-else class="file-icon-wrapper">
+ <wd-icon name="file-outline" size="48px" color="#999" />
+ <text class="file-name">鏂囦欢</text>
</view>
- <view class="attachment-actions">
- <wd-icon name="delete" color="#ff4757" @click.stop="deleteAttachment(item.id)" />
+
+ <!-- 鍒犻櫎鎸夐挳 -->
+ <view class="delete-btn" @click.stop="deleteAttachment(item.id)">
+ <wd-icon name="delete" color="#fff" size="20px" />
</view>
</view>
- </wd-card>
+ </view>
</view>
<wd-toast />
@@ -48,6 +76,12 @@
import { useToast } from "wot-design-uni";
import AttachmentAPI from "@/api/product/attachment";
+// H5 浣跨敤 VITE_APP_BASE_API 浣滀负浠g悊璺緞锛屽叾浠栧钩鍙颁娇鐢� VITE_APP_API_URL 浣滀负璇锋眰璺緞
+let baseUrl = import.meta.env.VITE_APP_API_URL;
+// #ifdef H5
+baseUrl = import.meta.env.VITE_APP_BASE_API;
+// #endif
+
const toast = useToast();
// 椤甸潰鍙傛暟
@@ -55,21 +89,79 @@
const reportType = ref("缁炵嚎");
const attachmentList = ref<any[]>([]);
+const detailData = ref<any>({});
+
+// 鑾峰彇瀹屾暣鐨勫浘鐗�/瑙嗛 URL
+const getFullUrl = (url: string) => {
+ if (!url) return "";
+ // 濡傛灉宸茬粡鏄畬鏁寸殑 URL锛坔ttp 鎴� https 寮�澶达級锛岀洿鎺ヨ繑鍥�
+ if (url.startsWith("http://") || url.startsWith("https://")) {
+ return url;
+ }
+ // 濡傛灉鏄浉瀵硅矾寰勶紝鎷兼帴鍩虹 URL
+ return `${baseUrl}${url.startsWith("/") ? "" : "/"}${url}`;
+};
+
+// 浠� URL 鎴栨枃浠跺悕涓彁鍙栨墿灞曞悕
+const getExtension = (urlOrFileName: string) => {
+ if (!urlOrFileName) return "";
+ // 绉婚櫎鏌ヨ鍙傛暟鍜屽搱甯�
+ const cleanUrl = urlOrFileName.split("?")[0].split("#")[0];
+ // 鑾峰彇鏈�鍚庝竴涓偣鍚庨潰鐨勫唴瀹�
+ const extension = cleanUrl.split(".").pop()?.toLowerCase();
+ return extension || "";
+};
+
+// 鍒ゆ柇鏄惁涓哄浘鐗囩被鍨�
+const isImageType = (urlOrFileName: string) => {
+ const extension = getExtension(urlOrFileName);
+ return ["jpg", "jpeg", "png", "gif", "bmp", "webp"].includes(extension);
+};
+
+// 鍒ゆ柇鏄惁涓鸿棰戠被鍨�
+const isVideoType = (urlOrFileName: string) => {
+ const extension = getExtension(urlOrFileName);
+ return ["mp4", "mov", "avi", "wmv", "flv", "mkv", "webm"].includes(extension);
+};
+
+// 鍥剧墖鍔犺浇鎴愬姛
+const onImageLoad = (item: any) => {
+ item.loadError = false;
+};
+
+// 鍥剧墖鍔犺浇澶辫触
+const onImageError = (item: any) => {
+ console.error("鍥剧墖鍔犺浇澶辫触:", item.url);
+ item.loadError = true;
+};
+
+// 瑙嗛鍔犺浇澶辫触
+const onVideoError = (item: any) => {
+ console.error("瑙嗛鍔犺浇澶辫触:", item.url);
+ item.loadError = true;
+};
+
// 鑾峰彇闄勪欢鍒楄〃
-const getAttachmentList = async () => {
+const getAttachmentList = async (data: any) => {
try {
+ detailData.value = data;
+ console.log(" detailData.value", detailData.value);
const pages = getCurrentPages();
const currentPage = pages[pages.length - 1];
const options = (currentPage as any).options;
- const currentReportId = options?.reportId;
+ const currentReportId = detailData.value.id;
if (currentReportId) {
reportId.value = currentReportId;
// 鐩存帴璋冪敤閫氱敤鏌ョ湅鎺ュ彛鏌ヨ闄勪欢鍒楄〃
// 浣跨敤绀轰緥涓殑闄勪欢ID鏁扮粍 [850,851]
- const attachmentIds: number[] = [850, 851]; // 浣跨敤HTTP鏂囦欢涓殑绀轰緥鏁版嵁
+ const attachmentIds: number[] =
+ detailData.value.attachmentId !== null ? detailData.value.attachmentId.split(",") : []; // 浣跨敤HTTP鏂囦欢涓殑绀轰緥鏁版嵁
+ if (attachmentIds.length === 0) {
+ return;
+ }
const { data } = await AttachmentAPI.listAttachmentFiles(attachmentIds);
attachmentList.value = data || [];
} else {
@@ -84,45 +176,136 @@
// 鏂板闄勪欢
const addAttachment = () => {
- uni.chooseFile({
- count: 9, // 鏈�澶氶�夋嫨9涓枃浠�
- type: "all", // 鎵�鏈夌被鍨嬫枃浠�
- success: async (res) => {
- try {
- toast.show("姝e湪涓婁紶...");
-
- // 涓婁紶鏂囦欢
- const filePaths = Array.isArray(res.tempFilePaths)
- ? res.tempFilePaths
- : [res.tempFilePaths];
- const uploadResults = await AttachmentAPI.uploadAttachmentFiles(filePaths);
-
- // 鎻愬彇闄勪欢ID
- const attachmentIds = uploadResults.map((result) => result.data.id).join(",");
-
- // 鍏宠仈鍒版姤宸�
- await AttachmentAPI.addOutputAttachments({
- id: parseInt(reportId.value),
- attachmentIds: attachmentIds,
- });
-
- toast.show("涓婁紶鎴愬姛");
- // 閲嶆柊鑾峰彇闄勪欢鍒楄〃
- await getAttachmentList();
- } catch (error) {
- console.error("涓婁紶澶辫触:", error);
- toast.show("涓婁紶澶辫触");
+ // 鏄剧ず閫夋嫨鏂囦欢绫诲瀷鐨勫脊绐�
+ uni.showActionSheet({
+ itemList: ["閫夋嫨鍥剧墖", "閫夋嫨瑙嗛", "鎷嶇収", "褰曞儚"],
+ success: (res) => {
+ switch (res.tapIndex) {
+ case 0: // 閫夋嫨鍥剧墖
+ chooseImages();
+ break;
+ case 1: // 閫夋嫨瑙嗛
+ chooseVideos();
+ break;
+ case 2: // 鎷嶇収
+ takePhoto();
+ break;
+ case 3: // 褰曞儚
+ recordVideo();
+ break;
}
},
fail: (error) => {
- console.error("閫夋嫨鏂囦欢澶辫触:", error);
- toast.show("閫夋嫨鏂囦欢澶辫触");
+ console.error("閫夋嫨鏂囦欢绫诲瀷澶辫触:", error);
+ toast.show("閫夋嫨鏂囦欢绫诲瀷澶辫触");
},
});
};
+// 閫夋嫨鍥剧墖
+const chooseImages = () => {
+ uni.chooseImage({
+ count: 9,
+ sizeType: ["original", "compressed"],
+ sourceType: ["album"],
+ success: async (res) => {
+ const filePaths = Array.isArray(res.tempFilePaths) ? res.tempFilePaths : [res.tempFilePaths];
+ await handleFileUpload(filePaths);
+ },
+ fail: (error) => {
+ console.error("閫夋嫨鍥剧墖澶辫触:", error);
+ toast.show("閫夋嫨鍥剧墖澶辫触");
+ },
+ });
+};
+
+// 閫夋嫨瑙嗛
+const chooseVideos = () => {
+ uni.chooseVideo({
+ sourceType: ["album"],
+ maxDuration: 60,
+ camera: "back",
+ success: async (res) => {
+ await handleFileUpload([res.tempFilePath]);
+ },
+ fail: (error) => {
+ console.error("閫夋嫨瑙嗛澶辫触:", error);
+ toast.show("閫夋嫨瑙嗛澶辫触");
+ },
+ });
+};
+
+// 鎷嶇収
+const takePhoto = () => {
+ uni.chooseImage({
+ count: 1,
+ sizeType: ["original", "compressed"],
+ sourceType: ["camera"],
+ success: async (res) => {
+ const filePaths = Array.isArray(res.tempFilePaths) ? res.tempFilePaths : [res.tempFilePaths];
+ await handleFileUpload(filePaths);
+ },
+ fail: (error) => {
+ console.error("鎷嶇収澶辫触:", error);
+ toast.show("鎷嶇収澶辫触");
+ },
+ });
+};
+
+// 褰曞儚
+const recordVideo = () => {
+ uni.chooseVideo({
+ sourceType: ["camera"],
+ maxDuration: 60,
+ camera: "back",
+ success: async (res) => {
+ await handleFileUpload([res.tempFilePath]);
+ },
+ fail: (error) => {
+ console.error("褰曞儚澶辫触:", error);
+ toast.show("褰曞儚澶辫触");
+ },
+ });
+};
+
+// 澶勭悊鏂囦欢涓婁紶
+const handleFileUpload = async (filePaths: string[]) => {
+ try {
+ toast.show("姝e湪涓婁紶...");
+
+ // 涓婁紶鏂囦欢
+ const uploadResults: any = await AttachmentAPI.uploadAttachmentFiles(filePaths);
+ const result = uploadResults.map((it: any) => {
+ return it.data;
+ });
+ console.log("result", result);
+
+ // 鏇存柊闄勪欢鍒楄〃
+ const flattenedResult = result.flat();
+ attachmentList.value.push(...flattenedResult);
+ console.log(attachmentList.value);
+
+ // 鎻愬彇闄勪欢ID
+ const attachmentId = attachmentList.value.map((item: any) => item.id).join(",");
+
+ // 鍏宠仈鍒版姤宸�
+ if (attachmentId) {
+ await AttachmentAPI.addOutputAttachments({
+ id: parseInt(detailData.value.id),
+ attachmentId: attachmentId,
+ });
+ detailData.value.attachmentId = attachmentId;
+ }
+
+ toast.show("涓婁紶鎴愬姛");
+ } catch (error) {
+ console.error("涓婁紶澶辫触:", error);
+ toast.show("涓婁紶澶辫触");
+ }
+};
+
// 鍒犻櫎闄勪欢
-const deleteAttachment = async (attachmentId: number) => {
+const deleteAttachment = async (aid: number) => {
try {
uni.showModal({
title: "纭鍒犻櫎",
@@ -130,18 +313,17 @@
success: async (res) => {
if (res.confirm) {
// 鍓嶇鎵嬪姩鍒犻櫎锛氱洿鎺ヤ粠鍒楄〃涓Щ闄よ繖鏉℃暟鎹�
- attachmentList.value = attachmentList.value.filter((item) => item.id !== attachmentId);
+ attachmentList.value = attachmentList.value.filter((item) => item.id !== aid);
// 鑾峰彇鍓╀綑鐨勯檮浠禝D缁勫悎
- const remainingIds = attachmentList.value.map((item) => item.id);
- const attachmentIds = remainingIds.join(",");
+ const attachmentId = attachmentList.value.map((item) => item.id).join(",");
// 璋冪敤鎶ュ伐娣诲姞闄勪欢鎺ュ彛锛屾洿鏂伴檮浠跺叧鑱�
await AttachmentAPI.addOutputAttachments({
- id: parseInt(reportId.value),
- attachmentIds: attachmentIds,
+ id: parseInt(detailData.value.id),
+ attachmentId: attachmentId,
});
-
+ detailData.value.attachmentId = attachmentId;
toast.show("鍒犻櫎鎴愬姛");
}
},
@@ -155,24 +337,24 @@
// 棰勮闄勪欢
const previewAttachment = (item: any) => {
// 鏍规嵁鏂囦欢绫诲瀷杩涜棰勮
- const fileName = item.bucketFileName || item.name;
- const fileType = getFileType(fileName);
+ const fileType = getFileType(item.url);
+ const fullUrl = getFullUrl(item.url);
if (fileType.startsWith("image")) {
// 鍥剧墖棰勮
uni.previewImage({
- urls: [item.url],
- current: item.url,
+ urls: [fullUrl],
+ current: fullUrl,
});
} else {
// 鍏朵粬鏂囦欢绫诲瀷锛屽彲浠ヤ笅杞芥垨鎵撳紑
uni.downloadFile({
- url: item.url,
+ url: fullUrl,
success: (res) => {
uni.openDocument({
filePath: res.tempFilePath,
success: () => {
- console.log("鎵撳紑鏂囨。鎴愬姛");
+ // 鎵撳紑鏂囨。鎴愬姛
},
fail: (error) => {
console.error("鎵撳紑鏂囨。澶辫触:", error);
@@ -189,9 +371,9 @@
};
// 鑾峰彇鏂囦欢绫诲瀷
-const getFileType = (fileName: string) => {
- if (!fileName) return "unknown";
- const extension = fileName.split(".").pop()?.toLowerCase();
+const getFileType = (urlOrFileName: string) => {
+ if (!urlOrFileName) return "unknown";
+ const extension = getExtension(urlOrFileName);
switch (extension) {
case "jpg":
case "jpeg":
@@ -200,6 +382,14 @@
case "bmp":
case "webp":
return "image";
+ case "mp4":
+ case "mov":
+ case "avi":
+ case "wmv":
+ case "flv":
+ case "mkv":
+ case "webm":
+ return "video";
case "pdf":
return "pdf";
case "doc":
@@ -235,7 +425,10 @@
};
onMounted(() => {
- getAttachmentList();
+ uni.$on("detailData", (data) => {
+ // 澶勭悊鎺ユ敹鍒扮殑鏁版嵁
+ getAttachmentList(data);
+ });
});
</script>
@@ -257,43 +450,69 @@
}
.attachment-list {
+ display: grid;
+ grid-template-columns: repeat(3, 1fr);
+ gap: 8px;
+
.attachment-card {
- margin-bottom: 12px;
- border-radius: 4px;
+ width: 100%;
+ aspect-ratio: 1;
}
}
-.attachment-item {
- display: flex;
- align-items: center;
- padding: 12px;
+.media-wrapper {
+ position: relative;
+ width: 100%;
+ height: 100%;
+ border-radius: 8px;
+ overflow: hidden;
+ background: #f5f5f5;
- .attachment-info {
- flex: 1;
+ .media-preview {
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+ }
- .attachment-name {
- font-size: 16px;
- font-weight: 500;
- color: #333;
- margin-bottom: 4px;
- word-break: break-all;
- }
+ .file-icon-wrapper {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ width: 100%;
+ height: 100%;
+ padding: 8px;
+ text-align: center;
- .attachment-meta {
- display: flex;
- gap: 12px;
+ .file-name {
+ margin-top: 8px;
font-size: 12px;
- color: #999;
+ color: #666;
+ word-break: break-all;
+ display: -webkit-box;
+ -webkit-line-clamp: 2;
+ line-clamp: 2;
+ -webkit-box-orient: vertical;
+ overflow: hidden;
+
+ &.error-text {
+ color: #ff4757;
+ }
}
}
- .attachment-actions {
- margin-left: 12px;
-
- :deep(.wd-icon) {
- font-size: 20px;
- cursor: pointer;
- }
+ .delete-btn {
+ position: absolute;
+ top: 4px;
+ right: 4px;
+ width: 28px;
+ height: 28px;
+ border-radius: 50%;
+ background: rgba(0, 0, 0, 0.5);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ z-index: 10;
}
}
</style>
--
Gitblit v1.9.3