diff --git a/.env.htjc6 b/.env.htjc6 index fc2b732..c3ee4e4 100644 --- a/.env.htjc6 +++ b/.env.htjc6 @@ -7,3 +7,4 @@ VUE_APP_NVR_API = 'http://192.168.1.86:28081' VUE_APP_PUBLIC_PATH = '/app/htjc6/' VUE_APP_OUTPUT_DIR = 'dist/app/htjc6' +VUE_APP_IMAGE_PATH_PREFIX = '/app/htjc6/htjcImage' diff --git a/src/components/AsyncImage/index.vue b/src/components/AsyncImage/index.vue index 12ffb23..d28c8af 100644 --- a/src/components/AsyncImage/index.vue +++ b/src/components/AsyncImage/index.vue @@ -22,6 +22,7 @@ import { mapGetters } from "vuex"; import { getConfigByKeys } from "@/api/system/config"; import store from "@/store"; +import { buildImageUrl } from "@/utils/image-url"; export default { name: "AsyncImage", @@ -62,10 +63,8 @@ export default { }, methods: { async ftpImageViewUrl(url) { - if (url.startsWith("http://") || url.startsWith("https://")) { - return url; - } - if (!this.systemParams.ftpViewAddress) { + const ftpViewAddress = this.systemParams && this.systemParams.ftpViewAddress; + if (!ftpViewAddress) { const systemParams = {}; await getConfigByKeys([ "EXTRANET_ADDRESS", @@ -92,9 +91,9 @@ export default { systemParams.FLV_MEDIA_URL = systemParams[systemParams.PREFIX + "_FLV_MEDIA_URL"]; }); - return systemParams.ftpViewAddress + url; + return buildImageUrl(systemParams.ftpViewAddress, url); } else { - return this.systemParams.ftpViewAddress + url; + return buildImageUrl(ftpViewAddress, url); } }, async getUrls(val) { diff --git a/src/components/AsyncImageFrame/index.vue b/src/components/AsyncImageFrame/index.vue index 7a0e2b1..63a3d02 100644 --- a/src/components/AsyncImageFrame/index.vue +++ b/src/components/AsyncImageFrame/index.vue @@ -66,6 +66,7 @@ // import { ftpImageViewUrl } from "@/utils/index"; import { mapGetters } from "vuex"; import { getConfigByKeys } from "@/api/system/config"; +import { buildImageUrl } from "@/utils/image-url"; import Papa from "papaparse"; // 接口 import { @@ -537,10 +538,8 @@ export default { // ==================== FTP和URL处理 ==================== async ftpImageViewUrl(url) { - if (url.startsWith('http://') || url.startsWith('https://')) { - return url; - } - if (!this.systemParams.ftpViewAddress) { + const ftpViewAddress = this.systemParams && this.systemParams.ftpViewAddress; + if (!ftpViewAddress) { const systemParams = {}; await getConfigByKeys([ 'EXTRANET_ADDRESS', @@ -563,9 +562,9 @@ export default { systemParams.MEDIA_URL = systemParams[systemParams.PREFIX + '_MEDIA_URL']; systemParams.FLV_MEDIA_URL = systemParams[systemParams.PREFIX + '_FLV_MEDIA_URL']; }); - return systemParams.ftpViewAddress + url; + return buildImageUrl(systemParams.ftpViewAddress, url); } else { - return this.systemParams.ftpViewAddress + url; + return buildImageUrl(ftpViewAddress, url); } }, diff --git a/src/main.js b/src/main.js index e55ce90..e399a4d 100644 --- a/src/main.js +++ b/src/main.js @@ -33,6 +33,8 @@ import FileUpload from "@/components/FileUpload" import ImageUpload from "@/components/ImageUpload" // 图片预览组件 import ImagePreview from '@/components/ImagePreview' +// 异步图片组件 +import AsyncImage from '@/components/AsyncImage' // 寮傛鍥剧墖鐢绘缁勪欢 import AsyncImageFrame from '@/components/AsyncImageFrame' // 字典标签组件 @@ -68,6 +70,7 @@ Vue.component('Editor', Editor) Vue.component('FileUpload', FileUpload) Vue.component('ImageUpload', ImageUpload) Vue.component('ImagePreview', ImagePreview) +Vue.component('AsyncImage', AsyncImage) Vue.component('AsyncImageFrame', AsyncImageFrame) Vue.use(VideoPlayer) diff --git a/src/store/getters.js b/src/store/getters.js index 3115cb5..fa1f4ae 100644 --- a/src/store/getters.js +++ b/src/store/getters.js @@ -16,5 +16,6 @@ const getters = { defaultRoutes:state => state.permission.defaultRoutes, sidebarRouters:state => state.permission.sidebarRouters, language: state => state.app.language, + systemParams: state => state.app.systemParams, } export default getters diff --git a/src/store/modules/app.js b/src/store/modules/app.js index d80effa..dca2840 100644 --- a/src/store/modules/app.js +++ b/src/store/modules/app.js @@ -9,7 +9,8 @@ const state = { }, device: 'desktop', size: Cookies.get('size') || 'medium', - language: savedLanguage === 'en_US' ? 'en_US' : 'zh_CN' + language: savedLanguage === 'en_US' ? 'en_US' : 'zh_CN', + systemParams: {} } const mutations = { diff --git a/src/utils/image-url.js b/src/utils/image-url.js new file mode 100644 index 0000000..ab50a0b --- /dev/null +++ b/src/utils/image-url.js @@ -0,0 +1,68 @@ +const imagePathPrefix = process.env.VUE_APP_IMAGE_PATH_PREFIX || ""; + +function joinPath(left, right) { + return `${left.replace(/\/+$/, "")}/${right.replace(/^\/+/, "")}`; +} + +function pathContainsPrefix(value, prefix) { + if (!value || !prefix) { + return false; + } + + try { + const pathname = /^https?:\/\//i.test(value) + ? new URL(value).pathname + : value; + const normalizedPathname = pathname.replace(/\/+$/, ""); + return ( + normalizedPathname === prefix || + normalizedPathname.endsWith(prefix) + ); + } catch (error) { + return false; + } +} + +export function buildImageUrl(ftpViewAddress, imagePath) { + if (!imagePath) { + return ""; + } + + const path = String(imagePath).trim(); + if (/^(data:|blob:)/i.test(path)) { + return path; + } + + if (/^https?:\/\//i.test(path)) { + try { + const absoluteUrl = new URL(path); + const normalizedPrefix = imagePathPrefix.replace(/\/+$/, ""); + if ( + !imagePathPrefix || + absoluteUrl.pathname === normalizedPrefix || + absoluteUrl.pathname.startsWith(`${normalizedPrefix}/`) + ) { + return path; + } + absoluteUrl.pathname = joinPath(imagePathPrefix, absoluteUrl.pathname); + return absoluteUrl.href; + } catch (error) { + return path; + } + } + + const normalizedPrefix = imagePathPrefix.replace(/\/+$/, ""); + if (ftpViewAddress && pathContainsPrefix(ftpViewAddress, normalizedPrefix)) { + const relativePath = path.startsWith(normalizedPrefix) + ? path.slice(normalizedPrefix.length) + : path; + return joinPath(ftpViewAddress, relativePath); + } + + const prefixedPath = + normalizedPrefix && !path.startsWith(normalizedPrefix) + ? joinPath(normalizedPrefix, path) + : path; + + return ftpViewAddress ? joinPath(ftpViewAddress, prefixedPath) : prefixedPath; +} diff --git a/src/views/cards/taskSummary/newInspectionTaskDetail.vue b/src/views/cards/taskSummary/newInspectionTaskDetail.vue index 47dacb5..4703186 100644 --- a/src/views/cards/taskSummary/newInspectionTaskDetail.vue +++ b/src/views/cards/taskSummary/newInspectionTaskDetail.vue @@ -439,8 +439,8 @@ :close-on-click-modal="false" :close-on-press-escape="false" :destroy-on-close="true" - custom-class="card-dialog card-page" - width="70%" + custom-class="card-dialog card-page task-image-preview-dialog" + width="90%" append-to-body > @@ -1096,6 +1096,31 @@ export default {