Commit 7daa5ae3cb782cbadd115552c8ef06d70d0516fe

Authored by xp.Huang
2 parents 0076f20b 42f2cc9d

Merge branch 'fix/configuration-component' into 'main_dev'

fix: 修复重构组态后组态链接生成方式变更

See merge request yunteng/thingskit-view!144
1 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 5 enum Api {
5 6 GET_DICT = '/dict_item',
... ... @@ -54,7 +55,7 @@ export const getPlatformInfo = () => defHttp.get({ url: Api.PLATFORM })
54 55
55 56 //获取组态列表
56 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 146 url: `${Api.DEVICE_ATTR}/${deviceProfileId}`,
146 147 params: { dataType },
147 148 });
148   -};
\ No newline at end of file
  149 +};
... ...
... ... @@ -23,4 +23,34 @@ export interface OrganizationListItem {
23 23 name: string;
24 24 parentId?: string;
25 25 remark: string;
26   -}
\ No newline at end of file
  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 3 import {chartInitConfig} from '@/settings/designSetting'
4 4 import {OverrideILoadConfigurationframeConfig} from './index'
5 5 import cloneDeep from 'lodash/cloneDeep'
  6 +import { Platform } from './help'
6 7
7 8 export const enum shareEnum {
8 9 PRIVATE_VIEW = "PRIVATE_VIEW",
  10 + PUBLIC_VIEW = 'PUBLIC_VIEW'
9 11 }
10 12
11 13 export const option = {
12 14 // 网站路径
13 15 dataset: '',
  16 + organizationId: '',
  17 + platform: Platform.PC,
  18 + publicId: '' as (undefined | string),
14 19 // 圆角
15 20 borderRadius: 10,
16 21 pages: {
... ...
... ... @@ -3,24 +3,19 @@
3 3 <setting-item-box name="路径" :alone="true">
4 4 <setting-item name="请选择要加载的组态">
5 5 <n-select label-in-value @change="handleUpdateValue" filterable size="small" v-model:value="optionData.dataset"
6   - :options="configurationOptions"/>
  6 + :options="configurationOptions" />
7 7 </setting-item>
8 8 </setting-item-box>
9 9 <setting-item-box name="是否公开">
10 10 <setting-item>
11 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 13 </div>
14 14 </setting-item>
15 15 </setting-item-box>
16 16 <setting-item-box name="样式">
17 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 19 </setting-item>
25 20 </setting-item-box>
26 21 <setting-item-box name="分页">
... ... @@ -28,13 +23,8 @@
28 23 <n-input-number v-model:value="optionData.pages.page" size="small" :min="1" placeholder="页码"></n-input-number>
29 24 </setting-item>
30 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 28 </setting-item>
39 29 </setting-item-box>
40 30 <setting-item-box name="颜色" :alone="true">
... ... @@ -49,11 +39,12 @@
49 39 </template>
50 40
51 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 49 const props = defineProps({
59 50 optionData: {
... ... @@ -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 58 const configurationId = ref('')
68 59
69 60 const getConfigurationOptions = async (params: object) => {
70   - const {items} = await getConfigurationList(params)
  61 + const { items } = await getConfigurationList(params)
71 62 if (items) {
72   - configurationOptions.value = items.map((item: SelectOption) => ({
  63 + configurationOptions.value = items.map((item) => ({
73 64 label: item.name,
74 65 value: item.id,
75   - viewType: item.viewType
  66 + ...item
76 67 }))
77 68 }
78 69 }
79 70
80 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 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 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 92 const handleChange = async (value: boolean) => {
... ... @@ -108,7 +95,7 @@ const handleChange = async (value: boolean) => {
108 95 })
109 96 if (res) {
110 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 101 </script>
... ...
  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 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 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 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 10 </svg>
23 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 13 </div>
26 14 </template>
27 15
... ... @@ -32,6 +20,8 @@ import { CreateComponentType } from '@/packages/index.d'
32 20 import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
33 21 import { useFullScreen } from '@/packages/components/external/Charts/utls/fullScreen'
34 22 import { isDevMode } from '@/utils/external/env'
  23 +import { createScadaPageLink, ScadaModeEnum } from './help'
  24 +import { option as typeOption } from './config'
35 25
36 26 const props = defineProps({
37 27 chartConfig: {
... ... @@ -60,16 +50,14 @@ const getStyle = (radius: number) => {
60 50
61 51 const isDev = isDevMode()
62 52
  53 +const iframeLink = ref('')
  54 +
63 55 // 编辑更新
64 56 watch(
65 57 () => props.chartConfig.option.dataset,
66 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 63 immediate: true
... ...