Commit 055fb44c1f650e3bbf74716eca7a908d7dcc6bd4

Authored by ww
2 parents c75b2494 36bebfb5

Merge branch 'main_dev' into feat/rule-engine-designer

Showing 142 changed files with 2161 additions and 471 deletions
@@ -127,6 +127,9 @@ export interface MasterDeviceList { @@ -127,6 +127,9 @@ export interface MasterDeviceList {
127 label?: string; 127 label?: string;
128 value?: string; 128 value?: string;
129 alias?: string; 129 alias?: string;
  130 + codeType?: string;
  131 + code?: string;
  132 + [key: string]: string | undefined;
130 } 133 }
131 134
132 export interface ComponentInfoDetail { 135 export interface ComponentInfoDetail {
@@ -167,6 +167,7 @@ export interface DeviceRecord { @@ -167,6 +167,7 @@ export interface DeviceRecord {
167 creator: string; 167 creator: string;
168 createTime: string; 168 createTime: string;
169 codeType?: string; 169 codeType?: string;
  170 + code?: string;
170 name: string; 171 name: string;
171 tenantId: string; 172 tenantId: string;
172 transportType: string; 173 transportType: string;
@@ -16,6 +16,7 @@ @@ -16,6 +16,7 @@
16 :formProps="getProps" 16 :formProps="getProps"
17 :allDefaultValues="defaultValueRef" 17 :allDefaultValues="defaultValueRef"
18 :formModel="formModel" 18 :formModel="formModel"
  19 + :validateFields="validateFields"
19 :setFormModel="setFormModel" 20 :setFormModel="setFormModel"
20 > 21 >
21 <template #[item]="data" v-for="item in Object.keys($slots)"> 22 <template #[item]="data" v-for="item in Object.keys($slots)">
@@ -229,10 +230,10 @@ @@ -229,10 +230,10 @@
229 230
230 function setFormModel(key: string, value: any) { 231 function setFormModel(key: string, value: any) {
231 formModel[key] = value; 232 formModel[key] = value;
232 - const { validateTrigger } = unref(getBindValue);  
233 - if (!validateTrigger || validateTrigger === 'change') {  
234 - validateFields([key]).catch((_) => {});  
235 - } 233 + // const { validateTrigger } = unref(getBindValue);
  234 + // if (!validateTrigger || validateTrigger === 'change') {
  235 + // validateFields([key]).catch((_) => {});
  236 + // }
236 } 237 }
237 238
238 function handleEnterPress(e: KeyboardEvent) { 239 function handleEnterPress(e: KeyboardEvent) {
@@ -14,6 +14,7 @@ @@ -14,6 +14,7 @@
14 import { upperFirst, cloneDeep } from 'lodash-es'; 14 import { upperFirst, cloneDeep } from 'lodash-es';
15 import { useItemLabelWidth } from '../hooks/useLabelWidth'; 15 import { useItemLabelWidth } from '../hooks/useLabelWidth';
16 import { useI18n } from '/@/hooks/web/useI18n'; 16 import { useI18n } from '/@/hooks/web/useI18n';
  17 + import { NamePath, ValidateOptions } from 'ant-design-vue/lib/form/interface';
17 18
18 export default defineComponent({ 19 export default defineComponent({
19 name: 'BasicFormItem', 20 name: 'BasicFormItem',
@@ -39,6 +40,12 @@ @@ -39,6 +40,12 @@
39 type: Function as PropType<(key: string, value: any) => void>, 40 type: Function as PropType<(key: string, value: any) => void>,
40 default: null, 41 default: null,
41 }, 42 },
  43 + validateFields: {
  44 + type: Function as PropType<
  45 + (nameList?: NamePath[], options?: ValidateOptions) => Promise<any>
  46 + >,
  47 + default: null,
  48 + },
42 tableAction: { 49 tableAction: {
43 type: Object as PropType<TableActionType>, 50 type: Object as PropType<TableActionType>,
44 }, 51 },
@@ -208,6 +215,7 @@ @@ -208,6 +215,7 @@
208 rules[characterInx].message || 215 rules[characterInx].message ||
209 t('component.form.maxTip', [rules[characterInx].max] as Recordable); 216 t('component.form.maxTip', [rules[characterInx].max] as Recordable);
210 } 217 }
  218 + rules.forEach((item) => !item.trigger && (item.trigger = 'change'));
211 return rules; 219 return rules;
212 } 220 }
213 221
@@ -234,6 +242,10 @@ @@ -234,6 +242,10 @@
234 const value = target ? (isCheck ? target.checked : target.value) : e; 242 const value = target ? (isCheck ? target.checked : target.value) : e;
235 props.setFormModel(field, value); 243 props.setFormModel(field, value);
236 }, 244 },
  245 + onBlur: (...args) => {
  246 + unref(getComponentsProps)?.onBlur?.(...args);
  247 + props.validateFields([field], { triggerName: 'blur' }).catch((_) => {});
  248 + },
237 }; 249 };
238 const Comp = componentMap.get(component) as ReturnType<typeof defineComponent>; 250 const Comp = componentMap.get(component) as ReturnType<typeof defineComponent>;
239 251
1 <script lang="ts" setup> 1 <script lang="ts" setup>
2 import { Button } from 'ant-design-vue'; 2 import { Button } from 'ant-design-vue';
3 - import { nextTick, ref, unref, watch } from 'vue'; 3 + import { nextTick, ref, watch } from 'vue';
4 import { BasicForm, useForm } from '/@/components/Form'; 4 import { BasicForm, useForm } from '/@/components/Form';
5 import { BasicModal } from '/@/components/Modal'; 5 import { BasicModal } from '/@/components/Modal';
6 import { PlusCircleOutlined } from '@ant-design/icons-vue'; 6 import { PlusCircleOutlined } from '@ant-design/icons-vue';
@@ -19,8 +19,6 @@ @@ -19,8 +19,6 @@
19 } 19 }
20 ); 20 );
21 21
22 - const dataType = ref(props.dataType); //获取数据类型  
23 -  
24 const emit = defineEmits(['update:value']); 22 const emit = defineEmits(['update:value']);
25 23
26 const [ 24 const [
@@ -46,15 +44,17 @@ @@ -46,15 +44,17 @@
46 show.value = false; 44 show.value = false;
47 }; 45 };
48 46
49 - watch(  
50 - () => props.dataType,  
51 - (value) => {  
52 - dataType.value = value; 47 + watch(show, async (value) => {
  48 + if (value) {
  49 + await nextTick();
53 updateSchema([ 50 updateSchema([
54 - { field: FormFieldsEnum.ZOOM_FACTOR, ifShow: unref(dataType) == 'BOOL' ? false : true }, 51 + {
  52 + field: FormFieldsEnum.ZOOM_FACTOR,
  53 + ifShow: props.dataType == DataTypeEnum.IS_BOOL ? false : true,
  54 + },
55 ]); 55 ]);
56 } 56 }
57 - ); 57 + });
58 58
59 watch( 59 watch(
60 () => props.value, 60 () => props.value,
1 import type { FormProps, FormActionType, UseFormReturnType, FormSchema } from '../types/form'; 1 import type { FormProps, FormActionType, UseFormReturnType, FormSchema } from '../types/form';
2 -import type { NamePath } from 'ant-design-vue/lib/form/interface'; 2 +import type { NamePath, ValidateOptions } from 'ant-design-vue/lib/form/interface';
3 import type { DynamicProps } from '/#/utils'; 3 import type { DynamicProps } from '/#/utils';
4 import { ref, onUnmounted, unref, nextTick, watch } from 'vue'; 4 import { ref, onUnmounted, unref, nextTick, watch } from 'vue';
5 import { isProdMode } from '/@/utils/env'; 5 import { isProdMode } from '/@/utils/env';
@@ -112,9 +112,12 @@ export function useForm(props?: Props): UseFormReturnType { @@ -112,9 +112,12 @@ export function useForm(props?: Props): UseFormReturnType {
112 return form.validate(nameList); 112 return form.validate(nameList);
113 }, 113 },
114 114
115 - validateFields: async (nameList?: NamePath[]): Promise<Recordable> => { 115 + validateFields: async (
  116 + nameList?: NamePath[],
  117 + options?: ValidateOptions
  118 + ): Promise<Recordable> => {
116 const form = await getForm(); 119 const form = await getForm();
117 - return form.validateFields(nameList); 120 + return form.validateFields(nameList, options);
118 }, 121 },
119 }; 122 };
120 123
1 import type { ComputedRef, Ref } from 'vue'; 1 import type { ComputedRef, Ref } from 'vue';
2 import type { FormProps, FormSchema, FormActionType } from '../types/form'; 2 import type { FormProps, FormSchema, FormActionType } from '../types/form';
3 -import type { NamePath } from 'ant-design-vue/lib/form/interface'; 3 +import type { NamePath, ValidateOptions } from 'ant-design-vue/lib/form/interface';
4 import { unref, toRaw } from 'vue'; 4 import { unref, toRaw } from 'vue';
5 import { isArray, isFunction, isObject, isString } from '/@/utils/is'; 5 import { isArray, isFunction, isObject, isString } from '/@/utils/is';
6 import { deepMerge } from '/@/utils'; 6 import { deepMerge } from '/@/utils';
@@ -206,8 +206,8 @@ export function useFormEvents({ @@ -206,8 +206,8 @@ export function useFormEvents({
206 }); 206 });
207 } 207 }
208 208
209 - async function validateFields(nameList?: NamePath[] | undefined) {  
210 - return unref(formElRef)?.validateFields(nameList); 209 + async function validateFields(nameList?: NamePath[] | undefined, options?: ValidateOptions) {
  210 + return unref(formElRef)?.validateFields(nameList, options);
211 } 211 }
212 212
213 async function validate(nameList?: NamePath[] | undefined) { 213 async function validate(nameList?: NamePath[] | undefined) {
1 -import type { NamePath, RuleObject } from 'ant-design-vue/lib/form/interface'; 1 +import type { NamePath, RuleObject, ValidateOptions } from 'ant-design-vue/lib/form/interface';
2 import type { VNode } from 'vue'; 2 import type { VNode } from 'vue';
3 import type { ButtonProps as AntdButtonProps } from '/@/components/Button'; 3 import type { ButtonProps as AntdButtonProps } from '/@/components/Button';
4 import type { FormItem } from './formItem'; 4 import type { FormItem } from './formItem';
@@ -39,7 +39,7 @@ export interface FormActionType { @@ -39,7 +39,7 @@ export interface FormActionType {
39 prefixField: string | undefined, 39 prefixField: string | undefined,
40 first?: boolean | undefined 40 first?: boolean | undefined
41 ) => Promise<void>; 41 ) => Promise<void>;
42 - validateFields: (nameList?: NamePath[]) => Promise<any>; 42 + validateFields: (nameList?: NamePath[], options?: ValidateOptions) => Promise<any>;
43 validate: (nameList?: NamePath[]) => Promise<any>; 43 validate: (nameList?: NamePath[]) => Promise<any>;
44 scrollToField: (name: NamePath, options?: ScrollOptions) => Promise<void>; 44 scrollToField: (name: NamePath, options?: ScrollOptions) => Promise<void>;
45 } 45 }
@@ -33,6 +33,7 @@ @@ -33,6 +33,7 @@
33 import { openWindow } from '/@/utils'; 33 import { openWindow } from '/@/utils';
34 34
35 import { useOpenKeys } from './useOpenKeys'; 35 import { useOpenKeys } from './useOpenKeys';
  36 + import { useMenuActiveFix } from '/@/hooks/business/useMenuActiveFix';
36 export default defineComponent({ 37 export default defineComponent({
37 name: 'SimpleMenu', 38 name: 'SimpleMenu',
38 components: { 39 components: {
@@ -120,7 +121,9 @@ @@ -120,7 +121,9 @@
120 isClickGo.value = false; 121 isClickGo.value = false;
121 return; 122 return;
122 } 123 }
123 - const path = (route || unref(currentRoute)).path; 124 +
  125 + let { flag, path } = useMenuActiveFix(route || unref(currentRoute));
  126 + path = flag ? path : (route || unref(currentRoute)).path;
124 127
125 menuState.activeName = path; 128 menuState.activeName = path;
126 129
@@ -29,7 +29,6 @@ export function useOpenKeys( @@ -29,7 +29,6 @@ export function useOpenKeys(
29 return; 29 return;
30 } 30 }
31 const keys = getAllParentPath(menuList, path); 31 const keys = getAllParentPath(menuList, path);
32 -  
33 if (!unref(accordion)) { 32 if (!unref(accordion)) {
34 menuState.openNames = uniq([...menuState.openNames, ...keys]); 33 menuState.openNames = uniq([...menuState.openNames, ...keys]);
35 } else { 34 } else {
@@ -48,6 +48,7 @@ @@ -48,6 +48,7 @@
48 'update:value', 48 'update:value',
49 'change', 49 'change',
50 'check', 50 'check',
  51 + 'unSelectAll',
51 'update:searchValue', 52 'update:searchValue',
52 ], 53 ],
53 setup(props, { attrs, slots, emit, expose }) { 54 setup(props, { attrs, slots, emit, expose }) {
@@ -188,6 +189,7 @@ @@ -188,6 +189,7 @@
188 } 189 }
189 190
190 function checkAll(checkAll: boolean) { 191 function checkAll(checkAll: boolean) {
  192 + if (!checkAll) emit('unSelectAll');
191 state.checkedKeys = checkAll ? getEnabledKeys() : ([] as Keys); 193 state.checkedKeys = checkAll ? getEnabledKeys() : ([] as Keys);
192 } 194 }
193 195
@@ -2,17 +2,23 @@ @@ -2,17 +2,23 @@
2 import { isNumber } from 'lodash'; 2 import { isNumber } from 'lodash';
3 import videoJs, { VideoJsPlayer, VideoJsPlayerOptions } from 'video.js'; 3 import videoJs, { VideoJsPlayer, VideoJsPlayerOptions } from 'video.js';
4 import 'video.js/dist/video-js.css'; 4 import 'video.js/dist/video-js.css';
5 - import { computed, CSSProperties, onMounted, onUnmounted, ref, unref } from 'vue'; 5 + import { computed, CSSProperties, onMounted, onUnmounted, ref, toRaw, unref } from 'vue';
6 import { useDesign } from '/@/hooks/web/useDesign'; 6 import { useDesign } from '/@/hooks/web/useDesign';
7 import { getJwtToken, getShareJwtToken } from '/@/utils/auth'; 7 import { getJwtToken, getShareJwtToken } from '/@/utils/auth';
8 import { isShareMode } from '/@/views/sys/share/hook'; 8 import { isShareMode } from '/@/views/sys/share/hook';
9 import 'videojs-flvjs-es6'; 9 import 'videojs-flvjs-es6';
10 const { prefixCls } = useDesign('basic-video-play'); 10 const { prefixCls } = useDesign('basic-video-play');
11 11
12 - const props = defineProps<{  
13 - options?: VideoJsPlayerOptions;  
14 - withToken?: boolean;  
15 - }>(); 12 + const props = withDefaults(
  13 + defineProps<{
  14 + options?: VideoJsPlayerOptions;
  15 + withToken?: boolean;
  16 + immediateInitOnMounted?: boolean;
  17 + }>(),
  18 + {
  19 + immediateInitOnMounted: true,
  20 + }
  21 + );
16 22
17 const emit = defineEmits<{ 23 const emit = defineEmits<{
18 (event: 'ready', instance?: Nullable<VideoJsPlayer>): void; 24 (event: 'ready', instance?: Nullable<VideoJsPlayer>): void;
@@ -68,8 +74,18 @@ @@ -68,8 +74,18 @@
68 }); 74 });
69 }; 75 };
70 76
  77 + const customInit = (getOptionsFn: (optios: VideoJsPlayerOptions) => VideoJsPlayerOptions) => {
  78 + return (videoPlayInstance.value = videoJs(
  79 + unref(videoPlayEl)!,
  80 + getOptionsFn(toRaw(unref(getOptions))),
  81 + () => {
  82 + emit('ready', unref(videoPlayInstance));
  83 + }
  84 + ));
  85 + };
  86 +
71 onMounted(() => { 87 onMounted(() => {
72 - init(); 88 + props.immediateInitOnMounted && init();
73 }); 89 });
74 90
75 onUnmounted(() => { 91 onUnmounted(() => {
@@ -79,6 +95,7 @@ @@ -79,6 +95,7 @@
79 }); 95 });
80 96
81 defineExpose({ 97 defineExpose({
  98 + customInit,
82 reloadPlayer: init, 99 reloadPlayer: init,
83 getInstance: () => unref(videoPlayInstance), 100 getInstance: () => unref(videoPlayInstance),
84 }); 101 });
  1 +import { RouteLocationNormalizedLoaded } from 'vue-router';
  2 +
  3 +const menuMap = new Map();
  4 +
  5 +menuMap.set('/visual/board/detail/:boardId/:boardName?', '/visual/board');
  6 +
  7 +export const useMenuActiveFix = (route: RouteLocationNormalizedLoaded) => {
  8 + let flag = false;
  9 + let path;
  10 +
  11 + const matchPath = route.matched.map((item) => item.path);
  12 + const needFixMenus: string[] = Array.from(menuMap.keys());
  13 +
  14 + for (const item of matchPath) {
  15 + for (const menu of needFixMenus) {
  16 + if (menu === item) {
  17 + flag = true;
  18 + path = menuMap.get(menu);
  19 + break;
  20 + }
  21 + }
  22 + }
  23 +
  24 + return {
  25 + flag,
  26 + path,
  27 + };
  28 +};
@@ -54,10 +54,11 @@ @@ -54,10 +54,11 @@
54 field: FiledKey.WEBSITE, 54 field: FiledKey.WEBSITE,
55 label: handleDecode(t('routes.aboutSoftware.websiteLabel')), 55 label: handleDecode(t('routes.aboutSoftware.websiteLabel')),
56 render: (val: string) => { 56 render: (val: string) => {
  57 + let joinWww = val.substring(0, 8) + 'www.' + val.substring(8);
57 return h( 58 return h(
58 'span', 59 'span',
59 - { class: 'text-blue-500 cursor-pointer', onClick: () => open(val) },  
60 - val 60 + { class: 'text-blue-500 cursor-pointer', onClick: () => open(joinWww) },
  61 + joinWww
61 ); 62 );
62 }, 63 },
63 }, 64 },
@@ -19,6 +19,7 @@ @@ -19,6 +19,7 @@
19 import { useRootSetting } from '/@/hooks/setting/useRootSetting'; 19 import { useRootSetting } from '/@/hooks/setting/useRootSetting';
20 import { useAppInject } from '/@/hooks/web/useAppInject'; 20 import { useAppInject } from '/@/hooks/web/useAppInject';
21 import { useDesign } from '/@/hooks/web/useDesign'; 21 import { useDesign } from '/@/hooks/web/useDesign';
  22 + import { OUTSIDE_LINK_PREFIX } from '/@/router/helper/routeHelper';
22 23
23 export default defineComponent({ 24 export default defineComponent({
24 name: 'LayoutMenu', 25 name: 'LayoutMenu',
@@ -113,6 +114,11 @@ @@ -113,6 +114,11 @@
113 */ 114 */
114 115
115 function handleMenuClick(path: string) { 116 function handleMenuClick(path: string) {
  117 + if (path.startsWith(OUTSIDE_LINK_PREFIX)) {
  118 + path = path.replace(OUTSIDE_LINK_PREFIX, '');
  119 + window.open(path);
  120 + return;
  121 + }
116 go(path); 122 go(path);
117 } 123 }
118 124
@@ -183,7 +189,6 @@ @@ -183,7 +189,6 @@
183 padding: 10px 4px 10px 10px; 189 padding: 10px 4px 10px 10px;
184 190
185 img { 191 img {
186 - width: @logo-width;  
187 height: @logo-width; 192 height: @logo-width;
188 } 193 }
189 } 194 }
@@ -6,6 +6,7 @@ import { cloneDeep, omit } from 'lodash-es'; @@ -6,6 +6,7 @@ import { cloneDeep, omit } from 'lodash-es';
6 import { warn } from '/@/utils/log'; 6 import { warn } from '/@/utils/log';
7 import { createRouter, createWebHashHistory } from 'vue-router'; 7 import { createRouter, createWebHashHistory } from 'vue-router';
8 8
  9 +export const OUTSIDE_LINK_PREFIX = '/outside/link';
9 export type LayoutMapKey = 'LAYOUT'; 10 export type LayoutMapKey = 'LAYOUT';
10 const IFRAME = () => import('/@/views/sys/iframe/FrameBlank.vue'); 11 const IFRAME = () => import('/@/views/sys/iframe/FrameBlank.vue');
11 12
@@ -81,6 +82,9 @@ export function transformObjToRoute<T = AppRouteModule>(routeList: AppRouteModul @@ -81,6 +82,9 @@ export function transformObjToRoute<T = AppRouteModule>(routeList: AppRouteModul
81 route.meta = meta; 82 route.meta = meta;
82 } 83 }
83 } 84 }
  85 + if (!route.path.startsWith('/') && route.meta.isLink) {
  86 + route.path = `${OUTSIDE_LINK_PREFIX}${route.path}`;
  87 + }
84 route.children && asyncImportRoute(route.children); 88 route.children && asyncImportRoute(route.children);
85 }); 89 });
86 return routeList as unknown as T[]; 90 return routeList as unknown as T[];
@@ -16,6 +16,7 @@ @@ -16,6 +16,7 @@
16 mode="multiple" 16 mode="multiple"
17 v-model:value="model[field]" 17 v-model:value="model[field]"
18 :options="alarmContactOptions.map((item) => ({ value: item.value, label: item.label }))" 18 :options="alarmContactOptions.map((item) => ({ value: item.value, label: item.label }))"
  19 + @change="handleChange"
19 > 20 >
20 <template #dropdownRender="{ menuNode: menu }"> 21 <template #dropdownRender="{ menuNode: menu }">
21 <v-nodes :vnodes="menu" /> 22 <v-nodes :vnodes="menu" />
@@ -82,6 +83,7 @@ @@ -82,6 +83,7 @@
82 const [registerAlarmContactDrawer, { openDrawer }] = useDrawer(); 83 const [registerAlarmContactDrawer, { openDrawer }] = useDrawer();
83 async function handleSuccess() { 84 async function handleSuccess() {
84 //获取告警联系人 85 //获取告警联系人
  86 + if (!unref(orgId)) return;
85 const res = await byOrgIdGetAlarmContact(orgId.value); 87 const res = await byOrgIdGetAlarmContact(orgId.value);
86 if (res) { 88 if (res) {
87 alarmContactOptions.value = res.map((m) => { 89 alarmContactOptions.value = res.map((m) => {
@@ -91,6 +93,10 @@ @@ -91,6 +93,10 @@
91 alarmContactOptions.value = []; 93 alarmContactOptions.value = [];
92 } 94 }
93 } 95 }
  96 +
  97 + const handleChange = () => {
  98 + validateFields(['alarmContactId']);
  99 + };
94 // 新增或编辑 100 // 新增或编辑
95 const handleOpenAlarmContact = () => { 101 const handleOpenAlarmContact = () => {
96 openDrawer(true, { 102 openDrawer(true, {
@@ -100,7 +106,10 @@ @@ -100,7 +106,10 @@
100 const isUpdate = ref(true); 106 const isUpdate = ref(true);
101 let allData: any = reactive({}); 107 let allData: any = reactive({});
102 const editId = ref(''); 108 const editId = ref('');
103 - const [registerForm, { validate, setFieldsValue, resetFields, updateSchema }] = useForm({ 109 + const [
  110 + registerForm,
  111 + { validate, setFieldsValue, resetFields, updateSchema, validateFields },
  112 + ] = useForm({
104 labelWidth: 120, 113 labelWidth: 120,
105 schemas: formSchema, 114 schemas: formSchema,
106 showActionButtonGroup: false, 115 showActionButtonGroup: false,
@@ -191,6 +200,7 @@ @@ -191,6 +200,7 @@
191 handleOpenAlarmContact, 200 handleOpenAlarmContact,
192 registerAlarmContactDrawer, 201 registerAlarmContactDrawer,
193 handleSuccess, 202 handleSuccess,
  203 + handleChange,
194 }; 204 };
195 }, 205 },
196 }); 206 });
@@ -37,13 +37,21 @@ @@ -37,13 +37,21 @@
37 </a-button> 37 </a-button>
38 </template> 38 </template>
39 <template #status="{ record }"> 39 <template #status="{ record }">
40 - <Switch  
41 - :checked="record.status === 1"  
42 - :loading="record.pendingStatus"  
43 - checkedChildren="启用"  
44 - unCheckedChildren="禁用"  
45 - @change="(checked:boolean)=>statusChange(checked,record)"  
46 - /> 40 + <Authority value="api:yt:alarm:profile:status">
  41 + <Switch
  42 + :checked="record.status === 1"
  43 + :loading="record.pendingStatus"
  44 + checkedChildren="启用"
  45 + unCheckedChildren="禁用"
  46 + @change="(checked:boolean)=>statusChange(checked,record)"
  47 + />
  48 + </Authority>
  49 + <Tag
  50 + v-if="!hasPermission('api:yt:alarm:profile:status')"
  51 + :color="record.status ? 'green' : 'red'"
  52 + >
  53 + {{ record.status ? '启用' : '禁用' }}
  54 + </Tag>
47 </template> 55 </template>
48 <template #action="{ record }"> 56 <template #action="{ record }">
49 <TableAction 57 <TableAction
@@ -88,7 +96,7 @@ @@ -88,7 +96,7 @@
88 import { useResetOrganizationTree, OrganizationIdTree } from '/@/views/common/organizationIdTree'; 96 import { useResetOrganizationTree, OrganizationIdTree } from '/@/views/common/organizationIdTree';
89 import { deleteAlarmConfig, queryAlarmConfig } from '/@/api/alarm/config/alarmConfig'; 97 import { deleteAlarmConfig, queryAlarmConfig } from '/@/api/alarm/config/alarmConfig';
90 import { searchFormSchema, columns } from './config.data'; 98 import { searchFormSchema, columns } from './config.data';
91 - import { Modal, Popconfirm } from 'ant-design-vue'; 99 + import { Modal, Popconfirm, Tag } from 'ant-design-vue';
92 import { JsonPreview } from '/@/components/CodeEditor'; 100 import { JsonPreview } from '/@/components/CodeEditor';
93 import { findDictItemByCode } from '/@/api/system/dict'; 101 import { findDictItemByCode } from '/@/api/system/dict';
94 import { alarmContactGetPage } from '/@/api/device/deviceConfigApi'; 102 import { alarmContactGetPage } from '/@/api/device/deviceConfigApi';
@@ -97,6 +105,7 @@ @@ -97,6 +105,7 @@
97 import { putAlarmConfigStatus } from '/@/api/alarm/config/alarmConfig'; 105 import { putAlarmConfigStatus } from '/@/api/alarm/config/alarmConfig';
98 import { useMessage } from '/@/hooks/web/useMessage'; 106 import { useMessage } from '/@/hooks/web/useMessage';
99 import { Authority } from '/@/components/Authority'; 107 import { Authority } from '/@/components/Authority';
  108 + import { usePermission } from '/@/hooks/web/usePermission';
100 109
101 export default defineComponent({ 110 export default defineComponent({
102 components: { 111 components: {
@@ -108,8 +117,10 @@ @@ -108,8 +117,10 @@
108 Switch, 117 Switch,
109 Authority, 118 Authority,
110 Popconfirm, 119 Popconfirm,
  120 + Tag,
111 }, 121 },
112 setup() { 122 setup() {
  123 + const { hasPermission } = usePermission();
113 const searchInfo = reactive<Recordable>({}); 124 const searchInfo = reactive<Recordable>({});
114 const { organizationIdTreeRef, resetFn } = useResetOrganizationTree(searchInfo); 125 const { organizationIdTreeRef, resetFn } = useResetOrganizationTree(searchInfo);
115 // 刷新 126 // 刷新
@@ -250,6 +261,7 @@ @@ -250,6 +261,7 @@
250 showAlarmContact, 261 showAlarmContact,
251 showMessageMode, 262 showMessageMode,
252 statusChange, 263 statusChange,
  264 + hasPermission,
253 }; 265 };
254 }, 266 },
255 }); 267 });
@@ -17,10 +17,21 @@ export enum ConfigurationPermission { @@ -17,10 +17,21 @@ export enum ConfigurationPermission {
17 UPDATE = 'api:yt:dataview:center:update', 17 UPDATE = 'api:yt:dataview:center:update',
18 DELETE = 'api:yt:dataview:center:delete', 18 DELETE = 'api:yt:dataview:center:delete',
19 SHARE = 'api:yt:dataview:center:share', 19 SHARE = 'api:yt:dataview:center:share',
20 - DESIGN = 'api:yt:dataview:center:get_configuration_info:design', 20 + // DESIGN = 'api:yt:dataview:center:get_configuration_info:design',
  21 + DESIGN = 'api:yt:dataview:center:get_dataview_info:design',
21 PREVIEW = 'api:yt:dataview:center:get_configuration_info:preview', 22 PREVIEW = 'api:yt:dataview:center:get_configuration_info:preview',
22 PUBLISH = 'api:yt:dataview:center:publish', 23 PUBLISH = 'api:yt:dataview:center:publish',
23 // CANCEL_PUBLISH = 'api:yt:dataview:center:cancel_publish', 24 // CANCEL_PUBLISH = 'api:yt:dataview:center:cancel_publish',
  25 + PUBLISH_INTERFACE = 'api:yt:dataview:center:public_interface',
  26 +}
  27 +
  28 +export enum PublicInterface {
  29 + CREATE = 'api:yt:dataview:center:public_interface:post',
  30 + LIST = 'api:yt:dataview:center:public_interface:list',
  31 + UPDATE = 'api:yt:dataview:center:public_interface:update',
  32 + DELETE = 'api:yt:dataview:center:public_interface:delete',
  33 + PUBLISH = 'api:yt:dataview:center:public_interface:publish',
  34 + CANCEL_PUBLISH = 'api:yt:dataview:center:public_interface:cancel',
24 } 35 }
25 36
26 // 查询字段 37 // 查询字段
@@ -218,7 +218,10 @@ @@ -218,7 +218,10 @@
218 <Authority v-if="!isCustomerUser" :value="ConfigurationPermission.CREATE"> 218 <Authority v-if="!isCustomerUser" :value="ConfigurationPermission.CREATE">
219 <Button type="primary" @click="handleCreateOrUpdate()"> 新增大屏 </Button> 219 <Button type="primary" @click="handleCreateOrUpdate()"> 新增大屏 </Button>
220 </Authority> 220 </Authority>
221 - <Authority v-if="hasPublicInterfacePermission" :value="ConfigurationPermission.CREATE"> 221 + <Authority
  222 + v-if="hasPublicInterfacePermission"
  223 + :value="ConfigurationPermission.PUBLISH_INTERFACE"
  224 + >
222 <Button type="primary" @click="handleCreateOrUpdatePublicApi()">公共接口管理</Button> 225 <Button type="primary" @click="handleCreateOrUpdatePublicApi()">公共接口管理</Button>
223 </Authority> 226 </Authority>
224 <CardLayoutButton v-model:value="listColumn" @change="handleCardLayoutChange" /> 227 <CardLayoutButton v-model:value="listColumn" @change="handleCardLayoutChange" />
@@ -280,6 +283,7 @@ @@ -280,6 +283,7 @@
280 </Tooltip> 283 </Tooltip>
281 <Tooltip v-if="!isCustomerUser" title="设计"> 284 <Tooltip v-if="!isCustomerUser" title="设计">
282 <AuthIcon 285 <AuthIcon
  286 + :auth="ConfigurationPermission.DESIGN"
283 :disabled="item.state === 1" 287 :disabled="item.state === 1"
284 icon="ant-design:edit-outlined" 288 icon="ant-design:edit-outlined"
285 @click="handleDesign(item)" 289 @click="handleDesign(item)"
@@ -9,23 +9,30 @@ @@ -9,23 +9,30 @@
9 <a-button type="link" class="ml-2" @click="handleRecordContent(record)"> 查看 </a-button> 9 <a-button type="link" class="ml-2" @click="handleRecordContent(record)"> 查看 </a-button>
10 </template> 10 </template>
11 <template #toolbar> 11 <template #toolbar>
12 - <a-button type="primary" @click="handleCreateOrEdit(null)"> 新增公共接口 </a-button>  
13 - <Popconfirm  
14 - title="您确定要批量删除数据"  
15 - ok-text="确定"  
16 - cancel-text="取消"  
17 - @confirm="handleDeleteOrBatchDelete(null)"  
18 - >  
19 - <a-button color="error" :disabled="hasBatchDelete"> 批量删除 </a-button>  
20 - </Popconfirm>  
21 - <Popconfirm  
22 - title="您确定要批量发布"  
23 - ok-text="确定"  
24 - cancel-text="取消"  
25 - @confirm="handleBatchPublish('batchPublish')"  
26 - >  
27 - <a-button color="error" :disabled="hasBatchPublish"> 批量发布 </a-button>  
28 - </Popconfirm> 12 + <Authority :value="PublicInterface.CREATE">
  13 + <a-button type="primary" @click="handleCreateOrEdit(null)"> 新增公共接口 </a-button>
  14 + </Authority>
  15 +
  16 + <Authority :value="PublicInterface.DELETE">
  17 + <Popconfirm
  18 + title="您确定要批量删除数据"
  19 + ok-text="确定"
  20 + cancel-text="取消"
  21 + @confirm="handleDeleteOrBatchDelete(null)"
  22 + >
  23 + <a-button color="error" :disabled="hasBatchDelete"> 批量删除 </a-button>
  24 + </Popconfirm>
  25 + </Authority>
  26 + <Authority :value="PublicInterface.PUBLISH">
  27 + <Popconfirm
  28 + title="您确定要批量发布"
  29 + ok-text="确定"
  30 + cancel-text="取消"
  31 + @confirm="handleBatchPublish('batchPublish')"
  32 + >
  33 + <a-button color="error" :disabled="hasBatchPublish"> 批量发布 </a-button>
  34 + </Popconfirm>
  35 + </Authority>
29 <!-- <Popconfirm 36 <!-- <Popconfirm
30 title="您确定要批量取消发布" 37 title="您确定要批量取消发布"
31 ok-text="确定" 38 ok-text="确定"
@@ -41,6 +48,7 @@ @@ -41,6 +48,7 @@
41 { 48 {
42 label: '发布', 49 label: '发布',
43 icon: 'ant-design:node-expand-outlined', 50 icon: 'ant-design:node-expand-outlined',
  51 + auth: PublicInterface.PUBLISH,
44 onClick: handlePublish.bind(null, 'publish', record), 52 onClick: handlePublish.bind(null, 'publish', record),
45 ifShow: () => { 53 ifShow: () => {
46 return record.state === 0 && record.creator === userId; 54 return record.state === 0 && record.creator === userId;
@@ -49,6 +57,7 @@ @@ -49,6 +57,7 @@
49 { 57 {
50 label: '取消发布', 58 label: '取消发布',
51 icon: 'ant-design:node-collapse-outlined', 59 icon: 'ant-design:node-collapse-outlined',
  60 + auth: PublicInterface.CANCEL_PUBLISH,
52 onClick: handlePublish.bind(null, 'canelPublish', record), 61 onClick: handlePublish.bind(null, 'canelPublish', record),
53 ifShow: () => { 62 ifShow: () => {
54 return record.state === 1 && record.creator === userId; 63 return record.state === 1 && record.creator === userId;
@@ -57,6 +66,7 @@ @@ -57,6 +66,7 @@
57 { 66 {
58 label: '修改', 67 label: '修改',
59 icon: 'clarity:note-edit-line', 68 icon: 'clarity:note-edit-line',
  69 + auth: PublicInterface.UPDATE,
60 onClick: handleCreateOrEdit.bind(null, record), 70 onClick: handleCreateOrEdit.bind(null, record),
61 ifShow: () => { 71 ifShow: () => {
62 return record.state === 0 && record.creator === userId; 72 return record.state === 0 && record.creator === userId;
@@ -65,6 +75,7 @@ @@ -65,6 +75,7 @@
65 { 75 {
66 label: '删除', 76 label: '删除',
67 icon: 'ant-design:delete-outlined', 77 icon: 'ant-design:delete-outlined',
  78 + auth: PublicInterface.DELETE,
68 color: 'error', 79 color: 'error',
69 ifShow: () => { 80 ifShow: () => {
70 return record.state === 0 && record.creator === userId; 81 return record.state === 0 && record.creator === userId;
@@ -99,6 +110,8 @@ @@ -99,6 +110,8 @@
99 import { useMessage } from '/@/hooks/web/useMessage'; 110 import { useMessage } from '/@/hooks/web/useMessage';
100 import { USER_INFO_KEY } from '/@/enums/cacheEnum'; 111 import { USER_INFO_KEY } from '/@/enums/cacheEnum';
101 import { getAuthCache } from '/@/utils/auth'; 112 import { getAuthCache } from '/@/utils/auth';
  113 + import { PublicInterface } from '../config';
  114 + import { Authority } from '/@/components/Authority';
102 115
103 const userInfo = getAuthCache(USER_INFO_KEY) as any; 116 const userInfo = getAuthCache(USER_INFO_KEY) as any;
104 117
@@ -119,7 +132,7 @@ @@ -119,7 +132,7 @@
119 }, 132 },
120 useSearchForm: true, 133 useSearchForm: true,
121 actionColumn: { 134 actionColumn: {
122 - width: 150, 135 + width: 180,
123 title: '操作', 136 title: '操作',
124 dataIndex: 'action', 137 dataIndex: 'action',
125 slots: { customRender: 'action' }, 138 slots: { customRender: 'action' },
@@ -125,23 +125,25 @@ export const step1Schemas: FormSchema[] = [ @@ -125,23 +125,25 @@ export const step1Schemas: FormSchema[] = [
125 dynamicRules({ values }) { 125 dynamicRules({ values }) {
126 return [ 126 return [
127 { 127 {
128 - required:  
129 - (values?.transportType === TransportTypeEnum.TCP &&  
130 - values?.deviceType === DeviceTypeEnum.SENSOR) ||  
131 - values?.deviceType === DeviceTypeEnum.GATEWAY, 128 + required: values?.transportType === TransportTypeEnum.TCP,
132 message: '请输入设备标识符', 129 message: '请输入设备标识符',
133 }, 130 },
134 ]; 131 ];
135 }, 132 },
136 - ifShow: ({ values }) =>  
137 - values?.transportType === TransportTypeEnum.TCP &&  
138 - (values.deviceType === DeviceTypeEnum.SENSOR || values.deviceType === DeviceTypeEnum.GATEWAY),  
139 - componentProps: ({}) => { 133 + // ifShow: ({ values }) =>
  134 + // values?.transportType === TransportTypeEnum.TCP &&
  135 + // (values.deviceType === DeviceTypeEnum.SENSOR || values.deviceType === DeviceTypeEnum.GATEWAY),
  136 + ifShow: ({ values }) => values?.transportType === TransportTypeEnum.TCP,
  137 + componentProps: ({ formActionType }) => {
  138 + const { setFieldsValue } = formActionType;
140 return { 139 return {
141 options: [ 140 options: [
142 { label: '自定义', value: TaskTypeEnum.CUSTOM }, 141 { label: '自定义', value: TaskTypeEnum.CUSTOM },
143 { label: 'ModBus', value: TaskTypeEnum.MODBUS_RTU }, 142 { label: 'ModBus', value: TaskTypeEnum.MODBUS_RTU },
144 ], 143 ],
  144 + onChange() {
  145 + setFieldsValue({ addressCode: null });
  146 + },
145 }; 147 };
146 }, 148 },
147 }, 149 },
@@ -167,11 +169,17 @@ export const step1Schemas: FormSchema[] = [ @@ -167,11 +169,17 @@ export const step1Schemas: FormSchema[] = [
167 minValue: 0, 169 minValue: 0,
168 disabledSwitch: true, 170 disabledSwitch: true,
169 }, 171 },
  172 + // ifShow: ({ values }) => {
  173 + // return (
  174 + // values?.transportType === TransportTypeEnum.TCP &&
  175 + // (values.deviceType === DeviceTypeEnum.SENSOR ||
  176 + // values.deviceType === DeviceTypeEnum.GATEWAY) &&
  177 + // values?.codeType === TaskTypeEnum.MODBUS_RTU
  178 + // );
  179 + // },
170 ifShow: ({ values }) => { 180 ifShow: ({ values }) => {
171 return ( 181 return (
172 values?.transportType === TransportTypeEnum.TCP && 182 values?.transportType === TransportTypeEnum.TCP &&
173 - (values.deviceType === DeviceTypeEnum.SENSOR ||  
174 - values.deviceType === DeviceTypeEnum.GATEWAY) &&  
175 values?.codeType === TaskTypeEnum.MODBUS_RTU 183 values?.codeType === TaskTypeEnum.MODBUS_RTU
176 ); 184 );
177 }, 185 },
@@ -43,7 +43,9 @@ export const descSchema = (emit: EmitType): DescItem[] => { @@ -43,7 +43,9 @@ export const descSchema = (emit: EmitType): DescItem[] => {
43 type: 'link', 43 type: 'link',
44 style: { padding: 0 }, 44 style: { padding: 0 },
45 onClick: () => 45 onClick: () =>
46 - !isCustomer ? go(PageEnum.DEVICE_PROFILE + '?name=' + String(val)) : '', 46 + !isCustomer
  47 + ? go(PageEnum.DEVICE_PROFILE + '?name=' + encodeURIComponent(String(val)))
  48 + : '',
47 }, 49 },
48 { default: () => val } 50 { default: () => val }
49 ); 51 );
@@ -167,12 +169,12 @@ export const alarmColumns: BasicColumn[] = [ @@ -167,12 +169,12 @@ export const alarmColumns: BasicColumn[] = [
167 { 169 {
168 title: '告警时间', 170 title: '告警时间',
169 dataIndex: 'createdTime', 171 dataIndex: 'createdTime',
170 - width: 120, 172 + width: 180,
171 }, 173 },
172 { 174 {
173 title: '告警设备', 175 title: '告警设备',
174 dataIndex: 'deviceName', 176 dataIndex: 'deviceName',
175 - width: 100, 177 + width: 120,
176 }, 178 },
177 { 179 {
178 title: '告警场景', 180 title: '告警场景',
@@ -182,14 +184,20 @@ export const alarmColumns: BasicColumn[] = [ @@ -182,14 +184,20 @@ export const alarmColumns: BasicColumn[] = [
182 { 184 {
183 title: '告警级别', 185 title: '告警级别',
184 dataIndex: 'severity', 186 dataIndex: 'severity',
185 - width: 160, 187 + width: 90,
186 format: (text) => alarmLevel(text), 188 format: (text) => alarmLevel(text),
187 }, 189 },
188 { 190 {
  191 + title: '告警详情',
  192 + dataIndex: 'details',
  193 + slots: { customRender: 'details' },
  194 + width: 160,
  195 + },
  196 + {
189 title: '状态', 197 title: '状态',
190 dataIndex: 'status', 198 dataIndex: 'status',
191 format: (text) => statusType(text), 199 format: (text) => statusType(text),
192 - width: 160, 200 + width: 100,
193 }, 201 },
194 ]; 202 ];
195 203
@@ -261,14 +269,6 @@ export const alarmSchemasForm: FormSchema[] = [ @@ -261,14 +269,6 @@ export const alarmSchemasForm: FormSchema[] = [
261 disabled: true, 269 disabled: true,
262 }, 270 },
263 }, 271 },
264 - {  
265 - field: 'details',  
266 - label: '详情',  
267 - component: 'InputTextArea',  
268 - componentProps: {  
269 - maxLength: 255,  
270 - },  
271 - },  
272 ]; 272 ];
273 // 子设备 273 // 子设备
274 export const childDeviceSchemas: FormSchema[] = [ 274 export const childDeviceSchemas: FormSchema[] = [
@@ -54,10 +54,6 @@ @@ -54,10 +54,6 @@
54 await resetFields(); 54 await resetFields();
55 await setFieldsValue({ 55 await setFieldsValue({
56 ...data, 56 ...data,
57 - details: JSON.stringify(data?.details?.data).slice(  
58 - 1,  
59 - JSON.stringify(data?.details?.data).length - 1  
60 - ),  
61 severity: alarmLevel(data.severity), 57 severity: alarmLevel(data.severity),
62 status: statusType(data.status), 58 status: statusType(data.status),
63 }); 59 });
@@ -145,6 +145,8 @@ @@ -145,6 +145,8 @@
145 // !!!此处需要删除地图的属性,否则会报堆栈溢出的错误 Uncaught RangeError: Maximum call stack size exceeded 145 // !!!此处需要删除地图的属性,否则会报堆栈溢出的错误 Uncaught RangeError: Maximum call stack size exceeded
146 Reflect.deleteProperty(DeviceStep1Ref.value.positionState, 'map'); 146 Reflect.deleteProperty(DeviceStep1Ref.value.positionState, 'map');
147 Reflect.deleteProperty(DeviceStep1Ref.value.positionState, 'marker'); 147 Reflect.deleteProperty(DeviceStep1Ref.value.positionState, 'marker');
  148 + Reflect.deleteProperty(DeviceStep1Ref.value.devicePositionState, 'map');
  149 + Reflect.deleteProperty(DeviceStep1Ref.value.devicePositionState, 'marker');
148 setModalProps({ 150 setModalProps({
149 confirmLoading: true, 151 confirmLoading: true,
150 }); 152 });
@@ -156,7 +158,7 @@ @@ -156,7 +158,7 @@
156 customerId: currentDeviceData.customerId, 158 customerId: currentDeviceData.customerId,
157 deviceInfo: { 159 deviceInfo: {
158 avatar: DeviceStep1Ref.value?.devicePic, 160 avatar: DeviceStep1Ref.value?.devicePic,
159 - ...DeviceStep1Ref.value?.positionState, 161 + ...DeviceStep1Ref.value?.devicePositionState,
160 }, 162 },
161 }; 163 };
162 validateNameLength(stepRecord.name); 164 validateNameLength(stepRecord.name);
@@ -168,7 +170,7 @@ @@ -168,7 +170,7 @@
168 sn: stepRecord.name, 170 sn: stepRecord.name,
169 deviceInfo: { 171 deviceInfo: {
170 avatar: DeviceStep1Ref.value?.devicePic, 172 avatar: DeviceStep1Ref.value?.devicePic,
171 - ...DeviceStep1Ref.value?.positionState, 173 + ...DeviceStep1Ref.value?.devicePositionState,
172 }, 174 },
173 deviceToken: 175 deviceToken:
174 unref(current) === 0 || !unref(stepState).addAgree 176 unref(current) === 0 || !unref(stepState).addAgree
@@ -46,7 +46,7 @@ @@ -46,7 +46,7 @@
46 </div> 46 </div>
47 </template> 47 </template>
48 <template #deviceAddress> 48 <template #deviceAddress>
49 - <Input disabled v-model:value="positionState.address"> 49 + <Input disabled v-model:value="devicePositionState.address">
50 <template #addonAfter> 50 <template #addonAfter>
51 <EnvironmentTwoTone @click="selectPosition" /> 51 <EnvironmentTwoTone @click="selectPosition" />
52 </template> 52 </template>
@@ -128,6 +128,7 @@ @@ -128,6 +128,7 @@
128 import { useDrawer } from '/@/components/Drawer'; 128 import { useDrawer } from '/@/components/Drawer';
129 import DeptDrawer from '/@/views/system/organization/OrganizationDrawer.vue'; 129 import DeptDrawer from '/@/views/system/organization/OrganizationDrawer.vue';
130 import { TaskTypeEnum } from '/@/views/task/center/config'; 130 import { TaskTypeEnum } from '/@/views/task/center/config';
  131 + import { toRaw } from 'vue';
131 132
132 export default defineComponent({ 133 export default defineComponent({
133 components: { 134 components: {
@@ -239,8 +240,14 @@ @@ -239,8 +240,14 @@
239 const selectPosition = () => { 240 const selectPosition = () => {
240 visible.value = true; 241 visible.value = true;
241 if (!positionState.longitude) { 242 if (!positionState.longitude) {
242 - positionState.longitude = '104.04666605565338';  
243 - positionState.latitude = '30.543516387560476'; 243 + positionState.longitude = '104.05326410962411';
  244 + positionState.latitude = '30.54855093076791';
  245 +
  246 + // 根据经纬度获取详细位置
  247 + if (positionState.longitude && positionState.latitude) {
  248 + var pt = new BMap.Point(positionState.longitude, positionState.latitude);
  249 + getAddrByPoint(pt);
  250 + }
244 initMap(positionState.longitude, positionState.latitude); 251 initMap(positionState.longitude, positionState.latitude);
245 } else { 252 } else {
246 initMap(positionState.longitude, positionState.latitude); 253 initMap(positionState.longitude, positionState.latitude);
@@ -261,6 +268,15 @@ @@ -261,6 +268,15 @@
261 map: null, 268 map: null,
262 marker: null, 269 marker: null,
263 }); 270 });
  271 +
  272 + const devicePositionState = ref({
  273 + longitude: '',
  274 + latitude: '',
  275 + address: '',
  276 + map: null,
  277 + marker: null,
  278 + });
  279 +
264 /** 280 /**
265 * 逆地址解析函数(根据坐标点获取详细地址) 281 * 逆地址解析函数(根据坐标点获取详细地址)
266 * @param {Object} point 百度地图坐标点,必传 282 * @param {Object} point 百度地图坐标点,必传
@@ -371,6 +387,7 @@ @@ -371,6 +387,7 @@
371 // 确定选择的位置 387 // 确定选择的位置
372 const handleOk = () => { 388 const handleOk = () => {
373 visible.value = false; 389 visible.value = false;
  390 + devicePositionState.value = { ...toRaw(positionState) };
374 }; 391 };
375 // 取消选择位置 392 // 取消选择位置
376 const handleCancel = () => { 393 const handleCancel = () => {
@@ -385,6 +402,7 @@ @@ -385,6 +402,7 @@
385 positionState.longitude = deviceInfo.longitude; 402 positionState.longitude = deviceInfo.longitude;
386 positionState.latitude = deviceInfo.latitude; 403 positionState.latitude = deviceInfo.latitude;
387 positionState.address = deviceInfo.address; 404 positionState.address = deviceInfo.address;
  405 + devicePositionState.value = { ...toRaw(positionState) };
388 devicePic.value = deviceInfo.avatar; 406 devicePic.value = deviceInfo.avatar;
389 setFieldsValue({ 407 setFieldsValue({
390 ...data, 408 ...data,
@@ -418,11 +436,13 @@ @@ -418,11 +436,13 @@
418 function parentResetDevicePic(deviceInfo) { 436 function parentResetDevicePic(deviceInfo) {
419 devicePic.value = deviceInfo.avatar; 437 devicePic.value = deviceInfo.avatar;
420 } 438 }
  439 +
421 // 父组件重置位置 440 // 父组件重置位置
422 function parentResetPositionState() { 441 function parentResetPositionState() {
423 for (let key in positionState) { 442 for (let key in positionState) {
424 positionState[key] = ''; 443 positionState[key] = '';
425 } 444 }
  445 + devicePositionState.value = { ...toRaw(positionState) };
426 } 446 }
427 // 禁用设备类型 447 // 禁用设备类型
428 function disabledDeviceType(disabled: boolean) { 448 function disabledDeviceType(disabled: boolean) {
@@ -474,6 +494,7 @@ @@ -474,6 +494,7 @@
474 handleOpenOrgDrawer, 494 handleOpenOrgDrawer,
475 handleSuccess, 495 handleSuccess,
476 handleTreeOrg, 496 handleTreeOrg,
  497 + devicePositionState,
477 }; 498 };
478 }, 499 },
479 }); 500 });
@@ -12,17 +12,31 @@ @@ -12,17 +12,31 @@
12 ]" 12 ]"
13 /> 13 />
14 </template> 14 </template>
  15 + <template #details="{ record }">
  16 + <a-button type="link" class="ml-2" @click="handleViewAlarmDetails(record)">
  17 + 查看告警详情
  18 + </a-button>
  19 + </template>
15 </BasicTable> 20 </BasicTable>
16 <AlarmDetailModal @register="registerDetailModal" @success="handleSuccess" /> 21 <AlarmDetailModal @register="registerDetailModal" @success="handleSuccess" />
17 </div> 22 </div>
18 </template> 23 </template>
19 <script lang="ts"> 24 <script lang="ts">
20 - import { defineComponent } from 'vue'; 25 + import { defineComponent, h, nextTick } from 'vue';
21 import { BasicTable, useTable, TableAction } from '/@/components/Table'; 26 import { BasicTable, useTable, TableAction } from '/@/components/Table';
22 import { alarmColumns, alarmSearchSchemas } from '../../config/detail.config'; 27 import { alarmColumns, alarmSearchSchemas } from '../../config/detail.config';
23 import { getDeviceAlarm } from '/@/api/device/deviceManager'; 28 import { getDeviceAlarm } from '/@/api/device/deviceManager';
24 import AlarmDetailModal from '../modal/AlarmDetailModal.vue'; 29 import AlarmDetailModal from '../modal/AlarmDetailModal.vue';
25 import { useModal } from '/@/components/Modal'; 30 import { useModal } from '/@/components/Modal';
  31 + import { Modal } from 'ant-design-vue';
  32 + import { JsonPreview } from '/@/components/CodeEditor';
  33 + import { getDeviceDetail } from '/@/api/device/deviceManager';
  34 + import { getAttribute } from '/@/api/ruleengine/ruleengineApi';
  35 + import {
  36 + operationNumber_OR_TIME,
  37 + operationString,
  38 + operationBoolean,
  39 + } from '/@/views/rule/linkedge/config/formatData';
26 export default defineComponent({ 40 export default defineComponent({
27 name: 'DeviceManagement', 41 name: 'DeviceManagement',
28 components: { 42 components: {
@@ -66,11 +80,86 @@ @@ -66,11 +80,86 @@
66 const handleSuccess = () => { 80 const handleSuccess = () => {
67 reload(); 81 reload();
68 }; 82 };
  83 + const handleViewAlarmDetails = async (record: Recordable) => {
  84 + await nextTick();
  85 + const { details } = record;
  86 + const deviceIdKeys = Object.keys(details);
  87 + const detailObject = deviceIdKeys.map((key) => ({ label: key, value: details[key] }));
  88 + const dataFormat = await handleAlarmDetailFormat(deviceIdKeys);
  89 + console.log(detailObject, dataFormat, 'dataFormat');
  90 + const dataFormats = detailObject.reduce((acc: any, curr: any) => {
  91 + dataFormat.forEach((item) => {
  92 + if (item.tbDeviceId === curr.label) {
  93 + const findName = item.attribute.find(
  94 + (item) => item.identifier === curr.value.key
  95 + )?.name;
  96 + const findLogin = [
  97 + ...operationNumber_OR_TIME,
  98 + ...operationString,
  99 + ...operationBoolean,
  100 + ].find((item) => item.value === curr.value.logic)?.symbol;
  101 + const findAttribute = item.attribute.find(
  102 + (findItem) => findItem.identifier === curr.value.key
  103 + );
  104 + const value = {
  105 + ['触发属性']: findName,
  106 + ['触发条件']: `${findLogin}${curr.value.logicValue}`,
  107 + ['触发值']: `${curr.value.realValue}${findAttribute.detail?.dataType?.specs?.unit?.key}`,
  108 + };
  109 + const data = {
  110 + [item.name]: value,
  111 + };
  112 + acc.push(data);
  113 + }
  114 + });
  115 + return [...acc];
  116 + }, []);
  117 + const objectFormat = dataFormats.reduce((acc: any, curr: any) => {
  118 + return {
  119 + ...acc,
  120 + ...curr,
  121 + };
  122 + }, {});
  123 + Modal.info({
  124 + title: '告警详情',
  125 + width: 600,
  126 + centered: true,
  127 + maskClosable: true,
  128 + content: h(JsonPreview, { data: JSON.parse(JSON.stringify(objectFormat)) }),
  129 + });
  130 + };
  131 + const handleAlarmDetailFormat = async (keys: string[]) => {
  132 + const temp: any = [];
  133 + for (let item of keys) {
  134 + if (item === 'key' || item === 'data') return []; //旧数据则终止
  135 + const deviceDetailRes = await getDeviceDetail(item);
  136 + const { deviceProfileId } = deviceDetailRes;
  137 + if (!deviceProfileId) return [];
  138 + const attributeRes = await getAttribute(deviceProfileId);
  139 + const dataFormat: any = handleDataFormat(deviceDetailRes, attributeRes);
  140 + temp.push(dataFormat);
  141 + }
  142 + return temp;
  143 + };
  144 + const handleDataFormat = (deviceDetail: any, attributes: any) => {
  145 + const { name, tbDeviceId } = deviceDetail;
  146 + const attribute = attributes.map((item) => ({
  147 + identifier: item.identifier,
  148 + name: item.name,
  149 + detail: item.detail,
  150 + }));
  151 + return {
  152 + name,
  153 + tbDeviceId,
  154 + attribute,
  155 + };
  156 + };
69 return { 157 return {
70 registerTable, 158 registerTable,
71 registerDetailModal, 159 registerDetailModal,
72 handleDetail, 160 handleDetail,
73 handleSuccess, 161 handleSuccess,
  162 + handleViewAlarmDetails,
74 }; 163 };
75 }, 164 },
76 }); 165 });
@@ -52,7 +52,9 @@ @@ -52,7 +52,9 @@
52 <div class="mt-4" v-if="!isCustomer"> 52 <div class="mt-4" v-if="!isCustomer">
53 <a-button type="primary" class="mr-4" @click="copyTbDeviceId">复制设备ID</a-button> 53 <a-button type="primary" class="mr-4" @click="copyTbDeviceId">复制设备ID</a-button>
54 <a-button type="primary" class="mr-4" @click="copyDeviceToken">复制访问令牌</a-button> 54 <a-button type="primary" class="mr-4" @click="copyDeviceToken">复制访问令牌</a-button>
55 - <a-button type="primary" class="mr-4" @click="manageDeviceToken">管理设备凭证</a-button> 55 + <Authority value="api:yt:device:equipment">
  56 + <a-button type="primary" class="mr-4" @click="manageDeviceToken">管理设备凭证</a-button>
  57 + </Authority>
56 <ManageDeviceTokenModal @register="registerModal" /> 58 <ManageDeviceTokenModal @register="registerModal" />
57 </div> 59 </div>
58 <div class="mt-4"> 60 <div class="mt-4">
@@ -84,10 +86,10 @@ @@ -84,10 +86,10 @@
84 import { DeviceTypeEnum } from '/@/api/device/model/deviceModel'; 86 import { DeviceTypeEnum } from '/@/api/device/model/deviceModel';
85 import { useAuthDeviceDetail } from '../../hook/useAuthDeviceDetail'; 87 import { useAuthDeviceDetail } from '../../hook/useAuthDeviceDetail';
86 import { useClipboard } from '@vueuse/core'; 88 import { useClipboard } from '@vueuse/core';
87 -  
88 import wz from '/@/assets/images/wz.png'; 89 import wz from '/@/assets/images/wz.png';
89 import { useAsyncQueue } from '../../../localtion/useAsyncQueue'; 90 import { useAsyncQueue } from '../../../localtion/useAsyncQueue';
90 import locationImage from '/@/assets/icons/location.svg'; 91 import locationImage from '/@/assets/icons/location.svg';
  92 + import { Authority } from '/@/components/Authority';
91 93
92 export default defineComponent({ 94 export default defineComponent({
93 components: { 95 components: {
@@ -98,6 +100,7 @@ @@ -98,6 +100,7 @@
98 BasicModal, 100 BasicModal,
99 Tooltip, 101 Tooltip,
100 Empty, 102 Empty,
  103 + Authority,
101 }, 104 },
102 props: { 105 props: {
103 deviceDetail: { 106 deviceDetail: {
@@ -72,7 +72,7 @@ export const formSchemas: FormSchema[] = [ @@ -72,7 +72,7 @@ export const formSchemas: FormSchema[] = [
72 }, 72 },
73 { 73 {
74 field: 'eventType', 74 field: 'eventType',
75 - label: '告警类型', 75 + label: '事件类型',
76 component: 'ApiSelect', 76 component: 'ApiSelect',
77 componentProps: { 77 componentProps: {
78 placeholder: '请选择事件类型', 78 placeholder: '请选择事件类型',
@@ -167,6 +167,7 @@ @@ -167,6 +167,7 @@
167 mode.value = value; 167 mode.value = value;
168 await nextTick(); 168 await nextTick();
169 setTableData(socketInfo.originData); 169 setTableData(socketInfo.originData);
  170 + socketInfo.dataSource = socketInfo.originData;
170 }; 171 };
171 172
172 const { createMessage } = useMessage(); 173 const { createMessage } = useMessage();
@@ -315,10 +316,10 @@ @@ -315,10 +316,10 @@
315 <ModeSwitchButton v-model:value="mode" @change="switchMode" /> 316 <ModeSwitchButton v-model:value="mode" @change="switchMode" />
316 </div> 317 </div>
317 <List 318 <List
318 - v-if="mode === EnumTableCardMode.CARD" 319 + v-show="mode === EnumTableCardMode.CARD"
319 ref="listElRef" 320 ref="listElRef"
320 class="list-mode !px-2" 321 class="list-mode !px-2"
321 - :data-source="socketInfo.originData" 322 + :data-source="socketInfo.dataSource"
322 :grid="grid" 323 :grid="grid"
323 :pagination="pagination" 324 :pagination="pagination"
324 > 325 >
@@ -129,17 +129,20 @@ const SingleToHexBatch = (t) => { @@ -129,17 +129,20 @@ const SingleToHexBatch = (t) => {
129 129
130 const formSchemasConfig = (schemas, actionType): FormSchema[] => { 130 const formSchemasConfig = (schemas, actionType): FormSchema[] => {
131 const { identifier, functionName } = schemas; 131 const { identifier, functionName } = schemas;
132 - console.log(identifier, 'identifier', actionType, 'actionType');  
133 if (actionType == '06') { 132 if (actionType == '06') {
134 return [ 133 return [
135 { 134 {
136 field: identifier, 135 field: identifier,
137 label: functionName, 136 label: functionName,
138 component: 'InputNumber', 137 component: 'InputNumber',
139 - rules: [{ required: true, message: '请输入' }], 138 + rules: [{ required: true, message: '请输入正数' }],
140 componentProps: { 139 componentProps: {
141 - precision: 0,  
142 - placeholder: `请输入整数`, 140 + min: 0,
  141 + formatter: (e) => {
  142 + const value = `${e}`.replace('-', '').replace(/^(-)*(\d+)\.(\d\d).*$/, '$1$2.$3');
  143 + return value;
  144 + },
  145 + placeholder: `请输入正数`,
143 }, 146 },
144 }, 147 },
145 ]; 148 ];
@@ -166,7 +169,7 @@ const formSchemasConfig = (schemas, actionType): FormSchema[] => { @@ -166,7 +169,7 @@ const formSchemasConfig = (schemas, actionType): FormSchema[] => {
166 component: 'InputNumber', 169 component: 'InputNumber',
167 rules: [{ required: true, message: '请输入值' }], 170 rules: [{ required: true, message: '请输入值' }],
168 componentProps: { 171 componentProps: {
169 - placeholder: `请输入`, 172 + placeholder: `请输入数字`,
170 formatter: (e) => 173 formatter: (e) =>
171 `${e}`.replace(/\B(?=(\d{3})+(?!\d))/g, '').replace(/^(-)*(\d+)\.(\d\d).*$/, '$1$2.$3'), 174 `${e}`.replace(/\B(?=(\d{3})+(?!\d))/g, '').replace(/^(-)*(\d+)\.(\d\d).*$/, '$1$2.$3'),
172 }, 175 },
@@ -39,10 +39,9 @@ @@ -39,10 +39,9 @@
39 const { name, detail, identifier, deviceDetail, extensionDesc } = record; 39 const { name, detail, identifier, deviceDetail, extensionDesc } = record;
40 const { dataType } = detail; 40 const { dataType } = detail;
41 const { type } = dataType || {}; 41 const { type } = dataType || {};
42 - const { codeType, deviceProfile } = deviceDetail || {}; 42 + const { codeType, deviceProfile, code } = deviceDetail || {};
43 const { transportType } = deviceProfile || {}; 43 const { transportType } = deviceProfile || {};
44 const { registerAddress, actionType, zoomFactor } = extensionDesc || {}; //获取扩展描述内容 44 const { registerAddress, actionType, zoomFactor } = extensionDesc || {}; //获取扩展描述内容
45 -  
46 formField.value = identifier; 45 formField.value = identifier;
47 zoomFactorValue.value = zoomFactor ? Number(zoomFactor) : 1; 46 zoomFactorValue.value = zoomFactor ? Number(zoomFactor) : 1;
48 isShowMultiply.value = type == 'INT' || type == 'DOUBLE' ? true : false; 47 isShowMultiply.value = type == 'INT' || type == 'DOUBLE' ? true : false;
@@ -64,7 +63,7 @@ @@ -64,7 +63,7 @@
64 isShowModBUS.value = true; 63 isShowModBUS.value = true;
65 modBUSForm.value = { 64 modBUSForm.value = {
66 crc: 'CRC_16_LOWER', 65 crc: 'CRC_16_LOWER',
67 - deviceCode: '01', 66 + deviceCode: code,
68 method: actionType == '16' ? '10' : actionType, 67 method: actionType == '16' ? '10' : actionType,
69 registerAddress, 68 registerAddress,
70 registerNumber: 1, 69 registerNumber: 1,
@@ -91,6 +90,17 @@ @@ -91,6 +90,17 @@
91 return array; 90 return array;
92 }; 91 };
93 92
  93 + // 获取小数
  94 + const getFloatPart = (number: string | number) => {
  95 + const isLessZero = Number(number) < 0;
  96 + number = number.toString();
  97 + const floatPartStartIndex = number.indexOf('.');
  98 + const value = ~floatPartStartIndex
  99 + ? `${isLessZero ? '-' : ''}0.${number.substring(floatPartStartIndex + 1)}`
  100 + : '0';
  101 + return Number(value);
  102 + };
  103 +
94 const { createMessage } = useMessage(); 104 const { createMessage } = useMessage();
95 const loading = ref(false); 105 const loading = ref(false);
96 const handleSend = async () => { 106 const handleSend = async () => {
@@ -111,15 +121,37 @@ @@ -111,15 +121,37 @@
111 const oldValue = getFieldsValue()[unref(formField)]; 121 const oldValue = getFieldsValue()[unref(formField)];
112 modBUSForm.value.registerNumber = 1; 122 modBUSForm.value.registerNumber = 1;
113 modBUSForm.value.registerValues = [oldValue]; 123 modBUSForm.value.registerValues = [oldValue];
  124 +
114 if (unref(isShowMultiply) && unref(modBUSForm).method == '06') { 125 if (unref(isShowMultiply) && unref(modBUSForm).method == '06') {
  126 + const newValue =
  127 + Math.trunc(oldValue) * unref(zoomFactorValue) +
  128 + getFloatPart(oldValue) * unref(zoomFactorValue);
  129 + if (newValue % 1 != 0) {
  130 + createMessage.warning(`属性下发类型必须是整数,缩放因子为${unref(zoomFactorValue)}`);
  131 + return;
  132 + }
  133 +
  134 + if (oldValue * unref(zoomFactorValue) > 65535) {
  135 + createMessage.warning(`属性下发值不能超过65535,缩放因子是${unref(zoomFactorValue)}`);
  136 + return;
  137 + }
115 //bool类型的就不用去乘缩放因子了 138 //bool类型的就不用去乘缩放因子了
116 - modBUSForm.value.registerValues = [oldValue * unref(zoomFactorValue)]; 139 + modBUSForm.value.registerValues = [newValue];
117 } 140 }
118 141
119 if (unref(modBUSForm).method == '16' || unref(modBUSForm).method == '10') { 142 if (unref(modBUSForm).method == '16' || unref(modBUSForm).method == '10') {
120 - const newValue = getArray(  
121 - SingleToHex(unref(isShowMultiply) ? oldValue * unref(zoomFactorValue) : oldValue)  
122 - ); 143 + const regex = /^-?\d+(\.\d{0,2})?$/;
  144 + const values =
  145 + Math.trunc(oldValue) * unref(zoomFactorValue) +
  146 + getFloatPart(oldValue) * unref(zoomFactorValue);
  147 +
  148 + if (!regex.test(values as any)) {
  149 + createMessage.warning(`属性下发值精确到两位小数,缩放因子是${unref(zoomFactorValue)}`);
  150 + return;
  151 + }
  152 +
  153 + const newValue =
  154 + values == 0 ? [0, 0] : getArray(SingleToHex(unref(isShowMultiply) ? values : oldValue));
123 modBUSForm.value.registerValues = newValue; 155 modBUSForm.value.registerValues = newValue;
124 modBUSForm.value.registerNumber = 2; 156 modBUSForm.value.registerNumber = 2;
125 modBUSForm.value.method = '10'; 157 modBUSForm.value.method = '10';
@@ -5,7 +5,9 @@ @@ -5,7 +5,9 @@
5 > 5 >
6 <template #toolbar> 6 <template #toolbar>
7 <Space> 7 <Space>
8 - <Button type="primary" @click="openModal(true)">命令下发</Button> 8 + <Authority value="api:yt:device:rpc">
  9 + <Button type="primary" @click="openModal(true)">命令下发</Button>
  10 + </Authority>
9 </Space> 11 </Space>
10 </template> 12 </template>
11 <template #recordContent="{ record }"> 13 <template #recordContent="{ record }">
@@ -43,6 +45,7 @@ @@ -43,6 +45,7 @@
43 import { DeviceRecord } from '/@/api/device/model/deviceModel'; 45 import { DeviceRecord } from '/@/api/device/model/deviceModel';
44 import { BasicModal, useModal } from '/@/components/Modal'; 46 import { BasicModal, useModal } from '/@/components/Modal';
45 import CommandIssuance from '../CommandIssuance.vue'; 47 import CommandIssuance from '../CommandIssuance.vue';
  48 + import { Authority } from '/@/components/Authority';
46 49
47 const props = defineProps({ 50 const props = defineProps({
48 fromId: { 51 fromId: {
@@ -85,7 +88,8 @@ @@ -85,7 +88,8 @@
85 }; 88 };
86 const handleRecordContent = (record) => { 89 const handleRecordContent = (record) => {
87 if (!record?.request?.body) return; 90 if (!record?.request?.body) return;
88 - const jsonParams = record?.request?.body; 91 + if (Object.prototype.toString.call(record?.request?.body) !== '[object Object]') return;
  92 + const jsonParams = record?.request?.body?.params;
89 commonModalInfo('命令下发内容', jsonParams); 93 commonModalInfo('命令下发内容', jsonParams);
90 }; 94 };
91 const handleRecordResponseContent = (record) => { 95 const handleRecordResponseContent = (record) => {
@@ -24,14 +24,16 @@ @@ -24,14 +24,16 @@
24 <Authority value="api:yt:device:import"> 24 <Authority value="api:yt:device:import">
25 <Button type="primary" @click="handleBatchImport">导入</Button> 25 <Button type="primary" @click="handleBatchImport">导入</Button>
26 </Authority> 26 </Authority>
27 - <a-button  
28 - v-if="authBtn(role)"  
29 - type="primary"  
30 - @click="handleBatchAssign"  
31 - :disabled="!isExistOption"  
32 - >  
33 - 批量分配  
34 - </a-button> 27 + <Authority value="api:yt:device:assign">
  28 + <a-button
  29 + v-if="authBtn(role)"
  30 + type="primary"
  31 + @click="handleBatchAssign"
  32 + :disabled="!isExistOption"
  33 + >
  34 + 批量分配
  35 + </a-button>
  36 + </Authority>
35 </template> 37 </template>
36 <template #img="{ record }"> 38 <template #img="{ record }">
37 <TableImg 39 <TableImg
@@ -134,6 +136,7 @@ @@ -134,6 +136,7 @@
134 label: '分配客户', 136 label: '分配客户',
135 icon: 'mdi:account-arrow-right', 137 icon: 'mdi:account-arrow-right',
136 ifShow: authBtn(role), 138 ifShow: authBtn(role),
  139 + auth: 'api:yt:device:assign',
137 onClick: handleDispatchCustomer.bind(null, record), 140 onClick: handleDispatchCustomer.bind(null, record),
138 }, 141 },
139 { 142 {
@@ -33,9 +33,15 @@ @@ -33,9 +33,15 @@
33 </Button> 33 </Button>
34 </Authority> 34 </Authority>
35 <Button type="primary" @click="handleOpenTsl"> 物模型TSL </Button> 35 <Button type="primary" @click="handleOpenTsl"> 物模型TSL </Button>
36 - <Upload v-if="isShowBtn" :show-upload-list="false" :customRequest="handleImportModel">  
37 - <Button type="primary" :loading="importLoading"> 导入物模型 </Button>  
38 - </Upload> 36 + <Authority value="api:yt:things_model:import">
  37 + <Upload
  38 + v-if="isShowBtn"
  39 + :show-upload-list="false"
  40 + :customRequest="handleImportModel"
  41 + >
  42 + <Button type="primary" :loading="importLoading"> 导入物模型 </Button>
  43 + </Upload>
  44 + </Authority>
39 </div> 45 </div>
40 <div class="flex gap-2"> 46 <div class="flex gap-2">
41 <Authority :value="ModelOfMatterPermission.RELEASE"> 47 <Authority :value="ModelOfMatterPermission.RELEASE">
@@ -19,6 +19,6 @@ @@ -19,6 +19,6 @@
19 </template> 19 </template>
20 <style scoped> 20 <style scoped>
21 :deep(.ant-table-body) { 21 :deep(.ant-table-body) {
22 - overflow: hidden !important; 22 + overflow: scroll !important;
23 } 23 }
24 </style> 24 </style>
@@ -78,8 +78,7 @@ @@ -78,8 +78,7 @@
78 return deviceType === DeviceTypeEnum.SENSOR && transportType === 'TCP'; 78 return deviceType === DeviceTypeEnum.SENSOR && transportType === 'TCP';
79 }); 79 });
80 80
81 - const blockContent = `属性一般是设备的运行状态,如当前温度等;服务是设备可被调用的方法,支持定义参数,如执行某项任务;事件则是设备上报的  
82 -通知,如告警,需要被及时处理。`; 81 + const blockContent = `属性一般是指设备的运行状态,如当前温度等;服务是指设备可被调用的方法,支持定义参数,如执行某项任务;事件则是指设备上报的通知,如告警,需要被及时处理。`;
83 const activeKey = ref<FunctionType>(FunctionType.PROPERTIES); 82 const activeKey = ref<FunctionType>(FunctionType.PROPERTIES);
84 const size = ref('small'); 83 const size = ref('small');
85 84
@@ -89,7 +89,9 @@ @@ -89,7 +89,9 @@
89 functionJson: { 89 functionJson: {
90 inputData, 90 inputData,
91 outputData, 91 outputData,
92 - ...(serviceCommand ? { inputData: [{ serviceCommand }] } : {}), 92 + ...(serviceCommand
  93 + ? { inputData: [{ serviceCommand: serviceCommand.replaceAll(/\s/g, '').toUpperCase() }] }
  94 + : {}),
93 }, 95 },
94 } as ModelOfMatterParams; 96 } as ModelOfMatterParams;
95 97
@@ -117,7 +117,18 @@ export const serviceSchemas = (tcpDeviceFlag: boolean): FormSchema[] => { @@ -117,7 +117,18 @@ export const serviceSchemas = (tcpDeviceFlag: boolean): FormSchema[] => {
117 field: FormField.SERVICE_COMMAND, 117 field: FormField.SERVICE_COMMAND,
118 label: '输入参数', 118 label: '输入参数',
119 component: 'Input', 119 component: 'Input',
120 - rules: [{ message: '输入参数为必填项', required: true }], 120 + rules: [
  121 + { message: '输入参数为必填项', required: true },
  122 + {
  123 + message: '请输入ASCII或HEX服务命令(0~9/A~F)',
  124 + validator(_rule, value, _callback) {
  125 + const reg = /^[\s0-9a-fA-F]+$/;
  126 +
  127 + if (reg.test(value)) return Promise.resolve();
  128 + return Promise.reject('请输入ASCII或HEX服务命令(0~9/A~F)');
  129 + },
  130 + },
  131 + ],
121 ifShow: tcpDeviceFlag, 132 ifShow: tcpDeviceFlag,
122 componentProps: { 133 componentProps: {
123 placeholder: '请输入ASCII或HEX服务命令', 134 placeholder: '请输入ASCII或HEX服务命令',
@@ -17,16 +17,26 @@ @@ -17,16 +17,26 @@
17 </Authority> 17 </Authority>
18 </template> 18 </template>
19 <template #config="{ record }"> 19 <template #config="{ record }">
20 - <a-button type="link" class="ml-2" @click="showData(record)"> 查看配置 </a-button> 20 + <Authority value="api:yt:message:get:config">
  21 + <a-button type="link" class="ml-2" @click="showData(record)"> 查看配置 </a-button>
  22 + </Authority>
21 </template> 23 </template>
22 <template #status="{ record }"> 24 <template #status="{ record }">
23 - <Switch  
24 - :checked="record.status === 1"  
25 - :loading="record.pendingStatus"  
26 - checkedChildren="启用"  
27 - unCheckedChildren="禁用"  
28 - @change="(checked:boolean)=>statusChange(checked,record)"  
29 - /> 25 + <Authority value="api:yt:message:status">
  26 + <Switch
  27 + :checked="record.status === 1"
  28 + :loading="record.pendingStatus"
  29 + checkedChildren="启用"
  30 + unCheckedChildren="禁用"
  31 + @change="(checked:boolean)=>statusChange(checked,record)"
  32 + />
  33 + </Authority>
  34 + <Tag
  35 + v-if="!hasPermission('api:yt:message:status')"
  36 + :color="record.status ? 'green' : 'red'"
  37 + >
  38 + {{ record.status ? '启用' : '禁用' }}
  39 + </Tag>
30 </template> 40 </template>
31 <template #action="{ record }"> 41 <template #action="{ record }">
32 <TableAction 42 <TableAction
@@ -62,18 +72,20 @@ @@ -62,18 +72,20 @@
62 import { useDrawer } from '/@/components/Drawer'; 72 import { useDrawer } from '/@/components/Drawer';
63 import ConfigDrawer from './ConfigDrawer.vue'; 73 import ConfigDrawer from './ConfigDrawer.vue';
64 import { columns, searchFormSchema } from './config.data'; 74 import { columns, searchFormSchema } from './config.data';
65 - import { Modal, Popconfirm } from 'ant-design-vue'; 75 + import { Modal, Popconfirm, Tag } from 'ant-design-vue';
66 import { JsonPreview } from '/@/components/CodeEditor'; 76 import { JsonPreview } from '/@/components/CodeEditor';
67 import { useMessage } from '/@/hooks/web/useMessage'; 77 import { useMessage } from '/@/hooks/web/useMessage';
68 import { useBatchDelete } from '/@/hooks/web/useBatchDelete'; 78 import { useBatchDelete } from '/@/hooks/web/useBatchDelete';
69 import { Switch } from 'ant-design-vue'; 79 import { Switch } from 'ant-design-vue';
70 import { setMessageConfigStatus } from '/@/api/message/config'; 80 import { setMessageConfigStatus } from '/@/api/message/config';
71 import { Authority } from '/@/components/Authority'; 81 import { Authority } from '/@/components/Authority';
  82 + import { usePermission } from '/@/hooks/web/usePermission';
72 83
73 export default defineComponent({ 84 export default defineComponent({
74 name: 'MessageConfigManagement', 85 name: 'MessageConfigManagement',
75 - components: { BasicTable, ConfigDrawer, TableAction, Switch, Authority, Popconfirm }, 86 + components: { BasicTable, ConfigDrawer, TableAction, Switch, Authority, Popconfirm, Tag },
76 setup() { 87 setup() {
  88 + const { hasPermission } = usePermission();
77 const [registerDrawer, { openDrawer }] = useDrawer(); 89 const [registerDrawer, { openDrawer }] = useDrawer();
78 function handleSuccess() { 90 function handleSuccess() {
79 reload(); 91 reload();
@@ -168,6 +180,7 @@ @@ -168,6 +180,7 @@
168 handleDeleteOrBatchDelete, 180 handleDeleteOrBatchDelete,
169 hasBatchDelete, 181 hasBatchDelete,
170 statusChange, 182 statusChange,
  183 + hasPermission,
171 }; 184 };
172 }, 185 },
173 }); 186 });
@@ -22,13 +22,21 @@ @@ -22,13 +22,21 @@
22 </a-button> 22 </a-button>
23 </template> 23 </template>
24 <template #status="{ record }"> 24 <template #status="{ record }">
25 - <Switch  
26 - :checked="record.status === 1"  
27 - :loading="record.pendingStatus"  
28 - checkedChildren="启用"  
29 - unCheckedChildren="禁用"  
30 - @change="(checked:boolean)=>statusChange(checked,record)"  
31 - /> 25 + <Authority value="api:yt:template:status">
  26 + <Switch
  27 + :checked="record.status === 1"
  28 + :loading="record.pendingStatus"
  29 + checkedChildren="启用"
  30 + unCheckedChildren="禁用"
  31 + @change="(checked:boolean)=>statusChange(checked,record)"
  32 + />
  33 + </Authority>
  34 + <Tag
  35 + v-if="!hasPermission('api:yt:template:status')"
  36 + :color="record.status ? 'green' : 'red'"
  37 + >
  38 + {{ record.status ? '启用' : '禁用' }}
  39 + </Tag>
32 </template> 40 </template>
33 <template #action="{ record }"> 41 <template #action="{ record }">
34 <TableAction 42 <TableAction
@@ -80,9 +88,10 @@ @@ -80,9 +88,10 @@
80 import SendEmail from '/@/views/message/template/SendEmail.vue'; 88 import SendEmail from '/@/views/message/template/SendEmail.vue';
81 import { useMessage } from '/@/hooks/web/useMessage'; 89 import { useMessage } from '/@/hooks/web/useMessage';
82 import { useBatchDelete } from '/@/hooks/web/useBatchDelete'; 90 import { useBatchDelete } from '/@/hooks/web/useBatchDelete';
83 - import { Switch, Popconfirm } from 'ant-design-vue'; 91 + import { Switch, Popconfirm, Tag } from 'ant-design-vue';
84 import { setMessageTemplateStatus } from '/@/api/message/template'; 92 import { setMessageTemplateStatus } from '/@/api/message/template';
85 import { Authority } from '/@/components/Authority'; 93 import { Authority } from '/@/components/Authority';
  94 + import { usePermission } from '/@/hooks/web/usePermission';
86 95
87 export default defineComponent({ 96 export default defineComponent({
88 name: 'MessageTemplateManagement', 97 name: 'MessageTemplateManagement',
@@ -95,8 +104,10 @@ @@ -95,8 +104,10 @@
95 Switch, 104 Switch,
96 Authority, 105 Authority,
97 Popconfirm, 106 Popconfirm,
  107 + Tag,
98 }, 108 },
99 setup() { 109 setup() {
  110 + const { hasPermission } = usePermission();
100 const [registerModal, { openModal: openModal }] = useModal(); 111 const [registerModal, { openModal: openModal }] = useModal();
101 const [registerMailModal, { openModal: openMailModal }] = useModal(); 112 const [registerMailModal, { openModal: openMailModal }] = useModal();
102 const go = useGo(); 113 const go = useGo();
@@ -218,6 +229,7 @@ @@ -218,6 +229,7 @@
218 handleDeleteOrBatchDelete, 229 handleDeleteOrBatchDelete,
219 statusChange, 230 statusChange,
220 hasBatchDelete, 231 hasBatchDelete,
  232 + hasPermission,
221 }; 233 };
222 }, 234 },
223 }); 235 });
@@ -135,10 +135,14 @@ @@ -135,10 +135,14 @@
135 <Tabs.TabPane tab="详情" key="detail"> 135 <Tabs.TabPane tab="详情" key="detail">
136 <Space> 136 <Space>
137 <!-- <Button type="primary" @click="openDetailPage">打开详情页</Button> --> 137 <!-- <Button type="primary" @click="openDetailPage">打开详情页</Button> -->
138 - <Button type="primary" @click="downloadPackage" :disabled="!!otaRecord.url">  
139 - 下载包  
140 - </Button>  
141 - <Button type="primary" @click="deletePackage" danger>删除包</Button> 138 + <Authority :value="OtaPermissionKey.DOWNLOAD">
  139 + <Button type="primary" @click="downloadPackage" :disabled="!!otaRecord.url">
  140 + 下载包
  141 + </Button>
  142 + </Authority>
  143 + <Authority :value="OtaPermissionKey.DELETE">
  144 + <Button type="primary" @click="deletePackage" danger>删除包</Button>
  145 + </Authority>
142 </Space> 146 </Space>
143 <div class="mt-3"> 147 <div class="mt-3">
144 <Space> 148 <Space>
@@ -9,6 +9,7 @@ export enum PermissionReportConfigEnum { @@ -9,6 +9,7 @@ export enum PermissionReportConfigEnum {
9 PERMISSION_GET = 'api:yt:report:get', 9 PERMISSION_GET = 'api:yt:report:get',
10 PERMISSION_DELETE = 'api:yt:report_form:config:delete', 10 PERMISSION_DELETE = 'api:yt:report_form:config:delete',
11 PERMISSION_UPDATE = 'api:yt:report_form:config:update', 11 PERMISSION_UPDATE = 'api:yt:report_form:config:update',
  12 + PERMISSION_STATUS = 'api:yt:report_form:config:status',
12 } 13 }
13 14
14 //业务文字描述配置枚举 15 //业务文字描述配置枚举
@@ -74,14 +74,22 @@ @@ -74,14 +74,22 @@
74 /> 74 />
75 </template> 75 </template>
76 <template #configStatus="{ record }"> 76 <template #configStatus="{ record }">
77 - <Switch  
78 - :disabled="disabledSwitch"  
79 - :checked="record.status === 1"  
80 - :loading="record.pendingStatus"  
81 - :checkedChildren="BusinessReportConfigTextEnum.BUSINESS_ENABLE_TEXT"  
82 - :unCheckedChildren="BusinessReportConfigTextEnum.BUSINESS_DISABLE_TEXT"  
83 - @change="(checked: boolean) => statusChange(checked, record)"  
84 - /> 77 + <Authority :value="PermissionReportConfigEnum.PERMISSION_STATUS">
  78 + <Switch
  79 + :disabled="disabledSwitch"
  80 + :checked="record.status === 1"
  81 + :loading="record.pendingStatus"
  82 + :checkedChildren="BusinessReportConfigTextEnum.BUSINESS_ENABLE_TEXT"
  83 + :unCheckedChildren="BusinessReportConfigTextEnum.BUSINESS_DISABLE_TEXT"
  84 + @change="(checked: boolean) => statusChange(checked, record)"
  85 + />
  86 + </Authority>
  87 + <Tag
  88 + v-if="!hasPermission(PermissionReportConfigEnum.PERMISSION_STATUS)"
  89 + :color="record.status ? 'green' : 'red'"
  90 + >
  91 + {{ record.status ? '启用' : '禁用' }}
  92 + </Tag>
85 </template> 93 </template>
86 </BasicTable> 94 </BasicTable>
87 <ReportConfigDrawer @register="registerDrawer" @success="handleSuccess" /> 95 <ReportConfigDrawer @register="registerDrawer" @success="handleSuccess" />
@@ -101,7 +109,7 @@ @@ -101,7 +109,7 @@
101 import { defaultTableAttribtes } from './config'; 109 import { defaultTableAttribtes } from './config';
102 import { Authority } from '/@/components/Authority'; 110 import { Authority } from '/@/components/Authority';
103 import { useBatchDelete } from '/@/hooks/web/useBatchDelete'; 111 import { useBatchDelete } from '/@/hooks/web/useBatchDelete';
104 - import { Popconfirm, Switch } from 'ant-design-vue'; 112 + import { Popconfirm, Switch, Tag } from 'ant-design-vue';
105 import { useModal } from '/@/components/Modal'; 113 import { useModal } from '/@/components/Modal';
106 import { useGo } from '/@/hooks/web/usePage'; 114 import { useGo } from '/@/hooks/web/usePage';
107 import { useMessage } from '/@/hooks/web/useMessage'; 115 import { useMessage } from '/@/hooks/web/useMessage';
@@ -111,6 +119,9 @@ @@ -111,6 +119,9 @@
111 BusinessReportConfigTextEnum, 119 BusinessReportConfigTextEnum,
112 BusinessReportConfigStatusEnum, 120 BusinessReportConfigStatusEnum,
113 } from './enum'; 121 } from './enum';
  122 + import { usePermission } from '/@/hooks/web/usePermission';
  123 +
  124 + const { hasPermission } = usePermission();
114 125
115 const disabledSwitch = ref(false); 126 const disabledSwitch = ref(false);
116 127
@@ -192,8 +192,8 @@ @@ -192,8 +192,8 @@
192 }, 192 },
193 toolbox: {}, 193 toolbox: {},
194 grid: { 194 grid: {
195 - left: '8%',  
196 - right: '8%', 195 + left: '14%',
  196 + right: '20%',
197 bottom: 80, 197 bottom: 80,
198 containLabel: true, 198 containLabel: true,
199 }, 199 },
@@ -8,6 +8,7 @@ export enum PermissionDataFlowEnum { @@ -8,6 +8,7 @@ export enum PermissionDataFlowEnum {
8 PERMISSION_GET = 'api:yt:convert:config:get', 8 PERMISSION_GET = 'api:yt:convert:config:get',
9 PERMISSION_DELETE = 'api:yt:convert:config:delete', 9 PERMISSION_DELETE = 'api:yt:convert:config:delete',
10 PERMISSION_UPDATE = 'api:yt:convert:config:update', 10 PERMISSION_UPDATE = 'api:yt:convert:config:update',
  11 + PERMISSION_STATUS = 'api:yt:convert:config:status',
11 } 12 }
12 13
13 //业务文字描述配置枚举 14 //业务文字描述配置枚举
@@ -79,13 +79,21 @@ @@ -79,13 +79,21 @@
79 /> 79 />
80 </template> 80 </template>
81 <template #status="{ record }"> 81 <template #status="{ record }">
82 - <Switch  
83 - :checked="record.status === 1"  
84 - :loading="record.pendingStatus"  
85 - checkedChildren="启用"  
86 - unCheckedChildren="禁用"  
87 - @change="(checked:boolean)=>hanldeSwitch(checked,record)"  
88 - /> 82 + <Authority :value="PermissionDataFlowEnum.PERMISSION_STATUS">
  83 + <Switch
  84 + :checked="record.status === 1"
  85 + :loading="record.pendingStatus"
  86 + checkedChildren="启用"
  87 + unCheckedChildren="禁用"
  88 + @change="(checked:boolean)=>hanldeSwitch(checked,record)"
  89 + />
  90 + </Authority>
  91 + <Tag
  92 + v-if="!hasPermission(PermissionDataFlowEnum.PERMISSION_STATUS)"
  93 + :color="record.status ? 'green' : 'red'"
  94 + >
  95 + {{ record.status ? '启用' : '禁用' }}
  96 + </Tag>
89 </template> 97 </template>
90 </BasicTable> 98 </BasicTable>
91 <DataFlowModal @register="registerModal" @success="handleSuccess" /> 99 <DataFlowModal @register="registerModal" @success="handleSuccess" />
@@ -103,15 +111,18 @@ @@ -103,15 +111,18 @@
103 import { useMessage } from '/@/hooks/web/useMessage'; 111 import { useMessage } from '/@/hooks/web/useMessage';
104 import { Authority } from '/@/components/Authority'; 112 import { Authority } from '/@/components/Authority';
105 import { useBatchDelete } from '/@/hooks/web/useBatchDelete'; 113 import { useBatchDelete } from '/@/hooks/web/useBatchDelete';
106 - import { Switch, Popconfirm } from 'ant-design-vue'; 114 + import { Switch, Popconfirm, Tag } from 'ant-design-vue';
107 import { PermissionDataFlowEnum, BusinessDataFlowTextEnum } from './enum'; 115 import { PermissionDataFlowEnum, BusinessDataFlowTextEnum } from './enum';
108 import { DataFlowModal } from './components/dataflowmodal'; 116 import { DataFlowModal } from './components/dataflowmodal';
109 import { defaultTableAttribute } from './config'; 117 import { defaultTableAttribute } from './config';
  118 + import { usePermission } from '/@/hooks/web/usePermission';
110 119
111 const { createMessage } = useMessage(); 120 const { createMessage } = useMessage();
112 121
113 const loading = ref(true); 122 const loading = ref(true);
114 123
  124 + const { hasPermission } = usePermission();
  125 +
115 const handleSuccess = () => { 126 const handleSuccess = () => {
116 reload(); 127 reload();
117 }; 128 };
@@ -31,6 +31,7 @@ export type TOption = { @@ -31,6 +31,7 @@ export type TOption = {
31 export enum CommandTypeEnum { 31 export enum CommandTypeEnum {
32 CUSTOM = 0, 32 CUSTOM = 0,
33 SERVICE = 1, 33 SERVICE = 1,
  34 + ATTRIBUTE = 2,
34 } 35 }
35 36
36 /** 37 /**
@@ -164,26 +164,26 @@ export const genActionData = (actionData) => { @@ -164,26 +164,26 @@ export const genActionData = (actionData) => {
164 }; 164 };
165 165
166 export const operationNumber_OR_TIME = [ 166 export const operationNumber_OR_TIME = [
167 - { label: '等于', value: Number_Operation.EQUAL },  
168 - { label: '不等于', value: Number_Operation.NOT_EQUAL },  
169 - { label: '小于', value: Number_Operation.LESS },  
170 - { label: '小于等于', value: Number_Operation.LESS_OR_EQUAL },  
171 - { label: '大于', value: Number_Operation.GREATER },  
172 - { label: '大于等于', value: Number_Operation.GREATER_OR_EQUAL }, 167 + { label: '等于', value: Number_Operation.EQUAL, symbol: '=' },
  168 + { label: '不等于', value: Number_Operation.NOT_EQUAL, symbol: '!=' },
  169 + { label: '小于', value: Number_Operation.LESS, symbol: '<' },
  170 + { label: '小于等于', value: Number_Operation.LESS_OR_EQUAL, symbol: '<=' },
  171 + { label: '大于', value: Number_Operation.GREATER, symbol: '>' },
  172 + { label: '大于等于', value: Number_Operation.GREATER_OR_EQUAL, symbol: '>=' },
173 ]; 173 ];
174 174
175 export const operationString = [ 175 export const operationString = [
176 - { label: '等于', value: String_Operation.EQUAL },  
177 - { label: '不等于', value: String_Operation.NOT_EQUAL },  
178 - { label: '开始于', value: String_Operation.BEGAN_IN },  
179 - { label: '结束于', value: String_Operation.END_IN },  
180 - { label: '包含', value: String_Operation.INCLUDE },  
181 - { label: '不包含', value: String_Operation.NOT_INCLUDE }, 176 + { label: '等于', value: String_Operation.EQUAL, symbol: '=' },
  177 + { label: '不等于', value: String_Operation.NOT_EQUAL, symbol: '!=' },
  178 + { label: '开始于', value: String_Operation.BEGAN_IN, symbol: '开始于' },
  179 + { label: '结束于', value: String_Operation.END_IN, symbol: '结束于' },
  180 + { label: '包含', value: String_Operation.INCLUDE, symbol: '包含' },
  181 + { label: '不包含', value: String_Operation.NOT_INCLUDE, symbol: '不包含' },
182 ]; 182 ];
183 183
184 export const operationBoolean = [ 184 export const operationBoolean = [
185 - { label: '等于', value: Boolean_Operation.EQUAL },  
186 - { label: '不等于', value: Boolean_Operation.NOT_EQUAL }, 185 + { label: '等于', value: Boolean_Operation.EQUAL, symbol: '=' },
  186 + { label: '不等于', value: Boolean_Operation.NOT_EQUAL, symbol: '!=' },
187 ]; 187 ];
188 188
189 export const scheduleOptions = [ 189 export const scheduleOptions = [
@@ -50,13 +50,21 @@ @@ -50,13 +50,21 @@
50 </template> 50 </template>
51 51
52 <template #status="{ record }"> 52 <template #status="{ record }">
53 - <Switch  
54 - :checked="record.status === 1"  
55 - :loading="record.pendingStatus"  
56 - checkedChildren="启用"  
57 - unCheckedChildren="禁用"  
58 - @change="(checked:boolean)=>statusChange(checked,record)"  
59 - /> 53 + <Authority value="api:yt:sceneLinkage:status">
  54 + <Switch
  55 + :checked="record.status === 1"
  56 + :loading="record.pendingStatus"
  57 + checkedChildren="启用"
  58 + unCheckedChildren="禁用"
  59 + @change="(checked:boolean)=>statusChange(checked,record)"
  60 + />
  61 + </Authority>
  62 + <Tag
  63 + v-if="!hasPermission('api:yt:sceneLinkage:status')"
  64 + :color="record.status ? 'green' : 'red'"
  65 + >
  66 + {{ record.status ? '启用' : '禁用' }}
  67 + </Tag>
60 </template> 68 </template>
61 </BasicTable> 69 </BasicTable>
62 <SceneLinkAgeDrawer @register="registerDrawer" @success="handleSuccess" /> 70 <SceneLinkAgeDrawer @register="registerDrawer" @success="handleSuccess" />
@@ -72,16 +80,18 @@ @@ -72,16 +80,18 @@
72 screenLinkPagePutApi, 80 screenLinkPagePutApi,
73 } from '/@/api/ruleengine/ruleengineApi'; 81 } from '/@/api/ruleengine/ruleengineApi';
74 import { useBatchDelete } from '/@/hooks/web/useBatchDelete'; 82 import { useBatchDelete } from '/@/hooks/web/useBatchDelete';
75 - import { Switch, Popconfirm } from 'ant-design-vue'; 83 + import { Switch, Popconfirm, Tag } from 'ant-design-vue';
76 import { columns, searchFormSchema } from './config/config.data'; 84 import { columns, searchFormSchema } from './config/config.data';
77 import { USER_INFO_KEY } from '/@/enums/cacheEnum'; 85 import { USER_INFO_KEY } from '/@/enums/cacheEnum';
78 import { getAuthCache } from '/@/utils/auth'; 86 import { getAuthCache } from '/@/utils/auth';
79 import SceneLinkAgeDrawer from './SceneLinkAgeDrawer.vue'; 87 import SceneLinkAgeDrawer from './SceneLinkAgeDrawer.vue';
80 import { useMessage } from '/@/hooks/web/useMessage'; 88 import { useMessage } from '/@/hooks/web/useMessage';
81 import { Authority } from '/@/components/Authority'; 89 import { Authority } from '/@/components/Authority';
  90 + import { usePermission } from '/@/hooks/web/usePermission';
82 91
83 const userInfo: any = getAuthCache(USER_INFO_KEY); 92 const userInfo: any = getAuthCache(USER_INFO_KEY);
84 const userId = userInfo.userId; 93 const userId = userInfo.userId;
  94 + const { hasPermission } = usePermission();
85 95
86 const [registerDrawer, { openDrawer }] = useDrawer(); 96 const [registerDrawer, { openDrawer }] = useDrawer();
87 const [registerTable, { reload, setProps, setSelectedRowKeys }] = useTable({ 97 const [registerTable, { reload, setProps, setSelectedRowKeys }] = useTable({
@@ -17,13 +17,21 @@ @@ -17,13 +17,21 @@
17 </Authority> 17 </Authority>
18 </template> 18 </template>
19 <template #status="{ record }"> 19 <template #status="{ record }">
20 - <Switch  
21 - :checked="record.status === 1"  
22 - :loading="record.pendingStatus"  
23 - checkedChildren="启用"  
24 - unCheckedChildren="禁用"  
25 - @change="(checked:boolean)=>statusChange(checked,record)"  
26 - /> 20 + <Authority value="api:yt:convert:js:status">
  21 + <Switch
  22 + :checked="record.status === 1"
  23 + :loading="record.pendingStatus"
  24 + checkedChildren="启用"
  25 + unCheckedChildren="禁用"
  26 + @change="(checked:boolean)=>statusChange(checked,record)"
  27 + />
  28 + </Authority>
  29 + <Tag
  30 + v-if="!hasPermission('api:yt:convert:js:status')"
  31 + :color="record.status ? 'green' : 'red'"
  32 + >
  33 + {{ record.status ? '启用' : '禁用' }}
  34 + </Tag>
27 </template> 35 </template>
28 <template #action="{ record }"> 36 <template #action="{ record }">
29 <TableAction 37 <TableAction
@@ -69,7 +77,7 @@ @@ -69,7 +77,7 @@
69 77
70 <script lang="ts" setup> 78 <script lang="ts" setup>
71 import { ref, nextTick } from 'vue'; 79 import { ref, nextTick } from 'vue';
72 - import { Switch, Popconfirm } from 'ant-design-vue'; 80 + import { Switch, Popconfirm, Tag } from 'ant-design-vue';
73 import { BasicTable, useTable, TableAction } from '/@/components/Table'; 81 import { BasicTable, useTable, TableAction } from '/@/components/Table';
74 import { columns } from '../config/config.data'; 82 import { columns } from '../config/config.data';
75 import { getConvertApi, deleteTransformApi } from '/@/api/device/TransformScriptApi'; 83 import { getConvertApi, deleteTransformApi } from '/@/api/device/TransformScriptApi';
@@ -81,11 +89,14 @@ @@ -81,11 +89,14 @@
81 import { useBatchDelete } from '/@/hooks/web/useBatchDelete'; 89 import { useBatchDelete } from '/@/hooks/web/useBatchDelete';
82 import { Authority } from '/@/components/Authority'; 90 import { Authority } from '/@/components/Authority';
83 import { computed, unref } from 'vue'; 91 import { computed, unref } from 'vue';
  92 + import { usePermission } from '/@/hooks/web/usePermission';
84 93
85 const props = defineProps<{ searchInfo: Recordable }>(); 94 const props = defineProps<{ searchInfo: Recordable }>();
86 95
87 const getSearchInfo = computed(() => props.searchInfo); 96 const getSearchInfo = computed(() => props.searchInfo);
88 97
  98 + const { hasPermission } = usePermission();
  99 +
89 const handleSuccess = () => { 100 const handleSuccess = () => {
90 reload(); 101 reload();
91 }; 102 };
@@ -16,8 +16,8 @@ @@ -16,8 +16,8 @@
16 <div class="hidden min-h-full pl-4 mr-4 xl:flex xl:flex-col xl:w-6/12"> 16 <div class="hidden min-h-full pl-4 mr-4 xl:flex xl:flex-col xl:w-6/12">
17 <!-- <AppLogo class="-enter-x" /> --> 17 <!-- <AppLogo class="-enter-x" /> -->
18 <div style="display: flex; margin-top: 10px"> 18 <div style="display: flex; margin-top: 10px">
19 - <img v-if="defaultLogo" :src="defaultLogo" style="width: 48px; height: 48px" />  
20 - <img style="width: 48px; height: 48px" v-else src="/src/assets/images/logo.png" /> 19 + <img v-if="defaultLogo" :src="defaultLogo" class="h-12" />
  20 + <img class="h-12" v-else src="/src/assets/images/logo.png" />
21 <div 21 <div
22 class="ml-2 truncate md:opacity-100" 22 class="ml-2 truncate md:opacity-100"
23 style=" 23 style="
@@ -24,8 +24,9 @@ @@ -24,8 +24,9 @@
24 :customRequest="customUploadIconPic" 24 :customRequest="customUploadIconPic"
25 :before-upload="beforeUploadIconPic" 25 :before-upload="beforeUploadIconPic"
26 > 26 >
27 - <div v-if="iconPic"> 27 + <div v-if="iconPic" class="relative">
28 <img :src="iconPic" class="m-auto fill-img" /> 28 <img :src="iconPic" class="m-auto fill-img" />
  29 + <CloseCircleOutlined class="absolute icon-delete" @click.stop="handleDelete" />
29 <div style="background-color: #ccc; margin-top: 20px">重新上传</div> 30 <div style="background-color: #ccc; margin-top: 20px">重新上传</div>
30 </div> 31 </div>
31 <div v-else> 32 <div v-else>
@@ -81,7 +82,7 @@ @@ -81,7 +82,7 @@
81 import { useMessage } from '/@/hooks/web/useMessage'; 82 import { useMessage } from '/@/hooks/web/useMessage';
82 import type { FileItem } from '/@/components/Upload/src/typing'; 83 import type { FileItem } from '/@/components/Upload/src/typing';
83 import { iconUpload, getPlatForm, updatePlatForm, resetPlateInfo } from '/@/api/oem/index'; 84 import { iconUpload, getPlatForm, updatePlatForm, resetPlateInfo } from '/@/api/oem/index';
84 - import { PlusOutlined } from '@ant-design/icons-vue'; 85 + import { PlusOutlined, CloseCircleOutlined } from '@ant-design/icons-vue';
85 import { useUserStore } from '/@/store/modules/user'; 86 import { useUserStore } from '/@/store/modules/user';
86 import { createLocalStorage } from '/@/utils/cache/index'; 87 import { createLocalStorage } from '/@/utils/cache/index';
87 import { Authority } from '/@/components/Authority'; 88 import { Authority } from '/@/components/Authority';
@@ -100,6 +101,7 @@ @@ -100,6 +101,7 @@
100 ContentUploadText, 101 ContentUploadText,
101 Spin, 102 Spin,
102 CustomUploadComp, 103 CustomUploadComp,
  104 + CloseCircleOutlined,
103 }, 105 },
104 setup() { 106 setup() {
105 const loading = ref(false); 107 const loading = ref(false);
@@ -188,6 +190,11 @@ @@ -188,6 +190,11 @@
188 storage.set('platformInfo', newFieldValue); 190 storage.set('platformInfo', newFieldValue);
189 } 191 }
190 192
  193 + // 删除浏览器ico图标
  194 + const handleDelete = () => {
  195 + iconPic.value = '';
  196 + };
  197 +
191 onMounted(async () => { 198 onMounted(async () => {
192 const res = await getPlatForm(); 199 const res = await getPlatForm();
193 setFieldsValue(res); 200 setFieldsValue(res);
@@ -227,6 +234,7 @@ @@ -227,6 +234,7 @@
227 handleResetInfo, 234 handleResetInfo,
228 handleSetBgImgUrl, 235 handleSetBgImgUrl,
229 handleSetLogoImgUrl, 236 handleSetLogoImgUrl,
  237 + handleDelete,
230 }; 238 };
231 }, 239 },
232 }); 240 });
@@ -251,4 +259,12 @@ @@ -251,4 +259,12 @@
251 width: 100%; 259 width: 100%;
252 height: 100%; 260 height: 100%;
253 } 261 }
  262 +
  263 + .icon-delete {
  264 + top: -13px;
  265 + right: -13px;
  266 + color: rgb(146, 145, 145);
  267 + font-size: 1rem;
  268 + z-index: 9999;
  269 + }
254 </style> 270 </style>
1 <script setup name="CustomUploadComp" lang="ts"> 1 <script setup name="CustomUploadComp" lang="ts">
2 - import { PlusOutlined } from '@ant-design/icons-vue'; 2 + import { PlusOutlined, CloseCircleOutlined } from '@ant-design/icons-vue';
3 import { Upload, Spin } from 'ant-design-vue'; 3 import { Upload, Spin } from 'ant-design-vue';
4 import { ref, watchEffect } from 'vue'; 4 import { ref, watchEffect } from 'vue';
5 import { useUpload } from './hooks/useUploadFile.hook'; 5 import { useUpload } from './hooks/useUploadFile.hook';
@@ -40,6 +40,12 @@ @@ -40,6 +40,12 @@
40 } 40 }
41 }; 41 };
42 42
  43 + // 删除图片
  44 + const handleDelete = () => {
  45 + uploadImgUrl.value = '';
  46 + emit('setImg', uploadImgUrl.value);
  47 + };
  48 +
43 watchEffect(() => { 49 watchEffect(() => {
44 init(); 50 init();
45 }); 51 });
@@ -59,7 +65,10 @@ @@ -59,7 +65,10 @@
59 :customRequest="customUpload" 65 :customRequest="customUpload"
60 :before-upload="beforeUploadVerify" 66 :before-upload="beforeUploadVerify"
61 > 67 >
62 - <img v-if="uploadImgUrl" class="fill-img" :src="uploadImgUrl" alt="avatar" /> 68 + <div v-if="uploadImgUrl" class="w-full h-full modal-div relative">
  69 + <img class="fill-img" :src="uploadImgUrl" alt="avatar" />
  70 + <CloseCircleOutlined class="absolute icon-delete" @click.stop="handleDelete" />
  71 + </div>
63 <div v-else> 72 <div v-else>
64 <Spin v-if="uploadLoading" tip="正在上传中..." /> 73 <Spin v-if="uploadLoading" tip="正在上传中..." />
65 <PlusOutlined v-else /> 74 <PlusOutlined v-else />
@@ -74,4 +83,12 @@ @@ -74,4 +83,12 @@
74 width: 100%; 83 width: 100%;
75 height: 100%; 84 height: 100%;
76 } 85 }
  86 +
  87 + .icon-delete {
  88 + top: -13px;
  89 + right: -13px;
  90 + color: rgb(146, 145, 145);
  91 + font-size: 1rem;
  92 + z-index: 9999;
  93 + }
77 </style> 94 </style>
@@ -21,13 +21,18 @@ @@ -21,13 +21,18 @@
21 </Authority> 21 </Authority>
22 </template> 22 </template>
23 <template #status="{ record }"> 23 <template #status="{ record }">
24 - <Switch  
25 - :checked="record.status === 1"  
26 - :loading="record.pendingStatus"  
27 - checkedChildren="启用"  
28 - unCheckedChildren="禁用"  
29 - @change="(checked:boolean)=>statusChange(checked,record)"  
30 - /> 24 + <Authority value="api:yt:role:status">
  25 + <Switch
  26 + :checked="record.status === 1"
  27 + :loading="record.pendingStatus"
  28 + checkedChildren="启用"
  29 + unCheckedChildren="禁用"
  30 + @change="(checked:boolean)=>statusChange(checked,record)"
  31 + />
  32 + </Authority>
  33 + <Tag v-if="!hasPermission('api:yt:role:status')" :color="record.status ? 'green' : 'red'">
  34 + {{ record.status ? '启用' : '禁用' }}
  35 + </Tag>
31 </template> 36 </template>
32 <template #action="{ record }"> 37 <template #action="{ record }">
33 <TableAction 38 <TableAction
@@ -67,12 +72,14 @@ @@ -67,12 +72,14 @@
67 import { Authority } from '/@/components/Authority'; 72 import { Authority } from '/@/components/Authority';
68 import { useBatchDelete } from '/@/hooks/web/useBatchDelete'; 73 import { useBatchDelete } from '/@/hooks/web/useBatchDelete';
69 import { useMessage } from '/@/hooks/web/useMessage'; 74 import { useMessage } from '/@/hooks/web/useMessage';
70 - import { Switch, Popconfirm } from 'ant-design-vue'; 75 + import { Switch, Popconfirm, Tag } from 'ant-design-vue';
  76 + import { usePermission } from '/@/hooks/web/usePermission';
71 77
72 export default defineComponent({ 78 export default defineComponent({
73 name: 'RoleManagement', 79 name: 'RoleManagement',
74 - components: { BasicTable, RoleDrawer, TableAction, Authority, Switch, Popconfirm }, 80 + components: { BasicTable, RoleDrawer, TableAction, Authority, Switch, Popconfirm, Tag },
75 setup() { 81 setup() {
  82 + const { hasPermission } = usePermission();
76 const [registerDrawer, { openDrawer }] = useDrawer(); 83 const [registerDrawer, { openDrawer }] = useDrawer();
77 function handleSuccess() { 84 function handleSuccess() {
78 reload(); 85 reload();
@@ -157,6 +164,7 @@ @@ -157,6 +164,7 @@
157 hasBatchDelete, 164 hasBatchDelete,
158 handleDeleteOrBatchDelete, 165 handleDeleteOrBatchDelete,
159 statusChange, 166 statusChange,
  167 + hasPermission,
160 }; 168 };
161 }, 169 },
162 }); 170 });
@@ -7,7 +7,7 @@ export const validateDevicePicker = () => { @@ -7,7 +7,7 @@ export const validateDevicePicker = () => {
7 validateTrigger: 'blur', 7 validateTrigger: 'blur',
8 validator(_rule: Recordable, value: Recordable, _callback: Fn) { 8 validator(_rule: Recordable, value: Recordable, _callback: Fn) {
9 const device = Reflect.get(value || {}, FormFieldsEnum.DEVICE); 9 const device = Reflect.get(value || {}, FormFieldsEnum.DEVICE);
10 - if (!device) return Promise.reject('请选择设备'); 10 + if (!device || !device.length) return Promise.reject('请选择设备');
11 return Promise.resolve(); 11 return Promise.resolve();
12 }, 12 },
13 } as Rule; 13 } as Rule;
@@ -41,7 +41,9 @@ @@ -41,7 +41,9 @@
41 const inputType = ref(props.type); 41 const inputType = ref(props.type);
42 42
43 const getInputValue = computed(() => { 43 const getInputValue = computed(() => {
44 - const { type, value, toUpperCase } = props; 44 + const { type, toUpperCase } = props;
  45 + let { value } = props;
  46 + if (isNaN(value as number)) value = undefined;
45 47
46 if (isNullOrUnDef(value)) return value; 48 if (isNullOrUnDef(value)) return value;
47 49
@@ -133,6 +133,7 @@ @@ -133,6 +133,7 @@
133 text: '详情', 133 text: '详情',
134 event: DropMenuEvent.DETAIL, 134 event: DropMenuEvent.DETAIL,
135 icon: 'ant-design:eye-outlined', 135 icon: 'ant-design:eye-outlined',
  136 + auth: PermissionEnum.DETAIL,
136 onClick: emit.bind(null, 'detail', getRecord), 137 onClick: emit.bind(null, 'detail', getRecord),
137 }, 138 },
138 { 139 {
@@ -7,6 +7,7 @@ export enum PermissionEnum { @@ -7,6 +7,7 @@ export enum PermissionEnum {
7 DELETE = 'api:yt:task_center:delete', 7 DELETE = 'api:yt:task_center:delete',
8 ALLOW = 'api:yt:task_center:cancel:allow', 8 ALLOW = 'api:yt:task_center:cancel:allow',
9 EXECUTE = 'api:yt:task_center:immediate:execute', 9 EXECUTE = 'api:yt:task_center:immediate:execute',
  10 + DETAIL = 'api:yt:task_center:get',
10 } 11 }
11 12
12 export enum FormFieldsEnum { 13 export enum FormFieldsEnum {
@@ -16,6 +16,7 @@ @@ -16,6 +16,7 @@
16 :replaceFields="{ title: 'name', key: 'id' }" 16 :replaceFields="{ title: 'name', key: 'id' }"
17 :checkedKeys="roleMenus" 17 :checkedKeys="roleMenus"
18 @check="handleCheckClick" 18 @check="handleCheckClick"
  19 + @unSelectAll="handleUnSelectAll"
19 checkable 20 checkable
20 toolbar 21 toolbar
21 ref="treeRef" 22 ref="treeRef"
@@ -128,6 +129,11 @@ @@ -128,6 +129,11 @@
128 }); 129 });
129 const getTitle = computed(() => (!unref(isUpdate) ? '新增角色' : '编辑角色')); 130 const getTitle = computed(() => (!unref(isUpdate) ? '新增角色' : '编辑角色'));
130 131
  132 + // 取消全部的时候清除回显时获取的
  133 + const handleUnSelectAll = () => {
  134 + checkedKeysWithHalfChecked.value = [];
  135 + };
  136 +
131 async function handleSubmit() { 137 async function handleSubmit() {
132 setDrawerProps({ loading: true, confirmLoading: true }); 138 setDrawerProps({ loading: true, confirmLoading: true });
133 const { createMessage } = useMessage(); 139 const { createMessage } = useMessage();
@@ -143,7 +149,8 @@ @@ -143,7 +149,8 @@
143 roleType: RoleEnum.TENANT_ADMIN, 149 roleType: RoleEnum.TENANT_ADMIN,
144 menu, 150 menu,
145 }; 151 };
146 - if (req.menu == undefined) return createMessage.error('请勾选权限菜单'); 152 + if (req.menu == undefined || !req.menu.length)
  153 + return createMessage.error('请勾选权限菜单');
147 const res = await saveOrUpdateRoleInfoWithMenu(req); 154 const res = await saveOrUpdateRoleInfoWithMenu(req);
148 if (res) { 155 if (res) {
149 closeDrawer(); 156 closeDrawer();
@@ -247,6 +254,7 @@ @@ -247,6 +254,7 @@
247 roleMenus, 254 roleMenus,
248 treeRef, 255 treeRef,
249 handleCheckClick, 256 handleCheckClick,
  257 + handleUnSelectAll,
250 }; 258 };
251 }, 259 },
252 }); 260 });
@@ -9,6 +9,7 @@ export enum VisualBoardPermission { @@ -9,6 +9,7 @@ export enum VisualBoardPermission {
9 UPDATE = 'api:yt:data_board:update:update', 9 UPDATE = 'api:yt:data_board:update:update',
10 DELETE = 'api:yt:data_board:delete', 10 DELETE = 'api:yt:data_board:delete',
11 CREATE = '', 11 CREATE = '',
  12 + SHARE = 'api:yt:data_board:share',
12 DETAIL = 'api:yt:data_component:list', 13 DETAIL = 'api:yt:data_component:list',
13 } 14 }
14 15
@@ -99,19 +99,22 @@ @@ -99,19 +99,22 @@
99 const dropMenuList = computed<DropMenu[]>(() => { 99 const dropMenuList = computed<DropMenu[]>(() => {
100 const hasUpdatePermission = hasPermission(VisualBoardPermission.UPDATE); 100 const hasUpdatePermission = hasPermission(VisualBoardPermission.UPDATE);
101 const hasDeletePermission = hasPermission(VisualBoardPermission.DELETE); 101 const hasDeletePermission = hasPermission(VisualBoardPermission.DELETE);
102 - const basicMenu: DropMenu[] = [  
103 - {  
104 - text: '分享',  
105 - event: MoreActionEvent.SHARE,  
106 - icon: 'ant-design:share-alt-outlined',  
107 - },  
108 - ]; 102 + const hasSharePermission = hasPermission(VisualBoardPermission.SHARE);
  103 + let basicMenu: DropMenu[] = [];
109 if (hasUpdatePermission) 104 if (hasUpdatePermission)
110 basicMenu.push({ 105 basicMenu.push({
111 text: '编辑', 106 text: '编辑',
112 event: MoreActionEvent.EDIT, 107 event: MoreActionEvent.EDIT,
113 icon: 'ant-design:edit-outlined', 108 icon: 'ant-design:edit-outlined',
114 }); 109 });
  110 + if (hasSharePermission) {
  111 + basicMenu.push({
  112 + text: '分享',
  113 + event: MoreActionEvent.SHARE,
  114 + icon: 'ant-design:share-alt-outlined',
  115 + });
  116 + }
  117 +
115 if (hasDeletePermission) 118 if (hasDeletePermission)
116 basicMenu.push({ 119 basicMenu.push({
117 text: '删除', 120 text: '删除',
@@ -122,7 +122,7 @@ @@ -122,7 +122,7 @@
122 }); 122 });
123 }; 123 };
124 124
125 - const handleCopy = (record: DataSourceType) => { 125 + const handleCopy = async (record: DataSourceType) => {
126 const { key } = props.componentConfig || {}; 126 const { key } = props.componentConfig || {};
127 if (key == 'HumidityComponent2' && props.dataSource.length >= 6) { 127 if (key == 'HumidityComponent2' && props.dataSource.length >= 6) {
128 createMessage.warning('绑定的数据源不能超过6条~'); 128 createMessage.warning('绑定的数据源不能超过6条~');
@@ -134,7 +134,7 @@ @@ -134,7 +134,7 @@
134 return; 134 return;
135 } 135 }
136 136
137 - const allValues = getFormValues(); 137 + const allValues = await getFormValues();
138 const currentRecord = getFormValueByUUID(record.uuid); 138 const currentRecord = getFormValueByUUID(record.uuid);
139 const uuid = trackUpdate(); 139 const uuid = trackUpdate();
140 const raw = toRaw(record); 140 const raw = toRaw(record);
@@ -173,7 +173,7 @@ @@ -173,7 +173,7 @@
173 173
174 const handleSettingOk = (data: DataSourceType) => { 174 const handleSettingOk = (data: DataSourceType) => {
175 const { uuid } = data; 175 const { uuid } = data;
176 - const _dataSource = cloneDeep(props.dataSource); 176 + const _dataSource = cloneDeep(getFormValues());
177 177
178 const index = _dataSource.findIndex((item) => item.uuid === uuid); 178 const index = _dataSource.findIndex((item) => item.uuid === uuid);
179 179
@@ -95,6 +95,11 @@ @@ -95,6 +95,11 @@
95 }; 95 };
96 setFormValues(record); 96 setFormValues(record);
97 } else { 97 } else {
  98 + selectWidgetKeys.value = {
  99 + componentKey: TextComponent1Config.key,
  100 + categoryKey: PackagesCategoryEnum.TEXT,
  101 + };
  102 + activeKey.value = TabKeyEnum.BASIC;
98 dataSource.value = [genNewDataSourceItem()]; 103 dataSource.value = [genNewDataSourceItem()];
99 } 104 }
100 } 105 }
@@ -16,6 +16,7 @@ export const option: PublicPresetOptions = { @@ -16,6 +16,7 @@ export const option: PublicPresetOptions = {
16 [ComponentConfigFieldEnum.CLOSE_COLOR]: '#FF0000', 16 [ComponentConfigFieldEnum.CLOSE_COLOR]: '#FF0000',
17 [ComponentConfigFieldEnum.SHOW_DEVICE_NAME]: true, 17 [ComponentConfigFieldEnum.SHOW_DEVICE_NAME]: true,
18 [ComponentConfigFieldEnum.SHOW_TIME]: false, 18 [ComponentConfigFieldEnum.SHOW_TIME]: false,
  19 + [ComponentConfigFieldEnum.FONT_SIZE]: 14,
19 }; 20 };
20 21
21 export default class Config extends PublicConfigClass implements CreateComponentType { 22 export default class Config extends PublicConfigClass implements CreateComponentType {
@@ -36,6 +36,23 @@ @@ -36,6 +36,23 @@
36 component: 'Checkbox', 36 component: 'Checkbox',
37 defaultValue: option.showTime, 37 defaultValue: option.showTime,
38 }, 38 },
  39 + {
  40 + field: ComponentConfigFieldEnum.FONT_SIZE,
  41 + label: '文本字体大小',
  42 + component: 'InputNumber',
  43 + defaultValue: 14,
  44 + componentProps: {
  45 + min: 0,
  46 + formatter: (e) => {
  47 + const value = e.replace(/^0/g, '');
  48 + if (value) {
  49 + return value.replace(/^0/g, '');
  50 + } else {
  51 + return 0;
  52 + }
  53 + },
  54 + },
  55 + },
39 ], 56 ],
40 showActionButtonGroup: false, 57 showActionButtonGroup: false,
41 labelWidth: 120, 58 labelWidth: 120,
@@ -24,6 +24,7 @@ @@ -24,6 +24,7 @@
24 showTime: boolean; 24 showTime: boolean;
25 status: IStatus; 25 status: IStatus;
26 time: number; 26 time: number;
  27 + fontSize?: number;
27 } 28 }
28 29
29 const props = defineProps<{ 30 const props = defineProps<{
@@ -53,7 +54,11 @@ @@ -53,7 +54,11 @@
53 const getDesign = computed(() => { 54 const getDesign = computed(() => {
54 const { persetOption = {}, option } = props.config; 55 const { persetOption = {}, option } = props.config;
55 const { dataSource } = option; 56 const { dataSource } = option;
56 - const { showDeviceName: presetShowDeviceName, showTime: persetShowTime } = persetOption; 57 + const {
  58 + showDeviceName: presetShowDeviceName,
  59 + showTime: persetShowTime,
  60 + fontSize: persetFontSize,
  61 + } = persetOption;
57 62
58 return { 63 return {
59 dataSource: dataSource?.map((item) => { 64 dataSource: dataSource?.map((item) => {
@@ -63,6 +68,7 @@ @@ -63,6 +68,7 @@
63 deviceName: deviceRename || deviceName, 68 deviceName: deviceRename || deviceName,
64 showDeviceName: componentInfo.showDeviceName ?? presetShowDeviceName, 69 showDeviceName: componentInfo.showDeviceName ?? presetShowDeviceName,
65 showTime: componentInfo.showTime ?? persetShowTime, 70 showTime: componentInfo.showTime ?? persetShowTime,
  71 + fontSize: componentInfo.fontSize || persetFontSize,
66 }; 72 };
67 }), 73 }),
68 }; 74 };
@@ -82,6 +88,7 @@ @@ -82,6 +88,7 @@
82 time: 1689574726, 88 time: 1689574726,
83 showDeviceName: true, 89 showDeviceName: true,
84 showTime: true, 90 showTime: true,
  91 + fontSize: 14,
85 }, 92 },
86 ]); 93 ]);
87 94
@@ -133,6 +140,7 @@ @@ -133,6 +140,7 @@
133 showTime: item.showTime, 140 showTime: item.showTime,
134 status: { text: '', color: '' }, 141 status: { text: '', color: '' },
135 time: 0, 142 time: 0,
  143 + fontSize: item.fontSize,
136 }; 144 };
137 }) as any; 145 }) as any;
138 const { data, update } = message; 146 const { data, update } = message;
@@ -163,7 +171,7 @@ @@ -163,7 +171,7 @@
163 <main :style="getScale" class="w-full h-full flex justify-center items-center"> 171 <main :style="getScale" class="w-full h-full flex justify-center items-center">
164 <div v-for="item in alarmStatusList" :key="item.id" class="flex flex-col items-center"> 172 <div v-for="item in alarmStatusList" :key="item.id" class="flex flex-col items-center">
165 <div class="flex justify-center items-center flex-col"> 173 <div class="flex justify-center items-center flex-col">
166 - <div class="text-gray-500 text-sm truncate" 174 + <div class="text-gray-500 truncate" :style="{ fontSize: item.fontSize + 'px' }"
167 >{{ 175 >{{
168 item.status.text 176 item.status.text
169 ? item.showDeviceName 177 ? item.showDeviceName
@@ -11,6 +11,7 @@ import { ComponentConfigFieldEnum } from '../../../enum'; @@ -11,6 +11,7 @@ import { ComponentConfigFieldEnum } from '../../../enum';
11 11
12 export const option: PublicPresetOptions = { 12 export const option: PublicPresetOptions = {
13 [ComponentConfigFieldEnum.SHOW_DEVICE_NAME]: false, 13 [ComponentConfigFieldEnum.SHOW_DEVICE_NAME]: false,
  14 + [ComponentConfigFieldEnum.FONT_SIZE]: 14,
14 // [ComponentConfigFieldEnum.FONT_COLOR]: '#000', 15 // [ComponentConfigFieldEnum.FONT_COLOR]: '#000',
15 }; 16 };
16 17
@@ -19,6 +19,12 @@ @@ -19,6 +19,12 @@
19 component: 'Checkbox', 19 component: 'Checkbox',
20 defaultValue: option.showDeviceName, 20 defaultValue: option.showDeviceName,
21 }, 21 },
  22 + {
  23 + field: ComponentConfigFieldEnum.FONT_SIZE,
  24 + label: '文本字体大小',
  25 + component: 'InputNumber',
  26 + defaultValue: 14,
  27 + },
22 ], 28 ],
23 showActionButtonGroup: false, 29 showActionButtonGroup: false,
24 labelWidth: 120, 30 labelWidth: 120,
@@ -32,6 +32,10 @@ @@ -32,6 +32,10 @@
32 transportType: value.transportType, 32 transportType: value.transportType,
33 service: value.service, 33 service: value.service,
34 command: value.command, 34 command: value.command,
  35 + openService: value.openService,
  36 + closeService: value.closeService,
  37 + openCommand: value.openCommand,
  38 + closeCommand: value.closeCommand,
35 commandType: value.commandType, 39 commandType: value.commandType,
36 callType: value.callType, 40 callType: value.callType,
37 }, 41 },
@@ -45,6 +49,10 @@ @@ -45,6 +49,10 @@
45 ...record, 49 ...record,
46 transportType: customCommand?.transportType || (record as Recordable).transportType, 50 transportType: customCommand?.transportType || (record as Recordable).transportType,
47 service: customCommand?.service || (record as Recordable).service, 51 service: customCommand?.service || (record as Recordable).service,
  52 + openService: customCommand?.openService || (record as Recordable).openService,
  53 + closeService: customCommand?.closeService || (record as Recordable).closeService,
  54 + openCommand: customCommand?.openCommand || (record as Recordable).openCommand,
  55 + closeCommand: customCommand?.closeCommand || (record as Recordable).closeCommand,
48 command: customCommand?.command || (record as Recordable).command, 56 command: customCommand?.command || (record as Recordable).command,
49 commandType: customCommand?.commandType || (record as Recordable).commandType, 57 commandType: customCommand?.commandType || (record as Recordable).commandType,
50 callType: customCommand?.callType || (record as Recordable).callType, 58 callType: customCommand?.callType || (record as Recordable).callType,
@@ -2,12 +2,13 @@ @@ -2,12 +2,13 @@
2 import { ComponentPropsConfigType } from '/@/views/visual/packages/index.type'; 2 import { ComponentPropsConfigType } from '/@/views/visual/packages/index.type';
3 import { option } from './config'; 3 import { option } from './config';
4 import { Spin } from 'ant-design-vue'; 4 import { Spin } from 'ant-design-vue';
5 - import { computed, ref } from 'vue'; 5 + import { computed, ref, unref } from 'vue';
6 import { useComponentScale } from '../../../hook/useComponentScale'; 6 import { useComponentScale } from '../../../hook/useComponentScale';
7 import { useSendCommand } from '../../../hook/useSendCommand'; 7 import { useSendCommand } from '../../../hook/useSendCommand';
8 import { DeviceName } from '/@/views/visual/commonComponents/DeviceName'; 8 import { DeviceName } from '/@/views/visual/commonComponents/DeviceName';
9 import { DataFetchUpdateFn } from '../../../hook/socket/useSocket.type'; 9 import { DataFetchUpdateFn } from '../../../hook/socket/useSocket.type';
10 import { useDataFetch } from '../../../hook/socket/useSocket'; 10 import { useDataFetch } from '../../../hook/socket/useSocket';
  11 + import { getSendValues } from '../config';
11 12
12 const props = defineProps<{ 13 const props = defineProps<{
13 config: ComponentPropsConfigType<typeof option>; 14 config: ComponentPropsConfigType<typeof option>;
@@ -18,10 +19,28 @@ @@ -18,10 +19,28 @@
18 const currentValue = ref(false); 19 const currentValue = ref(false);
19 20
20 const getDesign = computed(() => { 21 const getDesign = computed(() => {
21 - const { option } = props.config;  
22 - const { attribute, attributeRename, attributeName } = option; 22 + const { option, persetOption } = props.config;
  23 + const {
  24 + attribute,
  25 + attributeRename,
  26 + attributeName,
  27 + componentInfo,
  28 + commandType,
  29 + extensionDesc,
  30 + codeType,
  31 + deviceCode,
  32 + customCommand,
  33 + } = option;
  34 + const { fontSize: persetFontSize } = persetOption || {};
  35 + const { fontSize } = componentInfo || {};
23 return { 36 return {
24 attribute: attributeRename || attributeName || attribute, 37 attribute: attributeRename || attributeName || attribute,
  38 + fontSize: fontSize || persetFontSize || 14,
  39 + extensionDesc: extensionDesc ? JSON.parse(extensionDesc) : {},
  40 + commandType,
  41 + codeType,
  42 + deviceCode,
  43 + customCommand,
25 }; 44 };
26 }); 45 });
27 46
@@ -29,8 +48,12 @@ @@ -29,8 +48,12 @@
29 const handleChange = async (event: Event) => { 48 const handleChange = async (event: Event) => {
30 const target = event.target as HTMLInputElement; 49 const target = event.target as HTMLInputElement;
31 const value = target.checked; 50 const value = target.checked;
  51 + const { option } = props.config || {};
32 52
33 - const flag = await sendCommand(props.config.option, value); 53 + const { values, isModbusCommand, sendValue } =
  54 + (await getSendValues(option, unref(getDesign), value)) || {};
  55 +
  56 + const flag = await sendCommand(values, isModbusCommand ? sendValue : value, isModbusCommand);
34 if (flag) currentValue.value = value; 57 if (flag) currentValue.value = value;
35 flag ? (currentValue.value = value) : (target.checked = !value); 58 flag ? (currentValue.value = value) : (target.checked = !value);
36 }; 59 };
@@ -61,7 +84,10 @@ @@ -61,7 +84,10 @@
61 <span class="on">ON</span> 84 <span class="on">ON</span>
62 <span class="off">OFF</span> 85 <span class="off">OFF</span>
63 </label> 86 </label>
64 - <div class="text-center mt-2 text-gray-700" :style="getScale"> 87 + <div
  88 + class="text-center mt-2 text-gray-700"
  89 + :style="{ ...getScale, fontSize: getDesign.fontSize + 'px' }"
  90 + >
65 {{ getDesign.attribute || '属性' }} 91 {{ getDesign.attribute || '属性' }}
66 </div> 92 </div>
67 </Spin> 93 </Spin>
@@ -13,6 +13,7 @@ export const option: PublicPresetOptions = { @@ -13,6 +13,7 @@ export const option: PublicPresetOptions = {
13 [ComponentConfigFieldEnum.ICON]: 'shuiwen', 13 [ComponentConfigFieldEnum.ICON]: 'shuiwen',
14 [ComponentConfigFieldEnum.ICON_COLOR]: '#377DFF', 14 [ComponentConfigFieldEnum.ICON_COLOR]: '#377DFF',
15 [ComponentConfigFieldEnum.SHOW_DEVICE_NAME]: false, 15 [ComponentConfigFieldEnum.SHOW_DEVICE_NAME]: false,
  16 + [ComponentConfigFieldEnum.FONT_SIZE]: 14,
16 }; 17 };
17 18
18 export default class Config extends PublicConfigClass implements CreateComponentType { 19 export default class Config extends PublicConfigClass implements CreateComponentType {
@@ -32,6 +32,12 @@ @@ -32,6 +32,12 @@
32 component: 'Checkbox', 32 component: 'Checkbox',
33 defaultValue: option.showDeviceName, 33 defaultValue: option.showDeviceName,
34 }, 34 },
  35 + {
  36 + field: ComponentConfigFieldEnum.FONT_SIZE,
  37 + label: '文本字体大小',
  38 + component: 'InputNumber',
  39 + defaultValue: option.fontSize,
  40 + },
35 ], 41 ],
36 showActionButtonGroup: false, 42 showActionButtonGroup: false,
37 labelWidth: 120, 43 labelWidth: 120,
@@ -32,6 +32,10 @@ @@ -32,6 +32,10 @@
32 transportType: value.transportType, 32 transportType: value.transportType,
33 service: value.service, 33 service: value.service,
34 command: value.command, 34 command: value.command,
  35 + openService: value.openService,
  36 + closeService: value.closeService,
  37 + openCommand: value.openCommand,
  38 + closeCommand: value.closeCommand,
35 commandType: value.commandType, 39 commandType: value.commandType,
36 callType: value.callType, 40 callType: value.callType,
37 }, 41 },
@@ -41,14 +45,20 @@ @@ -41,14 +45,20 @@
41 45
42 const setFormValues = (record: DataSource) => { 46 const setFormValues = (record: DataSource) => {
43 const { customCommand } = record; 47 const { customCommand } = record;
44 - return setFieldsValue({ 48 + const values = {
45 ...record, 49 ...record,
46 transportType: customCommand?.transportType || (record as Recordable).transportType, 50 transportType: customCommand?.transportType || (record as Recordable).transportType,
47 service: customCommand?.service || (record as Recordable).service, 51 service: customCommand?.service || (record as Recordable).service,
48 command: customCommand?.command || (record as Recordable).command, 52 command: customCommand?.command || (record as Recordable).command,
  53 + openService: customCommand?.openService || (record as Recordable).openService,
  54 + closeService: customCommand?.closeService || (record as Recordable).closeService,
  55 + openCommand: customCommand?.openCommand || (record as Recordable).openCommand,
  56 + closeCommand: customCommand?.closeCommand || (record as Recordable).closeCommand,
49 commandType: customCommand?.commandType || (record as Recordable).commandType, 57 commandType: customCommand?.commandType || (record as Recordable).commandType,
50 callType: customCommand?.callType || (record as Recordable).callType, 58 callType: customCommand?.callType || (record as Recordable).callType,
51 - } as unknown as Partial<CommonDataSourceBindValueType>); 59 + } as unknown as Partial<CommonDataSourceBindValueType>;
  60 +
  61 + return setFieldsValue(values);
52 }; 62 };
53 63
54 defineExpose({ 64 defineExpose({
@@ -10,6 +10,7 @@ @@ -10,6 +10,7 @@
10 import { DeviceName } from '/@/views/visual/commonComponents/DeviceName'; 10 import { DeviceName } from '/@/views/visual/commonComponents/DeviceName';
11 import { DataFetchUpdateFn } from '../../../hook/socket/useSocket.type'; 11 import { DataFetchUpdateFn } from '../../../hook/socket/useSocket.type';
12 import { useDataFetch } from '../../../hook/socket/useSocket'; 12 import { useDataFetch } from '../../../hook/socket/useSocket';
  13 + import { getSendValues } from '../config';
13 14
14 const props = defineProps<{ 15 const props = defineProps<{
15 config: ComponentPropsConfigType<typeof option>; 16 config: ComponentPropsConfigType<typeof option>;
@@ -19,19 +20,50 @@ @@ -19,19 +20,50 @@
19 20
20 const getDesign = computed(() => { 21 const getDesign = computed(() => {
21 const { option, persetOption } = props.config; 22 const { option, persetOption } = props.config;
22 - const { componentInfo, attribute, attributeRename, attributeName } = option;  
23 - const { icon: presetIcon, iconColor: presetIconColor } = persetOption || {};  
24 - const { icon, iconColor } = componentInfo || {}; 23 + const {
  24 + componentInfo,
  25 + attribute,
  26 + attributeRename,
  27 + attributeName,
  28 + commandType,
  29 + extensionDesc,
  30 + codeType,
  31 + deviceCode,
  32 + customCommand,
  33 + } = option;
  34 + const {
  35 + icon: presetIcon,
  36 + iconColor: presetIconColor,
  37 + fontSize: persetFontSize,
  38 + } = persetOption || {};
  39 + const { icon, iconColor, fontSize } = componentInfo || {};
  40 +
25 return { 41 return {
26 icon: icon ?? presetIcon, 42 icon: icon ?? presetIcon,
27 iconColor: iconColor || presetIconColor, 43 iconColor: iconColor || presetIconColor,
28 attribute: attributeRename || attributeName || attribute, 44 attribute: attributeRename || attributeName || attribute,
  45 + extensionDesc: extensionDesc ? JSON.parse(extensionDesc) : {},
  46 + fontSize: fontSize || persetFontSize || 14,
  47 + commandType,
  48 + codeType,
  49 + deviceCode,
  50 + customCommand,
29 }; 51 };
30 }); 52 });
31 53
32 const { sendCommand, loading } = useSendCommand(); 54 const { sendCommand, loading } = useSendCommand();
  55 +
33 const handleChange = async () => { 56 const handleChange = async () => {
34 - const flag = await sendCommand(props.config.option, unref(checked)); 57 + const { option } = props.config || {};
  58 +
  59 + const { values, isModbusCommand, sendValue } =
  60 + (await getSendValues(option, unref(getDesign), unref(checked))) || {};
  61 +
  62 + const flag = await sendCommand(
  63 + values,
  64 + isModbusCommand ? sendValue : unref(checked),
  65 + isModbusCommand
  66 + );
35 if (!flag) checked.value = !unref(checked); 67 if (!flag) checked.value = !unref(checked);
36 }; 68 };
37 69
@@ -57,7 +89,10 @@ @@ -57,7 +89,10 @@
57 :style="{ color: getDesign.iconColor }" 89 :style="{ color: getDesign.iconColor }"
58 :size="50" 90 :size="50"
59 /> 91 />
60 - <span class="mt-3 truncate text-gray-500 text-xs text-center"> 92 + <span
  93 + class="mt-3 truncate text-gray-500 text-center"
  94 + :style="{ fontSize: getDesign.fontSize + 'px' }"
  95 + >
61 {{ getDesign.attribute || '属性' }} 96 {{ getDesign.attribute || '属性' }}
62 </span> 97 </span>
63 </div> 98 </div>
@@ -11,6 +11,7 @@ import { ComponentConfigFieldEnum } from '../../../enum'; @@ -11,6 +11,7 @@ import { ComponentConfigFieldEnum } from '../../../enum';
11 11
12 export const option: PublicPresetOptions = { 12 export const option: PublicPresetOptions = {
13 [ComponentConfigFieldEnum.SHOW_DEVICE_NAME]: false, 13 [ComponentConfigFieldEnum.SHOW_DEVICE_NAME]: false,
  14 + [ComponentConfigFieldEnum.FONT_SIZE]: 14,
14 // [ComponentConfigFieldEnum.FONT_COLOR]: '#000', 15 // [ComponentConfigFieldEnum.FONT_COLOR]: '#000',
15 }; 16 };
16 17
@@ -18,6 +18,12 @@ @@ -18,6 +18,12 @@
18 component: 'Checkbox', 18 component: 'Checkbox',
19 defaultValue: option.showDeviceName, 19 defaultValue: option.showDeviceName,
20 }, 20 },
  21 + {
  22 + field: ComponentConfigFieldEnum.FONT_SIZE,
  23 + label: '文本字体大小',
  24 + component: 'InputNumber',
  25 + defaultValue: option.fontSize,
  26 + },
21 ], 27 ],
22 showActionButtonGroup: false, 28 showActionButtonGroup: false,
23 labelWidth: 120, 29 labelWidth: 120,
@@ -32,6 +32,10 @@ @@ -32,6 +32,10 @@
32 transportType: value.transportType, 32 transportType: value.transportType,
33 service: value.service, 33 service: value.service,
34 command: value.command, 34 command: value.command,
  35 + openService: value.openService,
  36 + closeService: value.closeService,
  37 + openCommand: value.openCommand,
  38 + closeCommand: value.closeCommand,
35 commandType: value.commandType, 39 commandType: value.commandType,
36 callType: value.callType, 40 callType: value.callType,
37 }, 41 },
@@ -45,6 +49,10 @@ @@ -45,6 +49,10 @@
45 ...record, 49 ...record,
46 transportType: customCommand?.transportType || (record as Recordable).transportType, 50 transportType: customCommand?.transportType || (record as Recordable).transportType,
47 service: customCommand?.service || (record as Recordable).service, 51 service: customCommand?.service || (record as Recordable).service,
  52 + openService: customCommand?.openService || (record as Recordable).openService,
  53 + closeService: customCommand?.closeService || (record as Recordable).closeService,
  54 + openCommand: customCommand?.openCommand || (record as Recordable).openCommand,
  55 + closeCommand: customCommand?.closeCommand || (record as Recordable).closeCommand,
48 command: customCommand?.command || (record as Recordable).command, 56 command: customCommand?.command || (record as Recordable).command,
49 commandType: customCommand?.commandType || (record as Recordable).commandType, 57 commandType: customCommand?.commandType || (record as Recordable).commandType,
50 callType: customCommand?.callType || (record as Recordable).callType, 58 callType: customCommand?.callType || (record as Recordable).callType,
@@ -2,12 +2,13 @@ @@ -2,12 +2,13 @@
2 import { ComponentPropsConfigType } from '/@/views/visual/packages/index.type'; 2 import { ComponentPropsConfigType } from '/@/views/visual/packages/index.type';
3 import { option } from './config'; 3 import { option } from './config';
4 import { Spin } from 'ant-design-vue'; 4 import { Spin } from 'ant-design-vue';
5 - import { computed, ref } from 'vue'; 5 + import { computed, ref, unref } from 'vue';
6 import { useComponentScale } from '../../../hook/useComponentScale'; 6 import { useComponentScale } from '../../../hook/useComponentScale';
7 import { useSendCommand } from '../../../hook/useSendCommand'; 7 import { useSendCommand } from '../../../hook/useSendCommand';
8 import { DeviceName } from '/@/views/visual/commonComponents/DeviceName'; 8 import { DeviceName } from '/@/views/visual/commonComponents/DeviceName';
9 import { DataFetchUpdateFn } from '../../../hook/socket/useSocket.type'; 9 import { DataFetchUpdateFn } from '../../../hook/socket/useSocket.type';
10 import { useDataFetch } from '../../../hook/socket/useSocket'; 10 import { useDataFetch } from '../../../hook/socket/useSocket';
  11 + import { getSendValues } from '../config';
11 12
12 const props = defineProps<{ 13 const props = defineProps<{
13 config: ComponentPropsConfigType<typeof option>; 14 config: ComponentPropsConfigType<typeof option>;
@@ -18,10 +19,28 @@ @@ -18,10 +19,28 @@
18 const currentValue = ref(false); 19 const currentValue = ref(false);
19 20
20 const getDesign = computed(() => { 21 const getDesign = computed(() => {
21 - const { option } = props.config;  
22 - const { attribute, attributeRename, attributeName } = option; 22 + const { option, persetOption } = props.config;
  23 + const {
  24 + attribute,
  25 + attributeRename,
  26 + attributeName,
  27 + commandType,
  28 + extensionDesc,
  29 + codeType,
  30 + deviceCode,
  31 + customCommand,
  32 + componentInfo,
  33 + } = option;
  34 + const { fontSize: persetFontSize } = persetOption || {};
  35 + const { fontSize } = componentInfo || {};
23 return { 36 return {
24 attribute: attributeRename || attributeName || attribute, 37 attribute: attributeRename || attributeName || attribute,
  38 + extensionDesc: extensionDesc ? JSON.parse(extensionDesc) : {},
  39 + commandType,
  40 + codeType,
  41 + deviceCode,
  42 + customCommand,
  43 + fontSize: fontSize || persetFontSize || 14,
25 }; 44 };
26 }); 45 });
27 46
@@ -29,7 +48,12 @@ @@ -29,7 +48,12 @@
29 const handleChange = async (event: Event) => { 48 const handleChange = async (event: Event) => {
30 const target = event.target as HTMLInputElement; 49 const target = event.target as HTMLInputElement;
31 const value = target.checked; 50 const value = target.checked;
32 - const flag = await sendCommand(props.config.option, value); 51 + const { option } = props.config || {};
  52 +
  53 + const { values, isModbusCommand, sendValue } =
  54 + (await getSendValues(option, unref(getDesign), value)) || {};
  55 +
  56 + const flag = await sendCommand(values, isModbusCommand ? sendValue : value, isModbusCommand);
33 flag ? (currentValue.value = value) : (target.checked = !value); 57 flag ? (currentValue.value = value) : (target.checked = !value);
34 }; 58 };
35 59
@@ -60,9 +84,11 @@ @@ -60,9 +84,11 @@
60 </div> 84 </div>
61 </label> 85 </label>
62 </div> 86 </div>
63 - <div class="text-center mt-2 text-gray-500" :style="getScale">{{  
64 - getDesign.attribute || '属性'  
65 - }}</div> 87 + <div
  88 + class="text-center mt-2 text-gray-500"
  89 + :style="{ ...getScale, fontSize: getDesign.fontSize + 'px' }"
  90 + >{{ getDesign.attribute || '属性' }}</div
  91 + >
66 </Spin> 92 </Spin>
67 </main> 93 </main>
68 </main> 94 </main>
@@ -13,8 +13,11 @@ export const option: PublicPresetOptions = { @@ -13,8 +13,11 @@ export const option: PublicPresetOptions = {
13 [ComponentConfigFieldEnum.SHOW_DEVICE_NAME]: false, 13 [ComponentConfigFieldEnum.SHOW_DEVICE_NAME]: false,
14 [ComponentConfigFieldEnum.CONTROL_BAR_COLOR]: '#0072ff', 14 [ComponentConfigFieldEnum.CONTROL_BAR_COLOR]: '#0072ff',
15 [ComponentConfigFieldEnum.FONT_COLOR]: '#000000', 15 [ComponentConfigFieldEnum.FONT_COLOR]: '#000000',
  16 + [ComponentConfigFieldEnum.TEXT_COLOR]: '#000000',
16 [ComponentConfigFieldEnum.MIN_NUMBER]: 0, 17 [ComponentConfigFieldEnum.MIN_NUMBER]: 0,
17 [ComponentConfigFieldEnum.MAX_NUMBER]: 100, 18 [ComponentConfigFieldEnum.MAX_NUMBER]: 100,
  19 + [ComponentConfigFieldEnum.FONT_SIZE]: 14,
  20 + [ComponentConfigFieldEnum.VALUE_SIZE]: 20,
18 }; 21 };
19 22
20 export default class Config extends PublicConfigClass implements CreateComponentType { 23 export default class Config extends PublicConfigClass implements CreateComponentType {
@@ -8,20 +8,39 @@ @@ -8,20 +8,39 @@
8 const [register, { getFieldsValue, setFieldsValue, resetFields }] = useForm({ 8 const [register, { getFieldsValue, setFieldsValue, resetFields }] = useForm({
9 schemas: [ 9 schemas: [
10 { 10 {
11 - field: ComponentConfigFieldEnum.CONTROL_BAR_COLOR,  
12 - label: '控制栏背景色', 11 + field: ComponentConfigFieldEnum.FONT_COLOR,
  12 + label: '数值字体颜色',
13 component: 'ColorPicker', 13 component: 'ColorPicker',
14 changeEvent: 'update:value', 14 changeEvent: 'update:value',
15 - defaultValue: option.controlBarColor, 15 + defaultValue: option.fontColor,
16 }, 16 },
17 { 17 {
18 - field: ComponentConfigFieldEnum.FONT_COLOR,  
19 - label: '数值字体颜色', 18 + field: ComponentConfigFieldEnum.VALUE_SIZE,
  19 + label: '数值字体大小',
  20 + component: 'InputNumber',
  21 + defaultValue: option.fontSize,
  22 + },
  23 + {
  24 + field: ComponentConfigFieldEnum.TEXT_COLOR,
  25 + label: '文本字体颜色',
20 component: 'ColorPicker', 26 component: 'ColorPicker',
21 changeEvent: 'update:value', 27 changeEvent: 'update:value',
22 defaultValue: option.fontColor, 28 defaultValue: option.fontColor,
23 }, 29 },
24 { 30 {
  31 + field: ComponentConfigFieldEnum.FONT_SIZE,
  32 + label: '文本字体大小',
  33 + component: 'InputNumber',
  34 + defaultValue: option.fontSize,
  35 + },
  36 + {
  37 + field: ComponentConfigFieldEnum.CONTROL_BAR_COLOR,
  38 + label: '控制栏背景色',
  39 + component: 'ColorPicker',
  40 + changeEvent: 'update:value',
  41 + defaultValue: option.controlBarColor,
  42 + },
  43 + {
25 field: ComponentConfigFieldEnum.MIN_NUMBER, 44 field: ComponentConfigFieldEnum.MIN_NUMBER,
26 label: '最小值', 45 label: '最小值',
27 component: 'InputNumber', 46 component: 'InputNumber',
@@ -61,6 +80,7 @@ @@ -61,6 +80,7 @@
61 }; 80 };
62 }, 81 },
63 }, 82 },
  83 +
64 { 84 {
65 field: ComponentConfigFieldEnum.SHOW_DEVICE_NAME, 85 field: ComponentConfigFieldEnum.SHOW_DEVICE_NAME,
66 label: '显示设备名称', 86 label: '显示设备名称',
@@ -32,6 +32,10 @@ @@ -32,6 +32,10 @@
32 transportType: value.transportType, 32 transportType: value.transportType,
33 service: value.service, 33 service: value.service,
34 command: value.command, 34 command: value.command,
  35 + openService: value.openService,
  36 + closeService: value.closeService,
  37 + openCommand: value.openCommand,
  38 + closeCommand: value.closeCommand,
35 commandType: value.commandType, 39 commandType: value.commandType,
36 }, 40 },
37 }; 41 };
@@ -42,10 +46,14 @@ @@ -42,10 +46,14 @@
42 const { customCommand } = record; 46 const { customCommand } = record;
43 return setFieldsValue({ 47 return setFieldsValue({
44 ...record, 48 ...record,
45 - transportType: customCommand?.transportType,  
46 - service: customCommand?.service,  
47 - command: customCommand?.command,  
48 - commandType: customCommand?.commandType, 49 + transportType: customCommand?.transportType || (record as Recordable).transportType,
  50 + service: customCommand?.service || (record as Recordable).service,
  51 + openService: customCommand?.openService || (record as Recordable).openService,
  52 + closeService: customCommand?.closeService || (record as Recordable).closeService,
  53 + openCommand: customCommand?.openCommand || (record as Recordable).openCommand,
  54 + closeCommand: customCommand?.closeCommand || (record as Recordable).closeCommand,
  55 + command: customCommand?.command || (record as Recordable).command,
  56 + commandType: customCommand?.commandType || (record as Recordable).command,
49 } as unknown as Partial<CommonDataSourceBindValueType>); 57 } as unknown as Partial<CommonDataSourceBindValueType>);
50 }; 58 };
51 59
@@ -9,6 +9,10 @@ @@ -9,6 +9,10 @@
9 import { useReceiveValue } from '../../../hook/useReceiveValue'; 9 import { useReceiveValue } from '../../../hook/useReceiveValue';
10 import { DataFetchUpdateFn } from '../../../hook/socket/useSocket.type'; 10 import { DataFetchUpdateFn } from '../../../hook/socket/useSocket.type';
11 import { useDataFetch } from '../../../hook/socket/useSocket'; 11 import { useDataFetch } from '../../../hook/socket/useSocket';
  12 + import { TaskTypeEnum } from '/@/views/task/center/config';
  13 + import { useMessage } from '/@/hooks/web/useMessage';
  14 + import { SingleToHex } from '/@/views/device/list/cpns/tabs/ObjectModelCommandDeliveryModal/config';
  15 + import { genModbusCommand } from '/@/api/task';
12 16
13 const props = defineProps<{ 17 const props = defineProps<{
14 config: ComponentPropsConfigType<typeof option>; 18 config: ComponentPropsConfigType<typeof option>;
@@ -23,20 +27,42 @@ @@ -23,20 +27,42 @@
23 27
24 const getDesign = computed(() => { 28 const getDesign = computed(() => {
25 const { option, persetOption } = props.config; 29 const { option, persetOption } = props.config;
26 - const { componentInfo, attribute, attributeRename, attributeName } = option; 30 + const {
  31 + componentInfo,
  32 + attribute,
  33 + attributeRename,
  34 + attributeName,
  35 + commandType,
  36 + extensionDesc,
  37 + codeType,
  38 + deviceCode,
  39 + customCommand,
  40 + } = option;
27 const { 41 const {
28 controlBarColor: persetControlBarColor, 42 controlBarColor: persetControlBarColor,
29 fonColor: persetFontColor, 43 fonColor: persetFontColor,
30 minNumber: persetMinNumber, 44 minNumber: persetMinNumber,
31 maxNumber: persetMaxNumber, 45 maxNumber: persetMaxNumber,
  46 + textColor: persetTextColor,
  47 + valueSize: persetValueSize,
  48 + fontSize: persetFontSize,
32 } = persetOption || {}; 49 } = persetOption || {};
33 - const { controlBarColor, fontColor, minNumber, maxNumber } = componentInfo || {}; 50 + const { controlBarColor, fontColor, minNumber, maxNumber, textColor, valueSize, fontSize } =
  51 + componentInfo || {};
34 return { 52 return {
35 attribute: attributeRename || attributeName || attribute, 53 attribute: attributeRename || attributeName || attribute,
36 controlBarColor: controlBarColor ?? persetControlBarColor, 54 controlBarColor: controlBarColor ?? persetControlBarColor,
37 fontColor: fontColor ?? persetFontColor, 55 fontColor: fontColor ?? persetFontColor,
38 minNumber: minNumber ?? persetMinNumber, 56 minNumber: minNumber ?? persetMinNumber,
39 maxNumber: maxNumber ?? persetMaxNumber, 57 maxNumber: maxNumber ?? persetMaxNumber,
  58 + extensionDesc: extensionDesc ? JSON.parse(extensionDesc) : {},
  59 + commandType,
  60 + codeType,
  61 + deviceCode,
  62 + customCommand,
  63 + textColor: textColor || persetTextColor,
  64 + valueSize: valueSize || persetValueSize || 20,
  65 + fontSize: fontSize || persetFontSize || 14,
40 }; 66 };
41 }); 67 });
42 68
@@ -59,9 +85,98 @@ @@ -59,9 +85,98 @@
59 sliderValue.value = afterValue.value; //这一步是因为当我们是点击不是拖动时候,会让值更新不了,所以需要赋值一次 85 sliderValue.value = afterValue.value; //这一步是因为当我们是点击不是拖动时候,会让值更新不了,所以需要赋值一次
60 }; 86 };
61 87
  88 + const { createMessage } = useMessage();
  89 +
  90 + // 获取小数
  91 + const getFloatPart = (number: string | number) => {
  92 + const isLessZero = Number(number) < 0;
  93 + number = number.toString();
  94 + const floatPartStartIndex = number.indexOf('.');
  95 + const value = ~floatPartStartIndex
  96 + ? `${isLessZero ? '-' : ''}0.${number.substring(floatPartStartIndex + 1)}`
  97 + : '0';
  98 + return Number(value);
  99 + };
  100 +
  101 + const getArray = (values) => {
  102 + const str = values.replace(/\s+/g, '');
  103 + const array: any = [];
  104 +
  105 + for (let i = 0; i < str.length; i += 4) {
  106 + const chunk = parseInt(str.substring(i, i + 4), 16);
  107 + array.push(chunk);
  108 + }
  109 + return array;
  110 + };
  111 +
  112 + const getSendValue = async (value: number) => {
  113 + const { extensionDesc, codeType, deviceCode, customCommand } = unref(getDesign) || {};
  114 + const { transportType } = customCommand || {};
  115 + const { registerAddress, actionType, zoomFactor } = extensionDesc || {};
  116 + const newZoomValue = zoomFactor ? Number(zoomFactor) : 1;
  117 + if (transportType == 'TCP' && codeType == TaskTypeEnum.MODBUS_RTU) {
  118 + if (!deviceCode) {
  119 + createMessage.warning('当前设备没有设置地址码');
  120 + return;
  121 + }
  122 + const modbusForm = ref({
  123 + crc: 'CRC_16_LOWER',
  124 + deviceCode: deviceCode,
  125 + method: actionType == '16' ? '10' : actionType,
  126 + registerAddress,
  127 + registerNumber: 1,
  128 + registerValues: [value],
  129 + }) as any;
  130 + if (!actionType) {
  131 + createMessage.warning('当前物模型扩展描述没有填写');
  132 + return;
  133 + }
  134 + if (actionType == '06') {
  135 + const newValue = Math.trunc(value) * newZoomValue + getFloatPart(value) * newZoomValue;
  136 + if (newValue % 1 != 0) {
  137 + createMessage.warning(`值必须是整数,缩放因子为${unref(newZoomValue)}`);
  138 + return;
  139 + }
  140 +
  141 + if (newValue > 65535) {
  142 + createMessage.warning(`值不能超过65535,缩放因子是${unref(newZoomValue)}`);
  143 + return;
  144 + }
  145 + modbusForm.value.registerValues = [newValue];
  146 + }
  147 + if (actionType == '05') {
  148 + if (Number(value) != 0 || Number(value) != 1) {
  149 + createMessage.warning(`当前物模型仅支持值为0和1`);
  150 + return;
  151 + }
  152 + }
  153 + if (actionType == '16' || actionType == '10') {
  154 + const regex = /^-?\d+(\.\d{0,2})?$/;
  155 + const values =
  156 + Math.trunc(value) * unref(newZoomValue) + getFloatPart(value) * unref(newZoomValue);
  157 + if (!regex.test(values as any)) {
  158 + createMessage.warning(`值精确到两位小数,缩放因子是${unref(newZoomValue)}`);
  159 + return;
  160 + }
  161 + const newValue = values == 0 ? [0, 0] : getArray(SingleToHex(values));
  162 + modbusForm.value.registerValues = newValue;
  163 + modbusForm.value.registerNumber = 2;
  164 + modbusForm.value.method = '10';
  165 + }
  166 + const sendValue = await genModbusCommand(unref(modbusForm));
  167 + return sendValue;
  168 + }
  169 + };
  170 +
62 const handleBlur = async () => { 171 const handleBlur = async () => {
63 if (unref(oldSliderValue) !== unref(sliderValue)) { 172 if (unref(oldSliderValue) !== unref(sliderValue)) {
64 - const flag = await sendCommand(props.config.option, unref(sliderValue)); 173 + const { codeType, customCommand } = unref(getDesign) || {};
  174 + const { transportType } = customCommand || {};
  175 + const sendValue = ref<any>(unref(sliderValue));
  176 + if (transportType == 'TCP' && codeType == TaskTypeEnum.MODBUS_RTU) {
  177 + sendValue.value = await getSendValue(unref(sliderValue));
  178 + }
  179 + const flag = await sendCommand(props.config.option, unref(sendValue), true);
65 flag 180 flag
66 ? ((sliderValue.value = unref(sliderValue)), 181 ? ((sliderValue.value = unref(sliderValue)),
67 (oldSliderValue.value = sliderValue.value), 182 (oldSliderValue.value = sliderValue.value),
@@ -90,7 +205,7 @@ @@ -90,7 +205,7 @@
90 <Spin :spinning="loading" class="w-full h-full"> 205 <Spin :spinning="loading" class="w-full h-full">
91 <div class="flex flex-col" style="width: 80%"> 206 <div class="flex flex-col" style="width: 80%">
92 <span 207 <span
93 - :style="{ color: getDesign.fontColor }" 208 + :style="{ color: getDesign.fontColor, fontSize: getDesign.valueSize + 'px' }"
94 class="font-bold text-xl mt-3 truncate text-center" 209 class="font-bold text-xl mt-3 truncate text-center"
95 >{{ sliderValue }}</span 210 >{{ sliderValue }}</span
96 > 211 >
@@ -107,7 +222,7 @@ @@ -107,7 +222,7 @@
107 /> 222 />
108 223
109 <span 224 <span
110 - :style="{ color: getDesign.fontColor }" 225 + :style="{ color: getDesign.textColor, fontSize: getDesign.fontSize + 'px' }"
111 class="mt-3 truncate font-bold text-xs text-center" 226 class="mt-3 truncate font-bold text-xs text-center"
112 > 227 >
113 {{ getDesign.attribute || '属性' }} 228 {{ getDesign.attribute || '属性' }}
@@ -14,6 +14,7 @@ export const option: PublicPresetOptions = { @@ -14,6 +14,7 @@ export const option: PublicPresetOptions = {
14 [ComponentConfigFieldEnum.ICON]: 'shuiwen', 14 [ComponentConfigFieldEnum.ICON]: 'shuiwen',
15 [ComponentConfigFieldEnum.ICON_COLOR]: '#377DFF', 15 [ComponentConfigFieldEnum.ICON_COLOR]: '#377DFF',
16 [ComponentConfigFieldEnum.SHOW_DEVICE_NAME]: false, 16 [ComponentConfigFieldEnum.SHOW_DEVICE_NAME]: false,
  17 + [ComponentConfigFieldEnum.FONT_SIZE]: 14,
17 }; 18 };
18 19
19 export default class Config extends PublicConfigClass implements CreateComponentType { 20 export default class Config extends PublicConfigClass implements CreateComponentType {
@@ -27,6 +27,12 @@ @@ -27,6 +27,12 @@
27 }, 27 },
28 }, 28 },
29 { 29 {
  30 + field: ComponentConfigFieldEnum.FONT_SIZE,
  31 + label: '文本字体大小',
  32 + component: 'InputNumber',
  33 + defaultValue: option.fontSize,
  34 + },
  35 + {
30 field: ComponentConfigFieldEnum.SHOW_DEVICE_NAME, 36 field: ComponentConfigFieldEnum.SHOW_DEVICE_NAME,
31 label: '显示设备名称', 37 label: '显示设备名称',
32 component: 'Checkbox', 38 component: 'Checkbox',
@@ -32,6 +32,10 @@ @@ -32,6 +32,10 @@
32 transportType: value.transportType, 32 transportType: value.transportType,
33 service: value.service, 33 service: value.service,
34 command: value.command, 34 command: value.command,
  35 + openService: value.openService,
  36 + closeService: value.closeService,
  37 + openCommand: value.openCommand,
  38 + closeCommand: value.closeCommand,
35 commandType: value.commandType, 39 commandType: value.commandType,
36 callType: value.callType, 40 callType: value.callType,
37 }, 41 },
@@ -45,6 +49,10 @@ @@ -45,6 +49,10 @@
45 ...record, 49 ...record,
46 transportType: customCommand?.transportType || (record as Recordable).transportType, 50 transportType: customCommand?.transportType || (record as Recordable).transportType,
47 service: customCommand?.service || (record as Recordable).service, 51 service: customCommand?.service || (record as Recordable).service,
  52 + openService: customCommand?.openService || (record as Recordable).openService,
  53 + closeService: customCommand?.closeService || (record as Recordable).closeService,
  54 + openCommand: customCommand?.openCommand || (record as Recordable).openCommand,
  55 + closeCommand: customCommand?.closeCommand || (record as Recordable).closeCommand,
48 command: customCommand?.command || (record as Recordable).command, 56 command: customCommand?.command || (record as Recordable).command,
49 commandType: customCommand?.commandType || (record as Recordable).commandType, 57 commandType: customCommand?.commandType || (record as Recordable).commandType,
50 callType: customCommand?.callType || (record as Recordable).callType, 58 callType: customCommand?.callType || (record as Recordable).callType,
@@ -5,6 +5,6 @@ const componentKeys = useComponentKeys('SwitchList'); @@ -5,6 +5,6 @@ const componentKeys = useComponentKeys('SwitchList');
5 5
6 export const SwitchListConfig: ConfigType = { 6 export const SwitchListConfig: ConfigType = {
7 ...componentKeys, 7 ...componentKeys,
8 - title: '开关控制列表', 8 + title: '开关控制列表',
9 package: PackagesCategoryEnum.CONTROL, 9 package: PackagesCategoryEnum.CONTROL,
10 }; 10 };
@@ -13,6 +13,7 @@ @@ -13,6 +13,7 @@
13 import { useReceiveMessage } from '../../../hook/useReceiveMessage'; 13 import { useReceiveMessage } from '../../../hook/useReceiveMessage';
14 import { useReceiveValue } from '../../../hook/useReceiveValue'; 14 import { useReceiveValue } from '../../../hook/useReceiveValue';
15 import { DataSource } from '/@/views/visual/palette/types'; 15 import { DataSource } from '/@/views/visual/palette/types';
  16 + import { getSendValues, CommandTypeEnumLIst } from '../config';
16 17
17 const props = defineProps<{ 18 const props = defineProps<{
18 config: ComponentPropsConfigType<typeof option>; 19 config: ComponentPropsConfigType<typeof option>;
@@ -51,12 +52,24 @@ @@ -51,12 +52,24 @@
51 fontColor: persetFontColor, 52 fontColor: persetFontColor,
52 icon: persetIcon, 53 icon: persetIcon,
53 iconColor: persetIconColor, 54 iconColor: persetIconColor,
  55 + fontSize: persetFontSize,
54 } = persetOption || {}; 56 } = persetOption || {};
55 return { 57 return {
56 dataSource: dataSource.map((item) => { 58 dataSource: dataSource.map((item) => {
57 - const { fontColor, icon, iconColor, unit, showDeviceName } = item.componentInfo;  
58 - const { attribute, attributeRename, attributeName, deviceId, deviceName, deviceRename } =  
59 - item; 59 + const { fontColor, icon, iconColor, unit, showDeviceName, fontSize } = item.componentInfo;
  60 + const {
  61 + attribute,
  62 + attributeRename,
  63 + attributeName,
  64 + deviceId,
  65 + deviceName,
  66 + deviceRename,
  67 + commandType,
  68 + extensionDesc,
  69 + codeType,
  70 + deviceCode,
  71 + customCommand,
  72 + } = item;
60 return { 73 return {
61 unit: unit ?? persetUnit, 74 unit: unit ?? persetUnit,
62 fontColor: fontColor ?? persetFontColor, 75 fontColor: fontColor ?? persetFontColor,
@@ -67,6 +80,12 @@ @@ -67,6 +80,12 @@
67 showDeviceName, 80 showDeviceName,
68 deviceName: deviceRename || deviceName, 81 deviceName: deviceRename || deviceName,
69 id: deviceId, 82 id: deviceId,
  83 + extensionDesc: extensionDesc ? JSON.parse(extensionDesc) : {},
  84 + commandType,
  85 + codeType,
  86 + deviceCode,
  87 + customCommand,
  88 + fontSize: fontSize || persetFontSize || 14,
70 }; 89 };
71 }), 90 }),
72 }; 91 };
@@ -76,7 +95,6 @@ @@ -76,7 +95,6 @@
76 const handleChange = async (index: number, checked: Boolean) => { 95 const handleChange = async (index: number, checked: Boolean) => {
77 const { heightPx, itemHeightRatio, itemWidthRatio, mode, widthPx, dataSource } = 96 const { heightPx, itemHeightRatio, itemWidthRatio, mode, widthPx, dataSource } =
78 props.config.option; 97 props.config.option;
79 -  
80 const data = { 98 const data = {
81 ...dataSource?.[index], 99 ...dataSource?.[index],
82 heightPx, 100 heightPx,
@@ -85,8 +103,10 @@ @@ -85,8 +103,10 @@
85 mode, 103 mode,
86 widthPx, 104 widthPx,
87 } as DataSource; 105 } as DataSource;
  106 + const { values, isModbusCommand, sendValue } =
  107 + (await getSendValues(data, unref(getDesign).dataSource[index], checked)) || {};
88 108
89 - const flag = await sendCommand(data, checked); 109 + const flag = await sendCommand(values, isModbusCommand ? sendValue : checked, isModbusCommand);
90 if (!flag) controlList.value[index].checked = !checked; 110 if (!flag) controlList.value[index].checked = !checked;
91 }; 111 };
92 112
@@ -128,15 +148,15 @@ @@ -128,15 +148,15 @@
128 <SvgIcon 148 <SvgIcon
129 :name="item.icon!" 149 :name="item.icon!"
130 prefix="iconfont" 150 prefix="iconfont"
131 - :size="getRatio ? 30 * getRatio : 30" 151 + :size="getRatio ? 25 * getRatio : 25"
132 :style="{ color: item.iconColor }" 152 :style="{ color: item.iconColor }"
133 /> 153 />
134 154
135 - <div  
136 - class="text-gray-500 truncate ml-6"  
137 - :style="{ fontSize: getRatio ? '18px' : getRatio * 18 + 'px' }"  
138 - >{{ `${item.deviceName} - ${item.attributeName}` }}</div  
139 - > 155 + <div class="text-gray-500 truncate ml-6" :style="{ fontSize: item.fontSize + 'px' }">{{
  156 + `${item.deviceName} - ${
  157 + item.commandType ? CommandTypeEnumLIst[item.commandType].name : item.attributeName
  158 + }`
  159 + }}</div>
140 </div> 160 </div>
141 161
142 <Switch 162 <Switch
  1 +import { ref, unref } from 'vue';
  2 +import { TransportTypeEnum } from '/@/views/device/profiles/components/TransportDescript/const';
  3 +import { CommandTypeEnum } from '/@/views/rule/linkedge/config/config.data';
  4 +import { TaskTypeEnum } from '/@/views/task/center/config';
  5 +import { genModbusCommand } from '/@/api/task';
  6 +import { useMessage } from '/@/hooks/web/useMessage';
  7 +import { SingleToHex } from '/@/views/device/list/cpns/tabs/ObjectModelCommandDeliveryModal/config';
  8 +
  9 +const getArray = (values) => {
  10 + const str = values.replace(/\s+/g, '');
  11 + const array: any = [];
  12 +
  13 + for (let i = 0; i < str.length; i += 4) {
  14 + const chunk = parseInt(str.substring(i, i + 4), 16);
  15 + array.push(chunk);
  16 + }
  17 + return array;
  18 +};
  19 +
  20 +export const getSendValues = async (option, getDesign, checked) => {
  21 + const values: any = option;
  22 + const isModbusCommand = ref<boolean>(false); //判断是否是TCP设备-> 且设备标识符是modeBUs,切选择是下发命令类型是属性
  23 + const { extensionDesc, commandType, codeType, deviceCode, customCommand } = getDesign || {};
  24 + const { registerAddress, actionType } = extensionDesc || {};
  25 + const { openCommand, closeCommand, transportType } = customCommand || {};
  26 + const modBUS = ref<any>({});
  27 + const sendValue = ref();
  28 +
  29 + const { createMessage } = useMessage();
  30 + //判断是不是TCP类型设备
  31 + if (transportType === TransportTypeEnum.TCP) {
  32 + if (
  33 + //判断TCP下发类型是否是自定义还是服务
  34 + commandType === CommandTypeEnum.CUSTOM.toString() ||
  35 + commandType == CommandTypeEnum.SERVICE.toString()
  36 + ) {
  37 + values.customCommand.command = checked ? openCommand : closeCommand;
  38 + values.customCommand.command = values.customCommand.command
  39 + .replaceAll(/\s/g, '')
  40 + .toUpperCase();
  41 + }
  42 + if (
  43 + //判断命令下发类型是不是属性 且是modbus
  44 + commandType === CommandTypeEnum.ATTRIBUTE.toString() &&
  45 + codeType === TaskTypeEnum.MODBUS_RTU
  46 + ) {
  47 + if (!deviceCode) {
  48 + createMessage.warning('当前设备没有设置地址码');
  49 + return;
  50 + }
  51 + if (!actionType) {
  52 + createMessage.warning('当前物模型扩展描述没有填写');
  53 + return;
  54 + }
  55 + isModbusCommand.value = true;
  56 + modBUS.value = {
  57 + crc: 'CRC_16_LOWER',
  58 + deviceCode: deviceCode,
  59 + method: actionType == '16' ? '10' : actionType,
  60 + registerAddress,
  61 + registerNumber: 1,
  62 + registerValues: [Number(checked)],
  63 + };
  64 +
  65 + if (actionType == '16' || actionType == '10') {
  66 + const newValue = Number(checked) == 0 ? [0, 0] : getArray(SingleToHex(Number(checked)));
  67 + modBUS.value.registerValues = newValue;
  68 + modBUS.value.registerNumber = 2;
  69 + modBUS.value.method = '10';
  70 + }
  71 +
  72 + sendValue.value = await genModbusCommand(unref(modBUS));
  73 + }
  74 + }
  75 +
  76 + return { values, sendValue: unref(sendValue), isModbusCommand: unref(isModbusCommand) };
  77 +};
  78 +
  79 +export const CommandTypeEnumLIst = {
  80 + '0': { CUSTOM: 0, name: '自定义' },
  81 + '1': { CUSTOM: 0, name: '服务' },
  82 + '2': { CUSTOM: 0, name: '属性' },
  83 +};
@@ -13,6 +13,8 @@ export const option: PublicPresetOptions = { @@ -13,6 +13,8 @@ export const option: PublicPresetOptions = {
13 [ComponentConfigFieldEnum.SHOW_DEVICE_NAME]: false, 13 [ComponentConfigFieldEnum.SHOW_DEVICE_NAME]: false,
14 [ComponentConfigFieldEnum.UNIT]: 'm', 14 [ComponentConfigFieldEnum.UNIT]: 'm',
15 [ComponentConfigFieldEnum.MAX_NUMBER]: 100, 15 [ComponentConfigFieldEnum.MAX_NUMBER]: 100,
  16 + [ComponentConfigFieldEnum.VALUE_SIZE]: 20,
  17 + [ComponentConfigFieldEnum.FONT_SIZE]: 14,
16 [ComponentConfigFieldEnum.FONT_COLOR]: '#fff', 18 [ComponentConfigFieldEnum.FONT_COLOR]: '#fff',
17 [ComponentConfigFieldEnum.SHOW_TIME]: false, 19 [ComponentConfigFieldEnum.SHOW_TIME]: false,
18 [ComponentConfigFieldEnum.FLOWMETER_CONFIG]: { 20 [ComponentConfigFieldEnum.FLOWMETER_CONFIG]: {
@@ -10,7 +10,7 @@ @@ -10,7 +10,7 @@
10 schemas: [ 10 schemas: [
11 { 11 {
12 field: ComponentConfigFieldEnum.FONT_COLOR, 12 field: ComponentConfigFieldEnum.FONT_COLOR,
13 - label: '字体颜色', 13 + label: '数值字体颜色',
14 component: 'ColorPicker', 14 component: 'ColorPicker',
15 changeEvent: 'update:value', 15 changeEvent: 'update:value',
16 defaultValue: option.fontColor, 16 defaultValue: option.fontColor,
@@ -50,6 +50,40 @@ @@ -50,6 +50,40 @@
50 defaultValue: option.unit, 50 defaultValue: option.unit,
51 }, 51 },
52 { 52 {
  53 + field: ComponentConfigFieldEnum.VALUE_SIZE,
  54 + label: '数值字体大小',
  55 + component: 'InputNumber',
  56 + defaultValue: 14,
  57 + componentProps: {
  58 + min: 0,
  59 + formatter: (e) => {
  60 + const value = e.replace(/^0/g, '');
  61 + if (value) {
  62 + return value.replace(/^0/g, '');
  63 + } else {
  64 + return 0;
  65 + }
  66 + },
  67 + },
  68 + },
  69 + {
  70 + field: ComponentConfigFieldEnum.FONT_SIZE,
  71 + label: '文本字体大小',
  72 + component: 'InputNumber',
  73 + defaultValue: 14,
  74 + componentProps: {
  75 + min: 0,
  76 + formatter: (e) => {
  77 + const value = e.replace(/^0/g, '');
  78 + if (value) {
  79 + return value.replace(/^0/g, '');
  80 + } else {
  81 + return 0;
  82 + }
  83 + },
  84 + },
  85 + },
  86 + {
53 field: ComponentConfigFieldEnum.MAX_NUMBER, 87 field: ComponentConfigFieldEnum.MAX_NUMBER,
54 label: '最大值', 88 label: '最大值',
55 component: 'InputNumber', 89 component: 'InputNumber',
@@ -20,7 +20,8 @@ @@ -20,7 +20,8 @@
20 const getDesign = computed(() => { 20 const getDesign = computed(() => {
21 const { option, persetOption } = props.config; 21 const { option, persetOption } = props.config;
22 const { componentInfo, attribute, attributeName, attributeRename } = option; 22 const { componentInfo, attribute, attributeName, attributeRename } = option;
23 - const { flowmeterConfig, unit, fontColor, showTime, maxNumber } = componentInfo || {}; 23 + const { flowmeterConfig, unit, fontColor, showTime, maxNumber, valueSize, fontSize } =
  24 + componentInfo || {};
24 const { backgroundColor, waveFirst, waveSecond, waveThird } = flowmeterConfig || {}; 25 const { backgroundColor, waveFirst, waveSecond, waveThird } = flowmeterConfig || {};
25 const { 26 const {
26 flowmeterConfig: presetFlowmeterConfig, 27 flowmeterConfig: presetFlowmeterConfig,
@@ -28,6 +29,8 @@ @@ -28,6 +29,8 @@
28 fontColor: presetFontColor, 29 fontColor: presetFontColor,
29 showTime: persetShowTime, 30 showTime: persetShowTime,
30 maxNumber: persetMaxNumber, 31 maxNumber: persetMaxNumber,
  32 + valueSize: persetValueSize,
  33 + fontSize: persetFontSize,
31 } = persetOption || {}; 34 } = persetOption || {};
32 const { 35 const {
33 backgroundColor: presetBackgroundColor, 36 backgroundColor: presetBackgroundColor,
@@ -45,6 +48,8 @@ @@ -45,6 +48,8 @@
45 attribute: attributeRename || attributeName || attribute, 48 attribute: attributeRename || attributeName || attribute,
46 showTime: showTime ?? persetShowTime, 49 showTime: showTime ?? persetShowTime,
47 maxNumber: maxNumber ?? persetMaxNumber, 50 maxNumber: maxNumber ?? persetMaxNumber,
  51 + valueSize: valueSize || persetValueSize || 20,
  52 + fontSize: fontSize || persetFontSize || 14,
48 }; 53 };
49 }); 54 });
50 55
@@ -129,14 +134,17 @@ @@ -129,14 +134,17 @@
129 134
130 <div 135 <div
131 class="absolute w-full h-full top-0 left-0 text-center text-lg flex items-center justify-center" 136 class="absolute w-full h-full top-0 left-0 text-center text-lg flex items-center justify-center"
132 - :style="{ color: getDesign.fontColor }" 137 + :style="{ color: getDesign.fontColor, fontSize: getDesign.valueSize + 'px' }"
133 > 138 >
134 <div>{{ currentValue }}</div> 139 <div>{{ currentValue }}</div>
135 <div class="ml-1">{{ getDesign.unit }}</div> 140 <div class="ml-1">{{ getDesign.unit }}</div>
136 </div> 141 </div>
137 - <div class="text-gray-500 text-sm truncate" style="flex: 0 0 20px">{{  
138 - getDesign.attribute || '属性'  
139 - }}</div> 142 + <div
  143 + class="text-gray-500 text-sm truncate"
  144 + style="flex: 0 0 20px"
  145 + :style="{ fontSize: getDesign.fontSize + 'px' }"
  146 + >{{ getDesign.attribute || '属性' }}</div
  147 + >
140 <UpdateTime v-show="getDesign.showTime" :time="time" /> 148 <UpdateTime v-show="getDesign.showTime" :time="time" />
141 </main> 149 </main>
142 </template> 150 </template>
@@ -14,6 +14,8 @@ export const option: PublicPresetOptions = { @@ -14,6 +14,8 @@ export const option: PublicPresetOptions = {
14 [ComponentConfigFieldEnum.SHOW_TIME]: false, 14 [ComponentConfigFieldEnum.SHOW_TIME]: false,
15 [ComponentConfigFieldEnum.UNIT]: 'm', 15 [ComponentConfigFieldEnum.UNIT]: 'm',
16 [ComponentConfigFieldEnum.MAX_NUMBER]: 100, 16 [ComponentConfigFieldEnum.MAX_NUMBER]: 100,
  17 + [ComponentConfigFieldEnum.FONT_SIZE]: 14,
  18 + [ComponentConfigFieldEnum.VALUE_SIZE]: 20,
17 [ComponentConfigFieldEnum.FLOWMETER_CONFIG]: { 19 [ComponentConfigFieldEnum.FLOWMETER_CONFIG]: {
18 [ComponentConfigFieldEnum.BACKGROUND_COLOR]: '#8badcb', 20 [ComponentConfigFieldEnum.BACKGROUND_COLOR]: '#8badcb',
19 [ComponentConfigFieldEnum.WAVE_FIRST]: '#4579e2', 21 [ComponentConfigFieldEnum.WAVE_FIRST]: '#4579e2',
@@ -10,7 +10,7 @@ @@ -10,7 +10,7 @@
10 schemas: [ 10 schemas: [
11 { 11 {
12 field: ComponentConfigFieldEnum.FONT_COLOR, 12 field: ComponentConfigFieldEnum.FONT_COLOR,
13 - label: '字体颜色', 13 + label: '数值字体颜色',
14 component: 'ColorPicker', 14 component: 'ColorPicker',
15 changeEvent: 'update:value', 15 changeEvent: 'update:value',
16 defaultValue: option.fontColor, 16 defaultValue: option.fontColor,
@@ -56,6 +56,40 @@ @@ -56,6 +56,40 @@
56 // defaultValue: 0, 56 // defaultValue: 0,
57 // }, 57 // },
58 { 58 {
  59 + field: ComponentConfigFieldEnum.VALUE_SIZE,
  60 + label: '数值字体大小',
  61 + component: 'InputNumber',
  62 + defaultValue: 14,
  63 + componentProps: {
  64 + min: 0,
  65 + formatter: (e) => {
  66 + const value = e.replace(/^0/g, '');
  67 + if (value) {
  68 + return value.replace(/^0/g, '');
  69 + } else {
  70 + return 0;
  71 + }
  72 + },
  73 + },
  74 + },
  75 + {
  76 + field: ComponentConfigFieldEnum.FONT_SIZE,
  77 + label: '文本字体大小',
  78 + component: 'InputNumber',
  79 + defaultValue: 14,
  80 + componentProps: {
  81 + min: 0,
  82 + formatter: (e) => {
  83 + const value = e.replace(/^0/g, '');
  84 + if (value) {
  85 + return value.replace(/^0/g, '');
  86 + } else {
  87 + return 0;
  88 + }
  89 + },
  90 + },
  91 + },
  92 + {
59 field: ComponentConfigFieldEnum.MAX_NUMBER, 93 field: ComponentConfigFieldEnum.MAX_NUMBER,
60 label: '最大值', 94 label: '最大值',
61 component: 'InputNumber', 95 component: 'InputNumber',
@@ -20,7 +20,8 @@ @@ -20,7 +20,8 @@
20 const getDesign = computed(() => { 20 const getDesign = computed(() => {
21 const { option, persetOption } = props.config; 21 const { option, persetOption } = props.config;
22 const { componentInfo, attribute, attributeName, attributeRename } = option; 22 const { componentInfo, attribute, attributeName, attributeRename } = option;
23 - const { flowmeterConfig, unit, fontColor, showTime, maxNumber } = componentInfo || {}; 23 + const { flowmeterConfig, unit, fontColor, showTime, maxNumber, fontSize, valueSize } =
  24 + componentInfo || {};
24 const { backgroundColor, waveFirst, waveSecond, waveThird } = flowmeterConfig || {}; 25 const { backgroundColor, waveFirst, waveSecond, waveThird } = flowmeterConfig || {};
25 const { 26 const {
26 flowmeterConfig: presetFlowmeterConfig, 27 flowmeterConfig: presetFlowmeterConfig,
@@ -28,6 +29,8 @@ @@ -28,6 +29,8 @@
28 fontColor: presetFontColor, 29 fontColor: presetFontColor,
29 showTime: persetShowTime, 30 showTime: persetShowTime,
30 maxNumber: persetMaxNumber, 31 maxNumber: persetMaxNumber,
  32 + fontSize: persetFontSize,
  33 + valueSize: persetValueSize,
31 } = persetOption || {}; 34 } = persetOption || {};
32 const { 35 const {
33 backgroundColor: presetBackgroundColor, 36 backgroundColor: presetBackgroundColor,
@@ -45,6 +48,8 @@ @@ -45,6 +48,8 @@
45 attribute: attributeRename || attributeName || attribute, 48 attribute: attributeRename || attributeName || attribute,
46 showTime: showTime ?? persetShowTime, 49 showTime: showTime ?? persetShowTime,
47 maxNumber: maxNumber ?? persetMaxNumber, 50 maxNumber: maxNumber ?? persetMaxNumber,
  51 + fontSize: fontSize || persetFontSize || 14,
  52 + valueSize: valueSize || persetValueSize || 20,
48 }; 53 };
49 }); 54 });
50 55
@@ -122,14 +127,17 @@ @@ -122,14 +127,17 @@
122 </svg> 127 </svg>
123 <div 128 <div
124 class="absolute w-full h-full top-0 left-0 text-center text-lg flex items-center justify-center" 129 class="absolute w-full h-full top-0 left-0 text-center text-lg flex items-center justify-center"
125 - :style="{ color: getDesign.fontColor }" 130 + :style="{ color: getDesign.fontColor, fontSize: getDesign.valueSize + 'px' }"
126 > 131 >
127 <div>{{ currentValue }}</div> 132 <div>{{ currentValue }}</div>
128 <div class="ml-1">{{ getDesign.unit }}</div> 133 <div class="ml-1">{{ getDesign.unit }}</div>
129 </div> 134 </div>
130 - <div class="text-gray-500 text-sm truncate" style="flex: 0 0 20px">{{  
131 - getDesign.attribute || '属性'  
132 - }}</div> 135 + <div
  136 + class="text-gray-500"
  137 + style="flex: 0 0 20px"
  138 + :style="{ fontSize: getDesign.fontSize + 'px', height: getDesign.fontSize + 'px' }"
  139 + >{{ getDesign.attribute || '属性' }}</div
  140 + >
133 <UpdateTime v-show="getDesign.showTime" :time="time" /> 141 <UpdateTime v-show="getDesign.showTime" :time="time" />
134 </main> 142 </main>
135 </template> 143 </template>
@@ -27,6 +27,8 @@ export const option: PublicPresetOptions = { @@ -27,6 +27,8 @@ export const option: PublicPresetOptions = {
27 [ComponentConfigFieldEnum.UNIT]: '℃', 27 [ComponentConfigFieldEnum.UNIT]: '℃',
28 [ComponentConfigFieldEnum.POINTER_COLOR]: '#15E2C6', 28 [ComponentConfigFieldEnum.POINTER_COLOR]: '#15E2C6',
29 [ComponentConfigFieldEnum.INSTRUMENT_PANEL_COLOR]: '#61D4C5', 29 [ComponentConfigFieldEnum.INSTRUMENT_PANEL_COLOR]: '#61D4C5',
  30 + [ComponentConfigFieldEnum.FONT_SIZE]: 14,
  31 + [ComponentConfigFieldEnum.VALUE_SIZE]: 14,
30 [ComponentConfigFieldEnum.GRADIENT_INFO]: [ 32 [ComponentConfigFieldEnum.GRADIENT_INFO]: [
31 { key: Gradient.FIRST, value: 0, color: GradientColor.FIRST }, 33 { key: Gradient.FIRST, value: 0, color: GradientColor.FIRST },
32 { key: Gradient.SECOND, value: 1, color: GradientColor.SECOND }, 34 { key: Gradient.SECOND, value: 1, color: GradientColor.SECOND },
@@ -43,26 +43,6 @@ @@ -43,26 +43,6 @@
43 changeEvent: 'update:value', 43 changeEvent: 'update:value',
44 defaultValue: GradientColor.SECOND, 44 defaultValue: GradientColor.SECOND,
45 }, 45 },
46 - // {  
47 - // field: ComponentConfigFieldEnum.INSTRUMENT_PANEL_WIDTH,  
48 - // label: '仪表盘宽度',  
49 - // component: 'Slider',  
50 - // changeEvent: 'update:value',  
51 - // defaultValue: option.pointerColor,  
52 - // },  
53 - {  
54 - field: ComponentConfigFieldEnum.SHOW_DEVICE_NAME,  
55 - label: '显示设备名称',  
56 - component: 'Checkbox',  
57 - defaultValue: option.showDeviceName,  
58 - },  
59 - {  
60 - field: ComponentConfigFieldEnum.SHOW_TIME,  
61 - label: '显示时间',  
62 - component: 'Checkbox',  
63 - defaultValue: option.showTime,  
64 - },  
65 -  
66 { 46 {
67 field: ComponentConfigFieldEnum.UNIT, 47 field: ComponentConfigFieldEnum.UNIT,
68 label: '数值单位', 48 label: '数值单位',
@@ -70,6 +50,40 @@ @@ -70,6 +50,40 @@
70 defaultValue: option.unit, 50 defaultValue: option.unit,
71 }, 51 },
72 { 52 {
  53 + field: ComponentConfigFieldEnum.VALUE_SIZE,
  54 + label: '数值字体大小',
  55 + component: 'InputNumber',
  56 + defaultValue: 14,
  57 + componentProps: {
  58 + min: 0,
  59 + formatter: (e) => {
  60 + const value = e.replace(/^0/g, '');
  61 + if (value) {
  62 + return value.replace(/^0/g, '');
  63 + } else {
  64 + return 0;
  65 + }
  66 + },
  67 + },
  68 + },
  69 + {
  70 + field: ComponentConfigFieldEnum.FONT_SIZE,
  71 + label: '文本字体大小',
  72 + component: 'InputNumber',
  73 + defaultValue: 14,
  74 + componentProps: {
  75 + min: 0,
  76 + formatter: (e) => {
  77 + const value = e.replace(/^0/g, '');
  78 + if (value) {
  79 + return value.replace(/^0/g, '');
  80 + } else {
  81 + return 0;
  82 + }
  83 + },
  84 + },
  85 + },
  86 + {
73 field: ComponentConfigFieldEnum.MAX_NUMBER, 87 field: ComponentConfigFieldEnum.MAX_NUMBER,
74 label: '最大值', 88 label: '最大值',
75 component: 'InputNumber', 89 component: 'InputNumber',
@@ -90,6 +104,18 @@ @@ -90,6 +104,18 @@
90 }; 104 };
91 }, 105 },
92 }, 106 },
  107 + {
  108 + field: ComponentConfigFieldEnum.SHOW_DEVICE_NAME,
  109 + label: '显示设备名称',
  110 + component: 'Checkbox',
  111 + defaultValue: option.showDeviceName,
  112 + },
  113 + {
  114 + field: ComponentConfigFieldEnum.SHOW_TIME,
  115 + label: '显示时间',
  116 + component: 'Checkbox',
  117 + defaultValue: option.showTime,
  118 + },
93 ], 119 ],
94 showActionButtonGroup: false, 120 showActionButtonGroup: false,
95 labelWidth: 120, 121 labelWidth: 120,
@@ -120,13 +146,24 @@ @@ -120,13 +146,24 @@
120 showTime: item[ComponentConfigFieldEnum.SHOW_TIME], 146 showTime: item[ComponentConfigFieldEnum.SHOW_TIME],
121 pointerColor: item[ComponentConfigFieldEnum.POINTER_COLOR], 147 pointerColor: item[ComponentConfigFieldEnum.POINTER_COLOR],
122 maxNumber: item[ComponentConfigFieldEnum.MAX_NUMBER], 148 maxNumber: item[ComponentConfigFieldEnum.MAX_NUMBER],
  149 + fontSize: item[ComponentConfigFieldEnum.FONT_SIZE],
  150 + valueSize: item[ComponentConfigFieldEnum.VALUE_SIZE],
123 } as ComponentInfo; 151 } as ComponentInfo;
124 }; 152 };
125 153
126 const setFormValues = (data: Recordable) => { 154 const setFormValues = (data: Recordable) => {
127 // return setFieldsValue(data); 155 // return setFieldsValue(data);
128 - const { gradientInfo, unit, fontColor, showDeviceName, pointerColor, showTime, maxNumber } =  
129 - data; 156 + const {
  157 + gradientInfo,
  158 + unit,
  159 + fontColor,
  160 + showDeviceName,
  161 + pointerColor,
  162 + showTime,
  163 + maxNumber,
  164 + fontSize,
  165 + valueSize,
  166 + } = data;
130 const firstRecord = gradientInfo.find((item) => item.key === Gradient.FIRST); 167 const firstRecord = gradientInfo.find((item) => item.key === Gradient.FIRST);
131 const secondRecord = gradientInfo.find((item) => item.key === Gradient.SECOND); 168 const secondRecord = gradientInfo.find((item) => item.key === Gradient.SECOND);
132 169
@@ -141,6 +178,8 @@ @@ -141,6 +178,8 @@
141 [ComponentConfigFieldEnum.SECOND_PHASE_COLOR]: secondRecord?.color, 178 [ComponentConfigFieldEnum.SECOND_PHASE_COLOR]: secondRecord?.color,
142 [ComponentConfigFieldEnum.POINTER_COLOR]: pointerColor, 179 [ComponentConfigFieldEnum.POINTER_COLOR]: pointerColor,
143 [ComponentConfigFieldEnum.MAX_NUMBER]: maxNumber, 180 [ComponentConfigFieldEnum.MAX_NUMBER]: maxNumber,
  181 + [ComponentConfigFieldEnum.FONT_SIZE]: fontSize,
  182 + [ComponentConfigFieldEnum.VALUE_SIZE]: valueSize,
144 }; 183 };
145 return setFieldsValue(value); 184 return setFieldsValue(value);
146 }; 185 };
@@ -32,6 +32,8 @@ @@ -32,6 +32,8 @@
32 gradientInfo: presetGradientInfo, 32 gradientInfo: presetGradientInfo,
33 showTime: persetShowTime, 33 showTime: persetShowTime,
34 maxNumber: persetMaxNumber, 34 maxNumber: persetMaxNumber,
  35 + fontSize: persetFontSize,
  36 + valueSize: persetValueSize,
35 } = persetOption || {}; 37 } = persetOption || {};
36 const { 38 const {
37 unit, 39 unit,
@@ -41,6 +43,8 @@ @@ -41,6 +43,8 @@
41 gradientInfo, 43 gradientInfo,
42 showTime, 44 showTime,
43 maxNumber, 45 maxNumber,
  46 + fontSize,
  47 + valueSize,
44 } = componentInfo || {}; 48 } = componentInfo || {};
45 return { 49 return {
46 unit: unit ?? presetUnit, 50 unit: unit ?? presetUnit,
@@ -51,6 +55,8 @@ @@ -51,6 +55,8 @@
51 gradientInfo: gradientInfo ?? presetGradientInfo, 55 gradientInfo: gradientInfo ?? presetGradientInfo,
52 showTime: showTime ?? persetShowTime, 56 showTime: showTime ?? persetShowTime,
53 maxNumber: maxNumber || persetMaxNumber, 57 maxNumber: maxNumber || persetMaxNumber,
  58 + fontSize: fontSize || persetFontSize || 14,
  59 + valueSize: valueSize || persetValueSize || 14,
54 }; 60 };
55 }); 61 });
56 62
@@ -66,7 +72,7 @@ @@ -66,7 +72,7 @@
66 }; 72 };
67 73
68 const options = (): EChartsOption => { 74 const options = (): EChartsOption => {
69 - const { unit, fontColor, pointerColor, gradientInfo, maxNumber } = unref(getDesign); 75 + const { unit, fontColor, pointerColor, gradientInfo, maxNumber, valueSize } = unref(getDesign);
70 76
71 const instrumentPanelColor = getStageColor(gradientInfo); 77 const instrumentPanelColor = getStageColor(gradientInfo);
72 // getStageColor(gradientInfo); 78 // getStageColor(gradientInfo);
@@ -108,7 +114,7 @@ @@ -108,7 +114,7 @@
108 //指针 114 //指针
109 show: true, 115 show: true,
110 icon: 'path://M2090.36389,615.30999 L2090.36389,615.30999 C2091.48372,615.30999 2092.40383,616.194028 2092.44859,617.312956 L2096.90698,728.755929 C2097.05155,732.369577 2094.2393,735.416212 2090.62566,735.56078 C2090.53845,735.564269 2090.45117,735.566014 2090.36389,735.566014 L2090.36389,735.566014 C2086.74736,735.566014 2083.81557,732.63423 2083.81557,729.017692 C2083.81557,728.930412 2083.81732,728.84314 2083.82081,728.755929 L2088.2792,617.312956 C2088.32396,616.194028 2089.24407,615.30999 2090.36389,615.30999 Z', 116 icon: 'path://M2090.36389,615.30999 L2090.36389,615.30999 C2091.48372,615.30999 2092.40383,616.194028 2092.44859,617.312956 L2096.90698,728.755929 C2097.05155,732.369577 2094.2393,735.416212 2090.62566,735.56078 C2090.53845,735.564269 2090.45117,735.566014 2090.36389,735.566014 L2090.36389,735.566014 C2086.74736,735.566014 2083.81557,732.63423 2083.81557,729.017692 C2083.81557,728.930412 2083.81732,728.84314 2083.82081,728.755929 L2088.2792,617.312956 C2088.32396,616.194028 2089.24407,615.30999 2090.36389,615.30999 Z',
111 - width: 4 * unref(getRatio) ? 4 * unref(getRatio) : 4, 117 + width: unref(getRatio) ? 4 * unref(getRatio) : 4,
112 length: '100%', 118 length: '100%',
113 itemStyle: { 119 itemStyle: {
114 color: pointerColor, 120 color: pointerColor,
@@ -128,7 +134,7 @@ @@ -128,7 +134,7 @@
128 }, 134 },
129 detail: { 135 detail: {
130 valueAnimation: true, 136 valueAnimation: true,
131 - fontSize: 14 * unref(getRatio), 137 + fontSize: unref(getRatio) ? valueSize * unref(getRatio) : valueSize,
132 fontWeight: 'bolder', 138 fontWeight: 'bolder',
133 formatter: `{value} ${unit ?? ''}`, 139 formatter: `{value} ${unit ?? ''}`,
134 color: fontColor || 'inherit', 140 color: fontColor || 'inherit',
@@ -199,7 +205,7 @@ @@ -199,7 +205,7 @@
199 width: 4 * unref(getRatio), 205 width: 4 * unref(getRatio),
200 }, 206 },
201 detail: { 207 detail: {
202 - fontSize: 14 * unref(getRatio), 208 + fontSize: unref(getDesign).valueSize * unref(getRatio),
203 }, 209 },
204 }, 210 },
205 ], 211 ],
@@ -219,9 +225,11 @@ @@ -219,9 +225,11 @@
219 <div class="w-full h-full flex flex-1 flex-col justify-center items-center"> 225 <div class="w-full h-full flex flex-1 flex-col justify-center items-center">
220 <div ref="chartRefEl" class="flex-1 w-full h-6/7 flex flex-col justify-center items-center"> 226 <div ref="chartRefEl" class="flex-1 w-full h-6/7 flex flex-col justify-center items-center">
221 </div> 227 </div>
222 - <div class="text-gray-500 text-xs text-center truncate">{{  
223 - getDesign.attribute || '湿度'  
224 - }}</div> 228 + <div
  229 + class="text-gray-500 text-center truncate"
  230 + :style="{ fontSize: getDesign.fontSize + 'px' }"
  231 + >{{ getDesign.attribute || '湿度' }}</div
  232 + >
225 </div> 233 </div>
226 <UpdateTime v-if="getDesign.showTime" :time="time" /> 234 <UpdateTime v-if="getDesign.showTime" :time="time" />
227 </main> 235 </main>
@@ -26,6 +26,8 @@ export const option: PublicPresetOptions = { @@ -26,6 +26,8 @@ export const option: PublicPresetOptions = {
26 [ComponentConfigFieldEnum.POINTER_COLOR]: '#15E2C6', 26 [ComponentConfigFieldEnum.POINTER_COLOR]: '#15E2C6',
27 [ComponentConfigFieldEnum.INSTRUMENT_PANEL_COLOR]: '#61D4C5', 27 [ComponentConfigFieldEnum.INSTRUMENT_PANEL_COLOR]: '#61D4C5',
28 [ComponentConfigFieldEnum.MAX_NUMBER]: 100, 28 [ComponentConfigFieldEnum.MAX_NUMBER]: 100,
  29 + [ComponentConfigFieldEnum.FONT_SIZE]: 14,
  30 + [ComponentConfigFieldEnum.VALUE_SIZE]: 14,
29 [ComponentConfigFieldEnum.GRADIENT_INFO]: [ 31 [ComponentConfigFieldEnum.GRADIENT_INFO]: [
30 { key: Gradient.FIRST, value: 0, color: GradientColor.FIRST }, 32 { key: Gradient.FIRST, value: 0, color: GradientColor.FIRST },
31 { key: Gradient.SECOND, value: 1, color: GradientColor.SECOND }, 33 { key: Gradient.SECOND, value: 1, color: GradientColor.SECOND },
@@ -43,24 +43,6 @@ @@ -43,24 +43,6 @@
43 defaultValue: GradientColor.SECOND, 43 defaultValue: GradientColor.SECOND,
44 }, 44 },
45 { 45 {
46 - field: ComponentConfigFieldEnum.PROGRESS_BAR_CIRCLE,  
47 - label: '显示进度条圆形',  
48 - component: 'Checkbox',  
49 - defaultValue: option.progressBarCircle,  
50 - },  
51 - {  
52 - field: ComponentConfigFieldEnum.SHOW_DEVICE_NAME,  
53 - label: '显示设备名称',  
54 - component: 'Checkbox',  
55 - defaultValue: option.showDeviceName,  
56 - },  
57 - {  
58 - field: ComponentConfigFieldEnum.SHOW_TIME,  
59 - label: '显示时间',  
60 - component: 'Checkbox',  
61 - defaultValue: option.showTime,  
62 - },  
63 - {  
64 field: ComponentConfigFieldEnum.MAX_NUMBER, 46 field: ComponentConfigFieldEnum.MAX_NUMBER,
65 label: '最大值', 47 label: '最大值',
66 component: 'InputNumber', 48 component: 'InputNumber',
@@ -81,6 +63,58 @@ @@ -81,6 +63,58 @@
81 }; 63 };
82 }, 64 },
83 }, 65 },
  66 + {
  67 + field: ComponentConfigFieldEnum.VALUE_SIZE,
  68 + label: '数值字体大小',
  69 + component: 'InputNumber',
  70 + defaultValue: 14,
  71 + componentProps: {
  72 + min: 0,
  73 + formatter: (e) => {
  74 + const value = e.replace(/^0/g, '');
  75 + if (value) {
  76 + return value.replace(/^0/g, '');
  77 + } else {
  78 + return 0;
  79 + }
  80 + },
  81 + },
  82 + },
  83 + {
  84 + field: ComponentConfigFieldEnum.FONT_SIZE,
  85 + label: '文本字体大小',
  86 + component: 'InputNumber',
  87 + defaultValue: 14,
  88 + componentProps: {
  89 + min: 0,
  90 + formatter: (e) => {
  91 + const value = e.replace(/^0/g, '');
  92 + if (value) {
  93 + return value.replace(/^0/g, '');
  94 + } else {
  95 + return 0;
  96 + }
  97 + },
  98 + },
  99 + },
  100 + {
  101 + field: ComponentConfigFieldEnum.PROGRESS_BAR_CIRCLE,
  102 + label: '显示进度条圆形',
  103 + component: 'Checkbox',
  104 + defaultValue: option.progressBarCircle,
  105 + },
  106 + {
  107 + field: ComponentConfigFieldEnum.SHOW_DEVICE_NAME,
  108 + label: '显示设备名称',
  109 + component: 'Checkbox',
  110 + defaultValue: option.showDeviceName,
  111 + },
  112 + {
  113 + field: ComponentConfigFieldEnum.SHOW_TIME,
  114 + label: '显示时间',
  115 + component: 'Checkbox',
  116 + defaultValue: option.showTime,
  117 + },
84 ], 118 ],
85 showActionButtonGroup: false, 119 showActionButtonGroup: false,
86 labelWidth: 120, 120 labelWidth: 120,
@@ -111,6 +145,8 @@ @@ -111,6 +145,8 @@
111 showTime: item[ComponentConfigFieldEnum.SHOW_TIME], 145 showTime: item[ComponentConfigFieldEnum.SHOW_TIME],
112 progressBarCircle: item[ComponentConfigFieldEnum.PROGRESS_BAR_CIRCLE], 146 progressBarCircle: item[ComponentConfigFieldEnum.PROGRESS_BAR_CIRCLE],
113 maxNumber: item[ComponentConfigFieldEnum.MAX_NUMBER], 147 maxNumber: item[ComponentConfigFieldEnum.MAX_NUMBER],
  148 + valueSize: item[ComponentConfigFieldEnum.VALUE_SIZE],
  149 + fontSize: item[ComponentConfigFieldEnum.FONT_SIZE],
114 } as ComponentInfo; 150 } as ComponentInfo;
115 }; 151 };
116 152
@@ -124,6 +160,8 @@ @@ -124,6 +160,8 @@
124 progressBarCircle, 160 progressBarCircle,
125 showTime, 161 showTime,
126 maxNumber, 162 maxNumber,
  163 + valueSize,
  164 + fontSize,
127 } = data; 165 } = data;
128 const firstRecord = gradientInfo.find((item) => item.key === Gradient.FIRST); 166 const firstRecord = gradientInfo.find((item) => item.key === Gradient.FIRST);
129 const secondRecord = gradientInfo.find((item) => item.key === Gradient.SECOND); 167 const secondRecord = gradientInfo.find((item) => item.key === Gradient.SECOND);
@@ -139,6 +177,8 @@ @@ -139,6 +177,8 @@
139 [ComponentConfigFieldEnum.SECOND_PHASE_COLOR]: secondRecord?.color, 177 [ComponentConfigFieldEnum.SECOND_PHASE_COLOR]: secondRecord?.color,
140 [ComponentConfigFieldEnum.PROGRESS_BAR_CIRCLE]: progressBarCircle, 178 [ComponentConfigFieldEnum.PROGRESS_BAR_CIRCLE]: progressBarCircle,
141 [ComponentConfigFieldEnum.MAX_NUMBER]: maxNumber, 179 [ComponentConfigFieldEnum.MAX_NUMBER]: maxNumber,
  180 + [ComponentConfigFieldEnum.VALUE_SIZE]: valueSize,
  181 + [ComponentConfigFieldEnum.FONT_SIZE]: fontSize,
142 }; 182 };
143 return setFieldsValue(value); 183 return setFieldsValue(value);
144 }; 184 };
@@ -33,6 +33,8 @@ @@ -33,6 +33,8 @@
33 gradientInfo: presetGradientInfo, 33 gradientInfo: presetGradientInfo,
34 showTime: persetShowTime, 34 showTime: persetShowTime,
35 maxNumber: persetMaxNumber, 35 maxNumber: persetMaxNumber,
  36 + fontSize: persetFontSize,
  37 + valueSize: persetValueSize,
36 } = persetOption || {}; 38 } = persetOption || {};
37 const { 39 const {
38 unit, 40 unit,
@@ -43,6 +45,8 @@ @@ -43,6 +45,8 @@
43 instrumentPanelColor, 45 instrumentPanelColor,
44 showTime, 46 showTime,
45 maxNumber, 47 maxNumber,
  48 + fontSize,
  49 + valueSize,
46 } = componentInfo || {}; 50 } = componentInfo || {};
47 return { 51 return {
48 unit: unit ?? presetUnit, 52 unit: unit ?? presetUnit,
@@ -54,6 +58,8 @@ @@ -54,6 +58,8 @@
54 gradientInfo: gradientInfo ?? presetGradientInfo, 58 gradientInfo: gradientInfo ?? presetGradientInfo,
55 showTime: showTime ?? persetShowTime, 59 showTime: showTime ?? persetShowTime,
56 maxNumber: maxNumber || persetMaxNumber, 60 maxNumber: maxNumber || persetMaxNumber,
  61 + fontSize: fontSize || persetFontSize || 14,
  62 + valueSize: valueSize || persetValueSize || 14,
57 }; 63 };
58 }); 64 });
59 65
@@ -71,7 +77,8 @@ @@ -71,7 +77,8 @@
71 const titleValue = ref<number>(20); 77 const titleValue = ref<number>(20);
72 78
73 const options = (): EChartsOption => { 79 const options = (): EChartsOption => {
74 - const { unit, fontColor, progressBarCircle, gradientInfo, maxNumber } = unref(getDesign); 80 + const { unit, fontColor, progressBarCircle, gradientInfo, maxNumber, valueSize } =
  81 + unref(getDesign);
75 const instrumentPanelColor = getStageColor(gradientInfo); 82 const instrumentPanelColor = getStageColor(gradientInfo);
76 return { 83 return {
77 title: { 84 title: {
@@ -79,7 +86,7 @@ @@ -79,7 +86,7 @@
79 top: 'center', 86 top: 'center',
80 left: 'center', 87 left: 'center',
81 textStyle: { 88 textStyle: {
82 - fontSize: unref(getRatio) ? 14 * unref(getRatio) : 14, 89 + fontSize: unref(getRatio) ? valueSize * unref(getRatio) : valueSize,
83 color: fontColor || '#65d3ff', 90 color: fontColor || '#65d3ff',
84 valueAnimation: true, 91 valueAnimation: true,
85 }, 92 },
@@ -210,7 +217,7 @@ @@ -210,7 +217,7 @@
210 ], 217 ],
211 title: { 218 title: {
212 textStyle: { 219 textStyle: {
213 - fontSize: 14 * unref(getRatio), 220 + fontSize: unref(getDesign).valueSize * unref(getRatio),
214 }, 221 },
215 }, 222 },
216 }); 223 });
@@ -229,9 +236,11 @@ @@ -229,9 +236,11 @@
229 <div class="flex w-full h-full flex-col justify-center items-center flex-1"> 236 <div class="flex w-full h-full flex-col justify-center items-center flex-1">
230 <div ref="chartRefEl" class="flex-1 w-full h-6/7 flex-col justify-center items-center flex"> 237 <div ref="chartRefEl" class="flex-1 w-full h-6/7 flex-col justify-center items-center flex">
231 </div> 238 </div>
232 - <div class="text-gray-500 text-xs text-center truncate">{{  
233 - getDesign.attribute || '湿度'  
234 - }}</div> 239 + <div
  240 + class="text-gray-500 text-center truncate"
  241 + :style="{ fontSize: getDesign.fontSize + 'px' }"
  242 + >{{ getDesign.attribute || '湿度' }}</div
  243 + >
235 </div> 244 </div>
236 <UpdateTime v-if="getDesign.showTime" :time="time" /> 245 <UpdateTime v-if="getDesign.showTime" :time="time" />
237 </main> 246 </main>
@@ -23,6 +23,8 @@ export const option: PublicPresetOptions = { @@ -23,6 +23,8 @@ export const option: PublicPresetOptions = {
23 [ComponentConfigFieldEnum.SHOW_TIME]: false, 23 [ComponentConfigFieldEnum.SHOW_TIME]: false,
24 [ComponentConfigFieldEnum.MAX_NUMBER]: 100, 24 [ComponentConfigFieldEnum.MAX_NUMBER]: 100,
25 [ComponentConfigFieldEnum.UNIT]: 'kw', 25 [ComponentConfigFieldEnum.UNIT]: 'kw',
  26 + [ComponentConfigFieldEnum.FONT_SIZE]: 14,
  27 + [ComponentConfigFieldEnum.VALUE_SIZE]: 14,
26 }; 28 };
27 29
28 export default class Config extends PublicConfigClass implements CreateComponentType { 30 export default class Config extends PublicConfigClass implements CreateComponentType {
@@ -22,18 +22,6 @@ @@ -22,18 +22,6 @@
22 defaultValue: option.unit, 22 defaultValue: option.unit,
23 }, 23 },
24 { 24 {
25 - field: ComponentConfigFieldEnum.SHOW_DEVICE_NAME,  
26 - label: '显示设备名称',  
27 - component: 'Checkbox',  
28 - defaultValue: option.showDeviceName,  
29 - },  
30 - {  
31 - field: ComponentConfigFieldEnum.SHOW_TIME,  
32 - label: '显示时间',  
33 - component: 'Checkbox',  
34 - defaultValue: option.showTime,  
35 - },  
36 - {  
37 field: ComponentConfigFieldEnum.MAX_NUMBER, 25 field: ComponentConfigFieldEnum.MAX_NUMBER,
38 label: '最大值', 26 label: '最大值',
39 component: 'InputNumber', 27 component: 'InputNumber',
@@ -54,6 +42,52 @@ @@ -54,6 +42,52 @@
54 }; 42 };
55 }, 43 },
56 }, 44 },
  45 + {
  46 + field: ComponentConfigFieldEnum.VALUE_SIZE,
  47 + label: '数值字体大小',
  48 + component: 'InputNumber',
  49 + defaultValue: 14,
  50 + componentProps: {
  51 + min: 0,
  52 + formatter: (e) => {
  53 + const value = e.replace(/^0/g, '');
  54 + if (value) {
  55 + return value.replace(/^0/g, '');
  56 + } else {
  57 + return 0;
  58 + }
  59 + },
  60 + },
  61 + },
  62 + {
  63 + field: ComponentConfigFieldEnum.FONT_SIZE,
  64 + label: '文本字体大小',
  65 + component: 'InputNumber',
  66 + defaultValue: 14,
  67 + componentProps: {
  68 + min: 0,
  69 + formatter: (e) => {
  70 + const value = e.replace(/^0/g, '');
  71 + if (value) {
  72 + return value.replace(/^0/g, '');
  73 + } else {
  74 + return 0;
  75 + }
  76 + },
  77 + },
  78 + },
  79 + {
  80 + field: ComponentConfigFieldEnum.SHOW_DEVICE_NAME,
  81 + label: '显示设备名称',
  82 + component: 'Checkbox',
  83 + defaultValue: option.showDeviceName,
  84 + },
  85 + {
  86 + field: ComponentConfigFieldEnum.SHOW_TIME,
  87 + label: '显示时间',
  88 + component: 'Checkbox',
  89 + defaultValue: option.showTime,
  90 + },
57 ], 91 ],
58 showActionButtonGroup: false, 92 showActionButtonGroup: false,
59 labelWidth: 120, 93 labelWidth: 120,
@@ -71,12 +105,14 @@ @@ -71,12 +105,14 @@
71 showDeviceName: item[ComponentConfigFieldEnum.SHOW_DEVICE_NAME], 105 showDeviceName: item[ComponentConfigFieldEnum.SHOW_DEVICE_NAME],
72 showTime: item[ComponentConfigFieldEnum.SHOW_TIME], 106 showTime: item[ComponentConfigFieldEnum.SHOW_TIME],
73 maxNumber: item[ComponentConfigFieldEnum.MAX_NUMBER], 107 maxNumber: item[ComponentConfigFieldEnum.MAX_NUMBER],
  108 + fontSize: item[ComponentConfigFieldEnum.FONT_SIZE],
  109 + valueSize: item[ComponentConfigFieldEnum.VALUE_SIZE],
74 } as ComponentInfo; 110 } as ComponentInfo;
75 }; 111 };
76 112
77 const setFormValues = (data: Recordable) => { 113 const setFormValues = (data: Recordable) => {
78 // return setFieldsValue(data); 114 // return setFieldsValue(data);
79 - const { unit, fontColor, showDeviceName, showTime, maxNumber } = data; 115 + const { unit, fontColor, showDeviceName, showTime, maxNumber, fontSize, valueSize } = data;
80 116
81 const value = { 117 const value = {
82 [ComponentConfigFieldEnum.UNIT]: unit, 118 [ComponentConfigFieldEnum.UNIT]: unit,
@@ -84,6 +120,8 @@ @@ -84,6 +120,8 @@
84 [ComponentConfigFieldEnum.SHOW_DEVICE_NAME]: showDeviceName, 120 [ComponentConfigFieldEnum.SHOW_DEVICE_NAME]: showDeviceName,
85 [ComponentConfigFieldEnum.SHOW_TIME]: showTime, 121 [ComponentConfigFieldEnum.SHOW_TIME]: showTime,
86 [ComponentConfigFieldEnum.MAX_NUMBER]: maxNumber, 122 [ComponentConfigFieldEnum.MAX_NUMBER]: maxNumber,
  123 + [ComponentConfigFieldEnum.FONT_SIZE]: fontSize,
  124 + [ComponentConfigFieldEnum.VALUE_SIZE]: valueSize,
87 }; 125 };
88 return setFieldsValue(value); 126 return setFieldsValue(value);
89 }; 127 };
@@ -31,6 +31,8 @@ @@ -31,6 +31,8 @@
31 gradientInfo: presetGradientInfo, 31 gradientInfo: presetGradientInfo,
32 showTime: persetShowTime, 32 showTime: persetShowTime,
33 maxNumber: persetMaxNumber, 33 maxNumber: persetMaxNumber,
  34 + fontSize: persetFontSize,
  35 + valueSize: persetValueSize,
34 } = persetOption || {}; 36 } = persetOption || {};
35 const { 37 const {
36 unit, 38 unit,
@@ -40,6 +42,8 @@ @@ -40,6 +42,8 @@
40 gradientInfo, 42 gradientInfo,
41 showTime, 43 showTime,
42 maxNumber, 44 maxNumber,
  45 + fontSize,
  46 + valueSize,
43 } = componentInfo || {}; 47 } = componentInfo || {};
44 return { 48 return {
45 unit: unit ?? presetUnit, 49 unit: unit ?? presetUnit,
@@ -50,11 +54,13 @@ @@ -50,11 +54,13 @@
50 gradientInfo: gradientInfo ?? presetGradientInfo, 54 gradientInfo: gradientInfo ?? presetGradientInfo,
51 showTime: showTime ?? persetShowTime, 55 showTime: showTime ?? persetShowTime,
52 maxNumber: maxNumber || persetMaxNumber, 56 maxNumber: maxNumber || persetMaxNumber,
  57 + fontSize: fontSize || persetFontSize || 14,
  58 + valueSize: valueSize || persetValueSize || 14,
53 }; 59 };
54 }); 60 });
55 61
56 const options = (): EChartsOption => { 62 const options = (): EChartsOption => {
57 - const { unit, fontColor, pointerColor, maxNumber } = unref(getDesign); 63 + const { unit, fontColor, pointerColor, maxNumber, valueSize } = unref(getDesign);
58 64
59 // getStageColor(gradientInfo); 65 // getStageColor(gradientInfo);
60 return { 66 return {
@@ -110,7 +116,7 @@ @@ -110,7 +116,7 @@
110 }, 116 },
111 detail: { 117 detail: {
112 valueAnimation: true, 118 valueAnimation: true,
113 - fontSize: unref(getRatio) ? 16 * unref(getRatio) : 16, 119 + fontSize: unref(getRatio) ? valueSize * unref(getRatio) : valueSize,
114 offsetCenter: [0, '70%'], 120 offsetCenter: [0, '70%'],
115 formatter: `{value} ${unit ?? ''}`, 121 formatter: `{value} ${unit ?? ''}`,
116 color: fontColor || 'inherit', 122 color: fontColor || 'inherit',
@@ -191,7 +197,7 @@ @@ -191,7 +197,7 @@
191 }, 197 },
192 }, 198 },
193 detail: { 199 detail: {
194 - fontSize: 16 * unref(getRatio), 200 + fontSize: unref(getDesign).valueSize * unref(getRatio),
195 }, 201 },
196 }, 202 },
197 ], 203 ],
@@ -211,7 +217,7 @@ @@ -211,7 +217,7 @@
211 <div class="flex flex-1 flex-col justify-center items-center w-full h-full"> 217 <div class="flex flex-1 flex-col justify-center items-center w-full h-full">
212 <div ref="chartRefEl" class="flex-1 w-full h-6/7 flex flex-col justify-center items-center"> 218 <div ref="chartRefEl" class="flex-1 w-full h-6/7 flex flex-col justify-center items-center">
213 </div> 219 </div>
214 - <div class="text-gray-500 text-xs text-center truncate">{{ 220 + <div class="text-gray-500 text-center" :style="{ fontSize: getDesign.fontSize + 'px' }">{{
215 getDesign.attribute || '速度' 221 getDesign.attribute || '速度'
216 }}</div> 222 }}</div>
217 </div> 223 </div>
@@ -15,6 +15,8 @@ export const option: PublicPresetOptions = { @@ -15,6 +15,8 @@ export const option: PublicPresetOptions = {
15 [ComponentConfigFieldEnum.SHOW_TIME]: false, 15 [ComponentConfigFieldEnum.SHOW_TIME]: false,
16 [ComponentConfigFieldEnum.MAX_NUMBER]: 100, 16 [ComponentConfigFieldEnum.MAX_NUMBER]: 100,
17 [ComponentConfigFieldEnum.UNIT]: '℃', 17 [ComponentConfigFieldEnum.UNIT]: '℃',
  18 + [ComponentConfigFieldEnum.VALUE_SIZE]: 14,
  19 + [ComponentConfigFieldEnum.FONT_SIZE]: 14,
18 }; 20 };
19 21
20 export default class Config extends PublicConfigClass implements CreateComponentType { 22 export default class Config extends PublicConfigClass implements CreateComponentType {
@@ -53,6 +53,40 @@ @@ -53,6 +53,40 @@
53 }; 53 };
54 }, 54 },
55 }, 55 },
  56 + {
  57 + field: ComponentConfigFieldEnum.VALUE_SIZE,
  58 + label: '数值字体大小',
  59 + component: 'InputNumber',
  60 + defaultValue: 14,
  61 + componentProps: {
  62 + min: 0,
  63 + formatter: (e) => {
  64 + const value = e.replace(/^0/g, '');
  65 + if (value) {
  66 + return value.replace(/^0/g, '');
  67 + } else {
  68 + return 0;
  69 + }
  70 + },
  71 + },
  72 + },
  73 + {
  74 + field: ComponentConfigFieldEnum.FONT_SIZE,
  75 + label: '文本字体大小',
  76 + component: 'InputNumber',
  77 + defaultValue: 14,
  78 + componentProps: {
  79 + min: 0,
  80 + formatter: (e) => {
  81 + const value = e.replace(/^0/g, '');
  82 + if (value) {
  83 + return value.replace(/^0/g, '');
  84 + } else {
  85 + return 0;
  86 + }
  87 + },
  88 + },
  89 + },
56 ], 90 ],
57 showActionButtonGroup: false, 91 showActionButtonGroup: false,
58 labelWidth: 120, 92 labelWidth: 120,
@@ -32,19 +32,23 @@ @@ -32,19 +32,23 @@
32 unit: presetUnit, 32 unit: presetUnit,
33 showTime: persetShowTime, 33 showTime: persetShowTime,
34 maxNumber: persetMaxNumber, 34 maxNumber: persetMaxNumber,
  35 + valueSize: persetValueSize,
  36 + fontSize: persetFontSize,
35 } = persetOption || {}; 37 } = persetOption || {};
36 - const { unit, fontColor, showTime, maxNumber } = componentInfo || {}; 38 + const { unit, fontColor, showTime, maxNumber, valueSize, fontSize } = componentInfo || {};
37 return { 39 return {
38 unit: unit ?? presetUnit, 40 unit: unit ?? presetUnit,
39 fontColor: fontColor ?? presetFontColor, 41 fontColor: fontColor ?? presetFontColor,
40 attribute: attributeRename || attributeName || attribute, 42 attribute: attributeRename || attributeName || attribute,
41 showTime: persetShowTime || showTime, 43 showTime: persetShowTime || showTime,
42 maxNumber: maxNumber || persetMaxNumber, 44 maxNumber: maxNumber || persetMaxNumber,
  45 + valueSize: valueSize || persetValueSize || 14,
  46 + fontSize: fontSize || persetFontSize || 14,
43 }; 47 };
44 }); 48 });
45 49
46 const options = (): EChartsOption => { 50 const options = (): EChartsOption => {
47 - const { unit, fontColor, maxNumber } = unref(getDesign); 51 + const { unit, fontColor, maxNumber, valueSize } = unref(getDesign);
48 return { 52 return {
49 series: [ 53 series: [
50 { 54 {
@@ -104,7 +108,7 @@ @@ -104,7 +108,7 @@
104 lineHeight: 10, 108 lineHeight: 10,
105 borderRadius: 8, 109 borderRadius: 8,
106 offsetCenter: [0, '40%'], 110 offsetCenter: [0, '40%'],
107 - fontSize: unref(getRatio) ? 14 * unref(getRatio) : 14, 111 + fontSize: unref(getRatio) ? valueSize * unref(getRatio) : valueSize,
108 fontWeight: 'bolder', 112 fontWeight: 'bolder',
109 formatter: `{value} ${unit ?? ''}`, 113 formatter: `{value} ${unit ?? ''}`,
110 color: fontColor || 'inherit', 114 color: fontColor || 'inherit',
@@ -200,7 +204,7 @@ @@ -200,7 +204,7 @@
200 series: [ 204 series: [
201 { 205 {
202 detail: { 206 detail: {
203 - fontSize: 14 * unref(getRatio), 207 + fontSize: unref(getDesign).valueSize * unref(getRatio),
204 }, 208 },
205 progress: { 209 progress: {
206 width: 24 * unref(getRatio), 210 width: 24 * unref(getRatio),
@@ -238,9 +242,11 @@ @@ -238,9 +242,11 @@
238 <div class="w-full h-full flex justify-center items-center flex-1 flex-col"> 242 <div class="w-full h-full flex justify-center items-center flex-1 flex-col">
239 <div ref="chartRefEl" class="flex-1 w-full h-6/7 flex justify-center items-center flex-col"> 243 <div ref="chartRefEl" class="flex-1 w-full h-6/7 flex justify-center items-center flex-col">
240 </div> 244 </div>
241 - <div class="text-gray-500 text-xs text-center truncate">{{  
242 - getDesign.attribute || '温度'  
243 - }}</div> 245 + <div
  246 + class="text-gray-500 text-center truncate"
  247 + :style="{ fontSize: getDesign.fontSize + 'px' }"
  248 + >{{ getDesign.attribute || '温度' }}</div
  249 + >
244 </div> 250 </div>
245 <UpdateTime v-show="getDesign.showTime" :time="time" /> 251 <UpdateTime v-show="getDesign.showTime" :time="time" />
246 </main> 252 </main>
@@ -31,6 +31,8 @@ export const option: PublicPresetOptions = { @@ -31,6 +31,8 @@ export const option: PublicPresetOptions = {
31 [ComponentConfigFieldEnum.SHOW_DEVICE_NAME]: false, 31 [ComponentConfigFieldEnum.SHOW_DEVICE_NAME]: false,
32 [ComponentConfigFieldEnum.SHOW_TIME]: false, 32 [ComponentConfigFieldEnum.SHOW_TIME]: false,
33 [ComponentConfigFieldEnum.MAX_NUMBER]: 100, 33 [ComponentConfigFieldEnum.MAX_NUMBER]: 100,
  34 + [ComponentConfigFieldEnum.FONT_SIZE]: 14,
  35 + [ComponentConfigFieldEnum.VALUE_SIZE]: 14,
34 }; 36 };
35 37
36 export default class Config extends PublicConfigClass implements CreateComponentType { 38 export default class Config extends PublicConfigClass implements CreateComponentType {
@@ -77,16 +77,38 @@ @@ -77,16 +77,38 @@
77 }, 77 },
78 }, 78 },
79 { 79 {
80 - field: ComponentConfigFieldEnum.SHOW_DEVICE_NAME,  
81 - label: '显示设备名称',  
82 - component: 'Checkbox',  
83 - defaultValue: option.showDeviceName, 80 + field: ComponentConfigFieldEnum.VALUE_SIZE,
  81 + label: '数值字体大小',
  82 + component: 'InputNumber',
  83 + defaultValue: 14,
  84 + componentProps: {
  85 + min: 0,
  86 + formatter: (e) => {
  87 + const value = e.replace(/^0/g, '');
  88 + if (value) {
  89 + return value.replace(/^0/g, '');
  90 + } else {
  91 + return 0;
  92 + }
  93 + },
  94 + },
84 }, 95 },
85 { 96 {
86 - field: ComponentConfigFieldEnum.SHOW_TIME,  
87 - label: '显示时间',  
88 - component: 'Checkbox',  
89 - defaultValue: option.showTime, 97 + field: ComponentConfigFieldEnum.FONT_SIZE,
  98 + label: '文本字体大小',
  99 + component: 'InputNumber',
  100 + defaultValue: 14,
  101 + componentProps: {
  102 + min: 0,
  103 + formatter: (e) => {
  104 + const value = e.replace(/^0/g, '');
  105 + if (value) {
  106 + return value.replace(/^0/g, '');
  107 + } else {
  108 + return 0;
  109 + }
  110 + },
  111 + },
90 }, 112 },
91 { 113 {
92 field: ComponentConfigFieldEnum.MAX_NUMBER, 114 field: ComponentConfigFieldEnum.MAX_NUMBER,
@@ -109,6 +131,18 @@ @@ -109,6 +131,18 @@
109 }; 131 };
110 }, 132 },
111 }, 133 },
  134 + {
  135 + field: ComponentConfigFieldEnum.SHOW_DEVICE_NAME,
  136 + label: '显示设备名称',
  137 + component: 'Checkbox',
  138 + defaultValue: option.showDeviceName,
  139 + },
  140 + {
  141 + field: ComponentConfigFieldEnum.SHOW_TIME,
  142 + label: '显示时间',
  143 + component: 'Checkbox',
  144 + defaultValue: option.showTime,
  145 + },
112 ], 146 ],
113 showActionButtonGroup: false, 147 showActionButtonGroup: false,
114 labelWidth: 120, 148 labelWidth: 120,
@@ -142,11 +176,22 @@ @@ -142,11 +176,22 @@
142 showDeviceName: value[ComponentConfigFieldEnum.SHOW_DEVICE_NAME], 176 showDeviceName: value[ComponentConfigFieldEnum.SHOW_DEVICE_NAME],
143 showTime: value[ComponentConfigFieldEnum.SHOW_TIME], 177 showTime: value[ComponentConfigFieldEnum.SHOW_TIME],
144 maxNumber: value[ComponentConfigFieldEnum.MAX_NUMBER], 178 maxNumber: value[ComponentConfigFieldEnum.MAX_NUMBER],
  179 + valueSize: value[ComponentConfigFieldEnum.VALUE_SIZE],
  180 + fontSize: value[ComponentConfigFieldEnum.FONT_SIZE],
145 } as ComponentInfo; 181 } as ComponentInfo;
146 }; 182 };
147 183
148 const setFormValues = (data: ComponentInfo) => { 184 const setFormValues = (data: ComponentInfo) => {
149 - const { gradientInfo, unit, fontColor, showDeviceName, showTime, maxNumber } = data; 185 + const {
  186 + gradientInfo,
  187 + unit,
  188 + fontColor,
  189 + showDeviceName,
  190 + showTime,
  191 + maxNumber,
  192 + valueSize,
  193 + fontSize,
  194 + } = data;
150 const firstRecord = gradientInfo.find((item) => item.key === Gradient.FIRST); 195 const firstRecord = gradientInfo.find((item) => item.key === Gradient.FIRST);
151 const secondRecord = gradientInfo.find((item) => item.key === Gradient.SECOND); 196 const secondRecord = gradientInfo.find((item) => item.key === Gradient.SECOND);
152 const thirdRecord = gradientInfo.find((item) => item.key === Gradient.THIRD); 197 const thirdRecord = gradientInfo.find((item) => item.key === Gradient.THIRD);
@@ -156,6 +201,8 @@ @@ -156,6 +201,8 @@
156 [ComponentConfigFieldEnum.SHOW_DEVICE_NAME]: showDeviceName, 201 [ComponentConfigFieldEnum.SHOW_DEVICE_NAME]: showDeviceName,
157 [ComponentConfigFieldEnum.SHOW_TIME]: showTime, 202 [ComponentConfigFieldEnum.SHOW_TIME]: showTime,
158 [ComponentConfigFieldEnum.MAX_NUMBER]: maxNumber, 203 [ComponentConfigFieldEnum.MAX_NUMBER]: maxNumber,
  204 + [ComponentConfigFieldEnum.VALUE_SIZE]: valueSize,
  205 + [ComponentConfigFieldEnum.FONT_SIZE]: fontSize,
159 [ComponentConfigFieldEnum.FIRST_PHASE_VALUE]: firstRecord?.value, 206 [ComponentConfigFieldEnum.FIRST_PHASE_VALUE]: firstRecord?.value,
160 [ComponentConfigFieldEnum.FIRST_PHASE_COLOR]: firstRecord?.color, 207 [ComponentConfigFieldEnum.FIRST_PHASE_COLOR]: firstRecord?.color,
161 [ComponentConfigFieldEnum.SECOND_PHASE_VALUE]: secondRecord?.value, 208 [ComponentConfigFieldEnum.SECOND_PHASE_VALUE]: secondRecord?.value,
@@ -38,9 +38,12 @@ @@ -38,9 +38,12 @@
38 gradientInfo: presetGradientInfo, 38 gradientInfo: presetGradientInfo,
39 showTime: persetShowTime, 39 showTime: persetShowTime,
40 maxNumber: persetMaxNumber, 40 maxNumber: persetMaxNumber,
  41 + fontSize: persetFontSize,
  42 + valueSize: persetValueSize,
41 } = persetOption || {}; 43 } = persetOption || {};
42 44
43 - const { unit, fontColor, gradientInfo, showTime, maxNumber } = componentInfo || {}; 45 + const { unit, fontColor, gradientInfo, showTime, maxNumber, fontSize, valueSize } =
  46 + componentInfo || {};
44 return { 47 return {
45 unit: unit ?? presetUnit, 48 unit: unit ?? presetUnit,
46 fontColor: fontColor ?? presetFontColor, 49 fontColor: fontColor ?? presetFontColor,
@@ -48,6 +51,8 @@ @@ -48,6 +51,8 @@
48 attribute: attributeRename || attributeName || attribute, 51 attribute: attributeRename || attributeName || attribute,
49 showTime: showTime || persetShowTime, 52 showTime: showTime || persetShowTime,
50 maxNumber: maxNumber || persetMaxNumber, 53 maxNumber: maxNumber || persetMaxNumber,
  54 + fontSize: fontSize || persetFontSize || 14,
  55 + valueSize: valueSize || persetValueSize || 14,
51 }; 56 };
52 }); 57 });
53 58
@@ -57,7 +62,7 @@ @@ -57,7 +62,7 @@
57 }; 62 };
58 63
59 const options = (): EChartsOption => { 64 const options = (): EChartsOption => {
60 - const { gradientInfo, unit, fontColor, maxNumber } = unref(getDesign); 65 + const { gradientInfo, unit, fontColor, maxNumber, valueSize } = unref(getDesign);
61 const firstRecord = getGradient(Gradient.FIRST, gradientInfo); 66 const firstRecord = getGradient(Gradient.FIRST, gradientInfo);
62 const secondRecord = getGradient(Gradient.SECOND, gradientInfo); 67 const secondRecord = getGradient(Gradient.SECOND, gradientInfo);
63 const thirdRecord = getGradient(Gradient.THIRD, gradientInfo); 68 const thirdRecord = getGradient(Gradient.THIRD, gradientInfo);
@@ -122,7 +127,7 @@ @@ -122,7 +127,7 @@
122 formatter: `{value} ${unit ?? ''}`, 127 formatter: `{value} ${unit ?? ''}`,
123 color: fontColor || 'inherit', 128 color: fontColor || 'inherit',
124 offsetCenter: [0, '70%'], 129 offsetCenter: [0, '70%'],
125 - fontSize: unref(getRatio) ? unref(getRatio) * 14 : 14, 130 + fontSize: unref(getRatio) ? unref(getRatio) * valueSize : valueSize,
126 }, 131 },
127 data: [ 132 data: [
128 { 133 {
@@ -194,7 +199,7 @@ @@ -194,7 +199,7 @@
194 fontSize: 6 * unref(getRatio), 199 fontSize: 6 * unref(getRatio),
195 }, 200 },
196 detail: { 201 detail: {
197 - fontSize: 14 * unref(getRatio), 202 + fontSize: unref(getDesign).valueSize * unref(getRatio),
198 }, 203 },
199 }, 204 },
200 ], 205 ],
@@ -218,7 +223,10 @@ @@ -218,7 +223,10 @@
218 <div class="w-full h-full flex justify-center items-center flex-col flex-1"> 223 <div class="w-full h-full flex justify-center items-center flex-col flex-1">
219 <div ref="chartRefEl" class="flex-1 w-full h-6/7 flex flex-col justify-center items-center"> 224 <div ref="chartRefEl" class="flex-1 w-full h-6/7 flex flex-col justify-center items-center">
220 </div> 225 </div>
221 - <div class="text-center text-gray-500 text-xs truncate"> 226 + <div
  227 + class="text-center text-gray-500 truncate"
  228 + :style="{ fontSize: getDesign.fontSize + 'px' }"
  229 + >
222 {{ getDesign.attribute || '速度' }} 230 {{ getDesign.attribute || '速度' }}
223 </div> 231 </div>
224 </div> 232 </div>
@@ -42,17 +42,17 @@ @@ -42,17 +42,17 @@
42 42
43 const handleGetVideoPlayUrl = async () => { 43 const handleGetVideoPlayUrl = async () => {
44 try { 44 try {
45 - const instance = unref(basicVideoPlayEl)?.getInstance();  
46 const { config } = props; 45 const { config } = props;
47 const { option } = config; 46 const { option } = config;
48 const { videoConfig, uuid } = option || {}; 47 const { videoConfig, uuid } = option || {};
49 if (!uuid) return; 48 if (!uuid) return;
50 const { url, id, accessMode } = videoConfig || {}; 49 const { url, id, accessMode } = videoConfig || {};
51 - const type = getVideoTypeByUrl(url!); 50 + let type = getVideoTypeByUrl(url!);
52 let playUrl = url; 51 let playUrl = url;
53 if (accessMode === AccessMode.Streaming && id) { 52 if (accessMode === AccessMode.Streaming && id) {
54 const { data: { url } = { url: '' } } = await getStreamingPlayUrl(id!); 53 const { data: { url } = { url: '' } } = await getStreamingPlayUrl(id!);
55 playUrl = url; 54 playUrl = url;
  55 + playUrl && (type = getVideoTypeByUrl(playUrl!));
56 } 56 }
57 57
58 if (isRtspProtocol(url!)) { 58 if (isRtspProtocol(url!)) {
@@ -60,10 +60,6 @@ @@ -60,10 +60,6 @@
60 const { visitorId } = result; 60 const { visitorId } = result;
61 playUrl = getFlvPlayUrl(playUrl!, visitorId); 61 playUrl = getFlvPlayUrl(playUrl!, visitorId);
62 withToken.value = true; 62 withToken.value = true;
63 -  
64 - (instance!.options_ as any).flvjs.config.headers = {  
65 - 'X-Authorization': `Bearer ${isShareMode() ? getShareJwtToken() : getJwtToken()}`,  
66 - };  
67 } 63 }
68 64
69 playSource.value = { 65 playSource.value = {
@@ -71,7 +67,17 @@ @@ -71,7 +67,17 @@
71 type, 67 type,
72 }; 68 };
73 69
74 - instance?.src(toRaw(unref(playSource))); 70 + const instance = unref(basicVideoPlayEl)?.customInit((options) => {
  71 + withToken.value = true;
  72 +
  73 + if (unref(withToken)) {
  74 + (options as any).flvjs.config.headers = {
  75 + 'X-Authorization': `Bearer ${isShareMode() ? getShareJwtToken() : getJwtToken()}`,
  76 + };
  77 + }
  78 + return { ...options, sources: [toRaw(unref(playSource))] } as VideoJsPlayerOptions;
  79 + });
  80 +
75 instance?.play(); 81 instance?.play();
76 } finally { 82 } finally {
77 loading.value = false; 83 loading.value = false;
@@ -80,8 +86,19 @@ @@ -80,8 +86,19 @@
80 86
81 const handleSelectPreview = () => { 87 const handleSelectPreview = () => {
82 loading.value = false; 88 loading.value = false;
83 - const instance = unref(basicVideoPlayEl)?.getInstance();  
84 - instance?.src({ type: getVideoTypeByUrl(exampleVideoPlay), src: exampleVideoPlay }); 89 + const instance = unref(basicVideoPlayEl)?.customInit((options) => {
  90 + withToken.value = true;
  91 +
  92 + if (unref(withToken)) {
  93 + (options as any).flvjs.config.headers = {
  94 + 'X-Authorization': `Bearer ${isShareMode() ? getShareJwtToken() : getJwtToken()}`,
  95 + };
  96 + }
  97 + return {
  98 + ...options,
  99 + sources: [{ type: getVideoTypeByUrl(exampleVideoPlay), src: exampleVideoPlay }],
  100 + } as VideoJsPlayerOptions;
  101 + });
85 instance?.play(); 102 instance?.play();
86 }; 103 };
87 104
@@ -103,7 +120,12 @@ @@ -103,7 +120,12 @@
103 <template> 120 <template>
104 <main class="w-full h-full flex flex-col justify-center items-center p-2"> 121 <main class="w-full h-full flex flex-col justify-center items-center p-2">
105 <Spin :spinning="loading" wrapper-class-name="video-spin"> 122 <Spin :spinning="loading" wrapper-class-name="video-spin">
106 - <BasicVideoPlay ref="basicVideoPlayEl" :options="getOptions" :with-token="withToken" /> 123 + <BasicVideoPlay
  124 + ref="basicVideoPlayEl"
  125 + :options="getOptions"
  126 + :with-token="withToken"
  127 + :immediateInitOnMounted="false"
  128 + />
107 </Spin> 129 </Spin>
108 </main> 130 </main>
109 </template> 131 </template>
@@ -14,6 +14,7 @@ export const option: PublicPresetOptions = { @@ -14,6 +14,7 @@ export const option: PublicPresetOptions = {
14 [ComponentConfigFieldEnum.CLOSE_COLOR]: '#eeeeee', 14 [ComponentConfigFieldEnum.CLOSE_COLOR]: '#eeeeee',
15 [ComponentConfigFieldEnum.SHOW_DEVICE_NAME]: true, 15 [ComponentConfigFieldEnum.SHOW_DEVICE_NAME]: true,
16 [ComponentConfigFieldEnum.SHOW_TIME]: false, 16 [ComponentConfigFieldEnum.SHOW_TIME]: false,
  17 + [ComponentConfigFieldEnum.FONT_SIZE]: 14,
17 }; 18 };
18 19
19 export default class Config extends PublicConfigClass implements CreateComponentType { 20 export default class Config extends PublicConfigClass implements CreateComponentType {
@@ -25,6 +25,29 @@ @@ -25,6 +25,29 @@
25 }, 25 },
26 }, 26 },
27 { 27 {
  28 + field: ComponentConfigFieldEnum.FONT_SIZE,
  29 + label: '文本字体大小',
  30 + component: 'InputNumber',
  31 + defaultValue: 14,
  32 + componentProps: {
  33 + min: 0,
  34 + formatter: (e) => {
  35 + const value = e.replace(/^0/g, '');
  36 + if (value) {
  37 + return value.replace(/^0/g, '');
  38 + } else {
  39 + return 0;
  40 + }
  41 + },
  42 + },
  43 + },
  44 + {
  45 + field: ComponentConfigFieldEnum.SHOW_DEVICE_NAME,
  46 + label: '显示设备名称',
  47 + component: 'Checkbox',
  48 + defaultValue: option.showDeviceName,
  49 + },
  50 + {
28 field: ComponentConfigFieldEnum.SHOW_TIME, 51 field: ComponentConfigFieldEnum.SHOW_TIME,
29 label: '显示时间', 52 label: '显示时间',
30 component: 'Checkbox', 53 component: 'Checkbox',
@@ -25,16 +25,18 @@ @@ -25,16 +25,18 @@
25 closeColor: persetCloseColor, 25 closeColor: persetCloseColor,
26 showDeviceName: persetShowDeviceName, 26 showDeviceName: persetShowDeviceName,
27 showTime: persetShowTime, 27 showTime: persetShowTime,
  28 + fontSize: persetFontSize,
28 } = persetOption || {}; 29 } = persetOption || {};
29 const { componentInfo, attribute, attributeName, attributeRename } = option; 30 const { componentInfo, attribute, attributeName, attributeRename } = option;
30 31
31 - const { openColor, closeColor, showDeviceName, showTime } = componentInfo || {}; 32 + const { openColor, closeColor, showDeviceName, showTime, fontSize } = componentInfo || {};
32 return { 33 return {
33 openColor: openColor ?? persetOpenColor, 34 openColor: openColor ?? persetOpenColor,
34 closeColor: closeColor ?? persetCloseColor, 35 closeColor: closeColor ?? persetCloseColor,
35 showDeviceName: showDeviceName ?? persetShowDeviceName, 36 showDeviceName: showDeviceName ?? persetShowDeviceName,
36 attribute: attributeRename || attributeName || attribute, 37 attribute: attributeRename || attributeName || attribute,
37 showTime: showTime ?? persetShowTime, 38 showTime: showTime ?? persetShowTime,
  39 + fontSize: fontSize || persetFontSize || 14,
38 }; 40 };
39 }); 41 });
40 42
@@ -78,7 +80,9 @@ @@ -78,7 +80,9 @@
78 }" 80 }"
79 :class="isOpenClose ? 'switch_open' : 'switch_close'" 81 :class="isOpenClose ? 'switch_open' : 'switch_close'"
80 ></div> 82 ></div>
81 - <div class="text-gray-500 text-sm truncate">{{ getDesign.attribute }}</div> 83 + <div class="text-gray-500 truncate" :style="{ fontSize: getDesign.fontSize + 'px' }">{{
  84 + getDesign.attribute
  85 + }}</div>
82 </div> 86 </div>
83 <UpdateTime v-if="getDesign.showTime" :time="time" /> 87 <UpdateTime v-if="getDesign.showTime" :time="time" />
84 </main> 88 </main>
@@ -16,6 +16,7 @@ export const option: PublicPresetOptions = { @@ -16,6 +16,7 @@ export const option: PublicPresetOptions = {
16 [ComponentConfigFieldEnum.ICON_COLOR_CLOSE]: '#CCCCCC', 16 [ComponentConfigFieldEnum.ICON_COLOR_CLOSE]: '#CCCCCC',
17 [ComponentConfigFieldEnum.SHOW_DEVICE_NAME]: false, 17 [ComponentConfigFieldEnum.SHOW_DEVICE_NAME]: false,
18 [ComponentConfigFieldEnum.SHOW_TIME]: false, 18 [ComponentConfigFieldEnum.SHOW_TIME]: false,
  19 + [ComponentConfigFieldEnum.FONT_SIZE]: 14,
19 }; 20 };
20 21
21 export default class Config extends PublicConfigClass implements CreateComponentType { 22 export default class Config extends PublicConfigClass implements CreateComponentType {
@@ -47,6 +47,23 @@ @@ -47,6 +47,23 @@
47 defaultValue: option.iconColorClose, 47 defaultValue: option.iconColorClose,
48 }, 48 },
49 { 49 {
  50 + field: ComponentConfigFieldEnum.FONT_SIZE,
  51 + label: '文本字体大小',
  52 + component: 'InputNumber',
  53 + defaultValue: 14,
  54 + componentProps: {
  55 + min: 0,
  56 + formatter: (e) => {
  57 + const value = e.replace(/^0/g, '');
  58 + if (value) {
  59 + return value.replace(/^0/g, '');
  60 + } else {
  61 + return 0;
  62 + }
  63 + },
  64 + },
  65 + },
  66 + {
50 field: ComponentConfigFieldEnum.SHOW_DEVICE_NAME, 67 field: ComponentConfigFieldEnum.SHOW_DEVICE_NAME,
51 label: '显示设备名称', 68 label: '显示设备名称',
52 component: 'Checkbox', 69 component: 'Checkbox',
@@ -26,11 +26,12 @@ @@ -26,11 +26,12 @@
26 iconClose: persetIconCLose, 26 iconClose: persetIconCLose,
27 iconColorClose: persetIconColorClose, 27 iconColorClose: persetIconColorClose,
28 showTime: persetShowTime, 28 showTime: persetShowTime,
  29 + fontSize: persetFontSize,
29 } = persetOption; 30 } = persetOption;
30 31
31 const { componentInfo, attributeName, attributeRename } = option; 32 const { componentInfo, attributeName, attributeRename } = option;
32 33
33 - const { icon, iconColor, fontColor, unit, iconClose, iconColorClose, showTime } = 34 + const { icon, iconColor, fontColor, unit, iconClose, iconColorClose, showTime, fontSize } =
34 componentInfo || {}; 35 componentInfo || {};
35 return { 36 return {
36 iconColor: iconColor || persetIconColor, 37 iconColor: iconColor || persetIconColor,
@@ -41,6 +42,7 @@ @@ -41,6 +42,7 @@
41 iconClose: iconClose || persetIconCLose, 42 iconClose: iconClose || persetIconCLose,
42 iconColorClose: iconColorClose || persetIconColorClose, 43 iconColorClose: iconColorClose || persetIconColorClose,
43 showTime: showTime ?? persetShowTime, 44 showTime: showTime ?? persetShowTime,
  45 + fontSize: fontSize || persetFontSize || 14,
44 }; 46 };
45 }); 47 });
46 48
@@ -68,7 +70,9 @@ @@ -68,7 +70,9 @@
68 :size="60" 70 :size="60"
69 :style="{ color: isOpenClose ? getDesign.iconColor : getDesign.iconColorClose }" 71 :style="{ color: isOpenClose ? getDesign.iconColor : getDesign.iconColorClose }"
70 /> 72 />
71 - <div class="text-gray-500 text-sm truncate m-2">{{ getDesign.attribute || '' }}</div> 73 + <div class="text-gray-500 truncate m-2" :style="{ fontSize: getDesign.fontSize + 'px' }">{{
  74 + getDesign.attribute || ''
  75 + }}</div>
72 </div> 76 </div>
73 <UpdateTime v-show="getDesign.showTime" :time="time" /> 77 <UpdateTime v-show="getDesign.showTime" :time="time" />
74 </main> 78 </main>
@@ -12,6 +12,8 @@ import { ComponentConfigFieldEnum } from '/@/views/visual/packages/enum'; @@ -12,6 +12,8 @@ import { ComponentConfigFieldEnum } from '/@/views/visual/packages/enum';
12 export const option: PublicPresetOptions = { 12 export const option: PublicPresetOptions = {
13 [ComponentConfigFieldEnum.FONT_COLOR]: '#000', 13 [ComponentConfigFieldEnum.FONT_COLOR]: '#000',
14 [ComponentConfigFieldEnum.SHOW_DEVICE_NAME]: false, 14 [ComponentConfigFieldEnum.SHOW_DEVICE_NAME]: false,
  15 + [ComponentConfigFieldEnum.FONT_SIZE]: 14,
  16 + [ComponentConfigFieldEnum.VALUE_SIZE]: 20,
15 }; 17 };
16 18
17 export default class Config extends PublicConfigClass implements CreateComponentType { 19 export default class Config extends PublicConfigClass implements CreateComponentType {
@@ -19,6 +19,40 @@ @@ -19,6 +19,40 @@
19 label: '显示设备名称', 19 label: '显示设备名称',
20 component: 'Checkbox', 20 component: 'Checkbox',
21 }, 21 },
  22 + {
  23 + field: ComponentConfigFieldEnum.VALUE_SIZE,
  24 + label: '数值字体大小',
  25 + component: 'InputNumber',
  26 + defaultValue: 20,
  27 + componentProps: {
  28 + min: 0,
  29 + formatter: (e) => {
  30 + const value = e.replace(/^0/g, '');
  31 + if (value) {
  32 + return value.replace(/^0/g, '');
  33 + } else {
  34 + return 0;
  35 + }
  36 + },
  37 + },
  38 + },
  39 + {
  40 + field: ComponentConfigFieldEnum.FONT_SIZE,
  41 + label: '文本字体大小',
  42 + component: 'InputNumber',
  43 + defaultValue: 14,
  44 + componentProps: {
  45 + min: 0,
  46 + formatter: (e) => {
  47 + const value = e.replace(/^0/g, '');
  48 + if (value) {
  49 + return value.replace(/^0/g, '');
  50 + } else {
  51 + return 0;
  52 + }
  53 + },
  54 + },
  55 + },
22 ], 56 ],
23 showActionButtonGroup: false, 57 showActionButtonGroup: false,
24 labelWidth: 120, 58 labelWidth: 120,
@@ -17,13 +17,19 @@ @@ -17,13 +17,19 @@
17 const getDesign = computed(() => { 17 const getDesign = computed(() => {
18 const { persetOption = {}, option } = props.config; 18 const { persetOption = {}, option } = props.config;
19 19
20 - const { fontColor: persetFontColor } = persetOption; 20 + const {
  21 + fontColor: persetFontColor,
  22 + fontSize: persetFontSize,
  23 + valueSize: persetValueSize,
  24 + } = persetOption;
21 25
22 const { componentInfo, attribute, attributeRename, attributeName } = option; 26 const { componentInfo, attribute, attributeRename, attributeName } = option;
23 27
24 - const { fontColor } = componentInfo || {}; 28 + const { fontColor, fontSize, valueSize } = componentInfo || {};
25 return { 29 return {
26 fontColor: fontColor || persetFontColor, 30 fontColor: fontColor || persetFontColor,
  31 + fontSize: fontSize || persetFontSize || 14,
  32 + valueSize: valueSize || persetValueSize || 20,
27 attribute: attributeRename || attributeName || attribute, 33 attribute: attributeRename || attributeName || attribute,
28 }; 34 };
29 }); 35 });
@@ -45,10 +51,15 @@ @@ -45,10 +51,15 @@
45 <main :style="getScale" class="w-full h-full flex flex-col justify-center items-center"> 51 <main :style="getScale" class="w-full h-full flex flex-col justify-center items-center">
46 <DeviceName :config="config" /> 52 <DeviceName :config="config" />
47 53
48 - <h1 class="my-4 font-bold text-xl !my-2 truncate" :style="{ color: getDesign.fontColor }"> 54 + <h1
  55 + class="my-4 font-bold !my-2 truncate"
  56 + :style="{ color: getDesign.fontColor, fontSize: getDesign.valueSize + 'px' }"
  57 + >
49 {{ currentValue || 0 }} 58 {{ currentValue || 0 }}
50 </h1> 59 </h1>
51 - <div class="text-gray-500 text-sm truncate">{{ getDesign.attribute || '温度' }}</div> 60 + <div class="text-gray-500 truncate" :style="{ fontSize: getDesign.fontSize + 'px' }">{{
  61 + getDesign.attribute || '温度'
  62 + }}</div>
52 <!-- <div v-if="config.option.componentInfo.showDeviceName"> 63 <!-- <div v-if="config.option.componentInfo.showDeviceName">
53 {{ config.option.deviceRename || config.option.deviceName }} 64 {{ config.option.deviceRename || config.option.deviceName }}
54 </div> --> 65 </div> -->
@@ -12,6 +12,8 @@ import { ComponentConfigFieldEnum } from '/@/views/visual/packages/enum'; @@ -12,6 +12,8 @@ import { ComponentConfigFieldEnum } from '/@/views/visual/packages/enum';
12 export const option: PublicPresetOptions = { 12 export const option: PublicPresetOptions = {
13 [ComponentConfigFieldEnum.FONT_COLOR]: '#000', 13 [ComponentConfigFieldEnum.FONT_COLOR]: '#000',
14 [ComponentConfigFieldEnum.SHOW_DEVICE_NAME]: false, 14 [ComponentConfigFieldEnum.SHOW_DEVICE_NAME]: false,
  15 + [ComponentConfigFieldEnum.VALUE_SIZE]: 20,
  16 + [ComponentConfigFieldEnum.FONT_SIZE]: 14,
15 }; 17 };
16 18
17 export default class Config extends PublicConfigClass implements CreateComponentType { 19 export default class Config extends PublicConfigClass implements CreateComponentType {
@@ -19,6 +19,40 @@ @@ -19,6 +19,40 @@
19 label: '显示设备名称', 19 label: '显示设备名称',
20 component: 'Checkbox', 20 component: 'Checkbox',
21 }, 21 },
  22 + {
  23 + field: ComponentConfigFieldEnum.VALUE_SIZE,
  24 + label: '数值字体大小',
  25 + component: 'InputNumber',
  26 + defaultValue: 20,
  27 + componentProps: {
  28 + min: 0,
  29 + formatter: (e) => {
  30 + const value = e.replace(/^0/g, '');
  31 + if (value) {
  32 + return value.replace(/^0/g, '');
  33 + } else {
  34 + return 0;
  35 + }
  36 + },
  37 + },
  38 + },
  39 + {
  40 + field: ComponentConfigFieldEnum.FONT_SIZE,
  41 + label: '文本字体大小',
  42 + component: 'InputNumber',
  43 + defaultValue: 14,
  44 + componentProps: {
  45 + min: 0,
  46 + formatter: (e) => {
  47 + const value = e.replace(/^0/g, '');
  48 + if (value) {
  49 + return value.replace(/^0/g, '');
  50 + } else {
  51 + return 0;
  52 + }
  53 + },
  54 + },
  55 + },
22 ], 56 ],
23 showActionButtonGroup: false, 57 showActionButtonGroup: false,
24 labelWidth: 120, 58 labelWidth: 120,
@@ -19,14 +19,20 @@ @@ -19,14 +19,20 @@
19 const getDesign = computed(() => { 19 const getDesign = computed(() => {
20 const { persetOption = {}, option } = props.config; 20 const { persetOption = {}, option } = props.config;
21 21
22 - const { fontColor: persetFontColor } = persetOption; 22 + const {
  23 + fontColor: persetFontColor,
  24 + valueSize: persetValueSize,
  25 + fontSize: persetFontSize,
  26 + } = persetOption;
23 27
24 const { componentInfo, attribute, attributeName, attributeRename } = option; 28 const { componentInfo, attribute, attributeName, attributeRename } = option;
25 29
26 - const { fontColor } = componentInfo || {}; 30 + const { fontColor, valueSize, fontSize } = componentInfo || {};
27 31
28 return { 32 return {
29 fontColor: fontColor || persetFontColor, 33 fontColor: fontColor || persetFontColor,
  34 + valueSize: valueSize || persetValueSize || 20,
  35 + fontSize: fontSize || persetFontSize || 14,
30 attribute: attributeRename || attributeName || attribute, 36 attribute: attributeRename || attributeName || attribute,
31 }; 37 };
32 }); 38 });
@@ -50,10 +56,15 @@ @@ -50,10 +56,15 @@
50 <DeviceName :config="config" /> 56 <DeviceName :config="config" />
51 57
52 <div class="flex-1 flex justify-center items-center flex-col" :style="getScale"> 58 <div class="flex-1 flex justify-center items-center flex-col" :style="getScale">
53 - <h1 class="my-4 font-bold text-xl !my-2 truncate" :style="{ color: getDesign.fontColor }"> 59 + <h1
  60 + class="my-4 font-bold !my-2 truncate"
  61 + :style="{ color: getDesign.fontColor, fontSize: getDesign.valueSize + 'px' }"
  62 + >
54 {{ currentValue || 0 }} 63 {{ currentValue || 0 }}
55 </h1> 64 </h1>
56 - <div class="text-gray-500 text-sm truncate">{{ getDesign.attribute || '温度' }}</div> 65 + <div class="text-gray-500 truncate" :style="{ fontSize: getDesign.fontSize + 'px' }">{{
  66 + getDesign.attribute || '温度'
  67 + }}</div>
57 </div> 68 </div>
58 <UpdateTime :time="time" /> 69 <UpdateTime :time="time" />
59 </main> 70 </main>
@@ -15,6 +15,8 @@ export const option: PublicPresetOptions = { @@ -15,6 +15,8 @@ export const option: PublicPresetOptions = {
15 [ComponentConfigFieldEnum.ICON_COLOR]: '#367bff', 15 [ComponentConfigFieldEnum.ICON_COLOR]: '#367bff',
16 [ComponentConfigFieldEnum.FONT_COLOR]: '#000', 16 [ComponentConfigFieldEnum.FONT_COLOR]: '#000',
17 [ComponentConfigFieldEnum.SHOW_DEVICE_NAME]: false, 17 [ComponentConfigFieldEnum.SHOW_DEVICE_NAME]: false,
  18 + [ComponentConfigFieldEnum.VALUE_SIZE]: 20,
  19 + [ComponentConfigFieldEnum.FONT_SIZE]: 14,
18 }; 20 };
19 21
20 export default class Config extends PublicConfigClass implements CreateComponentType { 22 export default class Config extends PublicConfigClass implements CreateComponentType {
@@ -23,6 +23,41 @@ @@ -23,6 +23,41 @@
23 placeholder: '请输入数值单位', 23 placeholder: '请输入数值单位',
24 }, 24 },
25 }, 25 },
  26 +
  27 + {
  28 + field: ComponentConfigFieldEnum.VALUE_SIZE,
  29 + label: '数值字体大小',
  30 + component: 'InputNumber',
  31 + defaultValue: 20,
  32 + componentProps: {
  33 + min: 0,
  34 + formatter: (e) => {
  35 + const value = e.replace(/^0/g, '');
  36 + if (value) {
  37 + return value.replace(/^0/g, '');
  38 + } else {
  39 + return 0;
  40 + }
  41 + },
  42 + },
  43 + },
  44 + {
  45 + field: ComponentConfigFieldEnum.FONT_SIZE,
  46 + label: '文本字体大小',
  47 + component: 'InputNumber',
  48 + defaultValue: 14,
  49 + componentProps: {
  50 + min: 0,
  51 + formatter: (e) => {
  52 + const value = e.replace(/^0/g, '');
  53 + if (value) {
  54 + return value.replace(/^0/g, '');
  55 + } else {
  56 + return 0;
  57 + }
  58 + },
  59 + },
  60 + },
26 { 61 {
27 field: ComponentConfigFieldEnum.ICON_COLOR, 62 field: ComponentConfigFieldEnum.ICON_COLOR,
28 label: '图标颜色', 63 label: '图标颜色',
@@ -26,17 +26,21 @@ @@ -26,17 +26,21 @@
26 unit: perseUnit, 26 unit: perseUnit,
27 icon: persetIcon, 27 icon: persetIcon,
28 fontColor: persetFontColor, 28 fontColor: persetFontColor,
  29 + valueSize: persetValueSize,
  30 + fontSize: persetFontSize,
29 } = persetOption; 31 } = persetOption;
30 32
31 const { componentInfo, attribute, attributeRename, attributeName } = option; 33 const { componentInfo, attribute, attributeRename, attributeName } = option;
32 34
33 - const { icon, iconColor, fontColor, unit } = componentInfo || {}; 35 + const { icon, iconColor, fontColor, unit, valueSize, fontSize } = componentInfo || {};
34 return { 36 return {
35 iconColor: iconColor || persetIconColor, 37 iconColor: iconColor || persetIconColor,
36 unit: unit ?? perseUnit, 38 unit: unit ?? perseUnit,
37 icon: icon || persetIcon, 39 icon: icon || persetIcon,
38 fontColor: fontColor || persetFontColor, 40 fontColor: fontColor || persetFontColor,
39 attribute: attributeRename || attributeName || attribute, 41 attribute: attributeRename || attributeName || attribute,
  42 + valueSize: valueSize || persetValueSize || 20,
  43 + fontSize: fontSize || persetFontSize || 14,
40 }; 44 };
41 }); 45 });
42 46
@@ -64,11 +68,16 @@ @@ -64,11 +68,16 @@
64 :size="60" 68 :size="60"
65 :style="{ color: getDesign.iconColor }" 69 :style="{ color: getDesign.iconColor }"
66 /> 70 />
67 - <h1 class="font-bold text-xl m-2 truncate" :style="{ color: getDesign.fontColor }"> 71 + <h1
  72 + class="font-bold m-2 truncate"
  73 + :style="{ color: getDesign.fontColor, fontSize: getDesign.valueSize + 'px' }"
  74 + >
68 <span> {{ currentValue || 0 }}</span> 75 <span> {{ currentValue || 0 }}</span>
69 <span>{{ getDesign.unit }} </span> 76 <span>{{ getDesign.unit }} </span>
70 </h1> 77 </h1>
71 - <div class="text-gray-500 text-sm truncate">{{ getDesign.attribute || '温度' }}</div> 78 + <div class="text-gray-500 truncate" :style="{ fontSize: getDesign.fontSize + 'px' }">{{
  79 + getDesign.attribute || '温度'
  80 + }}</div>
72 </div> 81 </div>
73 <UpdateTime :time="time" /> 82 <UpdateTime :time="time" />
74 </main> 83 </main>
@@ -15,6 +15,8 @@ export const option: PublicPresetOptions = { @@ -15,6 +15,8 @@ export const option: PublicPresetOptions = {
15 [ComponentConfigFieldEnum.ICON_COLOR]: '#367bff', 15 [ComponentConfigFieldEnum.ICON_COLOR]: '#367bff',
16 [ComponentConfigFieldEnum.FONT_COLOR]: '#000', 16 [ComponentConfigFieldEnum.FONT_COLOR]: '#000',
17 [ComponentConfigFieldEnum.SHOW_DEVICE_NAME]: false, 17 [ComponentConfigFieldEnum.SHOW_DEVICE_NAME]: false,
  18 + [ComponentConfigFieldEnum.VALUE_SIZE]: 20,
  19 + [ComponentConfigFieldEnum.FONT_SIZE]: 14,
18 }; 20 };
19 21
20 export default class Config extends PublicConfigClass implements CreateComponentType { 22 export default class Config extends PublicConfigClass implements CreateComponentType {
@@ -24,6 +24,40 @@ @@ -24,6 +24,40 @@
24 }, 24 },
25 }, 25 },
26 { 26 {
  27 + field: ComponentConfigFieldEnum.VALUE_SIZE,
  28 + label: '数值字体大小',
  29 + component: 'InputNumber',
  30 + defaultValue: 20,
  31 + componentProps: {
  32 + min: 0,
  33 + formatter: (e) => {
  34 + const value = e.replace(/^0/g, '');
  35 + if (value) {
  36 + return value.replace(/^0/g, '');
  37 + } else {
  38 + return 0;
  39 + }
  40 + },
  41 + },
  42 + },
  43 + {
  44 + field: ComponentConfigFieldEnum.FONT_SIZE,
  45 + label: '文本字体大小',
  46 + component: 'InputNumber',
  47 + defaultValue: 14,
  48 + componentProps: {
  49 + min: 0,
  50 + formatter: (e) => {
  51 + const value = e.replace(/^0/g, '');
  52 + if (value) {
  53 + return value.replace(/^0/g, '');
  54 + } else {
  55 + return 0;
  56 + }
  57 + },
  58 + },
  59 + },
  60 + {
27 field: ComponentConfigFieldEnum.ICON_COLOR, 61 field: ComponentConfigFieldEnum.ICON_COLOR,
28 label: '图标颜色', 62 label: '图标颜色',
29 component: 'ColorPicker', 63 component: 'ColorPicker',
@@ -23,17 +23,21 @@ @@ -23,17 +23,21 @@
23 unit: perseUnit, 23 unit: perseUnit,
24 icon: persetIcon, 24 icon: persetIcon,
25 fontColor: persetFontColor, 25 fontColor: persetFontColor,
  26 + valueSize: persetValueSize,
  27 + fontSize: persetFontSize,
26 } = persetOption; 28 } = persetOption;
27 29
28 const { componentInfo, attribute, attributeRename, attributeName } = option; 30 const { componentInfo, attribute, attributeRename, attributeName } = option;
29 31
30 - const { icon, iconColor, fontColor, unit } = componentInfo || {}; 32 + const { icon, iconColor, fontColor, unit, valueSize, fontSize } = componentInfo || {};
31 return { 33 return {
32 iconColor: iconColor || persetIconColor, 34 iconColor: iconColor || persetIconColor,
33 unit: unit ?? perseUnit, 35 unit: unit ?? perseUnit,
34 icon: icon || persetIcon, 36 icon: icon || persetIcon,
35 fontColor: fontColor || persetFontColor, 37 fontColor: fontColor || persetFontColor,
36 attribute: attributeRename || attributeName || attribute, 38 attribute: attributeRename || attributeName || attribute,
  39 + valueSize: valueSize || persetValueSize || 20,
  40 + fontSize: fontSize || persetFontSize || 14,
37 }; 41 };
38 }); 42 });
39 43
@@ -60,11 +64,16 @@ @@ -60,11 +64,16 @@
60 :size="60" 64 :size="60"
61 :style="{ color: getDesign.iconColor }" 65 :style="{ color: getDesign.iconColor }"
62 /> 66 />
63 - <h1 class="my-4 font-bold text-lg !my-2 truncate" :style="{ color: getDesign.fontColor }"> 67 + <h1
  68 + class="my-4 font-bold !my-2 truncate"
  69 + :style="{ color: getDesign.fontColor, fontSize: getDesign.valueSize + 'px' }"
  70 + >
64 <span>{{ currentValue || 0 }}</span> 71 <span>{{ currentValue || 0 }}</span>
65 <span>{{ getDesign.unit }}</span> 72 <span>{{ getDesign.unit }}</span>
66 </h1> 73 </h1>
67 - <div class="text-gray-500 text-sm truncate">{{ getDesign.attribute || '温度' }}</div> 74 + <div class="text-gray-500 truncate" :style="{ fontSize: getDesign.fontSize + 'px' }">{{
  75 + getDesign.attribute || '温度'
  76 + }}</div>
68 </div> 77 </div>
69 </main> 78 </main>
70 </template> 79 </template>
@@ -16,7 +16,8 @@ export const option: PublicPresetOptions = { @@ -16,7 +16,8 @@ export const option: PublicPresetOptions = {
16 [ComponentConfigFieldEnum.UNIT]: '℃', 16 [ComponentConfigFieldEnum.UNIT]: '℃',
17 [ComponentConfigFieldEnum.SHOW_DEVICE_NAME]: false, 17 [ComponentConfigFieldEnum.SHOW_DEVICE_NAME]: false,
18 [ComponentConfigFieldEnum.BACKGROUND_COLOR]: '#377dff', 18 [ComponentConfigFieldEnum.BACKGROUND_COLOR]: '#377dff',
19 - fontSize: '18px', 19 + [ComponentConfigFieldEnum.VALUE_SIZE]: 20,
  20 + [ComponentConfigFieldEnum.FONT_SIZE]: 14,
20 }; 21 };
21 22
22 export default class Config extends PublicConfigClass implements CreateComponentType { 23 export default class Config extends PublicConfigClass implements CreateComponentType {
@@ -24,6 +24,41 @@ @@ -24,6 +24,41 @@
24 defaultValue: option.backgroundColor, 24 defaultValue: option.backgroundColor,
25 }, 25 },
26 }, 26 },
  27 +
  28 + {
  29 + field: ComponentConfigFieldEnum.VALUE_SIZE,
  30 + label: '数值字体大小',
  31 + component: 'InputNumber',
  32 + defaultValue: 20,
  33 + componentProps: {
  34 + min: 0,
  35 + formatter: (e) => {
  36 + const value = e.replace(/^0/g, '');
  37 + if (value) {
  38 + return value.replace(/^0/g, '');
  39 + } else {
  40 + return 0;
  41 + }
  42 + },
  43 + },
  44 + },
  45 + {
  46 + field: ComponentConfigFieldEnum.FONT_SIZE,
  47 + label: '文本字体大小',
  48 + component: 'InputNumber',
  49 + defaultValue: 14,
  50 + componentProps: {
  51 + min: 0,
  52 + formatter: (e) => {
  53 + const value = e.replace(/^0/g, '');
  54 + if (value) {
  55 + return value.replace(/^0/g, '');
  56 + } else {
  57 + return 0;
  58 + }
  59 + },
  60 + },
  61 + },
27 { 62 {
28 field: ComponentConfigFieldEnum.MAX_NUMBER, 63 field: ComponentConfigFieldEnum.MAX_NUMBER,
29 label: '最大值', 64 label: '最大值',
@@ -29,6 +29,7 @@ @@ -29,6 +29,7 @@
29 attributeName?: string; 29 attributeName?: string;
30 deviceRename?: string; 30 deviceRename?: string;
31 maxNumber?: number; 31 maxNumber?: number;
  32 + [key: string]: number | string | undefined;
32 } 33 }
33 34
34 const defaultValue: PercentType[] = [ 35 const defaultValue: PercentType[] = [
@@ -39,6 +40,8 @@ @@ -39,6 +40,8 @@
39 unit: '℃', 40 unit: '℃',
40 deviceName: '温湿度', 41 deviceName: '温湿度',
41 attribute: '温度', 42 attribute: '温度',
  43 + fontSize: 14,
  44 + valueSize: 20,
42 id: buildUUID(), 45 id: buildUUID(),
43 }, 46 },
44 { 47 {
@@ -60,10 +63,13 @@ @@ -60,10 +63,13 @@
60 fontColor: presetFontColor, 63 fontColor: presetFontColor,
61 backgroundColor: persetBackgroundColor, 64 backgroundColor: persetBackgroundColor,
62 maxNumber: persetMaxNumber, 65 maxNumber: persetMaxNumber,
  66 + valueSize: persetValueSize,
  67 + fontSize: persetFontSize,
63 } = persetOption || {}; 68 } = persetOption || {};
64 return { 69 return {
65 dataSource: dataSource.map((item) => { 70 dataSource: dataSource.map((item) => {
66 - const { unit, fontColor, backgroundColor, maxNumber } = item.componentInfo || {}; 71 + const { unit, fontColor, backgroundColor, maxNumber, valueSize, fontSize } =
  72 + item.componentInfo || {};
67 const { attribute, attributeRename, deviceName, deviceRename, deviceId, attributeName } = 73 const { attribute, attributeRename, deviceName, deviceRename, deviceId, attributeName } =
68 item; 74 item;
69 return { 75 return {
@@ -75,6 +81,8 @@ @@ -75,6 +81,8 @@
75 attributeName: attributeRename || attributeName, 81 attributeName: attributeRename || attributeName,
76 maxNumber: maxNumber || persetMaxNumber, 82 maxNumber: maxNumber || persetMaxNumber,
77 id: deviceId, 83 id: deviceId,
  84 + valueSize: valueSize || persetValueSize || 20,
  85 + fontSize: fontSize || persetFontSize || 14,
78 } as PercentType; 86 } as PercentType;
79 }), 87 }),
80 }; 88 };
@@ -112,14 +120,17 @@ @@ -112,14 +120,17 @@
112 class="mt-2 flex flex-col ml-3 mr-3 items-stretch" 120 class="mt-2 flex flex-col ml-3 mr-3 items-stretch"
113 > 121 >
114 <div class="flex justify-between"> 122 <div class="flex justify-between">
115 - <div class="text-gray-500 text-sm truncate" :style="{ color: item.fontColor }"> 123 + <div
  124 + class="text-gray-500 text-sm truncate"
  125 + :style="{ color: item.fontColor, fontSize: item.fontSize + 'px' }"
  126 + >
116 {{ 127 {{
117 `${item.deviceName} 128 `${item.deviceName}
118 - 129 -
119 ${item.attributeName || item.attribute || '温度'}` 130 ${item.attributeName || item.attribute || '温度'}`
120 }} 131 }}
121 </div> 132 </div>
122 - <span class="text-lg" :style="{ color: item.fontColor }" 133 + <span class="text-lg" :style="{ color: item.fontColor, fontSize: item.valueSize + 'px' }"
123 >{{ item.value }} {{ item.unit }}</span 134 >{{ item.value }} {{ item.unit }}</span
124 > 135 >
125 </div> 136 </div>
@@ -16,6 +16,8 @@ export const option: PublicPresetOptions = { @@ -16,6 +16,8 @@ export const option: PublicPresetOptions = {
16 [ComponentConfigFieldEnum.ICON_COLOR]: '#367bff', 16 [ComponentConfigFieldEnum.ICON_COLOR]: '#367bff',
17 [ComponentConfigFieldEnum.FONT_COLOR]: '#000', 17 [ComponentConfigFieldEnum.FONT_COLOR]: '#000',
18 [ComponentConfigFieldEnum.SHOW_DEVICE_NAME]: false, 18 [ComponentConfigFieldEnum.SHOW_DEVICE_NAME]: false,
  19 + [ComponentConfigFieldEnum.VALUE_SIZE]: 20,
  20 + [ComponentConfigFieldEnum.FONT_SIZE]: 14,
19 }; 21 };
20 22
21 export default class Config extends PublicConfigClass implements CreateComponentType { 23 export default class Config extends PublicConfigClass implements CreateComponentType {
@@ -23,6 +23,41 @@ @@ -23,6 +23,41 @@
23 placeholder: '请输入数值单位', 23 placeholder: '请输入数值单位',
24 }, 24 },
25 }, 25 },
  26 +
  27 + {
  28 + field: ComponentConfigFieldEnum.VALUE_SIZE,
  29 + label: '数值字体大小',
  30 + component: 'InputNumber',
  31 + defaultValue: 20,
  32 + componentProps: {
  33 + min: 0,
  34 + formatter: (e) => {
  35 + const value = e.replace(/^0/g, '');
  36 + if (value) {
  37 + return value.replace(/^0/g, '');
  38 + } else {
  39 + return 0;
  40 + }
  41 + },
  42 + },
  43 + },
  44 + {
  45 + field: ComponentConfigFieldEnum.FONT_SIZE,
  46 + label: '文本字体大小',
  47 + component: 'InputNumber',
  48 + defaultValue: 14,
  49 + componentProps: {
  50 + min: 0,
  51 + formatter: (e) => {
  52 + const value = e.replace(/^0/g, '');
  53 + if (value) {
  54 + return value.replace(/^0/g, '');
  55 + } else {
  56 + return 0;
  57 + }
  58 + },
  59 + },
  60 + },
26 { 61 {
27 field: ComponentConfigFieldEnum.ICON_COLOR, 62 field: ComponentConfigFieldEnum.ICON_COLOR,
28 label: '图标颜色', 63 label: '图标颜色',
@@ -9,6 +9,7 @@ @@ -9,6 +9,7 @@
9 import { useReceiveValue } from '../../../hook/useReceiveValue'; 9 import { useReceiveValue } from '../../../hook/useReceiveValue';
10 import { useMultipleDataFetch } from '../../../hook/socket/useSocket'; 10 import { useMultipleDataFetch } from '../../../hook/socket/useSocket';
11 import { MultipleDataFetchUpdateFn } from '../../../hook/socket/useSocket.type'; 11 import { MultipleDataFetchUpdateFn } from '../../../hook/socket/useSocket.type';
  12 + import { useComponentScale } from '../../../hook/useComponentScale';
12 13
13 const props = defineProps<{ 14 const props = defineProps<{
14 config: ComponentPropsConfigType<typeof option>; 15 config: ComponentPropsConfigType<typeof option>;
@@ -24,10 +25,12 @@ @@ -24,10 +25,12 @@
24 fontColor: persetFontColor, 25 fontColor: persetFontColor,
25 icon: persetIcon, 26 icon: persetIcon,
26 iconColor: persetIconColor, 27 iconColor: persetIconColor,
  28 + valueSize: persetValueSize,
  29 + fontSize: persetFontSize,
27 } = persetOption || {}; 30 } = persetOption || {};
28 return { 31 return {
29 dataSource: dataSource.map((item) => { 32 dataSource: dataSource.map((item) => {
30 - const { fontColor, icon, iconColor, unit } = item.componentInfo; 33 + const { fontColor, icon, iconColor, unit, valueSize, fontSize } = item.componentInfo;
31 const { attribute, attributeRename, deviceName, deviceRename, deviceId, attributeName } = 34 const { attribute, attributeRename, deviceName, deviceRename, deviceId, attributeName } =
32 item; 35 item;
33 36
@@ -40,6 +43,8 @@ @@ -40,6 +43,8 @@
40 deviceName: deviceRename || deviceName, 43 deviceName: deviceRename || deviceName,
41 attributeName: attributeRename || attributeName, 44 attributeName: attributeRename || attributeName,
42 id: deviceId, 45 id: deviceId,
  46 + valueSize: valueSize || persetValueSize || 20,
  47 + fontSize: fontSize || persetFontSize || 14,
43 }; 48 };
44 }), 49 }),
45 }; 50 };
@@ -84,6 +89,7 @@ @@ -84,6 +89,7 @@
84 }; 89 };
85 90
86 useMultipleDataFetch(props, updateFn); 91 useMultipleDataFetch(props, updateFn);
  92 + const { getRatio } = useComponentScale(props);
87 </script> 93 </script>
88 94
89 <template> 95 <template>
@@ -99,19 +105,21 @@ @@ -99,19 +105,21 @@
99 <SvgIcon 105 <SvgIcon
100 :name="item.icon!" 106 :name="item.icon!"
101 prefix="iconfont" 107 prefix="iconfont"
102 - :size="40" 108 + :size="getRatio ? 25 * getRatio : 25"
103 :style="{ color: item.iconColor }" 109 :style="{ color: item.iconColor }"
104 /> 110 />
105 111
106 - <div class="text-gray-500 text-lg truncate ml-6">{{  
107 - item.deviceName + '-' + item.attributeName || '温度'  
108 - }}</div> 112 + <div
  113 + class="text-gray-500 text-sm truncate ml-6"
  114 + :style="{ fontSize: item.fontSize + 'px' }"
  115 + >{{ item.deviceName + '-' + item.attributeName || '温度' }}</div
  116 + >
109 </div> 117 </div>
110 118
111 - <h1 class="font-bold text-xl m-2 truncate" :style="{ color: item.fontColor }"> 119 + <span class="text-lg" :style="{ color: item.fontColor, fontSize: item.valueSize + 'px' }">
112 <span> {{ item.value || 0 }}</span> 120 <span> {{ item.value || 0 }}</span>
113 <span>{{ item.unit }} </span> 121 <span>{{ item.unit }} </span>
114 - </h1> 122 + </span>
115 </div> 123 </div>
116 <!-- <UpdateTime :time="time" /> --> 124 <!-- <UpdateTime :time="time" /> -->
117 </main> 125 </main>
@@ -14,6 +14,7 @@ import { OrgTreeSelect } from '/@/views/common/OrgTreeSelect'; @@ -14,6 +14,7 @@ import { OrgTreeSelect } from '/@/views/common/OrgTreeSelect';
14 import { TransportTypeEnum } from '/@/views/device/profiles/components/TransportDescript/const'; 14 import { TransportTypeEnum } from '/@/views/device/profiles/components/TransportDescript/const';
15 import { CommandTypeEnum } from '/@/views/rule/linkedge/config/config.data'; 15 import { CommandTypeEnum } from '/@/views/rule/linkedge/config/config.data';
16 import { DataActionModeEnum } from '/@/enums/toolEnum'; 16 import { DataActionModeEnum } from '/@/enums/toolEnum';
  17 +import { TaskTypeEnum } from '/@/views/task/center/config';
17 18
18 useComponentRegister('OrgTreeSelect', OrgTreeSelect); 19 useComponentRegister('OrgTreeSelect', OrgTreeSelect);
19 20
@@ -24,6 +25,7 @@ export interface CommonDataSourceBindValueType extends Record<DataSourceField, s @@ -24,6 +25,7 @@ export interface CommonDataSourceBindValueType extends Record<DataSourceField, s
24 command?: string; 25 command?: string;
25 commandType?: string; 26 commandType?: string;
26 callType?: string; 27 callType?: string;
  28 + [ksy: string]: string | undefined;
27 }; 29 };
28 } 30 }
29 31
@@ -33,6 +35,7 @@ export enum DataSourceField { @@ -33,6 +35,7 @@ export enum DataSourceField {
33 TRANSPORT_TYPE = 'transportType', 35 TRANSPORT_TYPE = 'transportType',
34 ORIGINATION_ID = 'organizationId', 36 ORIGINATION_ID = 'organizationId',
35 DEVICE_ID = 'deviceId', 37 DEVICE_ID = 'deviceId',
  38 + DEVICE_CODE = 'deviceCode', //设备地址码
36 DEVICE_PROFILE_ID = 'deviceProfileId', 39 DEVICE_PROFILE_ID = 'deviceProfileId',
37 ATTRIBUTE = 'attribute', 40 ATTRIBUTE = 'attribute',
38 ATTRIBUTE_NAME = 'attributeName', 41 ATTRIBUTE_NAME = 'attributeName',
@@ -41,10 +44,15 @@ export enum DataSourceField { @@ -41,10 +44,15 @@ export enum DataSourceField {
41 DEVICE_RENAME = 'deviceRename', 44 DEVICE_RENAME = 'deviceRename',
42 LONGITUDE_ATTRIBUTE = 'longitudeAttribute', 45 LONGITUDE_ATTRIBUTE = 'longitudeAttribute',
43 LATITUDE_ATTRIBUTE = 'latitudeAttribute', 46 LATITUDE_ATTRIBUTE = 'latitudeAttribute',
44 - 47 + CODE_TYPE = 'codeType',
45 COMMAND = 'command', 48 COMMAND = 'command',
  49 + OPEN_COMMAND = 'openCommand',
  50 + CLOSE_COMMAND = 'closeCommand',
46 COMMAND_TYPE = 'commandType', 51 COMMAND_TYPE = 'commandType',
47 SERVICE = 'service', 52 SERVICE = 'service',
  53 + OPEN_SERVICE = 'openService',
  54 + CLOSE_SERVICE = 'closeService',
  55 + EXTENSION_DESC = 'extensionDesc',
48 CALL_TYPE = 'callType', 56 CALL_TYPE = 'callType',
49 } 57 }
50 58
@@ -72,7 +80,7 @@ const getDeviceService = async (deviceProfileId: string) => { @@ -72,7 +80,7 @@ const getDeviceService = async (deviceProfileId: string) => {
72 const getDeviceAttribute = async (params: DeviceAttributeParams) => { 80 const getDeviceAttribute = async (params: DeviceAttributeParams) => {
73 try { 81 try {
74 const data = await getDeviceAttributes(params); 82 const data = await getDeviceAttributes(params);
75 - if (data) return data.map((item) => ({ label: item.name, value: item.identifier })); 83 + if (data) return data.map((item) => ({ ...item, label: item.name, value: item.identifier }));
76 } catch (error) {} 84 } catch (error) {}
77 return []; 85 return [];
78 }; 86 };
@@ -82,7 +90,6 @@ export const commonDataSourceSchemas = (): FormSchema[] => { @@ -82,7 +90,6 @@ export const commonDataSourceSchemas = (): FormSchema[] => {
82 const isUpdate = unref(mode) === DataActionModeEnum.UPDATE; 90 const isUpdate = unref(mode) === DataActionModeEnum.UPDATE;
83 const selectWidgetKeys = useSelectWidgetKeys(); 91 const selectWidgetKeys = useSelectWidgetKeys();
84 const category = unref(selectWidgetKeys).categoryKey; 92 const category = unref(selectWidgetKeys).categoryKey;
85 -  
86 return [ 93 return [
87 { 94 {
88 field: DataSourceField.IS_GATEWAY_DEVICE, 95 field: DataSourceField.IS_GATEWAY_DEVICE,
@@ -161,6 +168,7 @@ export const commonDataSourceSchemas = (): FormSchema[] => { @@ -161,6 +168,7 @@ export const commonDataSourceSchemas = (): FormSchema[] => {
161 [DataSourceField.ATTRIBUTE]: null, 168 [DataSourceField.ATTRIBUTE]: null,
162 [DataSourceField.ATTRIBUTE_NAME]: null, 169 [DataSourceField.ATTRIBUTE_NAME]: null,
163 [DataSourceField.TRANSPORT_TYPE]: option[DataSourceField.TRANSPORT_TYPE], 170 [DataSourceField.TRANSPORT_TYPE]: option[DataSourceField.TRANSPORT_TYPE],
  171 + [DataSourceField.COMMAND_TYPE]: null,
164 }); 172 });
165 }, 173 },
166 getPopupContainer: () => document.body, 174 getPopupContainer: () => document.body,
@@ -228,6 +236,9 @@ export const commonDataSourceSchemas = (): FormSchema[] => { @@ -228,6 +236,9 @@ export const commonDataSourceSchemas = (): FormSchema[] => {
228 onChange(_value, record: MasterDeviceList) { 236 onChange(_value, record: MasterDeviceList) {
229 setFieldsValue({ 237 setFieldsValue({
230 [DataSourceField.DEVICE_NAME]: record?.label, 238 [DataSourceField.DEVICE_NAME]: record?.label,
  239 + [DataSourceField.CODE_TYPE]: record?.codeType,
  240 + [DataSourceField.DEVICE_CODE]: record?.code,
  241 + [DataSourceField.COMMAND_TYPE]: null,
231 }); 242 });
232 }, 243 },
233 placeholder: '请选择设备', 244 placeholder: '请选择设备',
@@ -236,19 +247,94 @@ export const commonDataSourceSchemas = (): FormSchema[] => { @@ -236,19 +247,94 @@ export const commonDataSourceSchemas = (): FormSchema[] => {
236 }, 247 },
237 }, 248 },
238 { 249 {
  250 + field: DataSourceField.CODE_TYPE,
  251 + component: 'Input',
  252 + label: '设备标识符',
  253 + show: false,
  254 + },
  255 +
  256 + {
  257 + field: DataSourceField.DEVICE_CODE,
  258 + component: 'Input',
  259 + show: false,
  260 + label: '设备地址码',
  261 + },
  262 +
  263 + {
239 field: DataSourceField.ATTRIBUTE_NAME, 264 field: DataSourceField.ATTRIBUTE_NAME,
240 component: 'Input', 265 component: 'Input',
241 label: '属性名', 266 label: '属性名',
242 show: false, 267 show: false,
243 }, 268 },
244 { 269 {
  270 + field: DataSourceField.COMMAND_TYPE,
  271 + component: 'ApiSelect',
  272 + label: '命令类型',
  273 + defaultValue: CommandTypeEnum.CUSTOM.toString(),
  274 + rules: [{ required: true, message: '请选择命令类型' }],
  275 + colProps: { span: 8 },
  276 + ifShow: ({ model }) => {
  277 + return isControlComponent(category!) && isTcpProfile(model[DataSourceField.TRANSPORT_TYPE]);
  278 + },
  279 + componentProps: ({ formActionType, formModel }) => {
  280 + const { setFieldsValue } = formActionType;
  281 + const { codeType } = formModel || {};
  282 + return {
  283 + // api: findDictItemByCode,
  284 + api: async (params: Recordable) => {
  285 + try {
  286 + const record = await findDictItemByCode(params);
  287 + if (unref(selectWidgetKeys).componentKey == 'LateralNumericalControl') {
  288 + return record.filter(
  289 + (item) => item.itemValue == CommandTypeEnum.ATTRIBUTE.toString()
  290 + );
  291 + }
  292 + if (codeType == TaskTypeEnum.MODBUS_RTU) {
  293 + // setFieldsValue({ [DataSourceField.COMMAND_TYPE]: undefined });
  294 + return record.filter(
  295 + (item) => item.itemValue !== CommandTypeEnum.CUSTOM.toString()
  296 + );
  297 + } else {
  298 + return record.filter(
  299 + (item) => item.itemValue !== CommandTypeEnum.ATTRIBUTE.toString()
  300 + );
  301 + }
  302 + } catch (error) {
  303 + console.log(error);
  304 + return [];
  305 + }
  306 + },
  307 + params: {
  308 + dictCode: 'custom_define',
  309 + },
  310 + labelField: 'itemText',
  311 + valueField: 'itemValue',
  312 + placeholder: '请选择命令类型',
  313 + getPopupContainer: () => document.body,
  314 + onChange() {
  315 + setFieldsValue({
  316 + [DataSourceField.COMMAND]: null,
  317 + [DataSourceField.SERVICE]: null,
  318 + [DataSourceField.OPEN_COMMAND]: null,
  319 + [DataSourceField.CLOSE_COMMAND]: null,
  320 + [DataSourceField.OPEN_SERVICE]: null,
  321 + [DataSourceField.CLOSE_SERVICE]: null,
  322 + [DataSourceField.CALL_TYPE]: null,
  323 + [DataSourceField.ATTRIBUTE]: null,
  324 + });
  325 + },
  326 + };
  327 + },
  328 + },
  329 + {
245 field: DataSourceField.ATTRIBUTE, 330 field: DataSourceField.ATTRIBUTE,
246 component: 'ApiSelect', 331 component: 'ApiSelect',
247 label: '属性', 332 label: '属性',
248 colProps: { span: 8 }, 333 colProps: { span: 8 },
249 rules: [{ required: true, message: '请选择属性' }], 334 rules: [{ required: true, message: '请选择属性' }],
250 ifShow: ({ model }) => 335 ifShow: ({ model }) =>
251 - !(isTcpProfile(model[DataSourceField.TRANSPORT_TYPE]) && isControlComponent(category!)), 336 + !(isTcpProfile(model[DataSourceField.TRANSPORT_TYPE]) && isControlComponent(category!)) ||
  337 + model[DataSourceField.COMMAND_TYPE] == 2,
252 componentProps({ formModel, formActionType }) { 338 componentProps({ formModel, formActionType }) {
253 const { setFieldsValue } = formActionType; 339 const { setFieldsValue } = formActionType;
254 const deviceProfileId = formModel[DataSourceField.DEVICE_PROFILE_ID]; 340 const deviceProfileId = formModel[DataSourceField.DEVICE_PROFILE_ID];
@@ -266,16 +352,15 @@ export const commonDataSourceSchemas = (): FormSchema[] => { @@ -266,16 +352,15 @@ export const commonDataSourceSchemas = (): FormSchema[] => {
266 : undefined, 352 : undefined,
267 }); 353 });
268 354
269 - // 当我们通过复制组件在进行编辑的时候选择控制组件会使不是bool属性的值进行赋值  
270 - if (  
271 - (!option?.length &&  
272 - isControlComponent(category!) &&  
273 - unref(selectWidgetKeys).componentKey !== 'LateralNumericalControl') ||  
274 - isBooleanComponent(unref(selectWidgetKeys))  
275 - ) { 355 + // 选择控制组件4的时候只能选择属性且是(int double类型)
  356 + if (unref(selectWidgetKeys).componentKey == 'LateralNumericalControl') {
276 setFieldsValue({ 357 setFieldsValue({
277 - [DataSourceField.ATTRIBUTE]: null, 358 + [DataSourceField.COMMAND_TYPE]: CommandTypeEnum.ATTRIBUTE.toString(),
278 }); 359 });
  360 + return option.filter(
  361 + (item) =>
  362 + item.detail.dataType.type == 'INT' || item.detail.dataType.type == 'DOUBLE'
  363 + );
279 } 364 }
280 return option; 365 return option;
281 } 366 }
@@ -284,53 +369,79 @@ export const commonDataSourceSchemas = (): FormSchema[] => { @@ -284,53 +369,79 @@ export const commonDataSourceSchemas = (): FormSchema[] => {
284 }, 369 },
285 placeholder: '请选择属性', 370 placeholder: '请选择属性',
286 getPopupContainer: () => document.body, 371 getPopupContainer: () => document.body,
287 - onChange(value: string, option: Record<'label' | 'value', string>) {  
288 - setFieldsValue({ [DataSourceField.ATTRIBUTE_NAME]: value ? option.label : null }); 372 + onChange(value: string, option: Record<'label' | 'value' | any, string>) {
  373 + setFieldsValue({
  374 + [DataSourceField.ATTRIBUTE_NAME]: value ? option.label : null,
  375 + [DataSourceField.EXTENSION_DESC]: value ? JSON.stringify(option.extensionDesc) : '',
  376 + });
289 }, 377 },
290 }; 378 };
291 }, 379 },
292 }, 380 },
293 { 381 {
294 - field: DataSourceField.COMMAND_TYPE, 382 + field: DataSourceField.EXTENSION_DESC,
  383 + component: 'Input',
  384 + show: false,
  385 + label: '扩展描述符',
  386 + },
  387 +
  388 + {
  389 + field: DataSourceField.CALL_TYPE,
  390 + component: 'Input',
  391 + ifShow: false,
  392 + label: 'callType',
  393 + },
  394 + {
  395 + field: DataSourceField.OPEN_SERVICE,
295 component: 'ApiSelect', 396 component: 'ApiSelect',
296 - label: '命令类型',  
297 - defaultValue: CommandTypeEnum.CUSTOM.toString(),  
298 - rules: [{ required: true, message: '请选择命令类型' }], 397 + label: '开服务',
299 colProps: { span: 8 }, 398 colProps: { span: 8 },
  399 + rules: [{ required: true, message: '请选择开服务' }],
300 ifShow: ({ model }) => 400 ifShow: ({ model }) =>
301 - isControlComponent(category!) && isTcpProfile(model[DataSourceField.TRANSPORT_TYPE]),  
302 - componentProps: ({ formActionType }) => { 401 + isControlComponent(category!) &&
  402 + model[DataSourceField.COMMAND_TYPE] === CommandTypeEnum.SERVICE.toString() &&
  403 + isTcpProfile(model[DataSourceField.TRANSPORT_TYPE]),
  404 + componentProps({ formModel, formActionType }) {
303 const { setFieldsValue } = formActionType; 405 const { setFieldsValue } = formActionType;
  406 + const deviceProfileId = formModel[DataSourceField.DEVICE_PROFILE_ID];
  407 + const transportType = formModel[DataSourceField.TRANSPORT_TYPE];
  408 + if (isUpdate && ![deviceProfileId, transportType].every(Boolean))
  409 + return { placeholder: '请选择开服务', getPopupContainer: () => document.body };
304 return { 410 return {
305 - api: findDictItemByCode,  
306 - params: {  
307 - dictCode: 'custom_define', 411 + api: async () => {
  412 + try {
  413 + if (deviceProfileId) {
  414 + const services = await getDeviceService(deviceProfileId);
  415 + const value = formModel[DataSourceField.SERVICE];
  416 + if (value) {
  417 + const selected = services.find((item) => item.value === value);
  418 + selected && setFieldsValue({ [DataSourceField.CALL_TYPE]: selected.callType });
  419 + }
  420 + return services;
  421 + }
  422 + } catch (error) {}
  423 + return [];
308 }, 424 },
309 - labelField: 'itemText',  
310 - valueField: 'itemValue',  
311 - placeholder: '请选择命令类型',  
312 - onChange() { 425 + placeholder: '请选择开服务',
  426 + getPopupContainer: () => document.body,
  427 + onChange(value: string, options: ModelOfMatterParams) {
  428 + const command = value
  429 + ? (options.functionJson.inputData || [])[0]?.serviceCommand
  430 + : null;
313 setFieldsValue({ 431 setFieldsValue({
314 - [DataSourceField.COMMAND]: null,  
315 - [DataSourceField.SERVICE]: null,  
316 - [DataSourceField.CALL_TYPE]: null, 432 + [DataSourceField.OPEN_COMMAND]: command,
  433 + [DataSourceField.CALL_TYPE]: value ? options.callType : null,
317 }); 434 });
318 }, 435 },
319 }; 436 };
320 }, 437 },
321 }, 438 },
322 { 439 {
323 - field: DataSourceField.CALL_TYPE,  
324 - component: 'Input',  
325 - ifShow: false,  
326 - label: 'callType',  
327 - },  
328 - {  
329 - field: DataSourceField.SERVICE, 440 + field: DataSourceField.CLOSE_SERVICE,
330 component: 'ApiSelect', 441 component: 'ApiSelect',
331 - label: '服务', 442 + label: '服务',
332 colProps: { span: 8 }, 443 colProps: { span: 8 },
333 - rules: [{ required: true, message: '请选择服务' }], 444 + rules: [{ required: true, message: '请选择服务' }],
334 ifShow: ({ model }) => 445 ifShow: ({ model }) =>
335 isControlComponent(category!) && 446 isControlComponent(category!) &&
336 model[DataSourceField.COMMAND_TYPE] === CommandTypeEnum.SERVICE.toString() && 447 model[DataSourceField.COMMAND_TYPE] === CommandTypeEnum.SERVICE.toString() &&
@@ -340,7 +451,7 @@ export const commonDataSourceSchemas = (): FormSchema[] => { @@ -340,7 +451,7 @@ export const commonDataSourceSchemas = (): FormSchema[] => {
340 const deviceProfileId = formModel[DataSourceField.DEVICE_PROFILE_ID]; 451 const deviceProfileId = formModel[DataSourceField.DEVICE_PROFILE_ID];
341 const transportType = formModel[DataSourceField.TRANSPORT_TYPE]; 452 const transportType = formModel[DataSourceField.TRANSPORT_TYPE];
342 if (isUpdate && ![deviceProfileId, transportType].every(Boolean)) 453 if (isUpdate && ![deviceProfileId, transportType].every(Boolean))
343 - return { placeholder: '请选择服务', getPopupContainer: () => document.body }; 454 + return { placeholder: '请选择服务', getPopupContainer: () => document.body };
344 return { 455 return {
345 api: async () => { 456 api: async () => {
346 try { 457 try {
@@ -356,14 +467,14 @@ export const commonDataSourceSchemas = (): FormSchema[] => { @@ -356,14 +467,14 @@ export const commonDataSourceSchemas = (): FormSchema[] => {
356 } catch (error) {} 467 } catch (error) {}
357 return []; 468 return [];
358 }, 469 },
359 - placeholder: '请选择服务', 470 + placeholder: '请选择服务',
360 getPopupContainer: () => document.body, 471 getPopupContainer: () => document.body,
361 onChange(value: string, options: ModelOfMatterParams) { 472 onChange(value: string, options: ModelOfMatterParams) {
362 const command = value 473 const command = value
363 ? (options.functionJson.inputData || [])[0]?.serviceCommand 474 ? (options.functionJson.inputData || [])[0]?.serviceCommand
364 : null; 475 : null;
365 setFieldsValue({ 476 setFieldsValue({
366 - [DataSourceField.COMMAND]: command, 477 + [DataSourceField.CLOSE_COMMAND]: command,
367 [DataSourceField.CALL_TYPE]: value ? options.callType : null, 478 [DataSourceField.CALL_TYPE]: value ? options.callType : null,
368 }); 479 });
369 }, 480 },
@@ -371,11 +482,27 @@ export const commonDataSourceSchemas = (): FormSchema[] => { @@ -371,11 +482,27 @@ export const commonDataSourceSchemas = (): FormSchema[] => {
371 }, 482 },
372 }, 483 },
373 { 484 {
374 - field: DataSourceField.COMMAND, 485 + field: DataSourceField.OPEN_COMMAND,
  486 + component: 'Input',
  487 + label: '命令',
  488 + colProps: { span: 8 },
  489 + rules: [{ required: true, message: '请输入开下发命令' }],
  490 + // 是控制组件 && 自定义命令 && 传输协议为TCP
  491 + ifShow: ({ model }) =>
  492 + isControlComponent(category!) &&
  493 + model[DataSourceField.COMMAND_TYPE] === CommandTypeEnum.CUSTOM.toString() &&
  494 + model[DataSourceField.TRANSPORT_TYPE] &&
  495 + isTcpProfile(model[DataSourceField.TRANSPORT_TYPE]),
  496 + componentProps: {
  497 + placeholder: '请输入开下发命令',
  498 + },
  499 + },
  500 + {
  501 + field: DataSourceField.CLOSE_COMMAND,
375 component: 'Input', 502 component: 'Input',
376 label: '命令', 503 label: '命令',
377 colProps: { span: 8 }, 504 colProps: { span: 8 },
378 - rules: [{ required: true, message: '请输入下发命令' }], 505 + rules: [{ required: true, message: '请输入下发命令' }],
379 // 是控制组件 && 自定义命令 && 传输协议为TCP 506 // 是控制组件 && 自定义命令 && 传输协议为TCP
380 ifShow: ({ model }) => 507 ifShow: ({ model }) =>
381 isControlComponent(category!) && 508 isControlComponent(category!) &&
@@ -383,7 +510,7 @@ export const commonDataSourceSchemas = (): FormSchema[] => { @@ -383,7 +510,7 @@ export const commonDataSourceSchemas = (): FormSchema[] => {
383 model[DataSourceField.TRANSPORT_TYPE] && 510 model[DataSourceField.TRANSPORT_TYPE] &&
384 isTcpProfile(model[DataSourceField.TRANSPORT_TYPE]), 511 isTcpProfile(model[DataSourceField.TRANSPORT_TYPE]),
385 componentProps: { 512 componentProps: {
386 - placeholder: '请输入下发命令', 513 + placeholder: '请输入下发命令',
387 }, 514 },
388 }, 515 },
389 { 516 {
1 export enum ComponentConfigFieldEnum { 1 export enum ComponentConfigFieldEnum {
2 - FONT_COLOR = 'fontColor', 2 + FONT_COLOR = 'fontColor', //数值字体颜色
  3 + VALUE_SIZE = 'valueSize', //数值字体大小
  4 + TEXT_COLOR = 'textColor', //文本字体颜色
  5 + FONT_SIZE = 'fontSize', //文本数值颜色
3 UNIT = 'unit', 6 UNIT = 'unit',
4 POINTER_COLOR = 'pointerColor', 7 POINTER_COLOR = 'pointerColor',
5 INSTRUMENT_PANEL_COLOR = 'instrumentPanelColor', 8 INSTRUMENT_PANEL_COLOR = 'instrumentPanelColor',
@@ -102,7 +102,7 @@ class Subscriber { @@ -102,7 +102,7 @@ class Subscriber {
102 return { 102 return {
103 cmdId: subscriptionId, 103 cmdId: subscriptionId,
104 entityId: deviceId, 104 entityId: deviceId,
105 - keys: Array.from(attributes.values()).join(','), 105 + keys: Array.from(attributes.values()).filter(Boolean).join(','),
106 entityType: EntityTypeEnum.DEVICE, 106 entityType: EntityTypeEnum.DEVICE,
107 scope: ScopeTypeEnum.LATEST_TELEMERY, 107 scope: ScopeTypeEnum.LATEST_TELEMERY,
108 ...(unsubscribe ? { unsubscribe } : {}), 108 ...(unsubscribe ? { unsubscribe } : {}),
@@ -14,7 +14,7 @@ export function useSendCommand() { @@ -14,7 +14,7 @@ export function useSendCommand() {
14 return false; 14 return false;
15 }; 15 };
16 16
17 - const sendCommand = async (record: DataSource, value: any) => { 17 + const sendCommand = async (record: DataSource, value: any, isModbusCommand = false) => {
18 if (!record) return false; 18 if (!record) return false;
19 const { customCommand, attribute } = record || {}; 19 const { customCommand, attribute } = record || {};
20 const { deviceId } = record; 20 const { deviceId } = record;
@@ -25,16 +25,18 @@ export function useSendCommand() { @@ -25,16 +25,18 @@ export function useSendCommand() {
25 let params: string | Recordable = { 25 let params: string | Recordable = {
26 [attribute!]: Number(value), 26 [attribute!]: Number(value),
27 }; 27 };
  28 + if (isModbusCommand) {
  29 + params = value;
  30 + }
28 31
29 let sendCommandFn = sendCommandOneway; 32 let sendCommandFn = sendCommandOneway;
30 // 如果是TCP设备从物模型中获取下发命令(TCP网关子设备无物模型服务与事件) 33 // 如果是TCP设备从物模型中获取下发命令(TCP网关子设备无物模型服务与事件)
31 - if (customCommand?.transportType === TransportTypeEnum.TCP) { 34 + if (customCommand?.transportType === TransportTypeEnum.TCP && !isModbusCommand) {
32 params = customCommand.command!; 35 params = customCommand.command!;
33 if (customCommand.callType === ServiceCallTypeEnum.SYNC) { 36 if (customCommand.callType === ServiceCallTypeEnum.SYNC) {
34 sendCommandFn = sendCommandTwoway; 37 sendCommandFn = sendCommandTwoway;
35 } 38 }
36 } 39 }
37 -  
38 // 控制按钮下发命令为0 或 1 40 // 控制按钮下发命令为0 或 1
39 await sendCommandFn({ 41 await sendCommandFn({
40 deviceId, 42 deviceId,
@@ -54,7 +54,7 @@ @@ -54,7 +54,7 @@
54 }, 54 },
55 labelWidth: 120, 55 labelWidth: 120,
56 fieldMapToTime: [ 56 fieldMapToTime: [
57 - [SchemaFiled.DATE_RANGE, [SchemaFiled.START_TS, SchemaFiled.END_TS], 'YYYY-MM-DD HH:ss'], 57 + [SchemaFiled.DATE_RANGE, [SchemaFiled.START_TS, SchemaFiled.END_TS], 'YYYY-MM-DD HH:mm:ss'],
58 ], 58 ],
59 submitButtonOptions: { 59 submitButtonOptions: {
60 loading: loading as unknown as boolean, 60 loading: loading as unknown as boolean,
@@ -260,7 +260,7 @@ @@ -260,7 +260,7 @@
260 :show-ok-btn="false" 260 :show-ok-btn="false"
261 cancel-text="关闭" 261 cancel-text="关闭"
262 width="70%" 262 width="70%"
263 - title="历史趋势" 263 + title="选择时间"
264 > 264 >
265 <section 265 <section
266 class="flex flex-col p-4 h-full w-full min-w-7/10" 266 class="flex flex-col p-4 h-full w-full min-w-7/10"
@@ -152,8 +152,10 @@ @@ -152,8 +152,10 @@
152 <section class="p-5 flex flex-col w-full"> 152 <section class="p-5 flex flex-col w-full">
153 <main class="flex w-full h-full h-7"> 153 <main class="flex w-full h-full h-7">
154 <Tooltip :title="sourceInfo.name"> 154 <Tooltip :title="sourceInfo.name">
155 - <div class="flex-1 w-full h-full flex text-lg justify-center font-semibold">  
156 - {{ sourceInfo.name }} 155 + <div class="flex-1 w-full h-full flex text-lg justify-center font-semibold truncate">
  156 + <div class="w-full truncate text-center">
  157 + {{ sourceInfo.name }}
  158 + </div>
157 </div> 159 </div>
158 </Tooltip> 160 </Tooltip>
159 161
@@ -28,6 +28,7 @@ export interface DataSource { @@ -28,6 +28,7 @@ export interface DataSource {
28 componentInfo: ComponentInfo; 28 componentInfo: ComponentInfo;
29 customCommand: CustomCommand; 29 customCommand: CustomCommand;
30 videoConfig?: VideoConfigType; 30 videoConfig?: VideoConfigType;
  31 + [key: string]: any;
31 } 32 }
32 33
33 export interface ExtraDataSource extends DataSource, PublicComponentOptions { 34 export interface ExtraDataSource extends DataSource, PublicComponentOptions {
@@ -62,6 +63,8 @@ export interface ComponentInfo { @@ -62,6 +63,8 @@ export interface ComponentInfo {
62 progressBarCircle?: Boolean; 63 progressBarCircle?: Boolean;
63 lineColor?: string; 64 lineColor?: string;
64 maxNumber?: number; 65 maxNumber?: number;
  66 + fontSize?: string | number;
  67 + valueSize?: string | number;
65 [key: string]: any; 68 [key: string]: any;
66 } 69 }
67 70
@@ -71,6 +74,7 @@ export interface CustomCommand { @@ -71,6 +74,7 @@ export interface CustomCommand {
71 command: string; 74 command: string;
72 service: string; 75 service: string;
73 callType: string; 76 callType: string;
  77 + [key: string]: string | undefined;
74 } 78 }
75 79
76 export interface ComponentLayoutType { 80 export interface ComponentLayoutType {