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