Showing
13 changed files
with
165 additions
and
346 deletions
1 | -<script lang="ts" setup> | 1 | +<script lang="ts" setup name="SelectCity"> |
2 | import { onMounted, reactive } from 'vue' | 2 | import { onMounted, reactive } from 'vue' |
3 | import { getAreaList } from '@/api/external/common/index' | 3 | import { getAreaList } from '@/api/external/common/index' |
4 | import { areaEnum } from '../config' | 4 | import { areaEnum } from '../config' |
1 | -<script lang="ts" setup> | 1 | +<script lang="ts" setup name="WeatherContent"> |
2 | import { toRefs } from 'vue' | 2 | import { toRefs } from 'vue' |
3 | import SelectCity from './SelectCity.vue' | 3 | import SelectCity from './SelectCity.vue' |
4 | -import { weatherTextMapImg } from '../config' | 4 | +import { useUtils } from '../hooks/useUtils' |
5 | 5 | ||
6 | const props = defineProps({ | 6 | const props = defineProps({ |
7 | data: { | 7 | data: { |
@@ -11,19 +11,13 @@ const props = defineProps({ | @@ -11,19 +11,13 @@ const props = defineProps({ | ||
11 | 11 | ||
12 | const emits = defineEmits(['submit']) | 12 | const emits = defineEmits(['submit']) |
13 | 13 | ||
14 | +const { loadWeatherImg, loadWeatherLevel } = useUtils() | ||
15 | + | ||
14 | const { casts } = toRefs(props.data[0]) | 16 | const { casts } = toRefs(props.data[0]) |
15 | 17 | ||
16 | const onHandleSelectValues = (values: any) => { | 18 | const onHandleSelectValues = (values: any) => { |
17 | emits('submit', values) | 19 | emits('submit', values) |
18 | } | 20 | } |
19 | - | ||
20 | -//根据返回的文字加载不同天气图片 | ||
21 | -const loadWeatherImg = (text: string) => { | ||
22 | - return ( | ||
23 | - weatherTextMapImg.find((item: any) => item.text === text)?.img || | ||
24 | - '/large-designer/src/assets/external/weather/clearDay.png' | ||
25 | - ) | ||
26 | -} | ||
27 | </script> | 21 | </script> |
28 | 22 | ||
29 | <template> | 23 | <template> |
@@ -59,16 +53,18 @@ const loadWeatherImg = (text: string) => { | @@ -59,16 +53,18 @@ const loadWeatherImg = (text: string) => { | ||
59 | <div class="content-weather-air"> | 53 | <div class="content-weather-air"> |
60 | <div>{{ casts[0]?.dayweather }}</div> | 54 | <div>{{ casts[0]?.dayweather }}</div> |
61 | <div>{{ casts[0]?.daywind }}</div> | 55 | <div>{{ casts[0]?.daywind }}</div> |
56 | + <div>{{ loadWeatherLevel(casts[0]?.daypower) }}</div> | ||
62 | </div> | 57 | </div> |
63 | </div> | 58 | </div> |
64 | <template #footer> | 59 | <template #footer> |
65 | - <div v-for="(item, index) in casts?.slice(0, 3)" :key="index" class="footer-content"> | ||
66 | - <div>{{ index === 0 ? '今天' : index === 1 ? '明天' : '后天' }}</div> | 60 | + <div v-for="(item, index) in casts" :key="index" class="footer-content"> |
61 | + <div>{{ index === 0 ? '今天' : index === 1 ? '明天' : index === 2 ? '后天' : '外天' }}</div> | ||
67 | <div> | 62 | <div> |
68 | <img :src="loadWeatherImg(item?.dayweather)" /> | 63 | <img :src="loadWeatherImg(item?.dayweather)" /> |
69 | </div> | 64 | </div> |
70 | <div>{{ item?.daytemp }}/{{ item?.nighttemp }}</div> | 65 | <div>{{ item?.daytemp }}/{{ item?.nighttemp }}</div> |
71 | <div>{{ item?.daywind }}</div> | 66 | <div>{{ item?.daywind }}</div> |
67 | + <div>{{ loadWeatherLevel(item?.daypower) }}</div> | ||
72 | </div> | 68 | </div> |
73 | </template> | 69 | </template> |
74 | </n-card> | 70 | </n-card> |
@@ -92,7 +88,6 @@ const loadWeatherImg = (text: string) => { | @@ -92,7 +88,6 @@ const loadWeatherImg = (text: string) => { | ||
92 | } | 88 | } |
93 | } | 89 | } |
94 | .card-content { | 90 | .card-content { |
95 | - width: 100%; | ||
96 | @extend %flex-style; | 91 | @extend %flex-style; |
97 | .content-weather { | 92 | .content-weather { |
98 | @extend %flex-style; | 93 | @extend %flex-style; |
@@ -108,12 +103,12 @@ const loadWeatherImg = (text: string) => { | @@ -108,12 +103,12 @@ const loadWeatherImg = (text: string) => { | ||
108 | } | 103 | } |
109 | } | 104 | } |
110 | .footer-content { | 105 | .footer-content { |
111 | - width: 100%; | ||
112 | @extend %flex-style; | 106 | @extend %flex-style; |
113 | - gap: 30px; | ||
114 | - margin-left: 5px; | 107 | + gap: 10px; |
108 | + margin-left: 10px; | ||
115 | div { | 109 | div { |
116 | flex: 1; | 110 | flex: 1; |
111 | + text-align: left; | ||
117 | img { | 112 | img { |
118 | width: 24px; | 113 | width: 24px; |
119 | height: 24px; | 114 | height: 24px; |
@@ -4,9 +4,13 @@ import { WeatherConfig } from './index' | @@ -4,9 +4,13 @@ import { WeatherConfig } from './index' | ||
4 | import cloneDeep from 'lodash/cloneDeep' | 4 | import cloneDeep from 'lodash/cloneDeep' |
5 | import { chartInitConfig } from '@/settings/designSetting' | 5 | import { chartInitConfig } from '@/settings/designSetting' |
6 | 6 | ||
7 | -//第三方 高德天气接口key值和api配置 | ||
8 | -export const thirdPartyWeatherKey = `0551a87b45e0363ae6c7a2242e8ac944` | ||
9 | -export const thirdPartyWeatherApi = `https://restapi.amap.com/v3/weather/weatherInfo` | 7 | +//第三方 天气接口key值和api配置(高德) |
8 | +export class ThirdPartyWeather { | ||
9 | + static ak = '0551a87b45e0363ae6c7a2242e8ac944' | ||
10 | + static api = 'https://restapi.amap.com/v3/weather/weatherInfo' | ||
11 | + // ((all,预报天气),(base,实况天气)) | ||
12 | + static extensions = 'all' | ||
13 | +} | ||
10 | 14 | ||
11 | //省市区枚举 | 15 | //省市区枚举 |
12 | export const enum areaEnum { | 16 | export const enum areaEnum { |
@@ -35,6 +39,62 @@ export const weatherTextMapImg = [ | @@ -35,6 +39,62 @@ export const weatherTextMapImg = [ | ||
35 | } | 39 | } |
36 | ] | 40 | ] |
37 | 41 | ||
42 | +//风力等级文字映射 | ||
43 | +export const weatherSpeedMapText = [ | ||
44 | + { | ||
45 | + level: (value: number) => value >= 0.0 && value <= 0.2, | ||
46 | + text: '无风' | ||
47 | + }, | ||
48 | + { | ||
49 | + level: (value: number) => value >= 0.3 && value <= 1.5, | ||
50 | + text: '软风' | ||
51 | + }, | ||
52 | + { | ||
53 | + level: (value: number) => value >= 1.6 && value <= 3.3, | ||
54 | + text: '轻风' | ||
55 | + }, | ||
56 | + { | ||
57 | + level: (value: number) => value >= 3.4 && value <= 5.4, | ||
58 | + text: '微风' | ||
59 | + }, | ||
60 | + { | ||
61 | + level: (value: number) => value >= 5.5 && value <= 7.9, | ||
62 | + text: '和风' | ||
63 | + }, | ||
64 | + { | ||
65 | + level: (value: number) => value >= 8.0 && value <= 10.7, | ||
66 | + text: '劲风' | ||
67 | + }, | ||
68 | + { | ||
69 | + level: (value: number) => value >= 10.8 && value <= 13.8, | ||
70 | + text: '强风' | ||
71 | + }, | ||
72 | + { | ||
73 | + level: (value: number) => value >= 13.9 || value <= 17.1, | ||
74 | + text: '疾风' | ||
75 | + }, | ||
76 | + { | ||
77 | + level: (value: number) => value >= 17.2 && value <= 20.7, | ||
78 | + text: '大风' | ||
79 | + }, | ||
80 | + { | ||
81 | + level: (value: number) => value >= 20.8 && value <= 24.4, | ||
82 | + text: '烈风' | ||
83 | + }, | ||
84 | + { | ||
85 | + level: (value: number) => value >= 24.5 && value <= 28.4, | ||
86 | + text: '狂风' | ||
87 | + }, | ||
88 | + { | ||
89 | + level: (value: number) => value >= 28.5 && value <= 32.6, | ||
90 | + text: '暴风' | ||
91 | + }, | ||
92 | + { | ||
93 | + level: (value: number) => value >= 32.7 && value <= 36.9, | ||
94 | + text: '飓风' | ||
95 | + } | ||
96 | +] | ||
97 | + | ||
38 | export const option = { | 98 | export const option = { |
39 | dataset: { | 99 | dataset: { |
40 | provinceValue: null, | 100 | provinceValue: null, |
@@ -50,6 +110,8 @@ export const option = { | @@ -50,6 +110,8 @@ export const option = { | ||
50 | weatherIconSizeHeight: '24', | 110 | weatherIconSizeHeight: '24', |
51 | airSpeedTextSize: '16', | 111 | airSpeedTextSize: '16', |
52 | airSpeedTextColor: '#000000', | 112 | airSpeedTextColor: '#000000', |
113 | + airSpeedLevelTextSize: '16', | ||
114 | + airSpeedLevelTextColor: '#000000', | ||
53 | backgroundColor: 'transparent', | 115 | backgroundColor: 'transparent', |
54 | borderRadius: '5' | 116 | borderRadius: '5' |
55 | } | 117 | } |
@@ -57,7 +119,7 @@ export const option = { | @@ -57,7 +119,7 @@ export const option = { | ||
57 | 119 | ||
58 | export default class Config extends PublicConfigClass implements CreateComponentType { | 120 | export default class Config extends PublicConfigClass implements CreateComponentType { |
59 | public key = WeatherConfig.key | 121 | public key = WeatherConfig.key |
60 | - public attr = { ...chartInitConfig, zIndex: 1, w: 181, h: 44 } | 122 | + public attr = { ...chartInitConfig, zIndex: 1, w: 300, h: 60 } |
61 | public chartConfig = cloneDeep(WeatherConfig) | 123 | public chartConfig = cloneDeep(WeatherConfig) |
62 | public option = cloneDeep(option) | 124 | public option = cloneDeep(option) |
63 | } | 125 | } |
1 | <template> | 1 | <template> |
2 | <CollapseItem name="天气配置" :expanded="true"> | 2 | <CollapseItem name="天气配置" :expanded="true"> |
3 | - <SettingItemBox name="区域选择"> | ||
4 | - <SelectCity @submit="onHandleSelectValues" /> | ||
5 | - </SettingItemBox> | 3 | + <SettingItemBox name="区域选择"> </SettingItemBox> |
4 | + <SelectCity @submit="onHandleSelectValues" /> | ||
6 | <SettingItemBox name="背景"> | 5 | <SettingItemBox name="背景"> |
7 | <SettingItem name="颜色"> | 6 | <SettingItem name="颜色"> |
8 | <n-color-picker v-model:value="optionData.weatherCss.backgroundColor" /> | 7 | <n-color-picker v-model:value="optionData.weatherCss.backgroundColor" /> |
@@ -55,6 +54,19 @@ | @@ -55,6 +54,19 @@ | ||
55 | <n-button size="small" @click="optionData.weatherCss.airSpeedTextColor = '#000000'"> 恢复默认颜色 </n-button> | 54 | <n-button size="small" @click="optionData.weatherCss.airSpeedTextColor = '#000000'"> 恢复默认颜色 </n-button> |
56 | </SettingItem> | 55 | </SettingItem> |
57 | </SettingItemBox> | 56 | </SettingItemBox> |
57 | + <SettingItemBox name="风速等级"> | ||
58 | + <SettingItem name="大小"> | ||
59 | + <n-input v-model:value="optionData.weatherCss.airSpeedLevelTextSize" /> | ||
60 | + </SettingItem> | ||
61 | + <SettingItem name="颜色"> | ||
62 | + <n-color-picker v-model:value="optionData.weatherCss.airSpeedLevelTextColor" /> | ||
63 | + </SettingItem> | ||
64 | + <SettingItem> | ||
65 | + <n-button size="small" @click="optionData.weatherCss.airSpeedLevelTextColor = '#000000'"> | ||
66 | + 恢复默认颜色 | ||
67 | + </n-button> | ||
68 | + </SettingItem> | ||
69 | + </SettingItemBox> | ||
58 | </CollapseItem> | 70 | </CollapseItem> |
59 | </template> | 71 | </template> |
60 | 72 |
1 | +import { weatherSpeedMapText, weatherTextMapImg } from '../config' | ||
2 | + | ||
3 | +export const useUtils = () => { | ||
4 | + const loadWeatherImg = (text: string) => { | ||
5 | + return ( | ||
6 | + weatherTextMapImg.find((item: any) => item.text === text)?.img || | ||
7 | + '/large-designer/src/assets/external/weather/clearDay.png' | ||
8 | + ) | ||
9 | + } | ||
10 | + | ||
11 | + //风力等级 ≤3 3 | ||
12 | + const loadWeatherLevel = (speed: string) => { | ||
13 | + let handleSpeed = '' | ||
14 | + if (speed?.startsWith('≤')) { | ||
15 | + handleSpeed = speed.slice(1) | ||
16 | + } else { | ||
17 | + handleSpeed = speed | ||
18 | + } | ||
19 | + return weatherSpeedMapText.find((item: any) => item.level(Number(handleSpeed)))?.text | ||
20 | + } | ||
21 | + return { | ||
22 | + loadWeatherImg, | ||
23 | + loadWeatherLevel | ||
24 | + } | ||
25 | +} |
1 | -<script lang="ts" setup> | 1 | +<script lang="ts" setup name="Weather"> |
2 | import { PropType, toRefs, onMounted, reactive, watch } from 'vue' | 2 | import { PropType, toRefs, onMounted, reactive, watch } from 'vue' |
3 | import { CreateComponentType } from '@/packages/index.d' | 3 | import { CreateComponentType } from '@/packages/index.d' |
4 | -import { option, thirdPartyWeatherKey, thirdPartyWeatherApi, weatherTextMapImg } from './config' | 4 | +import { option, ThirdPartyWeather } from './config' |
5 | import axios from 'axios' | 5 | import axios from 'axios' |
6 | import WeatherContent from './componnets/WeatherContent.vue' | 6 | import WeatherContent from './componnets/WeatherContent.vue' |
7 | +import { useUtils } from './hooks/useUtils' | ||
7 | 8 | ||
8 | const props = defineProps({ | 9 | const props = defineProps({ |
9 | chartConfig: { | 10 | chartConfig: { |
@@ -12,6 +13,8 @@ const props = defineProps({ | @@ -12,6 +13,8 @@ const props = defineProps({ | ||
12 | } | 13 | } |
13 | }) | 14 | }) |
14 | 15 | ||
16 | +const { loadWeatherImg, loadWeatherLevel } = useUtils() | ||
17 | + | ||
15 | const { w, h } = toRefs(props.chartConfig.attr) | 18 | const { w, h } = toRefs(props.chartConfig.attr) |
16 | 19 | ||
17 | const { | 20 | const { |
@@ -23,6 +26,8 @@ const { | @@ -23,6 +26,8 @@ const { | ||
23 | weatherIconSizeHeight, | 26 | weatherIconSizeHeight, |
24 | airSpeedTextSize, | 27 | airSpeedTextSize, |
25 | airSpeedTextColor, | 28 | airSpeedTextColor, |
29 | + airSpeedLevelTextSize, | ||
30 | + airSpeedLevelTextColor, | ||
26 | backgroundColor, | 31 | backgroundColor, |
27 | borderRadius | 32 | borderRadius |
28 | } = toRefs(props.chartConfig.option.weatherCss) | 33 | } = toRefs(props.chartConfig.option.weatherCss) |
@@ -31,17 +36,16 @@ const weatherInfoValues: any = reactive({ | @@ -31,17 +36,16 @@ const weatherInfoValues: any = reactive({ | ||
31 | weatherInfo: [] | 36 | weatherInfo: [] |
32 | }) | 37 | }) |
33 | 38 | ||
34 | -//获取第三方服务(高德天气) | ||
35 | -const getWeatherInfos = async (cityObj: any, extensions = 'all') => { | 39 | +const getWeatherInfos = async (cityObj: any) => { |
36 | const { cityValue, countyValue } = cityObj || props.chartConfig.option.dataset | 40 | const { cityValue, countyValue } = cityObj || props.chartConfig.option.dataset |
37 | const params = { | 41 | const params = { |
38 | - key: thirdPartyWeatherKey, | 42 | + key: ThirdPartyWeather.ak, |
39 | city: !countyValue ? cityValue : countyValue, | 43 | city: !countyValue ? cityValue : countyValue, |
40 | - extensions | 44 | + extensions: ThirdPartyWeather.extensions |
41 | } as any | 45 | } as any |
42 | const { | 46 | const { |
43 | data: { forecasts } | 47 | data: { forecasts } |
44 | - } = await axios.get(thirdPartyWeatherApi, { params }) | 48 | + } = await axios.get(ThirdPartyWeather.api, { params }) |
45 | if (!forecasts) return | 49 | if (!forecasts) return |
46 | weatherInfoValues.weatherInfo = forecasts | 50 | weatherInfoValues.weatherInfo = forecasts |
47 | } | 51 | } |
@@ -64,45 +68,23 @@ watch( | @@ -64,45 +68,23 @@ watch( | ||
64 | const onHandleSelectValues = (values: any) => { | 68 | const onHandleSelectValues = (values: any) => { |
65 | getWeatherInfos(values) | 69 | getWeatherInfos(values) |
66 | } | 70 | } |
67 | - | ||
68 | -//根据返回的文字加载不同天气图片 | ||
69 | -const loadWeatherImg = (text: string) => { | ||
70 | - return ( | ||
71 | - weatherTextMapImg.find((item: any) => item.text === text)?.img || | ||
72 | - '/large-designer/src/assets/external/weather/clearDay.png' | ||
73 | - ) | ||
74 | -} | ||
75 | </script> | 71 | </script> |
76 | 72 | ||
77 | <template> | 73 | <template> |
78 | <div> | 74 | <div> |
79 | <n-popover placement="bottom" trigger="hover" raw :show-arrow="false"> | 75 | <n-popover placement="bottom" trigger="hover" raw :show-arrow="false"> |
80 | <template #trigger> | 76 | <template #trigger> |
81 | - <n-card | ||
82 | - class="card" | ||
83 | - :bordered="false" | ||
84 | - :style="`background-color:${backgroundColor};border-radius:${borderRadius}px;`" | ||
85 | - > | 77 | + <n-card class="card" :bordered="false"> |
86 | <div class="card-content" v-for="(item, index) in weatherInfoValues.weatherInfo" :key="index"> | 78 | <div class="card-content" v-for="(item, index) in weatherInfoValues.weatherInfo" :key="index"> |
87 | - <div :style="`font-size:${temperatureTextSize}px;color:${temperatureTextColor};`"> | ||
88 | - {{ item?.casts[0]?.daytemp }}°C | ||
89 | - </div> | ||
90 | - <div class="card-content-city-text" :style="`font-size:${cityTextSize}px;color:${cityTextColor};`"> | ||
91 | - {{ item?.city }} | ||
92 | - </div> | ||
93 | - <div> | ||
94 | - <img | ||
95 | - :style="`width:${weatherIconSizeWidth}px;height:${weatherIconSizeHeight}px;`" | ||
96 | - :src="loadWeatherImg(item?.casts[0]?.dayweather)" | ||
97 | - /> | ||
98 | - </div> | ||
99 | - <div :style="`font-size:${airSpeedTextSize}px;color:${airSpeedTextColor};`"> | ||
100 | - {{ item?.casts[0]?.daywind }} | ||
101 | - </div> | 79 | + <div class="weather-temp">{{ item?.casts[0]?.daytemp }}°C</div> |
80 | + <div class="weather-city">{{ item?.city }}</div> | ||
81 | + <div><img class="weather-img" :src="loadWeatherImg(item?.casts[0]?.dayweather)" /></div> | ||
82 | + <div class="weather-speed">{{ item?.casts[0]?.daywind }}</div> | ||
83 | + <div class="weather-speed-level">{{ loadWeatherLevel(item?.casts[0]?.daypower) }}</div> | ||
102 | </div> | 84 | </div> |
103 | </n-card> | 85 | </n-card> |
104 | </template> | 86 | </template> |
105 | - <div :style="`width:${300}px;height:${300}px;`"> | 87 | + <div class="popup-content"> |
106 | <WeatherContent :data="weatherInfoValues.weatherInfo" @submit="onHandleSelectValues" /> | 88 | <WeatherContent :data="weatherInfoValues.weatherInfo" @submit="onHandleSelectValues" /> |
107 | </div> | 89 | </div> |
108 | </n-popover> | 90 | </n-popover> |
@@ -110,22 +92,45 @@ const loadWeatherImg = (text: string) => { | @@ -110,22 +92,45 @@ const loadWeatherImg = (text: string) => { | ||
110 | </template> | 92 | </template> |
111 | 93 | ||
112 | <style lang="scss" scoped> | 94 | <style lang="scss" scoped> |
95 | +.popup-content { | ||
96 | + width: 300px; | ||
97 | + height: 300px; | ||
98 | +} | ||
113 | .card { | 99 | .card { |
114 | width: v-bind('w+"px"'); | 100 | width: v-bind('w+"px"'); |
115 | height: v-bind('h+"px"'); | 101 | height: v-bind('h+"px"'); |
102 | + background-color: v-bind('backgroundColor'); | ||
103 | + border-radius: v-bind('`${borderRadius}px`'); | ||
116 | .card-content { | 104 | .card-content { |
117 | - width: 100%; | ||
118 | display: flex; | 105 | display: flex; |
119 | justify-content: space-between; | 106 | justify-content: space-between; |
120 | - img { | ||
121 | - width: 24px; | ||
122 | - height: 24px; | 107 | + .weather-temp { |
108 | + font-size: v-bind('`${temperatureTextSize}px`'); | ||
109 | + color: v-bind('temperatureTextColor'); | ||
123 | } | 110 | } |
124 | - .card-content-city-text { | 111 | + .weather-city { |
125 | text-overflow: ellipsis; | 112 | text-overflow: ellipsis; |
126 | overflow: hidden; | 113 | overflow: hidden; |
127 | word-break: break-all; | 114 | word-break: break-all; |
128 | white-space: nowrap; | 115 | white-space: nowrap; |
116 | + font-size: v-bind('`${cityTextSize}px`'); | ||
117 | + color: v-bind('cityTextColor'); | ||
118 | + } | ||
119 | + .weather-img { | ||
120 | + width: v-bind('`${weatherIconSizeWidth}px`'); | ||
121 | + height: v-bind('`${weatherIconSizeHeight}px`'); | ||
122 | + } | ||
123 | + .weather-speed { | ||
124 | + font-size: v-bind('`${airSpeedTextSize}px`'); | ||
125 | + color: v-bind('airSpeedTextColor'); | ||
126 | + } | ||
127 | + .weather-speed-level { | ||
128 | + font-size: v-bind('`${airSpeedLevelTextSize}px`'); | ||
129 | + color: v-bind('airSpeedLevelTextColor'); | ||
130 | + } | ||
131 | + img { | ||
132 | + width: 24px; | ||
133 | + height: 24px; | ||
129 | } | 134 | } |
130 | } | 135 | } |
131 | } | 136 | } |
1 | -import cloneDeep from 'lodash/cloneDeep' | ||
2 | -import { PublicConfigClass } from '@/packages/public' | ||
3 | -import { CreateComponentType } from '@/packages/index.d' | ||
4 | -import { chartInitConfig } from '@/settings/designSetting' | ||
5 | -import { COMPONENT_INTERACT_EVENT_KET } from '@/enums/eventEnum' | ||
6 | -import { interactActions, ComponentInteractEventEnum } from './interact' | ||
7 | -import { OverrideInputsTabConfig } from './index' | ||
8 | - | ||
9 | -export const option = { | ||
10 | - // 时间组件展示类型,必须和 interactActions 中定义的数据一致 | ||
11 | - [COMPONENT_INTERACT_EVENT_KET]: ComponentInteractEventEnum.DATA, | ||
12 | - // 默认值 | ||
13 | - tabLabel: '选项1', | ||
14 | - // 样式 | ||
15 | - tabType: 'segment', | ||
16 | - // 暴露配置内容给用户 | ||
17 | - dataset: [ | ||
18 | - { | ||
19 | - label: '选项1', | ||
20 | - value: '1' | ||
21 | - }, | ||
22 | - { | ||
23 | - label: '选项2', | ||
24 | - value: '2' | ||
25 | - }, | ||
26 | - { | ||
27 | - label: '选项3', | ||
28 | - value: '3' | ||
29 | - } | ||
30 | - ], | ||
31 | - customTabCss: { | ||
32 | - labelTextSize: '16', | ||
33 | - labelDefaultColor: 'black', | ||
34 | - labelActiveColor: 'green', | ||
35 | - tabBottomBarColor: 'green', | ||
36 | - segmentationBgColor: 'white', | ||
37 | - segmentationActiveBgColor: '#C0C0C0' | ||
38 | - } | ||
39 | -} | ||
40 | - | ||
41 | -export default class Config extends PublicConfigClass implements CreateComponentType { | ||
42 | - public key = OverrideInputsTabConfig.key | ||
43 | - public attr = { ...chartInitConfig, w: 460, h: 32, zIndex: -1 } | ||
44 | - public chartConfig = cloneDeep(OverrideInputsTabConfig) | ||
45 | - public interactActions = interactActions | ||
46 | - public option = cloneDeep(option) | ||
47 | -} |
1 | -<template> | ||
2 | - <collapse-item name="标签页配置" :expanded="true"> | ||
3 | - <setting-item-box name="默认值" :alone="true"> | ||
4 | - <n-select size="small" v-model:value="optionData.tabType" :options="tabTypeOptions" @change="onHandleSelect" /> | ||
5 | - </setting-item-box> | ||
6 | - <setting-item-box name="默认文字" :alone="true"> | ||
7 | - <SettingItem name="大小"> | ||
8 | - <n-input v-model:value="optionData.customTabCss.labelTextSize" /> | ||
9 | - </SettingItem> | ||
10 | - <SettingItem name="颜色"> | ||
11 | - <n-color-picker | ||
12 | - size="small" | ||
13 | - :modes="['hex']" | ||
14 | - v-model:value="optionData.customTabCss.labelDefaultColor" | ||
15 | - ></n-color-picker> | ||
16 | - </SettingItem> | ||
17 | - <SettingItem> | ||
18 | - <n-button size="small" @click="optionData.customTabCss.labelDefaultColor = 'black'"> 恢复默认 </n-button> | ||
19 | - </SettingItem> | ||
20 | - </setting-item-box> | ||
21 | - <setting-item-box name="激活文字" :alone="true"> | ||
22 | - <SettingItem name="颜色"> | ||
23 | - <n-color-picker | ||
24 | - size="small" | ||
25 | - :modes="['hex']" | ||
26 | - v-model:value="optionData.customTabCss.labelActiveColor" | ||
27 | - ></n-color-picker> | ||
28 | - </SettingItem> | ||
29 | - <SettingItem> | ||
30 | - <n-button size="small" @click="optionData.customTabCss.labelActiveColor = 'green'"> 恢复默认 </n-button> | ||
31 | - </SettingItem> | ||
32 | - </setting-item-box> | ||
33 | - <setting-item-box name="底部条颜色" :alone="true"> | ||
34 | - <SettingItem name="颜色"> | ||
35 | - <n-color-picker | ||
36 | - size="small" | ||
37 | - :modes="['hex']" | ||
38 | - v-model:value="optionData.customTabCss.tabBottomBarColor" | ||
39 | - ></n-color-picker> | ||
40 | - </SettingItem> | ||
41 | - <SettingItem> | ||
42 | - <n-button size="small" @click="optionData.customTabCss.tabBottomBarColor = 'green'"> 恢复默认 </n-button> | ||
43 | - </SettingItem> | ||
44 | - </setting-item-box> | ||
45 | - <setting-item-box v-if="optionData.tabType === 'segment'" name="分段背景色" :alone="true"> | ||
46 | - <SettingItem name="颜色"> | ||
47 | - <n-color-picker | ||
48 | - size="small" | ||
49 | - :modes="['hex']" | ||
50 | - v-model:value="optionData.customTabCss.segmentationBgColor" | ||
51 | - ></n-color-picker> | ||
52 | - </SettingItem> | ||
53 | - <SettingItem> | ||
54 | - <n-button size="small" @click="optionData.customTabCss.segmentationBgColor = 'white'"> 恢复默认 </n-button> | ||
55 | - </SettingItem> | ||
56 | - </setting-item-box> | ||
57 | - <setting-item-box v-if="optionData.tabType === 'segment'" name="分段激活色" :alone="true"> | ||
58 | - <SettingItem name="颜色"> | ||
59 | - <n-color-picker | ||
60 | - size="small" | ||
61 | - :modes="['hex']" | ||
62 | - v-model:value="optionData.customTabCss.segmentationActiveBgColor" | ||
63 | - ></n-color-picker> | ||
64 | - </SettingItem> | ||
65 | - <SettingItem> | ||
66 | - <n-button size="small" @click="optionData.customTabCss.segmentationActiveBgColor = '#C0C0C0'"> | ||
67 | - 恢复默认 | ||
68 | - </n-button> | ||
69 | - </SettingItem> | ||
70 | - </setting-item-box> | ||
71 | - </collapse-item> | ||
72 | -</template> | ||
73 | - | ||
74 | -<script lang="ts" setup> | ||
75 | -import { PropType } from 'vue' | ||
76 | -import { CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting' | ||
77 | -import { option } from './config' | ||
78 | - | ||
79 | -const props = defineProps({ | ||
80 | - optionData: { | ||
81 | - type: Object as PropType<typeof option>, | ||
82 | - required: true | ||
83 | - } | ||
84 | -}) | ||
85 | - | ||
86 | -const tabTypeOptions = [ | ||
87 | - { | ||
88 | - label: '线条', | ||
89 | - value: 'bar' | ||
90 | - }, | ||
91 | - { | ||
92 | - label: '分段', | ||
93 | - value: 'segment' | ||
94 | - } | ||
95 | -] | ||
96 | -const onHandleSelect = (value: string) => { | ||
97 | - if (value === 'bar') { | ||
98 | - props.optionData.customTabCss.segmentationBgColor = '' | ||
99 | - props.optionData.customTabCss.segmentationActiveBgColor = '' | ||
100 | - | ||
101 | - } | ||
102 | -} | ||
103 | -</script> |
1 | - | ||
2 | - | ||
3 | -import { ConfigType, PackagesCategoryEnum, ChartFrameEnum } from '@/packages/index.d' | ||
4 | -import { ChatCategoryEnum, ChatCategoryEnumName } from '@/packages/components/Informations/index.d' | ||
5 | -import { useWidgetKey } from '@/packages/external/useWidgetKey' | ||
6 | - | ||
7 | -const { key, conKey, chartKey } = useWidgetKey('OverrideInputsTab', true) | ||
8 | - | ||
9 | -export const OverrideInputsTabConfig: ConfigType = { | ||
10 | - key, | ||
11 | - chartKey, | ||
12 | - conKey, | ||
13 | - title: '自定义标签选择器', | ||
14 | - category: ChatCategoryEnum.MORE, | ||
15 | - categoryName: ChatCategoryEnumName.MORE, | ||
16 | - package: PackagesCategoryEnum.INFORMATIONS, | ||
17 | - chartFrame: ChartFrameEnum.COMMON, | ||
18 | - image: 'inputs_tab.png' | ||
19 | -} |
1 | -<template> | ||
2 | - <n-tabs class="override-n-tabs" :type="option.value.tabType" @update:value="onChange"> | ||
3 | - <n-tab v-for="(item, index) in option.value.dataset" :name="item.label" :key="index"> {{ item.label }} </n-tab> | ||
4 | - </n-tabs> | ||
5 | -</template> | ||
6 | - | ||
7 | -<script setup lang="ts"> | ||
8 | -import { PropType, toRefs, shallowReactive, watch } from 'vue' | ||
9 | -import cloneDeep from 'lodash/cloneDeep' | ||
10 | -import { CreateComponentType } from '@/packages/index.d' | ||
11 | -import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore' | ||
12 | -import { useChartInteract } from '@/hooks' | ||
13 | -import { InteractEventOn } from '@/enums/eventEnum' | ||
14 | -import { ComponentInteractParamsEnum } from './interact' | ||
15 | - | ||
16 | -const props = defineProps({ | ||
17 | - chartConfig: { | ||
18 | - type: Object as PropType<CreateComponentType>, | ||
19 | - required: true | ||
20 | - } | ||
21 | -}) | ||
22 | - | ||
23 | -const { w, h } = toRefs(props.chartConfig.attr) | ||
24 | - | ||
25 | -const { | ||
26 | - labelTextSize, | ||
27 | - labelDefaultColor, | ||
28 | - labelActiveColor, | ||
29 | - tabBottomBarColor, | ||
30 | - segmentationBgColor, | ||
31 | - segmentationActiveBgColor | ||
32 | -} = toRefs(props.chartConfig.option.customTabCss) | ||
33 | - | ||
34 | -const option = shallowReactive({ | ||
35 | - value: cloneDeep(props.chartConfig.option) | ||
36 | -}) | ||
37 | - | ||
38 | -// 监听事件改变 | ||
39 | -const onChange = (v: string) => { | ||
40 | - if (v === undefined) return | ||
41 | - const selectItem = option.value.dataset.find((item: { label: string; value: any }) => item.label === v) | ||
42 | - // 存储到联动数据 | ||
43 | - useChartInteract( | ||
44 | - props.chartConfig, | ||
45 | - useChartEditStore, | ||
46 | - { [ComponentInteractParamsEnum.DATA]: selectItem.value }, | ||
47 | - InteractEventOn.CHANGE | ||
48 | - ) | ||
49 | -} | ||
50 | - | ||
51 | -// 手动更新 | ||
52 | -watch( | ||
53 | - () => props.chartConfig.option, | ||
54 | - (newData: any) => { | ||
55 | - option.value = newData | ||
56 | - onChange(newData.tabValue) | ||
57 | - }, | ||
58 | - { | ||
59 | - immediate: true, | ||
60 | - deep: true | ||
61 | - } | ||
62 | -) | ||
63 | -</script> | ||
64 | - | ||
65 | -<style lang="scss" scoped> | ||
66 | -@include deep() { | ||
67 | - .n-tabs-tab { | ||
68 | - font-size: v-bind('labelTextSize+"px"') !important; | ||
69 | - color: v-bind('labelDefaultColor') !important; | ||
70 | - } | ||
71 | - .n-tabs-tab--active { | ||
72 | - color: v-bind('labelActiveColor') !important; | ||
73 | - background-color: v-bind('segmentationActiveBgColor') !important; | ||
74 | - } | ||
75 | - .n-tabs-bar { | ||
76 | - background-color: v-bind('tabBottomBarColor') !important; | ||
77 | - } | ||
78 | - .n-tabs-rail { | ||
79 | - background-color: v-bind('segmentationBgColor') !important; | ||
80 | - } | ||
81 | -} | ||
82 | -</style> |
src/packages/components/external/Informations/Mores/OverrideInputsTab/interact.ts
deleted
100644 → 0
1 | -import { InteractEventOn, InteractActionsType } from '@/enums/eventEnum' | ||
2 | - | ||
3 | -// 时间组件类型 | ||
4 | -export enum ComponentInteractEventEnum { | ||
5 | - DATA = 'data' | ||
6 | -} | ||
7 | - | ||
8 | -// 联动参数 | ||
9 | -export enum ComponentInteractParamsEnum { | ||
10 | - DATA = 'data' | ||
11 | -} | ||
12 | - | ||
13 | -// 定义组件触发回调事件 | ||
14 | -export const interactActions: InteractActionsType[] = [ | ||
15 | - { | ||
16 | - interactType: InteractEventOn.CHANGE, | ||
17 | - interactName: '选择完成', | ||
18 | - componentEmitEvents: { | ||
19 | - [ComponentInteractEventEnum.DATA]: [ | ||
20 | - { | ||
21 | - value: ComponentInteractParamsEnum.DATA, | ||
22 | - label: '选择项' | ||
23 | - } | ||
24 | - ] | ||
25 | - } | ||
26 | - } | ||
27 | -] |
@@ -86,7 +86,7 @@ | @@ -86,7 +86,7 @@ | ||
86 | 86 | ||
87 | <script lang="ts" setup> | 87 | <script lang="ts" setup> |
88 | import { PropType } from 'vue' | 88 | import { PropType } from 'vue' |
89 | -import { CollapseItem, SettingItemBox } from '@/components/Pages/ChartItemSetting' | 89 | +import { CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting' |
90 | import { option } from './config' | 90 | import { option } from './config' |
91 | 91 | ||
92 | defineProps({ | 92 | defineProps({ |
@@ -7,7 +7,6 @@ import { OverrideImageConfig } from '@/packages/components/external/Informations | @@ -7,7 +7,6 @@ import { OverrideImageConfig } from '@/packages/components/external/Informations | ||
7 | import { OverrideCarouselConfig } from '@/packages/components/external/Informations/Mores/OverrideCarousel' | 7 | import { OverrideCarouselConfig } from '@/packages/components/external/Informations/Mores/OverrideCarousel' |
8 | import { OverrideSelectConfig } from '@/packages/components/external/Informations/Mores/OverrideSelect' | 8 | import { OverrideSelectConfig } from '@/packages/components/external/Informations/Mores/OverrideSelect' |
9 | import { OverrideInputsDateConfig } from '@/packages/components/external/Informations/Mores/OverrideInputsDate' | 9 | import { OverrideInputsDateConfig } from '@/packages/components/external/Informations/Mores/OverrideInputsDate' |
10 | -import { OverrideInputsTabConfig } from '@/packages/components/external/Informations/Mores/OverrideInputsTab' | ||
11 | 10 | ||
12 | export function useInjectLib(packagesList: EPackagesType) { | 11 | export function useInjectLib(packagesList: EPackagesType) { |
13 | 12 | ||
@@ -19,7 +18,6 @@ export function useInjectLib(packagesList: EPackagesType) { | @@ -19,7 +18,6 @@ export function useInjectLib(packagesList: EPackagesType) { | ||
19 | addWidgetToCategoryByCategoryName(packagesList, PackagesCategoryEnum.INFORMATIONS, OverrideCarouselConfig) | 18 | addWidgetToCategoryByCategoryName(packagesList, PackagesCategoryEnum.INFORMATIONS, OverrideCarouselConfig) |
20 | addWidgetToCategoryByCategoryName(packagesList, PackagesCategoryEnum.INFORMATIONS, OverrideSelectConfig) | 19 | addWidgetToCategoryByCategoryName(packagesList, PackagesCategoryEnum.INFORMATIONS, OverrideSelectConfig) |
21 | addWidgetToCategoryByCategoryName(packagesList, PackagesCategoryEnum.INFORMATIONS, OverrideInputsDateConfig) | 20 | addWidgetToCategoryByCategoryName(packagesList, PackagesCategoryEnum.INFORMATIONS, OverrideInputsDateConfig) |
22 | - addWidgetToCategoryByCategoryName(packagesList, PackagesCategoryEnum.INFORMATIONS, OverrideInputsTabConfig) | ||
23 | } | 21 | } |
24 | 22 | ||
25 | /** | 23 | /** |