Commit fc9dfeffcf2f00aa6d38c99ea6002618157ddd83

Authored by xp.Huang
2 parents bc97472f c602434a

Merge branch 'main_dev' into 'main'

Main dev

See merge request yunteng/thingskit-view!251
Showing 42 changed files with 812 additions and 95 deletions
@@ -21,6 +21,7 @@ enum Api { @@ -21,6 +21,7 @@ enum Api {
21 GET_ATTRBUTELIST = '/device/attributes/', 21 GET_ATTRBUTELIST = '/device/attributes/',
22 GET_DEVICE_LATEST = '/plugins/telemetry/DEVICE/', 22 GET_DEVICE_LATEST = '/plugins/telemetry/DEVICE/',
23 DEVICE_ATTR = '/device/attributes', 23 DEVICE_ATTR = '/device/attributes',
  24 + ALARM_LIST = '/alarm',
24 } 25 }
25 26
26 export const getDictItemByCode = (value: string) => { 27 export const getDictItemByCode = (value: string) => {
@@ -152,3 +153,10 @@ export const getProfileAttrs = (params: { deviceProfileId: string; dataType?: st @@ -152,3 +153,10 @@ export const getProfileAttrs = (params: { deviceProfileId: string; dataType?: st
152 params: { dataType }, 153 params: { dataType },
153 }); 154 });
154 }; 155 };
  156 +
  157 +//获取告警列表
  158 +export const getAlarmList = (params?: object) =>
  159 + defHttp.get({
  160 + url: Api.ALARM_LIST,
  161 + params
  162 + })
@@ -93,6 +93,7 @@ const extraValue = (object: Recordable) => { @@ -93,6 +93,7 @@ const extraValue = (object: Recordable) => {
93 } 93 }
94 94
95 const handleParams = (Params: Recordable) => { 95 const handleParams = (Params: Recordable) => {
  96 + Reflect.deleteProperty(Params, 'attrName')
96 if (Params.keys && Params?.keys?.length) { 97 if (Params.keys && Params?.keys?.length) {
97 // 过滤无效参数 98 // 过滤无效参数
98 Reflect.deleteProperty(Params, 'attrName') 99 Reflect.deleteProperty(Params, 'attrName')
@@ -164,6 +164,14 @@ @@ -164,6 +164,14 @@
164 <template #header> 164 <template #header>
165 <n-switch v-model:value="yAxis.show" size="small"></n-switch> 165 <n-switch v-model:value="yAxis.show" size="small"></n-switch>
166 </template> 166 </template>
  167 + <setting-item-box name="范围" v-if="yAxis.showRange">
  168 + <setting-item name="最小值" >
  169 + <n-input-number v-model:value="yAxis.min" size="small" min="0"></n-input-number>
  170 + </setting-item>
  171 + <setting-item name="最大值">
  172 + <n-input-number v-model:value="yAxis.max" size="small" min="0"></n-input-number>
  173 + </setting-item>
  174 + </setting-item-box>
167 <setting-item-box name="单位"> 175 <setting-item-box name="单位">
168 <setting-item name="名称"> 176 <setting-item name="名称">
169 <n-input v-model:value="yAxis.name" size="small"></n-input> 177 <n-input v-model:value="yAxis.name" size="small"></n-input>
@@ -290,11 +298,40 @@ @@ -290,11 +298,40 @@
290 </setting-item-box> 298 </setting-item-box>
291 </collapse-item> 299 </collapse-item>
292 300
  301 + <!-- 颜色 -->
  302 + <collapse-item name="颜色" expanded>
  303 + <n-card
  304 + v-for="(value, key) in chartCustomColor"
  305 + :key="key"
  306 + class="card-box"
  307 + size="small"
  308 + hoverable
  309 + embedded
  310 + >
  311 + <div class="go-flex-items-center">
  312 + <n-ellipsis style="text-align: left; width: 60px">{{ value?.name }} </n-ellipsis>
  313 + <span
  314 + class="theme-color-item"
  315 + v-for="colorItem in fetchShowColors(value!.color)"
  316 + :key="colorItem"
  317 + :style="{ backgroundColor: colorItem }"
  318 + ></span>
  319 + <div @click="createCustomColorHandle">
  320 + <n-icon size="18">
  321 + <add-icon></add-icon>
  322 + </n-icon>
  323 + </div>
  324 + </div>
  325 + <div class="theme-bottom" :style="{ backgroundImage: colorBackgroundImage(value!) }"></div>
  326 + </n-card>
  327 + <!-- 自定义颜色 modal -->
  328 + <create-color v-model:modelShow="createColorModelShow" :applicationGroup="applicationGroup"></create-color>
  329 + </collapse-item>
  330 +
293 <collapse-item v-if="visualMap" name="视觉映射"> 331 <collapse-item v-if="visualMap" name="视觉映射">
294 <template #header> 332 <template #header>
295 <n-switch v-model:value="visualMap.show" size="small"></n-switch> 333 <n-switch v-model:value="visualMap.show" size="small"></n-switch>
296 </template> 334 </template>
297 -  
298 <setting-item-box name="范围"> 335 <setting-item-box name="范围">
299 <setting-item name="最小值"> 336 <setting-item name="最小值">
300 <n-input-number v-model:value="visualMap.min" size="small"></n-input-number> 337 <n-input-number v-model:value="visualMap.min" size="small"></n-input-number>
@@ -336,15 +373,19 @@ @@ -336,15 +373,19 @@
336 </template> 373 </template>
337 374
338 <script setup lang="ts"> 375 <script setup lang="ts">
339 -import { PropType, computed, watch } from 'vue' 376 +import { PropType, computed, watch, ref } from 'vue'
340 import { GlobalThemeJsonType } from '@/settings/chartThemes/index' 377 import { GlobalThemeJsonType } from '@/settings/chartThemes/index'
341 import { axisConfig, legendConfig } from '@/packages/chartConfiguration/echarts/index' 378 import { axisConfig, legendConfig } from '@/packages/chartConfiguration/echarts/index'
342 import { CollapseItem, SettingItemBox, SettingItem, GlobalSettingPosition } from '@/components/Pages/ChartItemSetting' 379 import { CollapseItem, SettingItemBox, SettingItem, GlobalSettingPosition } from '@/components/Pages/ChartItemSetting'
343 import { icon } from '@/plugins' 380 import { icon } from '@/plugins'
344 import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore' 381 import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
345 import EchartsRendererSetting from './EchartsRendererSetting.vue' 382 import EchartsRendererSetting from './EchartsRendererSetting.vue'
  383 +import cloneDeep from 'lodash/cloneDeep'
  384 +import { loadAsyncComponent, colorCustomMerge } from '@/utils'
  385 +import { useDesignStore } from '@/store/modules/designStore/designStore'
  386 +import { useTargetData } from "@/views/chart/ContentConfigurations/components/hooks/useTargetData.hook"
346 387
347 -const { HelpOutlineIcon } = icon.ionicons5 388 +const { HelpOutlineIcon, AddIcon } = icon.ionicons5
348 389
349 const props = defineProps({ 390 const props = defineProps({
350 optionData: { 391 optionData: {
@@ -358,6 +399,10 @@ const props = defineProps({ @@ -358,6 +399,10 @@ const props = defineProps({
358 } 399 }
359 }) 400 })
360 401
  402 +const { targetData } = useTargetData()
  403 +
  404 +const CreateColor = loadAsyncComponent(() => import('@/views/chart/ContentConfigurations/components/CanvasPage/components/CreateColor/index.vue'))
  405 +
361 const chartEditStore = useChartEditStore() 406 const chartEditStore = useChartEditStore()
362 const themeSetting = computed(() => { 407 const themeSetting = computed(() => {
363 const chartThemeSetting = chartEditStore.getEditCanvasConfig.chartThemeSetting 408 const chartThemeSetting = chartEditStore.getEditCanvasConfig.chartThemeSetting
@@ -373,6 +418,13 @@ const xAxis = computed(() => { @@ -373,6 +418,13 @@ const xAxis = computed(() => {
373 }) 418 })
374 419
375 const yAxis = computed(() => { 420 const yAxis = computed(() => {
  421 + if((props.optionData?.yAxis as Recordable)){
  422 + if(!(props.optionData?.yAxis as Recordable).showRange) {
  423 + //针对横向柱状图和热力图
  424 + Reflect.deleteProperty((props.optionData.yAxis as Recordable),'min');
  425 + Reflect.deleteProperty((props.optionData.yAxis as Recordable),'max');
  426 + }
  427 + }
376 return props.optionData.yAxis 428 return props.optionData.yAxis
377 }) 429 })
378 430
@@ -401,4 +453,85 @@ watch(() => legend.value && legend.value.textStyle.color, (newVal) => { @@ -401,4 +453,85 @@ watch(() => legend.value && legend.value.textStyle.color, (newVal) => {
401 immediate: true, 453 immediate: true,
402 deep: true, 454 deep: true,
403 }) 455 })
  456 +
  457 +// 底色
  458 +const colorBackgroundImage = (item: { color: string[] }) => {
  459 + return `linear-gradient(to right, ${item.color[0]} 0%, ${item.color[5]} 100%)`
  460 +}
  461 +
  462 +// 获取用来展示的色号
  463 +const fetchShowColors = (colors: Array<string>) => {
  464 + return cloneDeep(colors).splice(0, 6)
  465 +}
  466 +
  467 +// 自定义颜色
  468 +const chartCustomColor = computed(() => {
  469 + const colorCustomMergeData = colorCustomMerge(chartEditStore.getEditCanvasConfig.chartCustomThemeColorInfo)
  470 + if(Reflect.has(targetData.value, 'colors')){
  471 + return {
  472 + 'chartCustom': targetData.value?.colors
  473 + }
  474 + } else {
  475 + return {
  476 + 'chartCustom': colorCustomMergeData[chartEditStore.getEditCanvasConfig.chartThemeColor]
  477 + }
  478 + }
  479 +})
  480 +
  481 +// 全局颜色
  482 +const designStore = useDesignStore()
  483 +
  484 +// 颜色
  485 +const themeColor = computed(() => {
  486 + return designStore.getAppTheme
  487 +})
  488 +
  489 +const createColorModelShow = ref(false)
  490 +
  491 +const applicationGroup = ref(false)
  492 +
  493 +const createCustomColorHandle = () => {
  494 + createColorModelShow.value = true
  495 + applicationGroup.value = true
  496 +}
404 </script> 497 </script>
  498 +
  499 +<style lang="scss" scoped>
  500 +$radius: 10px;
  501 +$itemRadius: 6px;
  502 +
  503 +.card-box {
  504 + cursor: pointer;
  505 + margin-top: 15px;
  506 + padding: 0;
  507 + @include fetch-bg-color('background-color4-shallow');
  508 + border-radius: $radius;
  509 + overflow: hidden;
  510 +
  511 + &.selected {
  512 + border: 2px solid v-bind('themeColor');
  513 + border-bottom: 1px solid rgba(0, 0, 0, 0);
  514 + }
  515 + &:first-child {
  516 + margin-top: 5px;
  517 + }
  518 + .go-flex-items-center {
  519 + justify-content: space-between;
  520 + align-items: center;
  521 + margin-top: -4px;
  522 + }
  523 + .theme-color-item {
  524 + display: inline-block;
  525 + width: 20px;
  526 + height: 20px;
  527 + border-radius: $itemRadius;
  528 + }
  529 + .theme-bottom {
  530 + position: absolute;
  531 + left: 0;
  532 + bottom: 0px;
  533 + width: 100%;
  534 + height: 3px;
  535 + }
  536 +}
  537 +</style>
@@ -73,10 +73,11 @@ export const useChartDataFetch = ( @@ -73,10 +73,11 @@ export const useChartDataFetch = (
73 let endTsValue = null 73 let endTsValue = null
74 const {requestParams} = toRaw(targetComponent.request) 74 const {requestParams} = toRaw(targetComponent.request)
75 const {Params} = requestParams 75 const {Params} = requestParams
76 - const {entityType, startTs, endTs} = Params 76 + const {startTs, endTs, shortcutsSelect} = Params
77 let days = Math.ceil(((endTs as unknown as number) - (startTs as unknown as number)) / (1 * 60 * 60 * 24 * 1000)) 77 let days = Math.ceil(((endTs as unknown as number) - (startTs as unknown as number)) / (1 * 60 * 60 * 24 * 1000))
78 const ShortcutsDays = [1, 7, 30] 78 const ShortcutsDays = [1, 7, 30]
79 - if (entityType === 'DEVICE') { 79 + // shortcutsSelect为真
  80 + if (shortcutsSelect) {
80 //等于这三个,说明是从快捷选项里面选的 81 //等于这三个,说明是从快捷选项里面选的
81 if(ShortcutsDays.includes(days)) { 82 if(ShortcutsDays.includes(days)) {
82 days = days <= 2 ? 1 : days<= 8 ? 7 : 30 83 days = days <= 2 ? 1 : days<= 8 ? 7 : 30
@@ -85,12 +86,12 @@ export const useChartDataFetch = ( @@ -85,12 +86,12 @@ export const useChartDataFetch = (
85 endTsValue = dayjs().endOf('day').valueOf() 86 endTsValue = dayjs().endOf('day').valueOf()
86 ;(toRaw(targetComponent.request).requestParams.Params.startTs as unknown as number) = startTsValue as number 87 ;(toRaw(targetComponent.request).requestParams.Params.startTs as unknown as number) = startTsValue as number
87 ;(toRaw(targetComponent.request).requestParams.Params.endTs as unknown as number) = endTsValue 88 ;(toRaw(targetComponent.request).requestParams.Params.endTs as unknown as number) = endTsValue
88 - } else {  
89 - //否则,选择的是什么日期区间就是什么  
90 - (toRaw(targetComponent.request).requestParams.Params.startTs as unknown as number) = startTs as unknown as number  
91 - (toRaw(targetComponent.request).requestParams.Params.endTs as unknown as number) = endTs as unknown as number  
92 } 89 }
93 - } 90 + } else {
  91 + //否则,选择的是什么日期区间就是什么
  92 + (toRaw(targetComponent.request).requestParams.Params.startTs as unknown as number) = startTs as unknown as number
  93 + (toRaw(targetComponent.request).requestParams.Params.endTs as unknown as number) = endTs as unknown as number
  94 + }
94 const res = await customRequest(toRaw(targetComponent.request)) 95 const res = await customRequest(toRaw(targetComponent.request))
95 if (res) { 96 if (res) {
96 try { 97 try {
1 /** 1 /**
2 - * 重写select下拉框联动 2 + * 重写select下拉框联动(下拉选择和输入框共用此hook)
3 */ 3 */
4 import { toRefs } from 'vue' 4 import { toRefs } from 'vue'
5 import { CreateComponentType } from '@/packages/index.d' 5 import { CreateComponentType } from '@/packages/index.d'
@@ -13,7 +13,8 @@ export const useChartInteract = ( @@ -13,7 +13,8 @@ export const useChartInteract = (
13 chartConfig: CreateComponentType, 13 chartConfig: CreateComponentType,
14 useChartEditStore: ChartEditStoreType, 14 useChartEditStore: ChartEditStoreType,
15 param: { [T: string]: any }, 15 param: { [T: string]: any },
16 - interactEventOn: string 16 + interactEventOn: string,
  17 + attrNames?: string[]
17 ) => { 18 ) => {
18 const chartEditStore = useChartEditStore() 19 const chartEditStore = useChartEditStore()
19 const { interactEvents } = chartConfig.events 20 const { interactEvents } = chartConfig.events
@@ -34,12 +35,13 @@ export const useChartInteract = ( @@ -34,12 +35,13 @@ export const useChartInteract = (
34 if (groupItem.id === item.interactComponentId) { 35 if (groupItem.id === item.interactComponentId) {
35 const { Params, Header } = toRefs(groupItem.request.requestParams) 36 const { Params, Header } = toRefs(groupItem.request.requestParams)
36 Object.keys(item.interactFn).forEach(key => { 37 Object.keys(item.interactFn).forEach(key => {
37 - if (Params.value[key]) {  
38 - Params.value[key] = param[item.interactFn[key]]  
39 - }  
40 - if (Header.value[key]) {  
41 - Header.value[key] = param[item.interactFn[key]]  
42 - } 38 + Params.value[key] = decodeURIComponent(param[item.interactFn[key]])
  39 + if(Reflect.has(Params.value, 'attrName')) {
  40 + Params.value['attrName'] = attrNames as unknown as string // 修改联动选择,lengend未实时更新
  41 + }
  42 + if (key in Header.value) {
  43 + Header.value[key] = param[item.interactFn[key]]
  44 + }
43 }) 45 })
44 } 46 }
45 }) 47 })
@@ -56,12 +58,13 @@ export const useChartInteract = ( @@ -56,12 +58,13 @@ export const useChartInteract = (
56 } 58 }
57 // 59 //
58 Object.keys(item.interactFn).forEach(key => { 60 Object.keys(item.interactFn).forEach(key => {
59 - if (Params.value[key]) {  
60 - Params.value[key] = param[item.interactFn[key]]  
61 - }  
62 - if (Header.value[key]) {  
63 - Header.value[key] = param[item.interactFn[key]]  
64 - } 61 + Params.value[key] = decodeURIComponent(param[item.interactFn[key]])
  62 + if(Reflect.has(Params.value, 'attrName')) {
  63 + Params.value['attrName'] = attrNames as unknown as string // 修改联动选择,lengend未实时更新
  64 + }
  65 + if (key in Header.value) {
  66 + Header.value[key] = param[item.interactFn[key]]
  67 + }
65 }) 68 })
66 } 69 }
67 } 70 }
@@ -9,7 +9,7 @@ export const seriesItem = { @@ -9,7 +9,7 @@ export const seriesItem = {
9 type: 'bar', 9 type: 'bar',
10 barWidth: null, 10 barWidth: null,
11 label: { 11 label: {
12 - show: true, 12 + show: false,
13 position: 'right', 13 position: 'right',
14 color: '#fff', 14 color: '#fff',
15 fontSize: 12 15 fontSize: 12
@@ -33,6 +33,7 @@ export const option = { @@ -33,6 +33,7 @@ export const option = {
33 type: 'value' 33 type: 'value'
34 }, 34 },
35 yAxis: { 35 yAxis: {
  36 + showRange: false,
36 show: true, 37 show: true,
37 type: 'category' 38 type: 'category'
38 }, 39 },
@@ -51,7 +51,10 @@ use([DatasetComponent, CanvasRenderer, BarChart, GridComponent, TooltipComponent @@ -51,7 +51,10 @@ use([DatasetComponent, CanvasRenderer, BarChart, GridComponent, TooltipComponent
51 const replaceMergeArr = ref<string[]>() 51 const replaceMergeArr = ref<string[]>()
52 52
53 const option = computed(() => { 53 const option = computed(() => {
54 - return mergeTheme(props.chartConfig.option, props.themeSetting, includes) 54 + const mergeThemeData = mergeTheme(props.chartConfig.option, props.themeSetting, includes)
  55 + Reflect.deleteProperty(mergeThemeData.yAxis, 'min')
  56 + Reflect.deleteProperty(mergeThemeData.yAxis, 'max')
  57 + return mergeThemeData
55 }) 58 })
56 59
57 // dataset 无法变更条数的补丁 60 // dataset 无法变更条数的补丁
@@ -11,7 +11,7 @@ export const barSeriesItem = { @@ -11,7 +11,7 @@ export const barSeriesItem = {
11 type: 'bar', 11 type: 'bar',
12 barWidth: 15, 12 barWidth: 15,
13 label: { 13 label: {
14 - show: true, 14 + show: false,
15 position: 'top', 15 position: 'top',
16 color: '#fff', 16 color: '#fff',
17 fontSize: 12 17 fontSize: 12
@@ -26,7 +26,7 @@ export const lineSeriesItem = { @@ -26,7 +26,7 @@ export const lineSeriesItem = {
26 type: 'line', 26 type: 'line',
27 symbol: 'circle', 27 symbol: 'circle',
28 label: { 28 label: {
29 - show: true, 29 + show: false,
30 position: 'top', 30 position: 'top',
31 color: '#fff', 31 color: '#fff',
32 fontSize: 12 32 fontSize: 12
@@ -31,7 +31,7 @@ const options = { @@ -31,7 +31,7 @@ const options = {
31 smooth: false, 31 smooth: false,
32 symbolSize: 5, //设定实心点的大小 32 symbolSize: 5, //设定实心点的大小
33 label: { 33 label: {
34 - show: true, 34 + show: false,
35 position: 'top', 35 position: 'top',
36 color: '#fff', 36 color: '#fff',
37 fontSize: 12 37 fontSize: 12
@@ -15,6 +15,7 @@ export const option = { @@ -15,6 +15,7 @@ export const option = {
15 data: dataJson.xAxis 15 data: dataJson.xAxis
16 }, 16 },
17 yAxis: { 17 yAxis: {
  18 + showRange: false,
18 data: dataJson.yAxis 19 data: dataJson.yAxis
19 }, 20 },
20 visualMap: { 21 visualMap: {
@@ -52,7 +52,10 @@ use([ @@ -52,7 +52,10 @@ use([
52 ]) 52 ])
53 53
54 const option = computed(() => { 54 const option = computed(() => {
55 - return mergeTheme(props.chartConfig.option, props.themeSetting, includes) 55 + const mergeThemeData = mergeTheme(props.chartConfig.option, props.themeSetting, includes) as unknown as Recordable
  56 + Reflect.deleteProperty(mergeThemeData.yAxis, 'min')
  57 + Reflect.deleteProperty(mergeThemeData.yAxis, 'max')
  58 + return mergeThemeData
56 }) 59 })
57 60
58 const vChartRef = ref<typeof VChart>() 61 const vChartRef = ref<typeof VChart>()
@@ -3,7 +3,7 @@ @@ -3,7 +3,7 @@
3 <n-input :style="`width:${w}px;`" type="text" 3 <n-input :style="`width:${w}px;`" type="text"
4 v-model:value="option.value.dataset" 4 v-model:value="option.value.dataset"
5 placeholder="请输入" 5 placeholder="请输入"
6 - @change="onChange"> 6 + @update="onChange">
7 7
8 </n-input> 8 </n-input>
9 </div> 9 </div>
@@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@
13 import { PropType, toRefs, shallowReactive, watch } from 'vue' 13 import { PropType, toRefs, shallowReactive, watch } from 'vue'
14 import { CreateComponentType } from '@/packages/index.d' 14 import { CreateComponentType } from '@/packages/index.d'
15 import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore' 15 import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
16 -import { useChartInteract } from '@/hooks' 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 19
@@ -33,13 +33,14 @@ const option = shallowReactive({ @@ -33,13 +33,14 @@ const option = shallowReactive({
33 }) 33 })
34 34
35 const onChange = (v: string) => { 35 const onChange = (v: string) => {
36 - if(v == undefined) return; 36 + // if(v == undefined) return;
37 // 存储到联动数据 37 // 存储到联动数据
38 useChartInteract( 38 useChartInteract(
39 props.chartConfig, 39 props.chartConfig,
40 useChartEditStore, 40 useChartEditStore,
41 - { [ComponentInteractParamsEnum.DATA]: v },  
42 - InteractEventOn.CHANGE 41 + { [ComponentInteractParamsEnum.DATA]: encodeURIComponent(option.value.dataset) },
  42 + InteractEventOn.CHANGE,
  43 + []
43 ) 44 )
44 } 45 }
45 46
@@ -14,7 +14,7 @@ export const seriesItem = { @@ -14,7 +14,7 @@ export const seriesItem = {
14 type: 'bar', 14 type: 'bar',
15 barWidth: 15, 15 barWidth: 15,
16 label: { 16 label: {
17 - show: true, 17 + show: false,
18 position: 'top', 18 position: 'top',
19 color: '#fff', 19 color: '#fff',
20 fontSize: 12 20 fontSize: 12
@@ -112,8 +112,8 @@ watch( @@ -112,8 +112,8 @@ watch(
112 props.chartConfig.option.series.push(...seriesArr) 112 props.chartConfig.option.series.push(...seriesArr)
113 } 113 }
114 replaceMergeArr.value = ['series'] 114 replaceMergeArr.value = ['series']
  115 + useEchartsMapLegend(props.chartConfig, props.chartConfig.option.series)
115 nextTick(() => { 116 nextTick(() => {
116 - useEchartsMapLegend(props.chartConfig, props.chartConfig.option.series)  
117 replaceMergeArr.value = [] 117 replaceMergeArr.value = []
118 }) 118 })
119 } 119 }
@@ -245,8 +245,10 @@ const { vChartRef } = useChartDataFetch(props.chartConfig, useChartEditStore, ne @@ -245,8 +245,10 @@ const { vChartRef } = useChartDataFetch(props.chartConfig, useChartEditStore, ne
245 } 245 }
246 } 246 }
247 }) 247 })
248 - //  
249 - addPieInterval(newData) 248 + //动画为开启才执行动画
  249 + if (props.chartConfig.option.isCarousel) {
  250 + addPieInterval(newData)
  251 + }
250 updateVChart(newData) 252 updateVChart(newData)
251 }) 253 })
252 254
@@ -8,7 +8,7 @@ export const includes = ['legend', 'xAxis', 'yAxis', 'grid'] @@ -8,7 +8,7 @@ export const includes = ['legend', 'xAxis', 'yAxis', 'grid']
8 export const seriesItem = { 8 export const seriesItem = {
9 type: 'line', 9 type: 'line',
10 label: { 10 label: {
11 - show: true, 11 + show: false,
12 position: 'top', 12 position: 'top',
13 color: '#fff', 13 color: '#fff',
14 fontSize: 12 14 fontSize: 12
@@ -112,8 +112,8 @@ watch( @@ -112,8 +112,8 @@ watch(
112 props.chartConfig.option.series.push(...seriesArr) 112 props.chartConfig.option.series.push(...seriesArr)
113 } 113 }
114 replaceMergeArr.value = ['series'] 114 replaceMergeArr.value = ['series']
  115 + useEchartsMapLegend(props.chartConfig, props.chartConfig.option.series)
115 nextTick(() => { 116 nextTick(() => {
116 - useEchartsMapLegend(props.chartConfig, props.chartConfig.option.series)  
117 replaceMergeArr.value = [] 117 replaceMergeArr.value = []
118 }) 118 })
119 } 119 }
@@ -244,8 +244,10 @@ const {vChartRef} = useChartDataFetch(props.chartConfig, useChartEditStore, (new @@ -244,8 +244,10 @@ const {vChartRef} = useChartDataFetch(props.chartConfig, useChartEditStore, (new
244 } 244 }
245 } 245 }
246 }) 246 })
247 - //  
248 - addPieInterval(newData) 247 + //动画为开启才执行动画
  248 + if (props.chartConfig.option.isCarousel) {
  249 + addPieInterval(newData)
  250 + }
249 updateVChart(newData) 251 updateVChart(newData)
250 }) 252 })
251 253
1 <template> 1 <template>
2 - <div> 2 + <div class="device-history-query">
3 <n-space vertical> 3 <n-space vertical>
4 <div class="form"> 4 <div class="form">
5 <n-date-picker size="small" :to="true" clearable v-model:value="queryCondition.timeRange" type="datetimerange" 5 <n-date-picker size="small" :to="true" clearable v-model:value="queryCondition.timeRange" type="datetimerange"
@@ -96,6 +96,27 @@ const option = computed(() => { @@ -96,6 +96,27 @@ const option = computed(() => {
96 return mergeTheme(props.chartConfig.option, props.themeSetting, includes) 96 return mergeTheme(props.chartConfig.option, props.themeSetting, includes)
97 }) 97 })
98 98
  99 +const toolBoxOption = {
  100 + show: true,
  101 + right: 20,
  102 + feature: {
  103 + myFullButton: {
  104 + show: true,
  105 + title: '全屏查看',
  106 + icon: 'path://M733.549304 0l116.434359 116.23452-226.402521 226.40252 57.053835 57.068109 226.459617-226.445342 120.616689 120.41685V0H733.549304zM689.513507 619.855586l-57.068108 57.068109 224.232847 224.232847-122.64362 122.843458h293.676657V729.838022l-114.007751 114.207588-224.190025-224.190024zM338.197775 404.144414l57.068109-57.068109L171.033037 122.843458 293.676657 0H0v294.161978l114.022025-114.207588 224.17575 224.190024zM347.076305 624.294851L120.616689 850.754468 0 730.323343v293.676657h294.161978l-116.420084-116.23452 226.40252-226.40252-57.068109-57.068109z',
  107 + onclick: () => {
  108 + const domName = document.getElementsByClassName('device-history-query')[0] as HTMLElement
  109 + const htmlName = document.querySelector('html') as HTMLHtmlElement
  110 + useFullScreen(domName, htmlName)
  111 + }
  112 + }
  113 + }
  114 +}
  115 +props.chartConfig.option = {
  116 + ...props.chartConfig.option,
  117 + ...{ toolbox: toolBoxOption }
  118 +}
  119 +
99 // dataset 无法变更条数的补丁 120 // dataset 无法变更条数的补丁
100 watch( 121 watch(
101 () => props.chartConfig.option.dataset, 122 () => props.chartConfig.option.dataset,
@@ -122,8 +143,8 @@ watch( @@ -122,8 +143,8 @@ watch(
122 props.chartConfig.option.series.push(...seriesArr) 143 props.chartConfig.option.series.push(...seriesArr)
123 } 144 }
124 replaceMergeArr.value = ['series'] 145 replaceMergeArr.value = ['series']
  146 + useEchartsMapLegend(props.chartConfig, props.chartConfig.option.series)
125 nextTick(() => { 147 nextTick(() => {
126 - useEchartsMapLegend(props.chartConfig, props.chartConfig.option.series)  
127 replaceMergeArr.value = [] 148 replaceMergeArr.value = []
128 }) 149 })
129 } 150 }
@@ -12,7 +12,7 @@ export const seriesItem = { @@ -12,7 +12,7 @@ export const seriesItem = {
12 smooth: false, 12 smooth: false,
13 symbolSize: 5, //设定实心点的大小 13 symbolSize: 5, //设定实心点的大小
14 label: { 14 label: {
15 - show: true, 15 + show: false,
16 position: 'top', 16 position: 'top',
17 color: '#fff', 17 color: '#fff',
18 fontSize: 12 18 fontSize: 12
@@ -214,8 +214,8 @@ watch( @@ -214,8 +214,8 @@ watch(
214 props.chartConfig.option.series.push(...seriesArr) 214 props.chartConfig.option.series.push(...seriesArr)
215 } 215 }
216 replaceMergeArr.value = ['series'] 216 replaceMergeArr.value = ['series']
  217 + useEchartsMapLegend(props.chartConfig, props.chartConfig.option.series)
217 nextTick(() => { 218 nextTick(() => {
218 - useEchartsMapLegend(props.chartConfig, props.chartConfig.option.series)  
219 replaceMergeArr.value = [] 219 replaceMergeArr.value = []
220 }) 220 })
221 } 221 }
@@ -274,8 +274,10 @@ const { vChartRef } = useChartDataFetch(props.chartConfig, useChartEditStore, ne @@ -274,8 +274,10 @@ const { vChartRef } = useChartDataFetch(props.chartConfig, useChartEditStore, ne
274 } 274 }
275 } 275 }
276 }) 276 })
277 - //  
278 - addPieInterval(newData) 277 + //动画为开启才执行动画
  278 + if (props.chartConfig.option.isCarousel) {
  279 + addPieInterval(newData)
  280 + }
279 updateVChart(newData) 281 updateVChart(newData)
280 }) 282 })
281 283
@@ -43,13 +43,14 @@ onMounted(async () => { @@ -43,13 +43,14 @@ onMounted(async () => {
43 label: '中国', 43 label: '中国',
44 value: 'china' 44 value: 'china'
45 }) 45 })
46 - onHandleSelectProvince('china') 46 + onHandleSelectProvince(props.optionData?.mapRegion.saveSelect['provinceValue'])
47 for (let i in selectValues) Reflect.set(selectValues, i, props.optionData?.mapRegion.saveSelect[i]) 47 for (let i in selectValues) Reflect.set(selectValues, i, props.optionData?.mapRegion.saveSelect[i])
48 }) 48 })
49 49
50 const onHandleSelectProvince = async (value: number | string) => { 50 const onHandleSelectProvince = async (value: number | string) => {
51 selectValues.cityValue = null 51 selectValues.cityValue = null
52 selectValues.countyValue = null 52 selectValues.countyValue = null
  53 + selectOptions.cityOptions = []
53 if (value === 'china') return (selectValues.levelStr = areaEnum.COUNTRY) 54 if (value === 'china') return (selectValues.levelStr = areaEnum.COUNTRY)
54 selectOptions.cityOptions = await getAreaLists(areaEnum.CITY, value) 55 selectOptions.cityOptions = await getAreaLists(areaEnum.CITY, value)
55 selectValues.levelStr = areaEnum.PROVINCE 56 selectValues.levelStr = areaEnum.PROVINCE
  1 +/**
  2 + * 单个组件全屏
  3 + * @param domName
  4 + * @param htmlName
  5 + */
  6 +
1 export const useFullScreen = (domName: any, htmlName: HTMLHtmlElement) => { 7 export const useFullScreen = (domName: any, htmlName: HTMLHtmlElement) => {
2 const isFullScreen = document.fullscreenElement 8 const isFullScreen = document.fullscreenElement
  9 +
3 const currentDatkTheme = htmlName.getAttribute('data-theme') 10 const currentDatkTheme = htmlName.getAttribute('data-theme')
4 11
  12 + //特殊处理单设备多属性组件全屏显示
  13 + const setDomName = (domName: any,top0: string, top1: string) => {
  14 + domName.children[0].style.top = top0
  15 + domName.style.paddingBottom = '80px'
  16 + domName.children[1].style.top = top1
  17 + }
  18 +
  19 + const setDomNameAndStyle = () => {
  20 + domName.style.background = currentDatkTheme === 'light' ? 'white' : '#18181c'
  21 + domName.children[0].style.position = 'relative'
  22 + setDomName(domName, '30px','40px')
  23 + }
  24 +
5 if (isFullScreen) { 25 if (isFullScreen) {
6 if (document.exitFullscreen) { 26 if (document.exitFullscreen) {
7 document.exitFullscreen() 27 document.exitFullscreen()
@@ -11,18 +31,19 @@ export const useFullScreen = (domName: any, htmlName: HTMLHtmlElement) => { @@ -11,18 +31,19 @@ export const useFullScreen = (domName: any, htmlName: HTMLHtmlElement) => {
11 //兼容其他浏览器 31 //兼容其他浏览器
12 if (domName.requestFullscreen) { 32 if (domName.requestFullscreen) {
13 domName.requestFullscreen() 33 domName.requestFullscreen()
14 - domName.style.background = currentDatkTheme === 'light' ? 'white' : '#18181c' 34 + setDomNameAndStyle()
15 } else if (domName.mozRequestFullScreen) { 35 } else if (domName.mozRequestFullScreen) {
16 domName.mozRequestFullScreen() 36 domName.mozRequestFullScreen()
17 - domName.style.background = currentDatkTheme === 'light' ? 'white' : '#18181c' 37 + setDomNameAndStyle()
18 } else if (domName.webkitRequestFullscreen) { 38 } else if (domName.webkitRequestFullscreen) {
19 domName.webkitRequestFullscreen() 39 domName.webkitRequestFullscreen()
20 - domName.style.background = currentDatkTheme === 'light' ? 'white' : '#18181c' 40 + setDomNameAndStyle()
21 } else if (domName.msRequestFullscreen) { 41 } else if (domName.msRequestFullscreen) {
22 domName.msRequestFullscreen() 42 domName.msRequestFullscreen()
23 - domName.style.background = currentDatkTheme === 'light' ? 'white' : '#18181c' 43 + setDomNameAndStyle()
24 } 44 }
25 } 45 }
  46 +
26 //fix 浏览器监听esc退出 47 //fix 浏览器监听esc退出
27 function exitHandler() { 48 function exitHandler() {
28 if ( 49 if (
@@ -33,6 +54,7 @@ export const useFullScreen = (domName: any, htmlName: HTMLHtmlElement) => { @@ -33,6 +54,7 @@ export const useFullScreen = (domName: any, htmlName: HTMLHtmlElement) => {
33 domName.style.background = currentDatkTheme === 'light' ? '' : '' 54 domName.style.background = currentDatkTheme === 'light' ? '' : ''
34 } 55 }
35 } 56 }
  57 +
36 // 监听fullscreenchange事件(全屏模式的变化) 58 // 监听fullscreenchange事件(全屏模式的变化)
37 if (document.addEventListener) { 59 if (document.addEventListener) {
38 document.addEventListener('webkitfullscreenchange', exitHandler, false) 60 document.addEventListener('webkitfullscreenchange', exitHandler, false)
@@ -10,13 +10,15 @@ @@ -10,13 +10,15 @@
10 </template> 10 </template>
11 11
12 <script setup lang="ts"> 12 <script setup lang="ts">
13 -import { PropType, toRefs, shallowReactive, watch } from 'vue' 13 +import { PropType, toRefs, shallowReactive, watch, ref } from 'vue'
14 import { CreateComponentType } from '@/packages/index.d' 14 import { CreateComponentType } from '@/packages/index.d'
15 import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore' 15 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 import { useChartDataFetch } from '@/hooks'
  20 +import { isObject } from '@/utils/external/is'
  21 +import { SelectOption } from 'naive-ui'
20 22
21 const props = defineProps({ 23 const props = defineProps({
22 chartConfig: { 24 chartConfig: {
@@ -36,14 +38,23 @@ const option = shallowReactive({ @@ -36,14 +38,23 @@ const option = shallowReactive({
36 } 38 }
37 }) 39 })
38 40
  41 +const cacheOptions = ref<string[]>([])
  42 +
39 // 监听事件改变 43 // 监听事件改变
40 -const onChange = (v: string[] | string) => {  
41 - // 存储到联动数据  
42 - useChartInteract( 44 +const onChange = (v: string[] | string, options: SelectOption | SelectOption[]) => {
  45 + const attrName = isObject(options) ? [(options as SelectOption).label] : (options as SelectOption[])?.map(mapItem => mapItem.label)
  46 + cacheOptions.value = attrName as unknown as string[]
  47 + updateChartInteract(v, cacheOptions.value)
  48 +}
  49 +
  50 +const updateChartInteract = (v: string[] | string, attrName?: string[]) => {
  51 + // 存储到联动数据
  52 + useChartInteract(
43 props.chartConfig, 53 props.chartConfig,
44 useChartEditStore, 54 useChartEditStore,
45 - { [ComponentInteractParamsEnum.DATA]: v },  
46 - InteractEventOn.CHANGE 55 + { [ComponentInteractParamsEnum.DATA]: encodeURIComponent(v as unknown as string) },
  56 + InteractEventOn.CHANGE,
  57 + attrName!
47 ) 58 )
48 // 特殊处理 只针对两个下拉选择器,一个是产品下拉,一个是设备下拉,选择了产品,存储到sessionStorage里,用来判断预览时点击产品下拉,清除设备下拉值 59 // 特殊处理 只针对两个下拉选择器,一个是产品下拉,一个是设备下拉,选择了产品,存储到sessionStorage里,用来判断预览时点击产品下拉,清除设备下拉值
49 if (window.location.href.includes('preview')) { 60 if (window.location.href.includes('preview')) {
@@ -56,7 +67,7 @@ watch( @@ -56,7 +67,7 @@ watch(
56 () => props.chartConfig.option, 67 () => props.chartConfig.option,
57 (newData: any) => { 68 (newData: any) => {
58 option.value = newData 69 option.value = newData
59 - onChange(newData.selectValue) 70 + updateChartInteract(newData.selectValue, cacheOptions.value)
60 }, 71 },
61 { 72 {
62 immediate: true, 73 immediate: true,
@@ -42,15 +42,14 @@ const checkedKeys = ref([]) @@ -42,15 +42,14 @@ const checkedKeys = ref([])
42 42
43 const onClick = (v: string[]) => { 43 const onClick = (v: string[]) => {
44 // nTreeRef.value?.selectedKeys(v) 44 // nTreeRef.value?.selectedKeys(v)
45 - console.log(nTreeRef.value)  
46 - console.log(v)  
47 // nTreeRef.value?.onUpdateCheckedKeys(v) 45 // nTreeRef.value?.onUpdateCheckedKeys(v)
48 if (Array.isArray(v) && v.length == 0) return 46 if (Array.isArray(v) && v.length == 0) return
49 useChartInteract( 47 useChartInteract(
50 props.chartConfig, 48 props.chartConfig,
51 useChartEditStore, 49 useChartEditStore,
52 { [ComponentInteractParamsEnum.DATA]: v[0] }, 50 { [ComponentInteractParamsEnum.DATA]: v[0] },
53 - InteractEventOn.CHANGE 51 + InteractEventOn.CHANGE,
  52 + []
54 ) 53 )
55 } 54 }
56 </script> 55 </script>
@@ -75,7 +75,7 @@ const getConfigurationOptions = async (params: object) => { @@ -75,7 +75,7 @@ const getConfigurationOptions = async (params: object) => {
75 watch( 75 watch(
76 () => props.optionData.pages, 76 () => props.optionData.pages,
77 (newData: any) => { 77 (newData: any) => {
78 - getConfigurationOptions({ page: newData.page, pageSize: newData.pageSize }) 78 + getConfigurationOptions({ page: newData.page, pageSize: newData.pageSize, isTemplate: 0 })
79 }, 79 },
80 { 80 {
81 deep: true, 81 deep: true,
@@ -84,7 +84,7 @@ watch( @@ -84,7 +84,7 @@ watch(
84 ) 84 )
85 85
86 onMounted(() => { 86 onMounted(() => {
87 - getConfigurationOptions({ page: props.optionData.pages.page, pageSize: props.optionData.pages.pageSize }) 87 + getConfigurationOptions({ page: props.optionData.pages.page, pageSize: props.optionData.pages.pageSize, isTemplate: 0 })
88 }) 88 })
89 89
90 const handleUpdateValue = (value: string, options: ConfigurationItemType) => { 90 const handleUpdateValue = (value: string, options: ConfigurationItemType) => {
@@ -55,7 +55,7 @@ @@ -55,7 +55,7 @@
55 </template> 55 </template>
56 56
57 <script setup lang="ts"> 57 <script setup lang="ts">
58 -import { PropType, ref, onMounted } from 'vue' 58 +import { PropType, ref, onMounted, watch } from 'vue'
59 import { AccessMode, option, sourceTypeEnum, videoListInterface, sourceTypeNameEnum, Dataset } from './config' 59 import { AccessMode, option, sourceTypeEnum, videoListInterface, sourceTypeNameEnum, Dataset } from './config'
60 import { CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting' 60 import { CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting'
61 import { NTreeSelect } from 'naive-ui' 61 import { NTreeSelect } from 'naive-ui'
@@ -135,6 +135,19 @@ const handleSelect = (_: string, e: videoListInterface) => { @@ -135,6 +135,19 @@ const handleSelect = (_: string, e: videoListInterface) => {
135 } 135 }
136 } 136 }
137 137
  138 +watch(()=>props.optionData, (newData)=>{
  139 + if (newData.sourceType === sourceTypeEnum.PLATFORM) {
  140 + getOriginationList()
  141 + if (newData.organization) {
  142 + getVideoLists(newData.organization)
  143 + }
  144 + }
  145 +},
  146 +{
  147 + immediate: true,
  148 + deep: true
  149 +})
  150 +
138 onMounted(() => { 151 onMounted(() => {
139 if (props.optionData.sourceType === sourceTypeEnum.PLATFORM) { 152 if (props.optionData.sourceType === sourceTypeEnum.PLATFORM) {
140 getOriginationList() 153 getOriginationList()
  1 +import cloneDeep from 'lodash/cloneDeep'
  2 +import { PublicConfigClass } from '@/packages/public'
  3 +import { CreateComponentType } from '@/packages/index.d'
  4 +import { chartInitConfig } from '@/settings/designSetting'
  5 +import { OverrideTablesBasicConfig } from './index'
  6 +import dataJson from './data.json'
  7 +
  8 +const { dimensions, source } = dataJson
  9 +export const option = {
  10 + dynamicForm: {
  11 + keys: [
  12 + {
  13 + key: '告警设备,deviceName',
  14 + }
  15 + ]
  16 + },
  17 + dataset: { dimensions, source },
  18 + pagination: {
  19 + page: 1,
  20 + pageSize: 10
  21 + },
  22 + align: 'center',
  23 + style: {
  24 + border: 'on',
  25 + singleColumn: 'off',
  26 + singleLine: 'off',
  27 + bottomBordered: 'on',
  28 + striped: 'on',
  29 + fontSize: 16,
  30 + borderWidth: 0,
  31 + borderColor: 'black',
  32 + borderStyle: 'solid'
  33 + },
  34 + inputShow: false
  35 +}
  36 +
  37 +export default class Config extends PublicConfigClass implements CreateComponentType {
  38 + public key = OverrideTablesBasicConfig.key
  39 + public attr = { ...chartInitConfig, w: 600, h: 300, zIndex: -1 }
  40 + public chartConfig = cloneDeep(OverrideTablesBasicConfig)
  41 + public option = cloneDeep(option)
  42 +}
  1 +<template>
  2 + <collapse-item name="表格设置" :expanded="true">
  3 + <n-tag type="primary">配置分页接口查询参数键,以逗号分隔键名和键值</n-tag>
  4 + <n-tag type="primary">例如:设备名称,deviceName</n-tag>
  5 + <setting-item-box :alone="true" name="搜索字段">
  6 + <SettingItem name="表格搜索" :alone="true">
  7 + <n-switch v-model:value="optionData.inputShow"></n-switch>
  8 + </SettingItem>
  9 + <setting-item v-if="optionData.inputShow" :alone="true">
  10 + <n-form ref="formRef" :model="dynamicForm" :style="{ maxWidth: '640px' }">
  11 + <n-form-item
  12 + v-for="(item, index) in dynamicForm.keys"
  13 + :key="index"
  14 + :label="`字段${index + 1}`"
  15 + :path="`keys[${index}].key`"
  16 + >
  17 + <n-input v-model:value="item.key" clearable />
  18 + <n-button style="margin-left: 12px" @click="removeItem(index)" v-if="dynamicForm.keys.length > 1">
  19 + 删除
  20 + </n-button>
  21 + </n-form-item>
  22 + <n-form-item>
  23 + <n-space>
  24 + <n-button attr-type="button" @click="addItem" v-if="dynamicForm.keys.length < 2"> 增加 </n-button>
  25 + </n-space>
  26 + </n-form-item>
  27 + </n-form>
  28 + </setting-item>
  29 + </setting-item-box>
  30 + <n-tag type="primary">若配置无响应,请在预览页面查看效果</n-tag>
  31 + <setting-item-box :alone="true" name="对齐方式">
  32 + <setting-item :alone="true">
  33 + <n-select
  34 + v-model:value="optionData.align"
  35 + size="small"
  36 + :options="[
  37 + { label: '靠左', value: 'left' },
  38 + { label: '居中', value: 'center' },
  39 + { label: '靠右', value: 'right' }
  40 + ]"
  41 + />
  42 + </setting-item>
  43 + </setting-item-box>
  44 + <setting-item-box :alone="false" name="分页设置">
  45 + <setting-item name="默认页码" :alone="true">
  46 + <n-input-number v-model:value="optionData.pagination.page" size="small" placeholder="字体大小"></n-input-number>
  47 + </setting-item>
  48 + <setting-item name="分页" :alone="true">
  49 + <n-select v-model:value="optionData.pagination.pageSize" size="small" :options="page" />
  50 + </setting-item>
  51 + </setting-item-box>
  52 + <setting-item-box :alone="false" name="表格样式">
  53 + <SettingItem name="显示边框" :alone="true">
  54 + <n-select v-model:value="(optionData as any).style.border" size="small" :options="borderFlag" />
  55 + </SettingItem>
  56 + <SettingItem name="底部边框" :alone="true">
  57 + <n-select
  58 + v-model:value="(optionData as any).style.bottomBordered"
  59 + size="small"
  60 + :options="bottom_borderedFlag"
  61 + />
  62 + </SettingItem>
  63 + <SettingItem name="列分割线" :alone="true">
  64 + <n-select v-model:value="(optionData as any).style.singleLine" size="small" :options="columnFlag" />
  65 + </SettingItem>
  66 + <SettingItem name="行分割线" :alone="true">
  67 + <n-select v-model:value="(optionData as any).style.singleColumn" size="small" :options="lineFlag" />
  68 + </SettingItem>
  69 + <SettingItem name="斑马条纹" :alone="true">
  70 + <n-select v-model:value="(optionData as any).style.striped" size="small" :options="stripedFlag" />
  71 + </SettingItem>
  72 + <setting-item name="字体大小" :alone="true">
  73 + <n-input-number
  74 + v-model:value="optionData.style.fontSize"
  75 + :min="12"
  76 + size="small"
  77 + placeholder="字体大小"
  78 + ></n-input-number>
  79 + </setting-item>
  80 + <setting-item name="边框宽度" :alone="true">
  81 + <n-input-number
  82 + v-model:value="optionData.style.borderWidth"
  83 + :min="0"
  84 + size="small"
  85 + placeholder="字体大小"
  86 + ></n-input-number>
  87 + </setting-item>
  88 + <setting-item name="边框颜色" :alone="true">
  89 + <n-color-picker size="small" :modes="['rgb']" v-model:value="optionData.style.borderColor"></n-color-picker>
  90 + </setting-item>
  91 + <setting-item name="边框样式" :alone="true">
  92 + <n-select v-model:value="optionData.style.borderStyle" size="small" :options="borderStyleFlag" />
  93 + </setting-item>
  94 + </setting-item-box>
  95 + </collapse-item>
  96 +</template>
  97 +
  98 +<script setup lang="ts">
  99 +import { PropType, watch, ref, toRefs } from 'vue'
  100 +import { option } from './config'
  101 +import { CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting'
  102 +import { FormInst } from 'naive-ui'
  103 +
  104 +const page = [
  105 + { label: '2', value: 2 },
  106 + { label: '5', value: 5 },
  107 + { label: '10', value: 10 },
  108 + { label: '15', value: 15 },
  109 + { label: '30', value: 30 }
  110 +]
  111 +const borderFlag = [
  112 + { label: '显示', value: 'on' },
  113 + { label: '不显示', value: 'off' }
  114 +]
  115 +const columnFlag = [
  116 + { label: '显示', value: 'off' },
  117 + { label: '不显示', value: 'on' }
  118 +]
  119 +const lineFlag = [
  120 + { label: '显示', value: 'off' },
  121 + { label: '不显示', value: 'on' }
  122 +]
  123 +const bottom_borderedFlag = [
  124 + { label: '显示', value: 'on' },
  125 + { label: '不显示', value: 'off' }
  126 +]
  127 +const stripedFlag = [
  128 + { label: '显示', value: 'on' },
  129 + { label: '不显示', value: 'off' }
  130 +]
  131 +const borderStyleFlag = [
  132 + { label: '实线边框', value: 'solid' },
  133 + { label: '虚线边框', value: 'dashed' },
  134 + { label: '点状边框', value: 'dotted' },
  135 + { label: '双线边框', value: 'double' }
  136 +]
  137 +const props = defineProps({
  138 + optionData: {
  139 + type: Object as PropType<typeof option>,
  140 + required: true
  141 + }
  142 +})
  143 +
  144 +const header = ref()
  145 +const median = ref<string[]>([])
  146 +props.optionData.dataset.dimensions.forEach(item => {
  147 + median.value.push(item.title)
  148 +})
  149 +
  150 +const { dynamicForm } = toRefs(props.optionData)
  151 +
  152 +const formRef = ref<FormInst | null>(null)
  153 +
  154 +const removeItem = (index: number) => {
  155 + dynamicForm.value.keys.splice(index, 1)
  156 +}
  157 +
  158 +const addItem = () => {
  159 + dynamicForm.value.keys.push({ key: '' })
  160 +}
  161 +
  162 +//转string
  163 +watch(
  164 + () => props.optionData,
  165 + () => {
  166 + median.value = []
  167 + props.optionData.dataset.dimensions.forEach(item => {
  168 + median.value.push(item.title)
  169 + })
  170 + header.value = median.value.toString()
  171 + },
  172 + {
  173 + deep: false,
  174 + immediate: true
  175 + }
  176 +)
  177 +
  178 +//更新columns
  179 +watch([header], ([headerNew], [headerOld]) => {
  180 + if (headerNew !== headerOld) {
  181 + headerNew.split(',').forEach((item: string, index: number) => {
  182 + if (index + 1 <= props.optionData.dataset.dimensions.length) {
  183 + props.optionData.dataset.dimensions[index].title = headerNew.split(',')[index]
  184 + }
  185 + })
  186 + }
  187 +})
  188 +</script>
  1 +{
  2 + "dimensions": [
  3 + {
  4 + "title": "产品名称",
  5 + "key": "productName"
  6 + },
  7 + {
  8 + "title": "产品销量(万)",
  9 + "key": "totalSum"
  10 + },
  11 + {
  12 + "title": "销售额(万)",
  13 + "key": "totalAmount"
  14 + }
  15 + ],
  16 + "source": [
  17 + {
  18 + "key": 0,
  19 + "productName": "产品A1",
  20 + "totalSum": 10,
  21 + "totalAmount": 10
  22 + },
  23 + {
  24 + "key": 1,
  25 + "productName": "产品B1",
  26 + "totalSum": 10,
  27 + "totalAmount": 10
  28 + },
  29 + {
  30 + "key": 2,
  31 + "productName": "产品C1",
  32 + "totalSum": 10,
  33 + "totalAmount": 10
  34 + },
  35 + {
  36 + "key": 3,
  37 + "productName": "产品D1",
  38 + "totalSum": 10,
  39 + "totalAmount": 10
  40 + },
  41 + {
  42 + "key": 4,
  43 + "productName": "产品A2",
  44 + "totalSum": 10,
  45 + "totalAmount": 10
  46 + },
  47 + {
  48 + "key": 5,
  49 + "productName": "产品D2",
  50 + "totalSum": 10,
  51 + "totalAmount": 10
  52 + },
  53 + {
  54 + "key": 6,
  55 + "productName": "产品A3",
  56 + "totalSum": 10,
  57 + "totalAmount": 10
  58 + }
  59 + ]
  60 +}
  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('OverrideTablesBasic', true)
  6 +
  7 +export const OverrideTablesBasicConfig: 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: 'tables_basic.png'
  17 +}
  1 +<template>
  2 + <div class="go-tables-basic">
  3 + <n-space>
  4 + <n-form v-if="inputShow" :model="dynamicForm" :style="{ maxWidth: '640px' }" inline>
  5 + <n-form-item v-for="(item, index) in dynamicForm.keys" :key="index" >
  6 + <n-input v-model:value="item.value" clearable :placeholder=" `请输入${item.key.split(',').at(-2)}`">
  7 + <template #prefix>
  8 + <n-icon :component="SearchIcon" />
  9 + </template>
  10 + </n-input>
  11 + </n-form-item>
  12 + </n-form>
  13 + </n-space>
  14 + <n-data-table
  15 + remote
  16 + :style="`
  17 + width: ${w}px;
  18 + height: ${h}px;
  19 + font-size: ${option.style.fontSize}px;
  20 + border-width: ${option.style.border === 'on' ? option.style.borderWidth : 0}px;
  21 + border-color: ${option.style.borderColor};
  22 + border-style: ${option.style.borderStyle}`"
  23 + :bordered="option.style.border === 'on'"
  24 + :single-column="option.style.singleColumn === 'on'"
  25 + :single-line="option.style.singleLine === 'on'"
  26 + :bottom-bordered="option.style.bottomBordered === 'on'"
  27 + :striped="option.style.striped === 'on'"
  28 + :max-height="h"
  29 + size="small"
  30 + :columns="option.dataset.dimensions"
  31 + :data="option.dataset.source"
  32 + :pagination="pagination"
  33 + />
  34 + </div>
  35 +</template>
  36 +
  37 +<script setup lang="ts">
  38 +import { PropType, toRefs, watch, reactive, ref, onMounted } from 'vue'
  39 +import { CreateComponentType } from '@/packages/index.d'
  40 +import { icon } from '@/plugins'
  41 +import { getAlarmList, getDeviceList } from '@/api/external/common'
  42 +import { useFilterFn } from '@/hooks/external/useFilterFn'
  43 +import dataJson from './data.json'
  44 +
  45 +const props = defineProps({
  46 + chartConfig: {
  47 + type: Object as PropType<CreateComponentType>,
  48 + required: true
  49 + }
  50 +})
  51 +
  52 +const { SearchIcon } = icon.ionicons5
  53 +
  54 +const { align, pagination, inputShow, dynamicForm } = toRefs(props.chartConfig.option)
  55 +
  56 +pagination.value.onChange = (page: number) => {
  57 + pagination.value.page = page
  58 +}
  59 +
  60 +const { w, h } = toRefs(props.chartConfig.attr)
  61 +
  62 +const option = reactive({
  63 + dataset: props.chartConfig.option.dataset,
  64 + style: props.chartConfig.option.style
  65 +})
  66 +
  67 +watch(
  68 + () => props.chartConfig.option.dataset,
  69 + (newData: Recordable) => {
  70 + option.dataset = newData
  71 + option?.dataset?.dimensions?.forEach((header: Recordable) => {
  72 + header.align = align.value
  73 + })
  74 + },
  75 + {
  76 + immediate: true,
  77 + deep: true
  78 + }
  79 +)
  80 +
  81 +const alarmParams = ref({})
  82 +
  83 +watch(
  84 + () => props.chartConfig.option,
  85 + newData => {
  86 + const { dynamicForm } = newData
  87 + const { keys } = dynamicForm
  88 + alarmParams.value = keys.reduce((acc: Recordable, curr: Recordable) => {
  89 + const param = {
  90 + [curr.key.split(',').at(-1)]: curr.value
  91 + }
  92 + Object.assign(acc, param)
  93 + return acc
  94 + }, {})
  95 + fetchAlarmList(props.chartConfig.filter!, props.chartConfig.request!, {
  96 + ...alarmParams.value,
  97 + page: pagination.value.page,
  98 + pageSize: pagination.value.pageSize
  99 + })
  100 + },
  101 + {
  102 + deep: true
  103 + }
  104 +)
  105 +
  106 +const fetchAlarmList = async (filterStr: string, request: Recordable, params: Recordable) => {
  107 + const { requestUrl } = request
  108 + let res = null
  109 + if (requestUrl === '/api/yt/alarm') {
  110 + res = await getAlarmList(params)
  111 + } else if (requestUrl === '/api/yt/device') {
  112 + const { page, pageSize, ...rest } = params
  113 + res = await getDeviceList(
  114 + {
  115 + page: params.page,
  116 + pageSize: params.pageSize
  117 + },
  118 + Object.keys(rest).length === 0 ? {"name": ""} : rest
  119 + )
  120 + }
  121 + if (filterStr) {
  122 + const filterRes = useFilterFn(filterStr, res)
  123 + const { value } = filterRes
  124 + option.dataset = value
  125 + pagination.value.itemCount = res.total
  126 + } else {
  127 + option.dataset = dataJson
  128 + }
  129 +}
  130 +
  131 +onMounted(() => {
  132 + fetchAlarmList(props.chartConfig.filter!, props.chartConfig.request!, {
  133 + page: pagination.value.page,
  134 + pageSize: pagination.value.pageSize
  135 + })
  136 +})
  137 +</script>
  138 +
  139 +<style lang="scss" scoped>
  140 +@include go('tables-basic') {
  141 + display: flex;
  142 + flex-direction: column;
  143 + gap: 15px;
  144 + align-items: flex-end;
  145 +}
  146 +</style>
@@ -69,6 +69,7 @@ import { Decorates24Config } from '@/packages/components/external/Decorates/Deco @@ -69,6 +69,7 @@ import { Decorates24Config } from '@/packages/components/external/Decorates/Deco
69 import { Decorates25Config } from '@/packages/components/external/Decorates/Decorates/Decorates25' 69 import { Decorates25Config } from '@/packages/components/external/Decorates/Decorates/Decorates25'
70 import { Decorates26Config } from '@/packages/components/external/Decorates/Decorates/Decorates26' 70 import { Decorates26Config } from '@/packages/components/external/Decorates/Decorates/Decorates26'
71 import { OverrideTableScrollBoardConfig } from '@/packages/components/external/Tables/Tables/OverrideTableScrollBoard' 71 import { OverrideTableScrollBoardConfig } from '@/packages/components/external/Tables/Tables/OverrideTableScrollBoard'
  72 +import { OverrideTablesBasicConfig } from '@/packages/components/external/Tables/Tables/OverrideTablesBasic'
72 73
73 74
74 /** 75 /**
@@ -156,6 +157,7 @@ export function useInjectLib(packagesList: EPackagesType) { @@ -156,6 +157,7 @@ export function useInjectLib(packagesList: EPackagesType) {
156 157
157 //列表 158 //列表
158 addWidgetToCategoryByCategoryName(packagesList, PackagesCategoryEnum.TABLES, OverrideTableScrollBoardConfig)//重写列表下的轮播列表 159 addWidgetToCategoryByCategoryName(packagesList, PackagesCategoryEnum.TABLES, OverrideTableScrollBoardConfig)//重写列表下的轮播列表
  160 + addWidgetToCategoryByCategoryName(packagesList, PackagesCategoryEnum.TABLES, OverrideTablesBasicConfig)//重写列表下的轮播列表
159 // 161 //
160 } 162 }
161 163
@@ -185,6 +185,12 @@ export interface PublicConfigType { @@ -185,6 +185,12 @@ export interface PublicConfigType {
185 } 185 }
186 } 186 }
187 187
  188 +export interface ChartCustomColor {
  189 + name: string
  190 + color: string[]
  191 +}
  192 +
  193 +
188 export interface CreateComponentType extends PublicConfigType, requestConfig { 194 export interface CreateComponentType extends PublicConfigType, requestConfig {
189 key: string 195 key: string
190 chartConfig: ConfigType 196 chartConfig: ConfigType
@@ -192,6 +198,7 @@ export interface CreateComponentType extends PublicConfigType, requestConfig { @@ -192,6 +198,7 @@ export interface CreateComponentType extends PublicConfigType, requestConfig {
192 groupList?: Array<CreateComponentType> 198 groupList?: Array<CreateComponentType>
193 saveHistoryInput?: string // THINGS_KIT 新增一个接口字段 saveHistoryInput,用于记录当前组件id和输入框的内容,这里不能重写,有很多地方引用到的,这里升级版本有冲突 199 saveHistoryInput?: string // THINGS_KIT 新增一个接口字段 saveHistoryInput,用于记录当前组件id和输入框的内容,这里不能重写,有很多地方引用到的,这里升级版本有冲突
194 wsOriginalMessage?: any 200 wsOriginalMessage?: any
  201 + colors?: ChartCustomColor // THINGS_KIT 新增一个接口字段 用于组件自定义颜色,一般是图表组件
195 } 202 }
196 203
197 // 组件成组实例类 204 // 组件成组实例类
@@ -48,6 +48,9 @@ @@ -48,6 +48,9 @@
48 } 48 }
49 }, 49 },
50 "yAxis": { 50 "yAxis": {
  51 + "showRange":true,
  52 + "min": 0,
  53 + "max": 200,
51 "show": true, 54 "show": true,
52 "name": "", 55 "name": "",
53 "nameGap": 15, 56 "nameGap": 15,
@@ -40,7 +40,7 @@ import { ref, computed } from 'vue' @@ -40,7 +40,7 @@ import { ref, computed } from 'vue'
40 import cloneDeep from 'lodash/cloneDeep' 40 import cloneDeep from 'lodash/cloneDeep'
41 import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore' 41 import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
42 import { EditCanvasConfigEnum } from '@/store/modules/chartEditStore/chartEditStore.d' 42 import { EditCanvasConfigEnum } from '@/store/modules/chartEditStore/chartEditStore.d'
43 -import { chartColors, ChartColorsNameType } from '@/settings/chartThemes/index' 43 +import { ChartColorsNameType } from '@/settings/chartThemes/index'
44 import { useDesignStore } from '@/store/modules/designStore/designStore' 44 import { useDesignStore } from '@/store/modules/designStore/designStore'
45 import { loadAsyncComponent, colorCustomMerge } from '@/utils' 45 import { loadAsyncComponent, colorCustomMerge } from '@/utils'
46 import { icon } from '@/plugins' 46 import { icon } from '@/plugins'
@@ -93,7 +93,8 @@ @@ -93,7 +93,8 @@
93 <!-- 底部 --> 93 <!-- 底部 -->
94 <template #action> 94 <template #action>
95 <n-space justify="end"> 95 <n-space justify="end">
96 - <n-button @click="closeHandle">操作完成</n-button> 96 + <n-button @click="applicationGroupHandle" v-if="applicationGroup">应用此分组</n-button>
  97 + <n-button v-if="!applicationGroup" @click="closeHandle">操作完成</n-button>
97 </n-space> 98 </n-space>
98 </template> 99 </template>
99 </n-card> 100 </n-card>
@@ -101,22 +102,27 @@ @@ -101,22 +102,27 @@
101 </template> 102 </template>
102 103
103 <script setup lang="ts"> 104 <script setup lang="ts">
104 -import { ref, watch, computed, reactive, nextTick, onMounted } from 'vue' 105 +import { ref, watch, computed, reactive, nextTick } from 'vue'
105 import cloneDeep from 'lodash/cloneDeep' 106 import cloneDeep from 'lodash/cloneDeep'
106 import noData from '@/assets/images/canvas/noData.png' 107 import noData from '@/assets/images/canvas/noData.png'
107 import { getUUID, goDialog } from '@/utils' 108 import { getUUID, goDialog } from '@/utils'
108 import { icon } from '@/plugins' 109 import { icon } from '@/plugins'
109 -import { UvIndex } from '@vicons/carbon'  
110 import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore' 110 import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
111 import { EditCanvasConfigEnum } from '@/store/modules/chartEditStore/chartEditStore.d' 111 import { EditCanvasConfigEnum } from '@/store/modules/chartEditStore/chartEditStore.d'
112 import { CreateColorRender } from '../CreateColorRender/index' 112 import { CreateColorRender } from '../CreateColorRender/index'
  113 +import { useTargetData } from "@/views/chart/ContentConfigurations/components/hooks/useTargetData.hook"
  114 +
  115 +
113 116
114 const props = defineProps({ 117 const props = defineProps({
115 - modelShow: Boolean 118 + modelShow: Boolean,
  119 + applicationGroup: Boolean,
116 }) 120 })
117 const emit = defineEmits(['update:modelShow', 'editSaveHandle']) 121 const emit = defineEmits(['update:modelShow', 'editSaveHandle'])
118 const { DuplicateOutlineIcon, TrashIcon, ArrowDownIcon } = icon.ionicons5 122 const { DuplicateOutlineIcon, TrashIcon, ArrowDownIcon } = icon.ionicons5
119 123
  124 +const { targetData } = useTargetData()
  125 +
120 type ColorType = { 126 type ColorType = {
121 id: string 127 id: string
122 name: string 128 name: string
@@ -161,6 +167,7 @@ const selectThemeColor = computed(() => chartEditStore.getEditCanvasConfig.chart @@ -161,6 +167,7 @@ const selectThemeColor = computed(() => chartEditStore.getEditCanvasConfig.chart
161 167
162 // 选择 168 // 选择
163 const selectHandle = (item: ColorType) => { 169 const selectHandle = (item: ColorType) => {
  170 + targetData.value.colors = item
164 if (item.id === selectColorId.value) return 171 if (item.id === selectColorId.value) return
165 if (updateColor.value !== undefined) { 172 if (updateColor.value !== undefined) {
166 goDialog({ 173 goDialog({
@@ -281,6 +288,11 @@ const closeHandle = () => { @@ -281,6 +288,11 @@ const closeHandle = () => {
281 const colorBackgroundImage = (item: ColorType) => { 288 const colorBackgroundImage = (item: ColorType) => {
282 return `linear-gradient(to right, ${item.color[0]} 0%, ${item.color[5]} 100%)` 289 return `linear-gradient(to right, ${item.color[0]} 0%, ${item.color[5]} 100%)`
283 } 290 }
  291 +
  292 +//应用此分组
  293 +const applicationGroupHandle = () => {
  294 + closeHandle()
  295 +}
284 </script> 296 </script>
285 297
286 <style scoped lang="scss"> 298 <style scoped lang="scss">
@@ -11,6 +11,7 @@ interface Value { @@ -11,6 +11,7 @@ interface Value {
11 startTs?: Nullable<number> 11 startTs?: Nullable<number>
12 endTs?: Nullable<number> 12 endTs?: Nullable<number>
13 limit?: Nullable<number> 13 limit?: Nullable<number>
  14 + shortcutsSelect?: Nullable<boolean>
14 } 15 }
15 16
16 const props = withDefaults( 17 const props = withDefaults(
@@ -32,24 +33,43 @@ const timePeriod = ref<Nullable<[number, number]>>(null) @@ -32,24 +33,43 @@ const timePeriod = ref<Nullable<[number, number]>>(null)
32 const agg = ref() 33 const agg = ref()
33 const interval = ref() 34 const interval = ref()
34 const limit = ref(7) 35 const limit = ref(7)
  36 +//区分是否是从快捷选项里选择的
  37 +const shortcutsSelect = ref(false)
35 const rangeShortcuts = { 38 const rangeShortcuts = {
36 昨天: () => { 39 昨天: () => {
  40 + shortcutsSelect.value = true
37 return [ 41 return [
38 dayjs().startOf('day').valueOf(), 42 dayjs().startOf('day').valueOf(),
39 dayjs().endOf('day').valueOf() 43 dayjs().endOf('day').valueOf()
40 ] as const 44 ] as const
41 }, 45 },
42 最近7天: () => { 46 最近7天: () => {
  47 + shortcutsSelect.value = true
43 return [ 48 return [
44 dayjs().subtract(6, 'day').startOf('day').valueOf(), 49 dayjs().subtract(6, 'day').startOf('day').valueOf(),
45 dayjs().endOf('day').valueOf() 50 dayjs().endOf('day').valueOf()
46 ] as const 51 ] as const
47 }, 52 },
48 最近30天: () => { 53 最近30天: () => {
  54 + shortcutsSelect.value = true
49 return [ 55 return [
50 dayjs().subtract(29, 'day').startOf('day').valueOf(), 56 dayjs().subtract(29, 'day').startOf('day').valueOf(),
51 dayjs().endOf('day').valueOf() 57 dayjs().endOf('day').valueOf()
52 ] as const 58 ] as const
  59 + },
  60 + 本周: () => {
  61 + shortcutsSelect.value = true
  62 + return [
  63 + dayjs().startOf('week').add(1, 'day').valueOf(),
  64 + dayjs().endOf('week').add(1, 'day').valueOf(),
  65 + ] as const
  66 + },
  67 + 本月: () => {
  68 + shortcutsSelect.value = true
  69 + return [
  70 + dayjs().startOf('month').valueOf(),
  71 + dayjs().endOf('month').valueOf(),
  72 + ] as const
53 } 73 }
54 } 74 }
55 75
@@ -74,10 +94,15 @@ const getIntervalTimeOptions = computed(() => { @@ -74,10 +94,15 @@ const getIntervalTimeOptions = computed(() => {
74 return getRangeOptions(diff) 94 return getRangeOptions(diff)
75 }) 95 })
76 96
  97 +const handleTimeRangeBlur = () => {
  98 + //从面板里面选择
  99 + shortcutsSelect.value = false
  100 +}
  101 +
77 const handleTimePerionChange = (value: number[]) => { 102 const handleTimePerionChange = (value: number[]) => {
78 const [startTs, endTs] = value || [] 103 const [startTs, endTs] = value || []
79 - emit('update:value', {...props.value, startTs, endTs, interval: null})  
80 - emit('change', {...props.value || {}, startTs, endTs, interval: null}) 104 + emit('update:value', {...props.value, startTs, endTs, interval: null, shortcutsSelect: shortcutsSelect.value})
  105 + emit('change', {...props.value || {}, startTs, endTs, interval: null, shortcutsSelect: shortcutsSelect.value})
81 } 106 }
82 107
83 const handleAggChange = (value: string) => { 108 const handleAggChange = (value: string) => {
@@ -120,6 +145,7 @@ watch(() => props.value, (target) => { @@ -120,6 +145,7 @@ watch(() => props.value, (target) => {
120 <NFormItem :show-label="false"> 145 <NFormItem :show-label="false">
121 <NDatePicker :shortcuts="rangeShortcuts" v-model:value="timePeriod" type="datetimerange" 146 <NDatePicker :shortcuts="rangeShortcuts" v-model:value="timePeriod" type="datetimerange"
122 placeholder="请选择时间范围" 147 placeholder="请选择时间范围"
  148 + @blur="handleTimeRangeBlur"
123 @update-value="handleTimePerionChange" clearable 149 @update-value="handleTimePerionChange" clearable
124 :default-time="['00:00:00', '23:59:59']"></NDatePicker> 150 :default-time="['00:00:00', '23:59:59']"></NDatePicker>
125 </NFormItem> 151 </NFormItem>
@@ -6,10 +6,6 @@ @@ -6,10 +6,6 @@
6 <n-code word-wrap :code="toString(targetData.option.dataset)" language="json"></n-code> 6 <n-code word-wrap :code="toString(targetData.option.dataset)" language="json"></n-code>
7 </n-card> 7 </n-card>
8 <n-tag type="info"> 目前支持实时多属性 </n-tag> 8 <n-tag type="info"> 目前支持实时多属性 </n-tag>
9 - <!-- <n-tag type="warning">示例:res.xxxx</n-tag> -->  
10 - <!-- <span>目前支持实时多属性</span> -->  
11 - <!-- <n-input type="textarea" @input="handleTestInput($event, option)" size="small" placeholder="请输入"></n-input>  
12 - <n-code word-wrap :code="toString(testInputValue)" language="json"></n-code> -->  
13 <n-divider /> 9 <n-divider />
14 <div v-for="(item, index) in groupList" :key="item.key + index"> 10 <div v-for="(item, index) in groupList" :key="item.key + index">
15 <n-space justify="space-between"> 11 <n-space justify="space-between">
@@ -28,7 +24,6 @@ @@ -28,7 +24,6 @@
28 </n-space> 24 </n-space>
29 <n-space vertical justify="space-between"> 25 <n-space vertical justify="space-between">
30 <n-ellipsis>数据内容 </n-ellipsis> 26 <n-ellipsis>数据内容 </n-ellipsis>
31 - <!-- @update:value="handleInput(groupList!, item.id, $event)" -->  
32 <n-input 27 <n-input
33 type="textarea" 28 type="textarea"
34 size="small" 29 size="small"
@@ -52,11 +47,11 @@ import { SelectOption } from 'naive-ui' @@ -52,11 +47,11 @@ import { SelectOption } from 'naive-ui'
52 47
53 const { targetData } = useTargetData() 48 const { targetData } = useTargetData()
54 49
55 -const { groupList, option } = toRefs(targetData.value) 50 +const { groupList, option } = toRefs(targetData.value as unknown as Recordable)
56 51
57 const saveHistoryInputValueList = ref<saveHistoryInputValueListType>([]) 52 const saveHistoryInputValueList = ref<saveHistoryInputValueListType>([])
58 53
59 -const handleSelectDataKey = (key:string, options:SelectOption[], currentComponentId:string, groupList:CreateComponentType[]) => { 54 +const handleSelectDataKey = (key:string, _:SelectOption[], currentComponentId:string, groupList:CreateComponentType[]) => {
60 saveHistoryInputValueList.value.unshift({ 55 saveHistoryInputValueList.value.unshift({
61 id:currentComponentId, 56 id:currentComponentId,
62 inputValue:key 57 inputValue:key
@@ -64,14 +59,6 @@ const handleSelectDataKey = (key:string, options:SelectOption[], currentComponen @@ -64,14 +59,6 @@ const handleSelectDataKey = (key:string, options:SelectOption[], currentComponen
64 handleGroupListById(groupList, currentComponentId, key, option.value.dataset) 59 handleGroupListById(groupList, currentComponentId, key, option.value.dataset)
65 } 60 }
66 61
67 -// const handleInput = (groupList: CreateComponentType[], id: string, inputValue: string) => {  
68 -// saveHistoryInputValueList.value.unshift({  
69 -// id,  
70 -// inputValue  
71 -// })  
72 -// handleGroupListById(groupList, id, inputValue, option.value.dataset)  
73 -// }  
74 -  
75 const executeFn = (inputValue: string, dataset: any) => { 62 const executeFn = (inputValue: string, dataset: any) => {
76 try { 63 try {
77 return Function('res', `return ${dataset[inputValue]}`)(dataset) 64 return Function('res', `return ${dataset[inputValue]}`)(dataset)
@@ -38,7 +38,7 @@ @@ -38,7 +38,7 @@
38 :is="item.chartConfig.chartKey" 38 :is="item.chartConfig.chartKey"
39 :chartConfig="item" 39 :chartConfig="item"
40 :themeSetting="themeSetting" 40 :themeSetting="themeSetting"
41 - :themeColor="themeColor" 41 + :themeColor="item.colors ? item.colors : themeColor"
42 :style="{ 42 :style="{
43 ...useSizeStyle(item.attr), 43 ...useSizeStyle(item.attr),
44 ...getFilterStyle(item.styles), 44 ...getFilterStyle(item.styles),
@@ -61,7 +61,6 @@ const rangeModelStyle = computed(() => { @@ -61,7 +61,6 @@ const rangeModelStyle = computed(() => {
61 @include fetch-bg-color('background-color2'); 61 @include fetch-bg-color('background-color2');
62 @include go(edit-range-model) { 62 @include go(edit-range-model) {
63 z-index: -1; 63 z-index: -1;
64 - position: absolute;  
65 left: 0; 64 left: 0;
66 top: 0; 65 top: 0;
67 } 66 }
@@ -28,7 +28,7 @@ @@ -28,7 +28,7 @@
28 @contextmenu="handleContextMenu($event, item, optionsHandle)"> 28 @contextmenu="handleContextMenu($event, item, optionsHandle)">
29 <component class="edit-content-chart" :class="animationsClass(item.styles.animations)" 29 <component class="edit-content-chart" :class="animationsClass(item.styles.animations)"
30 :is="item.chartConfig.chartKey" :chartConfig="item" :themeSetting="themeSetting" 30 :is="item.chartConfig.chartKey" :chartConfig="item" :themeSetting="themeSetting"
31 - :themeColor="themeColor" :style="{ 31 + :themeColor="item.colors ? item.colors : themeColor" :style="{
32 ...useSizeStyle(item.attr), 32 ...useSizeStyle(item.attr),
33 ...getFilterStyle(item.styles), 33 ...getFilterStyle(item.styles),
34 ...getTransformStyle(item.styles), 34 ...getTransformStyle(item.styles),
@@ -24,7 +24,7 @@ @@ -24,7 +24,7 @@
24 :id="item.id" 24 :id="item.id"
25 :chartConfig="item" 25 :chartConfig="item"
26 :themeSetting="themeSetting" 26 :themeSetting="themeSetting"
27 - :themeColor="themeColor" 27 + :themeColor="item.colors ? item.colors : themeColor"
28 :style="{ 28 :style="{
29 ...getSizeStyle(item.attr), 29 ...getSizeStyle(item.attr),
30 ...getFilterStyle(item.styles), 30 ...getFilterStyle(item.styles),
@@ -20,7 +20,7 @@ @@ -20,7 +20,7 @@
20 :groupData="(item as CreateComponentGroupType)" 20 :groupData="(item as CreateComponentGroupType)"
21 :groupIndex="index" 21 :groupIndex="index"
22 :themeSetting="themeSetting" 22 :themeSetting="themeSetting"
23 - :themeColor="themeColor" 23 + :themeColor="item.colors ? item.colors : themeColor"
24 ></preview-render-group> 24 ></preview-render-group>
25 25
26 <!-- 单组件 --> 26 <!-- 单组件 -->
@@ -30,7 +30,7 @@ @@ -30,7 +30,7 @@
30 :id="item.id" 30 :id="item.id"
31 :chartConfig="item" 31 :chartConfig="item"
32 :themeSetting="themeSetting" 32 :themeSetting="themeSetting"
33 - :themeColor="themeColor" 33 + :themeColor="item.colors ? item.colors : themeColor"
34 :style="{ 34 :style="{
35 ...getSizeStyle(item.attr), 35 ...getSizeStyle(item.attr),
36 ...getFilterStyle(item.styles), 36 ...getFilterStyle(item.styles),