Showing
10 changed files
with
621 additions
and
2 deletions
@@ -14,7 +14,9 @@ enum Api { | @@ -14,7 +14,9 @@ enum Api { | ||
14 | DEVICE_PROFILE = '/device_profile/me/list', | 14 | DEVICE_PROFILE = '/device_profile/me/list', |
15 | DEVICE = '/device', | 15 | DEVICE = '/device', |
16 | VIDEOURL = '/video/url/', | 16 | VIDEOURL = '/video/url/', |
17 | - GEOJSONURL = '/map/geo_json/' | 17 | + GEOJSONURL = '/map/geo_json/', |
18 | + DEVICE_URL = '/device', | ||
19 | + GET_ATTRBUTELIST = '/device/attributes/' | ||
18 | } | 20 | } |
19 | 21 | ||
20 | export const getDictItemByCode = (value: string) => { | 22 | export const getDictItemByCode = (value: string) => { |
@@ -113,3 +115,15 @@ export const getGeoJsonMap = (code: number, level: string) => | @@ -113,3 +115,15 @@ export const getGeoJsonMap = (code: number, level: string) => | ||
113 | defHttp.get({ | 115 | defHttp.get({ |
114 | url: `${Api.GEOJSONURL}${code}/${level}` | 116 | url: `${Api.GEOJSONURL}${code}/${level}` |
115 | }) | 117 | }) |
118 | + | ||
119 | +// 获取设备详情 | ||
120 | +export const getDeviceDetail = (id: string) => | ||
121 | + defHttp.get({ | ||
122 | + url: Api.DEVICE_URL + `/${id}` | ||
123 | + }) | ||
124 | + | ||
125 | +// 获取产品属性 | ||
126 | +export const getAttribute = (deviceProfileId: string) => | ||
127 | + defHttp.get({ | ||
128 | + url: `${Api.GET_ATTRBUTELIST}${deviceProfileId}` | ||
129 | + }) |
@@ -75,7 +75,7 @@ export const useChartDataFetch = ( | @@ -75,7 +75,7 @@ export const useChartDataFetch = ( | ||
75 | echartsUpdateHandle(value) | 75 | echartsUpdateHandle(value) |
76 | // 更新回调函数 | 76 | // 更新回调函数 |
77 | if (updateCallback) { | 77 | if (updateCallback) { |
78 | - updateCallback(value) | 78 | + updateCallback(value, targetComponent.request)//为了处理设备最新数据轮播列表,这里传过去当前组件的信息 |
79 | } | 79 | } |
80 | } catch (error) { | 80 | } catch (error) { |
81 | console.error(error) | 81 | console.error(error) |
@@ -49,6 +49,7 @@ export const useChartInteract = ( | @@ -49,6 +49,7 @@ export const useChartInteract = ( | ||
49 | Object.keys(item.interactFn).forEach(key => { | 49 | Object.keys(item.interactFn).forEach(key => { |
50 | if (Params.value[key]) { | 50 | if (Params.value[key]) { |
51 | Params.value[key] = param[item.interactFn[key]] | 51 | Params.value[key] = param[item.interactFn[key]] |
52 | + console.log(Params.value[key]) | ||
52 | } | 53 | } |
53 | if (Header.value[key]) { | 54 | if (Header.value[key]) { |
54 | Header.value[key] = param[item.interactFn[key]] | 55 | Header.value[key] = param[item.interactFn[key]] |
@@ -16,6 +16,7 @@ import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore | @@ -16,6 +16,7 @@ import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore | ||
16 | import { useChartInteract } from '@/hooks/external/useChartSelectInteract.hook' | 16 | import { useChartInteract } from '@/hooks/external/useChartSelectInteract.hook' |
17 | import { InteractEventOn } from '@/enums/eventEnum' | 17 | import { InteractEventOn } from '@/enums/eventEnum' |
18 | import { ComponentInteractParamsEnum } from './interact' | 18 | import { ComponentInteractParamsEnum } from './interact' |
19 | +import { useChartDataFetch } from '@/hooks' | ||
19 | 20 | ||
20 | const props = defineProps({ | 21 | const props = defineProps({ |
21 | chartConfig: { | 22 | chartConfig: { |
@@ -58,6 +59,11 @@ watch( | @@ -58,6 +59,11 @@ watch( | ||
58 | deep: true | 59 | deep: true |
59 | } | 60 | } |
60 | ) | 61 | ) |
62 | + | ||
63 | +// 数据更新 (默认更新 dataset,若更新之后有其它操作,可添加回调函数) 解决给另一个下拉框赋值 | ||
64 | +useChartDataFetch(props.chartConfig, useChartEditStore, (resData: any) => { | ||
65 | + option.value.dataset = resData | ||
66 | +}) | ||
61 | </script> | 67 | </script> |
62 | 68 | ||
63 | <style lang="scss" scoped> | 69 | <style lang="scss" scoped> |
1 | +import { PublicConfigClass } from '@/packages/public' | ||
2 | +import { CreateComponentType } from '@/packages/index.d' | ||
3 | +import { OverrideTableScrollBoardConfig } from './index' | ||
4 | +import cloneDeep from 'lodash/cloneDeep' | ||
5 | +import dataJson from './data.json' | ||
6 | + | ||
7 | +export const option = { | ||
8 | + header: ['列1', '列2', '列3'], | ||
9 | + dataset: dataJson, | ||
10 | + index: true, | ||
11 | + columnWidth: [30, 100, 100], | ||
12 | + align: ['center', 'right', 'right', 'right'], | ||
13 | + rowNum: 5, | ||
14 | + waitTime: 2, | ||
15 | + headerHeight: 35, | ||
16 | + carousel: 'single', | ||
17 | + headerBGC: '#00BAFF', | ||
18 | + oddRowBGC: '#003B51', | ||
19 | + evenRowBGC: '#0A2732' | ||
20 | +} | ||
21 | + | ||
22 | +export default class Config extends PublicConfigClass implements CreateComponentType { | ||
23 | + public key = OverrideTableScrollBoardConfig.key | ||
24 | + public chartConfig = cloneDeep(OverrideTableScrollBoardConfig) | ||
25 | + public option = cloneDeep(option) | ||
26 | +} |
1 | +<template> | ||
2 | + <CollapseItem name="列表" :expanded="true"> | ||
3 | + <SettingItemBox name="基础"> | ||
4 | + <SettingItem name="表行数"> | ||
5 | + <n-input-number | ||
6 | + v-model:value="optionData.rowNum" | ||
7 | + :min="1" | ||
8 | + size="small" | ||
9 | + placeholder="请输入自动计算" | ||
10 | + ></n-input-number> | ||
11 | + </SettingItem> | ||
12 | + <SettingItem name="轮播时间(s)"> | ||
13 | + <n-input-number | ||
14 | + v-model:value="optionData.waitTime" | ||
15 | + :min="1" | ||
16 | + size="small" | ||
17 | + placeholder="请输入轮播时间" | ||
18 | + ></n-input-number> | ||
19 | + </SettingItem> | ||
20 | + <SettingItem name="表头高度"> | ||
21 | + <n-input-number | ||
22 | + v-model:value="optionData.headerHeight" | ||
23 | + :min="1" | ||
24 | + size="small" | ||
25 | + placeholder="请输入表头高度" | ||
26 | + ></n-input-number> | ||
27 | + </SettingItem> | ||
28 | + <SettingItem name="显示行号"> | ||
29 | + <n-switch size="small" v-model:value="optionData.index" /> | ||
30 | + </SettingItem> | ||
31 | + </SettingItemBox> | ||
32 | + | ||
33 | + <SettingItemBox name="配置" :alone="true"> | ||
34 | + <SettingItem name="表头数据"> | ||
35 | + <n-input v-model:value="header" :min="1" size="small" placeholder="表头数据(英文','分割)"></n-input> | ||
36 | + </SettingItem> | ||
37 | + <SettingItem name="列对齐方式"> | ||
38 | + <n-input v-model:value="align" :min="1" size="small" placeholder="对齐方式(英文','分割)"></n-input> | ||
39 | + </SettingItem> | ||
40 | + <SettingItem name="列宽度"> | ||
41 | + <n-input v-model:value="columnWidth" :min="1" size="small" placeholder="列宽度(英文','分割)"></n-input> | ||
42 | + </SettingItem> | ||
43 | + <SettingItem name="轮播方式"> | ||
44 | + <n-select | ||
45 | + v-model:value="optionData.carousel" | ||
46 | + :options="[ | ||
47 | + { label: '单条轮播', value: 'single' }, | ||
48 | + { label: '整页轮播', value: 'page' }, | ||
49 | + ]" | ||
50 | + /> | ||
51 | + </SettingItem> | ||
52 | + </SettingItemBox> | ||
53 | + | ||
54 | + <SettingItemBox name="样式"> | ||
55 | + <SettingItem name="表头背景色"> | ||
56 | + <n-color-picker size="small" :modes="['hex']" v-model:value="optionData.headerBGC"></n-color-picker> | ||
57 | + </SettingItem> | ||
58 | + <SettingItem name="奇数行背景色"> | ||
59 | + <n-color-picker size="small" :modes="['hex']" v-model:value="optionData.oddRowBGC"></n-color-picker> | ||
60 | + </SettingItem> | ||
61 | + <SettingItem name="偶数行背景色"> | ||
62 | + <n-color-picker size="small" :modes="['hex']" v-model:value="optionData.evenRowBGC"></n-color-picker> | ||
63 | + </SettingItem> | ||
64 | + </SettingItemBox> | ||
65 | + </CollapseItem> | ||
66 | +</template> | ||
67 | + | ||
68 | +<script setup lang="ts"> | ||
69 | +import { PropType, ref, watch } from 'vue' | ||
70 | +import { CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting' | ||
71 | +import { option } from './config' | ||
72 | + | ||
73 | +const props = defineProps({ | ||
74 | + optionData: { | ||
75 | + type: Object as PropType<typeof option>, | ||
76 | + required: true | ||
77 | + } | ||
78 | +}) | ||
79 | + | ||
80 | +const header = ref() | ||
81 | +const align = ref() | ||
82 | +const columnWidth = ref() | ||
83 | + | ||
84 | +watch( | ||
85 | + () => props.optionData, | ||
86 | + newData => { | ||
87 | + header.value = props.optionData.header.toString() | ||
88 | + align.value = props.optionData.align.toString() | ||
89 | + columnWidth.value = props.optionData.columnWidth.toString() | ||
90 | + }, | ||
91 | + { | ||
92 | + deep: false, | ||
93 | + immediate: true | ||
94 | + } | ||
95 | +) | ||
96 | + | ||
97 | +watch([header, align, columnWidth], ([headerNew, alignNew, columnWidthNew], [headerOld, alignOld, columnWidthOld]) => { | ||
98 | + if (headerNew !== headerOld) { | ||
99 | + props.optionData.header = headerNew.split(',') | ||
100 | + } | ||
101 | + if (alignNew !== alignOld) { | ||
102 | + props.optionData.align = alignNew.split(',') | ||
103 | + } | ||
104 | + if (columnWidthNew !== columnWidthOld) { | ||
105 | + // @ts-ignore | ||
106 | + props.optionData.columnWidth = columnWidthNew.split(',') | ||
107 | + } | ||
108 | +}) | ||
109 | +</script> |
1 | +[ | ||
2 | + ["行1列1", "行1列2", "行1列3"], | ||
3 | + ["行2列1", "行2列2", "行2列3"], | ||
4 | + ["行3列1", "行3列2", "行3列3"], | ||
5 | + ["行4列1", "行4列2", "行4列3"], | ||
6 | + ["行5列1", "行5列2", "行5列3"], | ||
7 | + ["行6列1", "行6列2", "行6列3"], | ||
8 | + ["行7列1", "行7列2", "行7列3"], | ||
9 | + ["行8列1", "行8列2", "行8列3"], | ||
10 | + ["行9列1", "行9列2", "行9列3"], | ||
11 | + ["行10列1", "行10列2", "行10列3"] | ||
12 | +] |
1 | +import { ConfigType, PackagesCategoryEnum, ChartFrameEnum } from '@/packages/index.d' | ||
2 | +import { ChatCategoryEnum, ChatCategoryEnumName } from '@/packages/components/Tables/index.d' | ||
3 | +import { useWidgetKey } from '@/packages/external/useWidgetKey' | ||
4 | + | ||
5 | +const { key, conKey, chartKey } = useWidgetKey('OverrideTableScrollBoard', true) | ||
6 | + | ||
7 | +export const OverrideTableScrollBoardConfig: ConfigType = { | ||
8 | + key, | ||
9 | + chartKey, | ||
10 | + conKey, | ||
11 | + title: '设备最新数据轮播列表', | ||
12 | + category: ChatCategoryEnum.TABLE, | ||
13 | + categoryName: ChatCategoryEnumName.TABLE, | ||
14 | + package: PackagesCategoryEnum.TABLES, | ||
15 | + chartFrame: ChartFrameEnum.COMMON, | ||
16 | + image: 'table_scrollboard.png' | ||
17 | +} |
1 | +<template> | ||
2 | + <div class="dv-scroll-board"> | ||
3 | + <div | ||
4 | + class="header" | ||
5 | + v-if="status.header.length && status.mergedConfig" | ||
6 | + :style="`background-color: ${status.mergedConfig.headerBGC};`" | ||
7 | + > | ||
8 | + <div | ||
9 | + class="header-item" | ||
10 | + v-for="(headerItem, i) in status.header" | ||
11 | + :key="`${headerItem}${i}`" | ||
12 | + :style="` | ||
13 | + height: ${status.mergedConfig.headerHeight}px; | ||
14 | + line-height: ${status.mergedConfig.headerHeight}px; | ||
15 | + width: ${status.widths[i]}px; | ||
16 | + `" | ||
17 | + :align="status.aligns[i]" | ||
18 | + v-html="headerItem" | ||
19 | + /> | ||
20 | + </div> | ||
21 | + | ||
22 | + <div | ||
23 | + v-if="status.mergedConfig" | ||
24 | + class="rows" | ||
25 | + :style="`height: ${h - (status.header.length ? status.mergedConfig.headerHeight : 0)}px;`" | ||
26 | + > | ||
27 | + <div | ||
28 | + class="row-item" | ||
29 | + v-for="(row, ri) in status.rows" | ||
30 | + :key="`${row.toString()}${row.scroll}`" | ||
31 | + :style="` | ||
32 | + height: ${status.heights[ri]}px; | ||
33 | + line-height: ${status.heights[ri]}px; | ||
34 | + background-color: ${status.mergedConfig[row.rowIndex % 2 === 0 ? 'evenRowBGC' : 'oddRowBGC']}; | ||
35 | + `" | ||
36 | + > | ||
37 | + <div | ||
38 | + class="ceil" | ||
39 | + v-for="(ceil, ci) in row.ceils" | ||
40 | + :key="`${ceil}${ri}${ci}`" | ||
41 | + :style="`width: ${status.widths[ci]}px;`" | ||
42 | + :align="status.aligns[ci]" | ||
43 | + v-html="ceil" | ||
44 | + /> | ||
45 | + </div> | ||
46 | + </div> | ||
47 | + </div> | ||
48 | +</template> | ||
49 | + | ||
50 | +<script setup lang="ts"> | ||
51 | +import { PropType, onUnmounted, reactive, toRefs, watch, onMounted } from 'vue' | ||
52 | +import { CreateComponentType } from '@/packages/index.d' | ||
53 | +import { useChartDataFetch } from '@/hooks' | ||
54 | +import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore' | ||
55 | +import merge from 'lodash/merge' | ||
56 | +import cloneDeep from 'lodash/cloneDeep' | ||
57 | +import { getDeviceDetail, getAttribute } from '@/api/external/common/index' | ||
58 | + | ||
59 | +const props = defineProps({ | ||
60 | + chartConfig: { | ||
61 | + type: Object as PropType<CreateComponentType>, | ||
62 | + required: true | ||
63 | + } | ||
64 | +}) | ||
65 | + | ||
66 | +// 这里能拿到图表宽高等 | ||
67 | +const { w, h } = toRefs(props.chartConfig.attr) | ||
68 | +// 这里能拿到上面 config.ts 里的 option 数据 | ||
69 | +// const { rowNum, headerHeight, index, backgroundColor } = toRefs(props.chartConfig.option) | ||
70 | + | ||
71 | +const status = reactive({ | ||
72 | + defaultConfig: { | ||
73 | + /** | ||
74 | + * @description Board header | ||
75 | + * @type {Array<String>} | ||
76 | + * @default header = [] | ||
77 | + * @example header = ['column1', 'column2', 'column3'] | ||
78 | + */ | ||
79 | + header: [], | ||
80 | + /** | ||
81 | + * @description Board dataset | ||
82 | + * @type {Array<Array>} | ||
83 | + * @default dataset = [] | ||
84 | + */ | ||
85 | + dataset: [], | ||
86 | + /** | ||
87 | + * @description Row num | ||
88 | + * @type {Number} | ||
89 | + * @default rowNum = 5 | ||
90 | + */ | ||
91 | + rowNum: 5, | ||
92 | + /** | ||
93 | + * @description Header background color | ||
94 | + * @type {String} | ||
95 | + * @default headerBGC = '#00BAFF' | ||
96 | + */ | ||
97 | + headerBGC: '#00BAFF', | ||
98 | + /** | ||
99 | + * @description Odd row background color | ||
100 | + * @type {String} | ||
101 | + * @default oddRowBGC = '#003B51' | ||
102 | + */ | ||
103 | + oddRowBGC: '#003B51', | ||
104 | + /** | ||
105 | + * @description Even row background color | ||
106 | + * @type {String} | ||
107 | + * @default evenRowBGC = '#003B51' | ||
108 | + */ | ||
109 | + evenRowBGC: '#0A2732', | ||
110 | + /** | ||
111 | + * @description Scroll wait time | ||
112 | + * @type {Number} | ||
113 | + * @default waitTime = 2 | ||
114 | + */ | ||
115 | + waitTime: 2, | ||
116 | + /** | ||
117 | + * @description Header height | ||
118 | + * @type {Number} | ||
119 | + * @default headerHeight = 35 | ||
120 | + */ | ||
121 | + headerHeight: 35, | ||
122 | + /** | ||
123 | + * @description Column width | ||
124 | + * @type {Array<Number>} | ||
125 | + * @default columnWidth = [] | ||
126 | + */ | ||
127 | + columnWidth: [], | ||
128 | + /** | ||
129 | + * @description Column align | ||
130 | + * @type {Array<String>} | ||
131 | + * @default align = [] | ||
132 | + * @example align = ['left', 'center', 'right'] | ||
133 | + */ | ||
134 | + align: [], | ||
135 | + /** | ||
136 | + * @description Show index | ||
137 | + * @type {Boolean} | ||
138 | + * @default index = false | ||
139 | + */ | ||
140 | + index: false, | ||
141 | + /** | ||
142 | + * @description index Header | ||
143 | + * @type {String} | ||
144 | + * @default indexHeader = '#' | ||
145 | + */ | ||
146 | + indexHeader: '#', | ||
147 | + /** | ||
148 | + * @description Carousel type | ||
149 | + * @type {String} | ||
150 | + * @default carousel = 'single' | ||
151 | + * @example carousel = 'single' | 'page' | ||
152 | + */ | ||
153 | + carousel: 'single', | ||
154 | + /** | ||
155 | + * @description Pause scroll when mouse hovered | ||
156 | + * @type {Boolean} | ||
157 | + * @default hoverPause = true | ||
158 | + * @example hoverPause = true | false | ||
159 | + */ | ||
160 | + hoverPause: true | ||
161 | + }, | ||
162 | + mergedConfig: props.chartConfig.option, | ||
163 | + header: [], | ||
164 | + rowsData: [], | ||
165 | + rows: [ | ||
166 | + { | ||
167 | + ceils: [], | ||
168 | + rowIndex: 0, | ||
169 | + scroll: 0 | ||
170 | + } | ||
171 | + ], | ||
172 | + widths: [], | ||
173 | + heights: [0], | ||
174 | + avgHeight: 0, | ||
175 | + aligns: [], | ||
176 | + animationIndex: 0, | ||
177 | + animationHandler: 0, | ||
178 | + updater: 0, | ||
179 | + needCalc: false | ||
180 | +}) | ||
181 | + | ||
182 | +const calcData = () => { | ||
183 | + mergeConfig() | ||
184 | + calcHeaderData() | ||
185 | + calcRowsData() | ||
186 | + calcWidths() | ||
187 | + calcHeights() | ||
188 | + calcAligns() | ||
189 | + animation(true) | ||
190 | +} | ||
191 | + | ||
192 | +onMounted(() => { | ||
193 | + calcData() | ||
194 | +}) | ||
195 | + | ||
196 | +const mergeConfig = () => { | ||
197 | + status.mergedConfig = merge(cloneDeep(status.defaultConfig), props.chartConfig.option) | ||
198 | +} | ||
199 | + | ||
200 | +const calcHeaderData = () => { | ||
201 | + let { header, index, indexHeader } = status.mergedConfig | ||
202 | + if (!header.length) { | ||
203 | + status.header = [] | ||
204 | + return | ||
205 | + } | ||
206 | + header = [...header] | ||
207 | + if (index) header.unshift(indexHeader) | ||
208 | + status.header = header | ||
209 | +} | ||
210 | + | ||
211 | +const calcRowsData = () => { | ||
212 | + let { dataset, index, headerBGC, rowNum } = status.mergedConfig | ||
213 | + if (index) { | ||
214 | + dataset = dataset.map((row: any, i: number) => { | ||
215 | + row = [...row] | ||
216 | + const indexTag = `<span class="index" style="background-color: ${headerBGC};border-radius: 3px;padding: 0px 3px;">${ | ||
217 | + i + 1 | ||
218 | + }</span>` | ||
219 | + row.unshift(indexTag) | ||
220 | + return row | ||
221 | + }) | ||
222 | + } | ||
223 | + dataset = dataset.map((ceils: any, i: number) => ({ ceils, rowIndex: i })) | ||
224 | + const rowLength = dataset.length | ||
225 | + if (rowLength > rowNum && rowLength < 2 * rowNum) { | ||
226 | + dataset = [...dataset, ...dataset] | ||
227 | + } | ||
228 | + dataset = dataset.map((d: any, i: number) => ({ ...d, scroll: i })) | ||
229 | + | ||
230 | + status.rowsData = dataset | ||
231 | + status.rows = dataset | ||
232 | +} | ||
233 | + | ||
234 | +const calcWidths = () => { | ||
235 | + const { mergedConfig, rowsData } = status | ||
236 | + const { columnWidth, header } = mergedConfig | ||
237 | + const usedWidth = columnWidth.reduce((all: any, ws: number) => all + ws, 0) | ||
238 | + let columnNum = 0 | ||
239 | + if (rowsData[0]) { | ||
240 | + columnNum = (rowsData[0] as any).ceils.length | ||
241 | + } else if (header.length) { | ||
242 | + columnNum = header.length | ||
243 | + } | ||
244 | + const avgWidth = (w.value - usedWidth) / (columnNum - columnWidth.length) | ||
245 | + const widths = new Array(columnNum).fill(avgWidth) | ||
246 | + status.widths = merge(widths, columnWidth) | ||
247 | +} | ||
248 | + | ||
249 | +const calcHeights = (onresize = false) => { | ||
250 | + const { mergedConfig, header } = status | ||
251 | + const { headerHeight, rowNum, dataset } = mergedConfig | ||
252 | + let allHeight = h.value | ||
253 | + if (header.length) allHeight -= headerHeight | ||
254 | + const avgHeight = allHeight / rowNum | ||
255 | + status.avgHeight = avgHeight | ||
256 | + if (!onresize) status.heights = new Array(dataset.length).fill(avgHeight) | ||
257 | +} | ||
258 | + | ||
259 | +const calcAligns = () => { | ||
260 | + const { header, mergedConfig } = status | ||
261 | + | ||
262 | + const columnNum = header.length | ||
263 | + | ||
264 | + let aligns = new Array(columnNum).fill('left') | ||
265 | + | ||
266 | + const { align } = mergedConfig | ||
267 | + | ||
268 | + status.aligns = merge(aligns, align) | ||
269 | +} | ||
270 | + | ||
271 | +const animation = async (start = false) => { | ||
272 | + const { needCalc } = status | ||
273 | + | ||
274 | + if (needCalc) { | ||
275 | + calcRowsData() | ||
276 | + calcHeights() | ||
277 | + status.needCalc = false | ||
278 | + } | ||
279 | + let { avgHeight, animationIndex, mergedConfig, rowsData, updater } = status | ||
280 | + const { waitTime, carousel, rowNum } = mergedConfig | ||
281 | + | ||
282 | + const rowLength = rowsData.length | ||
283 | + if (rowNum >= rowLength) return | ||
284 | + if (start) { | ||
285 | + await new Promise(resolve => setTimeout(resolve, waitTime * 1000)) | ||
286 | + if (updater !== status.updater) return | ||
287 | + } | ||
288 | + const animationNum = carousel === 'single' ? 1 : rowNum | ||
289 | + let rows = rowsData.slice(animationIndex) | ||
290 | + rows.push(...rowsData.slice(0, animationIndex)) | ||
291 | + status.rows = rows.slice(0, carousel === 'page' ? rowNum * 2 : rowNum + 1) | ||
292 | + status.heights = new Array(rowLength).fill(avgHeight) | ||
293 | + await new Promise(resolve => setTimeout(resolve, 300)) | ||
294 | + if (updater !== status.updater) return | ||
295 | + status.heights.splice(0, animationNum, ...new Array(animationNum).fill(0)) | ||
296 | + animationIndex += animationNum | ||
297 | + const back = animationIndex - rowLength | ||
298 | + if (back >= 0) animationIndex = back | ||
299 | + status.animationIndex = animationIndex | ||
300 | + status.animationHandler = setTimeout(animation, waitTime * 1000 - 300) as any | ||
301 | +} | ||
302 | + | ||
303 | +const stopAnimation = () => { | ||
304 | + status.updater = (status.updater + 1) % 999999 | ||
305 | + if (!status.animationHandler) return | ||
306 | + clearTimeout(status.animationHandler) | ||
307 | +} | ||
308 | + | ||
309 | +const onRestart = async () => { | ||
310 | + try { | ||
311 | + if (!status.mergedConfig) return | ||
312 | + stopAnimation() | ||
313 | + calcData() | ||
314 | + } catch (error) { | ||
315 | + console.log(error) | ||
316 | + } | ||
317 | +} | ||
318 | + | ||
319 | +watch( | ||
320 | + () => w.value, | ||
321 | + () => { | ||
322 | + onRestart() | ||
323 | + } | ||
324 | +) | ||
325 | + | ||
326 | +watch( | ||
327 | + () => h.value, | ||
328 | + () => { | ||
329 | + onRestart() | ||
330 | + } | ||
331 | +) | ||
332 | + | ||
333 | +// 数据更新 | ||
334 | +watch( | ||
335 | + () => props.chartConfig.option, | ||
336 | + () => { | ||
337 | + onRestart() | ||
338 | + }, | ||
339 | + { deep: true } | ||
340 | +) | ||
341 | + | ||
342 | +// 数据更新 (默认更新 dataset,若更新之后有其它操作,可添加回调函数) | ||
343 | +//特殊处理 获取属性,把标识符转为物模型的属性名称 | ||
344 | +useChartDataFetch(props.chartConfig, useChartEditStore, async (resData: any[], res: any) => { | ||
345 | + const { requestParams } = res | ||
346 | + if (!requestParams) return | ||
347 | + const { Params } = requestParams | ||
348 | + if (!Params) return | ||
349 | + const { entityId } = Params | ||
350 | + const thingsModel = await handleDeviceProfileAttributes(entityId) | ||
351 | + const { attribute } = thingsModel as any | ||
352 | + const resDataFormat = resData.reduce((acc, curr) => { | ||
353 | + attribute.forEach((item: any) => { | ||
354 | + if (item.identifier === curr[0]) { | ||
355 | + curr[0] = item.name | ||
356 | + } | ||
357 | + }) | ||
358 | + acc.push(curr) | ||
359 | + return [...acc] | ||
360 | + }, []) | ||
361 | + props.chartConfig.option.dataset = resDataFormat | ||
362 | + onRestart() | ||
363 | +}) | ||
364 | + | ||
365 | +onUnmounted(() => { | ||
366 | + stopAnimation() | ||
367 | +}) | ||
368 | + | ||
369 | +const handleDeviceProfileAttributes = async (entityId: string) => { | ||
370 | + const deviceDetailRes = await getDeviceDetail(entityId) | ||
371 | + const { deviceProfileId } = deviceDetailRes | ||
372 | + if (!deviceProfileId) return | ||
373 | + const attributeRes = await getAttribute(deviceProfileId) | ||
374 | + const dataFormat = handleDataFormat(deviceDetailRes, attributeRes) | ||
375 | + return dataFormat | ||
376 | +} | ||
377 | + | ||
378 | +const handleDataFormat = (deviceDetail: any, attributes: any) => { | ||
379 | + const { name, tbDeviceId } = deviceDetail | ||
380 | + const attribute = attributes.map((item: any) => ({ | ||
381 | + identifier: item.identifier, | ||
382 | + name: item.name, | ||
383 | + detail: item.detail | ||
384 | + })) | ||
385 | + return { | ||
386 | + name, | ||
387 | + tbDeviceId, | ||
388 | + attribute | ||
389 | + } | ||
390 | +} | ||
391 | +</script> | ||
392 | + | ||
393 | +<style lang="scss" scoped> | ||
394 | +.dv-scroll-board { | ||
395 | + position: relative; | ||
396 | + width: 100%; | ||
397 | + height: 100%; | ||
398 | + color: #fff; | ||
399 | + | ||
400 | + .text { | ||
401 | + padding: 0 10px; | ||
402 | + box-sizing: border-box; | ||
403 | + white-space: nowrap; | ||
404 | + overflow: hidden; | ||
405 | + text-overflow: ellipsis; | ||
406 | + } | ||
407 | + | ||
408 | + .header { | ||
409 | + display: flex; | ||
410 | + flex-direction: row; | ||
411 | + font-size: 15px; | ||
412 | + | ||
413 | + .header-item { | ||
414 | + transition: all 0.3s; | ||
415 | + } | ||
416 | + } | ||
417 | + | ||
418 | + .rows { | ||
419 | + overflow: hidden; | ||
420 | + | ||
421 | + .row-item { | ||
422 | + display: flex; | ||
423 | + font-size: 14px; | ||
424 | + transition: all 0.3s; | ||
425 | + overflow: hidden; | ||
426 | + } | ||
427 | + } | ||
428 | +} | ||
429 | +</style> |
@@ -49,6 +49,7 @@ import { Decorates09Config } from '@/packages/components/external/Decorates/Deco | @@ -49,6 +49,7 @@ import { Decorates09Config } from '@/packages/components/external/Decorates/Deco | ||
49 | import { Decorates10Config } from '@/packages/components/external/Decorates/Decorates/Decorates10' | 49 | import { Decorates10Config } from '@/packages/components/external/Decorates/Decorates/Decorates10' |
50 | import { Decorates11Config } from '@/packages/components/external/Decorates/Decorates/Decorates11' | 50 | import { Decorates11Config } from '@/packages/components/external/Decorates/Decorates/Decorates11' |
51 | import { Decorates12Config } from '@/packages/components/external/Decorates/Decorates/Decorates12' | 51 | import { Decorates12Config } from '@/packages/components/external/Decorates/Decorates/Decorates12' |
52 | +import { OverrideTableScrollBoardConfig } from '@/packages/components/external/Tables/Tables/OverrideTableScrollBoard' | ||
52 | 53 | ||
53 | 54 | ||
54 | /** | 55 | /** |
@@ -112,6 +113,10 @@ export function useInjectLib(packagesList: EPackagesType) { | @@ -112,6 +113,10 @@ export function useInjectLib(packagesList: EPackagesType) { | ||
112 | addWidgetToCategoryByCategoryName(packagesList, PackagesCategoryEnum.CHARTS, OverrideWaterPoloConfig)//重写图表下的水球图 | 113 | addWidgetToCategoryByCategoryName(packagesList, PackagesCategoryEnum.CHARTS, OverrideWaterPoloConfig)//重写图表下的水球图 |
113 | addWidgetToCategoryByCategoryName(packagesList, PackagesCategoryEnum.CHARTS, OverrideDialConfig)//重写图表下的表盘 | 114 | addWidgetToCategoryByCategoryName(packagesList, PackagesCategoryEnum.CHARTS, OverrideDialConfig)//重写图表下的表盘 |
114 | // | 115 | // |
116 | + | ||
117 | + //列表 | ||
118 | + addWidgetToCategoryByCategoryName(packagesList, PackagesCategoryEnum.TABLES, OverrideTableScrollBoardConfig)//重写列表下的轮播列表 | ||
119 | + // | ||
115 | } | 120 | } |
116 | 121 | ||
117 | /** | 122 | /** |