Commit e644b8dfb0db08a3fd6c50f0a183e6d2b79d4793

Authored by ww
1 parent 128a5ebd

wip: implement drag && drop save layou info

... ... @@ -53,6 +53,7 @@ export interface DataBoardList {
53 53 export interface GradientInfo {
54 54 value: number;
55 55 key: string;
  56 + color: string;
56 57 }
57 58
58 59 export interface ComponentInfo {
... ...
... ... @@ -27,7 +27,7 @@
27 27 function initChart() {
28 28 const chartDom = document.getElementById(getControlsWidgetId())!;
29 29 chartRef.value = init(chartDom);
30   - const option: EChartsOption = props.layout || instrumentComponent1();
  30 + const option: EChartsOption = props.layout.chartOption || instrumentComponent1();
31 31
32 32 nextTick(() => {
33 33 option && unref(chartRef)?.setOption(option);
... ... @@ -52,13 +52,15 @@
52 52
53 53 <template>
54 54 <div class="flex flex-col w-full h-full min-w-3 min-h-3">
55   - <div :id="getControlsWidgetId()" class="widget-charts w-full h-full"></div>
56   - <div>{{}}</div>
57   - <div class="text-xs text-center text-gray-400">
58   - <span>更新时间:</span>
59   - <span>
60   - {{ props.value.updateTime || dateUtil().format('YYYY-MM-DD HH:mm:ss') }}
61   - </span>
  55 + <div :id="getControlsWidgetId()" class="widget-charts flex-auto"></div>
  56 + <div>
  57 + <div class="text-center">{{ props.value.name }}</div>
  58 + <div class="text-xs text-center text-gray-400">
  59 + <span>更新时间:</span>
  60 + <span>
  61 + {{ props.value.updateTime || dateUtil().format('YYYY-MM-DD HH:mm:ss') }}
  62 + </span>
  63 + </div>
62 64 </div>
63 65 </div>
64 66 </template>
... ...
  1 +<script lang="ts" setup>
  2 + import { Image } from 'ant-design-vue';
  3 +
  4 + const props = defineProps<{
  5 + value: {
  6 + src: string;
  7 + };
  8 + }>();
  9 +</script>
  10 +
  11 +<template>
  12 + <section>
  13 + <Image
  14 + :src="
  15 + props?.value?.src ||
  16 + 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png'
  17 + "
  18 + />
  19 + </section>
  20 +</template>
  21 +
  22 +<style></style>
... ...
1 1 import { EChartsOption } from 'echarts';
2 2 import { visualOptionField } from '../../detail/config/visualOptions';
  3 +import { DataComponentRecord, DataSource } from '/@/api/dataBoard/model';
  4 +import { buildUUID } from '/@/utils/uuid';
3 5
4 6 export type InstrumentComponentType = 'instrument-component-1' | 'instrument-component-2';
5 7
... ... @@ -10,6 +12,7 @@ export type GradientKey =
10 12 | visualOptionField.SECOND_PHASE_VALUE
11 13 | visualOptionField.THIRD_PHASE_COLOR
12 14 | visualOptionField.THIRD_PHASE_VALUE;
  15 +
13 16 export interface GradientInfoRecord {
14 17 key: GradientKey;
15 18 value: number | string;
... ... @@ -24,6 +27,10 @@ export interface DashBoardValue {
24 27 gradientInfo?: GradientInfoRecord[];
25 28 }
26 29
  30 +export interface DashboardComponentLayout {
  31 + chartOption: EChartsOption;
  32 +}
  33 +
27 34 export const instrumentComponent1 = (params?: { value: number; unit: string }): EChartsOption => {
28 35 const { value = 10, unit = '°C' } = params || {};
29 36 return {
... ... @@ -214,3 +221,24 @@ export const instrumentComponent2 = (params?: {
214 221 export const getGradientValue = (key: GradientKey, record: GradientInfoRecord[]) => {
215 222 return record.find((item) => item.key === key)?.value;
216 223 };
  224 +
  225 +export const transformDashboardComponentConfig = (
  226 + config: DashboardComponentLayout,
  227 + record: DataComponentRecord,
  228 + dataSourceRecord: DataSource
  229 +) => {
  230 + return {
  231 + layout: {
  232 + chartOption: config,
  233 + } as DashboardComponentLayout,
  234 + value: {
  235 + id: buildUUID(),
  236 + name: dataSourceRecord.attributeRename || dataSourceRecord.attribute,
  237 + // value: record.va
  238 + unit: dataSourceRecord.componentInfo.unit,
  239 + updateTime: record.updateTime || record.createTime,
  240 + fontColor: dataSourceRecord.componentInfo.fontColor,
  241 + gradientInfo: dataSourceRecord.componentInfo.gradientInfo,
  242 + },
  243 + };
  244 +};
... ...
1   -export type DigitalDashBoardComponentType = 'digital-dashboard';
  1 +export type DigitalDashBoardComponentType = 'digital-dashboard-component';
2 2
3 3 export interface DigitalDashBoardLayout {
4 4 max: number;
... ...
  1 +import { EChartsOption } from 'echarts';
1 2 import { Component } from 'vue';
2 3 import { WidgetComponentType } from '../../detail/config/visualOptions';
3 4 import { instrumentComponent1, instrumentComponent2 } from './dashBoardComponent.config';
... ... @@ -5,9 +6,13 @@ import DashBoardComponent from './DashBoardComponent.vue';
5 6 import DigitalDashBoard from './DigitalDashBoard.vue';
6 7 import { buildUUID } from '/@/utils/uuid';
7 8
  9 +export interface DashboardComponentLayout {
  10 + chartOption: EChartsOption;
  11 +}
  12 +
8 13 interface InstrumentComponentConfig {
9 14 id: WidgetComponentType;
10   - layout: Recordable;
  15 + layout: DashboardComponentLayout;
11 16 component: Component;
12 17 value: Recordable;
13 18 }
... ... @@ -15,18 +20,18 @@ interface InstrumentComponentConfig {
15 20 export const instrumentComponentConfig: InstrumentComponentConfig[] = [
16 21 {
17 22 id: 'instrument-component-1',
18   - layout: instrumentComponent1(),
  23 + layout: { chartOption: instrumentComponent1() },
19 24 component: DashBoardComponent,
20 25 value: { id: buildUUID() },
21 26 },
22 27 {
23 28 id: 'instrument-component-2',
24   - layout: instrumentComponent2(),
  29 + layout: { chartOption: instrumentComponent2() },
25 30 component: DashBoardComponent,
26 31 value: { id: buildUUID() },
27 32 },
28 33 {
29   - id: 'digital-dashboard',
  34 + id: 'digital-dashboard-component',
30 35 layout: {},
31 36 component: DigitalDashBoard,
32 37 value: {},
... ...
... ... @@ -62,7 +62,7 @@
62 62 />
63 63 </div>
64 64 </div>
65   - <div v-if="getShowUpdate" class="h-6 text-center text-xs text-gray-400">
  65 + <div v-if="getShowUpdate" class="text-center text-xs text-gray-400">
66 66 <span> 更新时间: {{ props.value.updateTime }}</span>
67 67 </div>
68 68 </div>
... ...
... ... @@ -35,7 +35,7 @@
35 35 (record: DataBoardLayoutInfo & { isEdit: boolean }) => {
36 36 componentRecord.value = record;
37 37 frontId.value = record.record.frontId;
38   - isEdit.value = record.isEdit;
  38 + isEdit.value = record.isEdit || false;
39 39 }
40 40 );
41 41
... ...
1 1 <script lang="ts" setup>
2 2 import { ref, unref } from 'vue';
3   - import { WidgetComponentType, schemasMap } from '../config/visualOptions';
  3 + import {
  4 + WidgetComponentType,
  5 + schemasMap,
  6 + VisualOptionParams,
  7 + visualOptionField,
  8 + Gradient,
  9 + } from '../config/visualOptions';
4 10 import { useForm, BasicForm } from '/@/components/Form';
5 11 import { BasicModal, useModalInner } from '/@/components/Modal';
6 12 import { ComponentInfo } from '/@/api/dataBoard/model';
... ... @@ -29,13 +35,44 @@
29 35 const [register, { closeModal }] = useModalInner(
30 36 (data: { recordId: string; componentInfo: ComponentInfo }) => {
31 37 recordId.value = data.recordId;
32   - method.setFieldsValue(data.componentInfo || {});
  38 + console.log(data.componentInfo);
  39 + const gradientInfo = data.componentInfo.gradientInfo;
  40 + let gradientRecord = {};
  41 + if (gradientInfo && gradientInfo.length) {
  42 + const first = gradientInfo.find((item) => item.key === Gradient.FIRST);
  43 + const second = gradientInfo.find((item) => item.key === Gradient.SECOND);
  44 + const third = gradientInfo.find((item) => item.key === Gradient.THIRD);
  45 + gradientRecord = {
  46 + [visualOptionField.FIRST_PHASE_COLOR]: first?.color,
  47 + [visualOptionField.FIRST_PHASE_VALUE]: first?.value,
  48 + [visualOptionField.SECOND_PHASE_COLOR]: second?.color,
  49 + [visualOptionField.SECOND_PHASE_VALUE]: second?.value,
  50 + [visualOptionField.THIRD_PHASE_COLOR]: third?.color,
  51 + [visualOptionField.THIRD_PHASE_VALUE]: third?.value,
  52 + };
  53 + }
  54 +
  55 + method.setFieldsValue({ ...(data.componentInfo || {}), ...gradientRecord });
33 56 }
34 57 );
35 58
36 59 const handleGetValue = () => {
37 60 const value = method.getFieldsValue();
38   - emit('close', unref(recordId), value);
  61 + emit('close', unref(recordId), transformValue(value));
  62 + };
  63 +
  64 + const transformValue = (value: Partial<VisualOptionParams>) => {
  65 + return {
  66 + fontColor: value.fontColor || null,
  67 + icon: value.icon || null,
  68 + iconColor: value.iconColor || null,
  69 + unit: value.unit || null,
  70 + // gradientInfo: [
  71 + // { key: Gradient.FIRST, value: value.firstPhaseValue, color: value.firstPhaseColor },
  72 + // { key: Gradient.SECOND, value: value.secondPhaseValue, color: value.secondPhaseColor },
  73 + // { key: Gradient.THIRD, value: value.thirdPhaseValue, color: value.thirdPhaseColor },
  74 + // ],
  75 + };
39 76 };
40 77
41 78 const handleClose = () => {
... ... @@ -53,6 +90,12 @@
53 90 title="选项"
54 91 width="60%"
55 92 >
56   - <BasicForm @register="registerForm" :schemas="getSchemas" />
  93 + <BasicForm class="form" @register="registerForm" :schemas="getSchemas" />
57 94 </BasicModal>
58 95 </template>
  96 +
  97 +<style scoped>
  98 + .form:deep(.ant-input-number) {
  99 + width: 100%;
  100 + }
  101 +</style>
... ...
... ... @@ -9,21 +9,25 @@ import {
9 9 transformTextComponentConfig,
10 10 } from '../../components/TextComponent/config';
11 11 import { DataComponentRecord, DataSource } from '/@/api/dataBoard/model';
  12 +import DashBoardComponent from '../../components/InstrumentComponent/DashBoardComponent.vue';
  13 +import { WidgetComponentType } from './visualOptions';
  14 +import {
  15 + instrumentComponent1,
  16 + instrumentComponent2,
  17 + transformDashboardComponentConfig,
  18 +} from '../../components/InstrumentComponent/dashBoardComponent.config';
  19 +import DigitalDashBoard from '../../components/InstrumentComponent/DigitalDashBoard.vue';
12 20 export enum FrontComponent {
13 21 TEXT_COMPONENT_1 = 'text-component-1',
14 22 TEXT_COMPONENT_2 = 'text-component-2',
15 23 TEXT_COMPONENT_3 = 'text-component-3',
16 24 TEXT_COMPONENT_4 = 'text-component-4',
17 25 TEXT_COMPONENT_5 = 'text-component-5',
  26 + INSTRUMENT_COMPONENT_1 = 'instrument-component-1',
  27 + INSTRUMENT_COMPONENT_2 = 'instrument-component-2',
  28 + DIGITAL_DASHBOARD_COMPONENT = 'digital-dashboard-component',
18 29 }
19 30
20   -export type FrontComponentType =
21   - | 'text-component-1'
22   - | 'text-component-2'
23   - | 'text-component-3'
24   - | 'text-component-4'
25   - | 'text-component-5';
26   -
27 31 export interface ComponentConfig {
28 32 Component: Component;
29 33 ComponentConfig: Recordable;
... ... @@ -34,7 +38,7 @@ export interface ComponentConfig {
34 38 ) => Recordable;
35 39 }
36 40
37   -export const frontComponentMap = new Map<FrontComponentType, ComponentConfig>();
  41 +export const frontComponentMap = new Map<WidgetComponentType, ComponentConfig>();
38 42
39 43 frontComponentMap.set(FrontComponent.TEXT_COMPONENT_1, {
40 44 Component: TextComponent,
... ... @@ -65,3 +69,21 @@ frontComponentMap.set(FrontComponent.TEXT_COMPONENT_5, {
65 69 ComponentConfig: TextComponent5Config,
66 70 transformConfig: transformTextComponentConfig,
67 71 });
  72 +
  73 +frontComponentMap.set(FrontComponent.INSTRUMENT_COMPONENT_1, {
  74 + Component: DashBoardComponent,
  75 + ComponentConfig: instrumentComponent1(),
  76 + transformConfig: transformDashboardComponentConfig,
  77 +});
  78 +
  79 +frontComponentMap.set(FrontComponent.INSTRUMENT_COMPONENT_2, {
  80 + Component: DashBoardComponent,
  81 + ComponentConfig: instrumentComponent2(),
  82 + transformConfig: transformDashboardComponentConfig,
  83 +});
  84 +
  85 +frontComponentMap.set(FrontComponent.DIGITAL_DASHBOARD_COMPONENT, {
  86 + Component: DigitalDashBoard,
  87 + ComponentConfig: {},
  88 + transformConfig: transformDashboardComponentConfig,
  89 +});
... ...
... ... @@ -2,15 +2,31 @@ import { InstrumentComponentType } from '../../components/InstrumentComponent/da
2 2 import { DigitalDashBoardComponentType } from '../../components/InstrumentComponent/digitalDashBoard.config';
3 3 import { TextComponentType } from '../../components/TextComponent/config';
4 4 import { FormSchema } from '/@/components/Form';
5   -export enum defaultOptions {
6   - fontColor = '#rer',
7   -}
8 5
9 6 export type WidgetComponentType =
10 7 | TextComponentType
11 8 | InstrumentComponentType
12 9 | DigitalDashBoardComponentType;
13 10
  11 +export interface VisualOptionParams {
  12 + [visualOptionField.FONT_COLOR]: string;
  13 + [visualOptionField.UNIT]: string;
  14 + [visualOptionField.ICON_COLOR]: string;
  15 + [visualOptionField.ICON]: string;
  16 + [visualOptionField.FIRST_PHASE_COLOR]: string;
  17 + [visualOptionField.SECOND_PHASE_COLOR]: string;
  18 + [visualOptionField.THIRD_PHASE_COLOR]: string;
  19 + [visualOptionField.FIRST_PHASE_VALUE]: string;
  20 + [visualOptionField.SECOND_PHASE_VALUE]: string;
  21 + [visualOptionField.THIRD_PHASE_VALUE]: string;
  22 +}
  23 +
  24 +export enum Gradient {
  25 + FIRST = 'first',
  26 + SECOND = 'second',
  27 + THIRD = 'third',
  28 +}
  29 +
14 30 export enum visualOptionField {
15 31 FONT_COLOR = 'fontColor',
16 32 UNIT = 'unit',
... ... @@ -19,11 +35,9 @@ export enum visualOptionField {
19 35 FIRST_PHASE_COLOR = 'firstPhaseColor',
20 36 SECOND_PHASE_COLOR = 'secondPhaseColor',
21 37 THIRD_PHASE_COLOR = 'thirdPhaseColor',
22   - FOURTH_PHASE_COLOR = 'fourthPhaseColor',
23 38 FIRST_PHASE_VALUE = 'firstPhaseValue',
24 39 SECOND_PHASE_VALUE = 'secondPhaseValue',
25 40 THIRD_PHASE_VALUE = 'thirdPhaseValue',
26   - FOURTH_PHASE_VALUE = 'fourthPhaseValue',
27 41 }
28 42
29 43 export const modeOne: FormSchema[] = [
... ... @@ -94,9 +108,10 @@ export const modeThree: FormSchema[] = [
94 108 {
95 109 field: visualOptionField.FIRST_PHASE_VALUE,
96 110 label: '一阶段阀值',
97   - component: 'Input',
  111 + component: 'InputNumber',
98 112 componentProps: {
99 113 placeholder: '请输入一阶段阀值',
  114 + min: 0,
100 115 },
101 116 },
102 117 {
... ... @@ -108,9 +123,10 @@ export const modeThree: FormSchema[] = [
108 123 {
109 124 field: visualOptionField.SECOND_PHASE_VALUE,
110 125 label: '二阶段阀值',
111   - component: 'Input',
  126 + component: 'InputNumber',
112 127 componentProps: {
113 128 placeholder: '请输入二阶段阀值',
  129 + min: 0,
114 130 },
115 131 },
116 132 {
... ... @@ -122,9 +138,10 @@ export const modeThree: FormSchema[] = [
122 138 {
123 139 field: visualOptionField.THIRD_PHASE_VALUE,
124 140 label: '三阶段阀值',
125   - component: 'Input',
  141 + component: 'InputNumber',
126 142 componentProps: {
127 143 placeholder: '请输入三阶段阀值',
  144 + min: 0,
128 145 },
129 146 },
130 147 ];
... ... @@ -155,3 +172,4 @@ schemasMap.set('text-component-4', modeTwo);
155 172 schemasMap.set('text-component-4', modeTwo);
156 173 schemasMap.set('instrument-component-1', modeOne);
157 174 schemasMap.set('instrument-component-2', modeThree);
  175 +schemasMap.set('digital-dashboard-component', modeFour);
... ...
... ... @@ -16,7 +16,7 @@
16 16 } from '/@/api/dataBoard';
17 17 import { useRoute } from 'vue-router';
18 18 import { computed, unref } from '@vue/reactivity';
19   - import { DataComponentRecord, DataSource } from '/@/api/dataBoard/model';
  19 + import { DataComponentRecord, DataSource, Layout } from '/@/api/dataBoard/model';
20 20 import { frontComponentMap, FrontComponentType } from './config/help';
21 21 import { useMessage } from '/@/hooks/web/useMessage';
22 22 import { DataBoardLayoutInfo } from '../types/type';
... ... @@ -79,10 +79,13 @@
79 79 if (updateFn) updateFn();
80 80 });
81 81 }
  82 + const itemResize = (i: string, newH: number, newW: number, newHPx: number, newWPx: number) => {
  83 + updateSize(i, newH, newW, newHPx, newWPx);
  84 + };
82 85
83 86 const itemResized = (i: string, newH: number, newW: number, newHPx: number, newWPx: number) => {
  87 + handleSaveLayoutInfo();
84 88 updateSize(i, newH, newW, newHPx, newWPx);
85   - console.log({ newH, newW, newHPx, newWPx });
86 89 };
87 90
88 91 const itemContainerResized = (
... ... @@ -95,6 +98,11 @@
95 98 updateSize(i, newH, newW, newHPx, newWPx);
96 99 };
97 100
  101 + const itemMoved = (i: string) => {
  102 + handleSaveLayoutInfo();
  103 + updateCharts(i);
  104 + };
  105 +
98 106 const updateCharts = (i: string) => {
99 107 nextTick(() => {
100 108 const updateFn = widgetEl.get(i);
... ... @@ -126,6 +134,25 @@
126 134 openModal(true);
127 135 };
128 136
  137 + const handleSaveLayoutInfo = async () => {
  138 + try {
  139 + const layoutInfo = unref(dataBoardList).map((item) => {
  140 + return {
  141 + id: item.i,
  142 + h: item.h,
  143 + w: item.w,
  144 + x: item.x,
  145 + y: item.y,
  146 + } as Layout;
  147 + });
  148 +
  149 + await updateDataBoardLayout({
  150 + boardId: unref(getBoardId),
  151 + layout: layoutInfo,
  152 + });
  153 + } catch (error) {}
  154 + };
  155 +
129 156 const getDataBoardComponent = async () => {
130 157 try {
131 158 const data = await getDataComponent(unref(getBoardId));
... ... @@ -150,7 +177,6 @@
150 177 },
151 178 };
152 179 });
153   - console.log(unref(dataBoardList));
154 180 } catch (error) {}
155 181 };
156 182
... ... @@ -173,7 +199,6 @@
173 199
174 200 const handleCopy = async (id: string) => {
175 201 const record = unref(dataBoardList).find((item) => item.i === id);
176   - console.log({ record });
177 202 try {
178 203 const data = await addDataComponent({
179 204 boardId: unref(getBoardId),
... ... @@ -243,8 +268,8 @@
243 268 :style="{ display: 'flex', flexWrap: 'wrap' }"
244 269 class="grid-item-layout"
245 270 @resized="itemResized"
246   - @resize="itemResized"
247   - @moved="updateCharts"
  271 + @resize="itemResize"
  272 + @moved="itemMoved"
248 273 @container-resized="itemContainerResized"
249 274 >
250 275 <WidgetWrapper
... ...