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 21 GET_ATTRBUTELIST = '/device/attributes/',
22 22 GET_DEVICE_LATEST = '/plugins/telemetry/DEVICE/',
23 23 DEVICE_ATTR = '/device/attributes',
  24 + ALARM_LIST = '/alarm',
24 25 }
25 26
26 27 export const getDictItemByCode = (value: string) => {
... ... @@ -152,3 +153,10 @@ export const getProfileAttrs = (params: { deviceProfileId: string; dataType?: st
152 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 93 }
94 94
95 95 const handleParams = (Params: Recordable) => {
  96 + Reflect.deleteProperty(Params, 'attrName')
96 97 if (Params.keys && Params?.keys?.length) {
97 98 // 过滤无效参数
98 99 Reflect.deleteProperty(Params, 'attrName')
... ...
... ... @@ -164,6 +164,14 @@
164 164 <template #header>
165 165 <n-switch v-model:value="yAxis.show" size="small"></n-switch>
166 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 175 <setting-item-box name="单位">
168 176 <setting-item name="名称">
169 177 <n-input v-model:value="yAxis.name" size="small"></n-input>
... ... @@ -290,11 +298,40 @@
290 298 </setting-item-box>
291 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 331 <collapse-item v-if="visualMap" name="视觉映射">
294 332 <template #header>
295 333 <n-switch v-model:value="visualMap.show" size="small"></n-switch>
296 334 </template>
297   -
298 335 <setting-item-box name="范围">
299 336 <setting-item name="最小值">
300 337 <n-input-number v-model:value="visualMap.min" size="small"></n-input-number>
... ... @@ -336,15 +373,19 @@
336 373 </template>
337 374
338 375 <script setup lang="ts">
339   -import { PropType, computed, watch } from 'vue'
  376 +import { PropType, computed, watch, ref } from 'vue'
340 377 import { GlobalThemeJsonType } from '@/settings/chartThemes/index'
341 378 import { axisConfig, legendConfig } from '@/packages/chartConfiguration/echarts/index'
342 379 import { CollapseItem, SettingItemBox, SettingItem, GlobalSettingPosition } from '@/components/Pages/ChartItemSetting'
343 380 import { icon } from '@/plugins'
344 381 import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
345 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 390 const props = defineProps({
350 391 optionData: {
... ... @@ -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 406 const chartEditStore = useChartEditStore()
362 407 const themeSetting = computed(() => {
363 408 const chartThemeSetting = chartEditStore.getEditCanvasConfig.chartThemeSetting
... ... @@ -373,6 +418,13 @@ const xAxis = computed(() => {
373 418 })
374 419
375 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 428 return props.optionData.yAxis
377 429 })
378 430
... ... @@ -401,4 +453,85 @@ watch(() => legend.value && legend.value.textStyle.color, (newVal) => {
401 453 immediate: true,
402 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 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 73 let endTsValue = null
74 74 const {requestParams} = toRaw(targetComponent.request)
75 75 const {Params} = requestParams
76   - const {entityType, startTs, endTs} = Params
  76 + const {startTs, endTs, shortcutsSelect} = Params
77 77 let days = Math.ceil(((endTs as unknown as number) - (startTs as unknown as number)) / (1 * 60 * 60 * 24 * 1000))
78 78 const ShortcutsDays = [1, 7, 30]
79   - if (entityType === 'DEVICE') {
  79 + // shortcutsSelect为真
  80 + if (shortcutsSelect) {
80 81 //等于这三个,说明是从快捷选项里面选的
81 82 if(ShortcutsDays.includes(days)) {
82 83 days = days <= 2 ? 1 : days<= 8 ? 7 : 30
... ... @@ -85,12 +86,12 @@ export const useChartDataFetch = (
85 86 endTsValue = dayjs().endOf('day').valueOf()
86 87 ;(toRaw(targetComponent.request).requestParams.Params.startTs as unknown as number) = startTsValue as number
87 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 95 const res = await customRequest(toRaw(targetComponent.request))
95 96 if (res) {
96 97 try {
... ...
1 1 /**
2   - * 重写select下拉框联动
  2 + * 重写select下拉框联动(下拉选择和输入框共用此hook)
3 3 */
4 4 import { toRefs } from 'vue'
5 5 import { CreateComponentType } from '@/packages/index.d'
... ... @@ -13,7 +13,8 @@ export const useChartInteract = (
13 13 chartConfig: CreateComponentType,
14 14 useChartEditStore: ChartEditStoreType,
15 15 param: { [T: string]: any },
16   - interactEventOn: string
  16 + interactEventOn: string,
  17 + attrNames?: string[]
17 18 ) => {
18 19 const chartEditStore = useChartEditStore()
19 20 const { interactEvents } = chartConfig.events
... ... @@ -34,12 +35,13 @@ export const useChartInteract = (
34 35 if (groupItem.id === item.interactComponentId) {
35 36 const { Params, Header } = toRefs(groupItem.request.requestParams)
36 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 58 }
57 59 //
58 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 9 type: 'bar',
10 10 barWidth: null,
11 11 label: {
12   - show: true,
  12 + show: false,
13 13 position: 'right',
14 14 color: '#fff',
15 15 fontSize: 12
... ... @@ -33,6 +33,7 @@ export const option = {
33 33 type: 'value'
34 34 },
35 35 yAxis: {
  36 + showRange: false,
36 37 show: true,
37 38 type: 'category'
38 39 },
... ...
... ... @@ -51,7 +51,10 @@ use([DatasetComponent, CanvasRenderer, BarChart, GridComponent, TooltipComponent
51 51 const replaceMergeArr = ref<string[]>()
52 52
53 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 60 // dataset 无法变更条数的补丁
... ...
... ... @@ -11,7 +11,7 @@ export const barSeriesItem = {
11 11 type: 'bar',
12 12 barWidth: 15,
13 13 label: {
14   - show: true,
  14 + show: false,
15 15 position: 'top',
16 16 color: '#fff',
17 17 fontSize: 12
... ... @@ -26,7 +26,7 @@ export const lineSeriesItem = {
26 26 type: 'line',
27 27 symbol: 'circle',
28 28 label: {
29   - show: true,
  29 + show: false,
30 30 position: 'top',
31 31 color: '#fff',
32 32 fontSize: 12
... ...
... ... @@ -31,7 +31,7 @@ const options = {
31 31 smooth: false,
32 32 symbolSize: 5, //设定实心点的大小
33 33 label: {
34   - show: true,
  34 + show: false,
35 35 position: 'top',
36 36 color: '#fff',
37 37 fontSize: 12
... ...
... ... @@ -15,6 +15,7 @@ export const option = {
15 15 data: dataJson.xAxis
16 16 },
17 17 yAxis: {
  18 + showRange: false,
18 19 data: dataJson.yAxis
19 20 },
20 21 visualMap: {
... ...
... ... @@ -52,7 +52,10 @@ use([
52 52 ])
53 53
54 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 61 const vChartRef = ref<typeof VChart>()
... ...
... ... @@ -3,7 +3,7 @@
3 3 <n-input :style="`width:${w}px;`" type="text"
4 4 v-model:value="option.value.dataset"
5 5 placeholder="请输入"
6   - @change="onChange">
  6 + @update="onChange">
7 7
8 8 </n-input>
9 9 </div>
... ... @@ -13,7 +13,7 @@
13 13 import { PropType, toRefs, shallowReactive, watch } from 'vue'
14 14 import { CreateComponentType } from '@/packages/index.d'
15 15 import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
16   -import { useChartInteract } from '@/hooks'
  16 +import { useChartInteract } from '@/hooks/external/useChartSelectInteract.hook'
17 17 import { InteractEventOn } from '@/enums/eventEnum'
18 18 import { ComponentInteractParamsEnum } from './interact'
19 19
... ... @@ -33,13 +33,14 @@ const option = shallowReactive({
33 33 })
34 34
35 35 const onChange = (v: string) => {
36   - if(v == undefined) return;
  36 + // if(v == undefined) return;
37 37 // 存储到联动数据
38 38 useChartInteract(
39 39 props.chartConfig,
40 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 14 type: 'bar',
15 15 barWidth: 15,
16 16 label: {
17   - show: true,
  17 + show: false,
18 18 position: 'top',
19 19 color: '#fff',
20 20 fontSize: 12
... ...
... ... @@ -112,8 +112,8 @@ watch(
112 112 props.chartConfig.option.series.push(...seriesArr)
113 113 }
114 114 replaceMergeArr.value = ['series']
  115 + useEchartsMapLegend(props.chartConfig, props.chartConfig.option.series)
115 116 nextTick(() => {
116   - useEchartsMapLegend(props.chartConfig, props.chartConfig.option.series)
117 117 replaceMergeArr.value = []
118 118 })
119 119 }
... ... @@ -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 252 updateVChart(newData)
251 253 })
252 254
... ...
... ... @@ -8,7 +8,7 @@ export const includes = ['legend', 'xAxis', 'yAxis', 'grid']
8 8 export const seriesItem = {
9 9 type: 'line',
10 10 label: {
11   - show: true,
  11 + show: false,
12 12 position: 'top',
13 13 color: '#fff',
14 14 fontSize: 12
... ...
... ... @@ -112,8 +112,8 @@ watch(
112 112 props.chartConfig.option.series.push(...seriesArr)
113 113 }
114 114 replaceMergeArr.value = ['series']
  115 + useEchartsMapLegend(props.chartConfig, props.chartConfig.option.series)
115 116 nextTick(() => {
116   - useEchartsMapLegend(props.chartConfig, props.chartConfig.option.series)
117 117 replaceMergeArr.value = []
118 118 })
119 119 }
... ... @@ -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 251 updateVChart(newData)
250 252 })
251 253
... ...
1 1 <template>
2   - <div>
  2 + <div class="device-history-query">
3 3 <n-space vertical>
4 4 <div class="form">
5 5 <n-date-picker size="small" :to="true" clearable v-model:value="queryCondition.timeRange" type="datetimerange"
... ... @@ -96,6 +96,27 @@ const option = computed(() => {
96 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 120 // dataset 无法变更条数的补丁
100 121 watch(
101 122 () => props.chartConfig.option.dataset,
... ... @@ -122,8 +143,8 @@ watch(
122 143 props.chartConfig.option.series.push(...seriesArr)
123 144 }
124 145 replaceMergeArr.value = ['series']
  146 + useEchartsMapLegend(props.chartConfig, props.chartConfig.option.series)
125 147 nextTick(() => {
126   - useEchartsMapLegend(props.chartConfig, props.chartConfig.option.series)
127 148 replaceMergeArr.value = []
128 149 })
129 150 }
... ...
... ... @@ -12,7 +12,7 @@ export const seriesItem = {
12 12 smooth: false,
13 13 symbolSize: 5, //设定实心点的大小
14 14 label: {
15   - show: true,
  15 + show: false,
16 16 position: 'top',
17 17 color: '#fff',
18 18 fontSize: 12
... ...
... ... @@ -214,8 +214,8 @@ watch(
214 214 props.chartConfig.option.series.push(...seriesArr)
215 215 }
216 216 replaceMergeArr.value = ['series']
  217 + useEchartsMapLegend(props.chartConfig, props.chartConfig.option.series)
217 218 nextTick(() => {
218   - useEchartsMapLegend(props.chartConfig, props.chartConfig.option.series)
219 219 replaceMergeArr.value = []
220 220 })
221 221 }
... ... @@ -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 281 updateVChart(newData)
280 282 })
281 283
... ...
... ... @@ -43,13 +43,14 @@ onMounted(async () => {
43 43 label: '中国',
44 44 value: 'china'
45 45 })
46   - onHandleSelectProvince('china')
  46 + onHandleSelectProvince(props.optionData?.mapRegion.saveSelect['provinceValue'])
47 47 for (let i in selectValues) Reflect.set(selectValues, i, props.optionData?.mapRegion.saveSelect[i])
48 48 })
49 49
50 50 const onHandleSelectProvince = async (value: number | string) => {
51 51 selectValues.cityValue = null
52 52 selectValues.countyValue = null
  53 + selectOptions.cityOptions = []
53 54 if (value === 'china') return (selectValues.levelStr = areaEnum.COUNTRY)
54 55 selectOptions.cityOptions = await getAreaLists(areaEnum.CITY, value)
55 56 selectValues.levelStr = areaEnum.PROVINCE
... ...
  1 +/**
  2 + * 单个组件全屏
  3 + * @param domName
  4 + * @param htmlName
  5 + */
  6 +
1 7 export const useFullScreen = (domName: any, htmlName: HTMLHtmlElement) => {
2 8 const isFullScreen = document.fullscreenElement
  9 +
3 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 25 if (isFullScreen) {
6 26 if (document.exitFullscreen) {
7 27 document.exitFullscreen()
... ... @@ -11,18 +31,19 @@ export const useFullScreen = (domName: any, htmlName: HTMLHtmlElement) => {
11 31 //兼容其他浏览器
12 32 if (domName.requestFullscreen) {
13 33 domName.requestFullscreen()
14   - domName.style.background = currentDatkTheme === 'light' ? 'white' : '#18181c'
  34 + setDomNameAndStyle()
15 35 } else if (domName.mozRequestFullScreen) {
16 36 domName.mozRequestFullScreen()
17   - domName.style.background = currentDatkTheme === 'light' ? 'white' : '#18181c'
  37 + setDomNameAndStyle()
18 38 } else if (domName.webkitRequestFullscreen) {
19 39 domName.webkitRequestFullscreen()
20   - domName.style.background = currentDatkTheme === 'light' ? 'white' : '#18181c'
  40 + setDomNameAndStyle()
21 41 } else if (domName.msRequestFullscreen) {
22 42 domName.msRequestFullscreen()
23   - domName.style.background = currentDatkTheme === 'light' ? 'white' : '#18181c'
  43 + setDomNameAndStyle()
24 44 }
25 45 }
  46 +
26 47 //fix 浏览器监听esc退出
27 48 function exitHandler() {
28 49 if (
... ... @@ -33,6 +54,7 @@ export const useFullScreen = (domName: any, htmlName: HTMLHtmlElement) => {
33 54 domName.style.background = currentDatkTheme === 'light' ? '' : ''
34 55 }
35 56 }
  57 +
36 58 // 监听fullscreenchange事件(全屏模式的变化)
37 59 if (document.addEventListener) {
38 60 document.addEventListener('webkitfullscreenchange', exitHandler, false)
... ...
... ... @@ -10,13 +10,15 @@
10 10 </template>
11 11
12 12 <script setup lang="ts">
13   -import { PropType, toRefs, shallowReactive, watch } from 'vue'
  13 +import { PropType, toRefs, shallowReactive, watch, ref } from 'vue'
14 14 import { CreateComponentType } from '@/packages/index.d'
15 15 import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
16 16 import { useChartInteract } from '@/hooks/external/useChartSelectInteract.hook'
17 17 import { InteractEventOn } from '@/enums/eventEnum'
18 18 import { ComponentInteractParamsEnum } from './interact'
19 19 import { useChartDataFetch } from '@/hooks'
  20 +import { isObject } from '@/utils/external/is'
  21 +import { SelectOption } from 'naive-ui'
20 22
21 23 const props = defineProps({
22 24 chartConfig: {
... ... @@ -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 53 props.chartConfig,
44 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 59 // 特殊处理 只针对两个下拉选择器,一个是产品下拉,一个是设备下拉,选择了产品,存储到sessionStorage里,用来判断预览时点击产品下拉,清除设备下拉值
49 60 if (window.location.href.includes('preview')) {
... ... @@ -56,7 +67,7 @@ watch(
56 67 () => props.chartConfig.option,
57 68 (newData: any) => {
58 69 option.value = newData
59   - onChange(newData.selectValue)
  70 + updateChartInteract(newData.selectValue, cacheOptions.value)
60 71 },
61 72 {
62 73 immediate: true,
... ...
... ... @@ -42,15 +42,14 @@ const checkedKeys = ref([])
42 42
43 43 const onClick = (v: string[]) => {
44 44 // nTreeRef.value?.selectedKeys(v)
45   - console.log(nTreeRef.value)
46   - console.log(v)
47 45 // nTreeRef.value?.onUpdateCheckedKeys(v)
48 46 if (Array.isArray(v) && v.length == 0) return
49 47 useChartInteract(
50 48 props.chartConfig,
51 49 useChartEditStore,
52 50 { [ComponentInteractParamsEnum.DATA]: v[0] },
53   - InteractEventOn.CHANGE
  51 + InteractEventOn.CHANGE,
  52 + []
54 53 )
55 54 }
56 55 </script>
... ...
... ... @@ -75,7 +75,7 @@ const getConfigurationOptions = async (params: object) => {
75 75 watch(
76 76 () => props.optionData.pages,
77 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 81 deep: true,
... ... @@ -84,7 +84,7 @@ watch(
84 84 )
85 85
86 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 90 const handleUpdateValue = (value: string, options: ConfigurationItemType) => {
... ...
... ... @@ -55,7 +55,7 @@
55 55 </template>
56 56
57 57 <script setup lang="ts">
58   -import { PropType, ref, onMounted } from 'vue'
  58 +import { PropType, ref, onMounted, watch } from 'vue'
59 59 import { AccessMode, option, sourceTypeEnum, videoListInterface, sourceTypeNameEnum, Dataset } from './config'
60 60 import { CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting'
61 61 import { NTreeSelect } from 'naive-ui'
... ... @@ -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 151 onMounted(() => {
139 152 if (props.optionData.sourceType === sourceTypeEnum.PLATFORM) {
140 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 69 import { Decorates25Config } from '@/packages/components/external/Decorates/Decorates/Decorates25'
70 70 import { Decorates26Config } from '@/packages/components/external/Decorates/Decorates/Decorates26'
71 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 157
157 158 //列表
158 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 185 }
186 186 }
187 187
  188 +export interface ChartCustomColor {
  189 + name: string
  190 + color: string[]
  191 +}
  192 +
  193 +
188 194 export interface CreateComponentType extends PublicConfigType, requestConfig {
189 195 key: string
190 196 chartConfig: ConfigType
... ... @@ -192,6 +198,7 @@ export interface CreateComponentType extends PublicConfigType, requestConfig {
192 198 groupList?: Array<CreateComponentType>
193 199 saveHistoryInput?: string // THINGS_KIT 新增一个接口字段 saveHistoryInput,用于记录当前组件id和输入框的内容,这里不能重写,有很多地方引用到的,这里升级版本有冲突
194 200 wsOriginalMessage?: any
  201 + colors?: ChartCustomColor // THINGS_KIT 新增一个接口字段 用于组件自定义颜色,一般是图表组件
195 202 }
196 203
197 204 // 组件成组实例类
... ...
... ... @@ -48,6 +48,9 @@
48 48 }
49 49 },
50 50 "yAxis": {
  51 + "showRange":true,
  52 + "min": 0,
  53 + "max": 200,
51 54 "show": true,
52 55 "name": "",
53 56 "nameGap": 15,
... ...
... ... @@ -40,7 +40,7 @@ import { ref, computed } from 'vue'
40 40 import cloneDeep from 'lodash/cloneDeep'
41 41 import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
42 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 44 import { useDesignStore } from '@/store/modules/designStore/designStore'
45 45 import { loadAsyncComponent, colorCustomMerge } from '@/utils'
46 46 import { icon } from '@/plugins'
... ...
... ... @@ -93,7 +93,8 @@
93 93 <!-- 底部 -->
94 94 <template #action>
95 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 98 </n-space>
98 99 </template>
99 100 </n-card>
... ... @@ -101,22 +102,27 @@
101 102 </template>
102 103
103 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 106 import cloneDeep from 'lodash/cloneDeep'
106 107 import noData from '@/assets/images/canvas/noData.png'
107 108 import { getUUID, goDialog } from '@/utils'
108 109 import { icon } from '@/plugins'
109   -import { UvIndex } from '@vicons/carbon'
110 110 import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
111 111 import { EditCanvasConfigEnum } from '@/store/modules/chartEditStore/chartEditStore.d'
112 112 import { CreateColorRender } from '../CreateColorRender/index'
  113 +import { useTargetData } from "@/views/chart/ContentConfigurations/components/hooks/useTargetData.hook"
  114 +
  115 +
113 116
114 117 const props = defineProps({
115   - modelShow: Boolean
  118 + modelShow: Boolean,
  119 + applicationGroup: Boolean,
116 120 })
117 121 const emit = defineEmits(['update:modelShow', 'editSaveHandle'])
118 122 const { DuplicateOutlineIcon, TrashIcon, ArrowDownIcon } = icon.ionicons5
119 123
  124 +const { targetData } = useTargetData()
  125 +
120 126 type ColorType = {
121 127 id: string
122 128 name: string
... ... @@ -161,6 +167,7 @@ const selectThemeColor = computed(() => chartEditStore.getEditCanvasConfig.chart
161 167
162 168 // 选择
163 169 const selectHandle = (item: ColorType) => {
  170 + targetData.value.colors = item
164 171 if (item.id === selectColorId.value) return
165 172 if (updateColor.value !== undefined) {
166 173 goDialog({
... ... @@ -281,6 +288,11 @@ const closeHandle = () => {
281 288 const colorBackgroundImage = (item: ColorType) => {
282 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 296 </script>
285 297
286 298 <style scoped lang="scss">
... ...
... ... @@ -11,6 +11,7 @@ interface Value {
11 11 startTs?: Nullable<number>
12 12 endTs?: Nullable<number>
13 13 limit?: Nullable<number>
  14 + shortcutsSelect?: Nullable<boolean>
14 15 }
15 16
16 17 const props = withDefaults(
... ... @@ -32,24 +33,43 @@ const timePeriod = ref<Nullable<[number, number]>>(null)
32 33 const agg = ref()
33 34 const interval = ref()
34 35 const limit = ref(7)
  36 +//区分是否是从快捷选项里选择的
  37 +const shortcutsSelect = ref(false)
35 38 const rangeShortcuts = {
36 39 昨天: () => {
  40 + shortcutsSelect.value = true
37 41 return [
38 42 dayjs().startOf('day').valueOf(),
39 43 dayjs().endOf('day').valueOf()
40 44 ] as const
41 45 },
42 46 最近7天: () => {
  47 + shortcutsSelect.value = true
43 48 return [
44 49 dayjs().subtract(6, 'day').startOf('day').valueOf(),
45 50 dayjs().endOf('day').valueOf()
46 51 ] as const
47 52 },
48 53 最近30天: () => {
  54 + shortcutsSelect.value = true
49 55 return [
50 56 dayjs().subtract(29, 'day').startOf('day').valueOf(),
51 57 dayjs().endOf('day').valueOf()
52 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 94 return getRangeOptions(diff)
75 95 })
76 96
  97 +const handleTimeRangeBlur = () => {
  98 + //从面板里面选择
  99 + shortcutsSelect.value = false
  100 +}
  101 +
77 102 const handleTimePerionChange = (value: number[]) => {
78 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 108 const handleAggChange = (value: string) => {
... ... @@ -120,6 +145,7 @@ watch(() => props.value, (target) => {
120 145 <NFormItem :show-label="false">
121 146 <NDatePicker :shortcuts="rangeShortcuts" v-model:value="timePeriod" type="datetimerange"
122 147 placeholder="请选择时间范围"
  148 + @blur="handleTimeRangeBlur"
123 149 @update-value="handleTimePerionChange" clearable
124 150 :default-time="['00:00:00', '23:59:59']"></NDatePicker>
125 151 </NFormItem>
... ...
... ... @@ -6,10 +6,6 @@
6 6 <n-code word-wrap :code="toString(targetData.option.dataset)" language="json"></n-code>
7 7 </n-card>
8 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 9 <n-divider />
14 10 <div v-for="(item, index) in groupList" :key="item.key + index">
15 11 <n-space justify="space-between">
... ... @@ -28,7 +24,6 @@
28 24 </n-space>
29 25 <n-space vertical justify="space-between">
30 26 <n-ellipsis>数据内容 </n-ellipsis>
31   - <!-- @update:value="handleInput(groupList!, item.id, $event)" -->
32 27 <n-input
33 28 type="textarea"
34 29 size="small"
... ... @@ -52,11 +47,11 @@ import { SelectOption } from 'naive-ui'
52 47
53 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 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 55 saveHistoryInputValueList.value.unshift({
61 56 id:currentComponentId,
62 57 inputValue:key
... ... @@ -64,14 +59,6 @@ const handleSelectDataKey = (key:string, options:SelectOption[], currentComponen
64 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 62 const executeFn = (inputValue: string, dataset: any) => {
76 63 try {
77 64 return Function('res', `return ${dataset[inputValue]}`)(dataset)
... ...
... ... @@ -38,7 +38,7 @@
38 38 :is="item.chartConfig.chartKey"
39 39 :chartConfig="item"
40 40 :themeSetting="themeSetting"
41   - :themeColor="themeColor"
  41 + :themeColor="item.colors ? item.colors : themeColor"
42 42 :style="{
43 43 ...useSizeStyle(item.attr),
44 44 ...getFilterStyle(item.styles),
... ...
... ... @@ -61,7 +61,6 @@ const rangeModelStyle = computed(() => {
61 61 @include fetch-bg-color('background-color2');
62 62 @include go(edit-range-model) {
63 63 z-index: -1;
64   - position: absolute;
65 64 left: 0;
66 65 top: 0;
67 66 }
... ...
... ... @@ -28,7 +28,7 @@
28 28 @contextmenu="handleContextMenu($event, item, optionsHandle)">
29 29 <component class="edit-content-chart" :class="animationsClass(item.styles.animations)"
30 30 :is="item.chartConfig.chartKey" :chartConfig="item" :themeSetting="themeSetting"
31   - :themeColor="themeColor" :style="{
  31 + :themeColor="item.colors ? item.colors : themeColor" :style="{
32 32 ...useSizeStyle(item.attr),
33 33 ...getFilterStyle(item.styles),
34 34 ...getTransformStyle(item.styles),
... ...
... ... @@ -24,7 +24,7 @@
24 24 :id="item.id"
25 25 :chartConfig="item"
26 26 :themeSetting="themeSetting"
27   - :themeColor="themeColor"
  27 + :themeColor="item.colors ? item.colors : themeColor"
28 28 :style="{
29 29 ...getSizeStyle(item.attr),
30 30 ...getFilterStyle(item.styles),
... ...
... ... @@ -20,7 +20,7 @@
20 20 :groupData="(item as CreateComponentGroupType)"
21 21 :groupIndex="index"
22 22 :themeSetting="themeSetting"
23   - :themeColor="themeColor"
  23 + :themeColor="item.colors ? item.colors : themeColor"
24 24 ></preview-render-group>
25 25
26 26 <!-- 单组件 -->
... ... @@ -30,7 +30,7 @@
30 30 :id="item.id"
31 31 :chartConfig="item"
32 32 :themeSetting="themeSetting"
33   - :themeColor="themeColor"
  33 + :themeColor="item.colors ? item.colors : themeColor"
34 34 :style="{
35 35 ...getSizeStyle(item.attr),
36 36 ...getFilterStyle(item.styles),
... ...