Commit bcf448a55f4a5c6306e469a6d6e1cc0966446e6a

Authored by ww
1 parent 71709f42

fix(background): 修复生产环境与开发环境保存的静态资源路径不一致

... ... @@ -32,4 +32,7 @@ module.exports = {
32 32 'vue/valid-template-root': 'off',
33 33 'vue/no-mutating-props': 'off',
34 34 },
  35 + global: {
  36 + Recordable: 'readonly'
  37 + }
35 38 }
... ...
... ... @@ -7,11 +7,12 @@ export const useGlobSetting = (): Readonly<GlobConfig> => {
7 7 VITE_GLOB_API_URL,
8 8 VITE_GLOB_APP_SHORT_NAME,
9 9 VITE_GLOB_API_URL_PREFIX,
10   - VITE_GLOB_UPLOAD_URL,
  10 + VITE_GLOB_UPLOAD_URL,
11 11 VITE_GLOB_WEB_SOCKET,
12   - VITE_GLOB_CONTENT_SECURITY_POLICY,
  12 + VITE_GLOB_CONTENT_SECURITY_POLICY,
  13 + VITE_GLOB_PUBLIC_PATH
13 14 } = getAppEnvConfig();
14   -
  15 +
15 16 if (!/[a-zA-Z_]*/.test(VITE_GLOB_APP_SHORT_NAME)) {
16 17 console.warn(
17 18 `VITE_GLOB_APP_SHORT_NAME Variables can only be characters/underscores, please modify in the environment variables and re-running.`
... ... @@ -24,10 +25,11 @@ export const useGlobSetting = (): Readonly<GlobConfig> => {
24 25 apiUrl: VITE_GLOB_API_URL,
25 26 shortName: VITE_GLOB_APP_SHORT_NAME,
26 27 urlPrefix: VITE_GLOB_API_URL_PREFIX,
27   - uploadUrl: VITE_GLOB_UPLOAD_URL,
  28 + uploadUrl: VITE_GLOB_UPLOAD_URL,
28 29 socketUrl: VITE_GLOB_WEB_SOCKET,
29 30 securityPolicy: VITE_GLOB_CONTENT_SECURITY_POLICY,
  31 + publicPath: VITE_GLOB_PUBLIC_PATH
30 32 };
31   -
  33 +
32 34 return glob as Readonly<GlobConfig>;
33 35 };
... ...
... ... @@ -80,7 +80,7 @@ const selectBgOptions = ref<Array<SelectOption>>([])
80 80
81 81 const selectValue = ref('')
82 82
83   -//TODO待封装 成传文件夹名字获取下面所有图片
  83 +// TODO待封装 成传文件夹名字获取下面所有图片
84 84 const getFetchImages = () => {
85 85 const imagesModules = import.meta.globEager('@/assets/external/headbackground/*')
86 86 selectBgOptions.value = Object.keys(imagesModules).map(item => ({
... ...
... ... @@ -34,7 +34,8 @@ export function getAppEnvConfig() {
34 34 VITE_GLOB_UPLOAD_URL,
35 35 VITE_GLOB_WEB_SOCKET,
36 36 VITE_GLOB_ALARM_NOTIFY_DURATION,
37   - VITE_GLOB_CONTENT_SECURITY_POLICY
  37 + VITE_GLOB_CONTENT_SECURITY_POLICY,
  38 + VITE_GLOB_PUBLIC_PATH
38 39 } = ENV;
39 40
40 41 if (!/^[a-zA-Z\_]*$/.test(VITE_GLOB_APP_SHORT_NAME)) {
... ... @@ -51,7 +52,8 @@ export function getAppEnvConfig() {
51 52 VITE_GLOB_UPLOAD_URL,
52 53 VITE_GLOB_WEB_SOCKET,
53 54 VITE_GLOB_ALARM_NOTIFY_DURATION,
54   - VITE_GLOB_CONTENT_SECURITY_POLICY
  55 + VITE_GLOB_CONTENT_SECURITY_POLICY,
  56 + VITE_GLOB_PUBLIC_PATH
55 57 };
56 58 }
57 59
... ...
  1 +import { useGlobSetting } from "@/hooks/external/setting"
  2 +import { SelectOption } from "naive-ui"
  3 +import { ProjectRuntimeEnvEnum } from "../../../build/external/envEnum"
  4 +
  5 +export const useSyncAssetsFile = () => {
  6 + const { publicPath } = useGlobSetting()
  7 + const staticDir = 'static'
  8 + const isDev = [ProjectRuntimeEnvEnum.DEV, ProjectRuntimeEnvEnum.DEV_ALONE].includes(import.meta.env.MODE as ProjectRuntimeEnvEnum)
  9 + const jpgModules = import.meta.glob('../../assets/**/*.jpg')
  10 + const pngModules = import.meta.glob('../../assets/**/*.png')
  11 + const imagesModules = { ...jpgModules, ...pngModules }
  12 +
  13 + const getFileInfo = (filePath: string) => {
  14 + const filePathArr = filePath.split('/')
  15 + const fileName = filePathArr.at(-1)
  16 + const fileExt = fileName?.split('.').at(-1)
  17 + return { fileName, fileExt }
  18 + }
  19 +
  20 + const buildFilePath = (fileExt: string, fileName: string) => {
  21 + return `${publicPath}${staticDir}/${fileExt}/${fileName}`
  22 + }
  23 +
  24 + const setPath = (filePath: string) => {
  25 + if (isDev && filePath) {
  26 + const { fileExt, fileName } = getFileInfo(filePath)
  27 + return buildFilePath(fileExt!, fileName!)
  28 + }
  29 + return filePath
  30 + }
  31 +
  32 + const getPath = (filePath: string) => {
  33 + if (isDev && filePath) {
  34 + const { fileName } = getFileInfo(filePath)
  35 + const imagesKeys = Object.keys(imagesModules)
  36 + const path = imagesKeys.find(key => key.includes(fileName!))
  37 + return `/src/${path?.replaceAll('../', '')}`
  38 + }
  39 +
  40 + return filePath ?? ''
  41 + }
  42 +
  43 + const transformPath = (filesPath: string[]) => {
  44 + const _filesPath: SelectOption[] = []
  45 +
  46 + for (const file of filesPath) {
  47 + const { fileExt, fileName } = getFileInfo(file)
  48 + _filesPath.push({
  49 + label: fileName,
  50 + value: buildFilePath(fileExt!, fileName!)
  51 + })
  52 + }
  53 +
  54 + return _filesPath
  55 + }
  56 +
  57 + return { setPath, getPath, transformPath }
  58 +}
... ...
  1 +<script lang="ts" setup>
  2 +import { EditCanvasConfigEnum } from '@/store/modules/chartEditStore/chartEditStore.d';
  3 +import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore';
  4 +import { NEllipsis, NImage, NSelect, NSpace, NText, SelectOption } from 'naive-ui';
  5 +import { computed, h } from 'vue';
  6 +import { useSyncAssetsFile } from '@/utils/external/useSyncAssetsFile';
  7 +
  8 +const chartEditStore = useChartEditStore()
  9 +const canvasConfig = chartEditStore.getEditCanvasConfig
  10 +
  11 +const { transformPath, setPath, getPath } = useSyncAssetsFile()
  12 +const getSelectBgOptions = computed(() => {
  13 + const imagesModules = import.meta.globEager('@/assets/external/background/*')
  14 + return transformPath(Object.keys(imagesModules))
  15 +})
  16 +
  17 +const renderOption = (option: SelectOption) => {
  18 + return h(NSpace, { justify: 'space-between', style: 'padding: 0 15px; height: 28px; line-height: 28px;' }, () => [
  19 + h(NImage, { width: 50, src: getPath(option.value as string), previewDisabled: true, class: 'select-image' } as Recordable),
  20 + h(NEllipsis, null, () => option.label)
  21 + ])
  22 +}
  23 +
  24 +const handleUpdateValue = (value: string, _option: SelectOption) => {
  25 + chartEditStore.setEditCanvasConfig(EditCanvasConfigEnum.BACKGROUND_IMAGE, setPath(value))
  26 +}
  27 +
  28 +</script>
  29 +
  30 +
  31 +<template>
  32 + <NSpace>
  33 + <NText>背景选择</NText>
  34 + <NSelect size="small" placeholder="请选择您要使用的背景" style="width: 250px" :value="canvasConfig.backgroundImage"
  35 + :options="getSelectBgOptions" :render-label="renderOption" @update-value="handleUpdateValue" />
  36 + </NSpace>
  37 +</template>
  38 +
  39 +<style lang="scss" scoped>
  40 +</style>
... ...
... ... @@ -3,34 +3,21 @@
3 3 <n-form inline :label-width="45" size="small" label-placement="left">
4 4 <n-form-item label="宽度">
5 5 <!-- 尺寸选择 -->
6   - <n-input-number
7   - size="small"
8   - v-model:value="canvasConfig.width"
9   - :disabled="editCanvas.lockScale"
10   - :validator="validator"
11   - @update:value="changeSizeHandle"
12   - ></n-input-number>
  6 + <n-input-number size="small" v-model:value="canvasConfig.width" :disabled="editCanvas.lockScale"
  7 + :validator="validator" @update:value="changeSizeHandle"></n-input-number>
13 8 </n-form-item>
14 9 <n-form-item label="高度">
15   - <n-input-number
16   - size="small"
17   - v-model:value="canvasConfig.height"
18   - :disabled="editCanvas.lockScale"
19   - :validator="validator"
20   - @update:value="changeSizeHandle"
21   - ></n-input-number>
  10 + <n-input-number size="small" v-model:value="canvasConfig.height" :disabled="editCanvas.lockScale"
  11 + :validator="validator" @update:value="changeSizeHandle"></n-input-number>
22 12 </n-form-item>
23 13 </n-form>
24   -
25   - <div class="upload-box">
26   - <n-upload
27   - v-model:file-list="uploadFileListRef"
28   - :show-file-list="false"
29   - :customRequest="customRequest"
30   - :onBeforeUpload="beforeUploadHandle"
31   - >
  14 +
  15 + <n-card class="upload-box">
  16 + <n-upload v-model:file-list="uploadFileListRef" :show-file-list="false" :customRequest="customRequest"
  17 + :onBeforeUpload="beforeUploadHandle">
32 18 <n-upload-dragger>
33   - <img v-if="canvasConfig.backgroundImage" class="upload-show" :src="canvasConfig.backgroundImage" alt="背景" />
  19 + <!-- THINGS_KIT 路径转换,同步生产环境与开发环境的保存的静态资源文件路径不一致 -->
  20 + <img v-if="canvasConfig.backgroundImage" class="upload-show" :src="getPath(canvasConfig.backgroundImage)" alt="背景" />
34 21 <div class="upload-img" v-show="!canvasConfig.backgroundImage">
35 22 <img src="@/assets/images/canvas/noImage.png" />
36 23 <n-text class="upload-desc" depth="3">
... ... @@ -39,42 +26,22 @@
39 26 </div>
40 27 </n-upload-dragger>
41 28 </n-upload>
42   - </div>
  29 + </n-card>
43 30 <n-space vertical :size="12">
44 31 <n-space>
45   - <n-text>背景选择</n-text>
46   - <n-select
47   - size="small"
48   - placeholder="请选择您要使用的背景"
49   - style="width: 250px"
50   - v-model:value="bgSelectValue"
51   - :options="selectBgOptions"
52   - @update:value="selectBgValueHandle"
53   - />
54   - </n-space>
55   - <n-space>
  32 + <!-- THINGS_KIT 新增预置背景选择 -->
  33 + <SelectBackgroundImage />
56 34 <n-text>背景颜色</n-text>
57 35 <div class="picker-height">
58   - <n-color-picker
59   - v-if="!switchSelectColorLoading"
60   - size="small"
61   - style="width: 250px"
62   - v-model:value="canvasConfig.background"
63   - :showPreview="true"
64   - :swatches="swatchesColors"
65   - ></n-color-picker>
  36 + <n-color-picker v-if="!switchSelectColorLoading" size="small" style="width: 250px"
  37 + v-model:value="canvasConfig.background" :showPreview="true" :swatches="swatchesColors"></n-color-picker>
66 38 </div>
67 39 </n-space>
68 40 <n-space>
69 41 <n-text>应用类型</n-text>
70   - <n-select
71   - size="small"
72   - style="width: 250px"
73   - v-model:value="selectColorValue"
74   - :disabled="!canvasConfig.backgroundImage"
75   - :options="selectColorOptions"
76   - @update:value="selectColorValueHandle"
77   - />
  42 + <n-select size="small" style="width: 250px" v-model:value="selectColorValue"
  43 + :disabled="!canvasConfig.backgroundImage" :options="selectColorOptions"
  44 + @update:value="selectColorValueHandle" />
78 45 </n-space>
79 46 <n-space>
80 47 <n-text>背景控制</n-text>
... ... @@ -88,14 +55,9 @@
88 55 <n-space>
89 56 <n-text>适配方式</n-text>
90 57 <n-button-group>
91   - <n-button
92   - v-for="item in previewTypeList"
93   - :key="item.key"
94   - :type="canvasConfig.previewScaleType === item.key ? 'primary' : 'tertiary'"
95   - ghost
96   - size="small"
97   - @click="selectPreviewType(item.key)"
98   - >
  58 + <n-button v-for="item in previewTypeList" :key="item.key"
  59 + :type="canvasConfig.previewScaleType === item.key ? 'primary' : 'tertiary'" ghost size="small"
  60 + @click="selectPreviewType(item.key)">
99 61 <n-tooltip :show-arrow="false" trigger="hover">
100 62 <template #trigger>
101 63 <n-icon class="select-preview-icon" size="18">
... ... @@ -115,13 +77,8 @@
115 77
116 78 <!-- 主题选择和全局配置 -->
117 79 <n-tabs class="tabs-box" size="small" type="segment">
118   - <n-tab-pane
119   - v-for="item in globalTabList"
120   - :key="item.key"
121   - :name="item.key"
122   - size="small"
123   - display-directive="show:lazy"
124   - >
  80 + <n-tab-pane v-for="item in globalTabList" :key="item.key" :name="item.key" size="small"
  81 + display-directive="show:lazy">
125 82 <template #tab>
126 83 <n-space>
127 84 <span>{{ item.title }}</span>
... ... @@ -139,16 +96,21 @@
139 96 <script setup lang="ts">
140 97 import { ref, nextTick, watch } from 'vue'
141 98 import { backgroundImageSize } from '@/settings/designSetting'
142   -import { swatchesColors } from '@/settings/chartThemes/index'
  99 +import { swatchesColors } from '@/settings/chartThemes'
143 100 import { FileTypeEnum } from '@/enums/fileTypeEnum'
144 101 import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
145 102 import { EditCanvasConfigEnum } from '@/store/modules/chartEditStore/chartEditStore.d'
146 103 import { StylesSetting } from '@/components/Pages/ChartItemSetting'
147   -import { SelectOption, UploadCustomRequestOptions } from 'naive-ui'
  104 +import { UploadCustomRequestOptions } from 'naive-ui'
148 105 import { fileToUrl, loadAsyncComponent } from '@/utils'
149 106 import { PreviewScaleEnum } from '@/enums/styleEnum'
150 107 import { icon } from '@/plugins'
151 108
  109 +// THINGS_KIT 路径转换,同步生产环境与开发环境的保存的静态资源文件路径不一致
  110 +import SelectBackgroundImage from './external/SelectBackgroundImage.vue'
  111 +import { useSyncAssetsFile } from '@/utils/external/useSyncAssetsFile'
  112 +const { getPath } = useSyncAssetsFile()
  113 +
152 114 const { ColorPaletteIcon } = icon.ionicons5
153 115 const { ScaleIcon, FitToScreenIcon, FitToHeightIcon, FitToWidthIcon } = icon.carbon
154 116
... ... @@ -162,21 +124,6 @@ const selectColorValue = ref(0)
162 124
163 125 const ChartThemeColor = loadAsyncComponent(() => import('./components/ChartThemeColor/index.vue'))
164 126
165   -//背景选择配置项
166   -const bgSelectValue = ref('')
167   -
168   -const selectBgOptions = ref<Array<SelectOption>>([])
169   -
170   -//TODO待封装 成传文件夹名字获取下面所有图片
171   -const getFetchImages = () => {
172   - const imagesModules = import.meta.globEager('@/assets/external/background/*')
173   - selectBgOptions.value = Object.keys(imagesModules).map(item => ({
174   - label: imagesModules[item]?.default.split('/').at(-1),
175   - value: imagesModules[item]?.default
176   - }))
177   -}
178   -getFetchImages()
179   -
180 127 // 默认应用类型
181 128 const selectColorOptions = [
182 129 {
... ... @@ -266,12 +213,6 @@ const selectColorValueHandle = (value: number) => {
266 213 canvasConfig.selectColor = value == 0
267 214 }
268 215
269   -//选择背景
270   -const selectBgValueHandle = (value: string) => {
271   - bgSelectValue.value = value
272   - canvasConfig.backgroundImage = value
273   -}
274   -
275 216 // 清除背景
276 217 const clearImage = () => {
277 218 chartEditStore.setEditCanvasConfig(EditCanvasConfigEnum.BACKGROUND_IMAGE, undefined)
... ... @@ -318,49 +259,65 @@ const selectPreviewType = (key: PreviewScaleEnum) => {
318 259 <style lang="scss" scoped>
319 260 $uploadWidth: 326px;
320 261 $uploadHeight: 193px;
  262 +
321 263 @include go(canvas-setting) {
322 264 padding-top: 20px;
  265 +
323 266 .upload-box {
324 267 cursor: pointer;
325 268 margin-bottom: 20px;
  269 +
326 270 @include deep() {
  271 + .n-card__content {
  272 + padding: 0;
  273 + overflow: hidden;
  274 + }
  275 +
327 276 .n-upload-dragger {
328 277 padding: 5px;
329 278 width: $uploadWidth;
330   - background-color: rgba(0, 0, 0, 0);
331 279 }
332 280 }
  281 +
333 282 .upload-show {
334 283 width: -webkit-fill-available;
335 284 height: $uploadHeight;
336 285 border-radius: 5px;
337 286 }
  287 +
338 288 .upload-img {
339 289 display: flex;
340 290 flex-direction: column;
341 291 align-items: center;
  292 +
342 293 img {
343 294 height: 150px;
344 295 }
  296 +
345 297 .upload-desc {
346 298 padding: 10px 0;
347 299 }
348 300 }
349 301 }
  302 +
350 303 .icon-position {
351 304 padding-top: 2px;
352 305 }
  306 +
353 307 .picker-height {
354 308 min-height: 35px;
355 309 }
  310 +
356 311 .clear-btn {
357 312 padding-left: 2.25em;
358 313 padding-right: 2.25em;
359 314 }
  315 +
360 316 .select-preview-icon {
361   - padding-right: 0.68em;
362   - padding-left: 0.68em;
  317 + padding-right: .68em;
  318 + padding-left: .68em;
363 319 }
  320 +
364 321 .tabs-box {
365 322 margin-top: 20px;
366 323 }
... ...
1 1 import { toRaw } from 'vue'
2 2 import { DragKeyEnum, MouseEventButton } from '@/enums/editPageEnum'
3   -import { createComponent } from '@/packages'
  3 +// THINGS_KIT 覆盖原始创建组件方法
  4 +import { createComponent } from '@/packages/external/override'
4 5 import { ConfigType } from '@/packages/index.d'
5 6 import { CreateComponentType, CreateComponentGroupType, PickCreateComponentType } from '@/packages/index.d'
6 7 import { useContextMenu } from '@/views/chart/hooks/useContextMenu.hook'
... ...
... ... @@ -76,6 +76,7 @@ import { EditRule } from './components/EditRule'
76 76 import { EditBottom } from './components/EditBottom'
77 77 import { EditShapeBox } from './components/EditShapeBox'
78 78 import { EditTools } from './components/EditTools'
  79 +import { useSyncAssetsFile } from '@/utils/external/useSyncAssetsFile'
79 80
80 81 const chartEditStore = useChartEditStore()
81 82 const { handleContextMenu } = useContextMenu()
... ... @@ -130,17 +131,19 @@ const filterShow = computed(() => {
130 131 })
131 132
132 133 // 背景
  134 +// THINGS_KIT 路径转换,同步生产环境与开发环境的保存的静态资源文件路径不一致
  135 +const { getPath } = useSyncAssetsFile()
133 136 const rangeStyle = computed(() => {
134 137 // 设置背景色和图片背景
135 138 const background = chartEditStore.getEditCanvasConfig.background
136 139 const backgroundImage = chartEditStore.getEditCanvasConfig.backgroundImage
137 140 const selectColor = chartEditStore.getEditCanvasConfig.selectColor
138 141 const backgroundColor = background ? background : undefined
139   -
140 142 const computedBackground = selectColor
141 143 ? { background: backgroundColor }
142   - : { background: `url(${backgroundImage}) no-repeat center center / cover !important` }
143   -
  144 + // : { background: `url(${backgroundImage}) no-repeat center center / cover !important` }
  145 + // THINGS_KIT 路径转换,同步生产环境与开发环境的保存的静态资源文件路径不一致
  146 + : { background: `url(${getPath(backgroundImage!)}) no-repeat center center / cover !important` }
144 147 // @ts-ignore
145 148 return {
146 149 ...computedBackground,
... ...
... ... @@ -113,7 +113,8 @@ export const useSyncRemote = () => {
113 113 const canvasImage: HTMLCanvasElement = await html2canvas(range, {
114 114 backgroundColor: null,
115 115 allowTaint: true,
116   - useCORS: true
  116 + useCORS: true,
  117 + logging: false
117 118 })
118 119
119 120 // 上传预览图
... ...
... ... @@ -150,6 +150,8 @@ export interface GlobConfig {
150 150 socketUrl: string;
151 151 // upgrade your http policy to https
152 152 securityPolicy: string;
  153 + // assets file prefix
  154 + publicPath: string
153 155 }
154 156 export interface GlobEnvConfig {
155 157 // Site title
... ... @@ -168,4 +170,6 @@ export interface GlobEnvConfig {
168 170 VITE_GLOB_ALARM_NOTIFY_DURATION: string;
169 171 // content security policy
170 172 VITE_GLOB_CONTENT_SECURITY_POLICY: string
  173 + // public assets file prefix
  174 + VITE_GLOB_PUBLIC_PATH: string
171 175 }
... ...