Commit 837a9b854f92eb675e52f0771f830492bee3ba2a

Authored by loveumiko
1 parent 6b4a4c5a

feat: 新增数据看板组件

Showing 70 changed files with 3411 additions and 2 deletions
  1 +import cloneDeep from 'lodash-es/cloneDeep';
  2 +import { LateralNumericalControlConfig } from '.';
  3 +import {
  4 + ConfigType,
  5 + CreateComponentType,
  6 + PublicComponentOptions,
  7 + PublicPresetOptions,
  8 +} from '/@/views/visual/packages/index.type';
  9 +import { PublicConfigClass, componentInitConfig } from '/@/views/visual/packages/publicConfig';
  10 +import { ComponentConfigFieldEnum } from '../../../enum';
  11 +
  12 +export const option: PublicPresetOptions = {
  13 + [ComponentConfigFieldEnum.SHOW_DEVICE_NAME]: false,
  14 + [ComponentConfigFieldEnum.CONTROL_BAR_COLOR]: '#0072ff',
  15 + [ComponentConfigFieldEnum.FONT_COLOR]: '#000000',
  16 +};
  17 +
  18 +export default class Config extends PublicConfigClass implements CreateComponentType {
  19 + public key: string = LateralNumericalControlConfig.key;
  20 +
  21 + public attr = { ...componentInitConfig };
  22 +
  23 + public componentConfig: ConfigType = cloneDeep(LateralNumericalControlConfig);
  24 +
  25 + public persetOption = cloneDeep(option);
  26 +
  27 + public option: PublicComponentOptions;
  28 +
  29 + constructor(option: PublicComponentOptions) {
  30 + super();
  31 + this.option = { ...option };
  32 + }
  33 +}
  1 +<script lang="ts" setup>
  2 + import { ComponentConfigFieldEnum } from '/@/views/visual/packages/enum';
  3 + import { useForm, BasicForm } from '/@/components/Form';
  4 + import { PublicFormInstaceType } from '/@/views/visual/dataSourceBindPanel/index.type';
  5 + import { option } from './config';
  6 +
  7 + const [register, { getFieldsValue, setFieldsValue, resetFields }] = useForm({
  8 + schemas: [
  9 + {
  10 + field: ComponentConfigFieldEnum.CONTROL_BAR_COLOR,
  11 + label: '控制栏背景色',
  12 + component: 'ColorPicker',
  13 + changeEvent: 'update:value',
  14 + defaultValue: option.controlBarColor,
  15 + },
  16 + {
  17 + field: ComponentConfigFieldEnum.FONT_COLOR,
  18 + label: '数值字体颜色',
  19 + component: 'ColorPicker',
  20 + changeEvent: 'update:value',
  21 + defaultValue: option.fontColor,
  22 + },
  23 + {
  24 + field: ComponentConfigFieldEnum.SHOW_DEVICE_NAME,
  25 + label: '显示设备名称',
  26 + component: 'Checkbox',
  27 + defaultValue: option.showDeviceName,
  28 + },
  29 + ],
  30 + showActionButtonGroup: false,
  31 + labelWidth: 120,
  32 + baseColProps: {
  33 + span: 12,
  34 + },
  35 + });
  36 +
  37 + const getFormValues = () => {
  38 + return getFieldsValue();
  39 + };
  40 +
  41 + const setFormValues = (data: Recordable) => {
  42 + return setFieldsValue(data);
  43 + };
  44 +
  45 + defineExpose({
  46 + getFormValues,
  47 + setFormValues,
  48 + resetFormValues: resetFields,
  49 + } as PublicFormInstaceType);
  50 +</script>
  51 +
  52 +<template>
  53 + <BasicForm @register="register" />
  54 +</template>
  1 +<script lang="ts" setup>
  2 + import { CreateComponentType } from '/@/views/visual/packages/index.type';
  3 + import { BasicForm, useForm } from '/@/components/Form';
  4 + import {
  5 + PublicComponentValueType,
  6 + PublicFormInstaceType,
  7 + } from '/@/views/visual/dataSourceBindPanel/index.type';
  8 + import {
  9 + CommonDataSourceBindValueType,
  10 + commonDataSourceSchemas,
  11 + } from '../../../config/common.config';
  12 + import { DataSource } from '/@/views/visual/palette/types';
  13 +
  14 + defineProps<{
  15 + values: PublicComponentValueType;
  16 + componentConfig: CreateComponentType;
  17 + }>();
  18 +
  19 + const [register, { getFieldsValue, setFieldsValue, validate, resetFields }] = useForm({
  20 + labelWidth: 0,
  21 + showActionButtonGroup: false,
  22 + layout: 'horizontal',
  23 + labelCol: { span: 0 },
  24 + schemas: commonDataSourceSchemas(),
  25 + });
  26 +
  27 + const getFormValues = () => {
  28 + let value = getFieldsValue() as CommonDataSourceBindValueType;
  29 + value = {
  30 + ...value,
  31 + customCommand: {
  32 + transportType: value.transportType,
  33 + service: value.service,
  34 + command: value.command,
  35 + commandType: value.commandType,
  36 + },
  37 + };
  38 + return value;
  39 + };
  40 +
  41 + const setFormValues = (record: DataSource) => {
  42 + const { customCommand } = record;
  43 + return setFieldsValue({
  44 + ...record,
  45 + transportType: customCommand?.transportType,
  46 + service: customCommand?.service,
  47 + command: customCommand?.command,
  48 + commandType: customCommand?.commandType,
  49 + } as unknown as Partial<CommonDataSourceBindValueType>);
  50 + };
  51 +
  52 + defineExpose({
  53 + getFormValues,
  54 + setFormValues,
  55 + validate,
  56 + resetFormValues: resetFields,
  57 + } as PublicFormInstaceType);
  58 +</script>
  59 +
  60 +<template>
  61 + <BasicForm @register="register" />
  62 +</template>
  1 +import { useComponentKeys } from '/@/views/visual/packages/hook/useComponentKeys';
  2 +import { ConfigType, PackagesCategoryEnum } from '/@/views/visual/packages/index.type';
  3 +
  4 +const componentKeys = useComponentKeys('LateralNumericalControl');
  5 +
  6 +export const LateralNumericalControlConfig: ConfigType = {
  7 + ...componentKeys,
  8 + title: '控制组件1',
  9 + package: PackagesCategoryEnum.CONTROL,
  10 +};
  1 +<script lang="ts" setup>
  2 + import { ComponentPropsConfigType, DataFetchUpdateFn } from '/@/views/visual/packages/index.type';
  3 + import { option } from './config';
  4 + import { useDataFetch } from '/@/views/visual/packages/hook/useSocket';
  5 + import { Slider } from 'ant-design-vue';
  6 + import { computed, ref } from 'vue';
  7 + import { useComponentScale } from '../../../hook/useComponentScale';
  8 + import { DeviceName } from '/@/views/visual/commonComponents/DeviceName';
  9 +
  10 + const props = defineProps<{
  11 + config: ComponentPropsConfigType<typeof option>;
  12 + }>();
  13 +
  14 + const sliderValue = ref<number>(33);
  15 + const sMin = ref<number>(0);
  16 + const sMax = ref<number>(100);
  17 +
  18 + const getDesign = computed(() => {
  19 + const { option, persetOption } = props.config;
  20 + const { componentInfo, attribute, attributeRename } = option;
  21 + const { controlBarColor: persetControlBarColor, fonColor: persetFontColor } =
  22 + persetOption || {};
  23 + const { controlBarColor, fontColor } = componentInfo || {};
  24 + return {
  25 + attribute: attributeRename || attribute,
  26 + controlBarColor: controlBarColor ?? persetControlBarColor,
  27 + fontColor: fontColor ?? persetFontColor,
  28 + };
  29 + });
  30 +
  31 + const handleChange = async () => {};
  32 +
  33 + const updateFn: DataFetchUpdateFn = () => {
  34 + // console.log(message, 'message', attribute, 'attribute');
  35 + };
  36 +
  37 + useDataFetch(props, updateFn);
  38 + const { getScale } = useComponentScale(props);
  39 +</script>
  40 +
  41 +<template>
  42 + <main class="w-full h-full flex flex-col justify-center">
  43 + <DeviceName :config="config" class="text-center" />
  44 + <main :style="getScale">
  45 + <div class="flex flex-col ml-11 mr-11">
  46 + <span
  47 + :style="{ color: getDesign.fontColor }"
  48 + class="font-bold text-xl mt-3 truncate text-center"
  49 + >{{ sliderValue }}</span
  50 + >
  51 + <Slider
  52 + :style="{ '--slider-color': getDesign.controlBarColor }"
  53 + class="no-drag"
  54 + v-model:value="sliderValue"
  55 + :min="sMin"
  56 + :max="sMax"
  57 + @change="handleChange"
  58 + />
  59 +
  60 + <span
  61 + :style="{ color: getDesign.fontColor }"
  62 + class="mt-3 truncate font-bold text-xs text-center"
  63 + >
  64 + {{ getDesign.attribute || '设备1' }}
  65 + </span>
  66 + </div>
  67 + </main>
  68 + </main>
  69 +</template>
  70 +<style lang="less" scoped>
  71 + :deep(.ant-slider-track) {
  72 + background: var(--slider-color) !important;
  73 + }
  74 +</style>
  1 +import cloneDeep from 'lodash-es/cloneDeep';
  2 +import { SwitchListConfig } from '.';
  3 +import {
  4 + ConfigType,
  5 + CreateComponentType,
  6 + PublicComponentOptions,
  7 + PublicPresetOptions,
  8 +} from '/@/views/visual/packages/index.type';
  9 +import { PublicConfigClass, componentInitConfig } from '/@/views/visual/packages/publicConfig';
  10 +import { ComponentConfigFieldEnum } from '../../../enum';
  11 +
  12 +export const option: PublicPresetOptions = {
  13 + multipleDataSourceComponent: true,
  14 + [ComponentConfigFieldEnum.ICON]: 'shuiwen',
  15 + [ComponentConfigFieldEnum.ICON_COLOR]: '#377DFF',
  16 + [ComponentConfigFieldEnum.SHOW_DEVICE_NAME]: false,
  17 +};
  18 +
  19 +export default class Config extends PublicConfigClass implements CreateComponentType {
  20 + public key: string = SwitchListConfig.key;
  21 +
  22 + public attr = { ...componentInitConfig };
  23 +
  24 + public componentConfig: ConfigType = cloneDeep(SwitchListConfig);
  25 +
  26 + public persetOption = cloneDeep(option);
  27 +
  28 + public option: PublicComponentOptions;
  29 +
  30 + constructor(option: PublicComponentOptions) {
  31 + super();
  32 + this.option = { ...option };
  33 + }
  34 +}
  1 +<script lang="ts" setup>
  2 + import { ComponentConfigFieldEnum } from '/@/views/visual/packages/enum';
  3 + import { useForm, BasicForm } from '/@/components/Form';
  4 + import { PublicFormInstaceType } from '/@/views/visual/dataSourceBindPanel/index.type';
  5 + import { option } from './config';
  6 +
  7 + const [register, { getFieldsValue, setFieldsValue, resetFields }] = useForm({
  8 + schemas: [
  9 + {
  10 + field: ComponentConfigFieldEnum.ICON_COLOR,
  11 + label: '图标颜色',
  12 + component: 'ColorPicker',
  13 + changeEvent: 'update:value',
  14 + defaultValue: option.iconColor,
  15 + },
  16 + {
  17 + field: ComponentConfigFieldEnum.ICON,
  18 + label: '图标',
  19 + component: 'IconDrawer',
  20 + changeEvent: 'update:value',
  21 + defaultValue: option.icon,
  22 + componentProps({ formModel }) {
  23 + const color = formModel[ComponentConfigFieldEnum.ICON_COLOR];
  24 + return {
  25 + color,
  26 + };
  27 + },
  28 + },
  29 + {
  30 + field: ComponentConfigFieldEnum.SHOW_DEVICE_NAME,
  31 + label: '显示设备名称',
  32 + component: 'Checkbox',
  33 + defaultValue: option.showDeviceName,
  34 + },
  35 + ],
  36 + showActionButtonGroup: false,
  37 + labelWidth: 120,
  38 + baseColProps: {
  39 + span: 12,
  40 + },
  41 + });
  42 +
  43 + const getFormValues = () => {
  44 + return getFieldsValue();
  45 + };
  46 +
  47 + const setFormValues = (data: Recordable) => {
  48 + return setFieldsValue(data);
  49 + };
  50 +
  51 + defineExpose({
  52 + getFormValues,
  53 + setFormValues,
  54 + resetFormValues: resetFields,
  55 + } as PublicFormInstaceType);
  56 +</script>
  57 +
  58 +<template>
  59 + <BasicForm @register="register" />
  60 +</template>
  1 +<script lang="ts" setup>
  2 + import { CreateComponentType } from '/@/views/visual/packages/index.type';
  3 + import { BasicForm, useForm } from '/@/components/Form';
  4 + import {
  5 + PublicComponentValueType,
  6 + PublicFormInstaceType,
  7 + } from '/@/views/visual/dataSourceBindPanel/index.type';
  8 + import {
  9 + CommonDataSourceBindValueType,
  10 + commonDataSourceSchemas,
  11 + } from '../../../config/common.config';
  12 + import { DataSource } from '/@/views/visual/palette/types';
  13 +
  14 + defineProps<{
  15 + values: PublicComponentValueType;
  16 + componentConfig: CreateComponentType;
  17 + }>();
  18 +
  19 + const [register, { getFieldsValue, setFieldsValue, validate, resetFields }] = useForm({
  20 + labelWidth: 0,
  21 + showActionButtonGroup: false,
  22 + layout: 'horizontal',
  23 + labelCol: { span: 0 },
  24 + schemas: commonDataSourceSchemas(),
  25 + });
  26 +
  27 + const getFormValues = () => {
  28 + let value = getFieldsValue() as CommonDataSourceBindValueType;
  29 + value = {
  30 + ...value,
  31 + customCommand: {
  32 + transportType: value.transportType,
  33 + service: value.service,
  34 + command: value.command,
  35 + commandType: value.commandType,
  36 + },
  37 + };
  38 + return value;
  39 + };
  40 +
  41 + const setFormValues = (record: DataSource) => {
  42 + const { customCommand } = record;
  43 + return setFieldsValue({
  44 + ...record,
  45 + transportType: customCommand?.transportType,
  46 + service: customCommand?.service,
  47 + command: customCommand?.command,
  48 + commandType: customCommand?.commandType,
  49 + } as unknown as Partial<CommonDataSourceBindValueType>);
  50 + };
  51 +
  52 + defineExpose({
  53 + getFormValues,
  54 + setFormValues,
  55 + validate,
  56 + resetFormValues: resetFields,
  57 + } as PublicFormInstaceType);
  58 +</script>
  59 +
  60 +<template>
  61 + <BasicForm @register="register" />
  62 +</template>
  1 +import { useComponentKeys } from '/@/views/visual/packages/hook/useComponentKeys';
  2 +import { ConfigType, PackagesCategoryEnum } from '/@/views/visual/packages/index.type';
  3 +
  4 +const componentKeys = useComponentKeys('SwitchList');
  5 +
  6 +export const SwitchListConfig: ConfigType = {
  7 + ...componentKeys,
  8 + title: '开关量控制列表',
  9 + package: PackagesCategoryEnum.CONTROL,
  10 +};
  1 +<script lang="ts" setup>
  2 + import {
  3 + ComponentPropsConfigType,
  4 + MultipleDataFetchUpdateFn,
  5 + } from '/@/views/visual/packages/index.type';
  6 + import { option } from './config';
  7 + import { useMultipleDataFetch } from '/@/views/visual/packages/hook/useSocket';
  8 + import { SvgIcon } from '/@/components/Icon';
  9 + import { Switch } from 'ant-design-vue';
  10 + import { computed, ref } from 'vue';
  11 + import { useComponentScale } from '../../../hook/useComponentScale';
  12 + import { useSendCommand } from '../../../hook/useSendCommand';
  13 + import { unref } from 'vue';
  14 + import { DeviceName } from '/@/views/visual/commonComponents/DeviceName';
  15 +
  16 + const props = defineProps<{
  17 + config: ComponentPropsConfigType<typeof option>;
  18 + }>();
  19 +
  20 + const checked = ref(false);
  21 +
  22 + const svgList = ref<any>([
  23 + {
  24 + value: 26.2,
  25 + name: 'wendu',
  26 + icon: 'zongfushe',
  27 + unit: 'kw',
  28 + iconColor: '#367BFF',
  29 + fontColor: '#357CFB',
  30 + checked: false,
  31 + id: 0,
  32 + },
  33 + {
  34 + value: 53.7,
  35 + name: 'shidu',
  36 + icon: 'guangzhaoqiangdu',
  37 + unit: '℃',
  38 + iconColor: '#FFA000',
  39 + fontColor: '#FFA000',
  40 + checked: true,
  41 + id: 1,
  42 + },
  43 + ]);
  44 +
  45 + const getDesign = computed(() => {
  46 + const { persetOption = {}, option } = props.config;
  47 + const { dataSource = [] } = option || {};
  48 + const {
  49 + unit: persetUnit,
  50 + fontColor: persetFontColor,
  51 + icon: persetIcon,
  52 + iconColor: persetIconColor,
  53 + } = persetOption || {};
  54 + return {
  55 + dataSource: dataSource.map((item) => {
  56 + const { fontColor, icon, iconColor, unit } = item.componentInfo;
  57 + const { attribute, attributeRename } = item;
  58 + return {
  59 + unit: unit ?? persetUnit,
  60 + fontColor: fontColor ?? persetFontColor,
  61 + icon: icon ?? persetIcon,
  62 + iconColor: iconColor ?? persetIconColor,
  63 + attribute: attribute || attributeRename,
  64 + attributeRename,
  65 + };
  66 + }),
  67 + };
  68 + });
  69 +
  70 + const { sendCommand, loading } = useSendCommand();
  71 + const handleChange = async (index: number) => {
  72 + const flag = await sendCommand(props.config.option, unref(checked));
  73 + if (!flag) svgList[index].checked = !svgList[index].checked;
  74 + };
  75 +
  76 + const updateFn: MultipleDataFetchUpdateFn = (message) => {
  77 + const { data = {} } = message;
  78 + const { dataSource } = unref(getDesign);
  79 + svgList.value.length = 0;
  80 + svgList.value = dataSource.map((item) => {
  81 + const { icon, iconColor, unit, fontColor, attribute } = item || {};
  82 + const [latest] = data[attribute] || [];
  83 + const [_timespan, value] = latest || [];
  84 + return {
  85 + value: Number(value),
  86 + name: attribute,
  87 + icon,
  88 + unit,
  89 + iconColor,
  90 + fontColor,
  91 + };
  92 + });
  93 + };
  94 +
  95 + useMultipleDataFetch(props, updateFn);
  96 + const { getRatio } = useComponentScale(props);
  97 +</script>
  98 +
  99 +<template>
  100 + <main class="w-full h-full flex flex-col justify-evenly items-center">
  101 + <DeviceName :config="config" />
  102 + <div
  103 + style="width: 86%"
  104 + v-for="(item, index) in svgList"
  105 + :key="item.id"
  106 + class="flex justify-between items-center"
  107 + >
  108 + <div class="flex items-center">
  109 + <SvgIcon
  110 + :name="item.icon!"
  111 + prefix="iconfont"
  112 + :size="getRatio ? 30 * getRatio : 30"
  113 + :style="{ color: item.iconColor }"
  114 + />
  115 +
  116 + <div class="text-gray-500 text-lg truncate ml-6">{{ item.attribute || '温度' }}</div>
  117 + </div>
  118 +
  119 + <Switch v-model:checked="item.checked" :loading="loading" @change="handleChange(index)" />
  120 + </div>
  121 + </main>
  122 +</template>
1 import { ControlComponentSlidingSwitchConfig } from './ControlComponentSlidingSwitch'; 1 import { ControlComponentSlidingSwitchConfig } from './ControlComponentSlidingSwitch';
2 import { ControlComponentSwitchWithIconConfig } from './ControlComponentSwitchWithIcon'; 2 import { ControlComponentSwitchWithIconConfig } from './ControlComponentSwitchWithIcon';
3 import { ControlComponentToggleSwitchConfig } from './ControlComponentToggleSwitch'; 3 import { ControlComponentToggleSwitchConfig } from './ControlComponentToggleSwitch';
  4 +import { LateralNumericalControlConfig } from './LateralNumericalControl';
  5 +// import { SwitchListConfig } from './SwitchList';
4 6
5 export const ControlList = [ 7 export const ControlList = [
6 ControlComponentSwitchWithIconConfig, 8 ControlComponentSwitchWithIconConfig,
7 ControlComponentSlidingSwitchConfig, 9 ControlComponentSlidingSwitchConfig,
8 ControlComponentToggleSwitchConfig, 10 ControlComponentToggleSwitchConfig,
  11 + LateralNumericalControlConfig,
  12 + // SwitchListConfig,
9 ]; 13 ];
@@ -53,7 +53,6 @@ @@ -53,7 +53,6 @@
53 [ComponentConfigFieldEnum.FONT_COLOR]: fontColor, 53 [ComponentConfigFieldEnum.FONT_COLOR]: fontColor,
54 [ComponentConfigFieldEnum.SHOW_DEVICE_NAME]: showDeviceName, 54 [ComponentConfigFieldEnum.SHOW_DEVICE_NAME]: showDeviceName,
55 }; 55 };
56 - console.log(value, 'valie');  
57 return setFieldsValue(value); 56 return setFieldsValue(value);
58 }; 57 };
59 58
@@ -32,7 +32,6 @@ @@ -32,7 +32,6 @@
32 } = persetOption || {}; 32 } = persetOption || {};
33 const { unit, fontColor, pointerColor, gradientInfo, progressBarCircle, instrumentPanelColor } = 33 const { unit, fontColor, pointerColor, gradientInfo, progressBarCircle, instrumentPanelColor } =
34 componentInfo || {}; 34 componentInfo || {};
35 - console.log(option, 'unit');  
36 return { 35 return {
37 unit: unit ?? presetUnit, 36 unit: unit ?? presetUnit,
38 fontColor: fontColor ?? presetFontColor, 37 fontColor: fontColor ?? presetFontColor,
  1 +import cloneDeep from 'lodash-es/cloneDeep';
  2 +import { StatisticsComponent1Config } from '.';
  3 +import {
  4 + ConfigType,
  5 + CreateComponentType,
  6 + PublicComponentOptions,
  7 + PublicPresetOptions,
  8 +} from '../../../index.type';
  9 +import { PublicConfigClass, componentInitConfig } from '../../../publicConfig';
  10 +import { ComponentConfigFieldEnum } from '../../../enum';
  11 +
  12 +export enum Gradient {
  13 + FIRST = 'first',
  14 + SECOND = 'second',
  15 +}
  16 +export enum GradientColor {
  17 + FIRST = '#07ffd6',
  18 + SECOND = '#5eff10',
  19 +}
  20 +export const option: PublicPresetOptions = {
  21 + multipleDataSourceComponent: true,
  22 + [ComponentConfigFieldEnum.FONT_COLOR]: '#FD7347',
  23 + [ComponentConfigFieldEnum.SHOW_DEVICE_NAME]: false,
  24 + [ComponentConfigFieldEnum.UNIT]: '℃',
  25 +};
  26 +
  27 +export default class Config extends PublicConfigClass implements CreateComponentType {
  28 + public key: string = StatisticsComponent1Config.key;
  29 +
  30 + public attr = { ...componentInitConfig };
  31 +
  32 + public componentConfig: ConfigType = cloneDeep(StatisticsComponent1Config);
  33 +
  34 + public persetOption = cloneDeep(option);
  35 +
  36 + public option: PublicComponentOptions;
  37 +
  38 + constructor(option: PublicComponentOptions) {
  39 + super();
  40 + this.option = { ...option };
  41 + }
  42 +}
  1 +<script lang="ts" setup>
  2 + import { ComponentConfigFieldEnum } from '../../../enum';
  3 + import { option } from './config';
  4 + import { useForm, BasicForm } from '/@/components/Form';
  5 + import { PublicFormInstaceType } from '/@/views/visual/dataSourceBindPanel/index.type';
  6 + import { ComponentInfo } from '/@/views/visual/palette/types';
  7 +
  8 + const [register, { getFieldsValue, setFieldsValue, resetFields }] = useForm({
  9 + schemas: [
  10 + {
  11 + field: ComponentConfigFieldEnum.FONT_COLOR,
  12 + label: '数值字体颜色',
  13 + component: 'ColorPicker',
  14 + changeEvent: 'update:value',
  15 + defaultValue: option.fontColor,
  16 + },
  17 + {
  18 + field: ComponentConfigFieldEnum.UNIT,
  19 + label: '数值单位',
  20 + component: 'Input',
  21 + defaultValue: option.unit,
  22 + },
  23 + {
  24 + field: ComponentConfigFieldEnum.SHOW_DEVICE_NAME,
  25 + label: '显示设备名称',
  26 + component: 'Checkbox',
  27 + defaultValue: option.showDeviceName,
  28 + },
  29 + ],
  30 + showActionButtonGroup: false,
  31 + labelWidth: 120,
  32 + baseColProps: {
  33 + span: 12,
  34 + },
  35 + });
  36 +
  37 + const getFormValues = () => {
  38 + // return getFieldsValue();
  39 + const item = getFieldsValue();
  40 + return {
  41 + fontColor: item[ComponentConfigFieldEnum.FONT_COLOR],
  42 + unit: item[ComponentConfigFieldEnum.UNIT],
  43 + showDeviceName: item[ComponentConfigFieldEnum.SHOW_DEVICE_NAME],
  44 + } as ComponentInfo;
  45 + };
  46 +
  47 + const setFormValues = (data: Recordable) => {
  48 + // return setFieldsValue(data);
  49 + const { unit, fontColor, showDeviceName } = data;
  50 +
  51 + const value = {
  52 + [ComponentConfigFieldEnum.UNIT]: unit,
  53 + [ComponentConfigFieldEnum.FONT_COLOR]: fontColor,
  54 + [ComponentConfigFieldEnum.SHOW_DEVICE_NAME]: showDeviceName,
  55 + };
  56 + return setFieldsValue(value);
  57 + };
  58 +
  59 + defineExpose({
  60 + getFormValues,
  61 + setFormValues,
  62 + resetFormValues: resetFields,
  63 + } as PublicFormInstaceType);
  64 +</script>
  65 +
  66 +<template>
  67 + <BasicForm @register="register" />
  68 +</template>
  1 +<script lang="ts" setup>
  2 + import { commonDataSourceSchemas } from '../../../config/common.config';
  3 + import { CreateComponentType } from '../../../index.type';
  4 + import { BasicForm, useForm } from '/@/components/Form';
  5 + import {
  6 + PublicComponentValueType,
  7 + PublicFormInstaceType,
  8 + } from '/@/views/visual/dataSourceBindPanel/index.type';
  9 +
  10 + defineProps<{
  11 + values: PublicComponentValueType;
  12 + componentConfig: CreateComponentType;
  13 + }>();
  14 +
  15 + const [register, { getFieldsValue, setFieldsValue, validate, resetFields }] = useForm({
  16 + labelWidth: 0,
  17 + showActionButtonGroup: false,
  18 + layout: 'horizontal',
  19 + labelCol: { span: 0 },
  20 + schemas: commonDataSourceSchemas(),
  21 + });
  22 +
  23 + const getFormValues = () => {
  24 + return getFieldsValue();
  25 + };
  26 +
  27 + const setFormValues = (record: Recordable) => {
  28 + return setFieldsValue(record);
  29 + };
  30 +
  31 + defineExpose({
  32 + getFormValues,
  33 + setFormValues,
  34 + validate,
  35 + resetFormValues: resetFields,
  36 + } as PublicFormInstaceType);
  37 +</script>
  38 +
  39 +<template>
  40 + <BasicForm @register="register" />
  41 +</template>
  1 +import { useComponentKeys } from '/@/views/visual/packages/hook/useComponentKeys';
  2 +import { ConfigType, PackagesCategoryEnum } from '/@/views/visual/packages/index.type';
  3 +
  4 +const componentKeys = useComponentKeys('StatisticsComponent1');
  5 +
  6 +export const StatisticsComponent1Config: ConfigType = {
  7 + ...componentKeys,
  8 + title: '饼图',
  9 + package: PackagesCategoryEnum.STATISTICS,
  10 +};
  1 +<script lang="ts" setup>
  2 + import { EChartsOption, SeriesOption, ECharts, init } from 'echarts';
  3 + import { unref, ref, onMounted, computed, nextTick } from 'vue';
  4 + import { useMultipleDataFetch } from '../../../hook/useSocket';
  5 + import { ComponentPropsConfigType, MultipleDataFetchUpdateFn } from '../../../index.type';
  6 + import { option } from './config';
  7 + import { UpdateTime } from '/@/views/visual/commonComponents/UpdateTime';
  8 + import { useComponentScale } from '../../../hook/useComponentScale';
  9 + import { DeviceName } from '/@/views/visual/commonComponents/DeviceName';
  10 +
  11 + const props = defineProps<{
  12 + config: ComponentPropsConfigType<typeof option>;
  13 + }>();
  14 +
  15 + const chartRefEl = ref<Nullable<HTMLDivElement>>(null);
  16 +
  17 + const chartInstance = ref<Nullable<ECharts>>(null);
  18 +
  19 + const time = ref<Nullable<number>>(null);
  20 +
  21 + const getDesign = computed(() => {
  22 + const { persetOption, option } = props.config;
  23 + const { dataSource = [] } = option || {};
  24 + const { unit: presetUnit, fontColor: presetFontColor } = persetOption || {};
  25 + return {
  26 + dataSource: dataSource?.map((item) => {
  27 + const { unit, fontColor } = item.componentInfo || {};
  28 + const { attribute, attributeRename } = item;
  29 + return {
  30 + unit: unit ?? presetUnit,
  31 + fontColor: fontColor ?? presetFontColor,
  32 + attribute,
  33 + attributeRename,
  34 + };
  35 + }),
  36 + };
  37 + });
  38 +
  39 + const options = (): EChartsOption => {
  40 + // getStageColor(gradientInfo);
  41 + return {
  42 + tooltip: {
  43 + trigger: 'item',
  44 + },
  45 + legend: {
  46 + top: '5%',
  47 + left: 'center',
  48 + textStyle: {
  49 + fontSize: unref(getRatio) ? 14 * unref(getRatio) : 14,
  50 + },
  51 + },
  52 + series: [
  53 + {
  54 + name: '',
  55 + type: 'pie',
  56 + radius: ['%', '70%'],
  57 + center: ['50%', '65%'],
  58 + avoidLabelOverlap: false,
  59 + itemStyle: {
  60 + borderRadius: 4,
  61 + borderColor: '#fff',
  62 + borderWidth: 2,
  63 + },
  64 + label: {
  65 + show: false,
  66 + position: 'center',
  67 + },
  68 + labelLine: {
  69 + show: false,
  70 + },
  71 + data: [
  72 + { value: 1048, name: '数据1' },
  73 + { value: 735, name: '数据2' },
  74 + { value: 580, name: '数据3' },
  75 + ],
  76 + },
  77 + ],
  78 + };
  79 + };
  80 +
  81 + const initial = () => {
  82 + chartInstance.value = init(unref(chartRefEl)! as HTMLElement);
  83 + chartInstance.value.setOption(options());
  84 + };
  85 +
  86 + // const randomFn = () => {
  87 + // useIntervalFn(() => {
  88 + // const value = (Math.random() * 100).toFixed(0);
  89 + // unref(chartInstance)?.setOption({
  90 + // series: [{ data: [{ value }] }, { data: [{ value }] }],
  91 + // } as EChartsOption);
  92 + // }, 3000);
  93 + // };
  94 +
  95 + const updateChart = (data: SeriesOption['data']) => {
  96 + unref(chartInstance)?.setOption({
  97 + series: [{ data }],
  98 + // color: unref(list).map((item) => item.title.color),
  99 + } as EChartsOption);
  100 + };
  101 +
  102 + const updateFn: MultipleDataFetchUpdateFn = (message) => {
  103 + const { data = {} } = message;
  104 + const { dataSource } = unref(getDesign);
  105 + const series = dataSource.map((item) => {
  106 + const { attribute, attributeRename, fontColor, unit } = item;
  107 + const [latest] = data[attribute] || [];
  108 + const [_timespan, value] = latest || [];
  109 +
  110 + return {
  111 + value,
  112 + name: attributeRename ?? attribute,
  113 + itemStyle: { color: fontColor },
  114 + tooltip: {
  115 + valueFormatter(value) {
  116 + return `${value} ${unit ?? ''}`;
  117 + },
  118 + },
  119 + } as SeriesOption['data'];
  120 + });
  121 + updateChart(series);
  122 + };
  123 +
  124 + useMultipleDataFetch(props, updateFn);
  125 +
  126 + onMounted(() => {
  127 + initial();
  128 + // !props.config.option.uuid && randomFn();
  129 + !props.config.option.uuid;
  130 + });
  131 +
  132 + const resize = async () => {
  133 + await nextTick();
  134 +
  135 + // 修改echarts大小
  136 + unref(chartInstance)?.setOption({
  137 + legend: {
  138 + textStyle: {
  139 + fontSize: 14 * unref(getRatio),
  140 + },
  141 + },
  142 + } as EChartsOption);
  143 + unref(chartInstance)?.resize();
  144 + };
  145 +
  146 + const { getRatio } = useComponentScale(props, resize);
  147 +</script>
  148 +
  149 +<template>
  150 + <main class="w-full h-full flex flex-col justify-center items-center">
  151 + <DeviceName :config="config" />
  152 + <div ref="chartRefEl" class="flex-1 w-full h-full"> </div>
  153 + <UpdateTime :time="time" />
  154 + </main>
  155 +</template>
  1 +import cloneDeep from 'lodash-es/cloneDeep';
  2 +import { StatisticsComponent2Config } from '.';
  3 +import {
  4 + ConfigType,
  5 + CreateComponentType,
  6 + PublicComponentOptions,
  7 + PublicPresetOptions,
  8 +} from '../../../index.type';
  9 +import { PublicConfigClass, componentInitConfig } from '../../../publicConfig';
  10 +import { ComponentConfigFieldEnum } from '../../../enum';
  11 +
  12 +export enum Gradient {
  13 + FIRST = 'first',
  14 + SECOND = 'second',
  15 +}
  16 +export enum GradientColor {
  17 + FIRST = '#07ffd6',
  18 + SECOND = '#5eff10',
  19 +}
  20 +export const option: PublicPresetOptions = {
  21 + multipleDataSourceComponent: true,
  22 + [ComponentConfigFieldEnum.FONT_COLOR]: '#FD7347',
  23 + [ComponentConfigFieldEnum.SHOW_DEVICE_NAME]: false,
  24 + [ComponentConfigFieldEnum.UNIT]: '℃',
  25 +};
  26 +
  27 +export default class Config extends PublicConfigClass implements CreateComponentType {
  28 + public key: string = StatisticsComponent2Config.key;
  29 +
  30 + public attr = { ...componentInitConfig };
  31 +
  32 + public componentConfig: ConfigType = cloneDeep(StatisticsComponent2Config);
  33 +
  34 + public persetOption = cloneDeep(option);
  35 +
  36 + public option: PublicComponentOptions;
  37 +
  38 + constructor(option: PublicComponentOptions) {
  39 + super();
  40 + this.option = { ...option };
  41 + }
  42 +}
  1 +<script lang="ts" setup>
  2 + import { ComponentConfigFieldEnum } from '../../../enum';
  3 + import { option } from './config';
  4 + import { useForm, BasicForm } from '/@/components/Form';
  5 + import { PublicFormInstaceType } from '/@/views/visual/dataSourceBindPanel/index.type';
  6 + import { ComponentInfo } from '/@/views/visual/palette/types';
  7 +
  8 + const [register, { getFieldsValue, setFieldsValue, resetFields }] = useForm({
  9 + schemas: [
  10 + {
  11 + field: ComponentConfigFieldEnum.FONT_COLOR,
  12 + label: '数值字体颜色',
  13 + component: 'ColorPicker',
  14 + changeEvent: 'update:value',
  15 + defaultValue: option.fontColor,
  16 + },
  17 + {
  18 + field: ComponentConfigFieldEnum.UNIT,
  19 + label: '数值单位',
  20 + component: 'Input',
  21 + defaultValue: option.unit,
  22 + },
  23 + {
  24 + field: ComponentConfigFieldEnum.SHOW_DEVICE_NAME,
  25 + label: '显示设备名称',
  26 + component: 'Checkbox',
  27 + defaultValue: option.showDeviceName,
  28 + },
  29 + ],
  30 + showActionButtonGroup: false,
  31 + labelWidth: 120,
  32 + baseColProps: {
  33 + span: 12,
  34 + },
  35 + });
  36 +
  37 + const getFormValues = () => {
  38 + // return getFieldsValue();
  39 + const item = getFieldsValue();
  40 + return {
  41 + fontColor: item[ComponentConfigFieldEnum.FONT_COLOR],
  42 + unit: item[ComponentConfigFieldEnum.UNIT],
  43 + showDeviceName: item[ComponentConfigFieldEnum.SHOW_DEVICE_NAME],
  44 + } as ComponentInfo;
  45 + };
  46 +
  47 + const setFormValues = (data: Recordable) => {
  48 + // return setFieldsValue(data);
  49 + const { unit, fontColor, showDeviceName } = data;
  50 +
  51 + const value = {
  52 + [ComponentConfigFieldEnum.UNIT]: unit,
  53 + [ComponentConfigFieldEnum.FONT_COLOR]: fontColor,
  54 + [ComponentConfigFieldEnum.SHOW_DEVICE_NAME]: showDeviceName,
  55 + };
  56 + return setFieldsValue(value);
  57 + };
  58 +
  59 + defineExpose({
  60 + getFormValues,
  61 + setFormValues,
  62 + resetFormValues: resetFields,
  63 + } as PublicFormInstaceType);
  64 +</script>
  65 +
  66 +<template>
  67 + <BasicForm @register="register" />
  68 +</template>
  1 +<script lang="ts" setup>
  2 + import { commonDataSourceSchemas } from '../../../config/common.config';
  3 + import { CreateComponentType } from '../../../index.type';
  4 + import { BasicForm, useForm } from '/@/components/Form';
  5 + import {
  6 + PublicComponentValueType,
  7 + PublicFormInstaceType,
  8 + } from '/@/views/visual/dataSourceBindPanel/index.type';
  9 +
  10 + defineProps<{
  11 + values: PublicComponentValueType;
  12 + componentConfig: CreateComponentType;
  13 + }>();
  14 +
  15 + const [register, { getFieldsValue, setFieldsValue, validate, resetFields }] = useForm({
  16 + labelWidth: 0,
  17 + showActionButtonGroup: false,
  18 + layout: 'horizontal',
  19 + labelCol: { span: 0 },
  20 + schemas: commonDataSourceSchemas(),
  21 + });
  22 +
  23 + const getFormValues = () => {
  24 + return getFieldsValue();
  25 + };
  26 +
  27 + const setFormValues = (record: Recordable) => {
  28 + return setFieldsValue(record);
  29 + };
  30 +
  31 + defineExpose({
  32 + getFormValues,
  33 + setFormValues,
  34 + validate,
  35 + resetFormValues: resetFields,
  36 + } as PublicFormInstaceType);
  37 +</script>
  38 +
  39 +<template>
  40 + <BasicForm @register="register" />
  41 +</template>
  1 +import { useComponentKeys } from '/@/views/visual/packages/hook/useComponentKeys';
  2 +import { ConfigType, PackagesCategoryEnum } from '/@/views/visual/packages/index.type';
  3 +
  4 +const componentKeys = useComponentKeys('StatisticsComponent2');
  5 +
  6 +export const StatisticsComponent2Config: ConfigType = {
  7 + ...componentKeys,
  8 + title: '半环形图',
  9 + package: PackagesCategoryEnum.STATISTICS,
  10 +};
  1 +<script lang="ts" setup>
  2 + import { EChartsOption, SeriesOption, ECharts, init } from 'echarts';
  3 + import { unref, ref, onMounted, computed, nextTick } from 'vue';
  4 + import { useMultipleDataFetch } from '../../../hook/useSocket';
  5 + import { ComponentPropsConfigType, MultipleDataFetchUpdateFn } from '../../../index.type';
  6 + import { option } from './config';
  7 + import { UpdateTime } from '/@/views/visual/commonComponents/UpdateTime';
  8 + import { useComponentScale } from '../../../hook/useComponentScale';
  9 + import { DeviceName } from '/@/views/visual/commonComponents/DeviceName';
  10 +
  11 + const props = defineProps<{
  12 + config: ComponentPropsConfigType<typeof option>;
  13 + }>();
  14 +
  15 + const chartRefEl = ref<Nullable<HTMLDivElement>>(null);
  16 +
  17 + const chartInstance = ref<Nullable<ECharts>>(null);
  18 +
  19 + const time = ref<Nullable<number>>(null);
  20 +
  21 + const getDesign = computed(() => {
  22 + const { persetOption, option } = props.config;
  23 + const { dataSource = [] } = option || {};
  24 + const { unit: presetUnit, fontColor: presetFontColor } = persetOption || {};
  25 + return {
  26 + dataSource: dataSource?.map((item) => {
  27 + const { unit, fontColor } = item.componentInfo || {};
  28 + const { attribute, attributeRename } = item;
  29 + return {
  30 + unit: unit ?? presetUnit,
  31 + fontColor: fontColor ?? presetFontColor,
  32 + attribute,
  33 + attributeRename,
  34 + };
  35 + }),
  36 + };
  37 + });
  38 +
  39 + const options = (): EChartsOption => {
  40 + // getStageColor(gradientInfo);
  41 + return {
  42 + tooltip: {
  43 + trigger: 'item',
  44 + },
  45 + legend: {
  46 + top: '5%',
  47 + left: 'center',
  48 + selectedMode: false,
  49 + textStyle: {
  50 + fontSize: unref(getRatio) ? 14 * unref(getRatio) : 14,
  51 + },
  52 + },
  53 + series: [
  54 + {
  55 + type: 'pie',
  56 + radius: ['40%', '70%'],
  57 + center: ['50%', '70%'],
  58 + // adjust the start angle
  59 + startAngle: 180,
  60 + label: {
  61 + show: false,
  62 + },
  63 + itemStyle: {
  64 + borderRadius: 4,
  65 + borderColor: '#fff',
  66 + borderWidth: 2,
  67 + },
  68 + data: [
  69 + { value: 1048, name: '数据1' },
  70 + { value: 735, name: '数据2' },
  71 + {
  72 + value: 1048 + 735,
  73 + itemStyle: {
  74 + color: 'none',
  75 + decal: {
  76 + symbol: 'none',
  77 + },
  78 + },
  79 + label: {
  80 + show: false,
  81 + },
  82 + },
  83 + ],
  84 + },
  85 + ],
  86 + };
  87 + };
  88 +
  89 + const initial = () => {
  90 + chartInstance.value = init(unref(chartRefEl)! as HTMLElement);
  91 + chartInstance.value.setOption(options());
  92 + };
  93 +
  94 + // const randomFn = () => {
  95 + // useIntervalFn(() => {
  96 + // const value = (Math.random() * 100).toFixed(0);
  97 + // unref(chartInstance)?.setOption({
  98 + // series: [{ data: [{ value }] }, { data: [{ value }] }],
  99 + // } as EChartsOption);
  100 + // }, 3000);
  101 + // };
  102 +
  103 + const updateChart = (data: SeriesOption['data']) => {
  104 + unref(chartInstance)?.setOption({
  105 + series: [{ data }],
  106 + // color: unref(list).map((item) => item.title.color),
  107 + } as EChartsOption);
  108 + };
  109 +
  110 + const updateFn: MultipleDataFetchUpdateFn = (message) => {
  111 + const { data = {} } = message;
  112 + const { dataSource } = unref(getDesign);
  113 + const series = dataSource.map((item) => {
  114 + const { attribute, attributeRename, fontColor, unit } = item;
  115 + const [latest] = data[attribute] || [];
  116 + const [_timespan, value] = latest || [];
  117 +
  118 + return {
  119 + value,
  120 + name: attributeRename ?? attribute,
  121 + itemStyle: { color: fontColor },
  122 + tooltip: {
  123 + valueFormatter(value) {
  124 + return `${value} ${unit ?? ''}`;
  125 + },
  126 + },
  127 + } as SeriesOption['data'];
  128 + });
  129 + // if (series.length > 1) {
  130 + series.push({
  131 + value: series.reduce((total: number, current: any) => total + Number(current.value), 0),
  132 + itemStyle: {
  133 + color: 'none',
  134 + decal: {
  135 + symbol: 'none',
  136 + },
  137 + },
  138 + label: {
  139 + show: false,
  140 + },
  141 + });
  142 + // }
  143 + // console.log(message, 'message', series, 'series', sum);
  144 + updateChart(series);
  145 + };
  146 +
  147 + useMultipleDataFetch(props, updateFn);
  148 +
  149 + onMounted(() => {
  150 + initial();
  151 + // !props.config.option.uuid && randomFn();
  152 + !props.config.option.uuid;
  153 + });
  154 +
  155 + const resize = async () => {
  156 + await nextTick();
  157 +
  158 + // 修改echarts大小
  159 + unref(chartInstance)?.setOption({
  160 + legend: {
  161 + textStyle: {
  162 + fontSize: 14 * unref(getRatio),
  163 + },
  164 + },
  165 + } as EChartsOption);
  166 + unref(chartInstance)?.resize();
  167 + };
  168 +
  169 + const { getRatio } = useComponentScale(props, resize);
  170 +</script>
  171 +
  172 +<template>
  173 + <main class="w-full h-full flex flex-col justify-center items-center">
  174 + <DeviceName :config="config" />
  175 + <div ref="chartRefEl" class="flex-1 w-full h-full"> </div>
  176 + <UpdateTime :time="time" />
  177 + </main>
  178 +</template>
  1 +import cloneDeep from 'lodash-es/cloneDeep';
  2 +import { StatisticsComponent3Config } from '.';
  3 +import {
  4 + ConfigType,
  5 + CreateComponentType,
  6 + PublicComponentOptions,
  7 + PublicPresetOptions,
  8 +} from '../../../index.type';
  9 +import { PublicConfigClass, componentInitConfig } from '../../../publicConfig';
  10 +import { ComponentConfigFieldEnum } from '../../../enum';
  11 +
  12 +export enum Gradient {
  13 + FIRST = 'first',
  14 + SECOND = 'second',
  15 +}
  16 +export enum GradientColor {
  17 + FIRST = '#07ffd6',
  18 + SECOND = '#5eff10',
  19 +}
  20 +export const option: PublicPresetOptions = {
  21 + multipleDataSourceComponent: true,
  22 + [ComponentConfigFieldEnum.FONT_COLOR]: '#FD7347',
  23 + [ComponentConfigFieldEnum.SHOW_DEVICE_NAME]: false,
  24 + [ComponentConfigFieldEnum.UNIT]: '℃',
  25 +};
  26 +
  27 +export default class Config extends PublicConfigClass implements CreateComponentType {
  28 + public key: string = StatisticsComponent3Config.key;
  29 +
  30 + public attr = { ...componentInitConfig };
  31 +
  32 + public componentConfig: ConfigType = cloneDeep(StatisticsComponent3Config);
  33 +
  34 + public persetOption = cloneDeep(option);
  35 +
  36 + public option: PublicComponentOptions;
  37 +
  38 + constructor(option: PublicComponentOptions) {
  39 + super();
  40 + this.option = { ...option };
  41 + }
  42 +}
  1 +<script lang="ts" setup>
  2 + import { ComponentConfigFieldEnum } from '../../../enum';
  3 + import { option } from './config';
  4 + import { useForm, BasicForm } from '/@/components/Form';
  5 + import { PublicFormInstaceType } from '/@/views/visual/dataSourceBindPanel/index.type';
  6 + import { ComponentInfo } from '/@/views/visual/palette/types';
  7 +
  8 + const [register, { getFieldsValue, setFieldsValue, resetFields }] = useForm({
  9 + schemas: [
  10 + {
  11 + field: ComponentConfigFieldEnum.FONT_COLOR,
  12 + label: '数值字体颜色',
  13 + component: 'ColorPicker',
  14 + changeEvent: 'update:value',
  15 + defaultValue: option.fontColor,
  16 + },
  17 + {
  18 + field: ComponentConfigFieldEnum.UNIT,
  19 + label: '数值单位',
  20 + component: 'Input',
  21 + defaultValue: option.unit,
  22 + },
  23 + {
  24 + field: ComponentConfigFieldEnum.SHOW_DEVICE_NAME,
  25 + label: '显示设备名称',
  26 + component: 'Checkbox',
  27 + defaultValue: option.showDeviceName,
  28 + },
  29 + ],
  30 + showActionButtonGroup: false,
  31 + labelWidth: 120,
  32 + baseColProps: {
  33 + span: 12,
  34 + },
  35 + });
  36 +
  37 + const getFormValues = () => {
  38 + // return getFieldsValue();
  39 + const item = getFieldsValue();
  40 + return {
  41 + fontColor: item[ComponentConfigFieldEnum.FONT_COLOR],
  42 + unit: item[ComponentConfigFieldEnum.UNIT],
  43 + showDeviceName: item[ComponentConfigFieldEnum.SHOW_DEVICE_NAME],
  44 + } as ComponentInfo;
  45 + };
  46 +
  47 + const setFormValues = (data: Recordable) => {
  48 + // return setFieldsValue(data);
  49 + const { unit, fontColor, showDeviceName } = data;
  50 +
  51 + const value = {
  52 + [ComponentConfigFieldEnum.UNIT]: unit,
  53 + [ComponentConfigFieldEnum.FONT_COLOR]: fontColor,
  54 + [ComponentConfigFieldEnum.SHOW_DEVICE_NAME]: showDeviceName,
  55 + };
  56 + return setFieldsValue(value);
  57 + };
  58 +
  59 + defineExpose({
  60 + getFormValues,
  61 + setFormValues,
  62 + resetFormValues: resetFields,
  63 + } as PublicFormInstaceType);
  64 +</script>
  65 +
  66 +<template>
  67 + <BasicForm @register="register" />
  68 +</template>
  1 +<script lang="ts" setup>
  2 + import { commonDataSourceSchemas } from '../../../config/common.config';
  3 + import { CreateComponentType } from '../../../index.type';
  4 + import { BasicForm, useForm } from '/@/components/Form';
  5 + import {
  6 + PublicComponentValueType,
  7 + PublicFormInstaceType,
  8 + } from '/@/views/visual/dataSourceBindPanel/index.type';
  9 +
  10 + defineProps<{
  11 + values: PublicComponentValueType;
  12 + componentConfig: CreateComponentType;
  13 + }>();
  14 +
  15 + const [register, { getFieldsValue, setFieldsValue, validate, resetFields }] = useForm({
  16 + labelWidth: 0,
  17 + showActionButtonGroup: false,
  18 + layout: 'horizontal',
  19 + labelCol: { span: 0 },
  20 + schemas: commonDataSourceSchemas(),
  21 + });
  22 +
  23 + const getFormValues = () => {
  24 + return getFieldsValue();
  25 + };
  26 +
  27 + const setFormValues = (record: Recordable) => {
  28 + return setFieldsValue(record);
  29 + };
  30 +
  31 + defineExpose({
  32 + getFormValues,
  33 + setFormValues,
  34 + validate,
  35 + resetFormValues: resetFields,
  36 + } as PublicFormInstaceType);
  37 +</script>
  38 +
  39 +<template>
  40 + <BasicForm @register="register" />
  41 +</template>
  1 +import { useComponentKeys } from '/@/views/visual/packages/hook/useComponentKeys';
  2 +import { ConfigType, PackagesCategoryEnum } from '/@/views/visual/packages/index.type';
  3 +
  4 +const componentKeys = useComponentKeys('StatisticsComponent3');
  5 +
  6 +export const StatisticsComponent3Config: ConfigType = {
  7 + ...componentKeys,
  8 + title: '横柱状图',
  9 + package: PackagesCategoryEnum.STATISTICS,
  10 +};
  1 +<script lang="ts" setup>
  2 + import { EChartsOption, SeriesOption, ECharts, init } from 'echarts';
  3 + import { unref, ref, onMounted, computed, nextTick } from 'vue';
  4 + import { useMultipleDataFetch } from '../../../hook/useSocket';
  5 + import { ComponentPropsConfigType, MultipleDataFetchUpdateFn } from '../../../index.type';
  6 + import { option } from './config';
  7 + import { UpdateTime } from '/@/views/visual/commonComponents/UpdateTime';
  8 + import { useComponentScale } from '../../../hook/useComponentScale';
  9 + import { DeviceName } from '/@/views/visual/commonComponents/DeviceName';
  10 +
  11 + const props = defineProps<{
  12 + config: ComponentPropsConfigType<typeof option>;
  13 + }>();
  14 +
  15 + const chartRefEl = ref<Nullable<HTMLDivElement>>(null);
  16 +
  17 + const chartInstance = ref<Nullable<ECharts>>(null);
  18 +
  19 + const time = ref<Nullable<number>>(null);
  20 +
  21 + const getDesign = computed(() => {
  22 + const { persetOption, option } = props.config;
  23 + const { dataSource = [] } = option || {};
  24 + const { unit: presetUnit, fontColor: presetFontColor } = persetOption || {};
  25 + return {
  26 + dataSource: dataSource?.map((item) => {
  27 + const { unit, fontColor } = item.componentInfo || {};
  28 + const { attribute, attributeRename } = item;
  29 + return {
  30 + unit: unit ?? presetUnit,
  31 + fontColor: fontColor ?? presetFontColor,
  32 + attribute,
  33 + attributeRename,
  34 + };
  35 + }),
  36 + };
  37 + });
  38 + const seriesList = [
  39 + { value: 120, name: '123', itemStyle: { color: '#02E5F0' } },
  40 + { value: 150, name: '456', itemStyle: { color: '#028CF0' } },
  41 + { value: 40, name: '789', itemStyle: { color: '#F09202' } },
  42 + ];
  43 + const data = ['温度', '湿度', '温度1'];
  44 + const options = (): EChartsOption => {
  45 + // getStageColor(gradientInfo);
  46 + return {
  47 + color: ['#3398DB'],
  48 + tooltip: {
  49 + // 提示框
  50 + trigger: 'axis',
  51 + axisPointer: {
  52 + type: 'shadow',
  53 + },
  54 + },
  55 + xAxis: {
  56 + type: 'category',
  57 + data: data,
  58 + axisTick: {
  59 + alignWithLabel: true,
  60 + },
  61 + axisPointer: {
  62 + type: 'line',
  63 + },
  64 + },
  65 + grid: {
  66 + top: '15%',
  67 + left: '20%',
  68 + bottom: '15%',
  69 + },
  70 + yAxis: {
  71 + type: 'value',
  72 + },
  73 + series: [
  74 + {
  75 + name: '',
  76 + type: 'bar',
  77 + barWidth: '60%',
  78 + data: seriesList,
  79 + },
  80 + ],
  81 + };
  82 + };
  83 +
  84 + const initial = () => {
  85 + chartInstance.value = init(unref(chartRefEl)! as HTMLElement);
  86 + chartInstance.value.setOption(options());
  87 + };
  88 +
  89 + // const randomFn = () => {
  90 + // useIntervalFn(() => {
  91 + // const value = (Math.random() * 100).toFixed(0);
  92 + // unref(chartInstance)?.setOption({
  93 + // series: [{ data: [{ value }] }, { data: [{ value }] }],
  94 + // } as EChartsOption);
  95 + // }, 3000);
  96 + // };
  97 +
  98 + const updateChart = (data: SeriesOption['data'], xAxisData) => {
  99 + unref(chartInstance)?.setOption({
  100 + series: [{ data }],
  101 + xAxis: { data: xAxisData },
  102 + // color: unref(list).map((item) => item.title.color),
  103 + } as EChartsOption);
  104 + };
  105 +
  106 + const updateFn: MultipleDataFetchUpdateFn = (message) => {
  107 + const { data = {} } = message;
  108 + const { dataSource } = unref(getDesign);
  109 + const series = dataSource.map((item) => {
  110 + const { attribute, attributeRename, fontColor, unit } = item;
  111 + const [latest] = data[attribute] || [];
  112 + const [_timespan, value] = latest || [];
  113 +
  114 + return {
  115 + value,
  116 + name: attributeRename ?? attribute,
  117 + itemStyle: { color: fontColor },
  118 + tooltip: {
  119 + valueFormatter(value) {
  120 + return `${value} ${unit ?? ''}`;
  121 + },
  122 + },
  123 + } as SeriesOption['data'];
  124 + });
  125 + const xAxisData = series.map((item) => {
  126 + const { name } = item as any;
  127 + return name;
  128 + });
  129 + // }
  130 + // console.log(message, 'message', series, 'series', sum);
  131 + updateChart(series, xAxisData);
  132 + };
  133 +
  134 + useMultipleDataFetch(props, updateFn);
  135 +
  136 + onMounted(() => {
  137 + initial();
  138 + // !props.config.option.uuid && randomFn();
  139 + !props.config.option.uuid;
  140 + });
  141 +
  142 + const resize = async () => {
  143 + await nextTick();
  144 +
  145 + // 修改echarts大小
  146 + unref(chartInstance)?.setOption({
  147 + legend: {
  148 + textStyle: {
  149 + fontSize: 14 * unref(getRatio),
  150 + },
  151 + },
  152 + } as EChartsOption);
  153 + unref(chartInstance)?.resize();
  154 + };
  155 +
  156 + const { getRatio } = useComponentScale(props, resize);
  157 +</script>
  158 +
  159 +<template>
  160 + <main class="w-full h-full flex flex-col justify-center items-center">
  161 + <DeviceName :config="config" />
  162 + <div ref="chartRefEl" class="flex-1 w-full h-full"> </div>
  163 + <UpdateTime :time="time" />
  164 + </main>
  165 +</template>
  1 +import cloneDeep from 'lodash-es/cloneDeep';
  2 +import { StatisticsComponent4Config } from '.';
  3 +import {
  4 + ConfigType,
  5 + CreateComponentType,
  6 + PublicComponentOptions,
  7 + PublicPresetOptions,
  8 +} from '../../../index.type';
  9 +import { PublicConfigClass, componentInitConfig } from '../../../publicConfig';
  10 +import { ComponentConfigFieldEnum } from '../../../enum';
  11 +
  12 +export enum Gradient {
  13 + FIRST = 'first',
  14 + SECOND = 'second',
  15 +}
  16 +export enum GradientColor {
  17 + FIRST = '#07ffd6',
  18 + SECOND = '#5eff10',
  19 +}
  20 +export const option: PublicPresetOptions = {
  21 + multipleDataSourceComponent: true,
  22 + [ComponentConfigFieldEnum.FONT_COLOR]: '#FD7347',
  23 + [ComponentConfigFieldEnum.SHOW_DEVICE_NAME]: false,
  24 + [ComponentConfigFieldEnum.UNIT]: '℃',
  25 +};
  26 +
  27 +export default class Config extends PublicConfigClass implements CreateComponentType {
  28 + public key: string = StatisticsComponent4Config.key;
  29 +
  30 + public attr = { ...componentInitConfig };
  31 +
  32 + public componentConfig: ConfigType = cloneDeep(StatisticsComponent4Config);
  33 +
  34 + public persetOption = cloneDeep(option);
  35 +
  36 + public option: PublicComponentOptions;
  37 +
  38 + constructor(option: PublicComponentOptions) {
  39 + super();
  40 + this.option = { ...option };
  41 + }
  42 +}
  1 +<script lang="ts" setup>
  2 + import { ComponentConfigFieldEnum } from '../../../enum';
  3 + import { option } from './config';
  4 + import { useForm, BasicForm } from '/@/components/Form';
  5 + import { PublicFormInstaceType } from '/@/views/visual/dataSourceBindPanel/index.type';
  6 + import { ComponentInfo } from '/@/views/visual/palette/types';
  7 +
  8 + const [register, { getFieldsValue, setFieldsValue, resetFields }] = useForm({
  9 + schemas: [
  10 + {
  11 + field: ComponentConfigFieldEnum.FONT_COLOR,
  12 + label: '数值字体颜色',
  13 + component: 'ColorPicker',
  14 + changeEvent: 'update:value',
  15 + defaultValue: option.fontColor,
  16 + },
  17 + {
  18 + field: ComponentConfigFieldEnum.UNIT,
  19 + label: '数值单位',
  20 + component: 'Input',
  21 + defaultValue: option.unit,
  22 + },
  23 + {
  24 + field: ComponentConfigFieldEnum.SHOW_DEVICE_NAME,
  25 + label: '显示设备名称',
  26 + component: 'Checkbox',
  27 + defaultValue: option.showDeviceName,
  28 + },
  29 + ],
  30 + showActionButtonGroup: false,
  31 + labelWidth: 120,
  32 + baseColProps: {
  33 + span: 12,
  34 + },
  35 + });
  36 +
  37 + const getFormValues = () => {
  38 + // return getFieldsValue();
  39 + const item = getFieldsValue();
  40 + return {
  41 + fontColor: item[ComponentConfigFieldEnum.FONT_COLOR],
  42 + unit: item[ComponentConfigFieldEnum.UNIT],
  43 + showDeviceName: item[ComponentConfigFieldEnum.SHOW_DEVICE_NAME],
  44 + } as ComponentInfo;
  45 + };
  46 +
  47 + const setFormValues = (data: Recordable) => {
  48 + // return setFieldsValue(data);
  49 + const { unit, fontColor, showDeviceName } = data;
  50 +
  51 + const value = {
  52 + [ComponentConfigFieldEnum.UNIT]: unit,
  53 + [ComponentConfigFieldEnum.FONT_COLOR]: fontColor,
  54 + [ComponentConfigFieldEnum.SHOW_DEVICE_NAME]: showDeviceName,
  55 + };
  56 + return setFieldsValue(value);
  57 + };
  58 +
  59 + defineExpose({
  60 + getFormValues,
  61 + setFormValues,
  62 + resetFormValues: resetFields,
  63 + } as PublicFormInstaceType);
  64 +</script>
  65 +
  66 +<template>
  67 + <BasicForm @register="register" />
  68 +</template>
  1 +<script lang="ts" setup>
  2 + import { commonDataSourceSchemas } from '../../../config/common.config';
  3 + import { CreateComponentType } from '../../../index.type';
  4 + import { BasicForm, useForm } from '/@/components/Form';
  5 + import {
  6 + PublicComponentValueType,
  7 + PublicFormInstaceType,
  8 + } from '/@/views/visual/dataSourceBindPanel/index.type';
  9 +
  10 + defineProps<{
  11 + values: PublicComponentValueType;
  12 + componentConfig: CreateComponentType;
  13 + }>();
  14 +
  15 + const [register, { getFieldsValue, setFieldsValue, validate, resetFields }] = useForm({
  16 + labelWidth: 0,
  17 + showActionButtonGroup: false,
  18 + layout: 'horizontal',
  19 + labelCol: { span: 0 },
  20 + schemas: commonDataSourceSchemas(),
  21 + });
  22 +
  23 + const getFormValues = () => {
  24 + return getFieldsValue();
  25 + };
  26 +
  27 + const setFormValues = (record: Recordable) => {
  28 + return setFieldsValue(record);
  29 + };
  30 +
  31 + defineExpose({
  32 + getFormValues,
  33 + setFormValues,
  34 + validate,
  35 + resetFormValues: resetFields,
  36 + } as PublicFormInstaceType);
  37 +</script>
  38 +
  39 +<template>
  40 + <BasicForm @register="register" />
  41 +</template>
  1 +import { useComponentKeys } from '/@/views/visual/packages/hook/useComponentKeys';
  2 +import { ConfigType, PackagesCategoryEnum } from '/@/views/visual/packages/index.type';
  3 +
  4 +const componentKeys = useComponentKeys('StatisticsComponent4');
  5 +
  6 +export const StatisticsComponent4Config: ConfigType = {
  7 + ...componentKeys,
  8 + title: '竖柱状图',
  9 + package: PackagesCategoryEnum.STATISTICS,
  10 +};
  1 +<script lang="ts" setup>
  2 + import { EChartsOption, SeriesOption, ECharts, init } from 'echarts';
  3 + import { unref, ref, onMounted, computed, nextTick } from 'vue';
  4 + import { useMultipleDataFetch } from '../../../hook/useSocket';
  5 + import { ComponentPropsConfigType, MultipleDataFetchUpdateFn } from '../../../index.type';
  6 + import { option } from './config';
  7 + import { UpdateTime } from '/@/views/visual/commonComponents/UpdateTime';
  8 + import { useComponentScale } from '../../../hook/useComponentScale';
  9 + import { DeviceName } from '/@/views/visual/commonComponents/DeviceName';
  10 +
  11 + const props = defineProps<{
  12 + config: ComponentPropsConfigType<typeof option>;
  13 + }>();
  14 +
  15 + const chartRefEl = ref<Nullable<HTMLDivElement>>(null);
  16 +
  17 + const chartInstance = ref<Nullable<ECharts>>(null);
  18 +
  19 + const time = ref<Nullable<number>>(null);
  20 +
  21 + const getDesign = computed(() => {
  22 + const { persetOption, option } = props.config;
  23 + const { dataSource = [] } = option || {};
  24 + const { unit: presetUnit, fontColor: presetFontColor } = persetOption || {};
  25 + return {
  26 + dataSource: dataSource?.map((item) => {
  27 + const { unit, fontColor } = item.componentInfo || {};
  28 + const { attribute, attributeRename } = item;
  29 + return {
  30 + unit: unit ?? presetUnit,
  31 + fontColor: fontColor ?? presetFontColor,
  32 + attribute,
  33 + attributeRename,
  34 + };
  35 + }),
  36 + };
  37 + });
  38 + const seriesList = [
  39 + { value: 120, name: '123', itemStyle: { color: '#02E5F0' } },
  40 + { value: 150, name: '456', itemStyle: { color: '#028CF0' } },
  41 + { value: 40, name: '789', itemStyle: { color: '#F09202' } },
  42 + ];
  43 + const data = ['温度', '湿度', '温度1'];
  44 + const options = (): EChartsOption => {
  45 + // getStageColor(gradientInfo);
  46 + return {
  47 + color: ['#3398DB'],
  48 + tooltip: {
  49 + // 提示框
  50 + trigger: 'axis',
  51 + axisPointer: {
  52 + type: 'shadow',
  53 + },
  54 + },
  55 + xAxis: {
  56 + type: 'value',
  57 + },
  58 + yAxis: {
  59 + type: 'category',
  60 + data: data,
  61 + axisTick: {
  62 + alignWithLabel: true,
  63 + },
  64 + axisPointer: {
  65 + type: 'line',
  66 + },
  67 + },
  68 + grid: {
  69 + top: '15%',
  70 + left: '28%',
  71 + bottom: '15%',
  72 + },
  73 + series: [
  74 + {
  75 + name: '',
  76 + type: 'bar',
  77 + barWidth: '60%',
  78 + data: seriesList,
  79 + },
  80 + ],
  81 + };
  82 + };
  83 +
  84 + const initial = () => {
  85 + chartInstance.value = init(unref(chartRefEl)! as HTMLElement);
  86 + chartInstance.value.setOption(options());
  87 + };
  88 +
  89 + // const randomFn = () => {
  90 + // useIntervalFn(() => {
  91 + // const value = (Math.random() * 100).toFixed(0);
  92 + // unref(chartInstance)?.setOption({
  93 + // series: [{ data: [{ value }] }, { data: [{ value }] }],
  94 + // } as EChartsOption);
  95 + // }, 3000);
  96 + // };
  97 +
  98 + const updateChart = (data: SeriesOption['data'], yAxisData) => {
  99 + unref(chartInstance)?.setOption({
  100 + series: [{ data }],
  101 + yAxis: { data: yAxisData },
  102 + // color: unref(list).map((item) => item.title.color),
  103 + } as EChartsOption);
  104 + };
  105 +
  106 + const updateFn: MultipleDataFetchUpdateFn = (message) => {
  107 + const { data = {} } = message;
  108 + const { dataSource } = unref(getDesign);
  109 + const series = dataSource.map((item) => {
  110 + const { attribute, attributeRename, fontColor, unit } = item;
  111 + const [latest] = data[attribute] || [];
  112 + const [_timespan, value] = latest || [];
  113 +
  114 + return {
  115 + value,
  116 + name: attributeRename ?? attribute,
  117 + itemStyle: { color: fontColor },
  118 + tooltip: {
  119 + valueFormatter(value) {
  120 + return `${value} ${unit ?? ''}`;
  121 + },
  122 + },
  123 + } as SeriesOption['data'];
  124 + });
  125 + const yAxisData = series.map((item) => {
  126 + const { name } = item as any;
  127 + return name;
  128 + });
  129 + // }
  130 + // console.log(message, 'message', series, 'series', sum);
  131 + updateChart(series, yAxisData);
  132 + };
  133 +
  134 + useMultipleDataFetch(props, updateFn);
  135 +
  136 + onMounted(() => {
  137 + initial();
  138 + // !props.config.option.uuid && randomFn();
  139 + !props.config.option.uuid;
  140 + });
  141 +
  142 + const resize = async () => {
  143 + await nextTick();
  144 +
  145 + // 修改echarts大小
  146 + unref(chartInstance)?.setOption({
  147 + legend: {
  148 + textStyle: {
  149 + fontSize: 14 * unref(getRatio),
  150 + },
  151 + },
  152 + } as EChartsOption);
  153 + unref(chartInstance)?.resize();
  154 + };
  155 +
  156 + const { getRatio } = useComponentScale(props, resize);
  157 +</script>
  158 +
  159 +<template>
  160 + <main class="w-full h-full flex flex-col justify-center items-center">
  161 + <DeviceName :config="config" />
  162 + <div ref="chartRefEl" class="flex-1 w-full h-full"> </div>
  163 + <UpdateTime :time="time" />
  164 + </main>
  165 +</template>
  1 +import cloneDeep from 'lodash-es/cloneDeep';
  2 +import { StatisticsComponent5Config } from '.';
  3 +import {
  4 + ConfigType,
  5 + CreateComponentType,
  6 + PublicComponentOptions,
  7 + PublicPresetOptions,
  8 +} from '../../../index.type';
  9 +import { PublicConfigClass, componentInitConfig } from '../../../publicConfig';
  10 +import { ComponentConfigFieldEnum } from '../../../enum';
  11 +
  12 +export enum Gradient {
  13 + FIRST = 'first',
  14 + SECOND = 'second',
  15 +}
  16 +export enum GradientColor {
  17 + FIRST = '#07ffd6',
  18 + SECOND = '#5eff10',
  19 +}
  20 +export const option: PublicPresetOptions = {
  21 + multipleDataSourceComponent: true,
  22 + [ComponentConfigFieldEnum.FONT_COLOR]: '#FD7347',
  23 + [ComponentConfigFieldEnum.SHOW_DEVICE_NAME]: false,
  24 + [ComponentConfigFieldEnum.UNIT]: '℃',
  25 +};
  26 +
  27 +export default class Config extends PublicConfigClass implements CreateComponentType {
  28 + public key: string = StatisticsComponent5Config.key;
  29 +
  30 + public attr = { ...componentInitConfig };
  31 +
  32 + public componentConfig: ConfigType = cloneDeep(StatisticsComponent5Config);
  33 +
  34 + public persetOption = cloneDeep(option);
  35 +
  36 + public option: PublicComponentOptions;
  37 +
  38 + constructor(option: PublicComponentOptions) {
  39 + super();
  40 + this.option = { ...option };
  41 + }
  42 +}
  1 +<script lang="ts" setup>
  2 + import { ComponentConfigFieldEnum } from '../../../enum';
  3 + import { option } from './config';
  4 + import { useForm, BasicForm } from '/@/components/Form';
  5 + import { PublicFormInstaceType } from '/@/views/visual/dataSourceBindPanel/index.type';
  6 + import { ComponentInfo } from '/@/views/visual/palette/types';
  7 +
  8 + const [register, { getFieldsValue, setFieldsValue, resetFields }] = useForm({
  9 + schemas: [
  10 + {
  11 + field: ComponentConfigFieldEnum.FONT_COLOR,
  12 + label: '数值字体颜色',
  13 + component: 'ColorPicker',
  14 + changeEvent: 'update:value',
  15 + defaultValue: option.fontColor,
  16 + },
  17 + {
  18 + field: ComponentConfigFieldEnum.UNIT,
  19 + label: '数值单位',
  20 + component: 'Input',
  21 + defaultValue: option.unit,
  22 + },
  23 + {
  24 + field: ComponentConfigFieldEnum.SHOW_DEVICE_NAME,
  25 + label: '显示设备名称',
  26 + component: 'Checkbox',
  27 + defaultValue: option.showDeviceName,
  28 + },
  29 + ],
  30 + showActionButtonGroup: false,
  31 + labelWidth: 120,
  32 + baseColProps: {
  33 + span: 12,
  34 + },
  35 + });
  36 +
  37 + const getFormValues = () => {
  38 + // return getFieldsValue();
  39 + const item = getFieldsValue();
  40 + return {
  41 + fontColor: item[ComponentConfigFieldEnum.FONT_COLOR],
  42 + unit: item[ComponentConfigFieldEnum.UNIT],
  43 + showDeviceName: item[ComponentConfigFieldEnum.SHOW_DEVICE_NAME],
  44 + } as ComponentInfo;
  45 + };
  46 +
  47 + const setFormValues = (data: Recordable) => {
  48 + // return setFieldsValue(data);
  49 + const { unit, fontColor, showDeviceName } = data;
  50 +
  51 + const value = {
  52 + [ComponentConfigFieldEnum.UNIT]: unit,
  53 + [ComponentConfigFieldEnum.FONT_COLOR]: fontColor,
  54 + [ComponentConfigFieldEnum.SHOW_DEVICE_NAME]: showDeviceName,
  55 + };
  56 + return setFieldsValue(value);
  57 + };
  58 +
  59 + defineExpose({
  60 + getFormValues,
  61 + setFormValues,
  62 + resetFormValues: resetFields,
  63 + } as PublicFormInstaceType);
  64 +</script>
  65 +
  66 +<template>
  67 + <BasicForm @register="register" />
  68 +</template>
  1 +<script lang="ts" setup>
  2 + import { commonDataSourceSchemas } from '../../../config/common.config';
  3 + import { CreateComponentType } from '../../../index.type';
  4 + import { BasicForm, useForm } from '/@/components/Form';
  5 + import {
  6 + PublicComponentValueType,
  7 + PublicFormInstaceType,
  8 + } from '/@/views/visual/dataSourceBindPanel/index.type';
  9 +
  10 + defineProps<{
  11 + values: PublicComponentValueType;
  12 + componentConfig: CreateComponentType;
  13 + }>();
  14 +
  15 + const [register, { getFieldsValue, setFieldsValue, validate, resetFields }] = useForm({
  16 + labelWidth: 0,
  17 + showActionButtonGroup: false,
  18 + layout: 'horizontal',
  19 + labelCol: { span: 0 },
  20 + schemas: commonDataSourceSchemas(),
  21 + });
  22 +
  23 + const getFormValues = () => {
  24 + return getFieldsValue();
  25 + };
  26 +
  27 + const setFormValues = (record: Recordable) => {
  28 + return setFieldsValue(record);
  29 + };
  30 +
  31 + defineExpose({
  32 + getFormValues,
  33 + setFormValues,
  34 + validate,
  35 + resetFormValues: resetFields,
  36 + } as PublicFormInstaceType);
  37 +</script>
  38 +
  39 +<template>
  40 + <BasicForm @register="register" />
  41 +</template>
  1 +import { useComponentKeys } from '/@/views/visual/packages/hook/useComponentKeys';
  2 +import { ConfigType, PackagesCategoryEnum } from '/@/views/visual/packages/index.type';
  3 +
  4 +const componentKeys = useComponentKeys('StatisticsComponent5');
  5 +
  6 +export const StatisticsComponent5Config: ConfigType = {
  7 + ...componentKeys,
  8 + title: '实时数据表格',
  9 + package: PackagesCategoryEnum.STATISTICS,
  10 +};
  1 +<script lang="ts" setup>
  2 + import { reactive, ref } from 'vue';
  3 + import { useMultipleDataFetch } from '../../../hook/useSocket';
  4 + import { ComponentPropsConfigType, MultipleDataFetchUpdateFn } from '../../../index.type';
  5 + import { option } from './config';
  6 + import { DeviceName } from '/@/views/visual/commonComponents/DeviceName';
  7 + import { BasicTable, useTable, BasicColumn } from '/@/components/Table';
  8 +
  9 + const props = defineProps<{
  10 + config: ComponentPropsConfigType<typeof option>;
  11 + }>();
  12 +
  13 + const realTimeList = ref<any>([
  14 + { attribute: '测试', price: 2, time: '2023-06-29' },
  15 + { attribute: '测试1', price: 21, time: '2023-06-29' },
  16 + { attribute: '测试2', price: 213, time: '2023-06-29' },
  17 + ]);
  18 + const realTimeColumn = reactive<BasicColumn[]>([
  19 + { title: '属性', dataIndex: 'attribute', width: 80, ellipsis: true },
  20 + { title: '值', dataIndex: 'price', width: 80, ellipsis: true },
  21 + { title: '时间', dataIndex: 'time', width: 80, ellipsis: true },
  22 + ]);
  23 +
  24 + const [registerTable] = useTable({
  25 + showIndexColumn: false,
  26 + showTableSetting: false,
  27 + dataSource: realTimeList,
  28 + canResize: true,
  29 + maxHeight: 144,
  30 + size: 'small',
  31 + // columns: [{ title: '属性', dataIndex: 'attribute', width: 80 }],
  32 + columns: realTimeColumn as any,
  33 + });
  34 +
  35 + // const getDesign = computed(() => {
  36 + // const { persetOption, option } = props.config;
  37 + // clearInterval;
  38 + // return {};
  39 + // });
  40 +
  41 + // const randomFn = () => {
  42 + // useIntervalFn(() => {
  43 + // const value = (Math.random() * 100).toFixed(0);
  44 + // unref(chartInstance)?.setOption({
  45 + // series: [{ data: [{ value }] }, { data: [{ value }] }],
  46 + // } as EChartsOption);
  47 + // }, 3000);
  48 + // };
  49 +
  50 + const updateFn: MultipleDataFetchUpdateFn = () => {};
  51 +
  52 + useMultipleDataFetch(props, updateFn);
  53 +
  54 + // const { getRatio } = useComponentScale(props);
  55 +</script>
  56 +
  57 +<template>
  58 + <main class="flex flex-col justify-center items-center">
  59 + <DeviceName :config="config" />
  60 + <div>
  61 + <!-- <PageWrapper> -->
  62 + <BasicTable @register="registerTable" />
  63 + <!-- </PageWrapper> -->
  64 + </div>
  65 + </main>
  66 +</template>
  1 +import cloneDeep from 'lodash-es/cloneDeep';
  2 +import { StatisticsComponent6Config } from '.';
  3 +import {
  4 + ConfigType,
  5 + CreateComponentType,
  6 + PublicComponentOptions,
  7 + PublicPresetOptions,
  8 +} from '../../../index.type';
  9 +import { PublicConfigClass, componentInitConfig } from '../../../publicConfig';
  10 +import { ComponentConfigFieldEnum } from '../../../enum';
  11 +
  12 +export enum Gradient {
  13 + FIRST = 'first',
  14 + SECOND = 'second',
  15 +}
  16 +export enum GradientColor {
  17 + FIRST = '#07ffd6',
  18 + SECOND = '#5eff10',
  19 +}
  20 +export const option: PublicPresetOptions = {
  21 + multipleDataSourceComponent: true,
  22 + [ComponentConfigFieldEnum.FONT_COLOR]: '#FD7347',
  23 + [ComponentConfigFieldEnum.SHOW_DEVICE_NAME]: false,
  24 + [ComponentConfigFieldEnum.UNIT]: '℃',
  25 +};
  26 +
  27 +export default class Config extends PublicConfigClass implements CreateComponentType {
  28 + public key: string = StatisticsComponent6Config.key;
  29 +
  30 + public attr = { ...componentInitConfig };
  31 +
  32 + public componentConfig: ConfigType = cloneDeep(StatisticsComponent6Config);
  33 +
  34 + public persetOption = cloneDeep(option);
  35 +
  36 + public option: PublicComponentOptions;
  37 +
  38 + constructor(option: PublicComponentOptions) {
  39 + super();
  40 + this.option = { ...option };
  41 + }
  42 +}
  1 +<script lang="ts" setup>
  2 + import { ComponentConfigFieldEnum } from '../../../enum';
  3 + import { option } from './config';
  4 + import { useForm, BasicForm } from '/@/components/Form';
  5 + import { PublicFormInstaceType } from '/@/views/visual/dataSourceBindPanel/index.type';
  6 + import { ComponentInfo } from '/@/views/visual/palette/types';
  7 +
  8 + const [register, { getFieldsValue, setFieldsValue, resetFields }] = useForm({
  9 + schemas: [
  10 + {
  11 + field: ComponentConfigFieldEnum.FONT_COLOR,
  12 + label: '数值字体颜色',
  13 + component: 'ColorPicker',
  14 + changeEvent: 'update:value',
  15 + defaultValue: option.fontColor,
  16 + },
  17 + {
  18 + field: ComponentConfigFieldEnum.UNIT,
  19 + label: '数值单位',
  20 + component: 'Input',
  21 + defaultValue: option.unit,
  22 + },
  23 + {
  24 + field: ComponentConfigFieldEnum.SHOW_DEVICE_NAME,
  25 + label: '显示设备名称',
  26 + component: 'Checkbox',
  27 + defaultValue: option.showDeviceName,
  28 + },
  29 + ],
  30 + showActionButtonGroup: false,
  31 + labelWidth: 120,
  32 + baseColProps: {
  33 + span: 12,
  34 + },
  35 + });
  36 +
  37 + const getFormValues = () => {
  38 + // return getFieldsValue();
  39 + const item = getFieldsValue();
  40 + return {
  41 + fontColor: item[ComponentConfigFieldEnum.FONT_COLOR],
  42 + unit: item[ComponentConfigFieldEnum.UNIT],
  43 + showDeviceName: item[ComponentConfigFieldEnum.SHOW_DEVICE_NAME],
  44 + } as ComponentInfo;
  45 + };
  46 +
  47 + const setFormValues = (data: Recordable) => {
  48 + // return setFieldsValue(data);
  49 + const { unit, fontColor, showDeviceName } = data;
  50 +
  51 + const value = {
  52 + [ComponentConfigFieldEnum.UNIT]: unit,
  53 + [ComponentConfigFieldEnum.FONT_COLOR]: fontColor,
  54 + [ComponentConfigFieldEnum.SHOW_DEVICE_NAME]: showDeviceName,
  55 + };
  56 + return setFieldsValue(value);
  57 + };
  58 +
  59 + defineExpose({
  60 + getFormValues,
  61 + setFormValues,
  62 + resetFormValues: resetFields,
  63 + } as PublicFormInstaceType);
  64 +</script>
  65 +
  66 +<template>
  67 + <BasicForm @register="register" />
  68 +</template>
  1 +<script lang="ts" setup>
  2 + import { commonDataSourceSchemas } from '../../../config/common.config';
  3 + import { CreateComponentType } from '../../../index.type';
  4 + import { BasicForm, useForm } from '/@/components/Form';
  5 + import {
  6 + PublicComponentValueType,
  7 + PublicFormInstaceType,
  8 + } from '/@/views/visual/dataSourceBindPanel/index.type';
  9 +
  10 + defineProps<{
  11 + values: PublicComponentValueType;
  12 + componentConfig: CreateComponentType;
  13 + }>();
  14 +
  15 + const [register, { getFieldsValue, setFieldsValue, validate, resetFields }] = useForm({
  16 + labelWidth: 0,
  17 + showActionButtonGroup: false,
  18 + layout: 'horizontal',
  19 + labelCol: { span: 0 },
  20 + schemas: commonDataSourceSchemas(),
  21 + });
  22 +
  23 + const getFormValues = () => {
  24 + return getFieldsValue();
  25 + };
  26 +
  27 + const setFormValues = (record: Recordable) => {
  28 + return setFieldsValue(record);
  29 + };
  30 +
  31 + defineExpose({
  32 + getFormValues,
  33 + setFormValues,
  34 + validate,
  35 + resetFormValues: resetFields,
  36 + } as PublicFormInstaceType);
  37 +</script>
  38 +
  39 +<template>
  40 + <BasicForm @register="register" />
  41 +</template>
  1 +import { useComponentKeys } from '/@/views/visual/packages/hook/useComponentKeys';
  2 +import { ConfigType, PackagesCategoryEnum } from '/@/views/visual/packages/index.type';
  3 +
  4 +const componentKeys = useComponentKeys('StatisticsComponent6');
  5 +
  6 +export const StatisticsComponent6Config: ConfigType = {
  7 + ...componentKeys,
  8 + title: '实时数据折线图',
  9 + package: PackagesCategoryEnum.STATISTICS,
  10 +};
  1 +<script lang="ts" setup>
  2 + import { EChartsOption, ECharts, init } from 'echarts';
  3 + import { unref, ref, onMounted, nextTick } from 'vue';
  4 + import { useMultipleDataFetch } from '../../../hook/useSocket';
  5 + import { ComponentPropsConfigType, MultipleDataFetchUpdateFn } from '../../../index.type';
  6 + import { option } from './config';
  7 + import { UpdateTime } from '/@/views/visual/commonComponents/UpdateTime';
  8 + import { useComponentScale } from '../../../hook/useComponentScale';
  9 + import { DeviceName } from '/@/views/visual/commonComponents/DeviceName';
  10 + import { dateFormat } from '/@/utils/common/compUtils';
  11 +
  12 + const props = defineProps<{
  13 + config: ComponentPropsConfigType<typeof option>;
  14 + }>();
  15 +
  16 + const chartRefEl = ref<Nullable<HTMLDivElement>>(null);
  17 +
  18 + const chartInstance = ref<Nullable<ECharts>>(null);
  19 +
  20 + const time = ref<Nullable<number>>(null);
  21 +
  22 + function randomData() {
  23 + now.value = now.value + oneDay;
  24 + const newTime = dateFormat(unref(now), 'MM-dd hh:mm:ss');
  25 + value = value + Math.random() * 21 - 10;
  26 + return {
  27 + name: newTime,
  28 + value: [newTime, Math.round(value)],
  29 + };
  30 + }
  31 + const data = ref<any>([]);
  32 + const now = ref<number>(1688026367000);
  33 + let oneDay = 5000; //间隔秒数
  34 + let value = Math.random() * 1000;
  35 + for (let i = 0; i < 10; i++) {
  36 + data.value.push(randomData());
  37 + }
  38 + setInterval(function () {
  39 + for (let i = 0; i < 1; i++) {
  40 + data.value.shift();
  41 + data.value.push(randomData());
  42 + }
  43 + unref(chartInstance)?.setOption(options());
  44 + }, 1000);
  45 +
  46 + // const getDesign = computed(() => {
  47 + // const { persetOption, option } = props.config;
  48 + // const { dataSource = [] } = option || {};
  49 + // const { unit: presetUnit, fontColor: presetFontColor } = persetOption || {};
  50 + // return {
  51 + // dataSource: dataSource?.map((item) => {
  52 + // const { unit, fontColor } = item.componentInfo || {};
  53 + // const { attribute, attributeRename } = item;
  54 + // return {
  55 + // unit: unit ?? presetUnit,
  56 + // fontColor: fontColor ?? presetFontColor,
  57 + // attribute,
  58 + // attributeRename,
  59 + // };
  60 + // }),
  61 + // };
  62 + // });
  63 +
  64 + const options = (): EChartsOption => {
  65 + // getStageColor(gradientInfo);
  66 + return {
  67 + trigger: 'axis',
  68 + axisPointer: {
  69 + lineStyle: {
  70 + width: 1,
  71 + color: '#019680',
  72 + },
  73 + },
  74 + legend: {
  75 + top: '10%',
  76 + left: 'center',
  77 + data: ['温度', '湿度'],
  78 + },
  79 + grid: {
  80 + top: '45%',
  81 + left: '20%',
  82 + bottom: '14%',
  83 + containLabel: true,
  84 + },
  85 + xAxis: {
  86 + type: 'category',
  87 + splitLine: {
  88 + show: true,
  89 + lineStyle: {
  90 + width: 1,
  91 + type: 'solid',
  92 + color: 'rgba(226,226,226,0.5)',
  93 + },
  94 + },
  95 + data: unref(data).map((item) => item.name),
  96 + },
  97 + yAxis: {
  98 + type: 'value',
  99 + boundaryGap: [0, '50%'],
  100 + splitLine: {
  101 + show: false,
  102 + },
  103 + },
  104 + series: [
  105 + {
  106 + type: 'line',
  107 + name: '温度',
  108 + stack: 'Total',
  109 + data: unref(data).map((item) => item.value),
  110 + },
  111 + {
  112 + type: 'line',
  113 + name: '湿度',
  114 + stack: 'Total',
  115 + data: unref(data).map((item) => {
  116 + return Number(item.value[1]) * 0.99;
  117 + }),
  118 + },
  119 + ],
  120 + };
  121 + };
  122 +
  123 + const initial = () => {
  124 + chartInstance.value = init(unref(chartRefEl)! as HTMLElement);
  125 + chartInstance.value.setOption(options());
  126 + };
  127 +
  128 + // const updateChart = (data: SeriesOption['data'], yAxisData) => {
  129 + // unref(chartInstance)?.setOption({
  130 + // series: [{ data }],
  131 + // yAxis: { data: yAxisData },
  132 + // } as EChartsOption);
  133 + // };
  134 +
  135 + const updateFn: MultipleDataFetchUpdateFn = () => {
  136 + // console.log(message, 'message');
  137 + return {};
  138 + };
  139 +
  140 + useMultipleDataFetch(props, updateFn);
  141 +
  142 + onMounted(() => {
  143 + initial();
  144 + // !props.config.option.uuid && randomFn();
  145 + !props.config.option.uuid;
  146 + });
  147 +
  148 + const resize = async () => {
  149 + await nextTick();
  150 +
  151 + // 修改echarts大小
  152 + unref(chartInstance)?.setOption({
  153 + legend: {
  154 + textStyle: {
  155 + fontSize: 14 * unref(getRatio),
  156 + },
  157 + },
  158 + } as EChartsOption);
  159 + unref(chartInstance)?.resize();
  160 + };
  161 +
  162 + const { getRatio } = useComponentScale(props, resize);
  163 +</script>
  164 +
  165 +<template>
  166 + <main class="w-full h-full flex flex-col justify-center items-center">
  167 + <DeviceName :config="config" />
  168 + <div ref="chartRefEl" class="flex-1 w-full h-full"> </div>
  169 + <UpdateTime :time="time" />
  170 + </main>
  171 +</template>
  1 +import { StatisticsComponent1Config } from './StatisticsComponent1';
  2 +import { StatisticsComponent2Config } from './StatisticsComponent2';
  3 +// import { StatisticsComponent3Config } from './StatisticsComponent3';
  4 +// import { StatisticsComponent4Config } from './StatisticsComponent4';
  5 +// import { StatisticsComponent5Config } from './StatisticsComponent5';
  6 +// import { StatisticsComponent6Config } from './StatisticsComponent6';
  7 +
  8 +export const STATISTICSList = [
  9 + StatisticsComponent1Config,
  10 + StatisticsComponent2Config,
  11 + // StatisticsComponent3Config,
  12 + // StatisticsComponent4Config,
  13 + // StatisticsComponent5Config,
  14 + // StatisticsComponent6Config,
  15 +];
  1 +import cloneDeep from 'lodash-es/cloneDeep';
  2 +import { SwitchSignalLightConfig } from '.';
  3 +import {
  4 + ConfigType,
  5 + CreateComponentType,
  6 + PublicComponentOptions,
  7 + PublicPresetOptions,
  8 +} from '/@/views/visual/packages/index.type';
  9 +import { PublicConfigClass, componentInitConfig } from '/@/views/visual/packages/publicConfig';
  10 +import { ComponentConfigFieldEnum } from '/@/views/visual/packages/enum';
  11 +
  12 +export const option: PublicPresetOptions = {
  13 + [ComponentConfigFieldEnum.OPEN_COLOR]: '#30f230',
  14 + [ComponentConfigFieldEnum.CLOSE_COLOR]: '#eeeeee',
  15 + [ComponentConfigFieldEnum.SHOW_DEVICE_NAME]: true,
  16 +};
  17 +
  18 +export default class Config extends PublicConfigClass implements CreateComponentType {
  19 + public key: string = SwitchSignalLightConfig.key;
  20 +
  21 + public attr = { ...componentInitConfig };
  22 +
  23 + public componentConfig: ConfigType = cloneDeep(SwitchSignalLightConfig);
  24 +
  25 + public persetOption = cloneDeep(option);
  26 +
  27 + public option: PublicComponentOptions;
  28 +
  29 + constructor(option: PublicComponentOptions) {
  30 + super();
  31 + this.option = { ...option };
  32 + }
  33 +}
  1 +<script lang="ts" setup>
  2 + import { ComponentConfigFieldEnum } from '/@/views/visual/packages/enum';
  3 + import { useForm, BasicForm } from '/@/components/Form';
  4 + import { PublicFormInstaceType } from '/@/views/visual/dataSourceBindPanel/index.type';
  5 + import { option } from './config';
  6 +
  7 + const [register, { getFieldsValue, setFieldsValue, resetFields }] = useForm({
  8 + schemas: [
  9 + {
  10 + field: ComponentConfigFieldEnum.OPEN_COLOR,
  11 + label: 'ON颜色',
  12 + component: 'ColorPicker',
  13 + changeEvent: 'update:value',
  14 + componentProps: {
  15 + defaultValue: option.openColor,
  16 + },
  17 + },
  18 + {
  19 + field: ComponentConfigFieldEnum.CLOSE_COLOR,
  20 + label: 'OFF颜色',
  21 + component: 'ColorPicker',
  22 + changeEvent: 'update:value',
  23 + componentProps: {
  24 + defaultValue: option.closeColor,
  25 + },
  26 + },
  27 + {
  28 + field: ComponentConfigFieldEnum.SHOW_DEVICE_NAME,
  29 + label: '显示设备名称',
  30 + component: 'Checkbox',
  31 + defaultValue: option.showDeviceName,
  32 + },
  33 + ],
  34 + showActionButtonGroup: false,
  35 + labelWidth: 120,
  36 + baseColProps: {
  37 + span: 12,
  38 + },
  39 + });
  40 +
  41 + const getFormValues = () => {
  42 + return getFieldsValue();
  43 + };
  44 +
  45 + const setFormValues = (data: Recordable) => {
  46 + return setFieldsValue(data);
  47 + };
  48 +
  49 + defineExpose({
  50 + getFormValues,
  51 + setFormValues,
  52 + resetFormValues: resetFields,
  53 + } as PublicFormInstaceType);
  54 +</script>
  55 +
  56 +<template>
  57 + <BasicForm @register="register" />
  58 +</template>
  1 +<script lang="ts" setup>
  2 + import { commonDataSourceSchemas } from '../../../config/common.config';
  3 + import { BasicForm, useForm } from '/@/components/Form';
  4 + import { PublicFormInstaceType } from '/@/views/visual/dataSourceBindPanel/index.type';
  5 +
  6 + const [register, { getFieldsValue, setFieldsValue, validate, resetFields }] = useForm({
  7 + labelWidth: 0,
  8 + showActionButtonGroup: false,
  9 + layout: 'horizontal',
  10 + labelCol: { span: 0 },
  11 + schemas: commonDataSourceSchemas(),
  12 + });
  13 +
  14 + const getFormValues = () => {
  15 + return getFieldsValue();
  16 + };
  17 +
  18 + const setFormValues = (record: Recordable) => {
  19 + return setFieldsValue(record);
  20 + };
  21 +
  22 + defineExpose({
  23 + getFormValues,
  24 + setFormValues,
  25 + validate,
  26 + resetFormValues: resetFields,
  27 + } as PublicFormInstaceType);
  28 +</script>
  29 +
  30 +<template>
  31 + <BasicForm @register="register" />
  32 +</template>
  1 +// import { ComponentEnum, ComponentNameEnum } from '../index.type';
  2 +import { useComponentKeys } from '/@/views/visual/packages/hook/useComponentKeys';
  3 +import { ConfigType, PackagesCategoryEnum } from '/@/views/visual/packages/index.type';
  4 +
  5 +const componentKeys = useComponentKeys('SwitchSignalLight');
  6 +export const SwitchSignalLightConfig: ConfigType = {
  7 + ...componentKeys,
  8 + // title: ComponentNameEnum.TEXT_COMPONENT_1,
  9 + title: '开关量信号灯',
  10 + package: PackagesCategoryEnum.TEXT,
  11 +};
  1 +<script lang="ts" setup>
  2 + import { ComponentPropsConfigType, DataFetchUpdateFn } from '/@/views/visual/packages/index.type';
  3 + import { option } from './config';
  4 + import { useComponentScale } from '/@/views/visual/packages/hook/useComponentScale';
  5 + import { useDataFetch } from '/@/views/visual/packages/hook/useSocket';
  6 + import { computed } from 'vue';
  7 + import { ref, onMounted, unref } from 'vue';
  8 + import { useIntervalFn } from '@vueuse/core';
  9 + import { DeviceName } from '/@/views/visual/commonComponents/DeviceName';
  10 +
  11 + const props = defineProps<{
  12 + config: ComponentPropsConfigType<typeof option>;
  13 + }>();
  14 +
  15 + const isOpenClose = ref<boolean>(true);
  16 +
  17 + const getDesign = computed(() => {
  18 + const { persetOption = {}, option } = props.config;
  19 + const {
  20 + openColor: persetOpenColor,
  21 + closeColor: persetCloseColor,
  22 + showDeviceName: persetShowDeviceName,
  23 + } = persetOption || {};
  24 + const { componentInfo } = option;
  25 +
  26 + const { openColor, closeColor, showDeviceName } = componentInfo || {};
  27 + return {
  28 + openColor: openColor ?? persetOpenColor,
  29 + closeColor: closeColor ?? persetCloseColor,
  30 + showDeviceName: showDeviceName ?? persetShowDeviceName,
  31 + };
  32 + });
  33 +
  34 + const randomFn = () => {
  35 + useIntervalFn(() => {
  36 + isOpenClose.value = !unref(isOpenClose);
  37 + }, 2000);
  38 + };
  39 +
  40 + const updateFn: DataFetchUpdateFn = () => {};
  41 +
  42 + onMounted(() => {
  43 + !props.config.option.uuid && randomFn();
  44 + });
  45 +
  46 + useDataFetch(props, updateFn);
  47 +
  48 + const { getScale } = useComponentScale(props);
  49 +</script>
  50 +
  51 +<template>
  52 + <main :style="getScale" class="w-full h-full flex flex-col justify-center items-center">
  53 + <DeviceName :config="config" class="text-center" />
  54 + <div
  55 + :style="{
  56 + '--open-color': getDesign.openColor,
  57 + '--close-color': getDesign.closeColor,
  58 + }"
  59 + :class="isOpenClose ? 'switch_open' : 'switch_close'"
  60 + ></div>
  61 + </main>
  62 +</template>
  63 +<style lang="less" scoped>
  64 + .switch_open {
  65 + background: var(--open-color);
  66 + box-shadow: var(--open-color) 0 0 10px 3px;
  67 + width: 60px;
  68 + height: 60px;
  69 + border-radius: 50%;
  70 + margin: 10px 0;
  71 + }
  72 +
  73 + .switch_close {
  74 + background-color: var(--close-color);
  75 + box-shadow: none;
  76 + width: 42.023px;
  77 + height: 42.023px;
  78 + border-radius: 50%;
  79 + margin: 10px 0;
  80 + }
  81 +</style>
  1 +import cloneDeep from 'lodash-es/cloneDeep';
  2 +import { SwitchStatusConfig } from '.';
  3 +import {
  4 + ConfigType,
  5 + CreateComponentType,
  6 + PublicComponentOptions,
  7 + PublicPresetOptions,
  8 +} from '/@/views/visual/packages/index.type';
  9 +import { PublicConfigClass, componentInitConfig } from '/@/views/visual/packages/publicConfig';
  10 +import { ComponentConfigFieldEnum } from '/@/views/visual/packages/enum';
  11 +
  12 +export const option: PublicPresetOptions = {
  13 + [ComponentConfigFieldEnum.ICON]: 'shuiwen',
  14 + [ComponentConfigFieldEnum.ICON_COLOR]: '#367bff',
  15 + [ComponentConfigFieldEnum.ICON_CLOSE]: 'shuiwen',
  16 + [ComponentConfigFieldEnum.ICON_COLOR_CLOSE]: '#CCCCCC',
  17 + [ComponentConfigFieldEnum.SHOW_DEVICE_NAME]: false,
  18 +};
  19 +
  20 +export default class Config extends PublicConfigClass implements CreateComponentType {
  21 + public key: string = SwitchStatusConfig.key;
  22 +
  23 + public attr = { ...componentInitConfig };
  24 +
  25 + public componentConfig: ConfigType = cloneDeep(SwitchStatusConfig);
  26 +
  27 + public persetOption = cloneDeep(option);
  28 +
  29 + public option: PublicComponentOptions;
  30 +
  31 + constructor(option: PublicComponentOptions) {
  32 + super();
  33 + this.option = { ...option };
  34 + }
  35 +}
  1 +<script lang="ts" setup>
  2 + import { ComponentConfigFieldEnum } from '/@/views/visual/packages/enum';
  3 + import { useForm, BasicForm } from '/@/components/Form';
  4 + import { PublicFormInstaceType } from '/@/views/visual/dataSourceBindPanel/index.type';
  5 + import { option } from './config';
  6 +
  7 + const [register, { getFieldsValue, setFieldsValue, resetFields }] = useForm({
  8 + schemas: [
  9 + {
  10 + field: ComponentConfigFieldEnum.ICON,
  11 + label: '开启状态图标',
  12 + component: 'IconDrawer',
  13 + changeEvent: 'update:value',
  14 + defaultValue: option.icon,
  15 + componentProps({ formModel }) {
  16 + const color = formModel[ComponentConfigFieldEnum.ICON_COLOR];
  17 + return {
  18 + color,
  19 + };
  20 + },
  21 + },
  22 + {
  23 + field: ComponentConfigFieldEnum.ICON_COLOR,
  24 + label: '开启图标颜色',
  25 + component: 'ColorPicker',
  26 + changeEvent: 'update:value',
  27 + defaultValue: option.iconColor,
  28 + },
  29 + {
  30 + field: ComponentConfigFieldEnum.ICON_CLOSE,
  31 + label: '关闭状态图标',
  32 + component: 'IconDrawer',
  33 + changeEvent: 'update:value',
  34 + defaultValue: option.iconClose,
  35 + componentProps({ formModel }) {
  36 + const color = formModel[ComponentConfigFieldEnum.ICON_COLOR_CLOSE];
  37 + return {
  38 + color,
  39 + };
  40 + },
  41 + },
  42 + {
  43 + field: ComponentConfigFieldEnum.ICON_COLOR_CLOSE,
  44 + label: '关闭图标颜色',
  45 + component: 'ColorPicker',
  46 + changeEvent: 'update:value',
  47 + defaultValue: option.iconColorClose,
  48 + },
  49 + {
  50 + field: ComponentConfigFieldEnum.SHOW_DEVICE_NAME,
  51 + label: '显示设备名称',
  52 + component: 'Checkbox',
  53 + defaultValue: option.showDeviceName,
  54 + },
  55 + ],
  56 + showActionButtonGroup: false,
  57 + labelWidth: 120,
  58 + baseColProps: {
  59 + span: 12,
  60 + },
  61 + });
  62 +
  63 + const getFormValues = () => {
  64 + return getFieldsValue();
  65 + };
  66 +
  67 + const setFormValues = (data: Recordable) => {
  68 + return setFieldsValue(data);
  69 + };
  70 +
  71 + defineExpose({
  72 + getFormValues,
  73 + setFormValues,
  74 + resetFormValues: resetFields,
  75 + } as PublicFormInstaceType);
  76 +</script>
  77 +
  78 +<template>
  79 + <BasicForm @register="register" />
  80 +</template>
  1 +<script lang="ts" setup>
  2 + import { commonDataSourceSchemas } from '../../../config/common.config';
  3 + import { BasicForm, useForm } from '/@/components/Form';
  4 + import { PublicFormInstaceType } from '/@/views/visual/dataSourceBindPanel/index.type';
  5 +
  6 + // const props = defineProps<{
  7 + // values: PublicComponentDataSourceProps;
  8 + // }>();
  9 +
  10 + const [register, { getFieldsValue, setFieldsValue, validate, resetFields }] = useForm({
  11 + labelWidth: 0,
  12 + showActionButtonGroup: false,
  13 + layout: 'horizontal',
  14 + labelCol: { span: 0 },
  15 + schemas: commonDataSourceSchemas(),
  16 + });
  17 +
  18 + const getFormValues = () => {
  19 + return getFieldsValue();
  20 + };
  21 +
  22 + const setFormValues = (record: Recordable) => {
  23 + return setFieldsValue(record);
  24 + };
  25 +
  26 + defineExpose({
  27 + getFormValues,
  28 + setFormValues,
  29 + validate,
  30 + resetFormValues: resetFields,
  31 + } as PublicFormInstaceType);
  32 +</script>
  33 +
  34 +<template>
  35 + <BasicForm @register="register" />
  36 +</template>
  1 +import { useComponentKeys } from '/@/views/visual/packages/hook/useComponentKeys';
  2 +import { ConfigType, PackagesCategoryEnum } from '/@/views/visual/packages/index.type';
  3 +
  4 +const componentKeys = useComponentKeys('SwitchStatus');
  5 +export const SwitchStatusConfig: ConfigType = {
  6 + ...componentKeys,
  7 + title: '开关量状态',
  8 + package: PackagesCategoryEnum.TEXT,
  9 +};
  1 +<script lang="ts" setup>
  2 + import { useDataFetch } from '/@/views/visual/packages/hook/useSocket';
  3 + import { ComponentPropsConfigType, DataFetchUpdateFn } from '/@/views/visual/packages/index.type';
  4 +
  5 + import { option } from './config';
  6 + import { SvgIcon } from '/@/components/Icon';
  7 + import { computed } from 'vue';
  8 + import { DeviceName } from '/@/views/visual/commonComponents/DeviceName';
  9 +
  10 + const props = defineProps<{
  11 + config: ComponentPropsConfigType<typeof option>;
  12 + }>();
  13 +
  14 + const getDesign = computed(() => {
  15 + const { persetOption = {}, option } = props.config;
  16 +
  17 + const {
  18 + iconColor: persetIconColor,
  19 + unit: perseUnit,
  20 + icon: persetIcon,
  21 + fontColor: persetFontColor,
  22 + } = persetOption;
  23 +
  24 + const { componentInfo, attribute, attributeRename } = option;
  25 +
  26 + const { icon, iconColor, fontColor, unit } = componentInfo || {};
  27 + return {
  28 + iconColor: iconColor || persetIconColor,
  29 + unit: unit ?? perseUnit,
  30 + icon: icon || persetIcon,
  31 + fontColor: fontColor || persetFontColor,
  32 + attribute: attributeRename || attribute,
  33 + };
  34 + });
  35 +
  36 + // const svgList = ref<any>([
  37 + // {
  38 + // value: 26.2,
  39 + // name: 'wendu',
  40 + // icon: 'zongfushe',
  41 + // unit: 'kw',
  42 + // iconColor: '#367BFF',
  43 + // fontColor: '#357CFB',
  44 + // },
  45 + // {
  46 + // value: 53.7,
  47 + // name: 'shidu',
  48 + // icon: 'guangzhaoqiangdu',
  49 + // unit: '℃',
  50 + // iconColor: '#FFA000',
  51 + // fontColor: '#FFA000',
  52 + // },
  53 + // ]);
  54 +
  55 + const updateFn: DataFetchUpdateFn = () => {};
  56 +
  57 + useDataFetch(props, updateFn);
  58 +</script>
  59 +
  60 +<template>
  61 + <main class="w-full h-full flex flex-col justify-evenly items-center">
  62 + <DeviceName :config="config" />
  63 + <div class="flex justify-center items-center">
  64 + <SvgIcon
  65 + :name="getDesign.icon!"
  66 + prefix="iconfont"
  67 + :size="60"
  68 + :style="{ color: getDesign.iconColor }"
  69 + />
  70 + </div>
  71 + </main>
  72 +</template>
  1 +import cloneDeep from 'lodash-es/cloneDeep';
  2 +import { ValueList1Config } from '.';
  3 +import {
  4 + ConfigType,
  5 + CreateComponentType,
  6 + PublicComponentOptions,
  7 + PublicPresetOptions,
  8 +} from '/@/views/visual/packages/index.type';
  9 +import { PublicConfigClass, componentInitConfig } from '/@/views/visual/packages/publicConfig';
  10 +import { ComponentConfigFieldEnum } from '/@/views/visual/packages/enum';
  11 +
  12 +export const option: PublicPresetOptions = {
  13 + multipleDataSourceComponent: true,
  14 + [ComponentConfigFieldEnum.FONT_COLOR]: '#000',
  15 + [ComponentConfigFieldEnum.UNIT]: '℃',
  16 + [ComponentConfigFieldEnum.SHOW_DEVICE_NAME]: false,
  17 + [ComponentConfigFieldEnum.BACKGROUND_COLOR]: '#377dff',
  18 + fontSize: '18px',
  19 +};
  20 +
  21 +export default class Config extends PublicConfigClass implements CreateComponentType {
  22 + public key: string = ValueList1Config.key;
  23 +
  24 + public attr = { ...componentInitConfig };
  25 +
  26 + public componentConfig: ConfigType = cloneDeep(ValueList1Config);
  27 +
  28 + public persetOption = cloneDeep(option);
  29 +
  30 + public option: PublicComponentOptions;
  31 +
  32 + constructor(option: PublicComponentOptions) {
  33 + super();
  34 + this.option = { ...option };
  35 + }
  36 +}
  1 +<script lang="ts" setup>
  2 + import { ComponentConfigFieldEnum } from '/@/views/visual/packages/enum';
  3 + import { useForm, BasicForm } from '/@/components/Form';
  4 + import { PublicFormInstaceType } from '/@/views/visual/dataSourceBindPanel/index.type';
  5 + import { option } from './config';
  6 + const [register, { getFieldsValue, setFieldsValue, resetFields }] = useForm({
  7 + schemas: [
  8 + {
  9 + field: ComponentConfigFieldEnum.FONT_COLOR,
  10 + label: '数值字体颜色',
  11 + component: 'ColorPicker',
  12 + changeEvent: 'update:value',
  13 + componentProps: {
  14 + defaultValue: option.fontColor,
  15 + },
  16 + },
  17 + {
  18 + field: ComponentConfigFieldEnum.BACKGROUND_COLOR,
  19 + label: '进度条背景色',
  20 + component: 'ColorPicker',
  21 + changeEvent: 'update:value',
  22 + componentProps: {
  23 + defaultValue: option.backgroundColor,
  24 + },
  25 + },
  26 +
  27 + {
  28 + field: ComponentConfigFieldEnum.UNIT,
  29 + label: '数值单位',
  30 + component: 'Input',
  31 + defaultValue: option.unit,
  32 + },
  33 + // {
  34 + // field: ComponentConfigFieldEnum.SHOW_DEVICE_NAME,
  35 + // label: '显示设备名称',
  36 + // component: 'Checkbox',
  37 + // },
  38 + ],
  39 + showActionButtonGroup: false,
  40 + labelWidth: 120,
  41 + baseColProps: {
  42 + span: 12,
  43 + },
  44 + });
  45 +
  46 + const getFormValues = () => {
  47 + return getFieldsValue();
  48 + };
  49 +
  50 + const setFormValues = (data: Recordable) => {
  51 + return setFieldsValue(data);
  52 + };
  53 +
  54 + defineExpose({
  55 + getFormValues,
  56 + setFormValues,
  57 + resetFormValues: resetFields,
  58 + } as PublicFormInstaceType);
  59 +</script>
  60 +
  61 +<template>
  62 + <BasicForm @register="register" />
  63 +</template>
  1 +<script lang="ts" setup>
  2 + import { commonDataSourceSchemas } from '../../../config/common.config';
  3 + import { BasicForm, useForm } from '/@/components/Form';
  4 + import { PublicFormInstaceType } from '/@/views/visual/dataSourceBindPanel/index.type';
  5 +
  6 + // const props = defineProps<{
  7 + // values: PublicComponentDataSourceProps;
  8 + // }>();
  9 +
  10 + const [register, { getFieldsValue, setFieldsValue, validate, resetFields }] = useForm({
  11 + labelWidth: 0,
  12 + showActionButtonGroup: false,
  13 + layout: 'horizontal',
  14 + labelCol: { span: 0 },
  15 + schemas: commonDataSourceSchemas(),
  16 + });
  17 +
  18 + const getFormValues = () => {
  19 + return getFieldsValue();
  20 + };
  21 +
  22 + const setFormValues = (record: Recordable) => {
  23 + return setFieldsValue(record);
  24 + };
  25 +
  26 + defineExpose({
  27 + getFormValues,
  28 + setFormValues,
  29 + validate,
  30 + resetFormValues: resetFields,
  31 + } as PublicFormInstaceType);
  32 +</script>
  33 +
  34 +<template>
  35 + <BasicForm @register="register" />
  36 +</template>
  1 +import { useComponentKeys } from '/@/views/visual/packages/hook/useComponentKeys';
  2 +import { ConfigType, PackagesCategoryEnum } from '/@/views/visual/packages/index.type';
  3 +
  4 +const componentKeys = useComponentKeys('ValueList1');
  5 +export const ValueList1Config: ConfigType = {
  6 + ...componentKeys,
  7 + title: '数值列表1',
  8 + package: PackagesCategoryEnum.TEXT,
  9 +};
  1 +<script lang="ts" setup>
  2 + import { option } from './config';
  3 + // import { useComponentScale } from '/@/views/visual/packages/hook/useComponentScale';
  4 + import { ComponentPropsConfigType, MultipleDataFetchUpdateFn } from '../../../index.type';
  5 + import { useMultipleDataFetch } from '/@/views/visual/packages/hook/useSocket';
  6 + import { computed } from 'vue';
  7 + import { ref } from 'vue';
  8 + import { Progress } from 'ant-design-vue';
  9 + import { DeviceName } from '/@/views/visual/commonComponents/DeviceName';
  10 + import { unref } from 'vue';
  11 + import { onMounted } from 'vue';
  12 +
  13 + const props = defineProps<{
  14 + config: ComponentPropsConfigType<typeof option>;
  15 + }>();
  16 +
  17 + const percentList = ref<any[]>([
  18 + {
  19 + value: 20,
  20 + fontColor: '#19eff',
  21 + backgroundColor: '#19eff',
  22 + color: '#000',
  23 + fontSize: '16px',
  24 + unit: '℃',
  25 + id: 1,
  26 + },
  27 + {
  28 + value: 66,
  29 + fontColor: '#1E8667',
  30 + backgroundColor: '#1E8667',
  31 + color: '#000',
  32 + fontSize: '16px',
  33 + unit: '℃',
  34 + id: 2,
  35 + },
  36 + {
  37 + value: 49,
  38 + fontColor: '#2196F3',
  39 + backgroundColor: '#2196F3',
  40 + color: '#000',
  41 + fontSize: '16px',
  42 + unit: '℃',
  43 + id: 3,
  44 + },
  45 + ]);
  46 +
  47 + const getDesign = computed(() => {
  48 + const { persetOption = {}, option } = props.config;
  49 + const { dataSource = [] } = option || {};
  50 + const {
  51 + unit: presetUnit,
  52 + fontColor: presetFontColor,
  53 + backgroundColor: persetBackgroundColor,
  54 + } = persetOption || {};
  55 + return {
  56 + dataSource: dataSource?.map((item) => {
  57 + const { unit, fontColor, fontSize, backgroundColor } = item.componentInfo || {};
  58 + const { attribute, attributeRename } = item;
  59 + return {
  60 + unit: unit ?? presetUnit,
  61 + fontColor: fontColor ?? presetFontColor,
  62 + fontSize,
  63 + backgroundColor: backgroundColor ?? persetBackgroundColor,
  64 + attribute,
  65 + attributeRename,
  66 + };
  67 + }),
  68 + };
  69 + });
  70 +
  71 + const newPercentList = ref<any[]>([]);
  72 +
  73 + const updateFn: MultipleDataFetchUpdateFn = (message) => {
  74 + const { data = {} } = message;
  75 + const { dataSource } = unref(getDesign);
  76 + newPercentList.value = dataSource.map((item) => {
  77 + const { attribute, fontSize, attributeRename, fontColor, unit, backgroundColor } = item;
  78 +
  79 + const [latest] = data[attribute] || [];
  80 + const [_timespan, value] = latest || [];
  81 + return {
  82 + value: Number(value),
  83 + name: attributeRename ?? attribute,
  84 + fontSize,
  85 + unit,
  86 + backgroundColor: backgroundColor,
  87 + fontColor: fontColor,
  88 + };
  89 + });
  90 + // console.log(numberList, 'numberList');
  91 + };
  92 +
  93 + onMounted(() => {
  94 + newPercentList.value = percentList.value;
  95 + !props.config.option.uuid;
  96 + });
  97 +
  98 + useMultipleDataFetch(props, updateFn);
  99 +
  100 + // const { getScale } = useComponentScale(props);
  101 +</script>
  102 +
  103 +<template>
  104 + <main class="w-full h-full flex flex-col justify-center">
  105 + <DeviceName :config="config" />
  106 +
  107 + <div
  108 + v-for="item in newPercentList"
  109 + :key="item.id"
  110 + class="flex flex-col ml-3 mr-3 items-stretch"
  111 + >
  112 + <div class="flex justify-between">
  113 + <div class="text-gray-500 text-lg truncate">{{ item.name || '温度' }}</div>
  114 + <span class="text-lg" :style="{ color: item.fontColor }"
  115 + >{{ item.value }} {{ item.unit }}</span
  116 + >
  117 + </div>
  118 + <div>
  119 + <Progress :strokeColor="item.backgroundColor" :percent="item.value" :showInfo="false" />
  120 + </div>
  121 + </div>
  122 + </main>
  123 +</template>
  124 +<style lang="less" scoped>
  125 + // :deep(.ant-progress-success-bg, .ant-progress-bg) {
  126 + // background: '#2196F3' !important;
  127 + // }
  128 +</style>
  1 +import cloneDeep from 'lodash-es/cloneDeep';
  2 +import { ValueList2Config } from '.';
  3 +import {
  4 + ConfigType,
  5 + CreateComponentType,
  6 + PublicComponentOptions,
  7 + PublicPresetOptions,
  8 +} from '/@/views/visual/packages/index.type';
  9 +import { PublicConfigClass, componentInitConfig } from '/@/views/visual/packages/publicConfig';
  10 +import { ComponentConfigFieldEnum } from '/@/views/visual/packages/enum';
  11 +
  12 +export const option: PublicPresetOptions = {
  13 + multipleDataSourceComponent: true,
  14 + [ComponentConfigFieldEnum.UNIT]: '℃',
  15 + [ComponentConfigFieldEnum.ICON]: 'shuiwen',
  16 + [ComponentConfigFieldEnum.ICON_COLOR]: '#367bff',
  17 + [ComponentConfigFieldEnum.FONT_COLOR]: '#000',
  18 + [ComponentConfigFieldEnum.SHOW_DEVICE_NAME]: false,
  19 +};
  20 +
  21 +export default class Config extends PublicConfigClass implements CreateComponentType {
  22 + public key: string = ValueList2Config.key;
  23 +
  24 + public attr = { ...componentInitConfig };
  25 +
  26 + public componentConfig: ConfigType = cloneDeep(ValueList2Config);
  27 +
  28 + public persetOption = cloneDeep(option);
  29 +
  30 + public option: PublicComponentOptions;
  31 +
  32 + constructor(option: PublicComponentOptions) {
  33 + super();
  34 + this.option = { ...option };
  35 + }
  36 +}
  1 +<script lang="ts" setup>
  2 + import { ComponentConfigFieldEnum } from '/@/views/visual/packages/enum';
  3 + import { useForm, BasicForm } from '/@/components/Form';
  4 + import { PublicFormInstaceType } from '/@/views/visual/dataSourceBindPanel/index.type';
  5 + import { option } from './config';
  6 +
  7 + const [register, { getFieldsValue, setFieldsValue, resetFields }] = useForm({
  8 + schemas: [
  9 + {
  10 + field: ComponentConfigFieldEnum.FONT_COLOR,
  11 + label: '数值字体颜色',
  12 + component: 'ColorPicker',
  13 + changeEvent: 'update:value',
  14 + valueField: 'value',
  15 + defaultValue: option.fontColor,
  16 + },
  17 + {
  18 + field: ComponentConfigFieldEnum.UNIT,
  19 + label: '数值单位',
  20 + component: 'Input',
  21 + defaultValue: option.unit,
  22 + componentProps: {
  23 + placeholder: '请输入数值单位',
  24 + },
  25 + },
  26 + {
  27 + field: ComponentConfigFieldEnum.ICON_COLOR,
  28 + label: '图标颜色',
  29 + component: 'ColorPicker',
  30 + changeEvent: 'update:value',
  31 + defaultValue: option.iconColor,
  32 + },
  33 + {
  34 + field: ComponentConfigFieldEnum.ICON,
  35 + label: '图标',
  36 + component: 'IconDrawer',
  37 + changeEvent: 'update:value',
  38 + valueField: 'value',
  39 + defaultValue: option.icon,
  40 + componentProps({ formModel }) {
  41 + const color = formModel[ComponentConfigFieldEnum.ICON_COLOR];
  42 + return {
  43 + color,
  44 + };
  45 + },
  46 + },
  47 + {
  48 + field: ComponentConfigFieldEnum.SHOW_DEVICE_NAME,
  49 + label: '显示设备名称',
  50 + component: 'Checkbox',
  51 + defaultValue: option.showDeviceName,
  52 + },
  53 + ],
  54 + showActionButtonGroup: false,
  55 + labelWidth: 120,
  56 + baseColProps: {
  57 + span: 12,
  58 + },
  59 + });
  60 +
  61 + const getFormValues = () => {
  62 + return getFieldsValue();
  63 + };
  64 +
  65 + const setFormValues = (data: Recordable) => {
  66 + return setFieldsValue(data);
  67 + };
  68 +
  69 + defineExpose({
  70 + getFormValues,
  71 + setFormValues,
  72 + resetFormValues: resetFields,
  73 + } as PublicFormInstaceType);
  74 +</script>
  75 +
  76 +<template>
  77 + <BasicForm @register="register" />
  78 +</template>
  1 +<script lang="ts" setup>
  2 + import { commonDataSourceSchemas } from '../../../config/common.config';
  3 + import { BasicForm, useForm } from '/@/components/Form';
  4 + import { PublicFormInstaceType } from '/@/views/visual/dataSourceBindPanel/index.type';
  5 +
  6 + // const props = defineProps<{
  7 + // values: PublicComponentDataSourceProps;
  8 + // }>();
  9 +
  10 + const [register, { getFieldsValue, setFieldsValue, validate, resetFields }] = useForm({
  11 + labelWidth: 0,
  12 + showActionButtonGroup: false,
  13 + layout: 'horizontal',
  14 + labelCol: { span: 0 },
  15 + schemas: commonDataSourceSchemas(),
  16 + });
  17 +
  18 + const getFormValues = () => {
  19 + return getFieldsValue();
  20 + };
  21 +
  22 + const setFormValues = (record: Recordable) => {
  23 + return setFieldsValue(record);
  24 + };
  25 +
  26 + defineExpose({
  27 + getFormValues,
  28 + setFormValues,
  29 + validate,
  30 + resetFormValues: resetFields,
  31 + } as PublicFormInstaceType);
  32 +</script>
  33 +
  34 +<template>
  35 + <BasicForm @register="register" />
  36 +</template>
  1 +import { useComponentKeys } from '/@/views/visual/packages/hook/useComponentKeys';
  2 +import { ConfigType, PackagesCategoryEnum } from '/@/views/visual/packages/index.type';
  3 +
  4 +const componentKeys = useComponentKeys('ValueList2');
  5 +export const ValueList2Config: ConfigType = {
  6 + ...componentKeys,
  7 + title: '数值列表2',
  8 + package: PackagesCategoryEnum.TEXT,
  9 +};
  1 +<script lang="ts" setup>
  2 + import { ComponentPropsConfigType, MultipleDataFetchUpdateFn } from '../../../index.type';
  3 +
  4 + import { option } from './config';
  5 + import { useMultipleDataFetch } from '/@/views/visual/packages/hook/useSocket';
  6 + import { ref, unref } from 'vue';
  7 + import { SvgIcon } from '/@/components/Icon';
  8 + import { computed } from 'vue';
  9 + import { DeviceName } from '/@/views/visual/commonComponents/DeviceName';
  10 +
  11 + const props = defineProps<{
  12 + config: ComponentPropsConfigType<typeof option>;
  13 + }>();
  14 +
  15 + const getDesign = computed(() => {
  16 + const { persetOption = {}, option } = props.config;
  17 + const { dataSource = [] } = option || {};
  18 + const {
  19 + unit: persetUnit,
  20 + fontColor: persetFontColor,
  21 + icon: persetIcon,
  22 + iconColor: persetIconColor,
  23 + } = persetOption || {};
  24 + return {
  25 + dataSource: dataSource.map((item) => {
  26 + const { fontColor, icon, iconColor, unit } = item.componentInfo;
  27 + const { attribute, attributeRename } = item;
  28 + return {
  29 + unit: unit ?? persetUnit,
  30 + fontColor: fontColor ?? persetFontColor,
  31 + icon: icon ?? persetIcon,
  32 + iconColor: iconColor ?? persetIconColor,
  33 + attribute: attribute || attributeRename,
  34 + attributeRename,
  35 + };
  36 + }),
  37 + };
  38 + });
  39 + const svgList = ref<any>([
  40 + {
  41 + value: 26.2,
  42 + name: 'wendu',
  43 + icon: 'zongfushe',
  44 + unit: 'kw',
  45 + iconColor: '#367BFF',
  46 + fontColor: '#357CFB',
  47 + },
  48 + {
  49 + value: 53.7,
  50 + name: 'shidu',
  51 + icon: 'guangzhaoqiangdu',
  52 + unit: '℃',
  53 + iconColor: '#FFA000',
  54 + fontColor: '#FFA000',
  55 + },
  56 + ]);
  57 +
  58 + const updateFn: MultipleDataFetchUpdateFn = (message) => {
  59 + const { data = {} } = message;
  60 + const { dataSource } = unref(getDesign);
  61 + svgList.value.length = 0;
  62 + svgList.value = dataSource.map((item) => {
  63 + const { icon, iconColor, unit, fontColor, attribute } = item || {};
  64 + const [latest] = data[attribute] || [];
  65 + const [_timespan, value] = latest || [];
  66 + return {
  67 + value: Number(value),
  68 + name: attribute,
  69 + icon,
  70 + unit,
  71 + iconColor,
  72 + fontColor,
  73 + };
  74 + });
  75 + };
  76 +
  77 + useMultipleDataFetch(props, updateFn);
  78 +</script>
  79 +
  80 +<template>
  81 + <main class="w-full h-full flex flex-col justify-evenly items-center">
  82 + <DeviceName :config="config" />
  83 + <div
  84 + style="width: 86%"
  85 + v-for="item in svgList"
  86 + :key="item.id"
  87 + class="flex justify-between items-center"
  88 + >
  89 + <div class="flex items-center">
  90 + <SvgIcon
  91 + :name="item.icon!"
  92 + prefix="iconfont"
  93 + :size="45"
  94 + :style="{ color: item.iconColor }"
  95 + />
  96 +
  97 + <div class="text-gray-500 text-lg truncate ml-6">{{ item.attribute || '温度' }}</div>
  98 + </div>
  99 +
  100 + <h1 class="font-bold text-xl m-2 truncate" :style="{ color: item.fontColor }">
  101 + <span> {{ item.value || 0 }}</span>
  102 + <span>{{ item.unit }} </span>
  103 + </h1>
  104 + </div>
  105 + </main>
  106 +</template>
@@ -2,10 +2,18 @@ import { TextComponent1Config } from './TextComponent1'; @@ -2,10 +2,18 @@ import { TextComponent1Config } from './TextComponent1';
2 import { TextComponent2Config } from './TextComponent2'; 2 import { TextComponent2Config } from './TextComponent2';
3 import { TextComponent3Config } from './TextComponent3'; 3 import { TextComponent3Config } from './TextComponent3';
4 import { TextComponent4Config } from './TextComponent4'; 4 import { TextComponent4Config } from './TextComponent4';
  5 +import { SwitchSignalLightConfig } from './SwitchSignalLight';
  6 +// import { SwitchStatusConfig } from './SwitchStatus';
  7 +import { ValueList1Config } from './ValueList1';
  8 +// import { ValueList2Config } from './ValueList2';
5 9
6 export const TextList = [ 10 export const TextList = [
7 TextComponent1Config, 11 TextComponent1Config,
8 TextComponent2Config, 12 TextComponent2Config,
9 TextComponent3Config, 13 TextComponent3Config,
10 TextComponent4Config, 14 TextComponent4Config,
  15 + ValueList1Config,
  16 + // ValueList2Config,
  17 + SwitchSignalLightConfig,
  18 + // SwitchStatusConfig,
11 ]; 19 ];
@@ -3,12 +3,15 @@ export enum ComponentConfigFieldEnum { @@ -3,12 +3,15 @@ export enum ComponentConfigFieldEnum {
3 UNIT = 'unit', 3 UNIT = 'unit',
4 POINTER_COLOR = 'pointerColor', 4 POINTER_COLOR = 'pointerColor',
5 INSTRUMENT_PANEL_COLOR = 'instrumentPanelColor', 5 INSTRUMENT_PANEL_COLOR = 'instrumentPanelColor',
  6 + CONTROL_BAR_COLOR = 'controlBarColor',
6 // INSTRUMENT_PANEL_WIDTH = 'instrumentPanelWidth', 7 // INSTRUMENT_PANEL_WIDTH = 'instrumentPanelWidth',
7 8
8 PROGRESS_BAR_CIRCLE = 'progressBarCircle', 9 PROGRESS_BAR_CIRCLE = 'progressBarCircle',
9 10
10 ICON_COLOR = 'iconColor', 11 ICON_COLOR = 'iconColor',
  12 + ICON_COLOR_CLOSE = 'iconColorClose',
11 ICON = 'icon', 13 ICON = 'icon',
  14 + ICON_CLOSE = 'iconClose',
12 FIRST_PHASE_COLOR = 'firstPhaseColor', 15 FIRST_PHASE_COLOR = 'firstPhaseColor',
13 SECOND_PHASE_COLOR = 'secondPhaseColor', 16 SECOND_PHASE_COLOR = 'secondPhaseColor',
14 THIRD_PHASE_COLOR = 'thirdPhaseColor', 17 THIRD_PHASE_COLOR = 'thirdPhaseColor',
@@ -23,4 +26,6 @@ export enum ComponentConfigFieldEnum { @@ -23,4 +26,6 @@ export enum ComponentConfigFieldEnum {
23 WAVE_SECOND = 'waveSecond', 26 WAVE_SECOND = 'waveSecond',
24 WAVE_THIRD = 'waveThird', 27 WAVE_THIRD = 'waveThird',
25 BACKGROUND_COLOR = 'backgroundColor', 28 BACKGROUND_COLOR = 'backgroundColor',
  29 + OPEN_COLOR = 'openColor',
  30 + CLOSE_COLOR = 'closeColor',
26 } 31 }
@@ -8,6 +8,7 @@ export const useGetComponentConfig = ( @@ -8,6 +8,7 @@ export const useGetComponentConfig = (
8 ): CreateComponentType => { 8 ): CreateComponentType => {
9 try { 9 try {
10 const config = createComponent({ key: transformComponentKey(key) } as ConfigType, options); 10 const config = createComponent({ key: transformComponentKey(key) } as ConfigType, options);
  11 + if (!config) console.error(`can not get component config by component key (${key})`);
11 return config; 12 return config;
12 } catch (error) { 13 } catch (error) {
13 console.error(`can not get component config by component key (${key})`); 14 console.error(`can not get component config by component key (${key})`);
@@ -20,6 +20,7 @@ export enum PackagesCategoryNameEnum { @@ -20,6 +20,7 @@ export enum PackagesCategoryNameEnum {
20 CONTROL = '控制组件', 20 CONTROL = '控制组件',
21 MAP = '地图组件', 21 MAP = '地图组件',
22 FLOWMETER = '流量计', 22 FLOWMETER = '流量计',
  23 + STATISTICS = '统计',
23 OTHER = '其他', 24 OTHER = '其他',
24 } 25 }
25 26
@@ -33,6 +34,7 @@ export enum PackagesCategoryEnum { @@ -33,6 +34,7 @@ export enum PackagesCategoryEnum {
33 CONTROL = 'CONTROL', 34 CONTROL = 'CONTROL',
34 MAP = 'MAP', 35 MAP = 'MAP',
35 FLOWMETER = 'FLOWMETER', 36 FLOWMETER = 'FLOWMETER',
  37 + STATISTICS = 'STATISTICS',
36 OTHER = 'OTHER', 38 OTHER = 'OTHER',
37 } 39 }
38 40
@@ -92,6 +94,7 @@ export interface PublicPresetOptions { @@ -92,6 +94,7 @@ export interface PublicPresetOptions {
92 [ComponentConfigFieldEnum.UNIT]?: string; 94 [ComponentConfigFieldEnum.UNIT]?: string;
93 [ComponentConfigFieldEnum.ICON_COLOR]?: string; 95 [ComponentConfigFieldEnum.ICON_COLOR]?: string;
94 [ComponentConfigFieldEnum.ICON]?: string; 96 [ComponentConfigFieldEnum.ICON]?: string;
  97 + [ComponentConfigFieldEnum.CONTROL_BAR_COLOR]?: string;
95 [ComponentConfigFieldEnum.SHOW_DEVICE_NAME]?: boolean; 98 [ComponentConfigFieldEnum.SHOW_DEVICE_NAME]?: boolean;
96 [ComponentConfigFieldEnum.PROGRESS_BAR_CIRCLE]?: boolean; 99 [ComponentConfigFieldEnum.PROGRESS_BAR_CIRCLE]?: boolean;
97 [ComponentConfigFieldEnum.GRADIENT_INFO]?: ComponentInfoGradientInfoType[]; 100 [ComponentConfigFieldEnum.GRADIENT_INFO]?: ComponentInfoGradientInfoType[];
@@ -134,6 +137,7 @@ export interface PackagesType { @@ -134,6 +137,7 @@ export interface PackagesType {
134 [PackagesCategoryEnum.CONTROL]: ConfigType[]; 137 [PackagesCategoryEnum.CONTROL]: ConfigType[];
135 [PackagesCategoryEnum.MAP]: ConfigType[]; 138 [PackagesCategoryEnum.MAP]: ConfigType[];
136 [PackagesCategoryEnum.FLOWMETER]: ConfigType[]; 139 [PackagesCategoryEnum.FLOWMETER]: ConfigType[];
  140 + [PackagesCategoryEnum.STATISTICS]: ConfigType[];
137 [PackagesCategoryEnum.OTHER]: ConfigType[]; 141 [PackagesCategoryEnum.OTHER]: ConfigType[];
138 } 142 }
139 143
@@ -5,6 +5,7 @@ import { MapList } from './components/Map'; @@ -5,6 +5,7 @@ import { MapList } from './components/Map';
5 import { OtherList } from './components/Other'; 5 import { OtherList } from './components/Other';
6 import { PictureList } from './components/Picture'; 6 import { PictureList } from './components/Picture';
7 import { TextList } from './components/Text'; 7 import { TextList } from './components/Text';
  8 +import { STATISTICSList } from './components/Statistics';
8 import { PackagesCategoryEnum, PackagesType } from './index.type'; 9 import { PackagesCategoryEnum, PackagesType } from './index.type';
9 10
10 export const packageList: PackagesType = { 11 export const packageList: PackagesType = {
@@ -14,5 +15,6 @@ export const packageList: PackagesType = { @@ -14,5 +15,6 @@ export const packageList: PackagesType = {
14 [PackagesCategoryEnum.CONTROL]: ControlList, 15 [PackagesCategoryEnum.CONTROL]: ControlList,
15 [PackagesCategoryEnum.MAP]: MapList, 16 [PackagesCategoryEnum.MAP]: MapList,
16 [PackagesCategoryEnum.FLOWMETER]: FlowmeterList, 17 [PackagesCategoryEnum.FLOWMETER]: FlowmeterList,
  18 + [PackagesCategoryEnum.STATISTICS]: STATISTICSList,
17 [PackagesCategoryEnum.OTHER]: OtherList, 19 [PackagesCategoryEnum.OTHER]: OtherList,
18 }; 20 };
@@ -58,6 +58,7 @@ export interface ComponentInfo { @@ -58,6 +58,7 @@ export interface ComponentInfo {
58 instrumentPanelColor?: string; 58 instrumentPanelColor?: string;
59 // instrumentPanelWidth?: string | number; 59 // instrumentPanelWidth?: string | number;
60 progressBarCircle?: Boolean; 60 progressBarCircle?: Boolean;
  61 + [key: string]: any;
61 } 62 }
62 63
63 export interface CustomCommand { 64 export interface CustomCommand {