Showing
9 changed files
with
137 additions
and
109 deletions
src/views/data/board/components/Dashboard/BaseDashboard.vue
deleted
100644 → 0
1 | -<script lang="ts" setup> | |
2 | - import type { ECharts, EChartsOption } from 'echarts'; | |
3 | - import type { PropType } from 'vue'; | |
4 | - import { nextTick, onMounted, onUnmounted, ref, unref } from 'vue'; | |
5 | - import { init } from 'echarts'; | |
6 | - | |
7 | - interface DataSource { | |
8 | - id: string | number; | |
9 | - } | |
10 | - | |
11 | - const props = defineProps({ | |
12 | - dataSource: { | |
13 | - type: Object as PropType<DataSource>, | |
14 | - required: true, | |
15 | - }, | |
16 | - chartOption: { | |
17 | - type: Object as PropType<EChartsOption>, | |
18 | - // required: true, | |
19 | - }, | |
20 | - add: { | |
21 | - type: Function, | |
22 | - required: true, | |
23 | - }, | |
24 | - }); | |
25 | - | |
26 | - const getControlsWidgetId = () => `widget-chart-${props.dataSource.id}`; | |
27 | - | |
28 | - const chartRef = ref<Nullable<ECharts>>(null); | |
29 | - | |
30 | - function initChart() { | |
31 | - const chartDom = document.getElementById(getControlsWidgetId())!; | |
32 | - chartRef.value = init(chartDom); | |
33 | - const option: EChartsOption = props.chartOption || { | |
34 | - tooltip: { | |
35 | - trigger: 'item', | |
36 | - // confine: true, | |
37 | - extraCssText: 'position: fixed;', | |
38 | - position: (point, params, dom, rect, size) => { | |
39 | - const parentEl = (dom as HTMLDivElement).parentElement!; | |
40 | - | |
41 | - const { top = 0, left = 0 } = parentEl.getBoundingClientRect()!; | |
42 | - return [left, top]; | |
43 | - }, | |
44 | - }, | |
45 | - series: [ | |
46 | - { | |
47 | - name: 'Access From', | |
48 | - type: 'pie', | |
49 | - radius: '50%', | |
50 | - data: [ | |
51 | - { value: 1048, name: 'Search Engine' }, | |
52 | - { value: 735, name: 'Direct' }, | |
53 | - { value: 580, name: 'Email' }, | |
54 | - { value: 484, name: 'Union Ads' }, | |
55 | - { value: 300, name: 'Video Ads' }, | |
56 | - ], | |
57 | - emphasis: { | |
58 | - itemStyle: { | |
59 | - shadowBlur: 10, | |
60 | - shadowOffsetX: 0, | |
61 | - shadowColor: 'rgba(0, 0, 0, 0.5)', | |
62 | - }, | |
63 | - }, | |
64 | - }, | |
65 | - ], | |
66 | - }; | |
67 | - | |
68 | - nextTick(() => { | |
69 | - option && unref(chartRef)?.setOption(option); | |
70 | - }); | |
71 | - } | |
72 | - | |
73 | - function update() { | |
74 | - unref(chartRef)?.resize(); | |
75 | - } | |
76 | - | |
77 | - onMounted(() => { | |
78 | - initChart(); | |
79 | - props.add(props.dataSource.id, update); | |
80 | - }); | |
81 | - | |
82 | - onUnmounted(() => { | |
83 | - unref(chartRef)?.clear(); | |
84 | - }); | |
85 | - | |
86 | - defineExpose({ update }); | |
87 | -</script> | |
88 | - | |
89 | -<template> | |
90 | - <div :id="getControlsWidgetId()" class="widget-charts"></div> | |
91 | -</template> | |
92 | - | |
93 | -<style scoped> | |
94 | - .widget-charts { | |
95 | - min-width: 10px; | |
96 | - min-height: 10px; | |
97 | - width: 100%; | |
98 | - height: 100%; | |
99 | - } | |
100 | - | |
101 | - .widget-charts > div { | |
102 | - width: 100%; | |
103 | - height: 100%; | |
104 | - } | |
105 | -</style> |
1 | +<script lang="ts" setup> | |
2 | + import { computed } from 'vue'; | |
3 | + import { Tooltip, Image } from 'ant-design-vue'; | |
4 | + import { | |
5 | + DEFAULT_DATE_FORMAT, | |
6 | + DEFAULT_RADIO_RECORD, | |
7 | + fontSize, | |
8 | + RadioRecord, | |
9 | + } from '../../detail/config/util'; | |
10 | + import { PictureComponentLayout, PictureComponentValue } from './pictureComponent.config'; | |
11 | + import { dateUtil } from '/@/utils/dateUtil'; | |
12 | + | |
13 | + const props = defineProps<{ | |
14 | + layout: PictureComponentLayout; | |
15 | + value: PictureComponentValue; | |
16 | + radio: RadioRecord; | |
17 | + }>(); | |
18 | + | |
19 | + const fallback = | |
20 | + 'data:image/png;base64,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'; | |
21 | + | |
22 | + const getRadio = computed(() => { | |
23 | + const { radio } = props.radio || DEFAULT_RADIO_RECORD; | |
24 | + console.log(props.radio); | |
25 | + return radio; | |
26 | + }); | |
27 | + | |
28 | + const getWidth = computed(() => { | |
29 | + const marign = 5; | |
30 | + const { width = 180 } = props.radio || {}; | |
31 | + return width - 5; | |
32 | + }); | |
33 | +</script> | |
34 | + | |
35 | +<template> | |
36 | + <section class="w-full h-full flex flex-col justify-center items-center"> | |
37 | + <Image :width="getWidth" :src="props?.value?.value || ''" :fallback="fallback" /> | |
38 | + <div | |
39 | + class="w-full text-center text-gray-400 truncate" | |
40 | + :style="{ fontSize: fontSize({ radio: getRadio, basic: 12, max: 16 }) }" | |
41 | + > | |
42 | + <Tooltip | |
43 | + placement="topLeft" | |
44 | + :title="props?.value?.updateTime || dateUtil().format(DEFAULT_DATE_FORMAT)" | |
45 | + > | |
46 | + <span>更新时间:</span> | |
47 | + <span class="truncate"> | |
48 | + {{ props?.value?.updateTime || dateUtil().format(DEFAULT_DATE_FORMAT) }} | |
49 | + </span> | |
50 | + </Tooltip> | |
51 | + </div> | |
52 | + </section> | |
53 | +</template> | |
54 | + | |
55 | +<style scoped></style> | ... | ... |
1 | +import PictureComponent from './PictureComponent.vue'; | |
2 | + | |
3 | +import { PictureComponentType } from './pictureComponent.config'; | |
4 | +import { Component } from 'vue'; | |
5 | + | |
6 | +interface PictureComponentList { | |
7 | + id: PictureComponentType; | |
8 | + component: Component; | |
9 | +} | |
10 | +// { | |
11 | +// id: 'instrument-component-1', | |
12 | +// layout: { chartOption: instrumentComponent1() }, | |
13 | +// component: DashBoardComponent, | |
14 | +// value: { id: buildUUID() }, | |
15 | +// } | |
16 | +const pictureComponentList: PictureComponentList[] = [ | |
17 | + { | |
18 | + id: 'picture-component-1', | |
19 | + component: PictureComponent, | |
20 | + }, | |
21 | +]; | |
22 | + | |
23 | +export { PictureComponent, pictureComponentList }; | ... | ... |
1 | +import { DataComponentRecord, DataSource } from '/@/api/dataBoard/model'; | |
2 | + | |
3 | +export type PictureComponentType = 'picture-component-1'; | |
4 | + | |
5 | +export interface PictureComponentLayout {} | |
6 | + | |
7 | +export interface PictureComponentValue { | |
8 | + value?: string; | |
9 | + updateTime?: string; | |
10 | +} | |
11 | + | |
12 | +export const transformPictureConfig = ( | |
13 | + config: PictureComponentLayout, | |
14 | + record: DataComponentRecord, | |
15 | + dataSourceRecord: DataSource | |
16 | +) => { | |
17 | + return {}; | |
18 | +}; | ... | ... |
... | ... | @@ -4,13 +4,15 @@ |
4 | 4 | import { FormActionType, useForm } from '/@/components/Form'; |
5 | 5 | import { basicSchema, dataSourceSchema } from '../config/basicConfiguration'; |
6 | 6 | import BasicForm from '/@/components/Form/src/BasicForm.vue'; |
7 | - import { reactive, ref, shallowReactive, unref, nextTick, watch } from 'vue'; | |
7 | + import { ref, shallowReactive, unref, nextTick, watch } from 'vue'; | |
8 | 8 | import VisualOptionsModal from './VisualOptionsModal.vue'; |
9 | 9 | import { useModal } from '/@/components/Modal'; |
10 | 10 | import { buildUUID } from '/@/utils/uuid'; |
11 | 11 | import type { ComponentInfo, DataSource } from '/@/api/dataBoard/model'; |
12 | 12 | import { useMessage } from '/@/hooks/web/useMessage'; |
13 | 13 | import { DataBoardLayoutInfo } from '../../types/type'; |
14 | + import { FrontComponent } from '../config/help'; | |
15 | + import { computed } from '@vue/reactivity'; | |
14 | 16 | |
15 | 17 | type DataSourceFormEL = { [key: string]: Nullable<FormActionType> }; |
16 | 18 | |
... | ... | @@ -133,6 +135,10 @@ |
133 | 135 | }); |
134 | 136 | }; |
135 | 137 | |
138 | + const showSettingButton = computed(() => { | |
139 | + return props.frontId !== FrontComponent.PICTURE_COMPONENT_1; | |
140 | + }); | |
141 | + | |
136 | 142 | watch( |
137 | 143 | () => props.record, |
138 | 144 | () => { |
... | ... | @@ -183,6 +189,7 @@ |
183 | 189 | </Tooltip> |
184 | 190 | <Tooltip title="设置"> |
185 | 191 | <SettingOutlined |
192 | + v-show="showSettingButton" | |
186 | 193 | @click="handleSetting(item)" |
187 | 194 | class="cursor-pointer text-lg !leading-30px" |
188 | 195 | /> | ... | ... |
... | ... | @@ -4,6 +4,7 @@ |
4 | 4 | import TextComponent from '../../components/TextComponent/TextComponent.vue'; |
5 | 5 | import { textComponentConfig } from '../../components/TextComponent/config'; |
6 | 6 | import { instrumentComponentConfig } from '../../components/InstrumentComponent'; |
7 | + import { pictureComponentList } from '../../components/PictureComponent'; | |
7 | 8 | const props = defineProps<{ |
8 | 9 | value: string; |
9 | 10 | }>(); |
... | ... | @@ -35,7 +36,25 @@ |
35 | 36 | </template> |
36 | 37 | </List> |
37 | 38 | </Tabs.TabPane> |
38 | - <Tabs.TabPane key="2" tab="仪表组件"> | |
39 | + <Tabs.TabPane key="2" tab="图片组件"> | |
40 | + <List | |
41 | + :grid="{ gutter: 10, column: 3, xs: 3, sm: 3, md: 3, lg: 3, xl: 3, xxl: 3 }" | |
42 | + :data-source="pictureComponentList" | |
43 | + > | |
44 | + <template #renderItem="{ item }"> | |
45 | + <List.Item class="!flex !justify-center"> | |
46 | + <VisualWidgetSelect | |
47 | + :checked-id="props.value" | |
48 | + :control-id="item.id" | |
49 | + @change="handleCheck" | |
50 | + > | |
51 | + <component :is="item.component" /> | |
52 | + </VisualWidgetSelect> | |
53 | + </List.Item> | |
54 | + </template> | |
55 | + </List> | |
56 | + </Tabs.TabPane> | |
57 | + <Tabs.TabPane key="3" tab="仪表组件"> | |
39 | 58 | <List |
40 | 59 | :grid="{ gutter: 10, column: 3, xs: 3, sm: 3, md: 3, lg: 3, xl: 3, xxl: 3 }" |
41 | 60 | :data-source="instrumentComponentConfig" | ... | ... |
... | ... | @@ -10,6 +10,8 @@ import { |
10 | 10 | } from '../../components/TextComponent/config'; |
11 | 11 | import { DataComponentRecord, DataSource } from '/@/api/dataBoard/model'; |
12 | 12 | import DashBoardComponent from '../../components/InstrumentComponent/DashBoardComponent.vue'; |
13 | +import PictureComponent from '../../components/PictureComponent/PictureComponent.vue'; | |
14 | +import { transformPictureConfig } from '../../components/PictureComponent/pictureComponent.config'; | |
13 | 15 | import { WidgetComponentType } from './visualOptions'; |
14 | 16 | import { |
15 | 17 | DashboardComponentLayout, |
... | ... | @@ -27,6 +29,7 @@ export enum FrontComponent { |
27 | 29 | INSTRUMENT_COMPONENT_1 = 'instrument-component-1', |
28 | 30 | INSTRUMENT_COMPONENT_2 = 'instrument-component-2', |
29 | 31 | DIGITAL_DASHBOARD_COMPONENT = 'digital-dashboard-component', |
32 | + PICTURE_COMPONENT_1 = 'picture-component-1', | |
30 | 33 | } |
31 | 34 | |
32 | 35 | export interface ComponentConfig { |
... | ... | @@ -94,3 +97,9 @@ frontComponentMap.set(FrontComponent.DIGITAL_DASHBOARD_COMPONENT, { |
94 | 97 | ComponentConfig: {}, |
95 | 98 | transformConfig: transformDashboardComponentConfig, |
96 | 99 | }); |
100 | + | |
101 | +frontComponentMap.set(FrontComponent.PICTURE_COMPONENT_1, { | |
102 | + Component: PictureComponent, | |
103 | + ComponentConfig: {}, | |
104 | + transformConfig: transformPictureConfig, | |
105 | +}); | ... | ... |
1 | 1 | import { InstrumentComponentType } from '../../components/InstrumentComponent/dashBoardComponent.config'; |
2 | 2 | import { DigitalDashBoardComponentType } from '../../components/InstrumentComponent/digitalDashBoard.config'; |
3 | +import { PictureComponentType } from '../../components/PictureComponent/pictureComponent.config'; | |
3 | 4 | import { TextComponentType } from '../../components/TextComponent/config'; |
4 | 5 | import { FormSchema } from '/@/components/Form'; |
5 | 6 | |
6 | 7 | export type WidgetComponentType = |
7 | 8 | | TextComponentType |
8 | 9 | | InstrumentComponentType |
9 | - | DigitalDashBoardComponentType; | |
10 | + | DigitalDashBoardComponentType | |
11 | + | PictureComponentType; | |
10 | 12 | |
11 | 13 | export interface VisualOptionParams { |
12 | 14 | [visualOptionField.FONT_COLOR]: string; | ... | ... |