Commit 6d8d3f9e254c69a2b27516995192f676b3b10856

Authored by ww
1 parent d50cd716

feat: 数据看板新增流量计组件

  1 +import cloneDeep from 'lodash-es/cloneDeep';
  2 +import { RectFlowmeteConfig } 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.SHOW_DEVICE_NAME]: false,
  14 + [ComponentConfigFieldEnum.UNIT]: 'm',
  15 + [ComponentConfigFieldEnum.FLOWMETER_CONFIG]: {
  16 + [ComponentConfigFieldEnum.BACKGROUND_COLOR]: '#8badcb',
  17 + [ComponentConfigFieldEnum.WAVE_FIRST]: '#4579e2',
  18 + [ComponentConfigFieldEnum.WAVE_SECOND]: '#3461c1',
  19 + [ComponentConfigFieldEnum.WAVE_THIRD]: '#2d55aa',
  20 + },
  21 +};
  22 +
  23 +export default class Config extends PublicConfigClass implements CreateComponentType {
  24 + public key: string = RectFlowmeteConfig.key;
  25 +
  26 + public attr = { ...componentInitConfig };
  27 +
  28 + public componentConfig: ConfigType = cloneDeep(RectFlowmeteConfig);
  29 +
  30 + public persetOption = cloneDeep(option);
  31 +
  32 + public option: PublicComponentOptions;
  33 +
  34 + constructor(option: PublicComponentOptions) {
  35 + super();
  36 + this.option = { ...option };
  37 + }
  38 +}
... ...
  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.BACKGROUND_COLOR,
  11 + label: '背景颜色',
  12 + component: 'ColorPicker',
  13 + changeEvent: 'update:value',
  14 + defaultValue: option.flowmeterConfig?.backgroundColor,
  15 + },
  16 + {
  17 + field: ComponentConfigFieldEnum.WAVE_FIRST,
  18 + label: '浪1',
  19 + component: 'ColorPicker',
  20 + changeEvent: 'update:value',
  21 + defaultValue: option.flowmeterConfig?.waveFirst,
  22 + },
  23 + {
  24 + field: ComponentConfigFieldEnum.WAVE_SECOND,
  25 + label: '浪2',
  26 + component: 'ColorPicker',
  27 + changeEvent: 'update:value',
  28 + defaultValue: option.flowmeterConfig?.waveSecond,
  29 + },
  30 + {
  31 + field: ComponentConfigFieldEnum.WAVE_THIRD,
  32 + label: '浪3',
  33 + component: 'ColorPicker',
  34 + changeEvent: 'update:value',
  35 + defaultValue: option.flowmeterConfig?.waveThird,
  36 + },
  37 + {
  38 + field: ComponentConfigFieldEnum.UNIT,
  39 + label: '单位',
  40 + component: 'Input',
  41 + defaultValue: option.unit,
  42 + },
  43 + ],
  44 + showActionButtonGroup: false,
  45 + labelWidth: 120,
  46 + baseColProps: {
  47 + span: 12,
  48 + },
  49 + });
  50 +
  51 + const getFormValues = () => {
  52 + return getFieldsValue();
  53 + };
  54 +
  55 + const setFormValues = (data: Recordable) => {
  56 + return setFieldsValue(data);
  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 { CreateComponentType } from '/@/views/visual/packages/index.type';
  3 + import { BasicForm, useForm } from '/@/components/Form';
  4 + import { dataSourceSchema } from '/@/views/visual/board/detail/config/basicConfiguration';
  5 + import {
  6 + PublicComponentValueType,
  7 + PublicFormInstaceType,
  8 + } from '/@/views/visual/dataSourceBindPanel/index.type';
  9 +
  10 + const props = 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: dataSourceSchema(false, props.componentConfig.componentConfig.key),
  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('RectFlowmeter');
  5 +
  6 +export const RectFlowmeteConfig: ConfigType = {
  7 + ...componentKeys,
  8 + title: '流量计1',
  9 + package: PackagesCategoryEnum.FLOWMETER,
  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 { computed } from 'vue';
  6 + import { ref } from 'vue';
  7 + import { unref } from 'vue';
  8 +
  9 + const props = defineProps<{
  10 + config: ComponentPropsConfigType<typeof option>;
  11 + }>();
  12 +
  13 + const currentValue = ref(0);
  14 +
  15 + const getDesign = computed(() => {
  16 + const { option, persetOption } = props.config;
  17 + const { componentInfo } = option;
  18 + const { flowmeterConfig, unit } = componentInfo;
  19 + const { backgroundColor, waveFirst, waveSecond, waveThird } = flowmeterConfig || {};
  20 + const { flowmeterConfig: presetFlowmeterConfig, unit: persetUnit } = persetOption || {};
  21 + const {
  22 + backgroundColor: presetBackgroundColor,
  23 + waveFirst: presetWaveFirst,
  24 + waveSecond: presetWaveSecond,
  25 + waveThird: presetWaveThird,
  26 + } = presetFlowmeterConfig || {};
  27 + return {
  28 + backgroundColor: backgroundColor ?? presetBackgroundColor,
  29 + waveFirst: waveFirst ?? presetWaveFirst,
  30 + waveSecond: waveSecond ?? presetWaveSecond,
  31 + waveThird: waveThird ?? presetWaveThird,
  32 + unit: unit ?? persetUnit,
  33 + };
  34 + });
  35 +
  36 + const getWaveHeight = computed(() => {
  37 + const value = unref(currentValue);
  38 + return value <= 0 ? 0 : -value - 15;
  39 + });
  40 +
  41 + const getHeight = computed(() => {
  42 + const value = unref(currentValue);
  43 + return value >= 100 ? 0 : 100 - value + 10;
  44 + });
  45 +
  46 + const updateFn: DataFetchUpdateFn = (message, attribute) => {
  47 + const { data = {} } = message;
  48 + const [latest] = data[attribute] || [];
  49 + const [_, value] = latest;
  50 + currentValue.value = Number(value);
  51 + };
  52 +
  53 + useDataFetch(props, updateFn);
  54 +</script>
  55 +
  56 +<template>
  57 + <main class="w-full h-full flex flex-col justify-center items-center">
  58 + <svg
  59 + class="waves-rect"
  60 + viewBox="0 0 100 100"
  61 + preserveAspectRatio="none"
  62 + xmlns="http://www.w3.org/2000/svg"
  63 + xmlns:xlink="http://www.w3.org/1999/xlink"
  64 + >
  65 + <defs>
  66 + <path
  67 + id="wave"
  68 + d="M-160 118c30 0 58-18 88-18s 58 18 88 18 58-18 88-18 58 18 88 18 v100h-352z"
  69 + />
  70 + </defs>
  71 + <rect
  72 + class="bgColor"
  73 + x="0"
  74 + y="0"
  75 + width="100"
  76 + height="100"
  77 + :fill="getDesign.backgroundColor"
  78 + />
  79 + <g class="height" :transform="`translate(0 ${getWaveHeight})`">
  80 + <use class="wave waveFirst" xlink:href="#wave" :fill="getDesign.waveFirst" x="0" y="0" />
  81 + <use class="wave waveSecond" xlink:href="#wave" :fill="getDesign.waveSecond" x="0" y="2" />
  82 + <use class="wave waveThird" xlink:href="#wave" :fill="getDesign.waveThird" x="0" y="4" />
  83 + </g>
  84 + <rect
  85 + class="waveThird"
  86 + :transform="`translate(0 ${getHeight})`"
  87 + x="0"
  88 + y="0"
  89 + width="100"
  90 + height="100"
  91 + :fill="getDesign.waveThird"
  92 + />
  93 +
  94 + <foreignObject
  95 + x="0"
  96 + y="0"
  97 + width="100"
  98 + height="100"
  99 + text-anchor="middle"
  100 + dominant-baseline="middle"
  101 + >
  102 + <div xmlns="http://www.w3.org/1999/xhtml" class="text">
  103 + <span>{{ currentValue }}</span>
  104 + <span class="ml-1">{{ getDesign.unit }}</span>
  105 + </div>
  106 + </foreignObject>
  107 + </svg>
  108 + </main>
  109 +</template>
  110 +
  111 +<style lang="less" scoped>
  112 + .waves-rect {
  113 + width: 90%;
  114 + height: 90%;
  115 + }
  116 +
  117 + @keyframes move {
  118 + from {
  119 + transform: translate(-90px, 0%);
  120 + }
  121 +
  122 + to {
  123 + transform: translate(85px, 0%);
  124 + }
  125 + }
  126 +
  127 + .wave {
  128 + animation: move 3s linear infinite;
  129 + animation-play-state: running;
  130 + }
  131 +
  132 + .wave:nth-child(1) {
  133 + animation-delay: -2s;
  134 + animation-duration: 9s;
  135 + }
  136 +
  137 + .wave:nth-child(2) {
  138 + animation-delay: -4s;
  139 + animation-duration: 6s;
  140 + }
  141 +
  142 + .wave:nth-child(3) {
  143 + animation-delay: -6s;
  144 + animation-duration: 3s;
  145 + }
  146 +
  147 + .waves-rect > g + rect {
  148 + // transform: translateY(
  149 + // calc(calc(100 - var(--value)) * var(--full-flag) * 1% + var(--full-flag) * 15%)
  150 + // );
  151 + transition: transform linear 1s;
  152 + }
  153 +
  154 + .height {
  155 + // transform: translateY(calc(var(--value) * -1% - 10% + var(--over-min-flag) * 10%));
  156 + transition: transform linear 1s;
  157 + }
  158 +
  159 + .waves-rect .text {
  160 + display: flex;
  161 + justify-content: center;
  162 + align-items: center;
  163 + width: 100%;
  164 + height: 100%;
  165 + color: #fff;
  166 + font-weight: 700;
  167 + }
  168 +</style>
... ...
  1 +import { RectFlowmeteConfig } from './RectFlowmeter';
  2 +
  3 +export const FlowmeterList = [RectFlowmeteConfig];
... ...
... ... @@ -11,4 +11,10 @@ export enum ComponentConfigFieldEnum {
11 11 THIRD_PHASE_VALUE = 'thirdPhaseValue',
12 12 SHOW_DEVICE_NAME = 'showDeviceName',
13 13 GRADIENT_INFO = 'gradientInfo',
  14 +
  15 + FLOWMETER_CONFIG = 'flowmeterConfig',
  16 + WAVE_FIRST = 'waveFirst',
  17 + WAVE_SECOND = 'waveSecond',
  18 + WAVE_THIRD = 'waveThird',
  19 + BACKGROUND_COLOR = 'backgroundColor',
14 20 }
... ...
1   -import { ComponentInfoGradientInfoType, DataSource } from '../palette/types';
  1 +import { ComponentInfoGradientInfoType, DataSource, FlowmeterConfigType } from '../palette/types';
2 2 import { ComponentConfigFieldEnum } from './enum';
3 3
4 4 /**
... ... @@ -19,6 +19,8 @@ export enum PackagesCategoryNameEnum {
19 19 PICTURE = '图片组件',
20 20 CONTROL = '控制组件',
21 21 MAP = '地图组件',
  22 + FLOWMETER = '流量计',
  23 + OTHER = '其他',
22 24 }
23 25
24 26 /**
... ... @@ -30,6 +32,8 @@ export enum PackagesCategoryEnum {
30 32 PICTURE = 'PICTURE',
31 33 CONTROL = 'CONTROL',
32 34 MAP = 'MAP',
  35 + FLOWMETER = 'FLOWMETER',
  36 + OTHER = 'FLOWMETER',
33 37 }
34 38
35 39 /**
... ... @@ -90,6 +94,7 @@ export interface PublicPresetOptions {
90 94 [ComponentConfigFieldEnum.ICON]?: string;
91 95 [ComponentConfigFieldEnum.SHOW_DEVICE_NAME]?: boolean;
92 96 [ComponentConfigFieldEnum.GRADIENT_INFO]?: ComponentInfoGradientInfoType[];
  97 + [ComponentConfigFieldEnum.FLOWMETER_CONFIG]?: FlowmeterConfigType;
93 98 [key: string]: any;
94 99 }
95 100
... ... @@ -114,6 +119,8 @@ export interface PackagesType {
114 119 [PackagesCategoryEnum.INSTRUMENT]: ConfigType[];
115 120 [PackagesCategoryEnum.CONTROL]: ConfigType[];
116 121 [PackagesCategoryEnum.MAP]: ConfigType[];
  122 + [PackagesCategoryEnum.FLOWMETER]: ConfigType[];
  123 + [PackagesCategoryEnum.OTHER]: ConfigType[];
117 124 }
118 125
119 126 export interface SubscribeMessageType {
... ...
1 1 import { ControlList } from './components/Control';
  2 +import { FlowmeterList } from './components/Flowmeter';
2 3 import { InstrumentList } from './components/Instrument';
3 4 import { MapList } from './components/Map';
4 5 import { PictureList } from './components/Picture';
... ... @@ -11,4 +12,5 @@ export const packageList: PackagesType = {
11 12 [PackagesCategoryEnum.PICTURE]: PictureList,
12 13 [PackagesCategoryEnum.CONTROL]: ControlList,
13 14 [PackagesCategoryEnum.MAP]: MapList,
  15 + [PackagesCategoryEnum.FLOWMETER]: FlowmeterList,
14 16 };
... ...
... ... @@ -38,6 +38,13 @@ export interface ComponentInfoGradientInfoType {
38 38 color: string;
39 39 }
40 40
  41 +export interface FlowmeterConfigType {
  42 + backgroundColor: string;
  43 + waveFirst: string;
  44 + waveSecond: string;
  45 + waveThird: string;
  46 +}
  47 +
41 48 export interface ComponentInfo {
42 49 fontColor: string;
43 50 unit: string;
... ... @@ -45,6 +52,7 @@ export interface ComponentInfo {
45 52 iconColor: string;
46 53 showDeviceName: boolean;
47 54 gradientInfo: ComponentInfoGradientInfoType[];
  55 + flowmeterConfig: FlowmeterConfigType;
48 56 }
49 57
50 58 export interface CustomCommand {
... ...