Browse Source

修改部署到服务器图片不显示问题,图片预览不显示问题

master
douyage 1 month ago
parent
commit
3d1fd05359
8 changed files with 112 additions and 15 deletions
  1. +1
    -0
      .env.htjc6
  2. +5
    -6
      src/components/AsyncImage/index.vue
  3. +5
    -6
      src/components/AsyncImageFrame/index.vue
  4. +3
    -0
      src/main.js
  5. +1
    -0
      src/store/getters.js
  6. +2
    -1
      src/store/modules/app.js
  7. +68
    -0
      src/utils/image-url.js
  8. +27
    -2
      src/views/cards/taskSummary/newInspectionTaskDetail.vue

+ 1
- 0
.env.htjc6 View File

@ -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'

+ 5
- 6
src/components/AsyncImage/index.vue View File

@ -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) {


+ 5
- 6
src/components/AsyncImageFrame/index.vue View File

@ -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 {
// ==================== FTPURL ====================
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);
}
},


+ 3
- 0
src/main.js View File

@ -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)


+ 1
- 0
src/store/getters.js View File

@ -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

+ 2
- 1
src/store/modules/app.js View File

@ -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 = {


+ 68
- 0
src/utils/image-url.js View File

@ -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;
}

+ 27
- 2
src/views/cards/taskSummary/newInspectionTaskDetail.vue View File

@ -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
>
<!-- 根据 isInfrared 判断使用哪个预览组件 -->
@ -1096,6 +1096,31 @@ export default {
<!-- 全局样式用于 el-autocomplete 下拉菜单 -->
<style lang="scss">
.task-image-preview-dialog {
height: 90vh;
margin-top: 5vh !important;
display: flex;
flex-direction: column;
overflow: hidden;
.el-dialog__header {
flex: 0 0 63px;
}
.el-dialog__body {
flex: 1 1 auto;
min-height: 0;
height: auto;
padding: 12px;
overflow: hidden;
> .card-page {
width: 100%;
height: 100%;
}
}
}
.custom-autocomplete-popper {
background-color: #222f3e !important;
border: 1px solid #34495e !important;


Loading…
Cancel
Save