Commit 5d1d375220e022245a0ef2cb3884fdf6ecc826e7
1 parent
0a506eab
Merge branch 'ft' into 'main_dev'
perf(components/GoUserInfo): 覆盖external下的GoUserInfo等 See merge request yunteng/thingskit-view!32 (cherry picked from commit 89ffc88f) f58186a6 perf(external/Componse): 新增组合下的小标题2 801c381e perf(external/Componse): 重写信息下的图片 bffac482 perf(external/Componse): 重写信息下的图片 52854df6 perf(external/Componse): 新增组合下的小标题3 d337d91a feat(src/assets): 新增了图片,这里升级版本有冲突WARNING 43bc7e14 perf(external/Componse): 修改了图片名字 29886bb4 perf(views/ContentHeader/headerRightBtn): 新增了external扩展目录,这里升级版本有冲突WARNING c989940b perf(views/ContentHeader/headerLeftBtn): 新增了external扩展目录,这里升级版本有冲突WARNING 2b852e4a perf(views/ContentHeader/headerLeftBtn): 新增了external扩展目录,这里升级版本有冲突WARNING e990e729 perf(components/GoUserInfo): 覆盖external下的GoUserInfo
Showing
35 changed files
with
1134 additions
and
10 deletions
src/assets/images/chart/charts/camera.png
0 → 100644
43.8 KB
src/assets/images/chart/charts/title1.png
0 → 100644
43.8 KB
src/assets/images/chart/charts/title2.png
0 → 100644
43.8 KB
src/assets/images/chart/charts/title3.png
0 → 100644
43.8 KB
src/assets/images/chart/decorates/clock1.png
0 → 100644
43.8 KB
4.02 KB
src/components/external/GoUserInfo/index.ts
0 → 100644
src/components/external/GoUserInfo/index.vue
0 → 100644
1 | +<template> | ||
2 | + <n-dropdown trigger="hover" @select="handleSelect" :show-arrow="true" :options="options"> | ||
3 | + <div class="user-info-box"> | ||
4 | + <person-icon v-if="fallback"></person-icon> | ||
5 | + <n-avatar v-if="!fallback" round object-fit="cover" size="medium" :src="Person" @error="errorHandle"></n-avatar> | ||
6 | + </div> | ||
7 | + </n-dropdown> | ||
8 | + | ||
9 | + <!-- 系统设置 model --> | ||
10 | + <go-system-set v-model:modelShow="modelShow"></go-system-set> | ||
11 | + <!-- 关于软件 model --> | ||
12 | + <go-system-info v-model:modelShow="modelShowInfo"></go-system-info> | ||
13 | +</template> | ||
14 | + | ||
15 | +<script lang="ts" setup> | ||
16 | +import { h, ref, computed } from 'vue' | ||
17 | +import { NAvatar, NText } from 'naive-ui' | ||
18 | +import { renderIcon } from '@/utils' | ||
19 | +import { logout, renderLang } from '@/utils' | ||
20 | +import { GoSystemSet } from '@/components/GoSystemSet/index' | ||
21 | +import { GoSystemInfo } from '@/components/GoSystemInfo/index' | ||
22 | +import Person from './person.png' | ||
23 | +import { icon } from '@/plugins' | ||
24 | +import { useUserStore } from '@/store/external/modules/user' | ||
25 | +import { useSyncRemote } from '@/views/chart/hooks/external/useRemote.hook' | ||
26 | +const { ChatboxEllipsesIcon, PersonIcon, LogOutOutlineIcon, SettingsSharpIcon } = icon.ionicons5 | ||
27 | + | ||
28 | +const t = window['$t'] | ||
29 | + | ||
30 | +const { dataSyncUpdate } = useSyncRemote() | ||
31 | + | ||
32 | +const modelShowInfo = ref(false) | ||
33 | +const modelShow = ref(false) | ||
34 | + | ||
35 | +// 是否失败 | ||
36 | +const fallback = ref(false) | ||
37 | + | ||
38 | +// 用户图标渲染 | ||
39 | +const renderUserInfo = () => { | ||
40 | + const userStoreOverride = useUserStore() | ||
41 | + const { username, avatar } = userStoreOverride.getUserInfo | ||
42 | + console.log(userStoreOverride.getUserInfo) | ||
43 | + return h( | ||
44 | + 'div', | ||
45 | + { | ||
46 | + style: 'display: flex; align-items: center; padding: 8px 12px;' | ||
47 | + }, | ||
48 | + [ | ||
49 | + h(NAvatar, { | ||
50 | + round: true, | ||
51 | + style: 'margin-right: 12px;', | ||
52 | + src: Person | ||
53 | + }), | ||
54 | + h('div', null, [ | ||
55 | + h('div', null, [ | ||
56 | + h('div', null, [ | ||
57 | + h('div', null, [h(NText, { depth: 2 }, { default: () => (!username ? 'ThingsKit' : username) })]) | ||
58 | + ]) | ||
59 | + ]) | ||
60 | + ]) | ||
61 | + ] | ||
62 | + ) | ||
63 | +} | ||
64 | +const options = ref([ | ||
65 | + { | ||
66 | + label: '我的信息', | ||
67 | + key: 'info', | ||
68 | + type: 'render', | ||
69 | + render: renderUserInfo | ||
70 | + }, | ||
71 | + { | ||
72 | + type: 'divider', | ||
73 | + key: 'd1' | ||
74 | + }, | ||
75 | + { | ||
76 | + label: renderLang('global.sys_set'), | ||
77 | + key: 'sysSet', | ||
78 | + icon: renderIcon(SettingsSharpIcon) | ||
79 | + }, | ||
80 | + // THINGS_KIT 隐藏关于软件 | ||
81 | + // { | ||
82 | + // label: renderLang('global.contact'), | ||
83 | + // key: 'contact', | ||
84 | + // icon: renderIcon(ChatboxEllipsesIcon) | ||
85 | + // }, | ||
86 | + { | ||
87 | + type: 'divider', | ||
88 | + key: 'd3' | ||
89 | + }, | ||
90 | + { | ||
91 | + label: '关闭并退出', | ||
92 | + key: 'closePage', | ||
93 | + icon: renderIcon(LogOutOutlineIcon) | ||
94 | + } | ||
95 | + // { | ||
96 | + // label: renderLang('global.logout'), | ||
97 | + // key: 'logout', | ||
98 | + // icon: renderIcon(LogOutOutlineIcon) | ||
99 | + // } | ||
100 | +]) | ||
101 | + | ||
102 | +// 图片渲染错误 | ||
103 | +const errorHandle = (e: Event) => { | ||
104 | + fallback.value = true | ||
105 | +} | ||
106 | + | ||
107 | +// 系统设置 | ||
108 | +const sysSetHandle = () => { | ||
109 | + modelShow.value = true | ||
110 | +} | ||
111 | + | ||
112 | +// 系统设置 | ||
113 | +const sysInfoHandle = () => { | ||
114 | + modelShowInfo.value = true | ||
115 | +} | ||
116 | + | ||
117 | +// THINGS_KIT 修改退出登录 | ||
118 | +const userStore = useUserStore() | ||
119 | +const handleSelect = (key: string) => { | ||
120 | + switch (key) { | ||
121 | + case 'contact': | ||
122 | + sysInfoHandle() | ||
123 | + break | ||
124 | + case 'sysSet': | ||
125 | + sysSetHandle() | ||
126 | + break | ||
127 | + case 'closePage': | ||
128 | + handleClosePage() | ||
129 | + break | ||
130 | + case 'logout': | ||
131 | + // THINGS_KIT 修改退出登录 | ||
132 | + userStore.logout(true) | ||
133 | + // logout() | ||
134 | + break | ||
135 | + } | ||
136 | +} | ||
137 | + | ||
138 | +const handleClosePage = () => { | ||
139 | + //先保存当前页面数据 | ||
140 | + dataSyncUpdate() | ||
141 | + //兼容Firefox Chrome | ||
142 | + var userAgent = navigator.userAgent | ||
143 | + if (userAgent.indexOf('Firefox') != -1 || userAgent.indexOf('Chrome') != -1) { | ||
144 | + window.location.href = 'about:blank' | ||
145 | + window.close() | ||
146 | + } else { | ||
147 | + window.opener = null | ||
148 | + window.open('', '_self') | ||
149 | + window.close() | ||
150 | + } | ||
151 | +} | ||
152 | +</script> | ||
153 | + | ||
154 | +<style lang="scss" scoped> | ||
155 | +.user-info-box { | ||
156 | + cursor: pointer; | ||
157 | + transform: scale(0.7); | ||
158 | +} | ||
159 | +</style> |
9.54 KB
@@ -17,5 +17,10 @@ | @@ -17,5 +17,10 @@ | ||
17 | </template> | 17 | </template> |
18 | <script setup lang="ts"> | 18 | <script setup lang="ts"> |
19 | import { LayoutHeader } from '@/layout/components/LayoutHeader' | 19 | import { LayoutHeader } from '@/layout/components/LayoutHeader' |
20 | -import { GoUserInfo } from '@/components/GoUserInfo' | 20 | +/** |
21 | + * THINGS_KIT 升级版本这里有冲突 | ||
22 | + * 源文件 '@/components/GoUserInfo' | ||
23 | + * 修改后 '@/components/external/GoUserInfo' | ||
24 | + */ | ||
25 | +import { GoUserInfo } from '@/components/external/GoUserInfo' | ||
21 | </script> | 26 | </script> |
@@ -15,5 +15,5 @@ export const LeftCenterRightHeadAnimatConfig: ConfigType = { | @@ -15,5 +15,5 @@ export const LeftCenterRightHeadAnimatConfig: ConfigType = { | ||
15 | categoryName: ChatCategoryEnumName.HEADCOMBINATION, | 15 | categoryName: ChatCategoryEnumName.HEADCOMBINATION, |
16 | package: EPackagesCategoryEnum.COMPOSES, | 16 | package: EPackagesCategoryEnum.COMPOSES, |
17 | chartFrame: ChartFrameEnum.COMMON, | 17 | chartFrame: ChartFrameEnum.COMMON, |
18 | - image: 'decorates02.png', | 18 | + image: 'decorates07.png', |
19 | } | 19 | } |
@@ -13,5 +13,5 @@ export const CameraConfig: ConfigType = { | @@ -13,5 +13,5 @@ export const CameraConfig: ConfigType = { | ||
13 | categoryName: ChatCategoryEnumName.MORE, | 13 | categoryName: ChatCategoryEnumName.MORE, |
14 | package: EPackagesCategoryEnum.COMPOSES, | 14 | package: EPackagesCategoryEnum.COMPOSES, |
15 | chartFrame: ChartFrameEnum.NAIVE_UI, | 15 | chartFrame: ChartFrameEnum.NAIVE_UI, |
16 | - image: 'dateTime.png' | 16 | + image: 'camera.png' |
17 | } | 17 | } |
@@ -13,5 +13,5 @@ export const Title1Config: ConfigType = { | @@ -13,5 +13,5 @@ export const Title1Config: ConfigType = { | ||
13 | categoryName: ChatCategoryEnumName.MORE, | 13 | categoryName: ChatCategoryEnumName.MORE, |
14 | package: EPackagesCategoryEnum.COMPOSES, | 14 | package: EPackagesCategoryEnum.COMPOSES, |
15 | chartFrame: ChartFrameEnum.NAIVE_UI, | 15 | chartFrame: ChartFrameEnum.NAIVE_UI, |
16 | - image: 'dateTime.png' | 16 | + image: 'title1.png' |
17 | } | 17 | } |
1 | +import { PublicConfigClass } from '@/packages/public' | ||
2 | +import { CreateComponentType } from '@/packages/index.d' | ||
3 | +import { Title2Config } from './index' | ||
4 | +import cloneDeep from 'lodash/cloneDeep' | ||
5 | + | ||
6 | +export const option = { | ||
7 | + dataset: '我是标题', | ||
8 | + attribute: { | ||
9 | + linearColors: ['#21649C', '#060F1E', '#2AFFFF', '#000000', '#ffcc33', '#ffcc33'], | ||
10 | + fontSize: 20, | ||
11 | + fontPos: { | ||
12 | + x: 0, | ||
13 | + y: 20 | ||
14 | + }, | ||
15 | + fontColor: '#2AFFFF' | ||
16 | + } | ||
17 | +} | ||
18 | + | ||
19 | +export default class Config extends PublicConfigClass implements CreateComponentType { | ||
20 | + public key = Title2Config.key | ||
21 | + public chartConfig = cloneDeep(Title2Config) | ||
22 | + public option = cloneDeep(option) | ||
23 | +} |
1 | +<template> | ||
2 | + <CollapseItem name="配置" :expanded="true"> | ||
3 | + <SettingItemBox name="标题"> | ||
4 | + <SettingItem name="内容"> | ||
5 | + <n-input v-model:value="optionData.dataset" /> | ||
6 | + </SettingItem> | ||
7 | + <SettingItem name="大小"> | ||
8 | + <n-input-number v-model:value="optionData.attribute.fontSize" /> | ||
9 | + </SettingItem> | ||
10 | + <SettingItem name="颜色"> | ||
11 | + <n-color-picker size="small" :modes="['hex']" v-model:value="optionData.attribute.fontColor"></n-color-picker> | ||
12 | + </SettingItem> | ||
13 | + <SettingItem name="x轴位置"> | ||
14 | + <n-input-number v-model:value="optionData.attribute.fontPos.x" /> | ||
15 | + </SettingItem> | ||
16 | + <SettingItem name="y轴位置"> | ||
17 | + <n-input-number v-model:value="optionData.attribute.fontPos.y" /> | ||
18 | + </SettingItem> | ||
19 | + </SettingItemBox> | ||
20 | + <SettingItemBox | ||
21 | + :name="`装饰颜色-${index + 1}`" | ||
22 | + v-for="(item, index) in optionData.attribute.linearColors" | ||
23 | + :key="index" | ||
24 | + > | ||
25 | + <SettingItem name="颜色"> | ||
26 | + <n-color-picker | ||
27 | + size="small" | ||
28 | + :modes="['hex']" | ||
29 | + v-model:value="optionData.attribute.linearColors[index]" | ||
30 | + ></n-color-picker> | ||
31 | + </SettingItem> | ||
32 | + <SettingItem> | ||
33 | + <n-button | ||
34 | + size="small" | ||
35 | + @click="optionData.attribute.linearColors[index] = option.attribute.linearColors[index]" | ||
36 | + > | ||
37 | + 恢复默认 | ||
38 | + </n-button> | ||
39 | + </SettingItem> | ||
40 | + </SettingItemBox> | ||
41 | + </CollapseItem> | ||
42 | +</template> | ||
43 | + | ||
44 | +<script setup lang="ts"> | ||
45 | +import { PropType } from 'vue' | ||
46 | +import { option } from './config' | ||
47 | +import { CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting' | ||
48 | + | ||
49 | + | ||
50 | +defineProps({ | ||
51 | + optionData: { | ||
52 | + type: Object as PropType<typeof option>, | ||
53 | + required: true | ||
54 | + } | ||
55 | +}) | ||
56 | +</script> |
1 | +import { ChartFrameEnum, ConfigType } from '@/packages/index.d' | ||
2 | +import { EPackagesCategoryEnum } from '@/packages/components/external/types' | ||
3 | +import { ChatCategoryEnum, ChatCategoryEnumName } from '../../index.d' | ||
4 | +import { useWidgetKey } from '@/packages/external/useWidgetKey' | ||
5 | + | ||
6 | +const { key, chartKey, conKey } = useWidgetKey('Title2') | ||
7 | +export const Title2Config: ConfigType = { | ||
8 | + key, | ||
9 | + chartKey, | ||
10 | + conKey, | ||
11 | + title: '小标题2', | ||
12 | + category: ChatCategoryEnum.MORE, | ||
13 | + categoryName: ChatCategoryEnumName.MORE, | ||
14 | + package: EPackagesCategoryEnum.COMPOSES, | ||
15 | + chartFrame: ChartFrameEnum.NAIVE_UI, | ||
16 | + image: 'title2.png' | ||
17 | +} |
1 | +<template> | ||
2 | + <div class="go-content-box"> | ||
3 | + <svg :width="w" :height="h" fill="none"> | ||
4 | + <defs xmlns="http://www.w3.org/2000/svg"> | ||
5 | + <linearGradient id="linear_title2_u" x1="0%" y1="50%" x2="100%" y2="50%" gradientUnits="objectBoundingBox"> | ||
6 | + <stop offset="0" :stop-color="attribute.linearColors[0]" stop-opacity="1" /> | ||
7 | + <stop offset="1" :stop-color="attribute.linearColors[1]" stop-opacity="1" /> | ||
8 | + </linearGradient> | ||
9 | + <linearGradient id="linear_title2_d" x1="0%" y1="50%" x2="100%" y2="50%" gradientUnits="objectBoundingBox"> | ||
10 | + <stop offset="0" :stop-color="attribute.linearColors[3]" stop-opacity="1" /> | ||
11 | + <stop offset="1" :stop-color="attribute.linearColors[4]" stop-opacity="0" /> | ||
12 | + </linearGradient> | ||
13 | + </defs> | ||
14 | + <g opacity="1" transform="translate(0 0) rotate(0 160 15)"> | ||
15 | + <path | ||
16 | + id="矩形 title2_u" | ||
17 | + fill-rule="evenodd" | ||
18 | + fill="url(#linear_title2_u)" | ||
19 | + transform="translate(0 0) rotate(0 160 15)" | ||
20 | + opacity="1" | ||
21 | + :d="`M2.77,${h} L${w},${h} L${w},0 L${ | ||
22 | + w - 11.44 | ||
23 | + },0 C10.58,0 9.81,0.55 9.54,1.37 L0.88,27.37 C0.68,27.98 0.78,28.65 1.15,29.17 C1.53,29.69 2.13,30 2.77,30 Z `" | ||
24 | + /> | ||
25 | + <path | ||
26 | + id="矩形 title2_u" | ||
27 | + style="stroke: url(#linear_title2_d); stroke-width: 1; stroke-opacity: 100; stroke-dasharray: 0 0" | ||
28 | + transform="translate(0 0) rotate(0 160 15)" | ||
29 | + :d="`M2.77,${h} L${w},${h} L${w},0 L11.44,0 C10.58,0 9.81,0.55 9.54,1.37 L0.88,27.37 C0.68,27.98 0.78,28.65 1.15,29.17 C1.53,29.69 2.13,30 2.77,30 Z `" | ||
30 | + /> | ||
31 | + <g opacity="1" :transform="`translate(24 ${h / 2 - 26 / 2}) rotate(0 46 13)`"> | ||
32 | + <text> | ||
33 | + <tspan | ||
34 | + :x="attribute.fontPos.x" | ||
35 | + :y="attribute.fontPos.y" | ||
36 | + :font-size="attribute.fontSize" | ||
37 | + line-height="0" | ||
38 | + :fill="attribute.fontColor" | ||
39 | + opacity="1" | ||
40 | + font-family="YouSheBiaoTiHei" | ||
41 | + letter-spacing="0" | ||
42 | + > | ||
43 | + {{ dataset }} | ||
44 | + </tspan> | ||
45 | + </text> | ||
46 | + </g> | ||
47 | + <path | ||
48 | + id="矩形 title2_d" | ||
49 | + fill-rule="evenodd" | ||
50 | + :style="{ fill: attribute.linearColors[4] }" | ||
51 | + :transform="`translate(9 ${h / 2 - 15 / 2}) rotate(0 3.5 7.5)`" | ||
52 | + opacity="1" | ||
53 | + d="M0,15L2,15L7,0L5,0L0,15Z " | ||
54 | + /> | ||
55 | + <path | ||
56 | + id="矩形 title2_d" | ||
57 | + fill-rule="evenodd" | ||
58 | + :style="{ fill: attribute.linearColors[5] }" | ||
59 | + :transform="`translate(15 ${h / 2 - 15 / 2}) rotate(0 3.5 7.5)`" | ||
60 | + opacity="1" | ||
61 | + d="M0,15L2,15L7,0L5,0L0,15Z " | ||
62 | + /> | ||
63 | + </g> | ||
64 | + </svg> | ||
65 | + </div> | ||
66 | +</template> | ||
67 | +<script setup lang="ts"> | ||
68 | +import { PropType, toRefs } from 'vue' | ||
69 | +import { CreateComponentType } from '@/packages/index.d' | ||
70 | + | ||
71 | +const props = defineProps({ | ||
72 | + chartConfig: { | ||
73 | + type: Object as PropType<CreateComponentType>, | ||
74 | + required: true | ||
75 | + } | ||
76 | +}) | ||
77 | + | ||
78 | +const { dataset, attribute } = toRefs(props.chartConfig.option) | ||
79 | + | ||
80 | +const { w, h } = toRefs(props.chartConfig.attr) | ||
81 | +</script> | ||
82 | + | ||
83 | +<style lang="scss" scoped> | ||
84 | +.go-content-box { | ||
85 | + width: v-bind('w+"px"'); | ||
86 | + height: v-bind('h+"px"'); | ||
87 | + display: flex; | ||
88 | + align-items: center; | ||
89 | + justify-content: center; | ||
90 | +} | ||
91 | +</style> |
1 | +import { PublicConfigClass } from '@/packages/public' | ||
2 | +import { CreateComponentType } from '@/packages/index.d' | ||
3 | +import { Title3Config } from './index' | ||
4 | +import cloneDeep from 'lodash/cloneDeep' | ||
5 | + | ||
6 | +export const option = { | ||
7 | + dataset: '我是标题', | ||
8 | + attribute: { | ||
9 | + linearColors: [ | ||
10 | + '#21649C', | ||
11 | + '#060F1E', | ||
12 | + '#2AFFFF', | ||
13 | + '#2AFFFF', | ||
14 | + '#2AFFFF', | ||
15 | + '#2AFFFF', | ||
16 | + '#2affff', | ||
17 | + '#16d9d9', | ||
18 | + '#2affff', | ||
19 | + '#2affff', | ||
20 | + '#2affff', | ||
21 | + '#2affff' | ||
22 | + ], | ||
23 | + fontSize: 20, | ||
24 | + fontPos: { | ||
25 | + x: 0, | ||
26 | + y: 20 | ||
27 | + }, | ||
28 | + fontColor: '#2AFFFF' | ||
29 | + } | ||
30 | +} | ||
31 | + | ||
32 | +export default class Config extends PublicConfigClass implements CreateComponentType { | ||
33 | + public key = Title3Config.key | ||
34 | + public chartConfig = cloneDeep(Title3Config) | ||
35 | + public option = cloneDeep(option) | ||
36 | +} |
1 | +<template> | ||
2 | + <CollapseItem name="配置" :expanded="true"> | ||
3 | + <SettingItemBox name="标题"> | ||
4 | + <SettingItem name="内容"> | ||
5 | + <n-input v-model:value="optionData.dataset" /> | ||
6 | + </SettingItem> | ||
7 | + <SettingItem name="大小"> | ||
8 | + <n-input-number v-model:value="optionData.attribute.fontSize" /> | ||
9 | + </SettingItem> | ||
10 | + <SettingItem name="颜色"> | ||
11 | + <n-color-picker size="small" :modes="['hex']" v-model:value="optionData.attribute.fontColor"></n-color-picker> | ||
12 | + </SettingItem> | ||
13 | + <SettingItem name="x轴位置"> | ||
14 | + <n-input-number v-model:value="optionData.attribute.fontPos.x" /> | ||
15 | + </SettingItem> | ||
16 | + <SettingItem name="y轴位置"> | ||
17 | + <n-input-number v-model:value="optionData.attribute.fontPos.y" /> | ||
18 | + </SettingItem> | ||
19 | + </SettingItemBox> | ||
20 | + <SettingItemBox | ||
21 | + :name="`装饰颜色-${index + 1}`" | ||
22 | + v-for="(item, index) in optionData.attribute.linearColors" | ||
23 | + :key="index" | ||
24 | + > | ||
25 | + <SettingItem name="颜色"> | ||
26 | + <n-color-picker | ||
27 | + size="small" | ||
28 | + :modes="['hex']" | ||
29 | + v-model:value="optionData.attribute.linearColors[index]" | ||
30 | + ></n-color-picker> | ||
31 | + </SettingItem> | ||
32 | + <SettingItem> | ||
33 | + <n-button | ||
34 | + size="small" | ||
35 | + @click="optionData.attribute.linearColors[index] = option.attribute.linearColors[index]" | ||
36 | + > | ||
37 | + 恢复默认 | ||
38 | + </n-button> | ||
39 | + </SettingItem> | ||
40 | + </SettingItemBox> | ||
41 | + </CollapseItem> | ||
42 | +</template> | ||
43 | + | ||
44 | +<script setup lang="ts"> | ||
45 | +import { PropType } from 'vue' | ||
46 | +import { option } from './config' | ||
47 | +import { CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting' | ||
48 | + | ||
49 | + | ||
50 | +defineProps({ | ||
51 | + optionData: { | ||
52 | + type: Object as PropType<typeof option>, | ||
53 | + required: true | ||
54 | + } | ||
55 | +}) | ||
56 | +</script> |
1 | +import { ChartFrameEnum, ConfigType } from '@/packages/index.d' | ||
2 | +import { EPackagesCategoryEnum } from '@/packages/components/external/types' | ||
3 | +import { ChatCategoryEnum, ChatCategoryEnumName } from '../../index.d' | ||
4 | +import { useWidgetKey } from '@/packages/external/useWidgetKey' | ||
5 | + | ||
6 | +const { key, chartKey, conKey } = useWidgetKey('Title3') | ||
7 | +export const Title3Config: ConfigType = { | ||
8 | + key, | ||
9 | + chartKey, | ||
10 | + conKey, | ||
11 | + title: '小标题3', | ||
12 | + category: ChatCategoryEnum.MORE, | ||
13 | + categoryName: ChatCategoryEnumName.MORE, | ||
14 | + package: EPackagesCategoryEnum.COMPOSES, | ||
15 | + chartFrame: ChartFrameEnum.NAIVE_UI, | ||
16 | + image: 'title3.png' | ||
17 | +} |
1 | +<template> | ||
2 | + <div class="go-content-box"> | ||
3 | + <svg :width="w" :height="h" fill="none"> | ||
4 | + <defs> | ||
5 | + <linearGradient id="linear_0" x1="0%" y1="50%" x2="100%" y2="50%" gradientUnits="objectBoundingBox"> | ||
6 | + <stop offset="0" :stop-color="attribute.linearColors[0]" stop-opacity="1" /> | ||
7 | + <stop offset="1" :stop-color="attribute.linearColors[1]" stop-opacity="1" /> | ||
8 | + </linearGradient> | ||
9 | + <linearGradient id="linear_1" x1="0%" y1="50%" x2="100%" y2="50%" gradientUnits="objectBoundingBox"> | ||
10 | + <stop offset="0" :stop-color="attribute.linearColors[2]" stop-opacity="1" /> | ||
11 | + <stop offset="1" :stop-color="attribute.linearColors[3]" stop-opacity="0" /> | ||
12 | + </linearGradient> | ||
13 | + <linearGradient id="linear_2" x1="0%" y1="50%" x2="100%" y2="50%" gradientUnits="objectBoundingBox"> | ||
14 | + <stop offset="0" :stop-color="attribute.linearColors[4]" stop-opacity="1" /> | ||
15 | + <stop offset="1" :stop-color="attribute.linearColors[5]" stop-opacity="0" /> | ||
16 | + </linearGradient> | ||
17 | + </defs> | ||
18 | + <g opacity="1" transform="translate(-6.249999273677531e-8 0.5) rotate(0 160.00000003125 15.000000000000005)"> | ||
19 | + <path | ||
20 | + id="矩形 16" | ||
21 | + fill-rule="evenodd" | ||
22 | + fill="url(#linear_0)" | ||
23 | + transform="translate(6.249999895402425e-8 2) rotate(0 160 13)" | ||
24 | + opacity="1" | ||
25 | + :d="`M0,${h - 5} L${w},${h - 5} L${w},0 L0,0 L0,${h - 5} Z`" | ||
26 | + /> | ||
27 | + <g opacity="1" :transform="`translate(34.0000000625 ${h / 2 - 26 / 2}) rotate(0 46 13)`"> | ||
28 | + <text> | ||
29 | + <tspan | ||
30 | + :x="attribute.fontPos.x" | ||
31 | + :y="attribute.fontPos.y" | ||
32 | + :font-size="attribute.fontSize" | ||
33 | + line-height="0" | ||
34 | + :fill="attribute.fontColor" | ||
35 | + opacity="1" | ||
36 | + font-family="YouSheBiaoTiHei" | ||
37 | + letter-spacing="0" | ||
38 | + > | ||
39 | + {{ dataset }} | ||
40 | + </tspan> | ||
41 | + </text> | ||
42 | + </g> | ||
43 | + <path | ||
44 | + id="路径 5" | ||
45 | + style="stroke: url(#linear_1); stroke-width: 1; stroke-opacity: 100; stroke-dasharray: 0 0" | ||
46 | + transform="translate(6.249999895402425e-8 30) rotate(0 160 0)" | ||
47 | + d="M0,0L320,0 " | ||
48 | + /> | ||
49 | + <path | ||
50 | + id="路径 5" | ||
51 | + style="stroke: url(#linear_2); stroke-width: 1; stroke-opacity: 100; stroke-dasharray: 0 0" | ||
52 | + transform="translate(6.249999895402425e-8 0) rotate(0 160 0)" | ||
53 | + d="M0,0L320,0 " | ||
54 | + /> | ||
55 | + <path | ||
56 | + id="路径 5" | ||
57 | + :style="{ stroke: attribute.linearColors[10], strokeWidth: 1, strokeOpacity: 1, strokeDasharray: 0 }" | ||
58 | + transform="translate(0 0.0005) rotate(0 2.000000062499999 0)" | ||
59 | + d="M0,0L4,0 " | ||
60 | + /> | ||
61 | + <path | ||
62 | + id="路径 5" | ||
63 | + :style="{ stroke: attribute.linearColors[11], strokeWidth: 1, strokeOpacity: 1, strokeDasharray: 0 }" | ||
64 | + :transform="`translate(0 ${h - 1}) rotate(0 2.000000062499999 0)`" | ||
65 | + d="M0,0 L4,0 " | ||
66 | + /> | ||
67 | + <g opacity="1" :transform="`translate(10.0000000625 ${h / 2 - 18 / 2}) rotate(0 8.598076211353316 9)`"> | ||
68 | + <path | ||
69 | + id="三角形 1" | ||
70 | + fill-rule="evenodd" | ||
71 | + :style="{ fill: attribute.linearColors[6] }" | ||
72 | + transform="translate(4 0) rotate(0 6.598076211353316 4.5)" | ||
73 | + opacity="1" | ||
74 | + d="M2.8,9L13.2,9L0,0L2.8,9Z " | ||
75 | + /> | ||
76 | + <path | ||
77 | + id="三角形 1" | ||
78 | + fill-rule="evenodd" | ||
79 | + :style="{ fill: attribute.linearColors[7] }" | ||
80 | + transform="translate(4 9) rotate(0 6.598076211353316 4.5)" | ||
81 | + opacity="1" | ||
82 | + d="M13.2,0L2.8,0L0,9L13.2,0Z " | ||
83 | + /> | ||
84 | + <path | ||
85 | + id="圆形 7" | ||
86 | + fill-rule="evenodd" | ||
87 | + :style="{ fill: attribute.linearColors[8] }" | ||
88 | + transform="translate(0 7) rotate(0 2 2)" | ||
89 | + opacity="1" | ||
90 | + d="M2,0C0.9,0 0,0.9 0,2C0,3.1 0.9,4 2,4C3.1,4 4,3.1 4,2C4,0.9 3.1,0 2,0Z " | ||
91 | + /> | ||
92 | + </g> | ||
93 | + <path | ||
94 | + id="矩形 17" | ||
95 | + fill-rule="evenodd" | ||
96 | + :style="{ fill: attribute.linearColors[9] }" | ||
97 | + transform="translate(6.249999895402425e-8 2) rotate(0 0.5 13)" | ||
98 | + opacity="1" | ||
99 | + :d="`M0,${h - 5}L1,${h - 5}L1,0L0,0L0,${h - 5}Z`" | ||
100 | + /> | ||
101 | + </g> | ||
102 | + </svg> | ||
103 | + </div> | ||
104 | +</template> | ||
105 | +<script setup lang="ts"> | ||
106 | +import { PropType, toRefs } from 'vue' | ||
107 | +import { CreateComponentType } from '@/packages/index.d' | ||
108 | + | ||
109 | +const props = defineProps({ | ||
110 | + chartConfig: { | ||
111 | + type: Object as PropType<CreateComponentType>, | ||
112 | + required: true | ||
113 | + } | ||
114 | +}) | ||
115 | + | ||
116 | +const { dataset, attribute } = toRefs(props.chartConfig.option) | ||
117 | + | ||
118 | +const { w, h } = toRefs(props.chartConfig.attr) | ||
119 | +</script> | ||
120 | + | ||
121 | +<style lang="scss" scoped> | ||
122 | +.go-content-box { | ||
123 | + width: v-bind('w+"px"'); | ||
124 | + height: v-bind('h+"px"'); | ||
125 | + display: flex; | ||
126 | + align-items: center; | ||
127 | + justify-content: center; | ||
128 | +} | ||
129 | +</style> |
1 | -import { ButtonConfig } from './Button/index' | ||
2 | import { Title1Config } from './Title1/index' | 1 | import { Title1Config } from './Title1/index' |
2 | +import { Title2Config } from './Title2/index' | ||
3 | +import { Title3Config } from './Title3/index' | ||
4 | +import { ButtonConfig } from './Button/index' | ||
3 | import { CameraConfig } from './Camera/index' | 5 | import { CameraConfig } from './Camera/index' |
4 | 6 | ||
5 | -export default [ButtonConfig, Title1Config, CameraConfig] | 7 | +export default [Title1Config, Title2Config, Title3Config, CameraConfig, ButtonConfig] |
@@ -13,5 +13,5 @@ export const ClockConfig: ConfigType = { | @@ -13,5 +13,5 @@ export const ClockConfig: ConfigType = { | ||
13 | categoryName: ChatCategoryEnumName.MORE, | 13 | categoryName: ChatCategoryEnumName.MORE, |
14 | package: PackagesCategoryEnum.DECORATES, | 14 | package: PackagesCategoryEnum.DECORATES, |
15 | chartFrame: ChartFrameEnum.STATIC, | 15 | chartFrame: ChartFrameEnum.STATIC, |
16 | - image: 'clock.png' | 16 | + image: 'clock1.png' |
17 | } | 17 | } |
1 | +import { PublicConfigClass } from '@/packages/public' | ||
2 | +import { CreateComponentType } from '@/packages/index.d' | ||
3 | +import { OverrideImageConfig } from './index' | ||
4 | +import cloneDeep from 'lodash/cloneDeep' | ||
5 | + | ||
6 | +export const option = { | ||
7 | + // 图片路径 | ||
8 | + dataset: '', | ||
9 | + // 适应方式 | ||
10 | + fit: 'fill', | ||
11 | + // 圆角 | ||
12 | + borderRadius: 10 | ||
13 | +} | ||
14 | + | ||
15 | +export default class Config extends PublicConfigClass implements CreateComponentType { | ||
16 | + public key = OverrideImageConfig.key | ||
17 | + public chartConfig = cloneDeep(OverrideImageConfig) | ||
18 | + public option = cloneDeep(option) | ||
19 | +} |
1 | +<template> | ||
2 | + <collapse-item name="属性" :expanded="true"> | ||
3 | + <setting-item-box name="上传图片" :alone="true"> | ||
4 | + <setting-item> | ||
5 | + <n-card class="upload-box"> | ||
6 | + <n-upload | ||
7 | + :show-file-list="false" | ||
8 | + v-model:file-list="uploadFileListRef" | ||
9 | + :customRequest="customRequest" | ||
10 | + :onBeforeUpload="beforeUploadHandle" | ||
11 | + > | ||
12 | + <n-upload-dragger> | ||
13 | + <img v-if="optionData.dataset" class="upload-show" :src="optionData.dataset" alt="背景" /> | ||
14 | + <div class="upload-img" v-show="!optionData.dataset"> | ||
15 | + <img src="@/assets/images/canvas/noImage.png" /> | ||
16 | + <n-text class="upload-desc" depth="3"> | ||
17 | + 图片需小于 {{ backgroundImageSize }}M ,格式为 png/jpg/gif 的文件 | ||
18 | + </n-text> | ||
19 | + </div> | ||
20 | + </n-upload-dragger> | ||
21 | + </n-upload> | ||
22 | + </n-card> | ||
23 | + </setting-item> | ||
24 | + </setting-item-box> | ||
25 | + <setting-item-box name="样式"> | ||
26 | + <setting-item name="类型"> | ||
27 | + <n-select v-model:value="optionData.fit" size="small" :options="fitList"></n-select> | ||
28 | + </setting-item> | ||
29 | + <setting-item name="圆角"> | ||
30 | + <n-input-number | ||
31 | + v-model:value="optionData.borderRadius" | ||
32 | + size="small" | ||
33 | + :min="0" | ||
34 | + placeholder="圆角" | ||
35 | + ></n-input-number> | ||
36 | + </setting-item> | ||
37 | + </setting-item-box> | ||
38 | + </collapse-item> | ||
39 | +</template> | ||
40 | + | ||
41 | +<script setup lang="ts"> | ||
42 | +import { PropType, ref, nextTick } from 'vue' | ||
43 | +import { option } from './config' | ||
44 | +import { CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting' | ||
45 | +import { FileTypeEnum } from '@/enums/fileTypeEnum' | ||
46 | +import { uploadFile } from '@/api/external/contentSave/content' | ||
47 | +import { UploadCustomRequestOptions } from 'naive-ui' | ||
48 | +import { backgroundImageSize } from '@/settings/designSetting' | ||
49 | +import { fetchRouteParamsLocation } from '@/utils' | ||
50 | + | ||
51 | +const props = defineProps({ | ||
52 | + optionData: { | ||
53 | + type: Object as PropType<typeof option>, | ||
54 | + required: true | ||
55 | + } | ||
56 | +}) | ||
57 | + | ||
58 | +const uploadFileListRef = ref() | ||
59 | + | ||
60 | +// 上传图片前置处理 | ||
61 | +//@ts-ignore | ||
62 | +const beforeUploadHandle = async ({ file }) => { | ||
63 | + uploadFileListRef.value = [] | ||
64 | + const type = file.file.type | ||
65 | + const size = file.file.size | ||
66 | + | ||
67 | + if (size > 1024 * 1024 * backgroundImageSize) { | ||
68 | + window['$message'].warning(`图片超出 ${backgroundImageSize}M 限制,请重新上传!`) | ||
69 | + return false | ||
70 | + } | ||
71 | + if (type !== FileTypeEnum.PNG && type !== FileTypeEnum.JPEG && type !== FileTypeEnum.GIF) { | ||
72 | + window['$message'].warning('文件格式不符合,请重新上传!') | ||
73 | + return false | ||
74 | + } | ||
75 | + return true | ||
76 | +} | ||
77 | + | ||
78 | +// 自定义上传操作 | ||
79 | +const customRequest = (options: UploadCustomRequestOptions) => { | ||
80 | + const { file } = options | ||
81 | + nextTick(async () => { | ||
82 | + if (file.file) { | ||
83 | + // 修改名称 | ||
84 | + const newNameFile = new File([file.file], `${fetchRouteParamsLocation()}_index_background.png`, { | ||
85 | + type: file.file.type | ||
86 | + }) | ||
87 | + let uploadParams = new FormData() | ||
88 | + uploadParams.append('file', newNameFile) | ||
89 | + const uploadRes = await uploadFile(uploadParams) | ||
90 | + if (uploadRes) { | ||
91 | + props.optionData.dataset = uploadRes?.fileStaticUri | ||
92 | + window['$message'].success('添加图片成功!') | ||
93 | + } | ||
94 | + } else { | ||
95 | + window['$message'].error('添加图片失败,请稍后重试!') | ||
96 | + } | ||
97 | + }) | ||
98 | +} | ||
99 | + | ||
100 | +// 适应类型 | ||
101 | +const fitList = [ | ||
102 | + { | ||
103 | + value: 'fill', | ||
104 | + label: 'fill' | ||
105 | + }, | ||
106 | + { | ||
107 | + value: 'contain', | ||
108 | + label: 'contain' | ||
109 | + }, | ||
110 | + { | ||
111 | + value: 'cover', | ||
112 | + label: 'cover' | ||
113 | + }, | ||
114 | + { | ||
115 | + value: 'scale-down', | ||
116 | + label: 'scale-down' | ||
117 | + }, | ||
118 | + { | ||
119 | + value: 'none', | ||
120 | + label: 'none' | ||
121 | + } | ||
122 | +] | ||
123 | +</script> | ||
124 | +<style lang="scss" scoped> | ||
125 | +$uploadHeight: 193px; | ||
126 | +.upload-box { | ||
127 | + cursor: pointer; | ||
128 | + margin-bottom: 20px; | ||
129 | + @include deep() { | ||
130 | + .n-card__content { | ||
131 | + padding: 0; | ||
132 | + overflow: hidden; | ||
133 | + } | ||
134 | + .n-upload-dragger { | ||
135 | + padding: 5px; | ||
136 | + } | ||
137 | + } | ||
138 | + .upload-show { | ||
139 | + width: -webkit-fill-available; | ||
140 | + height: $uploadHeight; | ||
141 | + border-radius: 5px; | ||
142 | + } | ||
143 | + .upload-img { | ||
144 | + display: flex; | ||
145 | + flex-direction: column; | ||
146 | + align-items: center; | ||
147 | + img { | ||
148 | + height: 150px; | ||
149 | + } | ||
150 | + .upload-desc { | ||
151 | + padding: 10px 0; | ||
152 | + } | ||
153 | + } | ||
154 | +} | ||
155 | +</style> |
1 | +import { ConfigType, PackagesCategoryEnum, ChartFrameEnum } from '@/packages/index.d' | ||
2 | +import { ChatCategoryEnum, ChatCategoryEnumName } from '@/packages/components/Informations/index.d' | ||
3 | +import { useWidgetKey } from '@/packages/external/useWidgetKey' | ||
4 | + | ||
5 | +const { key, conKey, chartKey } = useWidgetKey('OverrideImage', true) | ||
6 | + | ||
7 | +export const OverrideImageConfig: ConfigType = { | ||
8 | + key, | ||
9 | + chartKey, | ||
10 | + conKey, | ||
11 | + title: '自定义图片', | ||
12 | + category: ChatCategoryEnum.MORE, | ||
13 | + categoryName: ChatCategoryEnumName.MORE, | ||
14 | + package: PackagesCategoryEnum.INFORMATIONS, | ||
15 | + chartFrame: ChartFrameEnum.COMMON, | ||
16 | + image: 'photo.png' | ||
17 | +} |
1 | +<template> | ||
2 | + <div :style="getStyle(borderRadius)"> | ||
3 | + <n-image | ||
4 | + :object-fit="fit" | ||
5 | + preview-disabled | ||
6 | + :src="!option.dataset ? logo : option.dataset" | ||
7 | + :fallback-src="requireErrorImg()" | ||
8 | + :width="w" | ||
9 | + :height="h" | ||
10 | + ></n-image> | ||
11 | + </div> | ||
12 | +</template> | ||
13 | + | ||
14 | +<script setup lang="ts"> | ||
15 | +import { PropType, shallowReactive, watch, toRefs } from 'vue' | ||
16 | +import { requireErrorImg } from '@/utils' | ||
17 | +import { useChartDataFetch } from '@/hooks' | ||
18 | +import { CreateComponentType } from '@/packages/index.d' | ||
19 | +import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore' | ||
20 | +import logo from '@/assets/logo.png' | ||
21 | + | ||
22 | +const props = defineProps({ | ||
23 | + chartConfig: { | ||
24 | + type: Object as PropType<CreateComponentType>, | ||
25 | + required: true | ||
26 | + } | ||
27 | +}) | ||
28 | + | ||
29 | +const { w, h } = toRefs(props.chartConfig.attr) | ||
30 | +const { dataset, fit, borderRadius } = toRefs(props.chartConfig.option) | ||
31 | + | ||
32 | +const option = shallowReactive({ | ||
33 | + dataset: '' | ||
34 | +}) | ||
35 | + | ||
36 | +const getStyle = (radius: number) => { | ||
37 | + return { | ||
38 | + borderRadius: `${radius}px`, | ||
39 | + overflow: 'hidden' | ||
40 | + } | ||
41 | +} | ||
42 | + | ||
43 | +// 编辑更新 | ||
44 | +watch( | ||
45 | + () => props.chartConfig.option.dataset, | ||
46 | + (newData: any) => { | ||
47 | + option.dataset = newData | ||
48 | + }, | ||
49 | + { | ||
50 | + immediate: true | ||
51 | + } | ||
52 | +) | ||
53 | + | ||
54 | +// 预览更新 | ||
55 | +useChartDataFetch(props.chartConfig, useChartEditStore, (newData: any) => { | ||
56 | + option.dataset = newData | ||
57 | +}) | ||
58 | +</script> |
@@ -2,12 +2,14 @@ import { EPackagesCategoryEnum, EPackagesType } from '@/packages/components/exte | @@ -2,12 +2,14 @@ import { EPackagesCategoryEnum, EPackagesType } from '@/packages/components/exte | ||
2 | import { ComposesList } from '@/packages/components/external/Composes' | 2 | import { ComposesList } from '@/packages/components/external/Composes' |
3 | import { ConfigType, PackagesCategoryEnum } from '@/packages/index.d' | 3 | import { ConfigType, PackagesCategoryEnum } from '@/packages/index.d' |
4 | import { ClockConfig } from '@/packages/components/external/Decorates/Mores/Icon' | 4 | import { ClockConfig } from '@/packages/components/external/Decorates/Mores/Icon' |
5 | +import { OverrideImageConfig } from '@/packages/components/external/Informations/Mores/OverrideImage' | ||
5 | 6 | ||
6 | export function useInjectLib(packagesList: EPackagesType) { | 7 | export function useInjectLib(packagesList: EPackagesType) { |
7 | 8 | ||
8 | packagesList[EPackagesCategoryEnum.COMPOSES] = ComposesList | 9 | packagesList[EPackagesCategoryEnum.COMPOSES] = ComposesList |
9 | 10 | ||
10 | addWidgetToCategoryByCategoryName(packagesList, PackagesCategoryEnum.DECORATES, ClockConfig) | 11 | addWidgetToCategoryByCategoryName(packagesList, PackagesCategoryEnum.DECORATES, ClockConfig) |
12 | + addWidgetToCategoryByCategoryName(packagesList, PackagesCategoryEnum.INFORMATIONS, OverrideImageConfig) | ||
11 | } | 13 | } |
12 | 14 | ||
13 | /** | 15 | /** |
1 | +<template> | ||
2 | + <n-space class="header-left-btn" :size="25"> | ||
3 | + <n-button disabled size="small" quaternary @click="goHomeHandle()"> | ||
4 | + <template #icon> | ||
5 | + <n-icon :depth="3"> | ||
6 | + <home-icon></home-icon> | ||
7 | + </n-icon> | ||
8 | + </template> | ||
9 | + </n-button> | ||
10 | + <n-space> | ||
11 | + <!-- 模块展示按钮 --> | ||
12 | + <n-tooltip v-for="item in btnList" :key="item.key" placement="bottom" trigger="hover"> | ||
13 | + <template #trigger> | ||
14 | + <n-button size="small" ghost :type="styleHandle(item)" @click="clickHandle(item)"> | ||
15 | + <component :is="item.icon"></component> | ||
16 | + </n-button> | ||
17 | + </template> | ||
18 | + <span>{{ item.title }}</span> | ||
19 | + </n-tooltip> | ||
20 | + | ||
21 | + <n-divider vertical /> | ||
22 | + | ||
23 | + <!-- 历史记录按钮 --> | ||
24 | + <n-tooltip v-for="item in historyList" :key="item.key" placement="bottom" trigger="hover"> | ||
25 | + <template #trigger> | ||
26 | + <n-button size="small" ghost type="primary" :disabled="!item.select" @click="clickHistoryHandle(item)"> | ||
27 | + <component :is="item.icon"></component> | ||
28 | + </n-button> | ||
29 | + </template> | ||
30 | + <span>{{ item.title }}</span> | ||
31 | + </n-tooltip> | ||
32 | + <n-divider vertical /> | ||
33 | + <!-- 保存 --> | ||
34 | + <n-tooltip placement="bottom" trigger="hover"> | ||
35 | + <template #trigger> | ||
36 | + <div class="save-btn"> | ||
37 | + <n-button size="small" type="primary" ghost @click="dataSyncUpdate()"> | ||
38 | + <template #icon> | ||
39 | + <n-icon> | ||
40 | + <Save /> | ||
41 | + </n-icon> | ||
42 | + </template> | ||
43 | + </n-button> | ||
44 | + </div> | ||
45 | + </template> | ||
46 | + <span>保存</span> | ||
47 | + </n-tooltip> | ||
48 | + </n-space> | ||
49 | + </n-space> | ||
50 | +</template> | ||
51 | + | ||
52 | +<script setup lang="ts"> | ||
53 | +import { toRefs, Ref, reactive, computed } from 'vue' | ||
54 | +import { renderIcon, goDialog, goHome } from '@/utils' | ||
55 | +import { icon } from '@/plugins' | ||
56 | +import { Save } from '@vicons/carbon' | ||
57 | +import { useRemoveKeyboard } from '../../../hooks/useKeyboard.hook' | ||
58 | + | ||
59 | +import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore' | ||
60 | + | ||
61 | +import { useChartHistoryStore } from '@/store/modules/chartHistoryStore/chartHistoryStore' | ||
62 | +import { HistoryStackEnum } from '@/store/modules/chartHistoryStore/chartHistoryStore.d' | ||
63 | +// THINGS_KIT 修改同步逻辑 | ||
64 | +import { useSyncRemote } from '../../../hooks/external/useRemote.hook' | ||
65 | +import { useChartLayoutStore } from '@/store/modules/chartLayoutStore/chartLayoutStore' | ||
66 | +import { ChartLayoutStoreEnum } from '@/store/modules/chartLayoutStore/chartLayoutStore.d' | ||
67 | + | ||
68 | +const { LayersIcon, BarChartIcon, PrismIcon, HomeIcon, ArrowBackIcon, ArrowForwardIcon } = icon.ionicons5 | ||
69 | +const { setItem } = useChartLayoutStore() | ||
70 | +const { getLayers, getCharts, getDetails } = toRefs(useChartLayoutStore()) | ||
71 | +const chartEditStore = useChartEditStore() | ||
72 | +const chartHistoryStore = useChartHistoryStore() | ||
73 | +const { dataSyncUpdate } = useSyncRemote() | ||
74 | + | ||
75 | +interface ItemType<T> { | ||
76 | + key: T | ||
77 | + select: Ref<boolean> | boolean | ||
78 | + title: string | ||
79 | + icon: any | ||
80 | +} | ||
81 | + | ||
82 | +const btnList = reactive<ItemType<ChartLayoutStoreEnum>[]>([ | ||
83 | + { | ||
84 | + key: ChartLayoutStoreEnum.CHARTS, | ||
85 | + select: getCharts, | ||
86 | + title: '图表组件', | ||
87 | + icon: renderIcon(BarChartIcon) | ||
88 | + }, | ||
89 | + { | ||
90 | + key: ChartLayoutStoreEnum.LAYERS, | ||
91 | + select: getLayers, | ||
92 | + title: '图层控制', | ||
93 | + icon: renderIcon(LayersIcon) | ||
94 | + }, | ||
95 | + { | ||
96 | + key: ChartLayoutStoreEnum.DETAILS, | ||
97 | + select: getDetails, | ||
98 | + title: '详情设置', | ||
99 | + icon: renderIcon(PrismIcon) | ||
100 | + } | ||
101 | +]) | ||
102 | + | ||
103 | +const isBackStack = computed(() => chartHistoryStore.getBackStack.length > 1) | ||
104 | + | ||
105 | +const isForwardStack = computed(() => chartHistoryStore.getForwardStack.length > 0) | ||
106 | + | ||
107 | +const historyList = reactive<ItemType<HistoryStackEnum>[]>([ | ||
108 | + { | ||
109 | + key: HistoryStackEnum.BACK_STACK, | ||
110 | + // 一定会有初始化画布 | ||
111 | + select: isBackStack, | ||
112 | + title: '后退', | ||
113 | + icon: renderIcon(ArrowBackIcon) | ||
114 | + }, | ||
115 | + { | ||
116 | + key: HistoryStackEnum.FORWARD_STACK, | ||
117 | + select: isForwardStack, | ||
118 | + title: '前进', | ||
119 | + icon: renderIcon(ArrowForwardIcon) | ||
120 | + } | ||
121 | +]) | ||
122 | + | ||
123 | + | ||
124 | +// store 描述的是展示的值,所以和 ContentConfigurations 的 collapsed 是相反的 | ||
125 | +const styleHandle = (item: ItemType<ChartLayoutStoreEnum>) => { | ||
126 | + if (item.key === ChartLayoutStoreEnum.DETAILS) { | ||
127 | + return item.select ? '' : 'primary' | ||
128 | + } | ||
129 | + return item.select ? 'primary' : '' | ||
130 | +} | ||
131 | + | ||
132 | +// 布局处理 | ||
133 | +const clickHandle = (item: ItemType<ChartLayoutStoreEnum>) => { | ||
134 | + setItem(item.key, !item.select) | ||
135 | +} | ||
136 | + | ||
137 | +// 历史记录处理 | ||
138 | +const clickHistoryHandle = (item: ItemType<HistoryStackEnum>) => { | ||
139 | + switch (item.key) { | ||
140 | + case HistoryStackEnum.BACK_STACK: | ||
141 | + chartEditStore.setBack() | ||
142 | + break; | ||
143 | + case HistoryStackEnum.FORWARD_STACK: | ||
144 | + chartEditStore.setForward() | ||
145 | + break; | ||
146 | + } | ||
147 | +} | ||
148 | + | ||
149 | +// 返回首页 | ||
150 | +const goHomeHandle = () => { | ||
151 | + goDialog({ | ||
152 | + message: '返回将不会保存任何操作', | ||
153 | + isMaskClosable: true, | ||
154 | + onPositiveCallback: () => { | ||
155 | + goHome() | ||
156 | + useRemoveKeyboard() | ||
157 | + } | ||
158 | + }) | ||
159 | +} | ||
160 | +</script> | ||
161 | +<style lang="scss" scoped> | ||
162 | +.header-left-btn { | ||
163 | + margin-left: -37px; | ||
164 | +} | ||
165 | +</style> |
1 | +<template> | ||
2 | + <n-space class="go-mt-0"> | ||
3 | + <n-button v-for="item in comBtnList" :key="item.title" :type="item.type" ghost @click="item.event"> | ||
4 | + <template #icon> | ||
5 | + <component :is="item.icon"></component> | ||
6 | + </template> | ||
7 | + <span>{{ item.title }}</span> | ||
8 | + </n-button> | ||
9 | + </n-space> | ||
10 | +</template> | ||
11 | + | ||
12 | +<script setup lang="ts"> | ||
13 | +import { computed } from 'vue' | ||
14 | +import { renderIcon, goDialog, fetchPathByName, routerTurnByPath, setSessionStorage, getLocalStorage } from '@/utils' | ||
15 | +import { PreviewEnum } from '@/enums/pageEnum' | ||
16 | +import { StorageEnum } from '@/enums/storageEnum' | ||
17 | +import { useRoute } from 'vue-router' | ||
18 | +import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore' | ||
19 | +import { syncData } from '../../../ContentEdit/components/EditTools/hooks/useSyncUpdate.hook' | ||
20 | +import { icon } from '@/plugins' | ||
21 | +import { cloneDeep } from 'lodash' | ||
22 | + | ||
23 | +const { BrowsersOutlineIcon, SendIcon, AnalyticsIcon } = icon.ionicons5 | ||
24 | +const chartEditStore = useChartEditStore() | ||
25 | + | ||
26 | +const routerParamsInfo = useRoute() | ||
27 | + | ||
28 | +// 预览 | ||
29 | +const previewHandle = () => { | ||
30 | + const path = fetchPathByName(PreviewEnum.CHART_PREVIEW_NAME, 'href') | ||
31 | + if (!path) return | ||
32 | + const { id } = routerParamsInfo.params | ||
33 | + // id 标识 | ||
34 | + const previewId = typeof id === 'string' ? id : id[0] | ||
35 | + const storageInfo = chartEditStore.getStorageInfo | ||
36 | + const sessionStorageInfo = getLocalStorage(StorageEnum.GO_CHART_STORAGE_LIST) || [] | ||
37 | + | ||
38 | + if (sessionStorageInfo?.length) { | ||
39 | + const repeateIndex = sessionStorageInfo.findIndex((e: { id: string }) => e.id === previewId) | ||
40 | + // 重复替换 | ||
41 | + if (repeateIndex !== -1) { | ||
42 | + sessionStorageInfo.splice(repeateIndex, 1, { id: previewId, ...storageInfo }) | ||
43 | + setSessionStorage(StorageEnum.GO_CHART_STORAGE_LIST, sessionStorageInfo) | ||
44 | + } else { | ||
45 | + sessionStorageInfo.push({ | ||
46 | + id: previewId, | ||
47 | + ...storageInfo | ||
48 | + }) | ||
49 | + setSessionStorage(StorageEnum.GO_CHART_STORAGE_LIST, sessionStorageInfo) | ||
50 | + } | ||
51 | + } else { | ||
52 | + setSessionStorage(StorageEnum.GO_CHART_STORAGE_LIST, [{ id: previewId, ...storageInfo }]) | ||
53 | + } | ||
54 | + // 跳转 | ||
55 | + routerTurnByPath(path, [previewId], undefined, true) | ||
56 | +} | ||
57 | + | ||
58 | +// 发布 | ||
59 | +const sendHandle = () => { | ||
60 | + goDialog({ | ||
61 | + message: '想体验发布功能,请前往 master-fetch 分支查看: https://demo.mtruning.club/#/login', | ||
62 | + positiveText: '了然', | ||
63 | + closeNegativeText: true, | ||
64 | + onPositiveCallback: () => {} | ||
65 | + }) | ||
66 | +} | ||
67 | + | ||
68 | +const btnList = [ | ||
69 | + { | ||
70 | + select: true, | ||
71 | + title: '同步内容', | ||
72 | + type: 'primary', | ||
73 | + icon: renderIcon(AnalyticsIcon), | ||
74 | + event: syncData | ||
75 | + }, | ||
76 | + { | ||
77 | + select: true, | ||
78 | + title: '预览', | ||
79 | + icon: renderIcon(BrowsersOutlineIcon), | ||
80 | + event: previewHandle | ||
81 | + }, | ||
82 | + // { | ||
83 | + // select: true, | ||
84 | + // title: '发布', | ||
85 | + // icon: renderIcon(SendIcon), | ||
86 | + // event: sendHandle | ||
87 | + // } | ||
88 | +] | ||
89 | + | ||
90 | +const comBtnList = computed(() => { | ||
91 | + if (chartEditStore.getEditCanvas.isCodeEdit) { | ||
92 | + return btnList | ||
93 | + } | ||
94 | + const cloneList = cloneDeep(btnList) | ||
95 | + cloneList.shift() | ||
96 | + return cloneList | ||
97 | +}) | ||
98 | +</script> | ||
99 | + | ||
100 | +<style lang="scss" scoped> | ||
101 | +.align-center { | ||
102 | + margin-top: -4px; | ||
103 | +} | ||
104 | +</style> |
@@ -50,9 +50,13 @@ const chartEditStore = useChartEditStore() | @@ -50,9 +50,13 @@ const chartEditStore = useChartEditStore() | ||
50 | 50 | ||
51 | // 记录初始化 | 51 | // 记录初始化 |
52 | chartHistoryStoreStore.canvasInit(chartEditStore.getEditCanvas) | 52 | chartHistoryStoreStore.canvasInit(chartEditStore.getEditCanvas) |
53 | - | ||
54 | -const HeaderLeftBtn = loadAsyncComponent(() => import('./ContentHeader/headerLeftBtn/index.vue')) | ||
55 | -const HeaderRightBtn = loadAsyncComponent(() => import('./ContentHeader/headerRightBtn/index.vue')) | 53 | +/** |
54 | + * THINGS_KIT 升级版本这里有冲突 | ||
55 | + * 源文件 './ContentHeader/headerRightBtn/index.vue' ./ContentHeader/headerLeftBtn/index.vue' | ||
56 | + * 修改后 './ContentHeader/headerRightBtn/external/index.vue' ./ContentHeader/headerLeftBtn/external/index.vue' | ||
57 | + */ | ||
58 | +const HeaderLeftBtn = loadAsyncComponent(() => import('./ContentHeader/headerLeftBtn/external/index.vue')) | ||
59 | +const HeaderRightBtn = loadAsyncComponent(() => import('./ContentHeader/headerRightBtn/external/index.vue')) | ||
56 | const HeaderTitle = loadAsyncComponent(() => import('./ContentHeader/headerTitle/index.vue')) | 60 | const HeaderTitle = loadAsyncComponent(() => import('./ContentHeader/headerTitle/index.vue')) |
57 | const ContentLayers = loadAsyncComponent(() => import('./ContentLayers/index.vue')) | 61 | const ContentLayers = loadAsyncComponent(() => import('./ContentLayers/index.vue')) |
58 | const ContentCharts = loadAsyncComponent(() => import('./ContentCharts/index.vue')) | 62 | const ContentCharts = loadAsyncComponent(() => import('./ContentCharts/index.vue')) |