Commit 7daa5ae3cb782cbadd115552c8ef06d70d0516fe
Merge branch 'fix/configuration-component' into 'main_dev'
fix: 修复重构组态后组态链接生成方式变更 See merge request yunteng/thingskit-view!144
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 |