Showing
6 changed files
with
140 additions
and
70 deletions
1 | import { defHttp } from '@/utils/external/http/axios' | 1 | import { defHttp } from '@/utils/external/http/axios' |
2 | -import { DictItem, OrganizationListItem, UploadResponse } from './model' | 2 | +import { ConfigurationItemType, DictItem, OrganizationListItem, UploadResponse } from './model' |
3 | +import { PaginationResult } from '/#/external/axios' | ||
3 | 4 | ||
4 | enum Api { | 5 | enum Api { |
5 | GET_DICT = '/dict_item', | 6 | GET_DICT = '/dict_item', |
@@ -54,7 +55,7 @@ export const getPlatformInfo = () => defHttp.get({ url: Api.PLATFORM }) | @@ -54,7 +55,7 @@ export const getPlatformInfo = () => defHttp.get({ url: Api.PLATFORM }) | ||
54 | 55 | ||
55 | //获取组态列表 | 56 | //获取组态列表 |
56 | export const getConfigurationList = (params: object) => { | 57 | export const getConfigurationList = (params: object) => { |
57 | - return defHttp.get({ url: `${Api.CONFIGURATION}`, params }) | 58 | + return defHttp.get<PaginationResult<ConfigurationItemType>>({ url: `${Api.CONFIGURATION}`, params }) |
58 | } | 59 | } |
59 | 60 | ||
60 | //组态设置是否公开或私有 | 61 | //组态设置是否公开或私有 |
@@ -145,4 +146,4 @@ export const getProfileAttrs = (params: { deviceProfileId: string; dataType?: st | @@ -145,4 +146,4 @@ export const getProfileAttrs = (params: { deviceProfileId: string; dataType?: st | ||
145 | url: `${Api.DEVICE_ATTR}/${deviceProfileId}`, | 146 | url: `${Api.DEVICE_ATTR}/${deviceProfileId}`, |
146 | params: { dataType }, | 147 | params: { dataType }, |
147 | }); | 148 | }); |
148 | -}; | ||
149 | +}; |
@@ -23,4 +23,34 @@ export interface OrganizationListItem { | @@ -23,4 +23,34 @@ export interface OrganizationListItem { | ||
23 | name: string; | 23 | name: string; |
24 | parentId?: string; | 24 | parentId?: string; |
25 | remark: string; | 25 | remark: string; |
26 | -} | ||
26 | +} | ||
27 | + | ||
28 | +export interface ConfigurationItemType { | ||
29 | + id: string | ||
30 | + creator: string | ||
31 | + createTime: string | ||
32 | + name: string | ||
33 | + enabled: boolean | ||
34 | + tenantId: string | ||
35 | + viewType: string | ||
36 | + organizationId: string | ||
37 | + platform: string | ||
38 | + organizationDTO: OrganizationDto | ||
39 | + publicId?: string | ||
40 | + productAndDevice: ProductAndDevice[] | ||
41 | +} | ||
42 | + | ||
43 | +export interface OrganizationDto { | ||
44 | + name: string | ||
45 | + enabled: boolean | ||
46 | + sort: number | ||
47 | + children: any[] | ||
48 | +} | ||
49 | + | ||
50 | +export interface ProductAndDevice { | ||
51 | + name: string | ||
52 | + profileId: string | ||
53 | + deviceList: any | ||
54 | + deviceType: string | ||
55 | + transportType: string | ||
56 | +} |
@@ -3,14 +3,19 @@ import {CreateComponentType} from '@/packages/index.d' | @@ -3,14 +3,19 @@ import {CreateComponentType} from '@/packages/index.d' | ||
3 | import {chartInitConfig} from '@/settings/designSetting' | 3 | import {chartInitConfig} from '@/settings/designSetting' |
4 | import {OverrideILoadConfigurationframeConfig} from './index' | 4 | import {OverrideILoadConfigurationframeConfig} from './index' |
5 | import cloneDeep from 'lodash/cloneDeep' | 5 | import cloneDeep from 'lodash/cloneDeep' |
6 | +import { Platform } from './help' | ||
6 | 7 | ||
7 | export const enum shareEnum { | 8 | export const enum shareEnum { |
8 | PRIVATE_VIEW = "PRIVATE_VIEW", | 9 | PRIVATE_VIEW = "PRIVATE_VIEW", |
10 | + PUBLIC_VIEW = 'PUBLIC_VIEW' | ||
9 | } | 11 | } |
10 | 12 | ||
11 | export const option = { | 13 | export const option = { |
12 | // 网站路径 | 14 | // 网站路径 |
13 | dataset: '', | 15 | dataset: '', |
16 | + organizationId: '', | ||
17 | + platform: Platform.PC, | ||
18 | + publicId: '' as (undefined | string), | ||
14 | // 圆角 | 19 | // 圆角 |
15 | borderRadius: 10, | 20 | borderRadius: 10, |
16 | pages: { | 21 | pages: { |
@@ -3,24 +3,19 @@ | @@ -3,24 +3,19 @@ | ||
3 | <setting-item-box name="路径" :alone="true"> | 3 | <setting-item-box name="路径" :alone="true"> |
4 | <setting-item name="请选择要加载的组态"> | 4 | <setting-item name="请选择要加载的组态"> |
5 | <n-select label-in-value @change="handleUpdateValue" filterable size="small" v-model:value="optionData.dataset" | 5 | <n-select label-in-value @change="handleUpdateValue" filterable size="small" v-model:value="optionData.dataset" |
6 | - :options="configurationOptions"/> | 6 | + :options="configurationOptions" /> |
7 | </setting-item> | 7 | </setting-item> |
8 | </setting-item-box> | 8 | </setting-item-box> |
9 | <setting-item-box name="是否公开"> | 9 | <setting-item-box name="是否公开"> |
10 | <setting-item> | 10 | <setting-item> |
11 | <div style="display:flex"> | 11 | <div style="display:flex"> |
12 | - <n-switch @change="handleChange" v-model:value="optionData.isShare" size="small"/> | 12 | + <n-switch @change="handleChange" v-model:value="optionData.isShare" size="small" /> |
13 | </div> | 13 | </div> |
14 | </setting-item> | 14 | </setting-item> |
15 | </setting-item-box> | 15 | </setting-item-box> |
16 | <setting-item-box name="样式"> | 16 | <setting-item-box name="样式"> |
17 | <setting-item name="圆角"> | 17 | <setting-item name="圆角"> |
18 | - <n-input-number | ||
19 | - v-model:value="optionData.borderRadius" | ||
20 | - size="small" | ||
21 | - :min="0" | ||
22 | - placeholder="圆角" | ||
23 | - ></n-input-number> | 18 | + <n-input-number v-model:value="optionData.borderRadius" size="small" :min="0" placeholder="圆角"></n-input-number> |
24 | </setting-item> | 19 | </setting-item> |
25 | </setting-item-box> | 20 | </setting-item-box> |
26 | <setting-item-box name="分页"> | 21 | <setting-item-box name="分页"> |
@@ -28,13 +23,8 @@ | @@ -28,13 +23,8 @@ | ||
28 | <n-input-number v-model:value="optionData.pages.page" size="small" :min="1" placeholder="页码"></n-input-number> | 23 | <n-input-number v-model:value="optionData.pages.page" size="small" :min="1" placeholder="页码"></n-input-number> |
29 | </setting-item> | 24 | </setting-item> |
30 | <setting-item name="页数"> | 25 | <setting-item name="页数"> |
31 | - <n-input-number | ||
32 | - disabled | ||
33 | - v-model:value="optionData.pages.pageSize" | ||
34 | - size="small" | ||
35 | - :min="10" | ||
36 | - placeholder="页数" | ||
37 | - ></n-input-number> | 26 | + <n-input-number disabled v-model:value="optionData.pages.pageSize" size="small" :min="10" |
27 | + placeholder="页数"></n-input-number> | ||
38 | </setting-item> | 28 | </setting-item> |
39 | </setting-item-box> | 29 | </setting-item-box> |
40 | <setting-item-box name="颜色" :alone="true"> | 30 | <setting-item-box name="颜色" :alone="true"> |
@@ -49,11 +39,12 @@ | @@ -49,11 +39,12 @@ | ||
49 | </template> | 39 | </template> |
50 | 40 | ||
51 | <script setup lang="ts"> | 41 | <script setup lang="ts"> |
52 | -import {PropType, onMounted, ref, watch} from 'vue' | ||
53 | -import {option, shareEnum} from './config' | ||
54 | -import {CollapseItem, SettingItemBox, SettingItem} from '@/components/Pages/ChartItemSetting' | ||
55 | -import {getConfigurationList, setConfigurationIsShare} from '@/api/external/common/index' | ||
56 | -import {SelectOption} from 'naive-ui' | 42 | +import { PropType, onMounted, ref, watch } from 'vue' |
43 | +import { option, shareEnum } from './config' | ||
44 | +import { CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting' | ||
45 | +import { getConfigurationList, setConfigurationIsShare } from '@/api/external/common/index' | ||
46 | +import { ConfigurationItemType } from '@/api/external/common/model' | ||
47 | +import { Platform } from './help' | ||
57 | 48 | ||
58 | const props = defineProps({ | 49 | const props = defineProps({ |
59 | optionData: { | 50 | optionData: { |
@@ -62,44 +53,40 @@ const props = defineProps({ | @@ -62,44 +53,40 @@ const props = defineProps({ | ||
62 | } | 53 | } |
63 | }) | 54 | }) |
64 | 55 | ||
65 | -const configurationOptions = ref([]) | 56 | +const configurationOptions = ref<ConfigurationItemType[]>([]) |
66 | 57 | ||
67 | const configurationId = ref('') | 58 | const configurationId = ref('') |
68 | 59 | ||
69 | const getConfigurationOptions = async (params: object) => { | 60 | const getConfigurationOptions = async (params: object) => { |
70 | - const {items} = await getConfigurationList(params) | 61 | + const { items } = await getConfigurationList(params) |
71 | if (items) { | 62 | if (items) { |
72 | - configurationOptions.value = items.map((item: SelectOption) => ({ | 63 | + configurationOptions.value = items.map((item) => ({ |
73 | label: item.name, | 64 | label: item.name, |
74 | value: item.id, | 65 | value: item.id, |
75 | - viewType: item.viewType | 66 | + ...item |
76 | })) | 67 | })) |
77 | } | 68 | } |
78 | } | 69 | } |
79 | 70 | ||
80 | watch( | 71 | watch( |
81 | - () => props.optionData.pages, | ||
82 | - (newData: any) => { | ||
83 | - getConfigurationOptions({page: newData.page, pageSize: newData.pageSize}) | ||
84 | - }, | ||
85 | - { | ||
86 | - deep: true, | ||
87 | - immediate: true | ||
88 | - } | 72 | + () => props.optionData.pages, |
73 | + (newData: any) => { | ||
74 | + getConfigurationOptions({ page: newData.page, pageSize: newData.pageSize }) | ||
75 | + }, | ||
76 | + { | ||
77 | + deep: true, | ||
78 | + immediate: true | ||
79 | + } | ||
89 | ) | 80 | ) |
90 | 81 | ||
91 | onMounted(() => { | 82 | onMounted(() => { |
92 | - getConfigurationOptions({page: props.optionData.pages.page, pageSize: props.optionData.pages.pageSize}) | 83 | + getConfigurationOptions({ page: props.optionData.pages.page, pageSize: props.optionData.pages.pageSize }) |
93 | }) | 84 | }) |
94 | 85 | ||
95 | -const handleUpdateValue = (value: string, options: SelectOption) => { | ||
96 | - const {viewType} = options | 86 | +const handleUpdateValue = (value: string, options: ConfigurationItemType) => { |
87 | + const { viewType, organizationId, publicId, platform } = options | ||
97 | configurationId.value = value | 88 | configurationId.value = value |
98 | - if (viewType === shareEnum.PRIVATE_VIEW) { | ||
99 | - props.optionData.isShare = false | ||
100 | - } else { | ||
101 | - props.optionData.isShare = true | ||
102 | - } | 89 | + Object.assign(props.optionData, { isShare: viewType === shareEnum.PUBLIC_VIEW, organizationId, platform, publicId } as typeof option) |
103 | } | 90 | } |
104 | 91 | ||
105 | const handleChange = async (value: boolean) => { | 92 | const handleChange = async (value: boolean) => { |
@@ -108,7 +95,7 @@ const handleChange = async (value: boolean) => { | @@ -108,7 +95,7 @@ const handleChange = async (value: boolean) => { | ||
108 | }) | 95 | }) |
109 | if (res) { | 96 | if (res) { |
110 | window.$message.success('操作成功!') | 97 | window.$message.success('操作成功!') |
111 | - await getConfigurationOptions({page: props.optionData.pages.page, pageSize: props.optionData.pages.pageSize}) | 98 | + await getConfigurationOptions({ page: props.optionData.pages.page, pageSize: props.optionData.pages.pageSize }) |
112 | } | 99 | } |
113 | } | 100 | } |
114 | </script> | 101 | </script> |
src/packages/components/external/Informations/Mores/OverrideILoadConfigurationframe/help.ts
0 → 100644
1 | + | ||
2 | +export enum ScadaModeEnum { | ||
3 | + LIGHTBOX = 'lightbox', | ||
4 | + DESIGN = 'design', | ||
5 | + SHARE = 'share', | ||
6 | +} | ||
7 | + | ||
8 | +export enum Platform { | ||
9 | + PHONE = 'phone', | ||
10 | + PC = 'pc', | ||
11 | +} | ||
12 | + | ||
13 | +interface ScadaLinkParamsType { | ||
14 | + configurationId: string; | ||
15 | + organizationId: string; | ||
16 | + mode: ScadaModeEnum; | ||
17 | + platform: Platform; | ||
18 | + publicId?: string; | ||
19 | +} | ||
20 | + | ||
21 | +const getRandomString = () => Number(Math.random().toString().substring(2)).toString(36); | ||
22 | + | ||
23 | +export const encode = (record: Recordable) => { | ||
24 | + let hash = JSON.stringify(record); | ||
25 | + const mixinString = getRandomString() | ||
26 | + .slice(0, 10) | ||
27 | + .padEnd(10, getRandomString()) | ||
28 | + .split('') | ||
29 | + .map((item) => (Math.random() > 0.5 ? item.toUpperCase() : item)) | ||
30 | + .join(''); | ||
31 | + hash = window.btoa(hash); | ||
32 | + hash = hash.substring(0, 6) + mixinString + hash.substring(6); | ||
33 | + hash = window.btoa(hash); | ||
34 | + return hash; | ||
35 | +}; | ||
36 | + | ||
37 | + | ||
38 | +export const createScadaPageLink = ( | ||
39 | + record: Partial<Record<'id' | 'organizationId' | 'platform' | 'publicId', string>>, | ||
40 | + mode: ScadaModeEnum = ScadaModeEnum.DESIGN, | ||
41 | + open = true | ||
42 | +) => { | ||
43 | + const params: ScadaLinkParamsType = { | ||
44 | + configurationId: record.id!, | ||
45 | + organizationId: record.organizationId!, | ||
46 | + mode: mode, | ||
47 | + platform: record.platform as Platform, | ||
48 | + }; | ||
49 | + | ||
50 | + if (mode === ScadaModeEnum.SHARE) { | ||
51 | + params.publicId = record.publicId; | ||
52 | + } | ||
53 | + | ||
54 | + const href = new URL(location.origin); | ||
55 | + href.pathname = '/thingskit-scada'; | ||
56 | + href.hash = encode(params); | ||
57 | + open && window.open(href.href); | ||
58 | + return href.href; | ||
59 | +}; |
1 | <template> | 1 | <template> |
2 | - <div | ||
3 | - @mouseenter="handleMouseenter" | ||
4 | - @mouseleave="handleMouseleave" | ||
5 | - class="iframe-content" | ||
6 | - :style="getStyle(borderRadius)" | ||
7 | - > | 2 | + <div @mouseenter="handleMouseenter" @mouseleave="handleMouseleave" class="iframe-content" |
3 | + :style="getStyle(borderRadius)"> | ||
8 | <div v-show="isShowSvg" @click="handleFullScreen" id="fullscreenButton"> | 4 | <div v-show="isShowSvg" @click="handleFullScreen" id="fullscreenButton"> |
9 | - <svg | ||
10 | - focusable="false" | ||
11 | - data-icon="fullscreen" | ||
12 | - width="4vw" | ||
13 | - :style="`color:${color}`" | ||
14 | - height="4vh" | ||
15 | - fill="currentColor" | ||
16 | - aria-hidden="true" | ||
17 | - viewBox="64 64 896 896" | ||
18 | - > | 5 | + <svg focusable="false" data-icon="fullscreen" width="4vw" :style="`color:${color}`" height="4vh" fill="currentColor" |
6 | + aria-hidden="true" viewBox="64 64 896 896"> | ||
19 | <path | 7 | <path |
20 | - d="M290 236.4l43.9-43.9a8.01 8.01 0 00-4.7-13.6L169 160c-5.1-.6-9.5 3.7-8.9 8.9L179 329.1c.8 6.6 8.9 9.4 13.6 4.7l43.7-43.7L370 423.7c3.1 3.1 8.2 3.1 11.3 0l42.4-42.3c3.1-3.1 3.1-8.2 0-11.3L290 236.4zm352.7 187.3c3.1 3.1 8.2 3.1 11.3 0l133.7-133.6 43.7 43.7a8.01 8.01 0 0013.6-4.7L863.9 169c.6-5.1-3.7-9.5-8.9-8.9L694.8 179c-6.6.8-9.4 8.9-4.7 13.6l43.9 43.9L600.3 370a8.03 8.03 0 000 11.3l42.4 42.4zM845 694.9c-.8-6.6-8.9-9.4-13.6-4.7l-43.7 43.7L654 600.3a8.03 8.03 0 00-11.3 0l-42.4 42.3a8.03 8.03 0 000 11.3L734 787.6l-43.9 43.9a8.01 8.01 0 004.7 13.6L855 864c5.1.6 9.5-3.7 8.9-8.9L845 694.9zm-463.7-94.6a8.03 8.03 0 00-11.3 0L236.3 733.9l-43.7-43.7a8.01 8.01 0 00-13.6 4.7L160.1 855c-.6 5.1 3.7 9.5 8.9 8.9L329.2 845c6.6-.8 9.4-8.9 4.7-13.6L290 787.6 423.7 654c3.1-3.1 3.1-8.2 0-11.3l-42.4-42.4z" | ||
21 | - ></path> | 8 | + d="M290 236.4l43.9-43.9a8.01 8.01 0 00-4.7-13.6L169 160c-5.1-.6-9.5 3.7-8.9 8.9L179 329.1c.8 6.6 8.9 9.4 13.6 4.7l43.7-43.7L370 423.7c3.1 3.1 8.2 3.1 11.3 0l42.4-42.3c3.1-3.1 3.1-8.2 0-11.3L290 236.4zm352.7 187.3c3.1 3.1 8.2 3.1 11.3 0l133.7-133.6 43.7 43.7a8.01 8.01 0 0013.6-4.7L863.9 169c.6-5.1-3.7-9.5-8.9-8.9L694.8 179c-6.6.8-9.4 8.9-4.7 13.6l43.9 43.9L600.3 370a8.03 8.03 0 000 11.3l42.4 42.4zM845 694.9c-.8-6.6-8.9-9.4-13.6-4.7l-43.7 43.7L654 600.3a8.03 8.03 0 00-11.3 0l-42.4 42.3a8.03 8.03 0 000 11.3L734 787.6l-43.9 43.9a8.01 8.01 0 004.7 13.6L855 864c5.1.6 9.5-3.7 8.9-8.9L845 694.9zm-463.7-94.6a8.03 8.03 0 00-11.3 0L236.3 733.9l-43.7-43.7a8.01 8.01 0 00-13.6 4.7L160.1 855c-.6 5.1 3.7 9.5 8.9 8.9L329.2 845c6.6-.8 9.4-8.9 4.7-13.6L290 787.6 423.7 654c3.1-3.1 3.1-8.2 0-11.3l-42.4-42.4z"> |
9 | + </path> | ||
22 | </svg> | 10 | </svg> |
23 | </div> | 11 | </div> |
24 | - <iframe id="iframeContent" :src="option.dataset" :width="w" :height="h" style="border-width: 0"></iframe> | 12 | + <iframe id="iframeContent" :src="iframeLink" :width="w" :height="h" style="border-width: 0"></iframe> |
25 | </div> | 13 | </div> |
26 | </template> | 14 | </template> |
27 | 15 | ||
@@ -32,6 +20,8 @@ import { CreateComponentType } from '@/packages/index.d' | @@ -32,6 +20,8 @@ import { CreateComponentType } from '@/packages/index.d' | ||
32 | import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore' | 20 | import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore' |
33 | import { useFullScreen } from '@/packages/components/external/Charts/utls/fullScreen' | 21 | import { useFullScreen } from '@/packages/components/external/Charts/utls/fullScreen' |
34 | import { isDevMode } from '@/utils/external/env' | 22 | import { isDevMode } from '@/utils/external/env' |
23 | +import { createScadaPageLink, ScadaModeEnum } from './help' | ||
24 | +import { option as typeOption } from './config' | ||
35 | 25 | ||
36 | const props = defineProps({ | 26 | const props = defineProps({ |
37 | chartConfig: { | 27 | chartConfig: { |
@@ -60,16 +50,14 @@ const getStyle = (radius: number) => { | @@ -60,16 +50,14 @@ const getStyle = (radius: number) => { | ||
60 | 50 | ||
61 | const isDev = isDevMode() | 51 | const isDev = isDevMode() |
62 | 52 | ||
53 | +const iframeLink = ref('') | ||
54 | + | ||
63 | // 编辑更新 | 55 | // 编辑更新 |
64 | watch( | 56 | watch( |
65 | () => props.chartConfig.option.dataset, | 57 | () => props.chartConfig.option.dataset, |
66 | (newData: string) => { | 58 | (newData: string) => { |
67 | - const currentHost = window.location.host | ||
68 | - const currentProtocol = window.location.protocol | ||
69 | - //预览 | ||
70 | - option.dataset = `${currentProtocol}//${currentHost}/thingskit-scada/${ | ||
71 | - isDev ? '?dev=1&' : '?' | ||
72 | - }configurationId=${newData}&lightbox=1` | 59 | + const { dataset, publicId, organizationId, platform, isShare } = props.chartConfig.option as typeof typeOption |
60 | + iframeLink.value = createScadaPageLink({ id: dataset, platform, publicId, organizationId, }, isShare ? ScadaModeEnum.SHARE : ScadaModeEnum.LIGHTBOX, false) | ||
73 | }, | 61 | }, |
74 | { | 62 | { |
75 | immediate: true | 63 | immediate: true |