Commit 2bebc57c71774548c1a1d0c4aa022a5429dc299c

Authored by xp.Huang
2 parents 46b6cdbf a1b1e8a7

Merge branch 'ft' into 'main_dev'

perf(src/packages): 优化自定义网页全屏图标展示

See merge request yunteng/thingskit-view!75
@@ -5,7 +5,8 @@ enum Api { @@ -5,7 +5,8 @@ enum Api {
5 GET_DICT = '/dict_item', 5 GET_DICT = '/dict_item',
6 UPLOAD = '/oss/upload', 6 UPLOAD = '/oss/upload',
7 DOWNLOAD = '/oss/download_file/', 7 DOWNLOAD = '/oss/download_file/',
8 - AREALIST = '/area/list' 8 + AREALIST = '/area/list',
  9 + PLATFORM = '/platform/get'
9 } 10 }
10 11
11 export const getDictItemByCode = (value: string) => { 12 export const getDictItemByCode = (value: string) => {
@@ -28,9 +29,13 @@ export const downloadFile = (fileName: string) => { @@ -28,9 +29,13 @@ export const downloadFile = (fileName: string) => {
28 return defHttp.get({ url: `${Api.DOWNLOAD}${fileName}` }) 29 return defHttp.get({ url: `${Api.DOWNLOAD}${fileName}` })
29 } 30 }
30 31
  32 +//获取区域
31 export const getAreaList = (data: object) => { 33 export const getAreaList = (data: object) => {
32 return defHttp.post<any>({ 34 return defHttp.post<any>({
33 url: Api.AREALIST, 35 url: Api.AREALIST,
34 data 36 data
35 }) 37 })
36 } 38 }
  39 +
  40 +//获取企业定制
  41 +export const getPlatformInfo = () => defHttp.get({ url: Api.PLATFORM })
1 <template> 1 <template>
2 <n-dropdown trigger="hover" @select="handleSelect" :show-arrow="true" :options="options"> 2 <n-dropdown trigger="hover" @select="handleSelect" :show-arrow="true" :options="options">
3 <div class="user-info-box"> 3 <div class="user-info-box">
4 - <person-icon v-if="fallback"></person-icon> 4 + <person-icon v-if="!avatarLogo"></person-icon>
5 <n-avatar 5 <n-avatar
6 - v-if="!fallback" 6 + v-else
7 round 7 round
8 object-fit="cover" 8 object-fit="cover"
9 size="medium" 9 size="medium"
@@ -20,24 +20,30 @@ @@ -20,24 +20,30 @@
20 </template> 20 </template>
21 21
22 <script lang="ts" setup> 22 <script lang="ts" setup>
23 -import { h, ref, computed } from 'vue' 23 +import { h, ref, onMounted } from 'vue'
24 import { NAvatar, NText } from 'naive-ui' 24 import { NAvatar, NText } from 'naive-ui'
25 import { renderIcon } from '@/utils' 25 import { renderIcon } from '@/utils'
26 -import { logout, renderLang } from '@/utils' 26 +import { renderLang } from '@/utils'
27 import { GoSystemSet } from '@/components/GoSystemSet/index' 27 import { GoSystemSet } from '@/components/GoSystemSet/index'
28 import { GoSystemInfo } from '@/components/GoSystemInfo/index' 28 import { GoSystemInfo } from '@/components/GoSystemInfo/index'
29 -import Person from './person.png'  
30 import { icon } from '@/plugins' 29 import { icon } from '@/plugins'
31 import { useUserStore } from '@/store/external/modules/user' 30 import { useUserStore } from '@/store/external/modules/user'
32 import { useSyncRemote } from '@/views/chart/hooks/external/useRemote.hook' 31 import { useSyncRemote } from '@/views/chart/hooks/external/useRemote.hook'
33 -const { ChatboxEllipsesIcon, PersonIcon, LogOutOutlineIcon, SettingsSharpIcon } = icon.ionicons5 32 +import Person from './person.png'
  33 +import { useSetWebsiteIcon } from '@/hooks/external/useSetWebsiteIcon.hook'
  34 +
  35 +const { getPlatform } = useSetWebsiteIcon()
  36 +
  37 +const { PersonIcon, LogOutOutlineIcon, SettingsSharpIcon } = icon.ionicons5
34 38
35 const t = window['$t'] 39 const t = window['$t']
36 40
37 const { dataSyncUpdate } = useSyncRemote() 41 const { dataSyncUpdate } = useSyncRemote()
38 42
39 const modelShowInfo = ref(false) 43 const modelShowInfo = ref(false)
  44 +
40 const modelShow = ref(false) 45 const modelShow = ref(false)
  46 +
41 const avatarLogo = ref('') 47 const avatarLogo = ref('')
42 48
43 // 是否失败 49 // 是否失败
@@ -69,6 +75,17 @@ const renderUserInfo = () => { @@ -69,6 +75,17 @@ const renderUserInfo = () => {
69 ] 75 ]
70 ) 76 )
71 } 77 }
  78 +
  79 +onMounted(() => {
  80 + try {
  81 + renderUserInfo()
  82 + //获取企业定制
  83 + getPlatform()
  84 + } finally {
  85 + console.log()
  86 + }
  87 +})
  88 +
72 const options = ref([ 89 const options = ref([
73 { 90 {
74 label: '我的信息', 91 label: '我的信息',
@@ -124,6 +141,7 @@ const sysInfoHandle = () => { @@ -124,6 +141,7 @@ const sysInfoHandle = () => {
124 141
125 // THINGS_KIT 修改退出登录 142 // THINGS_KIT 修改退出登录
126 const userStore = useUserStore() 143 const userStore = useUserStore()
  144 +
127 const handleSelect = (key: string) => { 145 const handleSelect = (key: string) => {
128 switch (key) { 146 switch (key) {
129 case 'contact': 147 case 'contact':
1 -import { toRefs, ref } from 'vue' 1 +import { toRefs } from 'vue'
2 import { CreateComponentType } from '@/packages/index.d' 2 import { CreateComponentType } from '@/packages/index.d'
3 import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore' 3 import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
4 4
@@ -14,6 +14,8 @@ export const useChartInteract = ( @@ -14,6 +14,8 @@ export const useChartInteract = (
14 ) => { 14 ) => {
15 const chartEditStore = useChartEditStore() 15 const chartEditStore = useChartEditStore()
16 const { interactEvents } = chartConfig.events 16 const { interactEvents } = chartConfig.events
  17 + const { selectCurrentItems } = chartConfig.option
  18 + const { selectTargetItems } = chartConfig.option
17 const fnOnEvent = interactEvents.filter(item => { 19 const fnOnEvent = interactEvents.filter(item => {
18 return item.interactOn === interactEventOn 20 return item.interactOn === interactEventOn
19 }) 21 })
@@ -30,26 +32,21 @@ export const useChartInteract = ( @@ -30,26 +32,21 @@ export const useChartInteract = (
30 Header.value[key] = param[item.interactFn[key]] 32 Header.value[key] = param[item.interactFn[key]]
31 } 33 }
32 }) 34 })
33 - setJump(chartConfig) 35 + setJump(selectCurrentItems, selectTargetItems)
34 }) 36 })
35 - function setJump(chart: CreateComponentType) {  
36 - /**  
37 - * 通过页面显示隐藏来模拟页面跳转  
38 - * 当前点击对象和绑定的联动组件(分组或单个)内容隐藏,目标对象和绑定的联动组件(分组或单个)内容显示  
39 - */ 37 + function setJump(selectCurrentItems: string[], selectTargetItems: string[]) {
40 try { 38 try {
41 - const targetId = chart.option.dataset[0].target  
42 - const currentId = chart.option.dataset[0].current  
43 - const targetButtonId = chart.option.dataset[0].targetButton  
44 - const currentButtonId = chart.option.dataset[0].currentButton  
45 - const targetIndex = chartEditStore.fetchTargetIndex(targetId)  
46 - const currentIndex = chartEditStore.fetchTargetIndex(currentId)  
47 - const targetButtonIndex = chartEditStore.fetchTargetIndex(targetButtonId)  
48 - const currentButtonIndex = chartEditStore.fetchTargetIndex(currentButtonId)  
49 - chartEditStore.componentList[targetIndex].status.hide = false  
50 - chartEditStore.componentList[currentIndex].status.hide = true  
51 - chartEditStore.componentList[targetButtonIndex].status.hide = false  
52 - chartEditStore.componentList[currentButtonIndex].status.hide = true 39 + //优化循环性能
  40 + for (let i = 0, len = chartEditStore.componentList.length; i < len; i++) {
  41 + const compId = chartEditStore.componentList[i].id
  42 + const compItem = chartEditStore.componentList[i]
  43 + if (selectCurrentItems.includes(compId)) {
  44 + compItem.status.hide = true
  45 + }
  46 + if (selectTargetItems.includes(compId)) {
  47 + compItem.status.hide = false
  48 + }
  49 + }
53 } finally { 50 } finally {
54 console.log() 51 console.log()
55 } 52 }
  1 +import DefaultWebsiteIcon from '../../../public/favicon.ico'
  2 +import { getPlatformInfo } from '@/api/external/common'
  3 +
  4 +export const useSetWebsiteIcon = () => {
  5 + const getPlatform = async () => {
  6 + //防止接口报错阻塞页面
  7 + try {
  8 + const rest = await getPlatformInfo()
  9 + replaceWebsiteIcon(rest?.icon || DefaultWebsiteIcon)
  10 + } finally {
  11 + console.log()
  12 + }
  13 + }
  14 +
  15 + const replaceWebsiteIcon = (icon: string) => {
  16 + const linkEl = document.querySelectorAll('link[rel*="icon"]')
  17 + linkEl.forEach(item => {
  18 + item.setAttribute('href', icon)
  19 + })
  20 + }
  21 + return {
  22 + getPlatform
  23 + }
  24 +}
@@ -16,11 +16,18 @@ import 'vue3-sketch-ruler/lib/style.css' @@ -16,11 +16,18 @@ import 'vue3-sketch-ruler/lib/style.css'
16 16
17 // THINGS_KIT 内容安全协议hook 17 // THINGS_KIT 内容安全协议hook
18 import { useWebSecurityPolicy } from './hooks/external/useWebSecurityPolicy' 18 import { useWebSecurityPolicy } from './hooks/external/useWebSecurityPolicy'
  19 +// THINGS_KIT web站点icon设置hook
  20 +import { useSetWebsiteIcon } from '@/hooks/external/useSetWebsiteIcon.hook'
  21 +
19 22
20 async function appInit() { 23 async function appInit() {
21 // THINGS_KIT 内容安全协议hook 24 // THINGS_KIT 内容安全协议hook
22 useWebSecurityPolicy() 25 useWebSecurityPolicy()
23 26
  27 + // THINGS_KIT web站点icon设置hook
  28 + const { getPlatform } = useSetWebsiteIcon()
  29 + getPlatform()
  30 +
24 const goAppProvider = createApp(GoAppProvider) 31 const goAppProvider = createApp(GoAppProvider)
25 32
26 const app = createApp(App) 33 const app = createApp(App)
@@ -6,25 +6,20 @@ import { COMPONENT_INTERACT_EVENT_KET } from '@/enums/eventEnum' @@ -6,25 +6,20 @@ import { COMPONENT_INTERACT_EVENT_KET } from '@/enums/eventEnum'
6 import { interactActions, ComponentInteractEventEnum } from './interact' 6 import { interactActions, ComponentInteractEventEnum } from './interact'
7 import { ButtonConfig } from './index' 7 import { ButtonConfig } from './index'
8 8
  9 +
9 export const option = { 10 export const option = {
10 // 时间组件展示类型,必须和 interactActions 中定义的数据一致 11 // 时间组件展示类型,必须和 interactActions 中定义的数据一致
11 [COMPONENT_INTERACT_EVENT_KET]: ComponentInteractEventEnum.DATA, 12 [COMPONENT_INTERACT_EVENT_KET]: ComponentInteractEventEnum.DATA,
12 // 暴露配置内容给用户 13 // 暴露配置内容给用户
13 - dataset: [  
14 - {  
15 - label: '',  
16 - current: '',  
17 - target: '',  
18 - currentButton: '',  
19 - targetButton: ''  
20 - }  
21 - ], 14 + dataset: '第1页',
22 buttonType: 'primary', 15 buttonType: 'primary',
23 buttonGhost: false, 16 buttonGhost: false,
24 buttonDashed: false, 17 buttonDashed: false,
25 buttonColor: '', 18 buttonColor: '',
26 buttonTextColor: 'white', 19 buttonTextColor: 'white',
27 buttonTextSize: '16', 20 buttonTextSize: '16',
  21 + selectCurrentItems: [],
  22 + selectTargetItems: []
28 } 23 }
29 24
30 export default class Config extends PublicConfigClass implements CreateComponentType { 25 export default class Config extends PublicConfigClass implements CreateComponentType {
@@ -40,27 +40,41 @@ @@ -40,27 +40,41 @@
40 <span class="help-span">{{ threeFileHelpMessgae }}</span> 40 <span class="help-span">{{ threeFileHelpMessgae }}</span>
41 </n-tooltip> 41 </n-tooltip>
42 </template> 42 </template>
43 - <setting-item v-for="(item, index) in optionData.dataset" :key="index">  
44 - <n-input v-model:value="item.label" size="small" placeholder="按钮文字"></n-input>  
45 - <div style="height: 5px"></div>  
46 - <n-input v-model:value="item.currentButton" size="small" placeholder="填写当前按钮id(事件里面)"></n-input>  
47 - <div style="height: 5px"></div>  
48 - <n-input v-model:value="item.targetButton" size="small" placeholder="填写目标按钮id(事件里面)"></n-input>  
49 - <div style="height: 5px"></div>  
50 - <n-input v-model:value="item.current" size="small" placeholder="填写当前页面id(事件里面)"></n-input>  
51 - <div style="height: 5px"></div>  
52 - <n-input v-model:value="item.target" size="small" placeholder="填写目标页面id(事件里面)"></n-input>  
53 - <div style="height: 5px"></div> 43 + <setting-item name="按钮文字" :alone="true">
  44 + <n-input v-model:value="optionData.dataset" size="small" placeholder="按钮文字"></n-input>
  45 + </setting-item>
  46 + </setting-item-box>
  47 + <setting-item-box name="当前项">
  48 + <setting-item name="当前项" :alone="true">
  49 + <n-select
  50 + placeholder="请选择当前项"
  51 + multiple
  52 + size="small"
  53 + v-model:value="optionData.selectCurrentItems"
  54 + :options="selectCurrentItemOptions"
  55 + />
  56 + </setting-item>
  57 + </setting-item-box>
  58 + <setting-item-box name="目标项">
  59 + <setting-item name="目标项" :alone="true">
  60 + <n-select
  61 + placeholder="请选择目标项"
  62 + multiple
  63 + size="small"
  64 + v-model:value="optionData.selectTargetItems"
  65 + :options="selectTargetItemOptions"
  66 + />
54 </setting-item> 67 </setting-item>
55 </setting-item-box> 68 </setting-item-box>
56 </collapse-item> 69 </collapse-item>
57 </template> 70 </template>
58 71
59 <script lang="ts" setup> 72 <script lang="ts" setup>
60 -import { PropType, ref } from 'vue' 73 +import { PropType, ref, onMounted } from 'vue'
61 import { CollapseItem, SettingItemBox } from '@/components/Pages/ChartItemSetting' 74 import { CollapseItem, SettingItemBox } from '@/components/Pages/ChartItemSetting'
62 import { option } from './config' 75 import { option } from './config'
63 import { icon } from '@/plugins' 76 import { icon } from '@/plugins'
  77 +import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
64 78
65 defineProps({ 79 defineProps({
66 optionData: { 80 optionData: {
@@ -69,11 +83,11 @@ defineProps({ @@ -69,11 +83,11 @@ defineProps({
69 } 83 }
70 }) 84 })
71 85
  86 +const chartEditStore = useChartEditStore()
  87 +
72 const { HelpOutlineIcon } = icon.ionicons5 88 const { HelpOutlineIcon } = icon.ionicons5
73 89
74 -const threeFileHelpMessgae = ref(`  
75 -在事件里面复制对应组件id,填写你要跳转的目标,相当于一个按钮就绑定了一个页面(分组),然后跳转到另一个页面,其实就是点击当前页隐藏,目标页显示  
76 -`) 90 +const threeFileHelpMessgae = ref(`勾选当前项和跳转的目标项`)
77 91
78 const buttonTypeOptions = [ 92 const buttonTypeOptions = [
79 { 93 {
@@ -105,6 +119,19 @@ const buttonTypeOptions = [ @@ -105,6 +119,19 @@ const buttonTypeOptions = [
105 value: 'error' 119 value: 'error'
106 } 120 }
107 ] 121 ]
  122 +
  123 +const selectCurrentItemOptions = ref<{ label: string; value: string }[]>([])
  124 +
  125 +const selectTargetItemOptions = ref<{ label: string; value: string }[]>([])
  126 +
  127 +onMounted(() => {
  128 + const componentList = chartEditStore.componentList.map(item => ({
  129 + label: item.chartConfig?.title,
  130 + value: item.id
  131 + }))
  132 + selectCurrentItemOptions.value = componentList
  133 + selectTargetItemOptions.value = componentList
  134 +})
108 </script> 135 </script>
109 <style lang="scss" scoped> 136 <style lang="scss" scoped>
110 .help-span { 137 .help-span {
@@ -5,9 +5,9 @@ @@ -5,9 +5,9 @@
5 :dashed="buttonDashed" 5 :dashed="buttonDashed"
6 :ghost="buttonGhost" 6 :ghost="buttonGhost"
7 :color="buttonColor" 7 :color="buttonColor"
8 - @click="onClick(option.value.dataset[0])" 8 + @click="onClick(option.value.dataset)"
9 > 9 >
10 - <span class="button-text-color">{{ option.value.dataset[0].label }}</span> 10 + <span class="button-text-color">{{ dataset }}</span>
11 </n-button> 11 </n-button>
12 </template> 12 </template>
13 13
@@ -28,7 +28,7 @@ const props = defineProps({ @@ -28,7 +28,7 @@ const props = defineProps({
28 }) 28 })
29 29
30 const { w, h } = toRefs(props.chartConfig.attr) 30 const { w, h } = toRefs(props.chartConfig.attr)
31 -const { buttonType, buttonDashed, buttonGhost, buttonColor, buttonTextColor, buttonTextSize } = toRefs( 31 +const { buttonType, buttonDashed, buttonGhost, buttonColor, buttonTextColor, buttonTextSize, dataset } = toRefs(
32 props.chartConfig.option 32 props.chartConfig.option
33 ) 33 )
34 const option = shallowReactive({ 34 const option = shallowReactive({
@@ -39,13 +39,13 @@ const onClick = (v: any) => { @@ -39,13 +39,13 @@ const onClick = (v: any) => {
39 useChartInteract( 39 useChartInteract(
40 props.chartConfig, 40 props.chartConfig,
41 useChartEditStore, 41 useChartEditStore,
42 - { [ComponentInteractParamsEnum.DATA]: v?.current },  
43 - InteractEventOn.CHANGE, 42 + { [ComponentInteractParamsEnum.DATA]: v },
  43 + InteractEventOn.CHANGE
44 ) 44 )
45 } 45 }
46 46
47 onMounted(() => { 47 onMounted(() => {
48 - onClick(option.value.dataset[0]) 48 + onClick(option.value.dataset)
49 }) 49 })
50 50
51 // 手动更新 51 // 手动更新
1 <template> 1 <template>
2 <div class="iframe-content" :style="getStyle(borderRadius)"> 2 <div class="iframe-content" :style="getStyle(borderRadius)">
3 - <div v-show="isShowSvg" @click="handleFullScreen" class="fullscreen-button"> 3 + <div v-show="isShowSvg" @click="handleFullScreen" id="fullscreenButton">
4 <svg 4 <svg
5 focusable="false" 5 focusable="false"
6 class="" 6 class=""
7 data-icon="fullscreen" 7 data-icon="fullscreen"
8 - width="2.1vw"  
9 - height="2.1vh" 8 + width="4vw"
  9 + height="4vh"
10 fill="currentColor" 10 fill="currentColor"
11 aria-hidden="true" 11 aria-hidden="true"
12 viewBox="64 64 896 896" 12 viewBox="64 64 896 896"
@@ -23,6 +23,7 @@ @@ -23,6 +23,7 @@
23 :src="option.dataset" 23 :src="option.dataset"
24 :width="w" 24 :width="w"
25 :height="h" 25 :height="h"
  26 + :allowfullscreen="allowfullscreen"
26 style="border-width: 0" 27 style="border-width: 0"
27 ></iframe> 28 ></iframe>
28 </div> 29 </div>
@@ -44,6 +45,8 @@ const props = defineProps({ @@ -44,6 +45,8 @@ const props = defineProps({
44 45
45 const isShowSvg = ref(false) 46 const isShowSvg = ref(false)
46 47
  48 +const allowfullscreen = ref(false)
  49 +
47 const { w, h } = toRefs(props.chartConfig.attr) 50 const { w, h } = toRefs(props.chartConfig.attr)
48 const { borderRadius } = toRefs(props.chartConfig.option) 51 const { borderRadius } = toRefs(props.chartConfig.option)
49 52
@@ -80,18 +83,22 @@ const handleFullScreen = () => { @@ -80,18 +83,22 @@ const handleFullScreen = () => {
80 useFullScreen(domName, htmlName) 83 useFullScreen(domName, htmlName)
81 } 84 }
82 85
83 -const handleMouseenter = () => (isShowSvg.value = true) 86 +const handleMouseenter = () => {
  87 + isShowSvg.value = true
  88 + allowfullscreen.value = true
  89 +}
  90 +
84 const handleMouseleave = () => (isShowSvg.value = false) 91 const handleMouseleave = () => (isShowSvg.value = false)
85 </script> 92 </script>
86 -  
87 <style lang="scss" scoped> 93 <style lang="scss" scoped>
88 .iframe-content { 94 .iframe-content {
89 - position: relative;  
90 - .fullscreen-button { 95 + #fullscreenButton {
  96 + color: white;
91 cursor: pointer; 97 cursor: pointer;
92 position: absolute; 98 position: absolute;
93 - right: 0;  
94 - top: 0; 99 + z-index: 999999;
  100 + top: 3%;
  101 + right: 0.1vw;
95 } 102 }
96 } 103 }
97 </style> 104 </style>