Commit 9065b5cb557361c8e7d6493ee0a406ec28cbc3ff

Authored by ww
1 parent 573a7484

chore: 升级go-view版本至v1.2.7

Showing 40 changed files with 750 additions and 248 deletions
1   -import axios, { AxiosResponse, AxiosRequestConfig } from 'axios'
  1 +import axios, { AxiosResponse, InternalAxiosRequestConfig, AxiosError } from 'axios'
2 2 import { ResultEnum } from "@/enums/httpEnum"
3 3 import { ErrorPageNameMap } from "@/enums/pageEnum"
4 4 import { redirectErrorPage } from '@/utils'
... ... @@ -9,10 +9,10 @@ const axiosInstance = axios.create({
9 9 })
10 10
11 11 axiosInstance.interceptors.request.use(
12   - (config: AxiosRequestConfig) => {
  12 + (config: InternalAxiosRequestConfig) => {
13 13 return config
14 14 },
15   - (error: AxiosRequestConfig) => {
  15 + (error: AxiosError) => {
16 16 Promise.reject(error)
17 17 }
18 18 )
... ... @@ -21,7 +21,7 @@ axiosInstance.interceptors.request.use(
21 21 axiosInstance.interceptors.response.use(
22 22 (res: AxiosResponse) => {
23 23 const { code } = res.data as { code: number }
24   - if (code === undefined || code === null) return Promise.resolve(res)
  24 + if (code === undefined || code === null) return Promise.resolve(res.data)
25 25 if (code === ResultEnum.DATA_SUCCESS) return Promise.resolve(res.data)
26 26 // 重定向
27 27 if (ErrorPageNameMap.get(code)) redirectErrorPage(code)
... ...
... ... @@ -391,8 +391,12 @@ const visualMap = computed(() => {
391 391 // 监听legend color颜色改变type = scroll的颜色
392 392 watch(() => legend.value && legend.value.textStyle.color, (newVal) => {
393 393 if (legend.value && newVal) {
394   - legend.value.pageTextStyle.color = newVal
395   - }
  394 + if (!legend.value.pageTextStyle) {
  395 + legend.value.pageTextStyle = { color: newVal }
  396 + } else {
  397 + legend.value.pageTextStyle.color = newVal
  398 + }
  399 + }
396 400 }, {
397 401 immediate: true,
398 402 deep: true,
... ...
... ... @@ -69,6 +69,22 @@
69 69 </setting-item>
70 70 </setting-item-box>
71 71
  72 + <!-- 预设滤镜 -->
  73 + <div v-if="presetImageList.length" class="preset-filter">
  74 + <n-image
  75 + class="preset-img"
  76 + width="46"
  77 + preview-disabled
  78 + object-fit="scale-down"
  79 + v-for="(item, index) in presetImageList"
  80 + :key="index"
  81 + :class="{ 'active-preset': item.hueRotate === chartStyles.hueRotate }"
  82 + :style="{ filter: `hue-rotate(${item.hueRotate}deg)` }"
  83 + :src="item.src"
  84 + @click="() => (chartStyles.hueRotate = item.hueRotate)"
  85 + ></n-image>
  86 + </div>
  87 +
72 88 <!-- 混合模式 -->
73 89 <setting-item-box v-if="!isCanvas" :alone="true">
74 90 <template #name>
... ... @@ -149,10 +165,12 @@
149 165 </template>
150 166
151 167 <script setup lang="ts">
152   -import { PropType } from 'vue'
  168 +import { ref, PropType } from 'vue'
153 169 import { PickCreateComponentType, BlendModeEnumList } from '@/packages/index.d'
154 170 import { SettingItemBox, SettingItem, CollapseItem } from '@/components/Pages/ChartItemSetting'
155 171 import { icon } from '@/plugins'
  172 +import logoImg from '@/assets/logo.png'
  173 +import { useDesignStore } from '@/store/modules/designStore/designStore'
156 174
157 175 const props = defineProps({
158 176 isGroup: {
... ... @@ -175,10 +193,48 @@ const { HelpOutlineIcon } = icon.ionicons5
175 193 const sliderFormatTooltip = (v: string) => {
176 194 return `${(parseFloat(v) * 100).toFixed(0)}%`
177 195 }
  196 +
178 197 // 角度格式化
179 198 const degFormatTooltip = (v: string) => {
180 199 return `${v}deg`
181 200 }
  201 +
  202 +// 预设滤镜
  203 +interface presetImageData {
  204 + index: number
  205 + src: string
  206 + hueRotate: number
  207 +}
  208 +
  209 +const presetImageList = ref([] as presetImageData[])
  210 +for (let i = 1; i <= 12; i++) {
  211 + presetImageList.value.push({
  212 + index: i,
  213 + src: logoImg,
  214 + hueRotate: i * 30
  215 + })
  216 +}
182 217 </script>
183 218
184   -<style lang="scss" scoped></style>
  219 +<style lang="scss" scoped>
  220 +// 预设滤镜
  221 +.preset-filter {
  222 + margin: 20px 0 10px 0;
  223 + display: flex;
  224 + flex-wrap: wrap;
  225 + justify-content: space-between;
  226 + .preset-img {
  227 + margin-bottom: 10px;
  228 + padding: 2px;
  229 + border-radius: 6px;
  230 + transition: 0.2s all;
  231 + cursor: pointer;
  232 + &:hover {
  233 + box-shadow: 0 0 0 2px #66a9c9;
  234 + }
  235 + }
  236 + .active-preset {
  237 + box-shadow: 0 0 0 2px #66a9c9;
  238 + }
  239 +}
  240 +</style>
... ...
... ... @@ -209,7 +209,7 @@ $lineColor: #4a9ef8;
209 209 &.down.go .front:before {
210 210 transform-origin: 50% 100%;
211 211 animation: frontFlipDown $speed ease-in-out both;
212   - box-shadow: 0 -2px 6px rgba($color: $lineColor, $alpha: 0.3);
  212 + box-shadow: 0 -2px $borderWidth 0 $frontColor;
213 213 backface-visibility: hidden;
214 214 }
215 215 &.down.go .back:after {
... ... @@ -233,7 +233,7 @@ $lineColor: #4a9ef8;
233 233 &.up.go .front:after {
234 234 transform-origin: 50% 0;
235 235 animation: frontFlipUp $speed ease-in-out both;
236   - box-shadow: 0 2px 6px rgba($color: $lineColor, $alpha: 0.3);
  236 + box-shadow: 0 2px $borderWidth 0 $frontColor;
237 237 backface-visibility: hidden;
238 238 }
239 239 &.up.go .back:before {
... ...
... ... @@ -21,7 +21,7 @@ type ChartEditStoreType = typeof useChartEditStore
21 21 * @param useChartEditStore 若直接引会报错,只能动态传递
22 22 * @param updateCallback 自定义更新函数
23 23 */
24   -export const originUseChartDataFetch = (
  24 +export const originUseChartDataFetch = (
25 25 targetComponent: CreateComponentType,
26 26 useChartEditStore: ChartEditStoreType,
27 27 updateCallback?: (...args: any) => any
... ... @@ -80,11 +80,11 @@ export const originUseChartDataFetch = (
80 80 if (res) {
81 81 try {
82 82 const filter = targetComponent.filter
83   - const { data } = res
84   - echartsUpdateHandle(newFunctionHandle(data, res, filter))
  83 + const { data } = res
  84 + echartsUpdateHandle(newFunctionHandle(data, res, filter))
85 85 // 更新回调函数
86 86 if (updateCallback) {
87   - updateCallback(newFunctionHandle(data, res, filter))
  87 + updateCallback(newFunctionHandle(data, res, filter))
88 88 }
89 89 } catch (error) {
90 90 console.error(error)
... ... @@ -94,12 +94,12 @@ export const originUseChartDataFetch = (
94 94
95 95 // 普通初始化与组件交互处理监听
96 96 watch(
97   - () => targetComponent.request,
  97 + () => targetComponent.request.requestParams,
98 98 () => {
99 99 fetchFn()
100 100 },
101 101 {
102   - immediate: true,
  102 + immediate: false,
103 103 deep: true
104 104 }
105 105 )
... ... @@ -109,7 +109,11 @@ export const originUseChartDataFetch = (
109 109 // 单位
110 110 const unit = targetInterval && targetInterval.value ? targetUnit.value : globalUnit.value
111 111 // 开启轮询
112   - if (time) fetchInterval = setInterval(fetchFn, intervalUnitHandle(time, unit))
  112 + if (time) {
  113 + fetchInterval = setInterval(fetchFn, intervalUnitHandle(time, unit))
  114 + } else {
  115 + fetchFn()
  116 + }
113 117 }
114 118 // eslint-disable-next-line no-empty
115 119 } catch (error) {
... ... @@ -118,10 +122,11 @@ export const originUseChartDataFetch = (
118 122 }
119 123
120 124 if (isPreview()) {
121   - // 判断是否是数据池类型
122 125 targetComponent.request.requestDataType === RequestDataTypeEnum.Pond
123 126 ? addGlobalDataInterface(targetComponent, useChartEditStore, updateCallback || echartsUpdateHandle)
124 127 : requestIntervalFn()
  128 + } else {
  129 + requestIntervalFn()
125 130 }
126 131 return { vChartRef }
127 132 }
... ...
1   -import { toRaw } from 'vue'
  1 +import { toRaw, watch, computed, ComputedRef } from 'vue'
2 2 import { customizeHttp } from '@/api/http'
3 3 import { CreateComponentType } from '@/packages/index.d'
4 4 import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
... ... @@ -20,7 +20,7 @@ const mittDataPondMap = new Map<string, DataPondMapType[]>()
20 20 // 创建单个数据项轮询接口
21 21 const newPondItemInterval = (
22 22 requestGlobalConfig: RequestGlobalConfigType,
23   - requestDataPondItem: RequestDataPondItemType,
  23 + requestDataPondItem: ComputedRef<RequestDataPondItemType>,
24 24 dataPondMapItem?: DataPondMapType[]
25 25 ) => {
26 26 if (!dataPondMapItem) return
... ... @@ -31,8 +31,7 @@ const newPondItemInterval = (
31 31 // 请求
32 32 const fetchFn = async () => {
33 33 try {
34   - const res = await customizeHttp(toRaw(requestDataPondItem.dataPondRequestConfig), toRaw(requestGlobalConfig))
35   -
  34 + const res = await customizeHttp(toRaw(requestDataPondItem.value.dataPondRequestConfig), toRaw(requestGlobalConfig))
36 35 if (res) {
37 36 try {
38 37 // 遍历更新回调函数
... ... @@ -49,19 +48,32 @@ const newPondItemInterval = (
49 48 }
50 49 }
51 50
  51 + watch(
  52 + () => requestDataPondItem.value.dataPondRequestConfig.requestParams.Params,
  53 + () => {
  54 + fetchFn()
  55 + },
  56 + {
  57 + immediate: false,
  58 + deep: true
  59 + }
  60 + )
  61 +
  62 +
52 63 // 立即调用
53 64 fetchFn()
54 65
55   - const targetInterval = requestDataPondItem.dataPondRequestConfig.requestInterval
56   - const targetUnit = requestDataPondItem.dataPondRequestConfig.requestIntervalUnit
  66 +
  67 + const targetInterval = requestDataPondItem.value.dataPondRequestConfig.requestInterval
  68 + const targetUnit = requestDataPondItem.value.dataPondRequestConfig.requestIntervalUnit
57 69
58 70 const globalRequestInterval = requestGlobalConfig.requestInterval
59 71 const globalUnit = requestGlobalConfig.requestIntervalUnit
60 72
61 73 // 定时时间
62   - const time = targetInterval ? targetInterval : globalRequestInterval
  74 + const time = targetInterval ? targetInterval : globalRequestInterval
63 75 // 单位
64   - const unit = targetInterval ? targetUnit : globalUnit
  76 + const unit = targetInterval ? targetUnit : globalUnit
65 77 // 开启轮询
66 78 if (time) fetchInterval = setInterval(fetchFn, intervalUnitHandle(time, unit))
67 79 }
... ... @@ -96,13 +108,16 @@ export const useChartDataPondFetch = () => {
96 108 }
97 109
98 110 // 初始化数据池
99   - const initDataPond = (requestGlobalConfig: RequestGlobalConfigType) => {
100   - const { requestDataPond } = requestGlobalConfig
  111 + const initDataPond = (useChartEditStore: ChartEditStoreType) => {
  112 + const { requestGlobalConfig } = useChartEditStore()
  113 + const chartEditStore = useChartEditStore()
101 114 // 根据 mapId 查找对应的数据池配置
102 115 for (let pondKey of mittDataPondMap.keys()) {
103   - const requestDataPondItem = requestDataPond.find(item => item.dataPondId === pondKey)
  116 + const requestDataPondItem = computed(() => {
  117 + return requestGlobalConfig.requestDataPond.find(item => item.dataPondId === pondKey)
  118 + }) as ComputedRef<RequestDataPondItemType>
104 119 if (requestDataPondItem) {
105   - newPondItemInterval(requestGlobalConfig, requestDataPondItem, mittDataPondMap.get(pondKey))
  120 + newPondItemInterval(chartEditStore.requestGlobalConfig, requestDataPondItem, mittDataPondMap.get(pondKey))
106 121 }
107 122 }
108 123 }
... ...
1 1 import { toRefs } from 'vue'
  2 +import { isPreview } from '@/utils'
2 3 import { CreateComponentType } from '@/packages/index.d'
3 4 import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
4 5
... ... @@ -12,6 +13,7 @@ export const useChartInteract = (
12 13 param: { [T: string]: any },
13 14 interactEventOn: string
14 15 ) => {
  16 + if (!isPreview()) return
15 17 const chartEditStore = useChartEditStore()
16 18 const { interactEvents } = chartConfig.events
17 19 const fnOnEvent = interactEvents.filter(item => {
... ... @@ -20,20 +22,37 @@ export const useChartInteract = (
20 22
21 23 if (fnOnEvent.length === 0) return
22 24 fnOnEvent.forEach(item => {
23   - const index = chartEditStore.fetchTargetIndex(item.interactComponentId)
24   - if (index === -1) return
25   - const { Params, Header } = toRefs(chartEditStore.componentList[index].request.requestParams)
26   - Object.keys(item.interactFn).forEach(key => {
27   - if (Params.value[key]) {
28   - Params.value[key] = param[item.interactFn[key]]
29   - }
30   - if (Header.value[key]) {
31   - Header.value[key] = param[item.interactFn[key]]
32   - }
33   - })
  25 +
  26 + const globalConfigPindAprndex = chartEditStore.requestGlobalConfig.requestDataPond.findIndex(cItem =>
  27 + cItem.dataPondId === item.interactComponentId
  28 + )
  29 + if (globalConfigPindAprndex !== -1) {
  30 + const { Params, Header } = toRefs(chartEditStore.requestGlobalConfig.requestDataPond[globalConfigPindAprndex].dataPondRequestConfig.requestParams)
  31 +
  32 + Object.keys(item.interactFn).forEach(key => {
  33 + if (key in Params.value) {
  34 + Params.value[key] = param[item.interactFn[key]]
  35 + }
  36 + if (key in Header.value) {
  37 + Header.value[key] = param[item.interactFn[key]]
  38 + }
  39 + })
  40 + } else {
  41 + const index = chartEditStore.fetchTargetIndex(item.interactComponentId)
  42 + if (index === -1) return
  43 + const { Params, Header } = toRefs(chartEditStore.componentList[index].request.requestParams)
  44 +
  45 + Object.keys(item.interactFn).forEach(key => {
  46 + if (key in Params.value) {
  47 + Params.value[key] = param[item.interactFn[key]]
  48 + }
  49 + if (key in Header.value) {
  50 + Header.value[key] = param[item.interactFn[key]]
  51 + }
  52 + })
  53 + }
34 54 })
35 55 }
36   -
37 56 // 联动事件触发的 type 变更时,清除当前绑定内容
38 57 export const clearInteractEvent = (chartConfig: CreateComponentType) => {
39 58
... ...
... ... @@ -54,7 +54,7 @@ export const usePreviewFitScale = (
54 54 window.addEventListener('resize', resize)
55 55 }
56 56
57   - // * 改变窗口大小重新绘制
  57 + // * 卸载监听
58 58 const unWindowResize = () => {
59 59 window.removeEventListener('resize', resize)
60 60 }
... ... @@ -106,7 +106,7 @@ export const usePreviewScrollYScale = (
106 106 window.addEventListener('resize', resize)
107 107 }
108 108
109   - // * 改变窗口大小重新绘制
  109 + // * 卸载监听
110 110 const unWindowResize = () => {
111 111 window.removeEventListener('resize', resize)
112 112 }
... ... @@ -158,7 +158,7 @@ export const usePreviewScrollXScale = (
158 158 window.addEventListener('resize', resize)
159 159 }
160 160
161   - // * 改变窗口大小重新绘制
  161 + // * 卸载监听
162 162 const unWindowResize = () => {
163 163 window.removeEventListener('resize', resize)
164 164 }
... ... @@ -205,7 +205,7 @@ export const usePreviewFullScale = (
205 205 window.addEventListener('resize', resize)
206 206 }
207 207
208   - // * 改变窗口大小重新绘制
  208 + // * 卸载监听
209 209 const unWindowResize = () => {
210 210 window.removeEventListener('resize', resize)
211 211 }
... ...
1 1 export default {
2   - create_btn: 'Creat',
  2 + create_btn: 'Create',
3 3 create_tip: 'Please select a content for development',
4 4 project: 'Project',
5 5 my: 'My',
... ...
1 1 <template>
2 2 <router-view>
3 3 <template #default="{ Component, route }">
4   - <component
5   - v-if="route.noKeepAlive"
6   - :is="Component"
7   - :key="route.fullPath"
8   - ></component>
  4 + <component v-if="route.meta.noKeepAlive" :is="Component"></component>
9 5 <keep-alive v-else>
10   - <component :is="Component" :key="route.fullPath"></component>
  6 + <component :is="Component"></component>
11 7 </keep-alive>
12 8 </template>
13 9 </router-view>
... ...
... ... @@ -134,6 +134,10 @@ const themeOptions = [
134 134 {
135 135 value: ThemeEnum.WINE,
136 136 label: '酱籽'
  137 + },
  138 + {
  139 + value: ThemeEnum.WEIXIN,
  140 + label: '卫星'
137 141 }
138 142 ]
139 143
... ...
... ... @@ -7,6 +7,22 @@
7 7 </n-input-number>
8 8 </SettingItem>
9 9 </SettingItemBox>
  10 + <!-- 中心标题 -->
  11 + <SettingItemBox v-if="config.title" name="标题">
  12 + <SettingItem name="颜色">
  13 + <n-color-picker size="small" :modes="['hex']" v-model:value="config.title.textStyle.color"></n-color-picker>
  14 + </SettingItem>
  15 + <SettingItem name="字体大小">
  16 + <n-input-number
  17 + v-model:value="config.title.textStyle.fontSize"
  18 + :min="0"
  19 + :step="1"
  20 + size="small"
  21 + placeholder="字体大小"
  22 + >
  23 + </n-input-number>
  24 + </SettingItem>
  25 + </SettingItemBox>
10 26 <!-- Echarts 全局设置 -->
11 27 <SettingItemBox name="进度条">
12 28 <SettingItem name="颜色">
... ... @@ -31,24 +47,8 @@
31 47 ></n-color-picker>
32 48 </SettingItem>
33 49 </SettingItemBox>
34   - <!-- 中心标题 -->
35   - <SettingItemBox v-if="config.title" name="标题">
36   - <SettingItem name="颜色">
37   - <n-color-picker size="small" :modes="['hex']" v-model:value="config.title.textStyle.color"></n-color-picker>
38   - </SettingItem>
39   - <SettingItem name="字体大小">
40   - <n-input-number
41   - v-model:value="config.title.textStyle.fontSize"
42   - :min="0"
43   - :step="1"
44   - size="small"
45   - placeholder="字体大小"
46   - >
47   - </n-input-number>
48   - </SettingItem>
49   - </SettingItemBox>
50 50 <!-- 其他样式 -->
51   - <SettingItemBox name="轨道样式">
  51 + <SettingItemBox name="轨道">
52 52 <SettingItem name="颜色">
53 53 <n-color-picker size="small" :modes="['hex']" v-model:value="item.data[1].itemStyle.color"></n-color-picker>
54 54 </SettingItem>
... ... @@ -69,6 +69,18 @@
69 69 v-model:value="item.data[1].itemStyle.shadowColor"
70 70 ></n-color-picker>
71 71 </SettingItem>
  72 + <SettingItem name="轨道宽度">
  73 + <n-select
  74 + v-model:value="item.radius[0]"
  75 + size="small"
  76 + :options="[
  77 + { label: '窄', value: '75%' },
  78 + { label: '中', value: '60%' },
  79 + { label: '宽', value: '45%' },
  80 + { label: '更宽', value: '30%' }
  81 + ]"
  82 + />
  83 + </SettingItem>
72 84 </SettingItemBox>
73 85 </CollapseItem>
74 86 </template>
... ...
... ... @@ -41,7 +41,7 @@ const option = reactive({
41 41 const dataHandle = (newData: any) => {
42 42 const d = parseFloat(`${newData}`) * 100
43 43 let config = props.chartConfig.option
44   - config.title.text = d.toFixed(2) + '%'
  44 + config.title.text = `${+d.toFixed(2)}%`
45 45 config.series[0].data[0].value[0] = d
46 46 config.series[0].data[1].value[0] = 100 - d
47 47 option.value = mergeTheme(props.chartConfig.option, props.themeSetting, includes)
... ... @@ -68,7 +68,7 @@ watch(
68 68 useChartDataFetch(props.chartConfig, useChartEditStore, (resData: number) => {
69 69 let d = parseFloat(`${resData}`) * 100
70 70 // @ts-ignore
71   - option.value.title.text = d.toFixed(2) + '%'
  71 + option.value.title.text = `${+d.toFixed(2)}%`
72 72 // @ts-ignore
73 73 option.value.series[0].data[0].value[0] = d
74 74 // @ts-ignore
... ...
1 1 <template>
2   - <v-chart ref="vChartRef" autoresize :init-options="initOptions" :theme="themeColor" :option="option"
3   - :manual-update="isPreview()" @mouseover="handleHighlight" @mouseout="handleDownplay"></v-chart>
  2 + <v-chart
  3 + ref="vChartRef"
  4 + autoresize
  5 + :init-options="initOptions"
  6 + :theme="themeColor"
  7 + :option="option"
  8 + :manual-update="isPreview()"
  9 + @mouseover="handleHighlight"
  10 + @mouseout="handleDownplay"
  11 + ></v-chart>
4 12 </template>
5 13
6 14 <script setup lang="ts">
7   -import { computed, onMounted, PropType, reactive, watch } from 'vue'
  15 +import { computed, PropType, onMounted, watch } from 'vue'
8 16 import VChart from 'vue-echarts'
9 17 import { useCanvasInitOptions } from '@/hooks/useCanvasInitOptions.hook'
10 18 import { use } from 'echarts/core'
... ... @@ -125,9 +133,9 @@ watch(
125 133 }
126 134 )
127 135
128   -const { vChartRef } = useChartDataFetch(props.chartConfig, useChartEditStore)
129   -
130   -
  136 +const { vChartRef } = useChartDataFetch(props.chartConfig, useChartEditStore, (newData: typeof dataJson) => {
  137 + addPieInterval(newData)
  138 +})
131 139
132 140 onMounted(() => {
133 141 seriesDataMaxLength = dataJson.source.length
... ...
... ... @@ -63,7 +63,7 @@ watch(
63 63 () => props.chartConfig.option,
64 64 newVal => {
65 65 try {
66   - updateDatasetHandler((newVal as OptionType).dataset)
  66 + updateDatasetHandler((newVal as any as OptionType).dataset)
67 67 } catch (error) {
68 68 console.log(error)
69 69 }
... ...
... ... @@ -15,11 +15,11 @@ export interface IResources {
15 15 const fileSuffix = ['earth', 'gradient', 'redCircle', 'label', 'aperture', 'glow', 'light_column', 'aircraft']
16 16 const textures: ITextures[] = []
17 17
18   -const modules: Record<string, { default: string }> = import.meta.glob("../../images/earth/*", { eager: true });
19   -
20   -for (const item in modules) {
21   - const n = item.split('/').pop()
22   - if (n) {
  18 +const modules: Record<string, { default: string }> = import.meta.glob("../../images/earth/*", { eager: true })
  19 +
  20 +for(let item in modules) {
  21 + const n = item.split('/').pop()
  22 + if(n) {
23 23 textures.push({
24 24 name: n.split('.')[0],
25 25 url: modules[item].default
... ...
... ... @@ -4,7 +4,7 @@ import { PublicConfigClass } from '@/packages/public'
4 4 import { CreateComponentType } from '@/packages/index.d'
5 5 import { chartInitConfig } from '@/settings/designSetting'
6 6 import { COMPONENT_INTERACT_EVENT_KET } from '@/enums/eventEnum'
7   -import { interactActions, ComponentInteractEventEnum } from './interact'
  7 +import { interactActions, ComponentInteractEventEnum, DefaultTypeEnum, DifferUnitEnum } from './interact'
8 8 import { InputsDateConfig } from './index'
9 9
10 10 export const option = {
... ... @@ -12,9 +12,14 @@ export const option = {
12 12 [COMPONENT_INTERACT_EVENT_KET]: ComponentInteractEventEnum.DATE,
13 13 // 下拉展示
14 14 isPanel: 0,
15   - dataset: dayjs().valueOf(),
16   - differValue: 0
17   -
  15 + // 默认值
  16 + dataset: dayjs().valueOf() as number | number[] | null,
  17 + // 默认值类型
  18 + defaultType: DefaultTypeEnum.STATIC,
  19 + // 动态默认值偏移单位
  20 + differUnit: [DifferUnitEnum.DAY, DifferUnitEnum.DAY],
  21 + // 动态默认值偏移值
  22 + differValue: [0, 0]
18 23 }
19 24
20 25 export default class Config extends PublicConfigClass implements CreateComponentType {
... ...
... ... @@ -8,39 +8,67 @@
8 8 <collapse-item name="时间配置" :expanded="true">
9 9 <setting-item-box name="基础">
10 10 <setting-item name="类型">
11   - <n-select v-model:value="optionData.componentInteractEventKey" size="small" :options="datePickerTypeOptions" />
  11 + <n-select v-model:value="optionData.componentInteractEventKey" size="small" :options="datePickerTypeOptions"
  12 + @update:value="datePickerTypeUpdate"/>
12 13 </setting-item>
13 14 </setting-item-box>
14 15
15   - <setting-item-box name="默认值" :alone="true">
16   - <n-date-picker size="small" v-model:value="optionData.dataset" :type="optionData.componentInteractEventKey" />
17   - </setting-item-box>
  16 + <setting-item-box name="默认值">
  17 + <setting-item name="类型">
  18 + <n-select v-model:value="optionData.defaultType" size="small" :options="defaultTypeOptions"
  19 + @update:value="defaultTypeUpdate" />
  20 + </setting-item>
18 21
19   - <setting-item-box :alone="true">
  22 + </setting-item-box>
  23 + <setting-item-box v-if="optionData.defaultType === DefaultTypeEnum.STATIC" :alone="true">
  24 + <setting-item name="静态默认值">
  25 + <n-date-picker size="small" clearable v-model:value="optionData.dataset" :type="optionData.componentInteractEventKey" />
  26 + </setting-item>
  27 + </setting-item-box>
  28 + <setting-item-box v-if="optionData.defaultType === DefaultTypeEnum.DYNAMIC" >
20 29 <template #name>
21   - <n-text>动态</n-text>
  30 + <n-text></n-text>
22 31 <n-tooltip trigger="hover">
23 32 <template #trigger>
24 33 <n-icon size="21" :depth="3">
25 34 <help-outline-icon></help-outline-icon>
26 35 </n-icon>
27 36 </template>
28   - <n-text>动态值不为0时,默认值:取当天时间相加当前值</n-text>
  37 + <span>打开页面时浏览器操作系统的系统时间+偏移量(单位)</span>
29 38 </n-tooltip>
30 39 </template>
31   - <n-input-number v-model:value="optionData.differValue" class="input-num-width" size="small" :min="-40" :max="40">
32   - <template #suffix> 天 </template>
33   - </n-input-number>
  40 + <setting-item :name="differValueName">
  41 + <n-input-number v-model:value="optionData.differValue[0]" class="input-num-width" size="small">
  42 + <template #suffix>
  43 + {{DifferUnitObject[optionData.differUnit[0]]}}
  44 + </template>
  45 + </n-input-number>
  46 + </setting-item>
  47 + <setting-item :name="differUnitName">
  48 + <n-select v-model:value="optionData.differUnit[0]" size="small" :options="differUnitOptions" />
  49 + </setting-item>
  50 + <setting-item v-if="isRange" name="结束值动态偏移量">
  51 + <n-input-number v-model:value="optionData.differValue[1]" class="input-num-width" size="small">
  52 + <template #suffix>
  53 + {{DifferUnitObject[optionData.differUnit[1]]}}
  54 + </template>
  55 + </n-input-number>
  56 + </setting-item>
  57 + <setting-item v-if="isRange" name="结束值偏移单位">
  58 + <n-select v-model:value="optionData.differUnit[1]" size="small" :options="differUnitOptions" />
  59 + </setting-item>
34 60 </setting-item-box>
  61 +
35 62 </collapse-item>
36 63 </template>
37 64
38 65 <script lang="ts" setup>
39   -import { PropType } from 'vue'
  66 +import { PropType, computed } from 'vue'
40 67 import { icon } from '@/plugins'
41 68 import { CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting'
42 69 import { option } from './config'
43   -import { ComponentInteractEventEnum } from './interact'
  70 +import { ComponentInteractEventEnum, DefaultTypeEnum, DifferUnitEnum, DifferUnitObject } from './interact'
  71 +import dayjs from "dayjs";
44 72
45 73 const { HelpOutlineIcon } = icon.ionicons5
46 74
... ... @@ -100,4 +128,87 @@ const datePickerTypeOptions = [
100 128 value: ComponentInteractEventEnum.QUARTER_RANGE
101 129 }
102 130 ]
  131 +
  132 +const defaultTypeOptions = [
  133 + {
  134 + label: '静态',
  135 + value: DefaultTypeEnum.STATIC
  136 + },
  137 + {
  138 + label: '动态',
  139 + value: DefaultTypeEnum.DYNAMIC
  140 + },
  141 + {
  142 + label: '无',
  143 + value: DefaultTypeEnum.NONE
  144 + }
  145 +]
  146 +
  147 +
  148 +const differUnitOptions = [
  149 + // ManipulateType
  150 + {
  151 + value: DifferUnitEnum.DAY,
  152 + label: DifferUnitObject[DifferUnitEnum.DAY]
  153 + },
  154 + {
  155 + value: DifferUnitEnum.WEEK,
  156 + label: DifferUnitObject[DifferUnitEnum.WEEK]
  157 + },
  158 + {
  159 + value: DifferUnitEnum.MONTH,
  160 + label: DifferUnitObject[DifferUnitEnum.MONTH]
  161 + },
  162 + {
  163 + value: DifferUnitEnum.QUARTER,
  164 + label: DifferUnitObject[DifferUnitEnum.QUARTER]
  165 + },
  166 + {
  167 + value: DifferUnitEnum.YEAR,
  168 + label: DifferUnitObject[DifferUnitEnum.YEAR]
  169 + },
  170 + {
  171 + value: DifferUnitEnum.HOUR,
  172 + label: DifferUnitObject[DifferUnitEnum.HOUR]
  173 + },
  174 + {
  175 + value: DifferUnitEnum.MINUTE,
  176 + label: DifferUnitObject[DifferUnitEnum.MINUTE]
  177 + },
  178 + {
  179 + value: DifferUnitEnum.SECOND,
  180 + label: DifferUnitObject[DifferUnitEnum.SECOND]
  181 + },
  182 + {
  183 + value: DifferUnitEnum.MILLISECOND,
  184 + label: DifferUnitObject[DifferUnitEnum.MILLISECOND]
  185 + }
  186 +]
  187 +
  188 +
  189 +const isRange = computed(() => {
  190 + return props.optionData.componentInteractEventKey.endsWith('range')
  191 +})
  192 +
  193 +const differValueName = computed(() => {
  194 + return isRange.value ? '开始值动态偏移量' : '动态偏移量'
  195 +})
  196 +
  197 +const differUnitName = computed(() => {
  198 + return isRange.value ? '开始值偏移单位' : '偏移单位'
  199 +})
  200 +
  201 +const datePickerTypeUpdate = () => {
  202 + props.optionData.dataset = isRange.value ? [dayjs().valueOf(), dayjs().valueOf()] : dayjs().valueOf()
  203 +}
  204 +
  205 +const defaultTypeUpdate = (v: string) => {
  206 + if (v === DefaultTypeEnum.STATIC) {
  207 + datePickerTypeUpdate()
  208 + } else {
  209 + // DefaultTypeEnum.
  210 + props.optionData.dataset = null
  211 + }
  212 +}
  213 +
103 214 </script>
... ...
1 1 <template>
2 2 <n-date-picker
3 3 v-model:value="option.dataset"
  4 + clearable
4 5 :panel="!!chartConfig.option.isPanel"
5 6 :type="chartConfig.option.componentInteractEventKey"
6 7 :style="`width:${w}px;`"
... ... @@ -9,13 +10,15 @@
9 10 </template>
10 11
11 12 <script setup lang="ts">
12   -import { PropType, toRefs, ref, shallowReactive, watch } from 'vue'
13   -import dayjs from 'dayjs'
  13 +import { computed, PropType, ref, shallowReactive, toRefs, watch } from 'vue'
14 14 import { CreateComponentType } from '@/packages/index.d'
15 15 import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
16 16 import { useChartInteract } from '@/hooks'
17 17 import { InteractEventOn } from '@/enums/eventEnum'
18   -import { ComponentInteractParamsEnum } from './interact'
  18 +import {ComponentInteractEventEnum, ComponentInteractParamsEnum, DefaultTypeEnum} from './interact'
  19 +import dayjs, {ManipulateType} from 'dayjs'
  20 +import quarterOfYear from 'dayjs/plugin/quarterOfYear';
  21 +
19 22
20 23 const props = defineProps({
21 24 chartConfig: {
... ... @@ -31,62 +34,107 @@ const option = shallowReactive({
31 34 dataset: props.chartConfig.option.dataset
32 35 })
33 36
  37 +const isRange = computed(() => {
  38 + return props.chartConfig.option.componentInteractEventKey.endsWith('range')
  39 +})
  40 +
34 41 // 监听事件改变
35   -const onChange = (v: number | number[]) => {
36   - if (v instanceof Array) {
  42 +const onChange = (v: number | number[] | null) => {
  43 + if (isRange.value) {
  44 + let dateStart = null
  45 + let dateEnd = null
  46 + let daterange = null
  47 + if(v instanceof Array){
  48 + dateStart = v[0]
  49 + dateEnd = v[1]
  50 + daterange = `${v[0]}-${v[1]}`
  51 + }
37 52 // 存储到联动数据
38 53 useChartInteract(
39   - props.chartConfig,
40   - useChartEditStore,
41   - {
42   - [ComponentInteractParamsEnum.DATE_START]: v[0] || dayjs().valueOf(),
43   - [ComponentInteractParamsEnum.DATE_END]: v[1] || dayjs().valueOf(),
44   - [ComponentInteractParamsEnum.DATE_RANGE]: `${v[0] || dayjs().valueOf()}-${v[1] || dayjs().valueOf()}`
45   - },
46   - InteractEventOn.CHANGE
  54 + props.chartConfig,
  55 + useChartEditStore,
  56 + {
  57 + [ComponentInteractParamsEnum.DATE_START]: dateStart,
  58 + [ComponentInteractParamsEnum.DATE_END]: dateEnd,
  59 + [ComponentInteractParamsEnum.DATE_RANGE]: daterange
  60 + },
  61 + InteractEventOn.CHANGE
47 62 )
48 63 } else {
49 64 // 存储到联动数据
50 65 useChartInteract(
51   - props.chartConfig,
52   - useChartEditStore,
53   - { [ComponentInteractParamsEnum.DATE]: v || dayjs().valueOf() },
54   - InteractEventOn.CHANGE
  66 + props.chartConfig,
  67 + useChartEditStore,
  68 + { [ComponentInteractParamsEnum.DATE]: v },
  69 + InteractEventOn.CHANGE
55 70 )
56 71 }
57 72 }
58 73
59   -// 手动更新
60   -watch(
61   - () => props.chartConfig.option.dataset,
62   - (newData: number | number[]) => {
63   - option.dataset = newData
64   - // 关联目标组件首次请求带上默认内容
65   - onChange(newData)
66   - },
67   - {
68   - immediate: true
  74 +const getDiffDate = (type: ComponentInteractEventEnum, date: dayjs.Dayjs) => {
  75 + // 注册 quarterOfYear 插件
  76 + dayjs.extend(quarterOfYear)
  77 + switch (type) {
  78 + case ComponentInteractEventEnum.DATE:
  79 + case ComponentInteractEventEnum.DATE_RANGE:
  80 + date = date.startOf('day')
  81 + break
  82 + case ComponentInteractEventEnum.MONTH:
  83 + case ComponentInteractEventEnum.MONTH_RANGE:
  84 + date = date.startOf('month')
  85 + break
  86 + case ComponentInteractEventEnum.YEAR:
  87 + case ComponentInteractEventEnum.YEAR_RANGE:
  88 + date = date.startOf('year')
  89 + break
  90 + case ComponentInteractEventEnum.QUARTER:
  91 + case ComponentInteractEventEnum.QUARTER_RANGE:
  92 + date = date.startOf('quarter')
  93 + break
  94 + default:
  95 + break
69 96 }
70   -)
  97 + return date
  98 +}
71 99
72   -// 手动更新
73 100 watch(
74   - () => props.chartConfig.option.differValue,
75   - (newData: number) => {
76   - if (props.chartConfig.option.differValue === 0) return
77   - if (typeof option.dataset === 'object') {
78   - option.dataset[0] = dayjs().add(newData, 'day').valueOf()
79   - option.dataset[1] = dayjs().add(newData, 'day').valueOf()
80   - } else {
81   - option.dataset = dayjs().add(newData, 'day').valueOf()
  101 + () => {
  102 + return {
  103 + type: props.chartConfig.option.componentInteractEventKey as ComponentInteractEventEnum,
  104 + defaultType: props.chartConfig.option.defaultType as string,
  105 + differValue: props.chartConfig.option.differValue as number[],
  106 + differUnit: props.chartConfig.option.differUnit as ManipulateType[],
  107 + dataset: props.chartConfig.option.dataset as number | number[] | null,
  108 + };
  109 + },
  110 + (newData, oldData) => {
  111 + const hasTypeChanged = newData.type !== oldData?.type;
  112 + const hasDefaultTypeChanged = newData.defaultType !== oldData?.defaultType;
  113 + const hasDifferValueChanged = newData.differValue !== oldData?.differValue;
  114 + const hasDifferUnitChanged = newData.differUnit !== oldData?.differUnit;
  115 +
  116 + if (hasTypeChanged || hasDefaultTypeChanged || hasDifferValueChanged || hasDifferUnitChanged) {
  117 + if (newData.defaultType === DefaultTypeEnum.NONE) {
  118 + props.chartConfig.option.dataset = null;
  119 + } else if (newData.defaultType === DefaultTypeEnum.DYNAMIC) {
  120 + let date = dayjs();
  121 + if (isRange.value) {
  122 + props.chartConfig.option.dataset = [
  123 + getDiffDate(newData.type,date.add(newData.differValue[0], newData.differUnit[0])).valueOf(),
  124 + getDiffDate(newData.type,date.add(newData.differValue[1], newData.differUnit[1])).valueOf(),
  125 + ];
  126 + } else {
  127 + props.chartConfig.option.dataset = getDiffDate(newData.type,date.add(newData.differValue[0], newData.differUnit[0])).valueOf()
  128 + }
  129 + }
  130 + }
  131 + option.dataset = props.chartConfig.option.dataset;
  132 + onChange(option.dataset);
  133 + },
  134 + {
  135 + immediate: true,
82 136 }
83   - // 关联目标组件首次请求带上默认内容
84   - onChange(newData)
85   - },
86   - {
87   - immediate: true
88   - }
89   -)
  137 +);
90 138 </script>
91 139
92 140 <style lang="scss" scoped>
... ...
... ... @@ -22,6 +22,37 @@ export enum ComponentInteractParamsEnum {
22 22 DATE_RANGE = 'daterange'
23 23 }
24 24
  25 +export enum DefaultTypeEnum {
  26 + NONE = "none",
  27 + STATIC = "static",
  28 + DYNAMIC = "dynamic"
  29 +}
  30 +
  31 +export enum DifferUnitEnum {
  32 + DAY = 'd',
  33 + WEEK = 'w',
  34 + MONTH = 'M',
  35 + QUARTER = 'Q',
  36 + YEAR = 'y',
  37 + HOUR = 'h',
  38 + MINUTE = 'm',
  39 + SECOND = 's',
  40 + MILLISECOND = 'ms',
  41 +}
  42 +
  43 +export const DifferUnitObject = {
  44 + // https://day.js.org/docs/en/manipulate/add
  45 + [DifferUnitEnum.DAY]: '天',
  46 + [DifferUnitEnum.WEEK]: '周',
  47 + [DifferUnitEnum.MONTH]: '月',
  48 + [DifferUnitEnum.QUARTER]: '季度',
  49 + [DifferUnitEnum.YEAR]: '年',
  50 + [DifferUnitEnum.HOUR]: '小时',
  51 + [DifferUnitEnum.MINUTE]: '分钟',
  52 + [DifferUnitEnum.SECOND]: '秒',
  53 + [DifferUnitEnum.MILLISECOND]: '毫秒',
  54 +}
  55 +
25 56 const time = [
26 57 {
27 58 value: ComponentInteractParamsEnum.DATE,
... ...
1 1 <template>
2 2 <collapse-item name="标签页配置" :expanded="true">
3   - <setting-item-box name="默认值" :alone="true">
  3 + <setting-item-box name="标签类型" :alone="true">
4 4 <n-select size="small" v-model:value="optionData.tabType" :options="tabTypeOptions" />
5 5 </setting-item-box>
  6 + <setting-item-box name="默认值" :alone="true">
  7 + <n-select size="small" v-model:value="optionData.tabLabel" value-field="label" :options="optionData.dataset" />
  8 + </setting-item-box>
6 9 </collapse-item>
7 10 </template>
8 11
... ...
1 1 <template>
2   - <n-tabs :type="option.value.tabType" @update:value="onChange">
  2 + <n-tabs :type="option.value.tabType" @update:value="onChange" :default-value="option.value.tabLabel">
3 3 <n-tab v-for="(item, index) in option.value.dataset" :name="item.label" :key="index"> {{ item.label }} </n-tab>
4 4 </n-tabs>
5 5 </template>
... ...
... ... @@ -516,7 +516,7 @@ export const useChartEditStore = defineStore({
516 516 return e
517 517 }
518 518 const isCut = recordCharts.type === HistoryActionTypeEnum.CUT
519   - const targetList = Array.isArray(recordCharts.charts) ? recordCharts.charts : [recordCharts.charts]
  519 + const targetList = Array.isArray(recordCharts.charts) ? recordCharts.charts : [ recordCharts.charts ]
520 520 // 多项
521 521 targetList.forEach((e: CreateComponentType | CreateComponentGroupType) => {
522 522 this.addComponentList(parseHandle(e), undefined, true)
... ...
... ... @@ -7,3 +7,9 @@
7 7 .amap-copyright {
8 8 opacity: 0 !important;
9 9 }
  10 +
  11 +[data-theme='dark'] {
  12 + body {
  13 + background-color: #18181c;
  14 + }
  15 +}
\ No newline at end of file
... ...
... ... @@ -338,12 +338,12 @@ export const JSONParseOriginal = (data: string) => {
338 338 }
339 339 // 还原函数值
340 340 if (typeof v === 'string' && v.indexOf && (v.indexOf('function') > -1 || v.indexOf('=>') > -1)) {
341   - return eval(`(function(){return ${v}})()`)
  341 + return evalFn(`(function(){return ${v}})()`)
342 342 } else if (typeof v === 'string' && v.indexOf && v.indexOf('return ') > -1) {
343 343 const baseLeftIndex = v.indexOf('(')
344 344 if (baseLeftIndex > -1) {
345 345 const newFn = `function ${v.substring(baseLeftIndex)}`
346   - return eval(`(function(){return ${newFn}})()`)
  346 + return evalFn(`(function(){return ${newFn}})()`)
347 347 }
348 348 }
349 349 return v
... ...
... ... @@ -130,9 +130,13 @@ const sendHandle = async () => {
130 130 const res = await customizeHttp(toRaw(targetData.value.request), toRaw(chartEditStore.getRequestGlobalConfig))
131 131 loading.value = false
132 132 if (res) {
133   - const { data } = res
134   - if (!data && !targetData.value.filter) window['$message'].warning('您的数据不符合默认格式,请配置过滤器!')
135   - targetData.value.option.dataset = newFunctionHandle(data, res, targetData.value.filter)
  133 + const { data } = res
  134 + if (!data && !targetData.value.filter) {
  135 + window['$message'].warning('您的数据不符合默认格式,请配置过滤器!')
  136 + showMatching.value = true
  137 + return
  138 + }
  139 + targetData.value.option.dataset = newFunctionHandle(data, res, targetData.value.filter)
136 140 showMatching.value = true
137 141 return
138 142 }
... ...
... ... @@ -117,7 +117,11 @@ const sendHandle = async () => {
117 117 const res = await customizeHttp(toRaw(targetData.value.request), toRaw(chartEditStore.getRequestGlobalConfig))
118 118 loading.value = false
119 119 if (res) {
120   - if (!res?.data && !targetData.value.filter) window['$message'].warning('您的数据不符合默认格式,请配置过滤器!')
  120 + if (!res?.data && !targetData.value.filter) {
  121 + window['$message'].warning('您的数据不符合默认格式,请配置过滤器!')
  122 + showMatching.value = true
  123 + return
  124 + }
121 125 targetData.value.option.dataset = newFunctionHandle(res?.data, res, targetData.value.filter)
122 126 showMatching.value = true
123 127 return
... ...
1 1 <template>
2 2 <!-- 组件配置 -->
3 3 <n-divider class="go-my-3" title-placement="left"></n-divider>
4   - <setting-item-box :itemRightStyle="{
5   - gridTemplateColumns: '6fr 2fr'
6   - }" style="padding-right: 25px">
  4 + <setting-item-box
  5 + :itemRightStyle="{
  6 + gridTemplateColumns: '6fr 2fr'
  7 + }"
  8 + style="padding-right: 25px"
  9 + >
7 10 <template #name>
8 11 地址
9 12 <n-tooltip trigger="hover" v-if="isDev()">
... ... @@ -34,8 +37,13 @@
34 37 </setting-item>
35 38 <setting-item name="更新间隔,为 0 只会初始化">
36 39 <n-input-group>
37   - <n-input-number v-model:value.trim="requestInterval" class="select-time-number" min="0" :show-button="false"
38   - placeholder="默认使用全局数据">
  40 + <n-input-number
  41 + v-model:value.trim="requestInterval"
  42 + class="select-time-number"
  43 + min="0"
  44 + :show-button="false"
  45 + placeholder="默认使用全局数据"
  46 + >
39 47 </n-input-number>
40 48 <!-- 单位 -->
41 49 <n-select class="select-time-options" v-model:value="requestIntervalUnit" :options="selectTimeOptions" />
... ... @@ -150,11 +158,9 @@ const apiList = [
150 158 .select-time-number {
151 159 width: 100%;
152 160 }
153   -
154 161 .select-time-options {
155 162 width: 100px;
156 163 }
157   -
158 164 .select-type-options {
159 165 width: 120px;
160 166 }
... ...
... ... @@ -58,7 +58,7 @@
58 58 <help-outline-icon></help-outline-icon>
59 59 </n-icon>
60 60 </template>
61   - <n-text>不支持「静态组件」</n-text>
  61 + <n-text>不支持「静态组件」支持「组件」「公共APi」</n-text>
62 62 </n-tooltip>
63 63 </template>
64 64 <n-select
... ... @@ -89,7 +89,7 @@
89 89 </n-table>
90 90 </setting-item-box>
91 91
92   - <n-tag :bordered="false" type="primary"> 关联目标组件请求参数 </n-tag>
  92 + <n-tag :bordered="false" type="primary"> 关联目标请求参数 </n-tag>
93 93
94 94 <setting-item-box
95 95 :name="requestParamsItem"
... ... @@ -125,7 +125,7 @@ import { VNodeChild, computed } from 'vue'
125 125 import { SelectOption, SelectGroupOption } from 'naive-ui'
126 126 import { SettingItemBox, SettingItem, CollapseItem } from '@/components/Pages/ChartItemSetting'
127 127 import { CreateComponentType, CreateComponentGroupType, ChartFrameEnum } from '@/packages/index.d'
128   -import { RequestParamsTypeEnum } from '@/enums/httpEnum'
  128 +import { RequestParamsTypeEnum, RequestDataTypeEnum } from '@/enums/httpEnum'
129 129 import { InteractEventOn, COMPONENT_INTERACT_EVENT_KET } from '@/enums/eventEnum'
130 130 import { icon } from '@/plugins'
131 131 import noData from '@/assets/images/canvas/noData.png'
... ... @@ -154,6 +154,11 @@ const option = computed(() => {
154 154 // 绑定组件数据 request
155 155 const fnGetRequest = (id: string | undefined, key: RequestParamsTypeEnum) => {
156 156 if (!id) return {}
  157 + const globalConfigPindApr = chartEditStore.requestGlobalConfig.requestDataPond.find(item => {
  158 + return item.dataPondId === id
  159 + })?.dataPondRequestConfig.requestParams
  160 +
  161 + if (globalConfigPindApr) return globalConfigPindApr[key]
157 162 return chartEditStore.componentList[chartEditStore.fetchTargetIndex(id)]?.request.requestParams[key]
158 163 }
159 164
... ... @@ -178,12 +183,10 @@ const fnEventsOptions = (): Array<SelectOption | SelectGroupOption> => {
178 183 iter: Array<CreateComponentType | CreateComponentGroupType>,
179 184 val: CreateComponentType | CreateComponentGroupType
180 185 ) => {
181   - if (val.groupList && val.groupList.length > 0) {
182   - iter.push(val)
183   - } else {
  186 + if (!val.groupList && val.request.requestDataType === RequestDataTypeEnum.AJAX && val.request.requestUrl) {
184 187 iter.push(val)
185 188 }
186   - return val.groupList ? [...iter, ...fnFlattern(val.groupList)] : iter
  189 + return val.groupList && val.groupList.length > 0 ? [...iter, ...fnFlattern(val.groupList)] : iter
187 190 },
188 191 []
189 192 )
... ... @@ -203,9 +206,17 @@ const fnEventsOptions = (): Array<SelectOption | SelectGroupOption> => {
203 206 const mapOptionList = filterOptionList.map(item => ({
204 207 id: item.id,
205 208 title: item.chartConfig.title,
206   - disabled: false
  209 + disabled: false,
  210 + type: 'componentList'
207 211 }))
208 212
  213 + const requestDataPond = chartEditStore.requestGlobalConfig.requestDataPond.map(item => ({
  214 + id: item.dataPondId,
  215 + title: item.dataPondName,
  216 + disabled: false,
  217 + type: 'requestDataPond'
  218 + }))
  219 + const tarArr = requestDataPond.concat(mapOptionList)
209 220 targetData.value.events.interactEvents?.forEach(iaItem => {
210 221 mapOptionList.forEach(optionItem => {
211 222 if (optionItem.id === iaItem.interactComponentId) {
... ... @@ -214,7 +225,7 @@ const fnEventsOptions = (): Array<SelectOption | SelectGroupOption> => {
214 225 })
215 226 })
216 227
217   - return mapOptionList
  228 + return tarArr
218 229 }
219 230
220 231 // 新增模块
... ...
... ... @@ -159,9 +159,11 @@ const dragCanvas = (e: any) => {
159 159 const canvasBox = () => {
160 160 const layoutDom = document.getElementById('go-chart-edit-layout')
161 161 if (layoutDom) {
  162 + // 此处减去滚动条的宽度和高度
  163 + const scrollW = 20
162 164 return {
163   - height: layoutDom.clientHeight - 25,
164   - width: layoutDom.clientWidth
  165 + height: layoutDom.clientHeight - scrollW,
  166 + width: layoutDom.clientWidth - scrollW
165 167 }
166 168 }
167 169 return {
... ...
... ... @@ -66,7 +66,7 @@ const useSyncUpdateHandle = () => {
66 66 // 关闭侦听
67 67 const unUse = () => {
68 68 // clearInterval(timer)
69   - // removeEventListener('blur', syncData)
  69 + removeEventListener('blur', syncDataToPreview)
70 70 removeEventListener(SavePageEnum.JSON, updateFn)
71 71 }
72 72
... ...
... ... @@ -33,8 +33,7 @@ export const dragHandle = async (e: DragEvent) => {
33 33 if (dropData.disabled) return
34 34
35 35 // 创建新图表组件
36   - const newComponent: CreateComponentType = await createComponent(dropData)
37   - console.log(newComponent)
  36 + let newComponent: CreateComponentType = await createComponent(dropData)
38 37 if (dropData.redirectComponent) {
39 38 dropData.dataset && (newComponent.option.dataset = dropData.dataset)
40 39 newComponent.chartConfig.title = dropData.title
... ...
... ... @@ -6,7 +6,7 @@ const chartEditStore = useChartEditStore()
6 6
7 7 // 布局处理
8 8 export const useLayout = (fn: () => Promise<void>) => {
9   - const removeScale: Function = () => { }
  9 + let removeScale: Function = () => { }
10 10 onMounted(async () => {
11 11 // 设置 Dom 值(ref 不生效先用 document)
12 12 chartEditStore.setEditCanvas(
... ... @@ -21,7 +21,7 @@ export const useLayout = (fn: () => Promise<void>) => {
21 21 // 获取数据
22 22 await fn()
23 23 // 监听初始化
24   - const removeScale = chartEditStore.listenerScale()
  24 + removeScale = chartEditStore.listenerScale()
25 25
26 26 })
27 27
... ...
... ... @@ -74,7 +74,7 @@ const themeColor = computed(() => {
74 74 // 组件渲染结束初始化数据池
75 75 clearMittDataPondMap()
76 76 onMounted(() => {
77   - initDataPond(chartEditStore.requestGlobalConfig)
  77 + initDataPond(useChartEditStore)
78 78 })
79 79 </script>
80 80
... ...
... ... @@ -12,7 +12,42 @@ export const useScale = (localStorageInfo: ChartEditStorageType) => {
12 12 const height = ref(localStorageInfo.editCanvasConfig.height)
13 13 const scaleRef = ref({ width: 1, height: 1 })
14 14
15   - provide(SCALE_KEY, scaleRef);
  15 + provide(SCALE_KEY, scaleRef)
  16 +
  17 + // 监听鼠标滚轮 +ctrl 键
  18 + const useAddWheelHandle = (removeEvent: Function) => {
  19 + addEventListener(
  20 + 'wheel',
  21 + (e: any) => {
  22 + if (window?.$KeyboardActive?.ctrl) {
  23 + e.preventDefault()
  24 + e.stopPropagation()
  25 + removeEvent()
  26 + const transform = previewRef.value?.style.transform
  27 + const regRes = transform.match(/scale\((\d+\.?\d*)*/) as RegExpMatchArray
  28 + const width = regRes[1]
  29 + const previewBoxDom = document.querySelector('.go-preview') as HTMLElement
  30 + const entityDom = document.querySelector('.go-preview-entity') as HTMLElement
  31 + if (previewBoxDom) {
  32 + previewBoxDom.style.overflow = 'unset'
  33 + previewBoxDom.style.position = 'absolute'
  34 + }
  35 + if (entityDom) {
  36 + entityDom.style.overflow = 'unset'
  37 + }
  38 +
  39 + if (e.wheelDelta > 0) {
  40 + const resNum = parseFloat(Number(width).toFixed(2))
  41 + previewRef.value.style.transform = `scale(${resNum > 5 ? 5 : resNum + 0.1})`
  42 + } else {
  43 + const resNum = parseFloat(Number(width).toFixed(2))
  44 + previewRef.value.style.transform = `scale(${resNum < 0.2 ? 0.2 : resNum - 0.1})`
  45 + }
  46 + }
  47 + },
  48 + { passive: false }
  49 + )
  50 + }
16 51
17 52 const updateScaleRef = (scale: { width: number; height: number }) => {
18 53 // 这里需要解构,保证赋值给scaleRef的为一个新对象
... ... @@ -23,74 +58,82 @@ export const useScale = (localStorageInfo: ChartEditStorageType) => {
23 58 // 屏幕适配
24 59 onMounted(() => {
25 60 switch (localStorageInfo.editCanvasConfig.previewScaleType) {
26   - case PreviewScaleEnum.FIT: (() => {
27   - const { calcRate, windowResize, unWindowResize } = usePreviewFitScale(
28   - width.value as number,
29   - height.value as number,
30   - previewRef.value,
31   - updateScaleRef
32   - )
33   - calcRate()
34   - windowResize()
35   - onUnmounted(() => {
36   - unWindowResize()
37   - })
38   - })()
39   - break;
40   - case PreviewScaleEnum.SCROLL_Y: (() => {
41   - const { calcRate, windowResize, unWindowResize } = usePreviewScrollYScale(
42   - width.value as number,
43   - height.value as number,
44   - previewRef.value,
45   - (scale) => {
46   - const dom = entityRef.value
47   - dom.style.width = `${width.value * scale.width}px`
48   - dom.style.height = `${height.value * scale.height}px`
49   - updateScaleRef(scale)
50   - }
51   - )
52   - calcRate()
53   - windowResize()
54   - onUnmounted(() => {
55   - unWindowResize()
56   - })
57   - })()
  61 + case PreviewScaleEnum.FIT:
  62 + ;(() => {
  63 + const { calcRate, windowResize, unWindowResize } = usePreviewFitScale(
  64 + width.value as number,
  65 + height.value as number,
  66 + previewRef.value,
  67 + updateScaleRef
  68 + )
  69 + calcRate()
  70 + windowResize()
  71 + useAddWheelHandle(unWindowResize)
  72 + onUnmounted(() => {
  73 + unWindowResize()
  74 + })
  75 + })()
  76 + break
  77 + case PreviewScaleEnum.SCROLL_Y:
  78 + ;(() => {
  79 + const { calcRate, windowResize, unWindowResize } = usePreviewScrollYScale(
  80 + width.value as number,
  81 + height.value as number,
  82 + previewRef.value,
  83 + scale => {
  84 + const dom = entityRef.value
  85 + dom.style.width = `${width.value * scale.width}px`
  86 + dom.style.height = `${height.value * scale.height}px`
  87 + updateScaleRef(scale)
  88 + }
  89 + )
  90 + calcRate()
  91 + windowResize()
  92 + useAddWheelHandle(unWindowResize)
  93 + onUnmounted(() => {
  94 + unWindowResize()
  95 + })
  96 + })()
58 97
59   - break;
60   - case PreviewScaleEnum.SCROLL_X: (() => {
61   - const { calcRate, windowResize, unWindowResize } = usePreviewScrollXScale(
62   - width.value as number,
63   - height.value as number,
64   - previewRef.value,
65   - (scale) => {
66   - const dom = entityRef.value
67   - dom.style.width = `${width.value * scale.width}px`
68   - dom.style.height = `${height.value * scale.height}px`
69   - updateScaleRef(scale)
70   - }
71   - )
72   - calcRate()
73   - windowResize()
74   - onUnmounted(() => {
75   - unWindowResize()
76   - })
77   - })()
  98 + break
  99 + case PreviewScaleEnum.SCROLL_X:
  100 + ;(() => {
  101 + const { calcRate, windowResize, unWindowResize } = usePreviewScrollXScale(
  102 + width.value as number,
  103 + height.value as number,
  104 + previewRef.value,
  105 + scale => {
  106 + const dom = entityRef.value
  107 + dom.style.width = `${width.value * scale.width}px`
  108 + dom.style.height = `${height.value * scale.height}px`
  109 + updateScaleRef(scale)
  110 + }
  111 + )
  112 + calcRate()
  113 + windowResize()
  114 + useAddWheelHandle(unWindowResize)
  115 + onUnmounted(() => {
  116 + unWindowResize()
  117 + })
  118 + })()
78 119
79   - break;
80   - case PreviewScaleEnum.FULL: (() => {
81   - const { calcRate, windowResize, unWindowResize } = usePreviewFullScale(
82   - width.value as number,
83   - height.value as number,
84   - previewRef.value,
85   - updateScaleRef
86   - )
87   - calcRate()
88   - windowResize()
89   - onUnmounted(() => {
90   - unWindowResize()
91   - })
92   - })()
93   - break;
  120 + break
  121 + case PreviewScaleEnum.FULL:
  122 + ;(() => {
  123 + const { calcRate, windowResize, unWindowResize } = usePreviewFullScale(
  124 + width.value as number,
  125 + height.value as number,
  126 + previewRef.value,
  127 + updateScaleRef
  128 + )
  129 + calcRate()
  130 + windowResize()
  131 + useAddWheelHandle(unWindowResize)
  132 + onUnmounted(() => {
  133 + unWindowResize()
  134 + })
  135 + })()
  136 + break
94 137 }
95 138 })
96 139
... ...
1 1 <template>
2   - <div :class="`go-preview ${chartEditStore.editCanvasConfig.previewScaleType}`">
  2 + <div :class="`go-preview ${chartEditStore.editCanvasConfig.previewScaleType}`" @mousedown="dragCanvas">
3 3 <template v-if="showEntity">
4 4 <!-- 实体区域 -->
5 5 <div ref="entityRef" class="go-preview-entity">
... ... @@ -32,7 +32,7 @@ import { PreviewRenderList } from './components/PreviewRenderList'
32 32 import { getFilterStyle, setTitle } from '@/utils'
33 33
34 34 // THINGS_KIT 重写预览逻辑,调用接口
35   -// import { getEditCanvasConfigStyle, getSessionStorageInfo } from './utils'
  35 +// import { getEditCanvasConfigStyle, getSessionStorageInfo, keyRecordHandle, dragCanvas } from './utils'
36 36 import { getEditCanvasConfigStyle } from './utils'
37 37 import { getSessionStorageInfo } from './external/usePreview'
38 38
... ... @@ -65,6 +65,9 @@ const showEntity = computed(() => {
65 65 useStore(chartEditStore)
66 66 const { entityRef, previewRef } = useScale(chartEditStore)
67 67 const { show } = useComInstall(chartEditStore)
  68 +
  69 +// 开启键盘监听
  70 +keyRecordHandle()
68 71 </script>
69 72
70 73 <style lang="scss" scoped>
... ...
  1 +import { listen } from 'dom-helpers'
  2 +import throttle from 'lodash/throttle'
  3 +
  4 +let prevMoveXValue = [0, 0]
  5 +let prevMoveYValue = [0, 0]
  6 +
  7 +// 拖拽处理
  8 +export const dragCanvas = (e: MouseEvent) => {
  9 + const previewBoxDom = document.querySelector('.go-preview') as HTMLElement
  10 + if (!previewBoxDom || previewBoxDom.style.position !== 'absolute') return
  11 + if (!window.$KeyboardActive?.space) return
  12 +
  13 + e.preventDefault()
  14 + e.stopPropagation()
  15 + // @ts-ignore
  16 + document.activeElement?.blur()
  17 + const startX = e.screenX
  18 + const startY = e.screenY
  19 +
  20 + const listenMousemove = listen(
  21 + window,
  22 + 'mousemove',
  23 + throttle((moveEvent: MouseEvent) => {
  24 + const nx = moveEvent.screenX - startX
  25 + const ny = moveEvent.screenY - startY
  26 +
  27 + const [prevMoveX1, prevMoveX2] = prevMoveXValue
  28 + const [prevMoveY1, prevMoveY2] = prevMoveYValue
  29 +
  30 + prevMoveXValue = [prevMoveX2, nx]
  31 + prevMoveYValue = [prevMoveY2, ny]
  32 +
  33 + // 去除小数部分
  34 + if (previewBoxDom) {
  35 + const oldLeft = previewBoxDom.style.left ? Number(previewBoxDom.style.left.split('px')[0]) : 0
  36 + const oldTop = previewBoxDom.style.top ? Number(previewBoxDom.style.top.split('px')[0]) : 0
  37 + previewBoxDom.style.left =
  38 + oldLeft +
  39 + (prevMoveX2 > prevMoveX1 ? Math.abs(prevMoveX2 - prevMoveX1) : -Math.abs(prevMoveX2 - prevMoveX1)) +
  40 + 'px'
  41 + previewBoxDom.style.top =
  42 + oldTop +
  43 + (prevMoveY2 > prevMoveY1 ? Math.abs(prevMoveY2 - prevMoveY1) : -Math.abs(prevMoveY2 - prevMoveY1)) +
  44 + 'px'
  45 + }
  46 + }, 20)
  47 + )
  48 +
  49 + const listenMouseup = listen(window, 'mouseup', () => {
  50 + prevMoveXValue = [0, 0]
  51 + prevMoveYValue = [0, 0]
  52 + listenMousemove()
  53 + listenMouseup()
  54 + })
  55 +}
... ...
1 1 export * from './style'
2   -export * from './storage'
\ No newline at end of file
  2 +export * from './storage'
  3 +export * from './keyboard'
  4 +export * from './drag'
\ No newline at end of file
... ...
  1 +// 处理键盘记录
  2 +export const keyRecordHandle = () => {
  3 + // 默认赋值
  4 + window.$KeyboardActive = {
  5 + ctrl: false,
  6 + space: false
  7 + }
  8 +
  9 + document.onkeydown = (e: KeyboardEvent) => {
  10 + const { keyCode } = e
  11 + if (keyCode == 32 && e.target == document.body) e.preventDefault()
  12 +
  13 + if ([17, 32].includes(keyCode) && window.$KeyboardActive) {
  14 + switch (keyCode) {
  15 + case 17:
  16 + window.$KeyboardActive.ctrl = true
  17 + break
  18 + case 32:
  19 + window.$KeyboardActive.space = true
  20 + const previewBoxDom = document.querySelector('.go-preview') as HTMLElement
  21 + if (previewBoxDom && previewBoxDom.style.position === 'absolute') {
  22 + previewBoxDom.style.cursor = 'move'
  23 + }
  24 + break
  25 + }
  26 + }
  27 + }
  28 +
  29 + document.onkeyup = (e: KeyboardEvent) => {
  30 + const { keyCode } = e
  31 + if (keyCode == 32 && e.target == document.body) e.preventDefault()
  32 +
  33 + if ([17, 32].includes(keyCode) && window.$KeyboardActive) {
  34 + switch (keyCode) {
  35 + case 17:
  36 + window.$KeyboardActive.ctrl = false
  37 + break
  38 + case 32:
  39 + window.$KeyboardActive.space = false
  40 + break
  41 + }
  42 + }
  43 +
  44 + const previewBoxDom = document.querySelector('.go-preview') as HTMLElement
  45 + if (previewBoxDom) {
  46 + previewBoxDom.style.cursor = 'default'
  47 + }
  48 + }
  49 +}
... ...
... ... @@ -5,4 +5,5 @@ declare module '*.vue' {
5 5 }
6 6
7 7 declare module 'lodash/*'
8   -declare module 'dom-helpers'
\ No newline at end of file
  8 +declare module 'dom-helpers'
  9 +declare module '@iconify/vue'
\ No newline at end of file
... ...