Commit 34cb6ea2341a5798a7760a13923eace5b5598edf

Authored by xp.Huang
2 parents a56d7ca9 958216db

Merge branch 'ft' into 'main_dev'

chore: 更新go-view基线版本至v1.2.8

See merge request yunteng/thingskit-view!118
Showing 86 changed files with 1909 additions and 390 deletions
... ... @@ -14,7 +14,9 @@ enum Api {
14 14 DEVICE_PROFILE = '/device_profile/me/list',
15 15 DEVICE = '/device',
16 16 VIDEOURL = '/video/url/',
17   - GEOJSONURL = '/map/geo_json/'
  17 + GEOJSONURL = '/map/geo_json/',
  18 + DEVICE_URL = '/device',
  19 + GET_ATTRBUTELIST = '/device/attributes/'
18 20 }
19 21
20 22 export const getDictItemByCode = (value: string) => {
... ... @@ -113,3 +115,15 @@ export const getGeoJsonMap = (code: number, level: string) =>
113 115 defHttp.get({
114 116 url: `${Api.GEOJSONURL}${code}/${level}`
115 117 })
  118 +
  119 +// 获取设备详情
  120 +export const getDeviceDetail = (id: string) =>
  121 + defHttp.get({
  122 + url: Api.DEVICE_URL + `/${id}`
  123 + })
  124 +
  125 +// 获取产品属性
  126 +export const getAttribute = (deviceProfileId: string) =>
  127 + defHttp.get({
  128 + url: `${Api.GET_ATTRBUTELIST}${deviceProfileId}`
  129 + })
... ...
... ... @@ -75,7 +75,7 @@ export const useChartDataFetch = (
75 75 echartsUpdateHandle(value)
76 76 // 更新回调函数
77 77 if (updateCallback) {
78   - updateCallback(value)
  78 + updateCallback(value, targetComponent.request)//为了处理设备最新数据轮播列表,这里传过去当前组件的信息
79 79 }
80 80 } catch (error) {
81 81 console.error(error)
... ...
... ... @@ -49,6 +49,7 @@ export const useChartInteract = (
49 49 Object.keys(item.interactFn).forEach(key => {
50 50 if (Params.value[key]) {
51 51 Params.value[key] = param[item.interactFn[key]]
  52 + console.log(Params.value[key])
52 53 }
53 54 if (Header.value[key]) {
54 55 Header.value[key] = param[item.interactFn[key]]
... ...
... ... @@ -99,7 +99,7 @@ export const originUseChartDataFetch = (
99 99 fetchFn()
100 100 },
101 101 {
102   - immediate: false,
  102 + immediate: true,
103 103 deep: true
104 104 }
105 105 )
... ...
... ... @@ -48,10 +48,10 @@ export const useLifeHandler = (chartConfig: CreateComponentType | CreateComponen
48 48 try {
49 49 return new Function(`
50 50 return (
51   - async function(mouseEvent){
  51 + async function(components,mouseEvent){
52 52 ${fnStr}
53 53 }
54   - )`)()
  54 + )`)().bind(undefined,components)
55 55 } catch (error) {
56 56 console.error(error)
57 57 }
... ...
... ... @@ -19,8 +19,9 @@
19 19 import { LayoutHeader } from '@/layout/components/LayoutHeader'
20 20 /**
21 21 * THINGS_KIT 升级版本这里有冲突
22   - * 源文件 '@/components/GoUserInfo'
23   - * 修改后 '@/components/external/GoUserInfo'
  22 + * 修改引入路径
  23 + * 源文件路径 import { GoUserInfo } from '@/components/GoUserInfo'
  24 + * 修改后路径 import { GoUserInfo } from '@/components/external/GoUserInfo'
24 25 */
25 26 import { GoUserInfo } from '@/components/external/GoUserInfo'
26 27 </script>
... ...
  1 +import { echartOptionProfixHandle, PublicConfigClass } from '@/packages/public'
  2 +import { BarLineConfig } from './index'
  3 +import { CreateComponentType } from '@/packages/index.d'
  4 +import cloneDeep from 'lodash/cloneDeep'
  5 +import dataJson from './data.json'
  6 +
  7 +export const includes = ['legend', 'xAxis', 'yAxis', 'grid']
  8 +// 柱状折线组合图 分别定义series
  9 +// 写死name可以定义legend显示的名称
  10 +export const barSeriesItem = {
  11 + type: 'bar',
  12 + barWidth: 15,
  13 + label: {
  14 + show: true,
  15 + position: 'top',
  16 + color: '#fff',
  17 + fontSize: 12
  18 + },
  19 + itemStyle: {
  20 + color: null,
  21 + borderRadius: 2
  22 + }
  23 +}
  24 +
  25 +export const lineSeriesItem = {
  26 + type: 'line',
  27 + symbol: 'circle',
  28 + label: {
  29 + show: true,
  30 + position: 'top',
  31 + color: '#fff',
  32 + fontSize: 12
  33 + },
  34 + symbolSize: 5, //设定实心点的大小
  35 + itemStyle: {
  36 + color: '#FFE47A',
  37 + borderWidth: 1
  38 + },
  39 + lineStyle: {
  40 + type: 'solid',
  41 + width: 3,
  42 + color: null
  43 + }
  44 +}
  45 +
  46 +export const option = {
  47 + tooltip: {
  48 + show: true,
  49 + trigger: 'axis',
  50 + axisPointer: {
  51 + show: true,
  52 + type: 'shadow'
  53 + }
  54 + },
  55 + legend: {
  56 + data: null
  57 + },
  58 + xAxis: {
  59 + show: true,
  60 + type: 'category'
  61 + },
  62 + yAxis: {
  63 + show: true,
  64 + type: 'value'
  65 + },
  66 + dataset: { ...dataJson },
  67 + series: [barSeriesItem, lineSeriesItem]
  68 +}
  69 +
  70 +export default class Config extends PublicConfigClass implements CreateComponentType {
  71 + public key = BarLineConfig.key
  72 + public chartConfig = cloneDeep(BarLineConfig)
  73 + // 图表配置项
  74 + public option = echartOptionProfixHandle(option, includes)
  75 +}
... ...
  1 +<template>
  2 + <!-- Echarts 全局设置 -->
  3 + <global-setting :optionData="optionData"></global-setting>
  4 + <CollapseItem
  5 + v-for="(item, index) in seriesList"
  6 + :key="index"
  7 + :name="`${item.type == 'bar' ? '柱状图' : '折线图'}`"
  8 + :expanded="true"
  9 + >
  10 + <SettingItemBox name="图形" v-if="item.type == 'bar'">
  11 + <SettingItem name="宽度">
  12 + <n-input-number
  13 + v-model:value="item.barWidth"
  14 + :min="1"
  15 + :max="100"
  16 + size="small"
  17 + placeholder="自动计算"
  18 + ></n-input-number>
  19 + </SettingItem>
  20 + <SettingItem name="圆角">
  21 + <n-input-number v-model:value="item.itemStyle.borderRadius" :min="0" size="small"></n-input-number>
  22 + </SettingItem>
  23 + </SettingItemBox>
  24 + <SettingItemBox name="线条" v-if="item.type == 'line'">
  25 + <SettingItem name="宽度">
  26 + <n-input-number
  27 + v-model:value="item.lineStyle.width"
  28 + :min="1"
  29 + :max="100"
  30 + size="small"
  31 + placeholder="自动计算"
  32 + ></n-input-number>
  33 + </SettingItem>
  34 + <SettingItem name="类型">
  35 + <n-select v-model:value="item.lineStyle.type" size="small" :options="lineConf.lineStyle.type"></n-select>
  36 + </SettingItem>
  37 + </SettingItemBox>
  38 + <SettingItemBox name="实心点" v-if="item.type == 'line'">
  39 + <SettingItem name="大小">
  40 + <n-input-number
  41 + v-model:value="item.symbolSize"
  42 + :min="1"
  43 + :max="100"
  44 + size="small"
  45 + placeholder="自动计算"
  46 + ></n-input-number>
  47 + </SettingItem>
  48 + </SettingItemBox>
  49 + <setting-item-box name="标签">
  50 + <setting-item>
  51 + <n-space>
  52 + <n-switch v-model:value="item.label.show" size="small" />
  53 + <n-text>展示标签</n-text>
  54 + </n-space>
  55 + </setting-item>
  56 + <setting-item name="大小">
  57 + <n-input-number v-model:value="item.label.fontSize" size="small" :min="1"></n-input-number>
  58 + </setting-item>
  59 + <setting-item name="tip颜色">
  60 + <n-color-picker size="small" :modes="['hex']" v-model:value="item.label.color"></n-color-picker>
  61 + </setting-item>
  62 + <setting-item name="位置">
  63 + <n-select
  64 + v-model:value="item.label.position"
  65 + :options="[
  66 + { label: 'top', value: 'top' },
  67 + { label: 'left', value: 'left' },
  68 + { label: 'right', value: 'right' },
  69 + { label: 'bottom', value: 'bottom' }
  70 + ]"
  71 + />
  72 + </setting-item>
  73 + </setting-item-box>
  74 + </CollapseItem>
  75 +</template>
  76 +
  77 +<script setup lang="ts">
  78 +import { PropType, computed } from 'vue'
  79 +import { GlobalSetting, CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting'
  80 +import { lineConf } from '@/packages/chartConfiguration/echarts'
  81 +import { GlobalThemeJsonType } from '@/settings/chartThemes'
  82 +
  83 +const props = defineProps({
  84 + optionData: {
  85 + type: Object as PropType<GlobalThemeJsonType>,
  86 + required: true
  87 + }
  88 +})
  89 +
  90 +const seriesList = computed(() => {
  91 + return props.optionData.series
  92 +})
  93 +</script>
... ...
  1 +{
  2 + "dimensions": ["product", "data1", "data2"],
  3 + "source": [
  4 + {
  5 + "product": "1月",
  6 + "data1": 104,
  7 + "data2": 30
  8 + },
  9 + {
  10 + "product": "2月",
  11 + "data1": 56,
  12 + "data2": 56
  13 + },
  14 + {
  15 + "product": "3月",
  16 + "data1": 136,
  17 + "data2": 36
  18 + },
  19 + {
  20 + "product": "4月",
  21 + "data1": 86,
  22 + "data2": 6
  23 + },
  24 + {
  25 + "product": "5月",
  26 + "data1": 98,
  27 + "data2": 10
  28 + },
  29 + {
  30 + "product": "6月",
  31 + "data1": 86,
  32 + "data2": 70
  33 + },
  34 + {
  35 + "product": "7月",
  36 + "data1": 77,
  37 + "data2": 57
  38 + }
  39 + ]
  40 +}
... ...
  1 +// 公共类型声明
  2 +import { ConfigType, PackagesCategoryEnum, ChartFrameEnum } from '@/packages/index.d'
  3 +// 当前[信息模块]分类声明
  4 +import { ChatCategoryEnum,ChatCategoryEnumName } from '../../index.d'
  5 +
  6 +export const BarLineConfig: ConfigType = {
  7 + key: 'BarLine',
  8 + chartKey: 'VBarLine',
  9 + conKey: 'VCBarLine',
  10 + title: '柱状图 & 折线图',
  11 + category: ChatCategoryEnum.BAR,
  12 + categoryName: ChatCategoryEnumName.BAR,
  13 + package: PackagesCategoryEnum.CHARTS,
  14 + chartFrame: ChartFrameEnum.ECHARTS,
  15 + image: 'bar_line.png'
  16 +}
\ No newline at end of file
... ...
  1 +<template>
  2 + <v-chart
  3 + ref="vChartRef"
  4 + :init-options="initOptions"
  5 + :theme="themeColor"
  6 + :option="option"
  7 + :manual-update="isPreview()"
  8 + autoresize
  9 + ></v-chart>
  10 +</template>
  11 +
  12 +<script setup lang="ts">
  13 +import { ref, computed, watch, PropType, nextTick } from 'vue'
  14 +import VChart from 'vue-echarts'
  15 +import { useCanvasInitOptions } from '@/hooks/useCanvasInitOptions.hook'
  16 +import { use } from 'echarts/core'
  17 +import { CanvasRenderer } from 'echarts/renderers'
  18 +//引入柱状图 折线图
  19 +import { BarChart, LineChart } from 'echarts/charts'
  20 +import config, { includes, barSeriesItem, lineSeriesItem } from './config'
  21 +import { mergeTheme } from '@/packages/public/chart'
  22 +import { useChartDataFetch } from '@/hooks'
  23 +import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
  24 +import { isPreview } from '@/utils'
  25 +import { DatasetComponent, GridComponent, TooltipComponent, LegendComponent } from 'echarts/components'
  26 +
  27 +const props = defineProps({
  28 + themeSetting: {
  29 + type: Object,
  30 + required: true
  31 + },
  32 + themeColor: {
  33 + type: Object,
  34 + required: true
  35 + },
  36 + chartConfig: {
  37 + type: Object as PropType<config>,
  38 + required: true
  39 + }
  40 +})
  41 +
  42 +const initOptions = useCanvasInitOptions(props.chartConfig.option, props.themeSetting)
  43 +
  44 +use([DatasetComponent, CanvasRenderer, BarChart, LineChart, GridComponent, TooltipComponent, LegendComponent])
  45 +
  46 +const replaceMergeArr = ref<string[]>()
  47 +
  48 +const option = computed(() => {
  49 + return mergeTheme(props.chartConfig.option, props.themeSetting, includes)
  50 +})
  51 +
  52 +watch(
  53 + () => props.chartConfig.option.dataset,
  54 + (newData, oldData) => {
  55 + if (newData.dimensions.length !== oldData.dimensions.length) {
  56 + const seriesArr = []
  57 + for (let i = 0; i < newData.dimensions.length - 1; i++) {
  58 + seriesArr.push(barSeriesItem, lineSeriesItem)
  59 + }
  60 + replaceMergeArr.value = ['series']
  61 + props.chartConfig.option.series = seriesArr
  62 + nextTick(() => {
  63 + replaceMergeArr.value = []
  64 + })
  65 + }
  66 + },
  67 + {
  68 + deep: false
  69 + }
  70 +)
  71 +
  72 +const { vChartRef } = useChartDataFetch(props.chartConfig, useChartEditStore)
  73 +</script>
... ...
1 1 import { BarCommonConfig } from './BarCommon/index'
2 2 import { BarCrossrangeConfig } from './BarCrossrange/index'
3 3 import { CapsuleChartConfig } from './CapsuleChart/index'
  4 +import { BarLineConfig } from './BarLine/index'
4 5
5   -export default [BarCommonConfig, BarCrossrangeConfig, CapsuleChartConfig]
  6 +export default [BarCommonConfig, BarCrossrangeConfig, BarLineConfig, CapsuleChartConfig]
... ...
... ... @@ -33,6 +33,10 @@ export const option = {
33 33 width: 3,
34 34 color: {
35 35 type: 'linear',
  36 + x: 0,
  37 + y: 0,
  38 + x2: 0,
  39 + y2: 1,
36 40 colorStops: [
37 41 {
38 42 offset: 0,
... ...
... ... @@ -84,7 +84,10 @@ export const option = {
84 84 shadowColor: '#E1FFFF',
85 85 shadowBlur: 10
86 86 },
87   - data: []
  87 + data: [],
  88 + encode: {
  89 + value: 2
  90 + }
88 91 },
89 92 {
90 93 name: '区域',
... ...
... ... @@ -3,7 +3,7 @@
3 3 :type="type"
4 4 :height="h"
5 5 :processing="processing"
6   - :percentage="option.dataset"
  6 + :percentage="dataset"
7 7 :indicator-placement="indicatorPlacement"
8 8 :color="color"
9 9 :rail-color="railColor"
... ... @@ -15,7 +15,7 @@
15 15 fontSize: `${indicatorTextSize}px`
16 16 }"
17 17 >
18   - {{ option.dataset }} {{ unit }}
  18 + {{ dataset }} {{ unit }}
19 19 </n-text>
20 20 </n-progress>
21 21 </template>
... ...
... ... @@ -14,5 +14,6 @@ export enum ChatCategoryEnumName {
14 14 LINE = '折线图',
15 15 SCATTER = '散点图',
16 16 MAP = '地图',
  17 + COMBINATION = '组合图',
17 18 MORE = '更多'
18 19 }
... ...
  1 +import { PublicConfigClass } from '@/packages/public'
  2 +import { CreateComponentType } from '@/packages/index.d'
  3 +import { chartInitConfig } from '@/settings/designSetting'
  4 +import { FullScreenConfig } from './index'
  5 +import cloneDeep from 'lodash/cloneDeep'
  6 +
  7 +export const option = {
  8 + border: 6,
  9 + bgColor: '#84a5e9',
  10 + borderColor: '#84a5e9'
  11 +}
  12 +
  13 +export default class Config extends PublicConfigClass implements CreateComponentType {
  14 + public key = FullScreenConfig.key
  15 + public attr = { ...chartInitConfig, w: 150, h: 150, zIndex: -1 }
  16 + public chartConfig = cloneDeep(FullScreenConfig)
  17 + public option = cloneDeep(option)
  18 +}
... ...
  1 +<template>
  2 + <CollapseItem name="全屏按钮" expanded>
  3 + <SettingItemBox name="按钮">
  4 + <SettingItem name="背景色">
  5 + <n-color-picker size="small" :modes="['hex']" v-model:value="optionData.bgColor"></n-color-picker>
  6 + </SettingItem>
  7 + <SettingItem name="边框色">
  8 + <n-color-picker size="small" :modes="['hex']" v-model:value="optionData.borderColor"></n-color-picker>
  9 + </SettingItem>
  10 + <SettingItem name="边框大小">
  11 + <n-input-number v-model:value="optionData.border" size="small" :step="0.5" :min="0"></n-input-number>
  12 + </SettingItem>
  13 + </SettingItemBox>
  14 + </CollapseItem>
  15 +</template>
  16 +
  17 +<script setup lang="ts">
  18 +import { PropType } from 'vue'
  19 +import { CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting'
  20 +import { option } from './config'
  21 +
  22 +const props = defineProps({
  23 + optionData: {
  24 + type: Object as PropType<typeof option>,
  25 + required: true
  26 + }
  27 +})
  28 +</script>
... ...
  1 +import { ConfigType, PackagesCategoryEnum, ChartFrameEnum } from '@/packages/index.d'
  2 +import { ChatCategoryEnum, ChatCategoryEnumName } from '../../index.d'
  3 +
  4 +export const FullScreenConfig: ConfigType = {
  5 + key: 'FullScreen',
  6 + chartKey: 'VFullScreen',
  7 + conKey: 'VCFullScreen',
  8 + title: '全屏按钮',
  9 + category: ChatCategoryEnum.MORE,
  10 + categoryName: ChatCategoryEnumName.MORE,
  11 + package: PackagesCategoryEnum.DECORATES,
  12 + chartFrame: ChartFrameEnum.STATIC,
  13 + image: 'fullScreen.png'
  14 +}
... ...
  1 +<template>
  2 + <svg @click="toggleFullscreen" v-if="!isFullscreen" viewBox="0 0 1024 1024">
  3 + <path
  4 + d="M665.6 1017.6c-19.2 0-38.4-19.2-38.4-38.4s19.2-38.4 38.4-38.4h268.8l6.4-268.8c0-19.2 19.2-38.4 38.4-38.4s38.4 19.2 38.4 38.4v294.4c0 32-25.6 51.2-51.2 51.2h-300.8zM51.2 396.8c-19.2 0-38.4-19.2-38.4-38.4V64C12.8 32 38.4 12.8 64 12.8h294.4c19.2 0 38.4 19.2 38.4 38.4s-19.2 38.4-38.4 38.4H89.6v268.8c0 19.2-19.2 38.4-38.4 38.4zM64 1017.6c-32 0-51.2-25.6-51.2-51.2v-294.4c0-19.2 19.2-38.4 38.4-38.4s38.4 19.2 38.4 38.4v217.6l198.4-198.4c6.4-6.4 19.2-12.8 25.6-12.8s19.2 6.4 25.6 12.8c6.4 6.4 12.8 19.2 12.8 25.6 0 12.8-6.4 19.2-12.8 25.6l-198.4 198.4h217.6c19.2 0 38.4 19.2 38.4 38.4s-19.2 38.4-38.4 38.4H64z m915.2-620.8c-19.2 0-38.4-19.2-38.4-38.4V140.8l-198.4 198.4c-6.4 6.4-19.2 12.8-25.6 12.8-12.8 0-19.2-6.4-25.6-12.8-12.8-12.8-12.8-38.4 0-51.2l198.4-198.4h-217.6c-19.2 0-38.4-19.2-38.4-38.4s19.2-38.4 38.4-38.4h294.4c32 0 51.2 25.6 51.2 51.2v294.4c0 19.2-19.2 38.4-38.4 38.4z"
  5 + class="fullScreen-border"
  6 + ></path>
  7 + </svg>
  8 + <svg @click="toggleFullscreen" v-else viewBox="0 0 1024 1024">
  9 + <path
  10 + d="M379.336 697.237L153.362 921.55c-14.11 14.007-36.905 13.922-50.912-0.188-14.007-14.11-13.922-36.905 0.188-50.912l227.6-225.927H138.645c-18.99 0-34.385-15.446-34.385-34.5 0-19.053 15.395-34.5 34.385-34.5H413.72c18.99 0 34.384 15.447 34.384 34.5v276c0 9.15-3.622 17.926-10.07 24.396a34.326 34.326 0 0 1-24.314 10.104 34.326 34.326 0 0 1-24.314-10.104 34.559 34.559 0 0 1-10.071-24.396V697.237z m263.395-366.88l227.813-227.813c14.059-14.059 36.853-14.059 50.912 0 14.059 14.059 14.059 36.853 0 50.912l-225.18 225.18h187.147c18.99 0 34.385 15.445 34.385 34.5 0 19.053-15.395 34.5-34.385 34.5H608.346c-18.99 0-34.384-15.447-34.384-34.5v-276c0-9.15 3.622-17.926 10.07-24.396a34.326 34.326 0 0 1 24.314-10.105c9.12 0 17.865 3.635 24.314 10.105a34.559 34.559 0 0 1 10.07 24.395v193.223zM99.385 410a34.326 34.326 0 0 1-24.314-10.105A34.559 34.559 0 0 1 65 375.5v-276C65 80.446 80.395 65 99.385 65h275.077c18.99 0 34.384 15.446 34.384 34.5 0 19.054-15.394 34.5-34.384 34.5H133.769v241.5c0 9.15-3.622 17.925-10.07 24.395A34.326 34.326 0 0 1 99.384 410z m825.23 552H649.538c-18.99 0-34.384-15.446-34.384-34.5 0-19.054 15.394-34.5 34.384-34.5h240.693V651.5c0-19.054 15.394-34.5 34.384-34.5 18.99 0 34.385 15.446 34.385 34.5v276c0 19.054-15.395 34.5-34.385 34.5z"
  11 + class="fullScreen-border"
  12 + ></path>
  13 + </svg>
  14 +</template>
  15 +
  16 +<script setup lang="ts">
  17 +import { PropType, toRefs, ref, onMounted, onUnmounted } from 'vue'
  18 +import { CreateComponentType } from '@/packages/index.d'
  19 +import { option } from './config'
  20 +
  21 +const props = defineProps({
  22 + chartConfig: {
  23 + type: Object as PropType<CreateComponentType & typeof option>,
  24 + required: true
  25 + }
  26 +})
  27 +
  28 +let { border, bgColor, borderColor } = toRefs(props.chartConfig.option)
  29 +const isFullscreen = ref(false)
  30 +const checkFullscreen = () => {
  31 + isFullscreen.value = !!(
  32 + document.fullscreenElement ||
  33 + (document as any).webkitFullscreenElement ||
  34 + (document as any).mozFullScreenElement ||
  35 + (document as any).msFullscreenElement
  36 + )
  37 +}
  38 +checkFullscreen()
  39 +
  40 +const requestFullscreen = (element: Element) => {
  41 + if (element.requestFullscreen) {
  42 + element.requestFullscreen()
  43 + } else if ((document as any).mozRequestFullScreen) {
  44 + /* Firefox */
  45 + (document as any).mozRequestFullScreen()
  46 + } else if ((document as any).webkitRequestFullscreen) {
  47 + /* Chrome, Safari and Opera */
  48 + (document as any).webkitRequestFullscreen()
  49 + } else if ((document as any).msRequestFullscreen) {
  50 + /* IE/Edge */
  51 + (document as any).msRequestFullscreen()
  52 + }
  53 +}
  54 +
  55 +const exitFullscreen = () => {
  56 + if (document.fullscreenElement && document.exitFullscreen) {
  57 + document.exitFullscreen()
  58 + } else if ((document as any).mozFullScreenElement && (document as any).mozCancelFullScreen) {
  59 + /* Firefox */
  60 + (document as any).mozCancelFullScreen()
  61 + } else if ((document as any).webkitFullscreenElement && (document as any).webkitExitFullscreen) {
  62 + /* Chrome, Safari and Opera */
  63 + (document as any).webkitExitFullscreen()
  64 + } else if ((document as any).msFullscreenElement && (document as any).msExitFullscreen) {
  65 + /* IE/Edge */
  66 + (document as any).msExitFullscreen()
  67 + }
  68 +}
  69 +
  70 +const toggleFullscreen = () => {
  71 + if (!isFullscreen.value) {
  72 + requestFullscreen(document.documentElement)
  73 + } else {
  74 + exitFullscreen()
  75 + }
  76 + isFullscreen.value = !isFullscreen.value
  77 + // 由于全屏状态的改变不会立即生效,所以需要延迟一段时间再去获取全屏状态
  78 + setTimeout(() => {
  79 + checkFullscreen()
  80 + }, 1000)
  81 +}
  82 +
  83 +// 监听全屏状态的改变,保证多个全屏组件的状态一致
  84 +onMounted(() => {
  85 + document.addEventListener('fullscreenchange', checkFullscreen)
  86 + document.addEventListener('webkitfullscreenchange', checkFullscreen)
  87 + document.addEventListener('mozfullscreenchange', checkFullscreen)
  88 + document.addEventListener('MSFullscreenChange', checkFullscreen)
  89 +})
  90 +
  91 +onUnmounted(() => {
  92 + document.removeEventListener('fullscreenchange', checkFullscreen)
  93 + document.removeEventListener('webkitfullscreenchange', checkFullscreen)
  94 + document.removeEventListener('mozfullscreenchange', checkFullscreen)
  95 + document.removeEventListener('MSFullscreenChange', checkFullscreen)
  96 +})
  97 +</script>
  98 +
  99 +<style lang="scss" scoped>
  100 +svg {
  101 + display: block;
  102 + width: 100%;
  103 + height: 100%;
  104 + cursor: pointer;
  105 +}
  106 +.fullScreen-border {
  107 + stroke: v-bind('borderColor');
  108 + stroke-width: v-bind('border+"px"');
  109 + fill: v-bind('bgColor');
  110 +}
  111 +</style>
... ...
1 1 import { NumberConfig } from './Number/index'
2 2 import { TimeCommonConfig } from './TimeCommon/index'
3 3 import { ClockConfig } from './Clock/index'
  4 +import { FullScreenConfig } from './FullScreen/index'
4 5 import { CountDownConfig } from './CountDown/index'
5 6 import { FlipperNumberConfig } from './FlipperNumber'
6 7 import { PipelineHConfig } from './PipelineH/index'
7 8 import { PipelineVConfig } from './PipelineV/index'
8 9
9   -export default [NumberConfig, FlipperNumberConfig, TimeCommonConfig, CountDownConfig, ClockConfig, PipelineHConfig, PipelineVConfig]
  10 +export default [
  11 + NumberConfig,
  12 + FlipperNumberConfig,
  13 + TimeCommonConfig,
  14 + CountDownConfig,
  15 + ClockConfig,
  16 + FullScreenConfig,
  17 + PipelineHConfig,
  18 + PipelineVConfig
  19 +]
... ...
1   -// eslint-disable-next-line @typescript-eslint/ban-ts-comment
2 1 // @ts-nocheck
3 2 import {
4 3 ArcCurve,
... ...
... ... @@ -27,21 +27,12 @@ export class Basic {
27 27
28 28 this.camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 100000)
29 29 this.camera.position.set(0, 30, -250)
30   - /**
31   - * 这里升级版本有冲突,升级版本可以使用这里的代码,官方还未修复
32   - * 修复官方Threejs生成缩略图无效问题,少加一个Threejs配置
33   - * 修改后的代码在注释之间,并标注好源代码和修改后代码,方便回溯
34   - * 源代码 属于新增代码,源代码无
35   - * 修改后代码 preserveDrawingBuffer: true //缩略图生效需开启
36   - *
37   - */
38 30 this.renderer = new THREE.WebGLRenderer({
39 31 // canvas: this.dom,
40 32 alpha: true, // 透明
41 33 antialias: true, // 抗锯齿
42   - preserveDrawingBuffer: true//缩略图生效需开启
  34 + preserveDrawingBuffer: true
43 35 })
44   - //ft
45 36 this.renderer.setPixelRatio(window.devicePixelRatio) // 设置屏幕像素比
46 37 this.renderer.setSize(window.innerWidth, window.innerHeight) // 设置渲染器宽高
47 38 this.dom.appendChild(this.renderer.domElement) // 添加到dom中
... ...
  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 { COMPONENT_INTERACT_EVENT_KET } from '@/enums/eventEnum'
  6 +import { interactActions, ComponentInteractEventEnum } from './interact'
  7 +import {InputsInputConfig} from "./index";
  8 +
  9 +export const option = {
  10 + // 时间组件展示类型,必须和 interactActions 中定义的数据一致
  11 + [COMPONENT_INTERACT_EVENT_KET]: ComponentInteractEventEnum.DATA,
  12 + // 默认值
  13 + inputValue: "0",
  14 + // 暴露配置内容给用户
  15 + dataset: ""
  16 +}
  17 +
  18 +export default class Config extends PublicConfigClass implements CreateComponentType {
  19 + public key = InputsInputConfig.key
  20 + public attr = { ...chartInitConfig, w: 260, h: 32, zIndex: -1 }
  21 + public chartConfig = cloneDeep(InputsInputConfig)
  22 + public interactActions = interactActions
  23 + public option = cloneDeep(option)
  24 +}
\ No newline at end of file
... ...
  1 +<template>
  2 + <collapse-item name="输入框配置" :expanded="true">
  3 + <setting-item-box name="默认值" :alone="true">
  4 + <n-input v-model:value="optionData.dataset" placeholder="若未输入,则默认值为0"/>
  5 + </setting-item-box>
  6 + </collapse-item>
  7 +</template>
  8 +<script setup lang="ts">
  9 +import { PropType } from 'vue'
  10 +import { CollapseItem, SettingItemBox } from '@/components/Pages/ChartItemSetting'
  11 +import { option } from './config'
  12 +defineProps({
  13 + optionData: {
  14 + type: Object as PropType<typeof option>,
  15 + required: true
  16 + }
  17 +})
  18 +</script>
\ No newline at end of file
... ...
  1 +import { ConfigType, PackagesCategoryEnum, ChartFrameEnum } from '@/packages/index.d'
  2 +import { ChatCategoryEnum, ChatCategoryEnumName } from '../../index.d'
  3 +
  4 +export const InputsInputConfig: ConfigType = {
  5 + key: 'InputsInput',
  6 + chartKey: 'VInputsInput',
  7 + conKey: 'VCInputsInput',
  8 + title: '输入框',
  9 + category: ChatCategoryEnum.INPUTS,
  10 + categoryName: ChatCategoryEnumName.INPUTS,
  11 + package: PackagesCategoryEnum.INFORMATIONS,
  12 + chartFrame: ChartFrameEnum.STATIC,
  13 + image: 'inputs_select.png'
  14 +}
\ No newline at end of file
... ...
  1 +<template>
  2 + <div>
  3 + <n-input :style="`width:${w}px;`" type="text"
  4 + v-model:value="option.value.dataset"
  5 + placeholder="请输入"
  6 + @change="onChange">
  7 +
  8 + </n-input>
  9 + </div>
  10 +</template>
  11 +
  12 +<script lang="ts" setup>
  13 +import { PropType, toRefs, shallowReactive, watch } from 'vue'
  14 +import { CreateComponentType } from '@/packages/index.d'
  15 +import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
  16 +import { useChartInteract } from '@/hooks'
  17 +import { InteractEventOn } from '@/enums/eventEnum'
  18 +import { ComponentInteractParamsEnum } from './interact'
  19 +
  20 +const props = defineProps({
  21 + chartConfig: {
  22 + type: Object as PropType<CreateComponentType>,
  23 + required: true
  24 + }
  25 +})
  26 +
  27 +const { w, h } = toRefs(props.chartConfig.attr)
  28 +const option = shallowReactive({
  29 + value: {
  30 + inputValue: props.chartConfig.option.inputValue,
  31 + dataset: props.chartConfig.option.dataset
  32 + }
  33 +})
  34 +
  35 +const onChange = (v: string) => {
  36 + if(v == undefined) return;
  37 + // 存储到联动数据
  38 + useChartInteract(
  39 + props.chartConfig,
  40 + useChartEditStore,
  41 + { [ComponentInteractParamsEnum.DATA]: v },
  42 + InteractEventOn.CHANGE
  43 + )
  44 +}
  45 +
  46 +// 手动更新
  47 +watch(
  48 + () => props.chartConfig.option,
  49 + (newData: any) => {
  50 + option.value = newData
  51 + onChange(newData.inputValue)
  52 + },
  53 + {
  54 + immediate: true,
  55 + deep: true
  56 + }
  57 +)
  58 +
  59 +</script>
  60 +
  61 +
  62 +
  63 +
  64 +
... ...
  1 +import { InteractEventOn, InteractActionsType } from '@/enums/eventEnum'
  2 +
  3 +// 时间组件类型
  4 +export enum ComponentInteractEventEnum {
  5 + DATA = 'data'
  6 +}
  7 +
  8 +// 联动参数
  9 +export enum ComponentInteractParamsEnum {
  10 + DATA = 'data'
  11 +}
  12 +
  13 +// 定义组件触发回调事件
  14 +export const interactActions: InteractActionsType[] = [
  15 + {
  16 + interactType: InteractEventOn.CHANGE,
  17 + interactName: '选择完成',
  18 + componentEmitEvents: {
  19 + [ComponentInteractEventEnum.DATA]: [
  20 + {
  21 + value: ComponentInteractParamsEnum.DATA,
  22 + label: '选择项'
  23 + }
  24 + ]
  25 + }
  26 + }
  27 +]
... ...
  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 { COMPONENT_INTERACT_EVENT_KET } from '@/enums/eventEnum'
  6 +import { interactActions, ComponentInteractEventEnum } from './interact'
  7 +import {InputsPaginationConfig} from "./index";
  8 +
  9 +export const option = {
  10 + // 时间组件展示类型,必须和 interactActions 中定义的数据一致
  11 + [COMPONENT_INTERACT_EVENT_KET]: ComponentInteractEventEnum.DATA,
  12 + // 默认值
  13 + pageValue:1,
  14 + sizeValue:[2,4,8,10,20],
  15 + pageSize:4,
  16 + // 暴露配置内容给用户
  17 + dataset: 10
  18 +}
  19 +
  20 +export default class Config extends PublicConfigClass implements CreateComponentType {
  21 + public key = InputsPaginationConfig.key
  22 + public attr = { ...chartInitConfig, w: 395, h: 32, zIndex: -1 }
  23 + public chartConfig = cloneDeep(InputsPaginationConfig)
  24 + public interactActions = interactActions
  25 + public option = cloneDeep(option)
  26 +}
\ No newline at end of file
... ...
  1 +<template>
  2 + <collapse-item name="分页配置" :expanded="true">
  3 + <setting-item-box :alone="false" name="分页设置">
  4 + <setting-item name="默认页码" :alone="true">
  5 + <n-input-number v-model:value="optionData.pageValue" size="small" placeholder="字体大小"></n-input-number>
  6 + </setting-item>
  7 + <setting-item name="分页" :alone="true">
  8 + <n-select v-model:value="optionData.pageSize" size="small"
  9 + :options="page" />
  10 + </setting-item>
  11 + <setting-item name="页数" :alone="true">
  12 + <n-input-number v-model:value="optionData.dataset" size="small" placeholder="字体大小"></n-input-number>
  13 + </setting-item>
  14 + </setting-item-box>
  15 + </collapse-item>
  16 +</template>
  17 +<script setup lang="ts">
  18 +import { PropType } from 'vue'
  19 +import {CollapseItem, SettingItem, SettingItemBox} from '@/components/Pages/ChartItemSetting'
  20 +import { option } from './config'
  21 +
  22 +const page = [
  23 + {label:'2',value:2},
  24 + {label:'4',value:4},
  25 + {label:'8',value:8},
  26 + {label:'10',value:10},
  27 + {label:'20',value:20}
  28 +]
  29 +defineProps({
  30 + optionData: {
  31 + type: Object as PropType<typeof option>,
  32 + required: true
  33 + }
  34 +})
  35 +</script>
\ No newline at end of file
... ...
  1 +import { ConfigType, PackagesCategoryEnum, ChartFrameEnum } from '@/packages/index.d'
  2 +import { ChatCategoryEnum, ChatCategoryEnumName } from '../../index.d'
  3 +
  4 +export const InputsPaginationConfig: ConfigType = {
  5 + key: 'InputsPagination',
  6 + chartKey: 'VInputsPagination',
  7 + conKey: 'VCInputsPagination',
  8 + title: '分页',
  9 + category: ChatCategoryEnum.INPUTS,
  10 + categoryName: ChatCategoryEnumName.INPUTS,
  11 + package: PackagesCategoryEnum.INFORMATIONS,
  12 + chartFrame: ChartFrameEnum.STATIC,
  13 + image: 'inputs_pagination.png'
  14 +}
\ No newline at end of file
... ...
  1 +<template>
  2 + <div>
  3 + <n-pagination
  4 + @on-update:page="onChange" :style="`width:${w}px;`"
  5 + v-model:page="option.value.pageValue"
  6 + :page-count="option.value.dataset"
  7 + :page-slot="7"
  8 + show-size-picker
  9 + :page-sizes="option.value.sizeValue"
  10 + v-model:page-size="option.value.pageSize"
  11 + />
  12 + </div>
  13 +</template>
  14 +
  15 +<script lang="ts" setup>
  16 +import { PropType, toRefs, shallowReactive, watch } from 'vue'
  17 +import { CreateComponentType } from '@/packages/index.d'
  18 +import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
  19 +import { useChartInteract } from '@/hooks'
  20 +import { InteractEventOn } from '@/enums/eventEnum'
  21 +import { ComponentInteractParamsEnum } from './interact'
  22 +
  23 +const props = defineProps({
  24 + chartConfig: {
  25 + type: Object as PropType<CreateComponentType>,
  26 + required: true
  27 + }
  28 +})
  29 +
  30 +const { w, h } = toRefs(props.chartConfig.attr)
  31 +const option = shallowReactive({
  32 + value: {
  33 + pageValue: props.chartConfig.option.pageValue,
  34 + dataset:props.chartConfig.option.dataset,
  35 + sizeValue:props.chartConfig.option.sizeValue,
  36 + pageSize:props.chartConfig.option.pageSize
  37 + }
  38 +})
  39 +
  40 +const onChange = (v: number,v2:number) => {
  41 + if(v == undefined) return;
  42 + // 存储到联动数据
  43 + useChartInteract(
  44 + props.chartConfig,
  45 + useChartEditStore,
  46 + {
  47 + [ComponentInteractParamsEnum.DATA]: v ,
  48 + [ComponentInteractParamsEnum.DATA2]:v2
  49 + },
  50 + InteractEventOn.CHANGE
  51 + )
  52 +}
  53 +
  54 +// 手动更新
  55 +watch(
  56 + () => props.chartConfig.option,
  57 + (newData: any) => {
  58 + option.value = newData
  59 + onChange(newData.pageValue,newData.pageSize)
  60 + },
  61 + {
  62 + immediate: true,
  63 + deep: true
  64 + }
  65 +)
  66 +</script>
\ No newline at end of file
... ...
  1 +import { InteractEventOn, InteractActionsType } from '@/enums/eventEnum'
  2 +
  3 +// 时间组件类型
  4 +export enum ComponentInteractEventEnum {
  5 + DATA = 'data'
  6 +}
  7 +
  8 +// 联动参数
  9 +export enum ComponentInteractParamsEnum {
  10 + DATA = 'data',
  11 + DATA2 = 'data2'
  12 +}
  13 +
  14 +// 定义组件触发回调事件
  15 +export const interactActions: InteractActionsType[] = [
  16 + {
  17 + interactType: InteractEventOn.CHANGE,
  18 + interactName: '选择完成',
  19 + componentEmitEvents: {
  20 + [ComponentInteractEventEnum.DATA]: [
  21 + {
  22 + value: ComponentInteractParamsEnum.DATA,
  23 + label: '页数'
  24 + },
  25 + {
  26 + value: ComponentInteractParamsEnum.DATA2,
  27 + label: '每页条数'
  28 + }
  29 + ]
  30 + }
  31 + }
  32 +]
\ No newline at end of file
... ...
1 1 import { InputsDateConfig } from './InputsDate/index'
2 2 import { InputsSelectConfig } from './InputsSelect/index'
3 3 import { InputsTabConfig } from './InputsTab/index'
  4 +import { InputsPaginationConfig } from "./InputsPagination/index";
  5 +import { InputsInputConfig} from "./InputsInput/index";
4 6
5   -export default [InputsDateConfig, InputsSelectConfig, InputsTabConfig]
  7 +export default [InputsDateConfig, InputsSelectConfig, InputsTabConfig,InputsPaginationConfig,InputsInputConfig]
... ...
1   -import { PublicConfigClass } from '@/packages/public'
2   -import { CreateComponentType } from '@/packages/index.d'
3   -import { CarouselConfig } from './index'
4   -import cloneDeep from 'lodash/cloneDeep'
5   -import logo from '@/assets/logo.png'
6   -
7   -// 示例图片资源
8   -const modules: Record<string, { default: string }> = import.meta.glob("./images/*", {eager: true});
9   -const dataset = [logo]
10   -for (const item in modules) {
11   - dataset.push(modules[item].default)
12   -}
13   -
14   -export const option = {
15   - // 图片资源列表
16   - dataset: dataset,
17   - // 自动播放
18   - autoplay: true,
19   - // 自动播放的间隔(ms)
20   - interval: 5000,
21   - // 每页显示的图片数量
22   - slidesPerview: 1,
23   - // 轮播方向
24   - direction: "horizontal",
25   - // 拖曳切换
26   - draggable: true,
27   - // 居中显示
28   - centeredSlides: false,
29   - // 过渡效果
30   - effect: "slide",
31   - // 是否显示指示点
32   - showDots: true,
33   - // 指示器样式
34   - dotType: "dot",
35   - // 指示器位置
36   - dotPlacement: "bottom",
37   - // 显示箭头
38   - showArrow: false,
39   - // 图片样式
40   - fit: "contain",
41   -}
42   -
43   -export default class Config extends PublicConfigClass implements CreateComponentType {
44   - public key = CarouselConfig.key
45   - public chartConfig = cloneDeep(CarouselConfig)
46   - public option = cloneDeep(option)
47   -}
1   -<template>
2   - <collapse-item name="属性" :expanded="true">
3   - <setting-item-box name="路径" :alone="true">
4   - <setting-item v-for="item, index in optionData.dataset" :key="index">
5   - <n-input-group>
6   - <n-input v-model:value="optionData.dataset[index]" size="small" placeholder="请输入图片地址"></n-input>
7   - <n-button ghost @click="optionData.dataset.splice(index, 1)">
8   - -
9   - </n-button>
10   - </n-input-group>
11   - </setting-item>
12   - <setting-item>
13   - <n-button size="small" @click="optionData.dataset.push('')">
14   - +
15   - </n-button>
16   - </setting-item>
17   - </setting-item-box>
18   - <setting-item-box name="播放器">
19   - <setting-item>
20   - <n-space>
21   - <n-switch v-model:value="optionData.autoplay" size="small" />
22   - <n-text>自动播放</n-text>
23   - </n-space>
24   - </setting-item>
25   - <!-- 开启自动播放时,设置间隔时间 -->
26   - <setting-item name="间隔时间">
27   - <n-input-number v-model:value="optionData.interval" size="small" placeholder=""></n-input-number>
28   - </setting-item>
29   - <setting-item name="轮播方向">
30   - <n-select v-model:value="optionData.direction" :options="directions" placeholder="选择方向" />
31   - </setting-item>
32   - <setting-item name="过渡效果">
33   - <n-select v-model:value="optionData.effect" :options="effects" placeholder="效果" />
34   - </setting-item>
35   - <setting-item name="每页数量">
36   - <n-input-number v-model:value="optionData.slidesPerview" size="small" placeholder=""></n-input-number>
37   - </setting-item>
38   - <setting-item>
39   - <n-space>
40   - <n-switch v-model:value="optionData.centeredSlides" size="small" />
41   - <n-text>居中显示</n-text>
42   - </n-space>
43   - </setting-item>
44   - <setting-item name="图片样式">
45   - <n-select v-model:value="optionData.fit" :options="fitList" placeholder="样式" />
46   - </setting-item>
47   - </setting-item-box>
48   -
49   - <setting-item-box name="指示器">
50   - <setting-item name="样式">
51   - <n-select v-model:value="optionData.dotType" :options="dotTypes" placeholder="选择样式" />
52   - </setting-item>
53   - <setting-item name="位置">
54   - <n-select v-model:value="optionData.dotPlacement" :options="dotPlacements" placeholder="选择位置" />
55   - </setting-item>
56   - <setting-item>
57   - <n-space>
58   - <n-switch v-model:value="optionData.showDots" size="small" />
59   - <n-text>显示</n-text>
60   - </n-space>
61   - </setting-item>
62   - <setting-item>
63   - <n-space>
64   - <n-switch v-model:value="optionData.showArrow" size="small" />
65   - <n-text>箭头</n-text>
66   - </n-space>
67   - </setting-item>
68   - <setting-item>
69   - <n-space>
70   - <n-switch v-model:value="optionData.draggable" size="small" />
71   - <n-text>拖曳切换</n-text>
72   - </n-space>
73   - </setting-item>
74   - </setting-item-box>
75   -
76   - </collapse-item>
77   -</template>
78   -
79   -<script setup lang="ts">
80   -import { PropType } from 'vue'
81   -import { option } from './config'
82   -import {
83   - CollapseItem,
84   - SettingItemBox,
85   - SettingItem
86   -} from '@/components/Pages/ChartItemSetting'
87   -
88   -const props = defineProps({
89   - optionData: {
90   - type: Object as PropType<typeof option>,
91   - required: true
92   - }
93   -})
94   -
95   -// 字典
96   -const dotTypes = [
97   - {
98   - label: "点",
99   - value: "dot"
100   - },
101   - {
102   - label: "线",
103   - value: "line"
104   - }
105   -]
106   -const directions = [
107   - {
108   - label: "水平方向",
109   - value: "horizontal"
110   - },
111   - {
112   - label: "垂直方向",
113   - value: "vertical"
114   - }
115   -]
116   -const effects = [
117   - {
118   - label: "slide",
119   - value: "slide"
120   - },
121   - {
122   - label: "fade",
123   - value: "fade"
124   - },
125   - {
126   - label: "card",
127   - value: "card"
128   - },
129   - {
130   - label: "custom",
131   - value: "custom"
132   - }
133   -]
134   -const dotPlacements = [
135   - {
136   - label: "上边",
137   - value: "top"
138   - },
139   - {
140   - label: "下边",
141   - value: "bottom"
142   - },
143   - {
144   - label: "左边",
145   - value: "left"
146   - },
147   - {
148   - label: "右边",
149   - value: "right"
150   - }
151   -]
152   -
153   -// 适应类型
154   -const fitList = [
155   - {
156   - value: 'fill',
157   - label: 'fill'
158   - },
159   - {
160   - value: 'contain',
161   - label: 'contain'
162   - },
163   - {
164   - value: 'cover',
165   - label: 'cover'
166   - },
167   - {
168   - value: 'scale-down',
169   - label: 'scale-down'
170   - },
171   - {
172   - value: 'none',
173   - label: 'none'
174   - },
175   -]
176   -</script>
1   -import { ConfigType, PackagesCategoryEnum, ChartFrameEnum } from '@/packages/index.d'
2   -import { ChatCategoryEnum,ChatCategoryEnumName } from '../../index.d'
3   -
4   -export const CarouselConfig: ConfigType = {
5   - key: 'Carousel',
6   - chartKey: 'VCarousel',
7   - conKey: 'VCCarousel',
8   - title: '轮播图',
9   - category: ChatCategoryEnum.MORE,
10   - categoryName: ChatCategoryEnumName.MORE,
11   - package: PackagesCategoryEnum.INFORMATIONS,
12   - chartFrame: ChartFrameEnum.NAIVE_UI,
13   - image: 'photo.png'
14   -}
1   -<template>
2   - <div>
3   - <n-carousel :autoplay="autoplay" :interval="interval" :centered-slides="centeredSlides" :direction="direction"
4   - :dot-placement="dotPlacement" :dot-type="dotType" :draggable="draggable" :effect="effect"
5   - :slides-per-view="slidesPerview" :show-arrow="showArrow" :show-dots="showDots">
6   - <n-image v-for="url in option.dataset" :object-fit="fit" preview-disabled :src="url"
7   - :fallback-src="requireErrorImg()" :width="w" :height="h"></n-image>
8   - </n-carousel>
9   - </div>
10   -</template>
11   -<script setup lang="ts">
12   -import { PropType, toRefs, shallowReactive, watch } from 'vue'
13   -import { CreateComponentType } from '@/packages/index.d'
14   -import { requireErrorImg } from '@/utils'
15   -import { useChartDataFetch } from '@/hooks'
16   -import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
17   -import { option as configOption } from './config'
18   -
19   -const props = defineProps({
20   - chartConfig: {
21   - type: Object as PropType<CreateComponentType>,
22   - required: true
23   - }
24   -})
25   -
26   -const option = shallowReactive({
27   - dataset: configOption.dataset
28   -})
29   -
30   -const { w, h } = toRefs(props.chartConfig.attr)
31   -const { autoplay, interval, slidesPerview, direction, draggable, centeredSlides, effect, dotType, dotPlacement, showArrow, showDots, fit } = toRefs(props.chartConfig.option)
32   -
33   -watch(
34   - () => props.chartConfig.option.dataset,
35   - (newData: any) => {
36   - option.dataset = newData
37   - },
38   - {
39   - immediate: true,
40   - deep: false
41   - }
42   -)
43   -
44   -useChartDataFetch(props.chartConfig, useChartEditStore, (newData: any) => {
45   - option.dataset = newData
46   -})
47   -</script>
... ... @@ -3,6 +3,5 @@ import { ImageCarouselConfig } from './ImageCarousel/index'
3 3 import { IframeConfig } from './Iframe/index'
4 4 import { VideoConfig } from './Video/index'
5 5 import { WordCloudConfig } from './WordCloud/index'
6   -import { CarouselConfig } from './Carousel/index'
7 6
8 7 export default [ImageConfig, ImageCarouselConfig, VideoConfig, IframeConfig, WordCloudConfig]
... ...
... ... @@ -2,7 +2,7 @@
2 2 <collapse-item name="信息" :expanded="true">
3 3 <setting-item-box name="文字" :alone="true">
4 4 <setting-item>
5   - <n-input v-model:value="optionData.dataset" size="small"></n-input>
  5 + <n-input v-model:value="optionData.dataset" type="textarea" size="small"></n-input>
6 6 </setting-item>
7 7 </setting-item-box>
8 8 </collapse-item>
... ...
1 1 <template>
2 2 <div class="go-text-box">
3 3 <div class="content">
4   - <span style="cursor: pointer; white-space: pre-wrap" v-if="link" @click="click"></span>
  4 + <span style="cursor: pointer; white-space: pre-wrap" v-if="link" @click="click">{{ option.dataset }}</span>
5 5 <span style="white-space: pre-wrap" v-else>{{ option.dataset }}</span>
6 6 </div>
7 7 </div>
... ...
... ... @@ -2,7 +2,7 @@
2 2 <collapse-item name="信息" :expanded="true">
3 3 <setting-item-box name="文字" :alone="true">
4 4 <setting-item>
5   - <n-input v-model:value="optionData.dataset" size="small"></n-input>
  5 + <n-input v-model:value="optionData.dataset" type="textarea" size="small"></n-input>
6 6 </setting-item>
7 7 </setting-item-box>
8 8 </collapse-item>
... ...
  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 { TablesBasicConfig } from './index'
  6 +import dataJson from './data.json'
  7 +
  8 +const { dimensions, source } = dataJson
  9 +export const option = {
  10 + dataset: { dimensions, source },
  11 + pagination: {
  12 + page: 1,
  13 + pageSize: 5
  14 + },
  15 + align: 'center',
  16 + style: {
  17 + border: 'on',
  18 + singleColumn: 'off',
  19 + singleLine: 'off',
  20 + bottomBordered: 'on',
  21 + striped: 'on',
  22 + fontSize: 16,
  23 + borderWidth: 0,
  24 + borderColor: 'black',
  25 + borderStyle: 'solid'
  26 + },
  27 + inputShow: 'none'
  28 +}
  29 +
  30 +export default class Config extends PublicConfigClass implements CreateComponentType {
  31 + public key = TablesBasicConfig.key
  32 + public attr = { ...chartInitConfig, w: 600, h: 300, zIndex: -1 }
  33 + public chartConfig = cloneDeep(TablesBasicConfig)
  34 + public option = cloneDeep(option)
  35 +}
... ...
  1 +<template>
  2 + <collapse-item name="表格设置" :expanded="true">
  3 + <n-tag type="primary">若配置无响应,请在预览页面查看效果</n-tag>
  4 + <setting-item-box :alone="true" name="对齐方式">
  5 + <setting-item :alone="true">
  6 + <n-select
  7 + v-model:value="optionData.align"
  8 + size="small"
  9 + :options="[
  10 + { label: '靠左', value: 'left' },
  11 + { label: '居中', value: 'center' },
  12 + { label: '靠右', value: 'right' }
  13 + ]"
  14 + />
  15 + </setting-item>
  16 + </setting-item-box>
  17 + <setting-item-box :alone="false" name="分页设置">
  18 + <setting-item name="默认页码" :alone="true">
  19 + <n-input-number v-model:value="optionData.pagination.page" size="small" placeholder="字体大小"></n-input-number>
  20 + </setting-item>
  21 + <setting-item name="分页" :alone="true">
  22 + <n-select v-model:value="optionData.pagination.pageSize" size="small" :options="page" />
  23 + </setting-item>
  24 + </setting-item-box>
  25 + <setting-item-box :alone="false" name="表格数据">
  26 + <SettingItem name="表头名称" class="form_name">
  27 + <div style="width: 260px">
  28 + <n-input v-model:value="header" size="small" placeholder="表头数据(英文','分割)"></n-input>
  29 + </div>
  30 + </SettingItem>
  31 + </setting-item-box>
  32 + <setting-item-box :alone="false" name="表格样式">
  33 + <SettingItem name="显示边框" :alone="true">
  34 + <n-select v-model:value="(optionData as any).style.border" size="small" :options="borderFlag" />
  35 + </SettingItem>
  36 + <SettingItem name="底部边框" :alone="true">
  37 + <n-select
  38 + v-model:value="(optionData as any).style.bottomBordered"
  39 + size="small"
  40 + :options="bottom_borderedFlag"
  41 + />
  42 + </SettingItem>
  43 + <SettingItem name="列分割线" :alone="true">
  44 + <n-select v-model:value="(optionData as any).style.singleLine" size="small" :options="columnFlag" />
  45 + </SettingItem>
  46 + <SettingItem name="行分割线" :alone="true">
  47 + <n-select v-model:value="(optionData as any).style.singleColumn" size="small" :options="lineFlag" />
  48 + </SettingItem>
  49 + <SettingItem name="斑马条纹" :alone="true">
  50 + <n-select v-model:value="(optionData as any).style.striped" size="small" :options="stripedFlag" />
  51 + </SettingItem>
  52 + <setting-item name="字体大小" :alone="true">
  53 + <n-input-number
  54 + v-model:value="optionData.style.fontSize"
  55 + :min="12"
  56 + size="small"
  57 + placeholder="字体大小"
  58 + ></n-input-number>
  59 + </setting-item>
  60 + <setting-item name="边框宽度" :alone="true">
  61 + <n-input-number
  62 + v-model:value="optionData.style.borderWidth"
  63 + :min="0"
  64 + size="small"
  65 + placeholder="字体大小"
  66 + ></n-input-number>
  67 + </setting-item>
  68 + <setting-item name="边框颜色" :alone="true">
  69 + <n-color-picker size="small" :modes="['rgb']" v-model:value="optionData.style.borderColor"></n-color-picker>
  70 + </setting-item>
  71 + <setting-item name="边框样式" :alone="true">
  72 + <n-select v-model:value="optionData.style.borderStyle" size="small" :options="borderStyleFlag" />
  73 + </setting-item>
  74 + <SettingItem name="表格搜索(前端静态搜索)" :alone="true">
  75 + <n-select v-model:value="optionData.inputShow" size="small" :options="inputSelect" />
  76 + </SettingItem>
  77 + </setting-item-box>
  78 + </collapse-item>
  79 +</template>
  80 +
  81 +<script setup lang="ts">
  82 +import { PropType, watch, ref } from 'vue'
  83 +import { option } from './config'
  84 +import { CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting'
  85 +
  86 +const page = [
  87 + { label: '2', value: 2 },
  88 + { label: '5', value: 5 },
  89 + { label: '10', value: 10 },
  90 + { label: '15', value: 15 },
  91 + { label: '30', value: 30 }
  92 +]
  93 +const borderFlag = [
  94 + { label: '显示', value: 'on' },
  95 + { label: '不显示', value: 'off' }
  96 +]
  97 +const columnFlag = [
  98 + { label: '显示', value: 'off' },
  99 + { label: '不显示', value: 'on' }
  100 +]
  101 +const lineFlag = [
  102 + { label: '显示', value: 'off' },
  103 + { label: '不显示', value: 'on' }
  104 +]
  105 +const bottom_borderedFlag = [
  106 + { label: '显示', value: 'on' },
  107 + { label: '不显示', value: 'off' }
  108 +]
  109 +const stripedFlag = [
  110 + { label: '显示', value: 'on' },
  111 + { label: '不显示', value: 'off' }
  112 +]
  113 +const borderStyleFlag = [
  114 + { label: '实线边框', value: 'solid' },
  115 + { label: '虚线边框', value: 'dashed' },
  116 + { label: '点状边框', value: 'dotted' },
  117 + { label: '双线边框', value: 'double' }
  118 +]
  119 +const inputSelect = [
  120 + { label: '停用', value: 'none' },
  121 + { label: '启用', value: 'flex' }
  122 +]
  123 +const props = defineProps({
  124 + optionData: {
  125 + type: Object as PropType<typeof option>,
  126 + required: true
  127 + }
  128 +})
  129 +
  130 +const header = ref()
  131 +const median = ref<string[]>([])
  132 +props.optionData.dataset.dimensions.forEach(item => {
  133 + median.value.push(item.title)
  134 +})
  135 +
  136 +//转string
  137 +watch(
  138 + () => props.optionData,
  139 + () => {
  140 + median.value = []
  141 + props.optionData.dataset.dimensions.forEach(item => {
  142 + median.value.push(item.title)
  143 + })
  144 + header.value = median.value.toString()
  145 + },
  146 + {
  147 + deep: false,
  148 + immediate: true
  149 + }
  150 +)
  151 +
  152 +//更新columns
  153 +watch([header], ([headerNew], [headerOld]) => {
  154 + if (headerNew !== headerOld) {
  155 + headerNew.split(',').forEach((item: string, index: number) => {
  156 + if (index + 1 <= props.optionData.dataset.dimensions.length) {
  157 + props.optionData.dataset.dimensions[index].title = headerNew.split(',')[index]
  158 + }
  159 + })
  160 + }
  161 +})
  162 +</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 '../../index.d'
  3 +
  4 +export const TablesBasicConfig: ConfigType = {
  5 + key: 'TablesBasic',
  6 + chartKey: 'VTablesBasic',
  7 + conKey: 'VCTablesBasic',
  8 + title: '基础分页表格',
  9 + category: ChatCategoryEnum.TABLE,
  10 + categoryName: ChatCategoryEnumName.TABLE,
  11 + package: PackagesCategoryEnum.TABLES,
  12 + chartFrame: ChartFrameEnum.COMMON,
  13 + image: 'tables_basic.png'
  14 +}
... ...
  1 +<template>
  2 + <div class="go-tables-basic">
  3 + <n-input
  4 + v-model:value="inputData"
  5 + placeholder="请输入信息"
  6 + :style="`display: ${inputShow}`"
  7 + style="margin-bottom: 5px; float: right; width: 240px"
  8 + >
  9 + <template #prefix>
  10 + <n-icon :component="SearchIcon" />
  11 + </template>
  12 + </n-input>
  13 + <n-data-table
  14 + :style="`
  15 + width: ${w}px;
  16 + height: ${h}px;
  17 + font-size: ${option.style.fontSize}px;
  18 + border-width: ${option.style.border === 'on' ? option.style.borderWidth : 0}px;
  19 + border-color: ${option.style.borderColor};
  20 + border-style: ${option.style.borderStyle}`"
  21 + :bordered="option.style.border === 'on'"
  22 + :single-column="option.style.singleColumn === 'on'"
  23 + :single-line="option.style.singleLine === 'on'"
  24 + :bottom-bordered="option.style.bottomBordered === 'on'"
  25 + :striped="option.style.striped === 'on'"
  26 + :max-height="h"
  27 + size="small"
  28 + :columns="option.dataset.dimensions"
  29 + :data="filterData"
  30 + :pagination="pagination"
  31 + />
  32 + </div>
  33 +</template>
  34 +
  35 +<script setup lang="ts">
  36 +import { computed, PropType, toRefs, watch, reactive, ref } from 'vue'
  37 +import { CreateComponentType } from '@/packages/index.d'
  38 +import { icon } from '@/plugins'
  39 +
  40 +const props = defineProps({
  41 + chartConfig: {
  42 + type: Object as PropType<CreateComponentType>,
  43 + required: true
  44 + }
  45 +})
  46 +
  47 +const { SearchIcon } = icon.ionicons5
  48 +
  49 +//查询字段
  50 +const inputData = ref('')
  51 +//前台过滤
  52 +const filterData = computed(() => {
  53 + return option?.dataset?.source?.filter((item: any) => {
  54 + return Object.values(item).some(val => {
  55 + return String(val).toLowerCase().includes(inputData.value.toLowerCase())
  56 + })
  57 + })
  58 +})
  59 +
  60 +const { align, pagination, inputShow } = toRefs(props.chartConfig.option)
  61 +
  62 +pagination.value.onChange = (page: number) => {
  63 + pagination.value.page = page
  64 +}
  65 +
  66 +const { w, h } = toRefs(props.chartConfig.attr)
  67 +
  68 +const option = reactive({
  69 + dataset: props.chartConfig.option.dataset,
  70 + style: props.chartConfig.option.style
  71 +})
  72 +
  73 +watch(
  74 + () => props.chartConfig.option.dataset,
  75 + (newData: any) => {
  76 + option.dataset = newData
  77 + option?.dataset?.dimensions?.forEach((header: any) => {
  78 + header.align = align.value
  79 + })
  80 + },
  81 + {
  82 + immediate: true,
  83 + deep: true
  84 + }
  85 +)
  86 +</script>
  87 +
  88 +<style lang="scss" scoped>
  89 +@include go('tables-basic') {
  90 + display: flex;
  91 + flex-direction: column;
  92 + gap: 15px;
  93 + align-items: flex-end;
  94 +}
  95 +</style>
... ...
1 1 import { TableListConfig } from './TableList'
2 2 import { TableScrollBoardConfig } from './TableScrollBoard'
  3 +import { TablesBasicConfig } from "./TablesBasic/index";
3 4
4   -export default [TableListConfig, TableScrollBoardConfig]
  5 +export default [TableListConfig, TableScrollBoardConfig,TablesBasicConfig]
... ...
1 1 <template>
2 2 <!-- 原生方式,没有使用vue-echarts -->
3   - <div :style="`width:${w}px;height:${h}px;`" ref="map3DRef"></div>
  3 + <n-space vertical>
  4 + <n-spin :show="show">
  5 + <div :style="`width:${w}px;height:${h}px;`" ref="map3DRef"></div>
  6 + </n-spin>
  7 + </n-space>
4 8 </template>
5 9
6 10 <script setup lang="ts">
... ... @@ -26,6 +30,8 @@ const { w, h } = toRefs(props.chartConfig.attr)
26 30
27 31 const map3DRef = ref()
28 32
  33 +const show = ref(true)
  34 +
29 35 const chartInstance = ref()
30 36
31 37 const toolBoxOption = ref({
... ... @@ -130,6 +136,7 @@ const getGeojson = (regionId: any) => {
130 136 const geoJsonFile = JSON.parse(geoJson)
131 137 saveGeojson.value = geoJsonFile
132 138 registerMap(level === areaEnum.COUNTRY ? name : code, { geoJSON: geoJsonFile as any, specialAreas: {} })
  139 + show.value = false
133 140 resolve(true)
134 141 })
135 142 })
... ...
1 1 <template>
2 2 <div @mouseenter="handleMouseenter" @mouseleave="handleMouseleave" class="chart-amap" ref="vChartRef">
3   - <div v-if="showSearchBox" @click.stop="handleOpenSearchBox" class="search-box"></div>
  3 + <div v-show="showSearchBox" @click.stop="handleOpenSearchBox" class="search-box"></div>
4 4 <search-box :modelShow="modelShow" @searchParams="handleSearchParams" @closeDrawer="handleCloseDrawer"></search-box>
5 5 </div>
6 6 </template>
... ...
... ... @@ -10,7 +10,7 @@ export const option = {
10 10 // 时间组件展示类型,必须和 interactActions 中定义的数据一致
11 11 [COMPONENT_INTERACT_EVENT_KET]: ComponentInteractEventEnum.DATA,
12 12 // 默认值
13   - selectValue: [],
  13 + selectValue: null,
14 14 // 暴露配置内容给用户
15 15 dataset: [
16 16 {
... ... @@ -25,7 +25,8 @@ export const option = {
25 25 label: '选项3',
26 26 value: '3'
27 27 }
28   - ]
  28 + ],
  29 + multiple: false
29 30 }
30 31
31 32 export default class Config extends PublicConfigClass implements CreateComponentType {
... ...
... ... @@ -2,7 +2,17 @@
2 2 <collapse-item name="下拉配置" :expanded="true">
3 3 <setting-item-box name="默认值" :alone="true">
4 4 <SettingItem name="选择项">
5   - <n-select filterable multiple size="small" v-model:value="optionData.selectValue" :options="optionData.dataset" />
  5 + <n-select
  6 + filterable
  7 + clearable
  8 + :multiple="optionData.multiple"
  9 + size="small"
  10 + v-model:value="optionData.selectValue"
  11 + :options="optionData.dataset"
  12 + />
  13 + </SettingItem>
  14 + <SettingItem name="是否多选">
  15 + <n-switch v-model:value="optionData.multiple" size="small"></n-switch>
6 16 </SettingItem>
7 17 </setting-item-box>
8 18 </collapse-item>
... ...
1 1 <template>
2 2 <n-select
3   - multiple
  3 + clearable
  4 + :multiple="multiple"
4 5 v-model:value="option.value.selectValue"
5 6 :options="option.value.dataset"
6 7 :style="`width:${w}px;`"
... ... @@ -15,6 +16,7 @@ import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore
15 16 import { useChartInteract } from '@/hooks/external/useChartSelectInteract.hook'
16 17 import { InteractEventOn } from '@/enums/eventEnum'
17 18 import { ComponentInteractParamsEnum } from './interact'
  19 +import { useChartDataFetch } from '@/hooks'
18 20
19 21 const props = defineProps({
20 22 chartConfig: {
... ... @@ -25,6 +27,8 @@ const props = defineProps({
25 27
26 28 const { w, h } = toRefs(props.chartConfig.attr)
27 29
  30 +const { multiple } = toRefs(props.chartConfig.option)
  31 +
28 32 const option = shallowReactive({
29 33 value: {
30 34 selectValue: props.chartConfig.option.selectValue,
... ... @@ -33,7 +37,7 @@ const option = shallowReactive({
33 37 })
34 38
35 39 // 监听事件改变
36   -const onChange = (v: string[]) => {
  40 +const onChange = (v: string[] | string) => {
37 41 // 存储到联动数据
38 42 useChartInteract(
39 43 props.chartConfig,
... ... @@ -55,6 +59,11 @@ watch(
55 59 deep: true
56 60 }
57 61 )
  62 +
  63 +// 数据更新 (默认更新 dataset,若更新之后有其它操作,可添加回调函数) 解决给另一个下拉框赋值
  64 +useChartDataFetch(props.chartConfig, useChartEditStore, (resData: any) => {
  65 + option.value.dataset = resData
  66 +})
58 67 </script>
59 68
60 69 <style lang="scss" scoped>
... ...
  1 +import { PublicConfigClass } from '@/packages/public'
  2 +import { CreateComponentType } from '@/packages/index.d'
  3 +import { OverrideTableScrollBoardConfig } from './index'
  4 +import cloneDeep from 'lodash/cloneDeep'
  5 +import dataJson from './data.json'
  6 +
  7 +export const option = {
  8 + header: ['列1', '列2', '列3'],
  9 + dataset: dataJson,
  10 + index: true,
  11 + columnWidth: [30, 100, 100],
  12 + align: ['center', 'right', 'right', 'right'],
  13 + rowNum: 5,
  14 + waitTime: 2,
  15 + headerHeight: 35,
  16 + carousel: 'single',
  17 + headerBGC: '#00BAFF',
  18 + oddRowBGC: '#003B51',
  19 + evenRowBGC: '#0A2732'
  20 +}
  21 +
  22 +export default class Config extends PublicConfigClass implements CreateComponentType {
  23 + public key = OverrideTableScrollBoardConfig.key
  24 + public chartConfig = cloneDeep(OverrideTableScrollBoardConfig)
  25 + public option = cloneDeep(option)
  26 +}
... ...
  1 +<template>
  2 + <CollapseItem name="列表" :expanded="true">
  3 + <SettingItemBox name="基础">
  4 + <SettingItem name="表行数">
  5 + <n-input-number
  6 + v-model:value="optionData.rowNum"
  7 + :min="1"
  8 + size="small"
  9 + placeholder="请输入自动计算"
  10 + ></n-input-number>
  11 + </SettingItem>
  12 + <SettingItem name="轮播时间(s)">
  13 + <n-input-number
  14 + v-model:value="optionData.waitTime"
  15 + :min="1"
  16 + size="small"
  17 + placeholder="请输入轮播时间"
  18 + ></n-input-number>
  19 + </SettingItem>
  20 + <SettingItem name="表头高度">
  21 + <n-input-number
  22 + v-model:value="optionData.headerHeight"
  23 + :min="1"
  24 + size="small"
  25 + placeholder="请输入表头高度"
  26 + ></n-input-number>
  27 + </SettingItem>
  28 + <SettingItem name="显示行号">
  29 + <n-switch size="small" v-model:value="optionData.index" />
  30 + </SettingItem>
  31 + </SettingItemBox>
  32 +
  33 + <SettingItemBox name="配置" :alone="true">
  34 + <SettingItem name="表头数据">
  35 + <n-input v-model:value="header" :min="1" size="small" placeholder="表头数据(英文','分割)"></n-input>
  36 + </SettingItem>
  37 + <SettingItem name="列对齐方式">
  38 + <n-input v-model:value="align" :min="1" size="small" placeholder="对齐方式(英文','分割)"></n-input>
  39 + </SettingItem>
  40 + <SettingItem name="列宽度">
  41 + <n-input v-model:value="columnWidth" :min="1" size="small" placeholder="列宽度(英文','分割)"></n-input>
  42 + </SettingItem>
  43 + <SettingItem name="轮播方式">
  44 + <n-select
  45 + v-model:value="optionData.carousel"
  46 + :options="[
  47 + { label: '单条轮播', value: 'single' },
  48 + { label: '整页轮播', value: 'page' },
  49 + ]"
  50 + />
  51 + </SettingItem>
  52 + </SettingItemBox>
  53 +
  54 + <SettingItemBox name="样式">
  55 + <SettingItem name="表头背景色">
  56 + <n-color-picker size="small" :modes="['hex']" v-model:value="optionData.headerBGC"></n-color-picker>
  57 + </SettingItem>
  58 + <SettingItem name="奇数行背景色">
  59 + <n-color-picker size="small" :modes="['hex']" v-model:value="optionData.oddRowBGC"></n-color-picker>
  60 + </SettingItem>
  61 + <SettingItem name="偶数行背景色">
  62 + <n-color-picker size="small" :modes="['hex']" v-model:value="optionData.evenRowBGC"></n-color-picker>
  63 + </SettingItem>
  64 + </SettingItemBox>
  65 + </CollapseItem>
  66 +</template>
  67 +
  68 +<script setup lang="ts">
  69 +import { PropType, ref, watch } from 'vue'
  70 +import { CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting'
  71 +import { option } from './config'
  72 +
  73 +const props = defineProps({
  74 + optionData: {
  75 + type: Object as PropType<typeof option>,
  76 + required: true
  77 + }
  78 +})
  79 +
  80 +const header = ref()
  81 +const align = ref()
  82 +const columnWidth = ref()
  83 +
  84 +watch(
  85 + () => props.optionData,
  86 + newData => {
  87 + header.value = props.optionData.header.toString()
  88 + align.value = props.optionData.align.toString()
  89 + columnWidth.value = props.optionData.columnWidth.toString()
  90 + },
  91 + {
  92 + deep: false,
  93 + immediate: true
  94 + }
  95 +)
  96 +
  97 +watch([header, align, columnWidth], ([headerNew, alignNew, columnWidthNew], [headerOld, alignOld, columnWidthOld]) => {
  98 + if (headerNew !== headerOld) {
  99 + props.optionData.header = headerNew.split(',')
  100 + }
  101 + if (alignNew !== alignOld) {
  102 + props.optionData.align = alignNew.split(',')
  103 + }
  104 + if (columnWidthNew !== columnWidthOld) {
  105 + // @ts-ignore
  106 + props.optionData.columnWidth = columnWidthNew.split(',')
  107 + }
  108 +})
  109 +</script>
... ...
  1 +[
  2 + ["行1列1", "行1列2", "行1列3"],
  3 + ["行2列1", "行2列2", "行2列3"],
  4 + ["行3列1", "行3列2", "行3列3"],
  5 + ["行4列1", "行4列2", "行4列3"],
  6 + ["行5列1", "行5列2", "行5列3"],
  7 + ["行6列1", "行6列2", "行6列3"],
  8 + ["行7列1", "行7列2", "行7列3"],
  9 + ["行8列1", "行8列2", "行8列3"],
  10 + ["行9列1", "行9列2", "行9列3"],
  11 + ["行10列1", "行10列2", "行10列3"]
  12 +]
... ...
  1 +import { ConfigType, PackagesCategoryEnum, ChartFrameEnum } from '@/packages/index.d'
  2 +import { ChatCategoryEnum, ChatCategoryEnumName } from '@/packages/components/Tables/index.d'
  3 +import { useWidgetKey } from '@/packages/external/useWidgetKey'
  4 +
  5 +const { key, conKey, chartKey } = useWidgetKey('OverrideTableScrollBoard', true)
  6 +
  7 +export const OverrideTableScrollBoardConfig: ConfigType = {
  8 + key,
  9 + chartKey,
  10 + conKey,
  11 + title: '设备最新数据轮播列表',
  12 + category: ChatCategoryEnum.TABLE,
  13 + categoryName: ChatCategoryEnumName.TABLE,
  14 + package: PackagesCategoryEnum.TABLES,
  15 + chartFrame: ChartFrameEnum.COMMON,
  16 + image: 'table_scrollboard.png'
  17 +}
... ...
  1 +<template>
  2 + <div class="dv-scroll-board">
  3 + <div
  4 + class="header"
  5 + v-if="status.header.length && status.mergedConfig"
  6 + :style="`background-color: ${status.mergedConfig.headerBGC};`"
  7 + >
  8 + <div
  9 + class="header-item"
  10 + v-for="(headerItem, i) in status.header"
  11 + :key="`${headerItem}${i}`"
  12 + :style="`
  13 + height: ${status.mergedConfig.headerHeight}px;
  14 + line-height: ${status.mergedConfig.headerHeight}px;
  15 + width: ${status.widths[i]}px;
  16 + `"
  17 + :align="status.aligns[i]"
  18 + v-html="headerItem"
  19 + />
  20 + </div>
  21 +
  22 + <div
  23 + v-if="status.mergedConfig"
  24 + class="rows"
  25 + :style="`height: ${h - (status.header.length ? status.mergedConfig.headerHeight : 0)}px;`"
  26 + >
  27 + <div
  28 + class="row-item"
  29 + v-for="(row, ri) in status.rows"
  30 + :key="`${row.toString()}${row.scroll}`"
  31 + :style="`
  32 + height: ${status.heights[ri]}px;
  33 + line-height: ${status.heights[ri]}px;
  34 + background-color: ${status.mergedConfig[row.rowIndex % 2 === 0 ? 'evenRowBGC' : 'oddRowBGC']};
  35 + `"
  36 + >
  37 + <div
  38 + class="ceil"
  39 + v-for="(ceil, ci) in row.ceils"
  40 + :key="`${ceil}${ri}${ci}`"
  41 + :style="`width: ${status.widths[ci]}px;`"
  42 + :align="status.aligns[ci]"
  43 + v-html="ceil"
  44 + />
  45 + </div>
  46 + </div>
  47 + </div>
  48 +</template>
  49 +
  50 +<script setup lang="ts">
  51 +import { PropType, onUnmounted, reactive, toRefs, watch, onMounted } from 'vue'
  52 +import { CreateComponentType } from '@/packages/index.d'
  53 +import { useChartDataFetch } from '@/hooks'
  54 +import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
  55 +import merge from 'lodash/merge'
  56 +import cloneDeep from 'lodash/cloneDeep'
  57 +import { getDeviceDetail, getAttribute } from '@/api/external/common/index'
  58 +
  59 +const props = defineProps({
  60 + chartConfig: {
  61 + type: Object as PropType<CreateComponentType>,
  62 + required: true
  63 + }
  64 +})
  65 +
  66 +// 这里能拿到图表宽高等
  67 +const { w, h } = toRefs(props.chartConfig.attr)
  68 +// 这里能拿到上面 config.ts 里的 option 数据
  69 +// const { rowNum, headerHeight, index, backgroundColor } = toRefs(props.chartConfig.option)
  70 +
  71 +const status = reactive({
  72 + defaultConfig: {
  73 + /**
  74 + * @description Board header
  75 + * @type {Array<String>}
  76 + * @default header = []
  77 + * @example header = ['column1', 'column2', 'column3']
  78 + */
  79 + header: [],
  80 + /**
  81 + * @description Board dataset
  82 + * @type {Array<Array>}
  83 + * @default dataset = []
  84 + */
  85 + dataset: [],
  86 + /**
  87 + * @description Row num
  88 + * @type {Number}
  89 + * @default rowNum = 5
  90 + */
  91 + rowNum: 5,
  92 + /**
  93 + * @description Header background color
  94 + * @type {String}
  95 + * @default headerBGC = '#00BAFF'
  96 + */
  97 + headerBGC: '#00BAFF',
  98 + /**
  99 + * @description Odd row background color
  100 + * @type {String}
  101 + * @default oddRowBGC = '#003B51'
  102 + */
  103 + oddRowBGC: '#003B51',
  104 + /**
  105 + * @description Even row background color
  106 + * @type {String}
  107 + * @default evenRowBGC = '#003B51'
  108 + */
  109 + evenRowBGC: '#0A2732',
  110 + /**
  111 + * @description Scroll wait time
  112 + * @type {Number}
  113 + * @default waitTime = 2
  114 + */
  115 + waitTime: 2,
  116 + /**
  117 + * @description Header height
  118 + * @type {Number}
  119 + * @default headerHeight = 35
  120 + */
  121 + headerHeight: 35,
  122 + /**
  123 + * @description Column width
  124 + * @type {Array<Number>}
  125 + * @default columnWidth = []
  126 + */
  127 + columnWidth: [],
  128 + /**
  129 + * @description Column align
  130 + * @type {Array<String>}
  131 + * @default align = []
  132 + * @example align = ['left', 'center', 'right']
  133 + */
  134 + align: [],
  135 + /**
  136 + * @description Show index
  137 + * @type {Boolean}
  138 + * @default index = false
  139 + */
  140 + index: false,
  141 + /**
  142 + * @description index Header
  143 + * @type {String}
  144 + * @default indexHeader = '#'
  145 + */
  146 + indexHeader: '#',
  147 + /**
  148 + * @description Carousel type
  149 + * @type {String}
  150 + * @default carousel = 'single'
  151 + * @example carousel = 'single' | 'page'
  152 + */
  153 + carousel: 'single',
  154 + /**
  155 + * @description Pause scroll when mouse hovered
  156 + * @type {Boolean}
  157 + * @default hoverPause = true
  158 + * @example hoverPause = true | false
  159 + */
  160 + hoverPause: true
  161 + },
  162 + mergedConfig: props.chartConfig.option,
  163 + header: [],
  164 + rowsData: [],
  165 + rows: [
  166 + {
  167 + ceils: [],
  168 + rowIndex: 0,
  169 + scroll: 0
  170 + }
  171 + ],
  172 + widths: [],
  173 + heights: [0],
  174 + avgHeight: 0,
  175 + aligns: [],
  176 + animationIndex: 0,
  177 + animationHandler: 0,
  178 + updater: 0,
  179 + needCalc: false
  180 +})
  181 +
  182 +const calcData = () => {
  183 + mergeConfig()
  184 + calcHeaderData()
  185 + calcRowsData()
  186 + calcWidths()
  187 + calcHeights()
  188 + calcAligns()
  189 + animation(true)
  190 +}
  191 +
  192 +onMounted(() => {
  193 + calcData()
  194 +})
  195 +
  196 +const mergeConfig = () => {
  197 + status.mergedConfig = merge(cloneDeep(status.defaultConfig), props.chartConfig.option)
  198 +}
  199 +
  200 +const calcHeaderData = () => {
  201 + let { header, index, indexHeader } = status.mergedConfig
  202 + if (!header.length) {
  203 + status.header = []
  204 + return
  205 + }
  206 + header = [...header]
  207 + if (index) header.unshift(indexHeader)
  208 + status.header = header
  209 +}
  210 +
  211 +const calcRowsData = () => {
  212 + let { dataset, index, headerBGC, rowNum } = status.mergedConfig
  213 + if (index) {
  214 + dataset = dataset.map((row: any, i: number) => {
  215 + row = [...row]
  216 + const indexTag = `<span class="index" style="background-color: ${headerBGC};border-radius: 3px;padding: 0px 3px;">${
  217 + i + 1
  218 + }</span>`
  219 + row.unshift(indexTag)
  220 + return row
  221 + })
  222 + }
  223 + dataset = dataset.map((ceils: any, i: number) => ({ ceils, rowIndex: i }))
  224 + const rowLength = dataset.length
  225 + if (rowLength > rowNum && rowLength < 2 * rowNum) {
  226 + dataset = [...dataset, ...dataset]
  227 + }
  228 + dataset = dataset.map((d: any, i: number) => ({ ...d, scroll: i }))
  229 +
  230 + status.rowsData = dataset
  231 + status.rows = dataset
  232 +}
  233 +
  234 +const calcWidths = () => {
  235 + const { mergedConfig, rowsData } = status
  236 + const { columnWidth, header } = mergedConfig
  237 + const usedWidth = columnWidth.reduce((all: any, ws: number) => all + ws, 0)
  238 + let columnNum = 0
  239 + if (rowsData[0]) {
  240 + columnNum = (rowsData[0] as any).ceils.length
  241 + } else if (header.length) {
  242 + columnNum = header.length
  243 + }
  244 + const avgWidth = (w.value - usedWidth) / (columnNum - columnWidth.length)
  245 + const widths = new Array(columnNum).fill(avgWidth)
  246 + status.widths = merge(widths, columnWidth)
  247 +}
  248 +
  249 +const calcHeights = (onresize = false) => {
  250 + const { mergedConfig, header } = status
  251 + const { headerHeight, rowNum, dataset } = mergedConfig
  252 + let allHeight = h.value
  253 + if (header.length) allHeight -= headerHeight
  254 + const avgHeight = allHeight / rowNum
  255 + status.avgHeight = avgHeight
  256 + if (!onresize) status.heights = new Array(dataset.length).fill(avgHeight)
  257 +}
  258 +
  259 +const calcAligns = () => {
  260 + const { header, mergedConfig } = status
  261 +
  262 + const columnNum = header.length
  263 +
  264 + let aligns = new Array(columnNum).fill('left')
  265 +
  266 + const { align } = mergedConfig
  267 +
  268 + status.aligns = merge(aligns, align)
  269 +}
  270 +
  271 +const animation = async (start = false) => {
  272 + const { needCalc } = status
  273 +
  274 + if (needCalc) {
  275 + calcRowsData()
  276 + calcHeights()
  277 + status.needCalc = false
  278 + }
  279 + let { avgHeight, animationIndex, mergedConfig, rowsData, updater } = status
  280 + const { waitTime, carousel, rowNum } = mergedConfig
  281 +
  282 + const rowLength = rowsData.length
  283 + if (rowNum >= rowLength) return
  284 + if (start) {
  285 + await new Promise(resolve => setTimeout(resolve, waitTime * 1000))
  286 + if (updater !== status.updater) return
  287 + }
  288 + const animationNum = carousel === 'single' ? 1 : rowNum
  289 + let rows = rowsData.slice(animationIndex)
  290 + rows.push(...rowsData.slice(0, animationIndex))
  291 + status.rows = rows.slice(0, carousel === 'page' ? rowNum * 2 : rowNum + 1)
  292 + status.heights = new Array(rowLength).fill(avgHeight)
  293 + await new Promise(resolve => setTimeout(resolve, 300))
  294 + if (updater !== status.updater) return
  295 + status.heights.splice(0, animationNum, ...new Array(animationNum).fill(0))
  296 + animationIndex += animationNum
  297 + const back = animationIndex - rowLength
  298 + if (back >= 0) animationIndex = back
  299 + status.animationIndex = animationIndex
  300 + status.animationHandler = setTimeout(animation, waitTime * 1000 - 300) as any
  301 +}
  302 +
  303 +const stopAnimation = () => {
  304 + status.updater = (status.updater + 1) % 999999
  305 + if (!status.animationHandler) return
  306 + clearTimeout(status.animationHandler)
  307 +}
  308 +
  309 +const onRestart = async () => {
  310 + try {
  311 + if (!status.mergedConfig) return
  312 + stopAnimation()
  313 + calcData()
  314 + } catch (error) {
  315 + console.log(error)
  316 + }
  317 +}
  318 +
  319 +watch(
  320 + () => w.value,
  321 + () => {
  322 + onRestart()
  323 + }
  324 +)
  325 +
  326 +watch(
  327 + () => h.value,
  328 + () => {
  329 + onRestart()
  330 + }
  331 +)
  332 +
  333 +// 数据更新
  334 +watch(
  335 + () => props.chartConfig.option,
  336 + () => {
  337 + onRestart()
  338 + },
  339 + { deep: true }
  340 +)
  341 +
  342 +// 数据更新 (默认更新 dataset,若更新之后有其它操作,可添加回调函数)
  343 +//特殊处理 获取属性,把标识符转为物模型的属性名称
  344 +useChartDataFetch(props.chartConfig, useChartEditStore, async (resData: any[], res: any) => {
  345 + const { requestParams } = res
  346 + if (!requestParams) return
  347 + const { Params } = requestParams
  348 + if (!Params) return
  349 + const { entityId } = Params
  350 + const thingsModel = await handleDeviceProfileAttributes(entityId)
  351 + const { attribute } = thingsModel as any
  352 + const resDataFormat = resData.reduce((acc, curr) => {
  353 + attribute.forEach((item: any) => {
  354 + if (item.identifier === curr[0]) {
  355 + curr[0] = item.name
  356 + }
  357 + })
  358 + acc.push(curr)
  359 + return [...acc]
  360 + }, [])
  361 + props.chartConfig.option.dataset = resDataFormat
  362 + onRestart()
  363 +})
  364 +
  365 +onUnmounted(() => {
  366 + stopAnimation()
  367 +})
  368 +
  369 +const handleDeviceProfileAttributes = async (entityId: string) => {
  370 + const deviceDetailRes = await getDeviceDetail(entityId)
  371 + const { deviceProfileId } = deviceDetailRes
  372 + if (!deviceProfileId) return
  373 + const attributeRes = await getAttribute(deviceProfileId)
  374 + const dataFormat = handleDataFormat(deviceDetailRes, attributeRes)
  375 + return dataFormat
  376 +}
  377 +
  378 +const handleDataFormat = (deviceDetail: any, attributes: any) => {
  379 + const { name, tbDeviceId } = deviceDetail
  380 + const attribute = attributes.map((item: any) => ({
  381 + identifier: item.identifier,
  382 + name: item.name,
  383 + detail: item.detail
  384 + }))
  385 + return {
  386 + name,
  387 + tbDeviceId,
  388 + attribute
  389 + }
  390 +}
  391 +</script>
  392 +
  393 +<style lang="scss" scoped>
  394 +.dv-scroll-board {
  395 + position: relative;
  396 + width: 100%;
  397 + height: 100%;
  398 + color: #fff;
  399 +
  400 + .text {
  401 + padding: 0 10px;
  402 + box-sizing: border-box;
  403 + white-space: nowrap;
  404 + overflow: hidden;
  405 + text-overflow: ellipsis;
  406 + }
  407 +
  408 + .header {
  409 + display: flex;
  410 + flex-direction: row;
  411 + font-size: 15px;
  412 +
  413 + .header-item {
  414 + transition: all 0.3s;
  415 + }
  416 + }
  417 +
  418 + .rows {
  419 + overflow: hidden;
  420 +
  421 + .row-item {
  422 + display: flex;
  423 + font-size: 14px;
  424 + transition: all 0.3s;
  425 + overflow: hidden;
  426 + }
  427 + }
  428 +}
  429 +</style>
... ...
... ... @@ -49,6 +49,7 @@ import { Decorates09Config } from '@/packages/components/external/Decorates/Deco
49 49 import { Decorates10Config } from '@/packages/components/external/Decorates/Decorates/Decorates10'
50 50 import { Decorates11Config } from '@/packages/components/external/Decorates/Decorates/Decorates11'
51 51 import { Decorates12Config } from '@/packages/components/external/Decorates/Decorates/Decorates12'
  52 +import { OverrideTableScrollBoardConfig } from '@/packages/components/external/Tables/Tables/OverrideTableScrollBoard'
52 53
53 54
54 55 /**
... ... @@ -112,6 +113,10 @@ export function useInjectLib(packagesList: EPackagesType) {
112 113 addWidgetToCategoryByCategoryName(packagesList, PackagesCategoryEnum.CHARTS, OverrideWaterPoloConfig)//重写图表下的水球图
113 114 addWidgetToCategoryByCategoryName(packagesList, PackagesCategoryEnum.CHARTS, OverrideDialConfig)//重写图表下的表盘
114 115 //
  116 +
  117 + //列表
  118 + addWidgetToCategoryByCategoryName(packagesList, PackagesCategoryEnum.TABLES, OverrideTableScrollBoardConfig)//重写列表下的轮播列表
  119 + //
115 120 }
116 121
117 122 /**
... ...
... ... @@ -4,9 +4,8 @@ import { InformationList } from '@/packages/components/Informations/index'
4 4 import { TableList } from '@/packages/components/Tables/index'
5 5 import { PhotoList } from '@/packages/components/Photos/index'
6 6 import { IconList } from '@/packages/components/Icons/index'
7   -
8 7 import { PackagesCategoryEnum, PackagesType, ConfigType, FetchComFlagType } from '@/packages/index.d'
9   -import { useInjectLib } from './components/external/utils/useInjectLib'
  8 +import { useInjectLib } from './components/external/utils/useInjectLib' // THINGS_KIT 修改注册组件
10 9
11 10 const configModules: Record<string, { default: string }> = import.meta.glob('./components/**/config.vue', {
12 11 eager: true
... ... @@ -18,9 +17,8 @@ const imagesModules: Record<string, { default: string }> = import.meta.glob('../
18 17 eager: true
19 18 })
20 19
21   -
22 20 // * 所有图表
23   -export const packagesList: PackagesType = {
  21 +export let packagesList: PackagesType = {
24 22 [PackagesCategoryEnum.CHARTS]: ChartList,
25 23 [PackagesCategoryEnum.INFORMATIONS]: InformationList,
26 24 [PackagesCategoryEnum.TABLES]: TableList,
... ... @@ -101,4 +99,4 @@ export const fetchImages = async (targetData?: ConfigType) => {
101 99 return ''
102 100 }
103 101
104   -useInjectLib(packagesList as any)
  102 +useInjectLib(packagesList as any) // THINGS_KIT 修改注册组件
... ...
... ... @@ -20,9 +20,9 @@ import cloneDeep from 'lodash/cloneDeep'
20 20
21 21 /**
22 22 * 这里更新版本有冲突
23   - * ft 修改在公共接口下拉框里默认选择公共接口
  23 + * ft 修改在公共接口下拉框里默认选择公共接口,不选择静态
24 24 * 修改后的代码在注释之间,并标注好源代码和修改后代码,方便回溯
25   - * 源代码 requestDataType: RequestDataTypeEnum.AJAX,
  25 + * 源代码 requestDataType: RequestDataTypeEnum.STATIC,
26 26 * 修改后的代码 requestDataType: RequestDataTypeEnum.Pond,
27 27 * 修改后代码在//ft之间
28 28 */
... ...
... ... @@ -73,5 +73,5 @@ export const canvasModelIndex = 9999
73 73 // 框选时蒙层的 z-index,需比所有图表高
74 74 export const selectBoxIndex = canvasModelIndex + 10
75 75
76   -// 工作台自动保存间隔(s)
  76 +// THINGS_KIT 修改工作台自动保存间隔(s)
77 77 export const saveInterval = 30
... ...
... ... @@ -29,12 +29,10 @@ import {
29 29 EditCanvasConfigType
30 30 } from './chartEditStore.d'
31 31
32   -// THINGS_KIT 引入store解决报错 Uncaught Error: [🍍]: getActivePinia was called with no active Pinia. Did you forget to install pinia?
33   -import { pinia } from '@/store'
34 32 import {useChartDataSocket} from "@/hooks/external/useChartDataSocket";
  33 +import { pinia } from '@/store'
35 34 const chartHistoryStore = useChartHistoryStore(pinia)
36 35 const settingStore = useSettingStore(pinia)
37   -
38 36 // 编辑区域内容
39 37 export const useChartEditStore = defineStore({
40 38 id: 'useChartEditStore',
... ... @@ -511,8 +509,8 @@ export const useChartEditStore = defineStore({
511 509 }
512 510 const parseHandle = (e: CreateComponentType | CreateComponentGroupType) => {
513 511 e = cloneDeep(e)
514   - e.attr.x = this.getMousePosition.x + 30
515   - e.attr.y = this.getMousePosition.y + 30
  512 + e.attr.x = this.getMousePosition.startX
  513 + e.attr.y = this.getMousePosition.startY
516 514 // 外层生成新 id
517 515 e.id = getUUID()
518 516 // 分组列表生成新 id
... ... @@ -553,7 +551,7 @@ export const useChartEditStore = defineStore({
553 551 this.setTargetSelectChart()
554 552
555 553 // 重新选中
556   - const historyData = HistoryItem.historyData as Array<CreateComponentType | CreateComponentGroupType>
  554 + let historyData = HistoryItem.historyData as Array<CreateComponentType | CreateComponentGroupType>
557 555 if (isArray(historyData)) {
558 556 // 选中目标元素,支持多个
559 557 historyData.forEach((item: CreateComponentType | CreateComponentGroupType) => {
... ... @@ -625,7 +623,7 @@ export const useChartEditStore = defineStore({
625 623 } else {
626 624 const group = historyData[0] as CreateComponentGroupType
627 625 group.groupList.forEach(item => {
628   - ids.push(item.id)
  626 + ids.unshift(item.id)
629 627 })
630 628 }
631 629 this.setGroup(ids, false)
... ... @@ -774,7 +772,7 @@ export const useChartEditStore = defineStore({
774 772 // 高
775 773 groupAttr.b = b < y + h ? y + h : b
776 774
777   - targetList.push(item)
  775 + targetList.unshift(item)
778 776 historyList.push(toRaw(item))
779 777 })
780 778
... ... @@ -820,7 +818,7 @@ export const useChartEditStore = defineStore({
820 818 if (isHistory) chartHistoryStore.createUnGroupHistory(cloneDeep([targetGroup]))
821 819
822 820 // 分离组件并还原位置属性
823   - targetGroup.groupList.forEach(item => {
  821 + targetGroup.groupList.reverse().forEach(item => {
824 822 item.attr.x = item.attr.x + targetGroup.attr.x
825 823 item.attr.y = item.attr.y + targetGroup.attr.y
826 824 if (!callBack) {
... ... @@ -850,7 +848,7 @@ export const useChartEditStore = defineStore({
850 848 }
851 849 },
852 850 // * 锁定
853   - setLock(status = true, isHistory = true) {
  851 + setLock(status: boolean = true, isHistory: boolean = true) {
854 852 try {
855 853 // 暂不支持多选
856 854 if (this.getTargetChart.selectId.length > 1) return
... ... @@ -879,11 +877,11 @@ export const useChartEditStore = defineStore({
879 877 }
880 878 },
881 879 // * 解除锁定
882   - setUnLock(isHistory = true) {
  880 + setUnLock(isHistory: boolean = true) {
883 881 this.setLock(false, isHistory)
884 882 },
885 883 // * 隐藏
886   - setHide(status = true, isHistory = true) {
  884 + setHide(status: boolean = true, isHistory: boolean = true) {
887 885 try {
888 886 // 暂不支持多选
889 887 if (this.getTargetChart.selectId.length > 1) return
... ... @@ -912,7 +910,7 @@ export const useChartEditStore = defineStore({
912 910 }
913 911 },
914 912 // * 显示
915   - setShow(isHistory = true) {
  913 + setShow(isHistory: boolean = true) {
916 914 this.setHide(false, isHistory)
917 915 },
918 916 // ----------------
... ...
... ... @@ -9,6 +9,12 @@
9 9 }
10 10 }
11 11
  12 +@mixin dark {
  13 + [data-theme='dark'] {
  14 + @content;
  15 + }
  16 +}
  17 +
12 18 @mixin goId($block) {
13 19 $B: $namespace + '-' + $block;
14 20 ##{$B} {
... ...
... ... @@ -130,11 +130,11 @@ export const fileToUrl = (file: File): string => {
130 130 * * file转base64
131 131 */
132 132 export const fileTobase64 = (file: File, callback: Function) => {
133   - const reader = new FileReader()
  133 + let reader = new FileReader()
134 134 reader.readAsDataURL(file)
135 135 reader.onload = function (e: ProgressEvent<FileReader>) {
136 136 if (e.target) {
137   - const base64 = e.target.result
  137 + let base64 = e.target.result
138 138 callback(base64)
139 139 }
140 140 }
... ...
... ... @@ -103,6 +103,6 @@ export const useAsideHook = () => {
103 103 selectOptions,
104 104 selectValue,
105 105 clickItemHandle,
106   - menuOptions,
  106 + menuOptions
107 107 }
108 108 }
... ...
... ... @@ -35,7 +35,7 @@
35 35
36 36 <!-- 弹窗 -->
37 37 <n-modal class="go-chart-data-monaco-editor" v-model:show="showModal" :mask-closable="false" :closeOnEsc="false">
38   - <n-card :bordered="false" role="dialog" size="small" aria-modal="true" style="width: 1000px; height: 600px">
  38 + <n-card :bordered="false" role="dialog" size="small" aria-modal="true" style="width: 1200px; height: 700px">
39 39 <template #header>
40 40 <n-space>
41 41 <n-text>过滤器函数编辑器</n-text>
... ... @@ -49,12 +49,12 @@
49 49 <n-tag type="info">
50 50 <span class="func-keyword">function</span>&nbsp;&nbsp;filter(data, res)&nbsp;&nbsp;{
51 51 </n-tag>
52   - <monaco-editor v-model:modelValue="filter" width="460px" height="380px" language="javascript" />
  52 + <monaco-editor v-model:modelValue="filter" width="660px" height="500px" language="javascript" />
53 53 <n-tag type="info">}</n-tag>
54 54 </n-space>
55 55 </div>
56   - <n-divider vertical style="height: 480px" />
57   - <n-scrollbar style="max-height: 480px">
  56 + <n-divider vertical style="height: 580px" />
  57 + <n-scrollbar style="max-height: 580px">
58 58 <n-space :size="15" vertical>
59 59 <div class="editor-data-show">
60 60 <n-space>
... ...
... ... @@ -72,7 +72,7 @@ const themeColor = computed(() => {
72 72 })
73 73
74 74 const handleClickPanel = () => {
75   - unref(requestModal)?.openModal?.(true, unref(selectedRequestType))
  75 + unref(requestModal as any)?.openModal?.(true, unref(selectedRequestType))
76 76 }
77 77
78 78 // TODO socket 请求时会触发
... ...
... ... @@ -41,13 +41,13 @@ const setConfigurationData = (params: PublicInterfaceRequestParams['Body'], valu
41 41 } else if (unref(isDynamicForm)) {
42 42 paramsItemList.value = paramsValue
43 43 const needSetValue = Reflect.get(value, type)
44   - unref(dynamicFormEl)?.setConfigurationData(needSetValue)
  44 + unref(dynamicFormEl as any)?.setConfigurationData(needSetValue)
45 45 }
46 46
47 47 }
48 48
49 49 const getConfigurationData = () => {
50   - const value = unref(dynamicFormEl)?.getConfigurationData()
  50 + const value = unref(dynamicFormEl as any)?.getConfigurationData()
51 51 const getValue = unref(isDynamicForm) ? value : unref(isEditor) ? unref(editorValue) : {}
52 52 const record = {
53 53 'form-data': {},
... ...
... ... @@ -91,7 +91,7 @@ const handleSelectedInterfaceChange = async (_value: string, option: PublicInter
91 91 requestHttpTypeRef.value = option.requestHttpType as RequestHttpEnum
92 92 const { Header = [], Body } = JSON.parse(option.requestParams) as PublicInterfaceRequestParams
93 93 headerRef.value = isArray(Header) ? (Header as ParamsItemType[]).reduce((prev, next) => ({ ...prev, [next.key]: next.value }), {}) : {}
94   - unref(bodyContentEl)?.setConfigurationData(unref(getSelectedInterfaceBody), Body)
  94 + unref(bodyContentEl as any)?.setConfigurationData(unref(getSelectedInterfaceBody), Body)
95 95 await nextTick()
96 96 /**
97 97 * FT 修改新增从接口取出filter
... ... @@ -108,16 +108,16 @@ const getGetRequestTypeName = (key: RequestContentTypeEnum) => {
108 108 }
109 109
110 110 const validate = async () => {
111   - if (unref(paramsDynamicFormEl)) return await unref(paramsDynamicFormEl)?.validate()
112   - if (unref(socketDynamicFormEl)) return await unref(socketDynamicFormEl)?.validate()
  111 + if (unref(paramsDynamicFormEl)) return await unref(paramsDynamicFormEl as any)?.validate()
  112 + if (unref(socketDynamicFormEl)) return await unref(socketDynamicFormEl as any)?.validate()
113 113 }
114 114
115 115 const setDynamicFormValue = (request: ExtraRequestConfigType) => {
116 116 const { requestParams: { Params, Body } } = request
117   - if (unref(paramsDynamicFormEl)) unref(paramsDynamicFormEl)?.setConfigurationData(Params)
118   - if (unref(socketDynamicFormEl)) unref(socketDynamicFormEl)?.setConfigurationData(Params)
  117 + if (unref(paramsDynamicFormEl)) unref(paramsDynamicFormEl as any)?.setConfigurationData(Params)
  118 + if (unref(socketDynamicFormEl)) unref(socketDynamicFormEl as any)?.setConfigurationData(Params)
119 119 if (unref(bodyContentEl)) {
120   - unref(bodyContentEl)?.setConfigurationData(unref(getSelectedInterfaceBody), Body)
  120 + unref(bodyContentEl as any)?.setConfigurationData(unref(getSelectedInterfaceBody), Body)
121 121 }
122 122 /**
123 123 * ft 优化动态表单包含有entityType,则自动回填DEVICE
... ... @@ -127,22 +127,22 @@ const setDynamicFormValue = (request: ExtraRequestConfigType) => {
127 127 const { Params: includeEntityTypeByParams } = JSON.parse(request.requestParams as unknown as string)
128 128 const findEntityType = includeEntityTypeByParams.find((item: Record<string, string>) => item.key === 'scope' && item.value === 'entityType')
129 129 if (!findEntityType) return
130   - if (unref(paramsDynamicFormEl)) unref(paramsDynamicFormEl)?.setConfigurationData({
  130 + if (unref(paramsDynamicFormEl)) unref(paramsDynamicFormEl as any)?.setConfigurationData({
131 131 [findEntityType?.value]: DEVICE
132   - })
  132 + }) as any
133 133 }
134 134 //ft
135 135 }
136 136
137 137 const getDynamicFormValue = (): Recordable => {
138   - if (unref(paramsDynamicFormEl)) return unref(paramsDynamicFormEl)?.getConfigurationData() || {}
139   - if (unref(socketDynamicFormEl)) return unref(socketDynamicFormEl)?.getConfigurationData() || {}
  138 + if (unref(paramsDynamicFormEl)) return unref(paramsDynamicFormEl as any)?.getConfigurationData() || {}
  139 + if (unref(socketDynamicFormEl)) return unref(socketDynamicFormEl as any)?.getConfigurationData() || {}
140 140 return {}
141 141 }
142 142
143 143 const getConfigurationData = () => {
144 144 const record = extraPublicInterfaceInfo(unref(getSelectedInterface))
145   - const bodyValue = unref(bodyContentEl)?.getConfigurationData() || {} as RequestParams['Body']
  145 + const bodyValue = unref(bodyContentEl as any)?.getConfigurationData() || {} as RequestParams['Body']
146 146 record.requestParams[RequestParamsTypeEnum.PARAMS] = getDynamicFormValue()
147 147 record.requestParams[RequestParamsTypeEnum.HEADER] = unref(headerRef)
148 148 record.requestParams[RequestParamsTypeEnum.BODY] = bodyValue
... ...
... ... @@ -37,8 +37,8 @@ const openModal = async (flag = true, type: RequestDataTypeEnum) => {
37 37 showModal.value = flag
38 38 await nextTick()
39 39
40   - unref(componentConfigurationEl)?.setConfigurationData(unref(selectTarget)!.request || {})
41   - unref(publicInterfaceFormEl)?.setConfigurationData(unref(selectTarget)!.request || {})
  40 + unref(componentConfigurationEl as any)?.setConfigurationData(unref(selectTarget)!.request || {})
  41 + unref(publicInterfaceFormEl as any)?.setConfigurationData(unref(selectTarget)!.request || {})
42 42 }
43 43
44 44 const handleSaveAndRequest = () => {
... ... @@ -55,16 +55,16 @@ const selectTarget = computed<CreateComponentType | CreateComponentGroupType | u
55 55
56 56 const validate = async () => {
57 57 if (unref(requestDataType) === RequestDataTypeEnum.Pond) {
58   - return await unref(publicInterfaceFormEl)?.validate()
  58 + return await unref(publicInterfaceFormEl as any)?.validate()
59 59 }
60 60 return true
61 61 }
62 62
63 63 const getResult = () => {
64 64 if (unref(requestDataType) === RequestDataTypeEnum.AJAX) {
65   - return unref(componentConfigurationEl)?.getConfigurationData()
  65 + return unref(componentConfigurationEl as any)?.getConfigurationData()
66 66 } else if (unref(requestDataType) === RequestDataTypeEnum.Pond) {
67   - return unref(publicInterfaceFormEl)?.getConfigurationData()
  67 + return unref(publicInterfaceFormEl as any)?.getConfigurationData()
68 68 }
69 69
70 70 return {} as unknown as RequestConfigType
... ...
... ... @@ -16,7 +16,7 @@
16 16 <p>
17 17 <span class="func-annotate">// {{ EventTypeName[eventName] }}</span>
18 18 <br />
19   - <span class="func-keyword">async {{ eventName }}</span> (mouseEvent) {
  19 + <span class="func-keyword">async {{ eventName }}</span> (mouseEvent,components) {
20 20 </p>
21 21 <p class="go-ml-4">
22 22 <n-code :code="(targetData.events.baseEvent || {})[eventName] || ''" language="typescript"></n-code>
... ... @@ -52,7 +52,7 @@
52 52 <!-- 函数名称 -->
53 53 <p class="go-pl-3">
54 54 <span class="func-keyword">async function &nbsp;&nbsp;</span>
55   - <span class="func-keyNameWord">{{ eventName }}(mouseEvent)&nbsp;&nbsp;{</span>
  55 + <span class="func-keyNameWord">{{ eventName }}(mouseEvent,components)&nbsp;&nbsp;{</span>
56 56 </p>
57 57 <!-- 编辑主体 -->
58 58 <monaco-editor v-model:modelValue="baseEvent[eventName]" height="480px" language="javascript" />
... ...
... ... @@ -188,7 +188,7 @@ const fnEventsOptions = (): Array<SelectOption | SelectGroupOption> => {
188 188 * 不修改这里的话,会造成联动组件绑定不了动态请求或者静态相关的组件
189 189 * 由于只修改一处,所以没必要进行重写,原因是原作者绑定组件(必须是带有动态请求,不支持静态组件),此项目有时需要绑定静态组件看效果,所以不判断必须是动态请求
190 190 * 修改后的代码在注释之间,并标注好源代码和修改后代码,方便回溯
191   - * 源代码 && val.request.requestDataType === RequestDataTypeEnum.AJAX && val.request.requestUrl
  191 + * 源代码 !val.groupList && val.request.requestDataType === RequestDataTypeEnum.AJAX && val.request.requestUrl
192 192 * 修改后的代码 无修改
193 193 * 修改后代码在//之间
194 194 */
... ... @@ -228,7 +228,7 @@ const fnEventsOptions = (): Array<SelectOption | SelectGroupOption> => {
228 228 }))
229 229 const tarArr = requestDataPond.concat(mapOptionList)
230 230 targetData.value.events.interactEvents?.forEach(iaItem => {
231   - mapOptionList.forEach(optionItem => {
  231 + tarArr.forEach(optionItem => {
232 232 if (optionItem.id === iaItem.interactComponentId) {
233 233 optionItem.disabled = true
234 234 }
... ...
... ... @@ -27,7 +27,7 @@
27 27 </div>
28 28 </div>
29 29 <!-- 修复右下角白点用的 -->
30   - <div v-if="designStore.getDarkTheme" class="fix-edit-screens-block"></div>
  30 + <!-- <div v-if="designStore.getDarkTheme" class="fix-edit-screens-block"></div> -->
31 31 </div>
32 32 </template>
33 33 <script setup lang="ts">
... ... @@ -290,7 +290,6 @@ window.onKeySpacePressHold = (isHold: boolean) => {
290 290
291 291 <style lang="scss" scoped>
292 292 @include go('sketch-rule') {
293   - position: relative;
294 293 overflow: hidden;
295 294 width: 100%;
296 295 height: 100%;
... ... @@ -321,6 +320,10 @@ window.onKeySpacePressHold = (isHold: boolean) => {
321 320 border-radius: 5px;
322 321 background-color: rgba(144, 146, 152, 0.3);
323 322 }
  323 + // 修复右下角白点用的
  324 + &::-webkit-scrollbar-corner {
  325 + background-color: transparent;
  326 + }
324 327 }
325 328
326 329 .fix-edit-screens-block {
... ...
... ... @@ -45,7 +45,6 @@ export const dragHandle = async (e: DragEvent) => {
45 45 chartEditStore.setTargetSelectChart(newComponent.id)
46 46 loadingFinish()
47 47 } catch (error) {
48   - console.log(error)
49 48 loadingError()
50 49 window['$message'].warning(`图表正在研发中, 敬请期待...`)
51 50 }
... ... @@ -232,7 +231,7 @@ export const useMouseHandle = () => {
232 231 const startY = e.screenY
233 232
234 233 // 记录历史位置
235   - const prevComponentInstance: Array<CreateComponentType | CreateComponentGroupType> = []
  234 + let prevComponentInstance: Array<CreateComponentType | CreateComponentGroupType> = []
236 235 chartEditStore.getTargetChart.selectId.forEach(id => {
237 236 if (!targetMap.has(id)) return
238 237
... ... @@ -250,8 +249,8 @@ export const useMouseHandle = () => {
250 249 chartEditStore.setMousePosition(moveEvent.screenX, moveEvent.screenY)
251 250
252 251 // 当前偏移量,处理 scale 比例问题
253   - const offsetX = (moveEvent.screenX - startX) / scale
254   - const offsetY = (moveEvent.screenY - startY) / scale
  252 + let offsetX = (moveEvent.screenX - startX) / scale
  253 + let offsetY = (moveEvent.screenY - startY) / scale
255 254
256 255 chartEditStore.getTargetChart.selectId.forEach(id => {
257 256 if (!targetMap.has(id)) return
... ... @@ -361,8 +360,8 @@ export const useMousePointHandle = (e: MouseEvent, point: string, attr: PickCrea
361 360 const mousemove = throttle((moveEvent: MouseEvent) => {
362 361 chartEditStore.setMousePosition(moveEvent.screenX, moveEvent.screenY)
363 362
364   - const currX = Math.round((moveEvent.screenX - startX) / scale)
365   - const currY = Math.round((moveEvent.screenY - startY) / scale)
  363 + let currX = Math.round((moveEvent.screenX - startX) / scale)
  364 + let currY = Math.round((moveEvent.screenY - startY) / scale)
366 365
367 366 const isTop = /t/.test(point)
368 367 const isBottom = /b/.test(point)
... ...
... ... @@ -30,7 +30,7 @@
30 30 <span>{{ item.title }}</span>
31 31 </n-tooltip>
32 32 <n-divider vertical />
33   - <!-- 保存 -->
  33 + <!-- THINKS_KIT 新增保存按钮 -->
34 34 <n-tooltip placement="bottom" trigger="hover">
35 35 <template #trigger>
36 36 <div class="save-btn">
... ...
... ... @@ -166,7 +166,7 @@ export const useSync = () => {
166 166 // 组件
167 167 if (key === ChartEditStoreEnum.COMPONENT_LIST) {
168 168 let loadIndex = 0
169   - const listLength = projectData[key].length;
  169 + const listLength = projectData[key].length
170 170 for (const comItem of projectData[key]) {
171 171 // 设置加载数量
172 172 let percentage = parseInt((parseFloat(`${++loadIndex / listLength}`) * 100).toString())
... ...
... ... @@ -271,7 +271,6 @@ $carousel-image-height: 60vh;
271 271 height: $carousel-image-height;
272 272 }
273 273 }
274   -
275 274 .login-account {
276 275 display: flex;
277 276 flex-direction: column;
... ...
... ... @@ -10,7 +10,8 @@
10 10 ...getTransformStyle(item.styles),
11 11 ...getStatusStyle(item.status),
12 12 ...getPreviewConfigStyle(item.preview),
13   - ...getBlendModeStyle(item.styles) as any
  13 + ...getBlendModeStyle(item.styles) as any,
  14 + ...getSizeStyle(item.attr)
14 15 }"
15 16 >
16 17 <!-- 分组 -->
... ...
... ... @@ -76,35 +76,28 @@ keyRecordHandle()
76 76 height: 100vh;
77 77 width: 100vw;
78 78 @include background-image('background-image');
79   -
80 79 &.fit,
81 80 &.full {
82 81 display: flex;
83 82 align-items: center;
84 83 justify-content: center;
85 84 overflow: hidden;
86   -
87 85 .go-preview-scale {
88 86 transform-origin: center center;
89 87 }
90 88 }
91   -
92 89 &.scrollY {
93 90 overflow-x: hidden;
94   -
95 91 .go-preview-scale {
96 92 transform-origin: left top;
97 93 }
98 94 }
99   -
100 95 &.scrollX {
101 96 overflow-y: hidden;
102   -
103 97 .go-preview-scale {
104 98 transform-origin: left top;
105 99 }
106 100 }
107   -
108 101 .go-preview-entity {
109 102 overflow: hidden;
110 103 }
... ...