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 import { ResultEnum } from "@/enums/httpEnum" 2 import { ResultEnum } from "@/enums/httpEnum"
3 import { ErrorPageNameMap } from "@/enums/pageEnum" 3 import { ErrorPageNameMap } from "@/enums/pageEnum"
4 import { redirectErrorPage } from '@/utils' 4 import { redirectErrorPage } from '@/utils'
@@ -9,10 +9,10 @@ const axiosInstance = axios.create({ @@ -9,10 +9,10 @@ const axiosInstance = axios.create({
9 }) 9 })
10 10
11 axiosInstance.interceptors.request.use( 11 axiosInstance.interceptors.request.use(
12 - (config: AxiosRequestConfig) => { 12 + (config: InternalAxiosRequestConfig) => {
13 return config 13 return config
14 }, 14 },
15 - (error: AxiosRequestConfig) => { 15 + (error: AxiosError) => {
16 Promise.reject(error) 16 Promise.reject(error)
17 } 17 }
18 ) 18 )
@@ -21,7 +21,7 @@ axiosInstance.interceptors.request.use( @@ -21,7 +21,7 @@ axiosInstance.interceptors.request.use(
21 axiosInstance.interceptors.response.use( 21 axiosInstance.interceptors.response.use(
22 (res: AxiosResponse) => { 22 (res: AxiosResponse) => {
23 const { code } = res.data as { code: number } 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 if (code === ResultEnum.DATA_SUCCESS) return Promise.resolve(res.data) 25 if (code === ResultEnum.DATA_SUCCESS) return Promise.resolve(res.data)
26 // 重定向 26 // 重定向
27 if (ErrorPageNameMap.get(code)) redirectErrorPage(code) 27 if (ErrorPageNameMap.get(code)) redirectErrorPage(code)
@@ -391,8 +391,12 @@ const visualMap = computed(() => { @@ -391,8 +391,12 @@ const visualMap = computed(() => {
391 // 监听legend color颜色改变type = scroll的颜色 391 // 监听legend color颜色改变type = scroll的颜色
392 watch(() => legend.value && legend.value.textStyle.color, (newVal) => { 392 watch(() => legend.value && legend.value.textStyle.color, (newVal) => {
393 if (legend.value && newVal) { 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 immediate: true, 401 immediate: true,
398 deep: true, 402 deep: true,
@@ -69,6 +69,22 @@ @@ -69,6 +69,22 @@
69 </setting-item> 69 </setting-item>
70 </setting-item-box> 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 <setting-item-box v-if="!isCanvas" :alone="true"> 89 <setting-item-box v-if="!isCanvas" :alone="true">
74 <template #name> 90 <template #name>
@@ -149,10 +165,12 @@ @@ -149,10 +165,12 @@
149 </template> 165 </template>
150 166
151 <script setup lang="ts"> 167 <script setup lang="ts">
152 -import { PropType } from 'vue' 168 +import { ref, PropType } from 'vue'
153 import { PickCreateComponentType, BlendModeEnumList } from '@/packages/index.d' 169 import { PickCreateComponentType, BlendModeEnumList } from '@/packages/index.d'
154 import { SettingItemBox, SettingItem, CollapseItem } from '@/components/Pages/ChartItemSetting' 170 import { SettingItemBox, SettingItem, CollapseItem } from '@/components/Pages/ChartItemSetting'
155 import { icon } from '@/plugins' 171 import { icon } from '@/plugins'
  172 +import logoImg from '@/assets/logo.png'
  173 +import { useDesignStore } from '@/store/modules/designStore/designStore'
156 174
157 const props = defineProps({ 175 const props = defineProps({
158 isGroup: { 176 isGroup: {
@@ -175,10 +193,48 @@ const { HelpOutlineIcon } = icon.ionicons5 @@ -175,10 +193,48 @@ const { HelpOutlineIcon } = icon.ionicons5
175 const sliderFormatTooltip = (v: string) => { 193 const sliderFormatTooltip = (v: string) => {
176 return `${(parseFloat(v) * 100).toFixed(0)}%` 194 return `${(parseFloat(v) * 100).toFixed(0)}%`
177 } 195 }
  196 +
178 // 角度格式化 197 // 角度格式化
179 const degFormatTooltip = (v: string) => { 198 const degFormatTooltip = (v: string) => {
180 return `${v}deg` 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 </script> 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,7 +209,7 @@ $lineColor: #4a9ef8;
209 &.down.go .front:before { 209 &.down.go .front:before {
210 transform-origin: 50% 100%; 210 transform-origin: 50% 100%;
211 animation: frontFlipDown $speed ease-in-out both; 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 backface-visibility: hidden; 213 backface-visibility: hidden;
214 } 214 }
215 &.down.go .back:after { 215 &.down.go .back:after {
@@ -233,7 +233,7 @@ $lineColor: #4a9ef8; @@ -233,7 +233,7 @@ $lineColor: #4a9ef8;
233 &.up.go .front:after { 233 &.up.go .front:after {
234 transform-origin: 50% 0; 234 transform-origin: 50% 0;
235 animation: frontFlipUp $speed ease-in-out both; 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 backface-visibility: hidden; 237 backface-visibility: hidden;
238 } 238 }
239 &.up.go .back:before { 239 &.up.go .back:before {
@@ -21,7 +21,7 @@ type ChartEditStoreType = typeof useChartEditStore @@ -21,7 +21,7 @@ type ChartEditStoreType = typeof useChartEditStore
21 * @param useChartEditStore 若直接引会报错,只能动态传递 21 * @param useChartEditStore 若直接引会报错,只能动态传递
22 * @param updateCallback 自定义更新函数 22 * @param updateCallback 自定义更新函数
23 */ 23 */
24 -export const originUseChartDataFetch = ( 24 +export const originUseChartDataFetch = (
25 targetComponent: CreateComponentType, 25 targetComponent: CreateComponentType,
26 useChartEditStore: ChartEditStoreType, 26 useChartEditStore: ChartEditStoreType,
27 updateCallback?: (...args: any) => any 27 updateCallback?: (...args: any) => any
@@ -80,11 +80,11 @@ export const originUseChartDataFetch = ( @@ -80,11 +80,11 @@ export const originUseChartDataFetch = (
80 if (res) { 80 if (res) {
81 try { 81 try {
82 const filter = targetComponent.filter 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 if (updateCallback) { 86 if (updateCallback) {
87 - updateCallback(newFunctionHandle(data, res, filter)) 87 + updateCallback(newFunctionHandle(data, res, filter))
88 } 88 }
89 } catch (error) { 89 } catch (error) {
90 console.error(error) 90 console.error(error)
@@ -94,12 +94,12 @@ export const originUseChartDataFetch = ( @@ -94,12 +94,12 @@ export const originUseChartDataFetch = (
94 94
95 // 普通初始化与组件交互处理监听 95 // 普通初始化与组件交互处理监听
96 watch( 96 watch(
97 - () => targetComponent.request, 97 + () => targetComponent.request.requestParams,
98 () => { 98 () => {
99 fetchFn() 99 fetchFn()
100 }, 100 },
101 { 101 {
102 - immediate: true, 102 + immediate: false,
103 deep: true 103 deep: true
104 } 104 }
105 ) 105 )
@@ -109,7 +109,11 @@ export const originUseChartDataFetch = ( @@ -109,7 +109,11 @@ export const originUseChartDataFetch = (
109 // 单位 109 // 单位
110 const unit = targetInterval && targetInterval.value ? targetUnit.value : globalUnit.value 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 // eslint-disable-next-line no-empty 118 // eslint-disable-next-line no-empty
115 } catch (error) { 119 } catch (error) {
@@ -118,10 +122,11 @@ export const originUseChartDataFetch = ( @@ -118,10 +122,11 @@ export const originUseChartDataFetch = (
118 } 122 }
119 123
120 if (isPreview()) { 124 if (isPreview()) {
121 - // 判断是否是数据池类型  
122 targetComponent.request.requestDataType === RequestDataTypeEnum.Pond 125 targetComponent.request.requestDataType === RequestDataTypeEnum.Pond
123 ? addGlobalDataInterface(targetComponent, useChartEditStore, updateCallback || echartsUpdateHandle) 126 ? addGlobalDataInterface(targetComponent, useChartEditStore, updateCallback || echartsUpdateHandle)
124 : requestIntervalFn() 127 : requestIntervalFn()
  128 + } else {
  129 + requestIntervalFn()
125 } 130 }
126 return { vChartRef } 131 return { vChartRef }
127 } 132 }
1 -import { toRaw } from 'vue' 1 +import { toRaw, watch, computed, ComputedRef } from 'vue'
2 import { customizeHttp } from '@/api/http' 2 import { customizeHttp } from '@/api/http'
3 import { CreateComponentType } from '@/packages/index.d' 3 import { CreateComponentType } from '@/packages/index.d'
4 import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore' 4 import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
@@ -20,7 +20,7 @@ const mittDataPondMap = new Map<string, DataPondMapType[]>() @@ -20,7 +20,7 @@ const mittDataPondMap = new Map<string, DataPondMapType[]>()
20 // 创建单个数据项轮询接口 20 // 创建单个数据项轮询接口
21 const newPondItemInterval = ( 21 const newPondItemInterval = (
22 requestGlobalConfig: RequestGlobalConfigType, 22 requestGlobalConfig: RequestGlobalConfigType,
23 - requestDataPondItem: RequestDataPondItemType, 23 + requestDataPondItem: ComputedRef<RequestDataPondItemType>,
24 dataPondMapItem?: DataPondMapType[] 24 dataPondMapItem?: DataPondMapType[]
25 ) => { 25 ) => {
26 if (!dataPondMapItem) return 26 if (!dataPondMapItem) return
@@ -31,8 +31,7 @@ const newPondItemInterval = ( @@ -31,8 +31,7 @@ const newPondItemInterval = (
31 // 请求 31 // 请求
32 const fetchFn = async () => { 32 const fetchFn = async () => {
33 try { 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 if (res) { 35 if (res) {
37 try { 36 try {
38 // 遍历更新回调函数 37 // 遍历更新回调函数
@@ -49,19 +48,32 @@ const newPondItemInterval = ( @@ -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 fetchFn() 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 const globalRequestInterval = requestGlobalConfig.requestInterval 70 const globalRequestInterval = requestGlobalConfig.requestInterval
59 const globalUnit = requestGlobalConfig.requestIntervalUnit 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 if (time) fetchInterval = setInterval(fetchFn, intervalUnitHandle(time, unit)) 78 if (time) fetchInterval = setInterval(fetchFn, intervalUnitHandle(time, unit))
67 } 79 }
@@ -96,13 +108,16 @@ export const useChartDataPondFetch = () => { @@ -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 // 根据 mapId 查找对应的数据池配置 114 // 根据 mapId 查找对应的数据池配置
102 for (let pondKey of mittDataPondMap.keys()) { 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 if (requestDataPondItem) { 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 import { toRefs } from 'vue' 1 import { toRefs } from 'vue'
  2 +import { isPreview } from '@/utils'
2 import { CreateComponentType } from '@/packages/index.d' 3 import { CreateComponentType } from '@/packages/index.d'
3 import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore' 4 import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
4 5
@@ -12,6 +13,7 @@ export const useChartInteract = ( @@ -12,6 +13,7 @@ export const useChartInteract = (
12 param: { [T: string]: any }, 13 param: { [T: string]: any },
13 interactEventOn: string 14 interactEventOn: string
14 ) => { 15 ) => {
  16 + if (!isPreview()) return
15 const chartEditStore = useChartEditStore() 17 const chartEditStore = useChartEditStore()
16 const { interactEvents } = chartConfig.events 18 const { interactEvents } = chartConfig.events
17 const fnOnEvent = interactEvents.filter(item => { 19 const fnOnEvent = interactEvents.filter(item => {
@@ -20,20 +22,37 @@ export const useChartInteract = ( @@ -20,20 +22,37 @@ export const useChartInteract = (
20 22
21 if (fnOnEvent.length === 0) return 23 if (fnOnEvent.length === 0) return
22 fnOnEvent.forEach(item => { 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 // 联动事件触发的 type 变更时,清除当前绑定内容 56 // 联动事件触发的 type 变更时,清除当前绑定内容
38 export const clearInteractEvent = (chartConfig: CreateComponentType) => { 57 export const clearInteractEvent = (chartConfig: CreateComponentType) => {
39 58
@@ -54,7 +54,7 @@ export const usePreviewFitScale = ( @@ -54,7 +54,7 @@ export const usePreviewFitScale = (
54 window.addEventListener('resize', resize) 54 window.addEventListener('resize', resize)
55 } 55 }
56 56
57 - // * 改变窗口大小重新绘制 57 + // * 卸载监听
58 const unWindowResize = () => { 58 const unWindowResize = () => {
59 window.removeEventListener('resize', resize) 59 window.removeEventListener('resize', resize)
60 } 60 }
@@ -106,7 +106,7 @@ export const usePreviewScrollYScale = ( @@ -106,7 +106,7 @@ export const usePreviewScrollYScale = (
106 window.addEventListener('resize', resize) 106 window.addEventListener('resize', resize)
107 } 107 }
108 108
109 - // * 改变窗口大小重新绘制 109 + // * 卸载监听
110 const unWindowResize = () => { 110 const unWindowResize = () => {
111 window.removeEventListener('resize', resize) 111 window.removeEventListener('resize', resize)
112 } 112 }
@@ -158,7 +158,7 @@ export const usePreviewScrollXScale = ( @@ -158,7 +158,7 @@ export const usePreviewScrollXScale = (
158 window.addEventListener('resize', resize) 158 window.addEventListener('resize', resize)
159 } 159 }
160 160
161 - // * 改变窗口大小重新绘制 161 + // * 卸载监听
162 const unWindowResize = () => { 162 const unWindowResize = () => {
163 window.removeEventListener('resize', resize) 163 window.removeEventListener('resize', resize)
164 } 164 }
@@ -205,7 +205,7 @@ export const usePreviewFullScale = ( @@ -205,7 +205,7 @@ export const usePreviewFullScale = (
205 window.addEventListener('resize', resize) 205 window.addEventListener('resize', resize)
206 } 206 }
207 207
208 - // * 改变窗口大小重新绘制 208 + // * 卸载监听
209 const unWindowResize = () => { 209 const unWindowResize = () => {
210 window.removeEventListener('resize', resize) 210 window.removeEventListener('resize', resize)
211 } 211 }
1 export default { 1 export default {
2 - create_btn: 'Creat', 2 + create_btn: 'Create',
3 create_tip: 'Please select a content for development', 3 create_tip: 'Please select a content for development',
4 project: 'Project', 4 project: 'Project',
5 my: 'My', 5 my: 'My',
1 <template> 1 <template>
2 <router-view> 2 <router-view>
3 <template #default="{ Component, route }"> 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 <keep-alive v-else> 5 <keep-alive v-else>
10 - <component :is="Component" :key="route.fullPath"></component> 6 + <component :is="Component"></component>
11 </keep-alive> 7 </keep-alive>
12 </template> 8 </template>
13 </router-view> 9 </router-view>
@@ -134,6 +134,10 @@ const themeOptions = [ @@ -134,6 +134,10 @@ const themeOptions = [
134 { 134 {
135 value: ThemeEnum.WINE, 135 value: ThemeEnum.WINE,
136 label: '酱籽' 136 label: '酱籽'
  137 + },
  138 + {
  139 + value: ThemeEnum.WEIXIN,
  140 + label: '卫星'
137 } 141 }
138 ] 142 ]
139 143
@@ -7,6 +7,22 @@ @@ -7,6 +7,22 @@
7 </n-input-number> 7 </n-input-number>
8 </SettingItem> 8 </SettingItem>
9 </SettingItemBox> 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 <!-- Echarts 全局设置 --> 26 <!-- Echarts 全局设置 -->
11 <SettingItemBox name="进度条"> 27 <SettingItemBox name="进度条">
12 <SettingItem name="颜色"> 28 <SettingItem name="颜色">
@@ -31,24 +47,8 @@ @@ -31,24 +47,8 @@
31 ></n-color-picker> 47 ></n-color-picker>
32 </SettingItem> 48 </SettingItem>
33 </SettingItemBox> 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 <SettingItem name="颜色"> 52 <SettingItem name="颜色">
53 <n-color-picker size="small" :modes="['hex']" v-model:value="item.data[1].itemStyle.color"></n-color-picker> 53 <n-color-picker size="small" :modes="['hex']" v-model:value="item.data[1].itemStyle.color"></n-color-picker>
54 </SettingItem> 54 </SettingItem>
@@ -69,6 +69,18 @@ @@ -69,6 +69,18 @@
69 v-model:value="item.data[1].itemStyle.shadowColor" 69 v-model:value="item.data[1].itemStyle.shadowColor"
70 ></n-color-picker> 70 ></n-color-picker>
71 </SettingItem> 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 </SettingItemBox> 84 </SettingItemBox>
73 </CollapseItem> 85 </CollapseItem>
74 </template> 86 </template>
@@ -41,7 +41,7 @@ const option = reactive({ @@ -41,7 +41,7 @@ const option = reactive({
41 const dataHandle = (newData: any) => { 41 const dataHandle = (newData: any) => {
42 const d = parseFloat(`${newData}`) * 100 42 const d = parseFloat(`${newData}`) * 100
43 let config = props.chartConfig.option 43 let config = props.chartConfig.option
44 - config.title.text = d.toFixed(2) + '%' 44 + config.title.text = `${+d.toFixed(2)}%`
45 config.series[0].data[0].value[0] = d 45 config.series[0].data[0].value[0] = d
46 config.series[0].data[1].value[0] = 100 - d 46 config.series[0].data[1].value[0] = 100 - d
47 option.value = mergeTheme(props.chartConfig.option, props.themeSetting, includes) 47 option.value = mergeTheme(props.chartConfig.option, props.themeSetting, includes)
@@ -68,7 +68,7 @@ watch( @@ -68,7 +68,7 @@ watch(
68 useChartDataFetch(props.chartConfig, useChartEditStore, (resData: number) => { 68 useChartDataFetch(props.chartConfig, useChartEditStore, (resData: number) => {
69 let d = parseFloat(`${resData}`) * 100 69 let d = parseFloat(`${resData}`) * 100
70 // @ts-ignore 70 // @ts-ignore
71 - option.value.title.text = d.toFixed(2) + '%' 71 + option.value.title.text = `${+d.toFixed(2)}%`
72 // @ts-ignore 72 // @ts-ignore
73 option.value.series[0].data[0].value[0] = d 73 option.value.series[0].data[0].value[0] = d
74 // @ts-ignore 74 // @ts-ignore
1 <template> 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 </template> 12 </template>
5 13
6 <script setup lang="ts"> 14 <script setup lang="ts">
7 -import { computed, onMounted, PropType, reactive, watch } from 'vue' 15 +import { computed, PropType, onMounted, watch } from 'vue'
8 import VChart from 'vue-echarts' 16 import VChart from 'vue-echarts'
9 import { useCanvasInitOptions } from '@/hooks/useCanvasInitOptions.hook' 17 import { useCanvasInitOptions } from '@/hooks/useCanvasInitOptions.hook'
10 import { use } from 'echarts/core' 18 import { use } from 'echarts/core'
@@ -125,9 +133,9 @@ watch( @@ -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 onMounted(() => { 140 onMounted(() => {
133 seriesDataMaxLength = dataJson.source.length 141 seriesDataMaxLength = dataJson.source.length
@@ -63,7 +63,7 @@ watch( @@ -63,7 +63,7 @@ watch(
63 () => props.chartConfig.option, 63 () => props.chartConfig.option,
64 newVal => { 64 newVal => {
65 try { 65 try {
66 - updateDatasetHandler((newVal as OptionType).dataset) 66 + updateDatasetHandler((newVal as any as OptionType).dataset)
67 } catch (error) { 67 } catch (error) {
68 console.log(error) 68 console.log(error)
69 } 69 }
@@ -15,11 +15,11 @@ export interface IResources { @@ -15,11 +15,11 @@ export interface IResources {
15 const fileSuffix = ['earth', 'gradient', 'redCircle', 'label', 'aperture', 'glow', 'light_column', 'aircraft'] 15 const fileSuffix = ['earth', 'gradient', 'redCircle', 'label', 'aperture', 'glow', 'light_column', 'aircraft']
16 const textures: ITextures[] = [] 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 textures.push({ 23 textures.push({
24 name: n.split('.')[0], 24 name: n.split('.')[0],
25 url: modules[item].default 25 url: modules[item].default
@@ -4,7 +4,7 @@ import { PublicConfigClass } from '@/packages/public' @@ -4,7 +4,7 @@ import { PublicConfigClass } from '@/packages/public'
4 import { CreateComponentType } from '@/packages/index.d' 4 import { CreateComponentType } from '@/packages/index.d'
5 import { chartInitConfig } from '@/settings/designSetting' 5 import { chartInitConfig } from '@/settings/designSetting'
6 import { COMPONENT_INTERACT_EVENT_KET } from '@/enums/eventEnum' 6 import { COMPONENT_INTERACT_EVENT_KET } from '@/enums/eventEnum'
7 -import { interactActions, ComponentInteractEventEnum } from './interact' 7 +import { interactActions, ComponentInteractEventEnum, DefaultTypeEnum, DifferUnitEnum } from './interact'
8 import { InputsDateConfig } from './index' 8 import { InputsDateConfig } from './index'
9 9
10 export const option = { 10 export const option = {
@@ -12,9 +12,14 @@ export const option = { @@ -12,9 +12,14 @@ export const option = {
12 [COMPONENT_INTERACT_EVENT_KET]: ComponentInteractEventEnum.DATE, 12 [COMPONENT_INTERACT_EVENT_KET]: ComponentInteractEventEnum.DATE,
13 // 下拉展示 13 // 下拉展示
14 isPanel: 0, 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 export default class Config extends PublicConfigClass implements CreateComponentType { 25 export default class Config extends PublicConfigClass implements CreateComponentType {
@@ -8,39 +8,67 @@ @@ -8,39 +8,67 @@
8 <collapse-item name="时间配置" :expanded="true"> 8 <collapse-item name="时间配置" :expanded="true">
9 <setting-item-box name="基础"> 9 <setting-item-box name="基础">
10 <setting-item name="类型"> 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 </setting-item> 13 </setting-item>
13 </setting-item-box> 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 <template #name> 29 <template #name>
21 - <n-text>动态</n-text> 30 + <n-text></n-text>
22 <n-tooltip trigger="hover"> 31 <n-tooltip trigger="hover">
23 <template #trigger> 32 <template #trigger>
24 <n-icon size="21" :depth="3"> 33 <n-icon size="21" :depth="3">
25 <help-outline-icon></help-outline-icon> 34 <help-outline-icon></help-outline-icon>
26 </n-icon> 35 </n-icon>
27 </template> 36 </template>
28 - <n-text>动态值不为0时,默认值:取当天时间相加当前值</n-text> 37 + <span>打开页面时浏览器操作系统的系统时间+偏移量(单位)</span>
29 </n-tooltip> 38 </n-tooltip>
30 </template> 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 </setting-item-box> 60 </setting-item-box>
  61 +
35 </collapse-item> 62 </collapse-item>
36 </template> 63 </template>
37 64
38 <script lang="ts" setup> 65 <script lang="ts" setup>
39 -import { PropType } from 'vue' 66 +import { PropType, computed } from 'vue'
40 import { icon } from '@/plugins' 67 import { icon } from '@/plugins'
41 import { CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting' 68 import { CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting'
42 import { option } from './config' 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 const { HelpOutlineIcon } = icon.ionicons5 73 const { HelpOutlineIcon } = icon.ionicons5
46 74
@@ -100,4 +128,87 @@ const datePickerTypeOptions = [ @@ -100,4 +128,87 @@ const datePickerTypeOptions = [
100 value: ComponentInteractEventEnum.QUARTER_RANGE 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 </script> 214 </script>
1 <template> 1 <template>
2 <n-date-picker 2 <n-date-picker
3 v-model:value="option.dataset" 3 v-model:value="option.dataset"
  4 + clearable
4 :panel="!!chartConfig.option.isPanel" 5 :panel="!!chartConfig.option.isPanel"
5 :type="chartConfig.option.componentInteractEventKey" 6 :type="chartConfig.option.componentInteractEventKey"
6 :style="`width:${w}px;`" 7 :style="`width:${w}px;`"
@@ -9,13 +10,15 @@ @@ -9,13 +10,15 @@
9 </template> 10 </template>
10 11
11 <script setup lang="ts"> 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 import { CreateComponentType } from '@/packages/index.d' 14 import { CreateComponentType } from '@/packages/index.d'
15 import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore' 15 import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
16 import { useChartInteract } from '@/hooks' 16 import { useChartInteract } from '@/hooks'
17 import { InteractEventOn } from '@/enums/eventEnum' 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 const props = defineProps({ 23 const props = defineProps({
21 chartConfig: { 24 chartConfig: {
@@ -31,62 +34,107 @@ const option = shallowReactive({ @@ -31,62 +34,107 @@ const option = shallowReactive({
31 dataset: props.chartConfig.option.dataset 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 useChartInteract( 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 } else { 63 } else {
49 // 存储到联动数据 64 // 存储到联动数据
50 useChartInteract( 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 watch( 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 </script> 138 </script>
91 139
92 <style lang="scss" scoped> 140 <style lang="scss" scoped>
@@ -22,6 +22,37 @@ export enum ComponentInteractParamsEnum { @@ -22,6 +22,37 @@ export enum ComponentInteractParamsEnum {
22 DATE_RANGE = 'daterange' 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 const time = [ 56 const time = [
26 { 57 {
27 value: ComponentInteractParamsEnum.DATE, 58 value: ComponentInteractParamsEnum.DATE,
1 <template> 1 <template>
2 <collapse-item name="标签页配置" :expanded="true"> 2 <collapse-item name="标签页配置" :expanded="true">
3 - <setting-item-box name="默认值" :alone="true"> 3 + <setting-item-box name="标签类型" :alone="true">
4 <n-select size="small" v-model:value="optionData.tabType" :options="tabTypeOptions" /> 4 <n-select size="small" v-model:value="optionData.tabType" :options="tabTypeOptions" />
5 </setting-item-box> 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 </collapse-item> 9 </collapse-item>
7 </template> 10 </template>
8 11
1 <template> 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 <n-tab v-for="(item, index) in option.value.dataset" :name="item.label" :key="index"> {{ item.label }} </n-tab> 3 <n-tab v-for="(item, index) in option.value.dataset" :name="item.label" :key="index"> {{ item.label }} </n-tab>
4 </n-tabs> 4 </n-tabs>
5 </template> 5 </template>
@@ -516,7 +516,7 @@ export const useChartEditStore = defineStore({ @@ -516,7 +516,7 @@ export const useChartEditStore = defineStore({
516 return e 516 return e
517 } 517 }
518 const isCut = recordCharts.type === HistoryActionTypeEnum.CUT 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 targetList.forEach((e: CreateComponentType | CreateComponentGroupType) => { 521 targetList.forEach((e: CreateComponentType | CreateComponentGroupType) => {
522 this.addComponentList(parseHandle(e), undefined, true) 522 this.addComponentList(parseHandle(e), undefined, true)
@@ -7,3 +7,9 @@ @@ -7,3 +7,9 @@
7 .amap-copyright { 7 .amap-copyright {
8 opacity: 0 !important; 8 opacity: 0 !important;
9 } 9 }
  10 +
  11 +[data-theme='dark'] {
  12 + body {
  13 + background-color: #18181c;
  14 + }
  15 +}
@@ -338,12 +338,12 @@ export const JSONParseOriginal = (data: string) => { @@ -338,12 +338,12 @@ export const JSONParseOriginal = (data: string) => {
338 } 338 }
339 // 还原函数值 339 // 还原函数值
340 if (typeof v === 'string' && v.indexOf && (v.indexOf('function') > -1 || v.indexOf('=>') > -1)) { 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 } else if (typeof v === 'string' && v.indexOf && v.indexOf('return ') > -1) { 342 } else if (typeof v === 'string' && v.indexOf && v.indexOf('return ') > -1) {
343 const baseLeftIndex = v.indexOf('(') 343 const baseLeftIndex = v.indexOf('(')
344 if (baseLeftIndex > -1) { 344 if (baseLeftIndex > -1) {
345 const newFn = `function ${v.substring(baseLeftIndex)}` 345 const newFn = `function ${v.substring(baseLeftIndex)}`
346 - return eval(`(function(){return ${newFn}})()`) 346 + return evalFn(`(function(){return ${newFn}})()`)
347 } 347 }
348 } 348 }
349 return v 349 return v
@@ -130,9 +130,13 @@ const sendHandle = async () => { @@ -130,9 +130,13 @@ const sendHandle = async () => {
130 const res = await customizeHttp(toRaw(targetData.value.request), toRaw(chartEditStore.getRequestGlobalConfig)) 130 const res = await customizeHttp(toRaw(targetData.value.request), toRaw(chartEditStore.getRequestGlobalConfig))
131 loading.value = false 131 loading.value = false
132 if (res) { 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 showMatching.value = true 140 showMatching.value = true
137 return 141 return
138 } 142 }
@@ -117,7 +117,11 @@ const sendHandle = async () => { @@ -117,7 +117,11 @@ const sendHandle = async () => {
117 const res = await customizeHttp(toRaw(targetData.value.request), toRaw(chartEditStore.getRequestGlobalConfig)) 117 const res = await customizeHttp(toRaw(targetData.value.request), toRaw(chartEditStore.getRequestGlobalConfig))
118 loading.value = false 118 loading.value = false
119 if (res) { 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 targetData.value.option.dataset = newFunctionHandle(res?.data, res, targetData.value.filter) 125 targetData.value.option.dataset = newFunctionHandle(res?.data, res, targetData.value.filter)
122 showMatching.value = true 126 showMatching.value = true
123 return 127 return
1 <template> 1 <template>
2 <!-- 组件配置 --> 2 <!-- 组件配置 -->
3 <n-divider class="go-my-3" title-placement="left"></n-divider> 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 <template #name> 10 <template #name>
8 地址 11 地址
9 <n-tooltip trigger="hover" v-if="isDev()"> 12 <n-tooltip trigger="hover" v-if="isDev()">
@@ -34,8 +37,13 @@ @@ -34,8 +37,13 @@
34 </setting-item> 37 </setting-item>
35 <setting-item name="更新间隔,为 0 只会初始化"> 38 <setting-item name="更新间隔,为 0 只会初始化">
36 <n-input-group> 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 </n-input-number> 47 </n-input-number>
40 <!-- 单位 --> 48 <!-- 单位 -->
41 <n-select class="select-time-options" v-model:value="requestIntervalUnit" :options="selectTimeOptions" /> 49 <n-select class="select-time-options" v-model:value="requestIntervalUnit" :options="selectTimeOptions" />
@@ -150,11 +158,9 @@ const apiList = [ @@ -150,11 +158,9 @@ const apiList = [
150 .select-time-number { 158 .select-time-number {
151 width: 100%; 159 width: 100%;
152 } 160 }
153 -  
154 .select-time-options { 161 .select-time-options {
155 width: 100px; 162 width: 100px;
156 } 163 }
157 -  
158 .select-type-options { 164 .select-type-options {
159 width: 120px; 165 width: 120px;
160 } 166 }
@@ -58,7 +58,7 @@ @@ -58,7 +58,7 @@
58 <help-outline-icon></help-outline-icon> 58 <help-outline-icon></help-outline-icon>
59 </n-icon> 59 </n-icon>
60 </template> 60 </template>
61 - <n-text>不支持「静态组件」</n-text> 61 + <n-text>不支持「静态组件」支持「组件」「公共APi」</n-text>
62 </n-tooltip> 62 </n-tooltip>
63 </template> 63 </template>
64 <n-select 64 <n-select
@@ -89,7 +89,7 @@ @@ -89,7 +89,7 @@
89 </n-table> 89 </n-table>
90 </setting-item-box> 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 <setting-item-box 94 <setting-item-box
95 :name="requestParamsItem" 95 :name="requestParamsItem"
@@ -125,7 +125,7 @@ import { VNodeChild, computed } from 'vue' @@ -125,7 +125,7 @@ import { VNodeChild, computed } from 'vue'
125 import { SelectOption, SelectGroupOption } from 'naive-ui' 125 import { SelectOption, SelectGroupOption } from 'naive-ui'
126 import { SettingItemBox, SettingItem, CollapseItem } from '@/components/Pages/ChartItemSetting' 126 import { SettingItemBox, SettingItem, CollapseItem } from '@/components/Pages/ChartItemSetting'
127 import { CreateComponentType, CreateComponentGroupType, ChartFrameEnum } from '@/packages/index.d' 127 import { CreateComponentType, CreateComponentGroupType, ChartFrameEnum } from '@/packages/index.d'
128 -import { RequestParamsTypeEnum } from '@/enums/httpEnum' 128 +import { RequestParamsTypeEnum, RequestDataTypeEnum } from '@/enums/httpEnum'
129 import { InteractEventOn, COMPONENT_INTERACT_EVENT_KET } from '@/enums/eventEnum' 129 import { InteractEventOn, COMPONENT_INTERACT_EVENT_KET } from '@/enums/eventEnum'
130 import { icon } from '@/plugins' 130 import { icon } from '@/plugins'
131 import noData from '@/assets/images/canvas/noData.png' 131 import noData from '@/assets/images/canvas/noData.png'
@@ -154,6 +154,11 @@ const option = computed(() => { @@ -154,6 +154,11 @@ const option = computed(() => {
154 // 绑定组件数据 request 154 // 绑定组件数据 request
155 const fnGetRequest = (id: string | undefined, key: RequestParamsTypeEnum) => { 155 const fnGetRequest = (id: string | undefined, key: RequestParamsTypeEnum) => {
156 if (!id) return {} 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 return chartEditStore.componentList[chartEditStore.fetchTargetIndex(id)]?.request.requestParams[key] 162 return chartEditStore.componentList[chartEditStore.fetchTargetIndex(id)]?.request.requestParams[key]
158 } 163 }
159 164
@@ -178,12 +183,10 @@ const fnEventsOptions = (): Array<SelectOption | SelectGroupOption> => { @@ -178,12 +183,10 @@ const fnEventsOptions = (): Array<SelectOption | SelectGroupOption> => {
178 iter: Array<CreateComponentType | CreateComponentGroupType>, 183 iter: Array<CreateComponentType | CreateComponentGroupType>,
179 val: CreateComponentType | CreateComponentGroupType 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 iter.push(val) 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,9 +206,17 @@ const fnEventsOptions = (): Array<SelectOption | SelectGroupOption> => {
203 const mapOptionList = filterOptionList.map(item => ({ 206 const mapOptionList = filterOptionList.map(item => ({
204 id: item.id, 207 id: item.id,
205 title: item.chartConfig.title, 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 targetData.value.events.interactEvents?.forEach(iaItem => { 220 targetData.value.events.interactEvents?.forEach(iaItem => {
210 mapOptionList.forEach(optionItem => { 221 mapOptionList.forEach(optionItem => {
211 if (optionItem.id === iaItem.interactComponentId) { 222 if (optionItem.id === iaItem.interactComponentId) {
@@ -214,7 +225,7 @@ const fnEventsOptions = (): Array<SelectOption | SelectGroupOption> => { @@ -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,9 +159,11 @@ const dragCanvas = (e: any) => {
159 const canvasBox = () => { 159 const canvasBox = () => {
160 const layoutDom = document.getElementById('go-chart-edit-layout') 160 const layoutDom = document.getElementById('go-chart-edit-layout')
161 if (layoutDom) { 161 if (layoutDom) {
  162 + // 此处减去滚动条的宽度和高度
  163 + const scrollW = 20
162 return { 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 return { 169 return {
@@ -66,7 +66,7 @@ const useSyncUpdateHandle = () => { @@ -66,7 +66,7 @@ const useSyncUpdateHandle = () => {
66 // 关闭侦听 66 // 关闭侦听
67 const unUse = () => { 67 const unUse = () => {
68 // clearInterval(timer) 68 // clearInterval(timer)
69 - // removeEventListener('blur', syncData) 69 + removeEventListener('blur', syncDataToPreview)
70 removeEventListener(SavePageEnum.JSON, updateFn) 70 removeEventListener(SavePageEnum.JSON, updateFn)
71 } 71 }
72 72
@@ -33,8 +33,7 @@ export const dragHandle = async (e: DragEvent) => { @@ -33,8 +33,7 @@ export const dragHandle = async (e: DragEvent) => {
33 if (dropData.disabled) return 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 if (dropData.redirectComponent) { 37 if (dropData.redirectComponent) {
39 dropData.dataset && (newComponent.option.dataset = dropData.dataset) 38 dropData.dataset && (newComponent.option.dataset = dropData.dataset)
40 newComponent.chartConfig.title = dropData.title 39 newComponent.chartConfig.title = dropData.title
@@ -6,7 +6,7 @@ const chartEditStore = useChartEditStore() @@ -6,7 +6,7 @@ const chartEditStore = useChartEditStore()
6 6
7 // 布局处理 7 // 布局处理
8 export const useLayout = (fn: () => Promise<void>) => { 8 export const useLayout = (fn: () => Promise<void>) => {
9 - const removeScale: Function = () => { } 9 + let removeScale: Function = () => { }
10 onMounted(async () => { 10 onMounted(async () => {
11 // 设置 Dom 值(ref 不生效先用 document) 11 // 设置 Dom 值(ref 不生效先用 document)
12 chartEditStore.setEditCanvas( 12 chartEditStore.setEditCanvas(
@@ -21,7 +21,7 @@ export const useLayout = (fn: () => Promise<void>) => { @@ -21,7 +21,7 @@ export const useLayout = (fn: () => Promise<void>) => {
21 // 获取数据 21 // 获取数据
22 await fn() 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,7 +74,7 @@ const themeColor = computed(() => {
74 // 组件渲染结束初始化数据池 74 // 组件渲染结束初始化数据池
75 clearMittDataPondMap() 75 clearMittDataPondMap()
76 onMounted(() => { 76 onMounted(() => {
77 - initDataPond(chartEditStore.requestGlobalConfig) 77 + initDataPond(useChartEditStore)
78 }) 78 })
79 </script> 79 </script>
80 80
@@ -12,7 +12,42 @@ export const useScale = (localStorageInfo: ChartEditStorageType) => { @@ -12,7 +12,42 @@ export const useScale = (localStorageInfo: ChartEditStorageType) => {
12 const height = ref(localStorageInfo.editCanvasConfig.height) 12 const height = ref(localStorageInfo.editCanvasConfig.height)
13 const scaleRef = ref({ width: 1, height: 1 }) 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 const updateScaleRef = (scale: { width: number; height: number }) => { 52 const updateScaleRef = (scale: { width: number; height: number }) => {
18 // 这里需要解构,保证赋值给scaleRef的为一个新对象 53 // 这里需要解构,保证赋值给scaleRef的为一个新对象
@@ -23,74 +58,82 @@ export const useScale = (localStorageInfo: ChartEditStorageType) => { @@ -23,74 +58,82 @@ export const useScale = (localStorageInfo: ChartEditStorageType) => {
23 // 屏幕适配 58 // 屏幕适配
24 onMounted(() => { 59 onMounted(() => {
25 switch (localStorageInfo.editCanvasConfig.previewScaleType) { 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 <template> 1 <template>
2 - <div :class="`go-preview ${chartEditStore.editCanvasConfig.previewScaleType}`"> 2 + <div :class="`go-preview ${chartEditStore.editCanvasConfig.previewScaleType}`" @mousedown="dragCanvas">
3 <template v-if="showEntity"> 3 <template v-if="showEntity">
4 <!-- 实体区域 --> 4 <!-- 实体区域 -->
5 <div ref="entityRef" class="go-preview-entity"> 5 <div ref="entityRef" class="go-preview-entity">
@@ -32,7 +32,7 @@ import { PreviewRenderList } from './components/PreviewRenderList' @@ -32,7 +32,7 @@ import { PreviewRenderList } from './components/PreviewRenderList'
32 import { getFilterStyle, setTitle } from '@/utils' 32 import { getFilterStyle, setTitle } from '@/utils'
33 33
34 // THINGS_KIT 重写预览逻辑,调用接口 34 // THINGS_KIT 重写预览逻辑,调用接口
35 -// import { getEditCanvasConfigStyle, getSessionStorageInfo } from './utils' 35 +// import { getEditCanvasConfigStyle, getSessionStorageInfo, keyRecordHandle, dragCanvas } from './utils'
36 import { getEditCanvasConfigStyle } from './utils' 36 import { getEditCanvasConfigStyle } from './utils'
37 import { getSessionStorageInfo } from './external/usePreview' 37 import { getSessionStorageInfo } from './external/usePreview'
38 38
@@ -65,6 +65,9 @@ const showEntity = computed(() => { @@ -65,6 +65,9 @@ const showEntity = computed(() => {
65 useStore(chartEditStore) 65 useStore(chartEditStore)
66 const { entityRef, previewRef } = useScale(chartEditStore) 66 const { entityRef, previewRef } = useScale(chartEditStore)
67 const { show } = useComInstall(chartEditStore) 67 const { show } = useComInstall(chartEditStore)
  68 +
  69 +// 开启键盘监听
  70 +keyRecordHandle()
68 </script> 71 </script>
69 72
70 <style lang="scss" scoped> 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 export * from './style' 1 export * from './style'
2 -export * from './storage'  
  2 +export * from './storage'
  3 +export * from './keyboard'
  4 +export * from './drag'
  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,4 +5,5 @@ declare module '*.vue' {
5 } 5 }
6 6
7 declare module 'lodash/*' 7 declare module 'lodash/*'
8 -declare module 'dom-helpers'  
  8 +declare module 'dom-helpers'
  9 +declare module '@iconify/vue'