Showing
53 changed files
with
1447 additions
and
691 deletions
@@ -22,7 +22,6 @@ | @@ -22,7 +22,6 @@ | ||
22 | theme = htmlRoot = null; | 22 | theme = htmlRoot = null; |
23 | } | 23 | } |
24 | })(); | 24 | })(); |
25 | - | ||
26 | </script> | 25 | </script> |
27 | <div id="app"> | 26 | <div id="app"> |
28 | <style> | 27 | <style> |
@@ -152,17 +151,17 @@ | @@ -152,17 +151,17 @@ | ||
152 | } | 151 | } |
153 | } | 152 | } |
154 | </style> | 153 | </style> |
155 | - <div class="app-loading"> | 154 | + <div id="first-screen-loading" class="app-loading"> |
156 | <div class="app-loading-wrap"> | 155 | <div class="app-loading-wrap"> |
157 | - <img src="/resource/img/logo.png" class="app-loading-logo" alt="Logo" /> | 156 | + <!-- <img src="/resource/img/logo.png" class="app-loading-logo" alt="Logo" /> --> |
158 | <div class="app-loading-dots"> | 157 | <div class="app-loading-dots"> |
159 | <span class="dot dot-spin"><i></i><i></i><i></i><i></i></span> | 158 | <span class="dot dot-spin"><i></i><i></i><i></i><i></i></span> |
160 | </div> | 159 | </div> |
161 | - <div class="app-loading-title"><%= title %></div> | 160 | + <!-- <div class="app-loading-title"><%= title %></div> --> |
162 | </div> | 161 | </div> |
163 | </div> | 162 | </div> |
164 | </div> | 163 | </div> |
165 | - | 164 | + |
166 | <script type="module" src="/src/main.ts"></script> | 165 | <script type="module" src="/src/main.ts"></script> |
167 | </body> | 166 | </body> |
168 | </html> | 167 | </html> |
1 | import { defHttp } from '/@/utils/http/axios'; | 1 | import { defHttp } from '/@/utils/http/axios'; |
2 | -import { FileUploadResponse } from './model/index'; | 2 | +import { FileUploadResponse, Platform } from './model/index'; |
3 | enum API { | 3 | enum API { |
4 | SELECT_DETAIL = '/enterprise/get', | 4 | SELECT_DETAIL = '/enterprise/get', |
5 | UPDATE_DETAIL = '/enterprise/update', | 5 | UPDATE_DETAIL = '/enterprise/update', |
@@ -67,7 +67,7 @@ export const bgUpload = (file) => { | @@ -67,7 +67,7 @@ export const bgUpload = (file) => { | ||
67 | 67 | ||
68 | // 获取平台定制详情 | 68 | // 获取平台定制详情 |
69 | export const getPlatForm = () => { | 69 | export const getPlatForm = () => { |
70 | - return defHttp.get({ | 70 | + return defHttp.get<Platform>({ |
71 | url: API.SELECT_PLATFORM, | 71 | url: API.SELECT_PLATFORM, |
72 | }); | 72 | }); |
73 | }; | 73 | }; |
@@ -5,3 +5,17 @@ export interface FileUploadResponse { | @@ -5,3 +5,17 @@ export interface FileUploadResponse { | ||
5 | size: number; | 5 | size: number; |
6 | fileStaticUri: string; | 6 | fileStaticUri: string; |
7 | } | 7 | } |
8 | + | ||
9 | +export interface Platform { | ||
10 | + id: string; | ||
11 | + creator: string; | ||
12 | + createTime: string; | ||
13 | + updater: string; | ||
14 | + updateTime: string; | ||
15 | + name: string; | ||
16 | + logo: string; | ||
17 | + background: string; | ||
18 | + copyright: string; | ||
19 | + presentedOurselves: string; | ||
20 | + domain: string; | ||
21 | +} |
@@ -10,6 +10,7 @@ export { default as ApiSelect } from './src/components/ApiSelect.vue'; | @@ -10,6 +10,7 @@ export { default as ApiSelect } from './src/components/ApiSelect.vue'; | ||
10 | export { default as RadioButtonGroup } from './src/components/RadioButtonGroup.vue'; | 10 | export { default as RadioButtonGroup } from './src/components/RadioButtonGroup.vue'; |
11 | export { default as ApiTreeSelect } from './src/components/ApiTreeSelect.vue'; | 11 | export { default as ApiTreeSelect } from './src/components/ApiTreeSelect.vue'; |
12 | export { default as ApiRadioGroup } from './src/components/ApiRadioGroup.vue'; | 12 | export { default as ApiRadioGroup } from './src/components/ApiRadioGroup.vue'; |
13 | +export { default as ApiUpload } from './src/components/ApiUpload.vue'; | ||
13 | 14 | ||
14 | //注册自定义组件 | 15 | //注册自定义组件 |
15 | export { | 16 | export { |
1 | +<script lang="ts"> | ||
2 | + export default { | ||
3 | + inheritAttrs: false, | ||
4 | + }; | ||
5 | +</script> | ||
6 | +<script lang="ts" setup> | ||
7 | + import { UploadDragger, Spin } from 'ant-design-vue'; | ||
8 | + import { InboxOutlined } from '@ant-design/icons-vue'; | ||
9 | + import { useMessage } from '/@/hooks/web/useMessage'; | ||
10 | + import { isBoolean, isFunction } from '/@/utils/is'; | ||
11 | + import { computed, ref, unref } from 'vue'; | ||
12 | + import { cloneDeep } from 'lodash-es'; | ||
13 | + interface FileItem { | ||
14 | + uid: string; | ||
15 | + name?: string; | ||
16 | + status?: string; | ||
17 | + response?: string; | ||
18 | + url?: string; | ||
19 | + } | ||
20 | + | ||
21 | + const emit = defineEmits(['update:fileList']); | ||
22 | + | ||
23 | + const { createMessage } = useMessage(); | ||
24 | + | ||
25 | + const loading = ref(false); | ||
26 | + | ||
27 | + const componentDisabled = ref(false); | ||
28 | + | ||
29 | + const setLoading = (spin: boolean) => { | ||
30 | + loading.value = spin; | ||
31 | + }; | ||
32 | + | ||
33 | + const props = withDefaults( | ||
34 | + defineProps<{ | ||
35 | + fileList?: FileItem[]; | ||
36 | + accept?: string; | ||
37 | + maxSize?: number; | ||
38 | + disabled?: boolean; | ||
39 | + listType?: string; | ||
40 | + multiple?: boolean; | ||
41 | + showUploadList?: boolean | { showPreviewIcon?: boolean; showRemoveIcon?: boolean }; | ||
42 | + transformFile?: (file: File) => string | Blob | Promise<string | Blob | File>; | ||
43 | + api: (file: string | Blob | Promise<string | Blob | File>) => Promise<FileItem>; | ||
44 | + }>(), | ||
45 | + { | ||
46 | + fileList: () => [], | ||
47 | + maxSize: 5 * 1024 * 1024, | ||
48 | + showUploadList: () => ({ showPreviewIcon: true, showRemoveIcon: true }), | ||
49 | + } | ||
50 | + ); | ||
51 | + | ||
52 | + const handleBeforeUpload = (file: File) => { | ||
53 | + if (file.size > props.maxSize) { | ||
54 | + createMessage.warning(`文件大小超过${Math.floor(props.maxSize / 1024)}mb`); | ||
55 | + return false; | ||
56 | + } | ||
57 | + handleUpload(file); | ||
58 | + return false; | ||
59 | + }; | ||
60 | + | ||
61 | + const getDisabled = computed(() => { | ||
62 | + const { disabled } = props; | ||
63 | + if (isBoolean(disabled)) { | ||
64 | + return disabled ? componentDisabled.value : disabled; | ||
65 | + } | ||
66 | + return componentDisabled.value; | ||
67 | + }); | ||
68 | + | ||
69 | + const handleUpload = async (file: File | string | Blob | Promise<string | Blob | File>) => { | ||
70 | + try { | ||
71 | + setLoading(true); | ||
72 | + componentDisabled.value = true; | ||
73 | + console.log({ componentDisabled: unref(componentDisabled), getDisabled: unref(getDisabled) }); | ||
74 | + const { transformFile, api } = props; | ||
75 | + if (transformFile && isFunction(transformFile)) file = await transformFile(file as File); | ||
76 | + if (api && isFunction(api)) { | ||
77 | + const data = await api(file); | ||
78 | + emit('update:fileList', cloneDeep([...props.fileList, data])); | ||
79 | + } | ||
80 | + } catch (error) { | ||
81 | + window.console.error(error); | ||
82 | + } finally { | ||
83 | + setLoading(false); | ||
84 | + componentDisabled.value = false; | ||
85 | + } | ||
86 | + }; | ||
87 | + | ||
88 | + const handleRemove = (file: FileItem) => { | ||
89 | + const _fileList = cloneDeep(props.fileList); | ||
90 | + const index = _fileList.findIndex((item) => item.uid === file.uid); | ||
91 | + ~index && _fileList.splice(index, 1); | ||
92 | + emit('update:fileList', _fileList); | ||
93 | + }; | ||
94 | + | ||
95 | + const handlePreview = (file: FileItem) => { | ||
96 | + console.log('preview', file); | ||
97 | + }; | ||
98 | + | ||
99 | + const handleDownload = (file: FileItem) => { | ||
100 | + console.log('download', file); | ||
101 | + }; | ||
102 | +</script> | ||
103 | + | ||
104 | +<template> | ||
105 | + <UploadDragger | ||
106 | + :file-list="props.fileList" | ||
107 | + :disabled="getDisabled" | ||
108 | + :before-upload="handleBeforeUpload" | ||
109 | + @preview="handlePreview" | ||
110 | + @download="handleDownload" | ||
111 | + :remove="handleRemove" | ||
112 | + > | ||
113 | + <Spin :spinning="loading"> | ||
114 | + {{ getDisabled }} | ||
115 | + <div class="w-full h-full flex flex-col justify-center content-center"> | ||
116 | + <InboxOutlined class="text-[3rem] !text-blue-500" /> | ||
117 | + <div class="m-2 text-gray-400">点击上传或拖拽上传</div> | ||
118 | + </div> | ||
119 | + </Spin> | ||
120 | + </UploadDragger> | ||
121 | +</template> |
@@ -14,6 +14,7 @@ import { setupGlobDirectives } from '/@/directives'; | @@ -14,6 +14,7 @@ import { setupGlobDirectives } from '/@/directives'; | ||
14 | import { setupI18n } from '/@/locales/setupI18n'; | 14 | import { setupI18n } from '/@/locales/setupI18n'; |
15 | import { registerGlobComp } from '/@/components/registerGlobComp'; | 15 | import { registerGlobComp } from '/@/components/registerGlobComp'; |
16 | import '/@/assets/iconfont/iconfont'; | 16 | import '/@/assets/iconfont/iconfont'; |
17 | +import { usePlatform } from './views/system/customize/hook/usePlatformInfo'; | ||
17 | 18 | ||
18 | if (import.meta.env.DEV) { | 19 | if (import.meta.env.DEV) { |
19 | import('ant-design-vue/dist/antd.less'); | 20 | import('ant-design-vue/dist/antd.less'); |
@@ -23,6 +24,8 @@ async function bootstrap() { | @@ -23,6 +24,8 @@ async function bootstrap() { | ||
23 | // Configure store | 24 | // Configure store |
24 | setupStore(app); | 25 | setupStore(app); |
25 | 26 | ||
27 | + await usePlatform(); | ||
28 | + | ||
26 | // Initialize internal system configuration | 29 | // Initialize internal system configuration |
27 | initAppConfigStore(); | 30 | initAppConfigStore(); |
28 | 31 | ||
@@ -47,6 +50,7 @@ async function bootstrap() { | @@ -47,6 +50,7 @@ async function bootstrap() { | ||
47 | // Mount when the route is ready | 50 | // Mount when the route is ready |
48 | // https://next.router.vuejs.org/api/#isready | 51 | // https://next.router.vuejs.org/api/#isready |
49 | await router.isReady(); | 52 | await router.isReady(); |
53 | + | ||
50 | app.mount('#app', true); | 54 | app.mount('#app', true); |
51 | } | 55 | } |
52 | 56 |
@@ -39,7 +39,7 @@ | @@ -39,7 +39,7 @@ | ||
39 | width: '200px', | 39 | width: '200px', |
40 | height: '200px', | 40 | height: '200px', |
41 | color: '#409eff', | 41 | color: '#409eff', |
42 | - muted: false, //静音 | 42 | + muted: true, //静音 |
43 | webFullScreen: false, | 43 | webFullScreen: false, |
44 | autoPlay: true, //自动播放 | 44 | autoPlay: true, //自动播放 |
45 | currentTime: 0, | 45 | currentTime: 0, |
@@ -238,7 +238,7 @@ | @@ -238,7 +238,7 @@ | ||
238 | class="h-full flex flex-col justify-center items-center" | 238 | class="h-full flex flex-col justify-center items-center" |
239 | v-if="!cameraList.length" | 239 | v-if="!cameraList.length" |
240 | /> | 240 | /> |
241 | - <Row :gutter="16" class="h-full mx-0"> | 241 | + <Row :gutter="16" class="h-full mx-0 content-start"> |
242 | <Col | 242 | <Col |
243 | v-for="item in cameraList" | 243 | v-for="item in cameraList" |
244 | :key="item.id" | 244 | :key="item.id" |
1 | +<script lang="ts" setup> | ||
2 | + import { BasicModal, useModalInner } from '/@/components/Modal'; | ||
3 | + import { BasicForm, useForm } from '/@/components/Form'; | ||
4 | + import { formSchema } from '../config/packageDetail.config'; | ||
5 | + defineEmits(['register']); | ||
6 | + | ||
7 | + const [registerModal] = useModalInner((_record: Recordable) => {}); | ||
8 | + | ||
9 | + const [registerForm] = useForm({ | ||
10 | + schemas: formSchema, | ||
11 | + showActionButtonGroup: false, | ||
12 | + // labelCol: { span: 8 }, | ||
13 | + labelWidth: 100, | ||
14 | + wrapperCol: { span: 16 }, | ||
15 | + }); | ||
16 | +</script> | ||
17 | + | ||
18 | +<template> | ||
19 | + <BasicModal title="包管理" @register="registerModal"> | ||
20 | + <BasicForm @register="registerForm" /> | ||
21 | + </BasicModal> | ||
22 | +</template> |
src/views/operation/ota/config/config.ts
0 → 100644
1 | +import { BasicColumn, FormSchema } from '/@/components/Table'; | ||
2 | + | ||
3 | +export const columns: BasicColumn[] = [ | ||
4 | + { | ||
5 | + title: '创建时间', | ||
6 | + dataIndex: 'createTime', | ||
7 | + width: 120, | ||
8 | + }, | ||
9 | + { | ||
10 | + title: '标题', | ||
11 | + dataIndex: 'title', | ||
12 | + width: 120, | ||
13 | + }, | ||
14 | + { | ||
15 | + title: '版本', | ||
16 | + dataIndex: 'version', | ||
17 | + width: 120, | ||
18 | + }, | ||
19 | + { | ||
20 | + title: '版本标签', | ||
21 | + dataIndex: 'versionLabel', | ||
22 | + width: 120, | ||
23 | + }, | ||
24 | + { | ||
25 | + title: '包类型', | ||
26 | + dataIndex: 'pkgType', | ||
27 | + width: 120, | ||
28 | + }, | ||
29 | + { | ||
30 | + title: '直接URL', | ||
31 | + dataIndex: 'url', | ||
32 | + width: 120, | ||
33 | + }, | ||
34 | + { | ||
35 | + title: '文件大小', | ||
36 | + dataIndex: 'fileSize', | ||
37 | + width: 120, | ||
38 | + }, | ||
39 | + { | ||
40 | + title: '校验和', | ||
41 | + dataIndex: 'vaildateTotal', | ||
42 | + width: 120, | ||
43 | + }, | ||
44 | +]; | ||
45 | + | ||
46 | +export const searchFormSchema: FormSchema[] = [ | ||
47 | + { | ||
48 | + field: 'name', | ||
49 | + label: '标题', | ||
50 | + component: 'Input', | ||
51 | + colProps: { span: 8 }, | ||
52 | + }, | ||
53 | +]; |
1 | +import { FormSchema } from '/@/components/Form'; | ||
2 | + | ||
3 | +export enum PackageField { | ||
4 | + TITLE = 'title', | ||
5 | + VERSION = 'version', | ||
6 | + VERSION_LABEL = 'versionLabel', | ||
7 | + DEVICE_CONFIGURATION = 'deviceConfiguration', | ||
8 | + PACKAGE_TYPE = 'packageType', | ||
9 | + PACKAGE_UPDATE_TYPE = 'PackageUpdateType', | ||
10 | + PACKAGE_BINARY_FILE = 'packageBinaryFile', | ||
11 | + PACKAGE_EXTERNAL_URL = 'packageEexternalUrl', | ||
12 | + CHECK_SUM_WAY = 'checkSumWay', | ||
13 | + ALG = 'alg', | ||
14 | + CHECK_SUM = 'checkSum', | ||
15 | + DESCRIPTION = 'description', | ||
16 | +} | ||
17 | + | ||
18 | +export enum PackageUpdateType { | ||
19 | + BINARY_FILE = 'binaryFile', | ||
20 | + EXTERNAL_URL = 'externalUrl', | ||
21 | +} | ||
22 | + | ||
23 | +export enum PackageType { | ||
24 | + FIRMWARE = 'firmware', | ||
25 | + SOFTWARE = 'software', | ||
26 | +} | ||
27 | + | ||
28 | +export enum CheckSumWay { | ||
29 | + AUTO = 'auto', | ||
30 | + MANUAL = 'manual', | ||
31 | +} | ||
32 | + | ||
33 | +export enum ALG { | ||
34 | + MD5 = 'md5', | ||
35 | + SHA_256 = 'sha-256', | ||
36 | + SHA_384 = 'sha-384', | ||
37 | + SHA_512 = 'sha-512', | ||
38 | + CRC_32 = 'crc-32', | ||
39 | + MURMUR3_32 = 'murmur3-32', | ||
40 | + MURMUR3_128 = 'murmur3-128', | ||
41 | +} | ||
42 | + | ||
43 | +export const formSchema: FormSchema[] = [ | ||
44 | + { | ||
45 | + field: PackageField.TITLE, | ||
46 | + label: '标题', | ||
47 | + component: 'Input', | ||
48 | + rules: [{ required: true, message: '标题为必填项' }], | ||
49 | + componentProps: { | ||
50 | + placeholder: '请输入标题', | ||
51 | + }, | ||
52 | + }, | ||
53 | + { | ||
54 | + field: PackageField.VERSION, | ||
55 | + label: '版本', | ||
56 | + component: 'Input', | ||
57 | + rules: [{ required: true, message: '版本为必填项' }], | ||
58 | + componentProps: { | ||
59 | + placeholder: '请输入版本', | ||
60 | + }, | ||
61 | + }, | ||
62 | + { | ||
63 | + field: PackageField.VERSION_LABEL, | ||
64 | + label: '版本标签', | ||
65 | + component: 'Input', | ||
66 | + helpMessage: ['自定义标签应与您设备报告的软件包版本相匹配'], | ||
67 | + componentProps: { | ||
68 | + placeholder: '请输入版本标签', | ||
69 | + }, | ||
70 | + }, | ||
71 | + { | ||
72 | + field: PackageField.DEVICE_CONFIGURATION, | ||
73 | + label: '设备配置', | ||
74 | + component: 'Select', | ||
75 | + helpMessage: ['上传的包仅适用于具有所选配置文件的设备'], | ||
76 | + defaultValue: 'default', | ||
77 | + rules: [{ required: true, message: '设备配置为必填项' }], | ||
78 | + componentProps: () => { | ||
79 | + return { | ||
80 | + options: [{ label: 'default', value: 'default' }], | ||
81 | + placeholder: '请选择设备配置', | ||
82 | + }; | ||
83 | + }, | ||
84 | + }, | ||
85 | + { | ||
86 | + field: PackageField.PACKAGE_TYPE, | ||
87 | + label: '包类型', | ||
88 | + component: 'Select', | ||
89 | + helpMessage: ['上传包后,您将无法修改标题、版本、设备配置文件和包类型'], | ||
90 | + defaultValue: PackageType.FIRMWARE, | ||
91 | + rules: [{ required: true, message: '包类型为必填项' }], | ||
92 | + componentProps: () => { | ||
93 | + return { | ||
94 | + options: [ | ||
95 | + { label: '固件', value: PackageType.FIRMWARE }, | ||
96 | + { label: '软件', value: PackageType.SOFTWARE }, | ||
97 | + ], | ||
98 | + placeholder: '请选择设备配置', | ||
99 | + }; | ||
100 | + }, | ||
101 | + }, | ||
102 | + { | ||
103 | + field: PackageField.PACKAGE_UPDATE_TYPE, | ||
104 | + label: '上传方式', | ||
105 | + component: 'RadioGroup', | ||
106 | + defaultValue: PackageUpdateType.BINARY_FILE, | ||
107 | + componentProps: () => { | ||
108 | + return { | ||
109 | + options: [ | ||
110 | + { label: '上传二进制文件', value: PackageUpdateType.BINARY_FILE }, | ||
111 | + { label: '使用外部URL', value: PackageUpdateType.EXTERNAL_URL }, | ||
112 | + ], | ||
113 | + }; | ||
114 | + }, | ||
115 | + }, | ||
116 | + { | ||
117 | + field: PackageField.PACKAGE_BINARY_FILE, | ||
118 | + label: '二进制文件', | ||
119 | + ifShow: ({ model }) => { | ||
120 | + return model[PackageField.PACKAGE_UPDATE_TYPE] === PackageUpdateType.BINARY_FILE; | ||
121 | + }, | ||
122 | + component: 'Upload', | ||
123 | + componentProps: { | ||
124 | + api: () => { | ||
125 | + return {}; | ||
126 | + }, | ||
127 | + }, | ||
128 | + }, | ||
129 | + { | ||
130 | + field: PackageField.PACKAGE_EXTERNAL_URL, | ||
131 | + label: '外部URL', | ||
132 | + component: 'Input', | ||
133 | + ifShow: ({ model }) => { | ||
134 | + return model[PackageField.PACKAGE_UPDATE_TYPE] === PackageUpdateType.EXTERNAL_URL; | ||
135 | + }, | ||
136 | + rules: [{ required: true, message: '外部URL为必填项' }], | ||
137 | + componentProps: { | ||
138 | + placeholder: '请输入外部URL', | ||
139 | + }, | ||
140 | + }, | ||
141 | + { | ||
142 | + field: PackageField.CHECK_SUM_WAY, | ||
143 | + label: '校验和方式', | ||
144 | + component: 'RadioGroup', | ||
145 | + defaultValue: CheckSumWay.AUTO, | ||
146 | + componentProps: () => { | ||
147 | + return { | ||
148 | + options: [ | ||
149 | + { label: '自动生成', value: CheckSumWay.AUTO }, | ||
150 | + { label: '手动生成', value: CheckSumWay.MANUAL }, | ||
151 | + ], | ||
152 | + }; | ||
153 | + }, | ||
154 | + }, | ||
155 | + { | ||
156 | + field: PackageField.ALG, | ||
157 | + label: '校验和算法', | ||
158 | + component: 'Select', | ||
159 | + ifShow: ({ model }) => { | ||
160 | + return model[PackageField.CHECK_SUM_WAY] === CheckSumWay.MANUAL; | ||
161 | + }, | ||
162 | + componentProps: { | ||
163 | + placeholder: '请选择校验和算法', | ||
164 | + options: Object.keys(ALG).map((key) => { | ||
165 | + return { | ||
166 | + label: String(ALG[key]).toUpperCase(), | ||
167 | + value: ALG[key], | ||
168 | + }; | ||
169 | + }), | ||
170 | + }, | ||
171 | + }, | ||
172 | + { | ||
173 | + field: PackageField.CHECK_SUM, | ||
174 | + label: '校验和', | ||
175 | + component: 'Input', | ||
176 | + ifShow: ({ model }) => { | ||
177 | + return model[PackageField.CHECK_SUM_WAY] === CheckSumWay.MANUAL; | ||
178 | + }, | ||
179 | + helpMessage: ['如果校验和为空,会自动生成'], | ||
180 | + componentProps: { | ||
181 | + placeholder: '请输入校验和', | ||
182 | + }, | ||
183 | + }, | ||
184 | + { | ||
185 | + field: PackageField.DESCRIPTION, | ||
186 | + label: '描述', | ||
187 | + component: 'InputTextArea', | ||
188 | + componentProps: { | ||
189 | + placeholder: '请输入描述', | ||
190 | + }, | ||
191 | + }, | ||
192 | +]; |
src/views/operation/ota/index.vue
0 → 100644
1 | +<script lang="ts" setup> | ||
2 | + import { Button } from 'ant-design-vue'; | ||
3 | + import { columns, searchFormSchema } from './config/config'; | ||
4 | + import { PageWrapper } from '/@/components/Page'; | ||
5 | + import { BasicTable, useTable } from '/@/components/Table'; | ||
6 | + import PackageDetailModal from './components/PackageDetailModal.vue'; | ||
7 | + import { useModal } from '/@/components/Modal'; | ||
8 | + // import { ApiUpload } from '/@/components/Form'; | ||
9 | + // import { computed, ref, unref } from 'vue'; | ||
10 | + | ||
11 | + const [register] = useTable({ | ||
12 | + columns, | ||
13 | + title: '包仓库', | ||
14 | + formConfig: { | ||
15 | + labelWidth: 120, | ||
16 | + schemas: searchFormSchema, | ||
17 | + }, | ||
18 | + useSearchForm: true, | ||
19 | + showTableSetting: true, | ||
20 | + }); | ||
21 | + | ||
22 | + const [registerModal, { openModal }] = useModal(); | ||
23 | + | ||
24 | + const handleCreatePackage = () => { | ||
25 | + openModal(true); | ||
26 | + }; | ||
27 | + | ||
28 | + // const fileList = ref([]); | ||
29 | + // const handleUpload = async (file: File) => { | ||
30 | + // console.log(file); | ||
31 | + // return new Promise((resolve) => { | ||
32 | + // setTimeout(() => { | ||
33 | + // resolve({ | ||
34 | + // uid: file.uid, | ||
35 | + // type: file.type, | ||
36 | + // name: file.name, | ||
37 | + // linkProps: { download: 'http://www.baidu.cn' }, | ||
38 | + // }); | ||
39 | + // }, 3000); | ||
40 | + // }); | ||
41 | + // }; | ||
42 | +</script> | ||
43 | + | ||
44 | +<template> | ||
45 | + <PageWrapper dense contentFullHeight contentClass="flex flex-col"> | ||
46 | + <!-- <div class="w-40 h-40"> | ||
47 | + <ApiUpload v-model:file-list="fileList" :api="handleUpload" /> | ||
48 | + </div> --> | ||
49 | + <BasicTable @register="register"> | ||
50 | + <template #toolbar> | ||
51 | + <Button @click="handleCreatePackage" type="primary">新增包</Button> | ||
52 | + </template> | ||
53 | + </BasicTable> | ||
54 | + <PackageDetailModal @register="registerModal" /> | ||
55 | + </PageWrapper> | ||
56 | +</template> |
@@ -6,149 +6,161 @@ | @@ -6,149 +6,161 @@ | ||
6 | <a-button type="primary" @click="handleAdd"> 新增场景联动 </a-button> | 6 | <a-button type="primary" @click="handleAdd"> 新增场景联动 </a-button> |
7 | </Authority> | 7 | </Authority> |
8 | <Authority value="api:yt:sceneLinkage:delete"> | 8 | <Authority value="api:yt:sceneLinkage:delete"> |
9 | - <Popconfirm title="您确定要批量删除数据" ok-text="确定" cancel-text="取消" @confirm="handleDeleteOrBatchDelete(null)"> | 9 | + <Popconfirm |
10 | + title="您确定要批量删除数据" | ||
11 | + ok-text="确定" | ||
12 | + cancel-text="取消" | ||
13 | + @confirm="handleDeleteOrBatchDelete(null)" | ||
14 | + > | ||
10 | <a-button color="error" :disabled="hasBatchDelete"> 批量删除 </a-button> | 15 | <a-button color="error" :disabled="hasBatchDelete"> 批量删除 </a-button> |
11 | </Popconfirm> | 16 | </Popconfirm> |
12 | </Authority> | 17 | </Authority> |
13 | </template> | 18 | </template> |
14 | <template #action="{ record }"> | 19 | <template #action="{ record }"> |
15 | - <TableAction :actions="[ | ||
16 | - { | ||
17 | - label: '查看', | ||
18 | - auth: 'api:yt:sceneLinkage:get', | ||
19 | - icon: 'ant-design:eye-outlined', | ||
20 | - onClick: handleView.bind(null, record), | ||
21 | - }, | ||
22 | - { | ||
23 | - label: '编辑', | ||
24 | - auth: 'api:yt:sceneLinkage:update', | ||
25 | - icon: 'clarity:note-edit-line', | ||
26 | - onClick: handleEdit.bind(null, record), | ||
27 | - ifShow: record.creator === userId && record.status !== 1, | ||
28 | - }, | ||
29 | - { | ||
30 | - label: '删除', | ||
31 | - auth: 'api:yt:sceneLinkage:delete', | ||
32 | - icon: 'ant-design:delete-outlined', | ||
33 | - color: 'error', | ||
34 | - ifShow: record.creator === userId && record.status !== 1, | ||
35 | - popConfirm: { | ||
36 | - title: '是否确认删除', | ||
37 | - confirm: handleDeleteOrBatchDelete.bind(null, record), | 20 | + <TableAction |
21 | + :actions="[ | ||
22 | + { | ||
23 | + label: '查看', | ||
24 | + auth: 'api:yt:sceneLinkage:get', | ||
25 | + icon: 'ant-design:eye-outlined', | ||
26 | + onClick: handleView.bind(null, record), | ||
38 | }, | 27 | }, |
39 | - }, | ||
40 | - ]" /> | 28 | + { |
29 | + label: '编辑', | ||
30 | + auth: 'api:yt:sceneLinkage:update', | ||
31 | + icon: 'clarity:note-edit-line', | ||
32 | + onClick: handleEdit.bind(null, record), | ||
33 | + ifShow: record.creator === userId && record.status !== 1, | ||
34 | + }, | ||
35 | + { | ||
36 | + label: '删除', | ||
37 | + auth: 'api:yt:sceneLinkage:delete', | ||
38 | + icon: 'ant-design:delete-outlined', | ||
39 | + color: 'error', | ||
40 | + ifShow: record.creator === userId && record.status !== 1, | ||
41 | + popConfirm: { | ||
42 | + title: '是否确认删除', | ||
43 | + confirm: handleDeleteOrBatchDelete.bind(null, record), | ||
44 | + }, | ||
45 | + }, | ||
46 | + ]" | ||
47 | + /> | ||
41 | </template> | 48 | </template> |
42 | 49 | ||
43 | <template #status="{ record }"> | 50 | <template #status="{ record }"> |
44 | - <Switch :checked="record.status === 1" :loading="record.pendingStatus" checkedChildren="启用" | ||
45 | - unCheckedChildren="禁用" @change="(checked:boolean)=>statusChange(checked,record)" /> | 51 | + <Switch |
52 | + :checked="record.status === 1" | ||
53 | + :loading="record.pendingStatus" | ||
54 | + checkedChildren="启用" | ||
55 | + unCheckedChildren="禁用" | ||
56 | + @change="(checked:boolean)=>statusChange(checked,record)" | ||
57 | + /> | ||
46 | </template> | 58 | </template> |
47 | </BasicTable> | 59 | </BasicTable> |
48 | <SceneLinkAgeDrawer @register="registerDrawer" @success="handleSuccess" /> | 60 | <SceneLinkAgeDrawer @register="registerDrawer" @success="handleSuccess" /> |
49 | </div> | 61 | </div> |
50 | </template> | 62 | </template> |
51 | <script lang="ts" setup> | 63 | <script lang="ts" setup> |
52 | -import { nextTick } from 'vue'; | ||
53 | -import { BasicTable, useTable, TableAction } from '/@/components/Table'; | ||
54 | -import { useDrawer } from '/@/components/Drawer'; | ||
55 | -import { | ||
56 | - screenLinkPageGetApi, | ||
57 | - screenLinkPageDeleteApi, | ||
58 | - screenLinkPagePutApi, | ||
59 | -} from '/@/api/ruleengine/ruleengineApi'; | ||
60 | -import { useBatchDelete } from '/@/hooks/web/useBatchDelete'; | ||
61 | -import { Switch, Popconfirm } from 'ant-design-vue'; | ||
62 | -import { columns, searchFormSchema } from './config/config.data.ts'; | ||
63 | -import { USER_INFO_KEY } from '/@/enums/cacheEnum'; | ||
64 | -import { getAuthCache } from '/@/utils/auth'; | ||
65 | -import SceneLinkAgeDrawer from './SceneLinkAgeDrawer.vue'; | ||
66 | -import { useMessage } from '/@/hooks/web/useMessage'; | ||
67 | -import { Authority } from '/@/components/Authority'; | ||
68 | - | ||
69 | -const userInfo: any = getAuthCache(USER_INFO_KEY); | ||
70 | -const userId = userInfo.userId; | 64 | + import { nextTick } from 'vue'; |
65 | + import { BasicTable, useTable, TableAction } from '/@/components/Table'; | ||
66 | + import { useDrawer } from '/@/components/Drawer'; | ||
67 | + import { | ||
68 | + screenLinkPageGetApi, | ||
69 | + screenLinkPageDeleteApi, | ||
70 | + screenLinkPagePutApi, | ||
71 | + } from '/@/api/ruleengine/ruleengineApi'; | ||
72 | + import { useBatchDelete } from '/@/hooks/web/useBatchDelete'; | ||
73 | + import { Switch, Popconfirm } from 'ant-design-vue'; | ||
74 | + import { columns, searchFormSchema } from './config/config.data'; | ||
75 | + import { USER_INFO_KEY } from '/@/enums/cacheEnum'; | ||
76 | + import { getAuthCache } from '/@/utils/auth'; | ||
77 | + import SceneLinkAgeDrawer from './SceneLinkAgeDrawer.vue'; | ||
78 | + import { useMessage } from '/@/hooks/web/useMessage'; | ||
79 | + import { Authority } from '/@/components/Authority'; | ||
71 | 80 | ||
72 | -const [registerDrawer, { openDrawer }] = useDrawer(); | ||
73 | -const [registerTable, { reload, setProps, setSelectedRowKeys }] = useTable({ | ||
74 | - title: '场景联动列表', | ||
75 | - api: screenLinkPageGetApi, | ||
76 | - columns, | ||
77 | - formConfig: { | ||
78 | - labelWidth: 120, | ||
79 | - schemas: searchFormSchema, | ||
80 | - }, | ||
81 | - useSearchForm: true, | ||
82 | - showTableSetting: true, | ||
83 | - bordered: true, | ||
84 | - showIndexColumn: false, | ||
85 | - actionColumn: { | ||
86 | - width: 200, | ||
87 | - title: '操作', | ||
88 | - dataIndex: 'action', | ||
89 | - slots: { customRender: 'action' }, | ||
90 | - fixed: 'right', | ||
91 | - }, | ||
92 | -}); | ||
93 | -const { hasBatchDelete, handleDeleteOrBatchDelete, selectionOptions, resetSelectedRowKeys } = | ||
94 | - useBatchDelete(screenLinkPageDeleteApi, handleSuccess, setProps); | ||
95 | -selectionOptions.rowSelection.getCheckboxProps = (record: Recordable) => { | ||
96 | - // Demo:status为1的选择框禁用 | ||
97 | - if (record.status === 1) { | ||
98 | - return { disabled: true }; | ||
99 | - } else { | ||
100 | - return { disabled: false }; | ||
101 | - } | ||
102 | -}; | ||
103 | -nextTick(() => { | ||
104 | - setProps(selectionOptions); | ||
105 | -}); | ||
106 | - | ||
107 | -function handleAdd() { | ||
108 | - window.localStorage.setItem('isViewDisabledBtn', 'noView') | ||
109 | - openDrawer(true, { | ||
110 | - isUpdate: false, | ||
111 | - }); | ||
112 | -} | 81 | + const userInfo: any = getAuthCache(USER_INFO_KEY); |
82 | + const userId = userInfo.userId; | ||
113 | 83 | ||
114 | -function handleEdit(record: Recordable) { | ||
115 | - window.localStorage.setItem('isViewDisabledBtn', 'noView') | ||
116 | - openDrawer(true, { | ||
117 | - record, | ||
118 | - isUpdate: true, | 84 | + const [registerDrawer, { openDrawer }] = useDrawer(); |
85 | + const [registerTable, { reload, setProps, setSelectedRowKeys }] = useTable({ | ||
86 | + title: '场景联动列表', | ||
87 | + api: screenLinkPageGetApi, | ||
88 | + columns, | ||
89 | + formConfig: { | ||
90 | + labelWidth: 120, | ||
91 | + schemas: searchFormSchema, | ||
92 | + }, | ||
93 | + useSearchForm: true, | ||
94 | + showTableSetting: true, | ||
95 | + bordered: true, | ||
96 | + showIndexColumn: false, | ||
97 | + actionColumn: { | ||
98 | + width: 200, | ||
99 | + title: '操作', | ||
100 | + dataIndex: 'action', | ||
101 | + slots: { customRender: 'action' }, | ||
102 | + fixed: 'right', | ||
103 | + }, | ||
119 | }); | 104 | }); |
120 | -} | ||
121 | -function handleView(record: Recordable) { | ||
122 | - window.localStorage.setItem('isViewDisabledBtn', 'isView') | ||
123 | - openDrawer(true, { | ||
124 | - record, | ||
125 | - isUpdate: 3, | ||
126 | - }); | ||
127 | -} | ||
128 | -function handleSuccess() { | ||
129 | - reload(); | ||
130 | -} | ||
131 | - | ||
132 | -const statusChange = async (checked, record) => { | ||
133 | - setProps({ | ||
134 | - loading: true, | ||
135 | - }); | ||
136 | - setSelectedRowKeys([]); | ||
137 | - resetSelectedRowKeys(); | ||
138 | - const newStatus = checked ? 1 : 0; | ||
139 | - const { createMessage } = useMessage(); | ||
140 | - try { | ||
141 | - await screenLinkPagePutApi({ id: record.id, status: newStatus }); | ||
142 | - if (newStatus) { | ||
143 | - createMessage.success(`启用成功`); | 105 | + const { hasBatchDelete, handleDeleteOrBatchDelete, selectionOptions, resetSelectedRowKeys } = |
106 | + useBatchDelete(screenLinkPageDeleteApi, handleSuccess, setProps); | ||
107 | + selectionOptions.rowSelection.getCheckboxProps = (record: Recordable) => { | ||
108 | + // Demo:status为1的选择框禁用 | ||
109 | + if (record.status === 1) { | ||
110 | + return { disabled: true }; | ||
144 | } else { | 111 | } else { |
145 | - createMessage.success('禁用成功'); | 112 | + return { disabled: false }; |
146 | } | 113 | } |
147 | - } finally { | ||
148 | - setProps({ | ||
149 | - loading: false, | 114 | + }; |
115 | + nextTick(() => { | ||
116 | + setProps(selectionOptions); | ||
117 | + }); | ||
118 | + | ||
119 | + function handleAdd() { | ||
120 | + window.localStorage.setItem('isViewDisabledBtn', 'noView'); | ||
121 | + openDrawer(true, { | ||
122 | + isUpdate: false, | ||
123 | + }); | ||
124 | + } | ||
125 | + | ||
126 | + function handleEdit(record: Recordable) { | ||
127 | + window.localStorage.setItem('isViewDisabledBtn', 'noView'); | ||
128 | + openDrawer(true, { | ||
129 | + record, | ||
130 | + isUpdate: true, | ||
131 | + }); | ||
132 | + } | ||
133 | + function handleView(record: Recordable) { | ||
134 | + window.localStorage.setItem('isViewDisabledBtn', 'isView'); | ||
135 | + openDrawer(true, { | ||
136 | + record, | ||
137 | + isUpdate: 3, | ||
150 | }); | 138 | }); |
139 | + } | ||
140 | + function handleSuccess() { | ||
151 | reload(); | 141 | reload(); |
152 | } | 142 | } |
153 | -}; | 143 | + |
144 | + const statusChange = async (checked, record) => { | ||
145 | + setProps({ | ||
146 | + loading: true, | ||
147 | + }); | ||
148 | + setSelectedRowKeys([]); | ||
149 | + resetSelectedRowKeys(); | ||
150 | + const newStatus = checked ? 1 : 0; | ||
151 | + const { createMessage } = useMessage(); | ||
152 | + try { | ||
153 | + await screenLinkPagePutApi({ id: record.id, status: newStatus }); | ||
154 | + if (newStatus) { | ||
155 | + createMessage.success(`启用成功`); | ||
156 | + } else { | ||
157 | + createMessage.success('禁用成功'); | ||
158 | + } | ||
159 | + } finally { | ||
160 | + setProps({ | ||
161 | + loading: false, | ||
162 | + }); | ||
163 | + reload(); | ||
164 | + } | ||
165 | + }; | ||
154 | </script> | 166 | </script> |
1 | +import { getPlatForm } from '/@/api/oem'; | ||
2 | + | ||
3 | +enum DefaultPlatform { | ||
4 | + LOGO = '/resource/img/logo.png', | ||
5 | + // TITLE = 'ThingsKit', | ||
6 | + ICO = '/favicon.ico', | ||
7 | +} | ||
8 | + | ||
9 | +export const usePlatform = async () => { | ||
10 | + const platformInfo = await getPlatForm(); | ||
11 | + | ||
12 | + const createLoadingEffect = () => { | ||
13 | + const wrap = document.createElement('div'); | ||
14 | + wrap.setAttribute('class', 'app-loading-wrap'); | ||
15 | + const img = document.createElement('img'); | ||
16 | + img.setAttribute('src', platformInfo.logo || DefaultPlatform.LOGO); | ||
17 | + img.setAttribute('class', 'app-loading-logo'); | ||
18 | + img.setAttribute('alt', 'Logo'); | ||
19 | + const dots = document.createElement('div'); | ||
20 | + dots.setAttribute('class', 'app-loading-dots'); | ||
21 | + const dotWrap = document.createElement('span'); | ||
22 | + dotWrap.setAttribute('class', 'dot dot-spin'); | ||
23 | + for (let i = 0; i < 4; i++) { | ||
24 | + dotWrap.appendChild(document.createElement('i')); | ||
25 | + } | ||
26 | + const title = document.createElement('div'); | ||
27 | + title.setAttribute('class', 'app-loading-title'); | ||
28 | + const textNode = document.createTextNode( | ||
29 | + platformInfo.name || import.meta.env.VITE_GLOB_APP_TITLE | ||
30 | + ); | ||
31 | + title.appendChild(textNode); | ||
32 | + wrap.appendChild(img); | ||
33 | + dots.appendChild(dotWrap); | ||
34 | + wrap.appendChild(dots); | ||
35 | + wrap.appendChild(title); | ||
36 | + return wrap; | ||
37 | + }; | ||
38 | + | ||
39 | + const replaceSiteIco = () => { | ||
40 | + const linkEl = document.querySelectorAll('link[rel*="icon"]'); | ||
41 | + linkEl.forEach((item) => { | ||
42 | + item.setAttribute('href', platformInfo.logo || DefaultPlatform.ICO); | ||
43 | + }); | ||
44 | + }; | ||
45 | + | ||
46 | + const replaceLoadingEffect = () => { | ||
47 | + const loadingWrapper = document.getElementById('first-screen-loading'); | ||
48 | + loadingWrapper!.innerHTML = ''; | ||
49 | + loadingWrapper?.appendChild(createLoadingEffect()); | ||
50 | + }; | ||
51 | + | ||
52 | + const bootstrap = () => { | ||
53 | + replaceSiteIco(); | ||
54 | + replaceLoadingEffect(); | ||
55 | + }; | ||
56 | + | ||
57 | + bootstrap(); | ||
58 | +}; |
src/views/visual/board/components/ControlComponent/SlidingSwitch.vue
renamed from
src/views/visual/board/components/Other/SlidingSwitch.vue
1 | +<script lang="ts"> | ||
2 | + export default { | ||
3 | + inheritAttrs: false, | ||
4 | + }; | ||
5 | +</script> | ||
1 | <script lang="ts" setup> | 6 | <script lang="ts" setup> |
2 | - const props = defineProps<{ | ||
3 | - value?: boolean; | ||
4 | - }>(); | 7 | + import { RadioRecord } from '../../detail/config/util'; |
8 | + | ||
9 | + interface VisualComponentProps<Layout = Recordable, Value = Recordable> { | ||
10 | + value?: Value; | ||
11 | + layout?: Layout; | ||
12 | + radio?: RadioRecord; | ||
13 | + random?: boolean; | ||
14 | + add?: (key: string, method: Fn) => void; | ||
15 | + update?: () => void; | ||
16 | + remove?: (key: string) => void; | ||
17 | + } | ||
18 | + const props = defineProps<VisualComponentProps>(); | ||
5 | 19 | ||
6 | const emit = defineEmits(['update:value', 'change']); | 20 | const emit = defineEmits(['update:value', 'change']); |
7 | 21 | ||
@@ -14,7 +28,12 @@ | @@ -14,7 +28,12 @@ | ||
14 | 28 | ||
15 | <template> | 29 | <template> |
16 | <label class="sliding-switch"> | 30 | <label class="sliding-switch"> |
17 | - <input :value="props.value" type="checkbox" :checked="props.value" @change="handleChange" /> | 31 | + <input |
32 | + :value="props.value?.value" | ||
33 | + type="checkbox" | ||
34 | + :checked="props.value?.value" | ||
35 | + @change="handleChange" | ||
36 | + /> | ||
18 | <span class="slider"></span> | 37 | <span class="slider"></span> |
19 | <span class="on">ON</span> | 38 | <span class="on">ON</span> |
20 | <span class="off">OFF</span> | 39 | <span class="off">OFF</span> |
@@ -40,12 +59,9 @@ | @@ -40,12 +59,9 @@ | ||
40 | .slider { | 59 | .slider { |
41 | width: 80px; | 60 | width: 80px; |
42 | height: 40px; | 61 | height: 40px; |
62 | + display: flex; | ||
63 | + align-items: center; | ||
43 | box-sizing: border-box; | 64 | box-sizing: border-box; |
44 | - position: absolute; | ||
45 | - top: 0; | ||
46 | - left: 0; | ||
47 | - right: 0; | ||
48 | - bottom: 0; | ||
49 | border: 2px solid #ecf0f3; | 65 | border: 2px solid #ecf0f3; |
50 | border-radius: 20px; | 66 | border-radius: 20px; |
51 | box-shadow: -2px -2px 8px #fff, -2px -2px 12px hsl(0deg 0% 100% / 50%), | 67 | box-shadow: -2px -2px 8px #fff, -2px -2px 12px hsl(0deg 0% 100% / 50%), |
@@ -57,15 +73,14 @@ | @@ -57,15 +73,14 @@ | ||
57 | } | 73 | } |
58 | 74 | ||
59 | .slider::after { | 75 | .slider::after { |
60 | - position: absolute; | ||
61 | cursor: pointer; | 76 | cursor: pointer; |
62 | display: block; | 77 | display: block; |
63 | content: ''; | 78 | content: ''; |
64 | width: 24px; | 79 | width: 24px; |
65 | height: 24px; | 80 | height: 24px; |
66 | border-radius: 50%; | 81 | border-radius: 50%; |
67 | - top: 6px; | ||
68 | - left: 6px; | 82 | + margin-left: 6px; |
83 | + margin-right: 6px; | ||
69 | background-color: #ecf0f3; | 84 | background-color: #ecf0f3; |
70 | box-shadow: -2px -2px 8px #fff, -2px -2px 12px hsl(0deg 0% 100% / 50%), | 85 | box-shadow: -2px -2px 8px #fff, -2px -2px 12px hsl(0deg 0% 100% / 50%), |
71 | inset 2px 2px 4px hsl(0deg 0% 100% / 10%), 2px 2px 8px rgb(0 0 0 / 30%); | 86 | inset 2px 2px 4px hsl(0deg 0% 100% / 10%), 2px 2px 8px rgb(0 0 0 / 30%); |
@@ -80,13 +95,16 @@ | @@ -80,13 +95,16 @@ | ||
80 | input:checked ~ .slider::after { | 95 | input:checked ~ .slider::after { |
81 | transform: translateX(35px); | 96 | transform: translateX(35px); |
82 | } | 97 | } |
98 | + | ||
83 | input:not(:checked) ~ .on { | 99 | input:not(:checked) ~ .on { |
84 | opacity: 0; | 100 | opacity: 0; |
85 | - transform: translateX(0px); | 101 | + transform: translateX(0); |
86 | } | 102 | } |
87 | 103 | ||
88 | .on, | 104 | .on, |
89 | .off { | 105 | .off { |
106 | + position: absolute; | ||
107 | + top: 0; | ||
90 | display: inline-block; | 108 | display: inline-block; |
91 | margin-left: 3px; | 109 | margin-left: 3px; |
92 | width: 34px; | 110 | width: 34px; |
@@ -97,7 +115,9 @@ | @@ -97,7 +115,9 @@ | ||
97 | .on { | 115 | .on { |
98 | color: #039be5; | 116 | color: #039be5; |
99 | } | 117 | } |
118 | + | ||
100 | .off { | 119 | .off { |
120 | + right: 6px; | ||
101 | color: #999; | 121 | color: #999; |
102 | } | 122 | } |
103 | } | 123 | } |
1 | +<script lang="ts"> | ||
2 | + export default { | ||
3 | + inheritAttrs: false, | ||
4 | + }; | ||
5 | +</script> | ||
6 | +<script lang="ts" setup> | ||
7 | + import { Switch } from 'ant-design-vue'; | ||
8 | + import { computed } from 'vue'; | ||
9 | + import { DEFAULT_RADIO_RECORD, fontSize, RadioRecord } from '../../detail/config/util'; | ||
10 | + import SvgIcon from '/@/components/Icon/src/SvgIcon.vue'; | ||
11 | + import { | ||
12 | + ControlComponentDefaultConfig, | ||
13 | + ControlComponentValue, | ||
14 | + ControlComponentLayout, | ||
15 | + } from './control.config'; | ||
16 | + const props = withDefaults( | ||
17 | + defineProps<{ | ||
18 | + layout?: ControlComponentLayout; | ||
19 | + value?: ControlComponentValue; | ||
20 | + radio?: RadioRecord; | ||
21 | + }>(), | ||
22 | + { | ||
23 | + value: () => ControlComponentDefaultConfig, | ||
24 | + } | ||
25 | + ); | ||
26 | + const getRadio = computed(() => { | ||
27 | + return props.radio || DEFAULT_RADIO_RECORD; | ||
28 | + }); | ||
29 | +</script> | ||
30 | + | ||
31 | +<template> | ||
32 | + <div class="flex items-center w-full h-full p-4"> | ||
33 | + <div class="flex-auto flex truncate"> | ||
34 | + <SvgIcon | ||
35 | + :name="props.value?.icon! || ControlComponentDefaultConfig.icon!" | ||
36 | + prefix="iconfont" | ||
37 | + :style="{ | ||
38 | + color: props.value?.iconColor || ControlComponentDefaultConfig.iconColor, | ||
39 | + width: fontSize({ radioRecord: getRadio, basic: 30, min: 16 }), | ||
40 | + height: fontSize({ radioRecord: getRadio, basic: 30, min: 16 }), | ||
41 | + }" | ||
42 | + /> | ||
43 | + <span class="flex-auto mx-4 flex items-center truncate inline-block">属性名</span> | ||
44 | + </div> | ||
45 | + <Switch /> | ||
46 | + </div> | ||
47 | +</template> |
src/views/visual/board/components/ControlComponent/ToggleSwitch.vue
renamed from
src/views/visual/board/components/Other/ToggleSwitch.vue
1 | +<script lang="ts"> | ||
2 | + export default { | ||
3 | + inheritAttrs: false, | ||
4 | + }; | ||
5 | +</script> | ||
1 | <script lang="ts" setup> | 6 | <script lang="ts" setup> |
7 | + import { computed } from '@vue/reactivity'; | ||
8 | + import { DEFAULT_RADIO_RECORD, fontSize, RadioRecord } from '../../detail/config/util'; | ||
9 | + import { ControlComponentValue } from './control.config'; | ||
10 | + | ||
2 | const props = defineProps<{ | 11 | const props = defineProps<{ |
3 | - value?: boolean; | 12 | + value?: ControlComponentValue; |
13 | + layout?: Recordable; | ||
14 | + radio?: RadioRecord; | ||
4 | }>(); | 15 | }>(); |
5 | 16 | ||
6 | const emit = defineEmits(['update:value', 'change']); | 17 | const emit = defineEmits(['update:value', 'change']); |
@@ -10,12 +21,27 @@ | @@ -10,12 +21,27 @@ | ||
10 | emit('update:value', _value); | 21 | emit('update:value', _value); |
11 | emit('change', _value); | 22 | emit('change', _value); |
12 | }; | 23 | }; |
24 | + | ||
25 | + const getRadio = computed(() => { | ||
26 | + return props.radio! || DEFAULT_RADIO_RECORD; | ||
27 | + }); | ||
13 | </script> | 28 | </script> |
14 | 29 | ||
15 | <template> | 30 | <template> |
16 | - <div class="toggle-switch"> | 31 | + <div |
32 | + class="toggle-switch" | ||
33 | + :style="{ | ||
34 | + width: fontSize({ radioRecord: getRadio, basic: 75, max: 75, min: 60 }), | ||
35 | + height: fontSize({ radioRecord: getRadio, basic: 97.5, max: 97.5, min: 80 }), | ||
36 | + }" | ||
37 | + > | ||
17 | <label class="switch"> | 38 | <label class="switch"> |
18 | - <input :value="props.value" type="checkbox" :checked="props.value" @change="handleChange" /> | 39 | + <input |
40 | + :value="props.value?.value" | ||
41 | + type="checkbox" | ||
42 | + :checked="props.value?.value" | ||
43 | + @change="handleChange" | ||
44 | + /> | ||
19 | <div class="button"> | 45 | <div class="button"> |
20 | <div class="light"></div> | 46 | <div class="light"></div> |
21 | <div class="dots"></div> | 47 | <div class="dots"></div> |
@@ -29,9 +55,10 @@ | @@ -29,9 +55,10 @@ | ||
29 | 55 | ||
30 | <style scoped> | 56 | <style scoped> |
31 | .toggle-switch { | 57 | .toggle-switch { |
32 | - flex: 1 1 auto; | 58 | + /* flex: 1 1 auto; */ |
33 | max-width: 75px; | 59 | max-width: 75px; |
34 | - height: 97.5px; | 60 | + |
61 | + /* height: 97.5px; */ | ||
35 | display: flex; | 62 | display: flex; |
36 | } | 63 | } |
37 | 64 | ||
@@ -76,12 +103,12 @@ | @@ -76,12 +103,12 @@ | ||
76 | transform-origin: center center -20px; | 103 | transform-origin: center center -20px; |
77 | transform: translateZ(20px) rotateX(-25deg); | 104 | transform: translateZ(20px) rotateX(-25deg); |
78 | transform-style: preserve-3d; | 105 | transform-style: preserve-3d; |
79 | - background-color: #9b0621; | ||
80 | width: 100%; | 106 | width: 100%; |
81 | height: 100%; | 107 | height: 100%; |
82 | position: relative; | 108 | position: relative; |
83 | cursor: pointer; | 109 | cursor: pointer; |
84 | background: linear-gradient(#980000 0%, #6f0000 30%, #6f0000 70%, #980000 100%); | 110 | background: linear-gradient(#980000 0%, #6f0000 30%, #6f0000 70%, #980000 100%); |
111 | + background-color: #9b0621; | ||
85 | background-repeat: no-repeat; | 112 | background-repeat: no-repeat; |
86 | } | 113 | } |
87 | 114 | ||
@@ -113,7 +140,7 @@ | @@ -113,7 +140,7 @@ | ||
113 | transform: translateY(30px) rotateX(-90deg); | 140 | transform: translateY(30px) rotateX(-90deg); |
114 | position: absolute; | 141 | position: absolute; |
115 | bottom: 0; | 142 | bottom: 0; |
116 | - box-shadow: 0 30px 8px 0px black, 0 60px 20px 0px rgb(0 0 0 / 50%); | 143 | + box-shadow: 0 30px 8px 0 black, 0 60px 20px 0 rgb(0 0 0 / 50%); |
117 | } | 144 | } |
118 | 145 | ||
119 | .switch .light { | 146 | .switch .light { |
1 | +import { DataComponentRecord, DataSource } from '/@/api/dataBoard/model'; | ||
2 | + | ||
3 | +export interface ControlComponentLayout { | ||
4 | + [key: string]: any; | ||
5 | +} | ||
6 | + | ||
7 | +export interface ControlComponentValue { | ||
8 | + value?: boolean; | ||
9 | + name?: string; | ||
10 | + icon?: string; | ||
11 | + iconColor?: string; | ||
12 | +} | ||
13 | + | ||
14 | +export const ControlComponentDefaultConfig: ControlComponentValue = { | ||
15 | + icon: 'shuiwen', | ||
16 | + iconColor: '#367BFF', | ||
17 | +}; | ||
18 | + | ||
19 | +export const transformControlConfig = ( | ||
20 | + _ComponentConfig: Recordable, | ||
21 | + _record: DataComponentRecord, | ||
22 | + dataSourceRecord: DataSource | ||
23 | +) => { | ||
24 | + return { | ||
25 | + value: { | ||
26 | + value: dataSourceRecord.componentInfo.value, | ||
27 | + icon: dataSourceRecord.componentInfo.icon, | ||
28 | + } as ControlComponentValue, | ||
29 | + }; | ||
30 | +}; |
1 | +<script lang="ts"> | ||
2 | + export default { | ||
3 | + inheritAttrs: false, | ||
4 | + }; | ||
5 | +</script> | ||
1 | <script lang="ts" setup> | 6 | <script lang="ts" setup> |
2 | import type { ECharts, EChartsOption } from 'echarts'; | 7 | import type { ECharts, EChartsOption } from 'echarts'; |
3 | import { PropType, watch } from 'vue'; | 8 | import { PropType, watch } from 'vue'; |
@@ -7,21 +12,21 @@ | @@ -7,21 +12,21 @@ | ||
7 | DashboardComponentLayout, | 12 | DashboardComponentLayout, |
8 | DashBoardValue, | 13 | DashBoardValue, |
9 | instrumentComponent1, | 14 | instrumentComponent1, |
10 | - InstrumentComponentType, | ||
11 | update_instrument_1_font, | 15 | update_instrument_1_font, |
12 | update_instrument_2_font, | 16 | update_instrument_2_font, |
13 | update_instrument_1_value, | 17 | update_instrument_1_value, |
14 | update_instrument_2_value, | 18 | update_instrument_2_value, |
15 | } from './dashBoardComponent.config'; | 19 | } from './dashBoardComponent.config'; |
16 | - import { dateUtil } from '/@/utils/dateUtil'; | ||
17 | import { | 20 | import { |
18 | DEFAULT_RADIO_RECORD, | 21 | DEFAULT_RADIO_RECORD, |
19 | RadioRecord, | 22 | RadioRecord, |
20 | - DEFAULT_DATE_FORMAT, | ||
21 | fontSize, | 23 | fontSize, |
24 | + getUpdateTime, | ||
22 | } from '../../detail/config/util'; | 25 | } from '../../detail/config/util'; |
23 | import { Tooltip } from 'ant-design-vue'; | 26 | import { Tooltip } from 'ant-design-vue'; |
24 | import { useThrottleFn } from '@vueuse/shared'; | 27 | import { useThrottleFn } from '@vueuse/shared'; |
28 | + import { buildUUID } from '/@/utils/uuid'; | ||
29 | + import { FrontComponent } from '../help'; | ||
25 | 30 | ||
26 | const props = defineProps({ | 31 | const props = defineProps({ |
27 | add: { | 32 | add: { |
@@ -33,7 +38,7 @@ | @@ -33,7 +38,7 @@ | ||
33 | }, | 38 | }, |
34 | value: { | 39 | value: { |
35 | type: Object as PropType<DashBoardValue>, | 40 | type: Object as PropType<DashBoardValue>, |
36 | - default: () => ({}), | 41 | + default: () => ({ id: buildUUID() }), |
37 | }, | 42 | }, |
38 | radio: { | 43 | radio: { |
39 | type: Object as PropType<RadioRecord>, | 44 | type: Object as PropType<RadioRecord>, |
@@ -60,7 +65,6 @@ | @@ -60,7 +65,6 @@ | ||
60 | } | 65 | } |
61 | 66 | ||
62 | const getRadio = computed(() => { | 67 | const getRadio = computed(() => { |
63 | - // const { radio } = props.radio; | ||
64 | return props.radio; | 68 | return props.radio; |
65 | }); | 69 | }); |
66 | 70 | ||
@@ -68,7 +72,6 @@ | @@ -68,7 +72,6 @@ | ||
68 | const realWidth = unref(chartRef)?.getWidth(); | 72 | const realWidth = unref(chartRef)?.getWidth(); |
69 | const realHeight = unref(chartRef)?.getHeight(); | 73 | const realHeight = unref(chartRef)?.getHeight(); |
70 | const radioRecord = props.radio; | 74 | const radioRecord = props.radio; |
71 | - // const widht | ||
72 | return { | 75 | return { |
73 | ...radioRecord, | 76 | ...radioRecord, |
74 | height: realHeight || radioRecord.height, | 77 | height: realHeight || radioRecord.height, |
@@ -76,7 +79,7 @@ | @@ -76,7 +79,7 @@ | ||
76 | }; | 79 | }; |
77 | }); | 80 | }); |
78 | 81 | ||
79 | - const beforeUpdateFn = (componentType: InstrumentComponentType) => { | 82 | + const beforeUpdateFn = (componentType: FrontComponent) => { |
80 | if (componentType === 'instrument-component-1') return update_instrument_1_font; | 83 | if (componentType === 'instrument-component-1') return update_instrument_1_font; |
81 | if (componentType === 'instrument-component-2') return update_instrument_2_font; | 84 | if (componentType === 'instrument-component-2') return update_instrument_2_font; |
82 | return (_radio: RadioRecord) => {}; | 85 | return (_radio: RadioRecord) => {}; |
@@ -88,7 +91,7 @@ | @@ -88,7 +91,7 @@ | ||
88 | unref(chartRef)?.resize(); | 91 | unref(chartRef)?.resize(); |
89 | } | 92 | } |
90 | 93 | ||
91 | - const getUpdateValueFn = (componentType: InstrumentComponentType) => { | 94 | + const getUpdateValueFn = (componentType: FrontComponent) => { |
92 | if (componentType === 'instrument-component-1') return update_instrument_1_value; | 95 | if (componentType === 'instrument-component-1') return update_instrument_1_value; |
93 | if (componentType === 'instrument-component-2') return update_instrument_2_value; | 96 | if (componentType === 'instrument-component-2') return update_instrument_2_value; |
94 | return (_radio: DashBoardValue) => {}; | 97 | return (_radio: DashBoardValue) => {}; |
@@ -101,11 +104,6 @@ | @@ -101,11 +104,6 @@ | ||
101 | 104 | ||
102 | watch(() => props.value, updateChartValue); | 105 | watch(() => props.value, updateChartValue); |
103 | 106 | ||
104 | - // watch( | ||
105 | - // () => [props.value.gradientInfo, props.value.unit, props.value.valueColor, props.value.name], | ||
106 | - // updateChartValue | ||
107 | - // ); | ||
108 | - | ||
109 | const updateChartFont = useThrottleFn(() => { | 107 | const updateChartFont = useThrottleFn(() => { |
110 | const option = beforeUpdateFn(props.layout.componentType); | 108 | const option = beforeUpdateFn(props.layout.componentType); |
111 | setTimeout(() => { | 109 | setTimeout(() => { |
@@ -122,8 +120,6 @@ | @@ -122,8 +120,6 @@ | ||
122 | 120 | ||
123 | watch(() => props.layout.componentType, updateChartType); | 121 | watch(() => props.layout.componentType, updateChartType); |
124 | 122 | ||
125 | - // watch(() => props.value.gradientInfo, updateChartType); | ||
126 | - | ||
127 | let timeout: Nullable<number> = null; | 123 | let timeout: Nullable<number> = null; |
128 | 124 | ||
129 | function handleRandomValue() { | 125 | function handleRandomValue() { |
@@ -170,22 +166,11 @@ | @@ -170,22 +166,11 @@ | ||
170 | color: '#999', | 166 | color: '#999', |
171 | }" | 167 | }" |
172 | > | 168 | > |
173 | - <Tooltip | ||
174 | - placement="top" | ||
175 | - :title=" | ||
176 | - props.value?.updateTime | ||
177 | - ? dateUtil(props?.value?.updateTime).format(DEFAULT_DATE_FORMAT) | ||
178 | - : '暂无更新时间' | ||
179 | - " | ||
180 | - > | 169 | + <Tooltip placement="top" :title="getUpdateTime(props.value?.updateTime)"> |
181 | <div class="truncate"> | 170 | <div class="truncate"> |
182 | <span class="mr-2">更新时间:</span> | 171 | <span class="mr-2">更新时间:</span> |
183 | <span> | 172 | <span> |
184 | - {{ | ||
185 | - props.value?.updateTime | ||
186 | - ? dateUtil(props?.value?.updateTime).format(DEFAULT_DATE_FORMAT) | ||
187 | - : '暂无更新时间' | ||
188 | - }} | 173 | + {{ getUpdateTime(props.value?.updateTime) }} |
189 | </span> | 174 | </span> |
190 | </div> | 175 | </div> |
191 | </Tooltip> | 176 | </Tooltip> |
1 | +<script lang="ts"> | ||
2 | + export default { | ||
3 | + inheritAttrs: false, | ||
4 | + }; | ||
5 | +</script> | ||
1 | <script lang="ts" setup> | 6 | <script lang="ts" setup> |
2 | import { computed, onMounted, onUnmounted, ref, unref } from 'vue'; | 7 | import { computed, onMounted, onUnmounted, ref, unref } from 'vue'; |
3 | import { Space, Tooltip } from 'ant-design-vue'; | 8 | import { Space, Tooltip } from 'ant-design-vue'; |
@@ -6,22 +11,27 @@ | @@ -6,22 +11,27 @@ | ||
6 | DigitalDashBoardLayout, | 11 | DigitalDashBoardLayout, |
7 | DigitalDashBoardValue, | 12 | DigitalDashBoardValue, |
8 | } from './digitalDashBoard.config'; | 13 | } from './digitalDashBoard.config'; |
9 | - import { dateUtil } from '/@/utils/dateUtil'; | ||
10 | import { | 14 | import { |
11 | fontSize, | 15 | fontSize, |
12 | RadioRecord, | 16 | RadioRecord, |
13 | - DEFAULT_DATE_FORMAT, | 17 | + getUpdateTime, |
14 | DEFAULT_RADIO_RECORD, | 18 | DEFAULT_RADIO_RECORD, |
15 | DEFAULT_ANIMATION_INTERVAL, | 19 | DEFAULT_ANIMATION_INTERVAL, |
16 | } from '../../detail/config/util'; | 20 | } from '../../detail/config/util'; |
17 | import { isNaN } from 'lodash'; | 21 | import { isNaN } from 'lodash'; |
18 | 22 | ||
19 | - const props = defineProps<{ | ||
20 | - layout: DigitalDashBoardLayout; | ||
21 | - value: DigitalDashBoardValue; | ||
22 | - radio?: RadioRecord; | ||
23 | - random?: boolean; | ||
24 | - }>(); | 23 | + const props = withDefaults( |
24 | + defineProps<{ | ||
25 | + layout?: DigitalDashBoardLayout; | ||
26 | + value?: DigitalDashBoardValue; | ||
27 | + radio?: RadioRecord; | ||
28 | + random?: boolean; | ||
29 | + }>(), | ||
30 | + { | ||
31 | + value: () => ({}), | ||
32 | + layout: () => ({ max: 5, keepNumber: 2 }), | ||
33 | + } | ||
34 | + ); | ||
25 | 35 | ||
26 | const changeValue = ref(0); | 36 | const changeValue = ref(0); |
27 | 37 | ||
@@ -53,8 +63,6 @@ | @@ -53,8 +63,6 @@ | ||
53 | }); | 63 | }); |
54 | 64 | ||
55 | const getRadio = computed(() => { | 65 | const getRadio = computed(() => { |
56 | - // const { radio } = props.radio || DEFAULT_RADIO_RECORD; | ||
57 | - // return radio; | ||
58 | return props.radio || DEFAULT_RADIO_RECORD; | 66 | return props.radio || DEFAULT_RADIO_RECORD; |
59 | }); | 67 | }); |
60 | 68 | ||
@@ -160,22 +168,11 @@ | @@ -160,22 +168,11 @@ | ||
160 | color: '#999', | 168 | color: '#999', |
161 | }" | 169 | }" |
162 | > | 170 | > |
163 | - <Tooltip | ||
164 | - placement="top" | ||
165 | - :title=" | ||
166 | - props.value?.updateTime | ||
167 | - ? dateUtil(props?.value?.updateTime).format(DEFAULT_DATE_FORMAT) | ||
168 | - : '暂无更新时间' | ||
169 | - " | ||
170 | - > | 171 | + <Tooltip placement="top" :title="getUpdateTime(props.value?.updateTime)"> |
171 | <div class="truncate"> | 172 | <div class="truncate"> |
172 | <span class="mr-1">更新时间:</span> | 173 | <span class="mr-1">更新时间:</span> |
173 | <span> | 174 | <span> |
174 | - {{ | ||
175 | - props.value?.updateTime | ||
176 | - ? dateUtil(props?.value?.updateTime).format(DEFAULT_DATE_FORMAT) | ||
177 | - : '暂无更新时间' | ||
178 | - }} | 175 | + {{ getUpdateTime(props.value?.updateTime) }} |
179 | </span> | 176 | </span> |
180 | </div> | 177 | </div> |
181 | </Tooltip> | 178 | </Tooltip> |
@@ -188,11 +185,12 @@ | @@ -188,11 +185,12 @@ | ||
188 | <style scoped lang="less"> | 185 | <style scoped lang="less"> |
189 | .digital-wrapper__int { | 186 | .digital-wrapper__int { |
190 | border-radius: 1px; | 187 | border-radius: 1px; |
191 | - box-shadow: inset 0px 1px 3px 0px rgba(0, 0, 0, 0.7); | ||
192 | - background: url('/@/assets/images/digital-wrapper-bg-int.png') 0px -1px no-repeat; | 188 | + box-shadow: inset 0 1px 3px 0 rgba(0, 0, 0, 0.7); |
189 | + background: url('/@/assets/images/digital-wrapper-bg-int.png') 0 -1px no-repeat; | ||
193 | padding: 5px; | 190 | padding: 5px; |
194 | background-size: 100% 100%; | 191 | background-size: 100% 100%; |
195 | } | 192 | } |
193 | + | ||
196 | .digital-text_int { | 194 | .digital-text_int { |
197 | display: inline-block; | 195 | display: inline-block; |
198 | overflow-wrap: break-word; | 196 | overflow-wrap: break-word; |
@@ -203,11 +201,12 @@ | @@ -203,11 +201,12 @@ | ||
203 | 201 | ||
204 | .digital-wrapper__float { | 202 | .digital-wrapper__float { |
205 | border-radius: 1px; | 203 | border-radius: 1px; |
206 | - box-shadow: inset 0px 1px 3px 0px rgba(112, 22, 15, 1); | ||
207 | - background: url('/@/assets/images/digital-wrapper-bg-float.png') 0px -1px no-repeat; | 204 | + box-shadow: inset 0 1px 3px 0 rgba(112, 22, 15, 1); |
205 | + background: url('/@/assets/images/digital-wrapper-bg-float.png') 0 -1px no-repeat; | ||
208 | padding: 5px; | 206 | padding: 5px; |
209 | background-size: 100% 100%; | 207 | background-size: 100% 100%; |
210 | } | 208 | } |
209 | + | ||
211 | .digital-text_float { | 210 | .digital-text_float { |
212 | display: inline-block; | 211 | display: inline-block; |
213 | overflow-wrap: break-word; | 212 | overflow-wrap: break-word; |
1 | import { EChartsOption } from 'echarts'; | 1 | import { EChartsOption } from 'echarts'; |
2 | +import { FrontComponent, Gradient, GradientColor } from '../../const/const'; | ||
2 | import { fontSize, RadioRecord } from '../../detail/config/util'; | 3 | import { fontSize, RadioRecord } from '../../detail/config/util'; |
3 | -import { Gradient, visualOptionField } from '../../detail/config/visualOptions'; | ||
4 | import { | 4 | import { |
5 | ComponentInfo, | 5 | ComponentInfo, |
6 | DataComponentRecord, | 6 | DataComponentRecord, |
@@ -10,16 +10,6 @@ import { | @@ -10,16 +10,6 @@ import { | ||
10 | import { isArray } from '/@/utils/is'; | 10 | import { isArray } from '/@/utils/is'; |
11 | import { buildUUID } from '/@/utils/uuid'; | 11 | import { buildUUID } from '/@/utils/uuid'; |
12 | 12 | ||
13 | -export type InstrumentComponentType = 'instrument-component-1' | 'instrument-component-2'; | ||
14 | - | ||
15 | -export type GradientKey = | ||
16 | - | visualOptionField.FIRST_PHASE_COLOR | ||
17 | - | visualOptionField.FIRST_PHASE_VALUE | ||
18 | - | visualOptionField.SECOND_PHASE_COLOR | ||
19 | - | visualOptionField.SECOND_PHASE_VALUE | ||
20 | - | visualOptionField.THIRD_PHASE_COLOR | ||
21 | - | visualOptionField.THIRD_PHASE_VALUE; | ||
22 | - | ||
23 | export interface GradientInfoRecord { | 13 | export interface GradientInfoRecord { |
24 | key: Gradient; | 14 | key: Gradient; |
25 | value: number; | 15 | value: number; |
@@ -38,13 +28,7 @@ export interface DashBoardValue { | @@ -38,13 +28,7 @@ export interface DashBoardValue { | ||
38 | 28 | ||
39 | export interface DashboardComponentLayout { | 29 | export interface DashboardComponentLayout { |
40 | chartOption: EChartsOption; | 30 | chartOption: EChartsOption; |
41 | - componentType: InstrumentComponentType; | ||
42 | -} | ||
43 | - | ||
44 | -export enum GradientColor { | ||
45 | - FIRST = '#67e0e3', | ||
46 | - SECOND = '#37a2da', | ||
47 | - THIRD = '#fd666d', | 31 | + componentType: FrontComponent; |
48 | } | 32 | } |
49 | 33 | ||
50 | export const instrumentComponent1 = (params?: Partial<ComponentInfo>): EChartsOption => { | 34 | export const instrumentComponent1 = (params?: Partial<ComponentInfo>): EChartsOption => { |
@@ -94,7 +78,6 @@ export const instrumentComponent1 = (params?: Partial<ComponentInfo>): EChartsOp | @@ -94,7 +78,6 @@ export const instrumentComponent1 = (params?: Partial<ComponentInfo>): EChartsOp | ||
94 | axisLabel: { | 78 | axisLabel: { |
95 | distance: 0, | 79 | distance: 0, |
96 | color: '#999', | 80 | color: '#999', |
97 | - // fontSize: 20, | ||
98 | }, | 81 | }, |
99 | anchor: { | 82 | anchor: { |
100 | show: false, | 83 | show: false, |
@@ -173,7 +156,6 @@ export const instrumentComponent2 = (params?: Partial<ComponentInfo>): EChartsOp | @@ -173,7 +156,6 @@ export const instrumentComponent2 = (params?: Partial<ComponentInfo>): EChartsOp | ||
173 | 156 | ||
174 | const firstGradient = firstRecord?.value ? firstRecord.value / max : 0.3; | 157 | const firstGradient = firstRecord?.value ? firstRecord.value / max : 0.3; |
175 | const secondGradient = secondRecord?.value ? secondRecord.value / max : 0.7; | 158 | const secondGradient = secondRecord?.value ? secondRecord.value / max : 0.7; |
176 | - // const thirdGradient = thirdRecord?.value ? thirdRecord.value / max : 1; | ||
177 | 159 | ||
178 | return { | 160 | return { |
179 | series: [ | 161 | series: [ |
@@ -307,12 +289,15 @@ export const update_instrument_2_value = (params: DashBoardValue) => { | @@ -307,12 +289,15 @@ export const update_instrument_2_value = (params: DashBoardValue) => { | ||
307 | 289 | ||
308 | let max = thirdRecord?.value || secondRecord?.value || firstRecord?.value || 70; | 290 | let max = thirdRecord?.value || secondRecord?.value || firstRecord?.value || 70; |
309 | max = Number(1 + Array(String(max).length).fill(0).join('')); | 291 | max = Number(1 + Array(String(max).length).fill(0).join('')); |
292 | + max = value > 1 ? Number(1 + Array(String(value).length).fill(0).join('')) / 2 : 100 / 2; | ||
293 | + max = value > max ? max * 2 : max; | ||
310 | 294 | ||
311 | const firstGradient = firstRecord?.value ? firstRecord.value / max : 0.3; | 295 | const firstGradient = firstRecord?.value ? firstRecord.value / max : 0.3; |
312 | const secondGradient = secondRecord?.value ? secondRecord.value / max : 0.7; | 296 | const secondGradient = secondRecord?.value ? secondRecord.value / max : 0.7; |
313 | return { | 297 | return { |
314 | series: [ | 298 | series: [ |
315 | { | 299 | { |
300 | + max: max < 100 ? 100 : max, | ||
316 | data: [{ value: handleValue(value) }], | 301 | data: [{ value: handleValue(value) }], |
317 | detail: { | 302 | detail: { |
318 | formatter: `{value} ${unit ?? ''}`, | 303 | formatter: `{value} ${unit ?? ''}`, |
@@ -354,7 +339,7 @@ export const Instrument2DefaultConfig: Partial<ComponentInfo> = { | @@ -354,7 +339,7 @@ export const Instrument2DefaultConfig: Partial<ComponentInfo> = { | ||
354 | 339 | ||
355 | export const transformDashboardComponentConfig = ( | 340 | export const transformDashboardComponentConfig = ( |
356 | config: DashboardComponentLayout, | 341 | config: DashboardComponentLayout, |
357 | - record: DataComponentRecord, | 342 | + _record: DataComponentRecord, |
358 | dataSourceRecord: DataSource | 343 | dataSourceRecord: DataSource |
359 | ) => { | 344 | ) => { |
360 | let chartOption = config.chartOption; | 345 | let chartOption = config.chartOption; |
1 | import { ComponentInfo } from '/@/api/dataBoard/model'; | 1 | import { ComponentInfo } from '/@/api/dataBoard/model'; |
2 | 2 | ||
3 | -export type DigitalDashBoardComponentType = 'digital-dashboard-component'; | ||
4 | - | ||
5 | export interface DigitalDashBoardLayout { | 3 | export interface DigitalDashBoardLayout { |
6 | max: number; | 4 | max: number; |
7 | keepNumber: number; | 5 | keepNumber: number; |
1 | import { EChartsOption } from 'echarts'; | 1 | import { EChartsOption } from 'echarts'; |
2 | -import { Component } from 'vue'; | ||
3 | -import { WidgetComponentType } from '../../detail/config/visualOptions'; | ||
4 | -import { | ||
5 | - Instrument1DefaultConfig, | ||
6 | - Instrument2DefaultConfig, | ||
7 | - instrumentComponent1, | ||
8 | - instrumentComponent2, | ||
9 | - InstrumentComponentType, | ||
10 | -} from './dashBoardComponent.config'; | ||
11 | -import DashBoardComponent from './DashBoardComponent.vue'; | ||
12 | -import DigitalDashBoard from './DigitalDashBoard.vue'; | ||
13 | -import { buildUUID } from '/@/utils/uuid'; | 2 | +import { InstrumentComponentType } from './dashBoardComponent.config'; |
14 | 3 | ||
15 | export interface DashboardComponentLayout { | 4 | export interface DashboardComponentLayout { |
16 | chartOption: EChartsOption; | 5 | chartOption: EChartsOption; |
17 | componentType: InstrumentComponentType; | 6 | componentType: InstrumentComponentType; |
18 | } | 7 | } |
19 | - | ||
20 | -interface InstrumentComponentConfig { | ||
21 | - id: WidgetComponentType; | ||
22 | - layout: DashboardComponentLayout; | ||
23 | - component: Component; | ||
24 | - value: Recordable; | ||
25 | -} | ||
26 | - | ||
27 | -export const instrumentComponentConfig: InstrumentComponentConfig[] = [ | ||
28 | - { | ||
29 | - id: 'instrument-component-1', | ||
30 | - layout: { | ||
31 | - chartOption: instrumentComponent1(Instrument1DefaultConfig), | ||
32 | - componentType: 'instrument-component-1', | ||
33 | - }, | ||
34 | - component: DashBoardComponent, | ||
35 | - value: { id: buildUUID() }, | ||
36 | - }, | ||
37 | - { | ||
38 | - id: 'instrument-component-2', | ||
39 | - layout: { | ||
40 | - chartOption: instrumentComponent2(Instrument2DefaultConfig), | ||
41 | - componentType: 'instrument-component-2', | ||
42 | - }, | ||
43 | - component: DashBoardComponent, | ||
44 | - value: { id: buildUUID() }, | ||
45 | - }, | ||
46 | - { | ||
47 | - id: 'digital-dashboard-component', | ||
48 | - layout: {}, | ||
49 | - component: DigitalDashBoard, | ||
50 | - value: {}, | ||
51 | - }, | ||
52 | -]; |
1 | +<script lang="ts"> | ||
2 | + export default { | ||
3 | + inheritAttrs: false, | ||
4 | + }; | ||
5 | +</script> | ||
6 | +<script lang="ts" setup> | ||
7 | + import { nextTick, onMounted, ref, unref } from 'vue'; | ||
8 | + import { useScript } from '/@/hooks/web/useScript'; | ||
9 | + import { BAI_DU_MAP_URL } from '/@/utils/fnUtils'; | ||
10 | + | ||
11 | + const wrapRef = ref<HTMLDivElement | null>(null); | ||
12 | + const { toPromise } = useScript({ src: BAI_DU_MAP_URL }); | ||
13 | + | ||
14 | + async function initMap() { | ||
15 | + await toPromise(); | ||
16 | + await nextTick(); | ||
17 | + const wrapEl = unref(wrapRef); | ||
18 | + if (!wrapEl) return; | ||
19 | + const BMap = (window as any).BMap; | ||
20 | + const map = new BMap.Map(wrapEl); | ||
21 | + const point = new BMap.Point(116.404, 39.915); | ||
22 | + map.centerAndZoom(point, 15); | ||
23 | + map.enableScrollWheelZoom(true); | ||
24 | + } | ||
25 | + | ||
26 | + onMounted(() => { | ||
27 | + initMap(); | ||
28 | + }); | ||
29 | +</script> | ||
30 | + | ||
31 | +<template> | ||
32 | + <div class="w-full h-full flex justify-center items-center"> | ||
33 | + <div ref="wrapRef" class="w-[95%] h-[95%]"></div> | ||
34 | + </div> | ||
35 | +</template> |
@@ -12,6 +12,7 @@ | @@ -12,6 +12,7 @@ | ||
12 | 12 | ||
13 | const isEdit = ref(false); | 13 | const isEdit = ref(false); |
14 | const recordId = ref<Nullable<string>>(null); | 14 | const recordId = ref<Nullable<string>>(null); |
15 | + const loading = ref(false); | ||
15 | 16 | ||
16 | const [registerModal, { changeLoading, closeModal }] = useModalInner( | 17 | const [registerModal, { changeLoading, closeModal }] = useModalInner( |
17 | (record: DataBoardRecord & { isEdit: boolean }) => { | 18 | (record: DataBoardRecord & { isEdit: boolean }) => { |
@@ -33,6 +34,7 @@ | @@ -33,6 +34,7 @@ | ||
33 | await method.validate(); | 34 | await method.validate(); |
34 | try { | 35 | try { |
35 | const value = method.getFieldsValue() as AddDataBoardParams; | 36 | const value = method.getFieldsValue() as AddDataBoardParams; |
37 | + loading.value = true; | ||
36 | changeLoading(true); | 38 | changeLoading(true); |
37 | await addDataBoard(value); | 39 | await addDataBoard(value); |
38 | createMessage.success('创建成功'); | 40 | createMessage.success('创建成功'); |
@@ -42,12 +44,14 @@ | @@ -42,12 +44,14 @@ | ||
42 | createMessage.error('创建失败'); | 44 | createMessage.error('创建失败'); |
43 | } finally { | 45 | } finally { |
44 | changeLoading(false); | 46 | changeLoading(false); |
47 | + loading.value = false; | ||
45 | } | 48 | } |
46 | }; | 49 | }; |
47 | 50 | ||
48 | const handleEditPanel = async () => { | 51 | const handleEditPanel = async () => { |
49 | await method.validate(); | 52 | await method.validate(); |
50 | try { | 53 | try { |
54 | + loading.value = true; | ||
51 | const value = method.getFieldsValue() as UpdateDataBoardParams; | 55 | const value = method.getFieldsValue() as UpdateDataBoardParams; |
52 | value.id = unref(recordId) as string; | 56 | value.id = unref(recordId) as string; |
53 | changeLoading(true); | 57 | changeLoading(true); |
@@ -59,6 +63,7 @@ | @@ -59,6 +63,7 @@ | ||
59 | createMessage.error('编辑失败'); | 63 | createMessage.error('编辑失败'); |
60 | } finally { | 64 | } finally { |
61 | changeLoading(false); | 65 | changeLoading(false); |
66 | + loading.value = false; | ||
62 | } | 67 | } |
63 | }; | 68 | }; |
64 | 69 | ||
@@ -75,6 +80,7 @@ | @@ -75,6 +80,7 @@ | ||
75 | :title="isEdit ? '编辑看板' : '创建看板'" | 80 | :title="isEdit ? '编辑看板' : '创建看板'" |
76 | @register="registerModal" | 81 | @register="registerModal" |
77 | @ok="handleGetValue" | 82 | @ok="handleGetValue" |
83 | + :okButtonProps="{ loading }" | ||
78 | > | 84 | > |
79 | <BasicForm @register="registerForm" /> | 85 | <BasicForm @register="registerForm" /> |
80 | </BasicModal> | 86 | </BasicModal> |
1 | +<script lang="ts"> | ||
2 | + export default { | ||
3 | + inheritAttrs: false, | ||
4 | + }; | ||
5 | +</script> | ||
1 | <script lang="ts" setup> | 6 | <script lang="ts" setup> |
2 | import { computed, ref, watch } from 'vue'; | 7 | import { computed, ref, watch } from 'vue'; |
3 | import { Tooltip, Image as AntImage } from 'ant-design-vue'; | 8 | import { Tooltip, Image as AntImage } from 'ant-design-vue'; |
4 | import { | 9 | import { |
5 | - DEFAULT_DATE_FORMAT, | 10 | + getUpdateTime, |
6 | DEFAULT_RADIO_RECORD, | 11 | DEFAULT_RADIO_RECORD, |
7 | fontSize, | 12 | fontSize, |
8 | RadioRecord, | 13 | RadioRecord, |
9 | } from '../../detail/config/util'; | 14 | } from '../../detail/config/util'; |
10 | - import { PictureComponentLayout, PictureComponentValue } from './pictureComponent.config'; | ||
11 | - import { dateUtil } from '/@/utils/dateUtil'; | 15 | + import { PictureComponentValue } from './pictureComponent.config'; |
12 | 16 | ||
13 | const props = defineProps<{ | 17 | const props = defineProps<{ |
14 | - layout?: PictureComponentLayout; | 18 | + layout?: Recordable; |
15 | value?: PictureComponentValue; | 19 | value?: PictureComponentValue; |
16 | radio?: RadioRecord; | 20 | radio?: RadioRecord; |
17 | }>(); | 21 | }>(); |
@@ -22,8 +26,6 @@ | @@ -22,8 +26,6 @@ | ||
22 | const getImagBase64 = ref(fallback); | 26 | const getImagBase64 = ref(fallback); |
23 | 27 | ||
24 | const getRadio = computed(() => { | 28 | const getRadio = computed(() => { |
25 | - // const { radio } = props.radio || DEFAULT_RADIO_RECORD; | ||
26 | - // return radio; | ||
27 | return props.radio || DEFAULT_RADIO_RECORD; | 29 | return props.radio || DEFAULT_RADIO_RECORD; |
28 | }); | 30 | }); |
29 | 31 | ||
@@ -67,26 +69,14 @@ | @@ -67,26 +69,14 @@ | ||
67 | class="w-full h-full flex flex-col justify-center items-center justify-between widget-picture" | 69 | class="w-full h-full flex flex-col justify-center items-center justify-between widget-picture" |
68 | > | 70 | > |
69 | <AntImage :width="getWidth" :src="getImagBase64" :fallback="fallback" /> | 71 | <AntImage :width="getWidth" :src="getImagBase64" :fallback="fallback" /> |
70 | - <!-- <Image :style="{ width: `${getWidth}px` }" :src="getImagBase64" /> --> | ||
71 | <div | 72 | <div |
72 | class="w-full text-center truncate p-5" | 73 | class="w-full text-center truncate p-5" |
73 | :style="{ fontSize: fontSize({ radioRecord: getRadio, basic: 12, max: 12 }), color: '#999' }" | 74 | :style="{ fontSize: fontSize({ radioRecord: getRadio, basic: 12, max: 12 }), color: '#999' }" |
74 | > | 75 | > |
75 | - <Tooltip | ||
76 | - placement="top" | ||
77 | - :title=" | ||
78 | - props.value?.updateTime | ||
79 | - ? dateUtil(props?.value?.updateTime).format(DEFAULT_DATE_FORMAT) | ||
80 | - : '暂无更新时间' | ||
81 | - " | ||
82 | - > | 76 | + <Tooltip placement="top" :title="getUpdateTime(props.value?.updateTime)"> |
83 | <span class="mr-1">更新时间:</span> | 77 | <span class="mr-1">更新时间:</span> |
84 | <span class="truncate"> | 78 | <span class="truncate"> |
85 | - {{ | ||
86 | - props.value?.updateTime | ||
87 | - ? dateUtil(props?.value?.updateTime).format(DEFAULT_DATE_FORMAT) | ||
88 | - : '暂无更新时间' | ||
89 | - }} | 79 | + {{ getUpdateTime(props.value?.updateTime) }} |
90 | </span> | 80 | </span> |
91 | </Tooltip> | 81 | </Tooltip> |
92 | </div> | 82 | </div> |
1 | import PictureComponent from './PictureComponent.vue'; | 1 | import PictureComponent from './PictureComponent.vue'; |
2 | 2 | ||
3 | -import { PictureComponentType } from './pictureComponent.config'; | ||
4 | -import { Component } from 'vue'; | ||
5 | - | ||
6 | -interface PictureComponentList { | ||
7 | - id: PictureComponentType; | ||
8 | - component: Component; | ||
9 | -} | ||
10 | -// { | ||
11 | -// id: 'instrument-component-1', | ||
12 | -// layout: { chartOption: instrumentComponent1() }, | ||
13 | -// component: DashBoardComponent, | ||
14 | -// value: { id: buildUUID() }, | ||
15 | -// } | ||
16 | -const pictureComponentList: PictureComponentList[] = [ | ||
17 | - { | ||
18 | - id: 'picture-component-1', | ||
19 | - component: PictureComponent, | ||
20 | - }, | ||
21 | -]; | ||
22 | - | ||
23 | -export { PictureComponent, pictureComponentList }; | 3 | +export { PictureComponent }; |
1 | import { DataComponentRecord, DataSource } from '/@/api/dataBoard/model'; | 1 | import { DataComponentRecord, DataSource } from '/@/api/dataBoard/model'; |
2 | 2 | ||
3 | -export type PictureComponentType = 'picture-component-1'; | ||
4 | - | ||
5 | -export interface PictureComponentLayout {} | ||
6 | - | ||
7 | export interface PictureComponentValue { | 3 | export interface PictureComponentValue { |
8 | value?: string; | 4 | value?: string; |
9 | updateTime?: string; | 5 | updateTime?: string; |
10 | } | 6 | } |
11 | 7 | ||
12 | export const transformPictureConfig = ( | 8 | export const transformPictureConfig = ( |
13 | - config: PictureComponentLayout, | ||
14 | - record: DataComponentRecord, | 9 | + _config: Recordable, |
10 | + _record: DataComponentRecord, | ||
15 | dataSourceRecord: DataSource | 11 | dataSourceRecord: DataSource |
16 | ) => { | 12 | ) => { |
17 | const componentInfo = dataSourceRecord.componentInfo; | 13 | const componentInfo = dataSourceRecord.componentInfo; |
1 | +<script lang="ts"> | ||
2 | + export default { | ||
3 | + inheritAttrs: false, | ||
4 | + }; | ||
5 | +</script> | ||
1 | <script lang="ts" setup> | 6 | <script lang="ts" setup> |
2 | import { computed } from 'vue'; | 7 | import { computed } from 'vue'; |
3 | import { Statistic, Tooltip } from 'ant-design-vue'; | 8 | import { Statistic, Tooltip } from 'ant-design-vue'; |
4 | import { | 9 | import { |
10 | + getUpdateTime, | ||
5 | fontSize, | 11 | fontSize, |
6 | RadioRecord, | 12 | RadioRecord, |
7 | DEFAULT_RADIO_RECORD, | 13 | DEFAULT_RADIO_RECORD, |
8 | - DEFAULT_DATE_FORMAT, | ||
9 | } from '../../detail/config/util'; | 14 | } from '../../detail/config/util'; |
10 | import { TextComponentDefaultConfig, TextComponentLayout, TextComponentValue } from './config'; | 15 | import { TextComponentDefaultConfig, TextComponentLayout, TextComponentValue } from './config'; |
11 | import { SvgIcon } from '/@/components/Icon'; | 16 | import { SvgIcon } from '/@/components/Icon'; |
12 | - import { dateUtil } from '/@/utils/dateUtil'; | ||
13 | const props = defineProps({ | 17 | const props = defineProps({ |
14 | layout: { | 18 | layout: { |
15 | type: Object as PropType<TextComponentLayout>, | 19 | type: Object as PropType<TextComponentLayout>, |
@@ -47,8 +51,6 @@ | @@ -47,8 +51,6 @@ | ||
47 | }); | 51 | }); |
48 | 52 | ||
49 | const getRadio = computed(() => { | 53 | const getRadio = computed(() => { |
50 | - // const { radio } = props.radio; | ||
51 | - // return radio; | ||
52 | return props.radio || DEFAULT_RADIO_RECORD; | 54 | return props.radio || DEFAULT_RADIO_RECORD; |
53 | }); | 55 | }); |
54 | </script> | 56 | </script> |
@@ -84,37 +86,21 @@ | @@ -84,37 +86,21 @@ | ||
84 | /> | 86 | /> |
85 | </div> | 87 | </div> |
86 | <div :style="{ color: '#666', fontSize: fontSize({ radioRecord: getRadio, basic: 16 }) }"> | 88 | <div :style="{ color: '#666', fontSize: fontSize({ radioRecord: getRadio, basic: 16 }) }"> |
87 | - <!-- {{ getShowUnit ? props.value.unit : '' }} --> | ||
88 | {{ props.value.name }} | 89 | {{ props.value.name }} |
89 | </div> | 90 | </div> |
90 | - <!-- <div class="truncate" :style="{ fontSize: fontSize({ radio: getRadio, basic: 16 }) }"> | ||
91 | - {{ props.value.name }} | ||
92 | - </div> --> | ||
93 | </div> | 91 | </div> |
94 | </div> | 92 | </div> |
95 | </div> | 93 | </div> |
96 | 94 | ||
97 | <div class="text-center text-xs truncate p-5" style="color: #999"> | 95 | <div class="text-center text-xs truncate p-5" style="color: #999"> |
98 | - <Tooltip | ||
99 | - v-if="getShowUpdate" | ||
100 | - placement="top" | ||
101 | - :title=" | ||
102 | - props.value?.updateTime | ||
103 | - ? dateUtil(props?.value?.updateTime).format(DEFAULT_DATE_FORMAT) | ||
104 | - : '暂无更新时间' | ||
105 | - " | ||
106 | - > | 96 | + <Tooltip v-if="getShowUpdate" placement="top" :title="getUpdateTime(props.value?.updateTime)"> |
107 | <div | 97 | <div |
108 | :style="{ fontSize: fontSize({ radioRecord: getRadio, basic: 12, max: 12 }) }" | 98 | :style="{ fontSize: fontSize({ radioRecord: getRadio, basic: 12, max: 12 }) }" |
109 | class="truncate" | 99 | class="truncate" |
110 | > | 100 | > |
111 | <span class="mr-1">更新时间:</span> | 101 | <span class="mr-1">更新时间:</span> |
112 | <span class="truncate"> | 102 | <span class="truncate"> |
113 | - {{ | ||
114 | - props.value?.updateTime | ||
115 | - ? dateUtil(props?.value?.updateTime).format(DEFAULT_DATE_FORMAT) | ||
116 | - : '暂无更新时间' | ||
117 | - }} | 103 | + {{ getUpdateTime(props.value?.updateTime) }} |
118 | </span> | 104 | </span> |
119 | </div> | 105 | </div> |
120 | </Tooltip> | 106 | </Tooltip> |
@@ -18,13 +18,6 @@ export interface TextComponentValue { | @@ -18,13 +18,6 @@ export interface TextComponentValue { | ||
18 | deviceName?: string; | 18 | deviceName?: string; |
19 | } | 19 | } |
20 | 20 | ||
21 | -export type TextComponentType = | ||
22 | - | 'text-component-1' | ||
23 | - | 'text-component-2' | ||
24 | - | 'text-component-3' | ||
25 | - | 'text-component-4' | ||
26 | - | 'text-component-5'; | ||
27 | - | ||
28 | type TextComponentDefault = TextComponentLayout; | 21 | type TextComponentDefault = TextComponentLayout; |
29 | 22 | ||
30 | export const TextComponent1Config: TextComponentDefault = { | 23 | export const TextComponent1Config: TextComponentDefault = { |
@@ -32,10 +25,6 @@ export const TextComponent1Config: TextComponentDefault = { | @@ -32,10 +25,6 @@ export const TextComponent1Config: TextComponentDefault = { | ||
32 | base: true, | 25 | base: true, |
33 | }; | 26 | }; |
34 | 27 | ||
35 | -export const TextComponent2Config: TextComponentDefault = { | ||
36 | - id: 'text-component-2', | ||
37 | - base: false, | ||
38 | -}; | ||
39 | export const TextComponent3Config: TextComponentDefault = { | 28 | export const TextComponent3Config: TextComponentDefault = { |
40 | id: 'text-component-3', | 29 | id: 'text-component-3', |
41 | base: false, | 30 | base: false, |
@@ -62,17 +51,9 @@ export const TextComponentDefaultConfig: Partial<ComponentInfo> = { | @@ -62,17 +51,9 @@ export const TextComponentDefaultConfig: Partial<ComponentInfo> = { | ||
62 | icon: 'shuiwen', | 51 | icon: 'shuiwen', |
63 | }; | 52 | }; |
64 | 53 | ||
65 | -export const textComponentConfig: TextComponentDefault[] = [ | ||
66 | - TextComponent1Config, | ||
67 | - // TextComponent2Config, | ||
68 | - TextComponent3Config, | ||
69 | - TextComponent4Config, | ||
70 | - TextComponent5Config, | ||
71 | -]; | ||
72 | - | ||
73 | export const transformTextComponentConfig = ( | 54 | export const transformTextComponentConfig = ( |
74 | config: TextComponentDefault, | 55 | config: TextComponentDefault, |
75 | - record: DataComponentRecord, | 56 | + _record: DataComponentRecord, |
76 | dataSourceRecord: DataSource | 57 | dataSourceRecord: DataSource |
77 | ) => { | 58 | ) => { |
78 | return { | 59 | return { |
@@ -3,8 +3,11 @@ | @@ -3,8 +3,11 @@ | ||
3 | import { DropMenu } from '/@/components/Dropdown'; | 3 | import { DropMenu } from '/@/components/Dropdown'; |
4 | import Dropdown from '/@/components/Dropdown/src/Dropdown.vue'; | 4 | import Dropdown from '/@/components/Dropdown/src/Dropdown.vue'; |
5 | import { Tooltip } from 'ant-design-vue'; | 5 | import { Tooltip } from 'ant-design-vue'; |
6 | - // import SvgIcon from '/@/components/Icon/src/SvgIcon.vue'; | ||
7 | - import { isBataBoardSharePage, MoreActionEvent } from '../../config/config'; | 6 | + import { |
7 | + isBataBoardSharePage, | ||
8 | + MoreActionEvent, | ||
9 | + VisualComponentPermission, | ||
10 | + } from '../../config/config'; | ||
8 | import { computed } from '@vue/reactivity'; | 11 | import { computed } from '@vue/reactivity'; |
9 | import { usePermission } from '/@/hooks/web/usePermission'; | 12 | import { usePermission } from '/@/hooks/web/usePermission'; |
10 | import { DataSource } from '/@/api/dataBoard/model'; | 13 | import { DataSource } from '/@/api/dataBoard/model'; |
@@ -19,9 +22,9 @@ | @@ -19,9 +22,9 @@ | ||
19 | const { hasPermission } = usePermission(); | 22 | const { hasPermission } = usePermission(); |
20 | const dropMenuList = computed<DropMenu[]>(() => { | 23 | const dropMenuList = computed<DropMenu[]>(() => { |
21 | const basicMenu: DropMenu[] = []; | 24 | const basicMenu: DropMenu[] = []; |
22 | - const hasUpdatePermission = hasPermission('api:yt:data_component:update:update'); | ||
23 | - const hasDeletePermission = hasPermission('api:yt:data_component:delete'); | ||
24 | - const hasCopyPermission = hasPermission('api:yt:dataBoardDetail:copy'); | 25 | + const hasUpdatePermission = hasPermission(VisualComponentPermission.UPDATE); |
26 | + const hasDeletePermission = hasPermission(VisualComponentPermission.DELETE); | ||
27 | + const hasCopyPermission = hasPermission(VisualComponentPermission.COPY); | ||
25 | if (hasUpdatePermission) | 28 | if (hasUpdatePermission) |
26 | basicMenu.push({ | 29 | basicMenu.push({ |
27 | text: '编辑组件', | 30 | text: '编辑组件', |
@@ -69,7 +72,6 @@ | @@ -69,7 +72,6 @@ | ||
69 | > | 72 | > |
70 | <Tooltip :title="item.deviceName" placement="topLeft"> | 73 | <Tooltip :title="item.deviceName" placement="topLeft"> |
71 | <div class="flex p-1"> | 74 | <div class="flex p-1"> |
72 | - <!-- <SvgIcon name="" prefix="iconfont" class="!fill-emerald-400" /> --> | ||
73 | <div class="truncate font-bold">{{ item.deviceRename || item.deviceName }}</div> | 75 | <div class="truncate font-bold">{{ item.deviceRename || item.deviceName }}</div> |
74 | </div> | 76 | </div> |
75 | </Tooltip> | 77 | </Tooltip> |
1 | <script lang="ts" setup> | 1 | <script lang="ts" setup> |
2 | - import { useSlots } from 'vue'; | ||
3 | import { useUpdateCenter } from '../../hook/useUpdateCenter'; | 2 | import { useUpdateCenter } from '../../hook/useUpdateCenter'; |
4 | import { FrontDataSourceRecord } from '../../types/type'; | 3 | import { FrontDataSourceRecord } from '../../types/type'; |
5 | - // import type { WidgetWrapperRegister } from './type'; | ||
6 | - // import { DataSource } from '/@/api/dataBoard/model'; | ||
7 | 4 | ||
8 | const props = defineProps<{ | 5 | const props = defineProps<{ |
9 | dataSource: FrontDataSourceRecord[]; | 6 | dataSource: FrontDataSourceRecord[]; |
10 | }>(); | 7 | }>(); |
11 | 8 | ||
12 | - const slot = useSlots(); | ||
13 | - | ||
14 | const { update, add, remove } = useUpdateCenter(); | 9 | const { update, add, remove } = useUpdateCenter(); |
15 | 10 | ||
16 | defineExpose({ update }); | 11 | defineExpose({ update }); |
@@ -20,7 +15,7 @@ | @@ -20,7 +15,7 @@ | ||
20 | <section class="widget"> | 15 | <section class="widget"> |
21 | <slot name="header"></slot> | 16 | <slot name="header"></slot> |
22 | 17 | ||
23 | - <div class="widget-content" :style="{ height: slot.header ? 'calc(100% - 22px)' : '100%' }"> | 18 | + <div class="widget-content"> |
24 | <div | 19 | <div |
25 | v-for="item in props.dataSource" | 20 | v-for="item in props.dataSource" |
26 | :key="item.id" | 21 | :key="item.id" |
@@ -28,10 +23,7 @@ | @@ -28,10 +23,7 @@ | ||
28 | class="widget-item" | 23 | class="widget-item" |
29 | > | 24 | > |
30 | <div class="widget-box"> | 25 | <div class="widget-box"> |
31 | - <div | ||
32 | - class="widget-controls-container" | ||
33 | - :style="{ height: slot.footer ? 'calc(100% - 20px)' : '100%' }" | ||
34 | - > | 26 | + <div class="widget-controls-container"> |
35 | <slot | 27 | <slot |
36 | name="controls" | 28 | name="controls" |
37 | :record="item" | 29 | :record="item" |
@@ -40,12 +32,6 @@ | @@ -40,12 +32,6 @@ | ||
40 | :update="update" | 32 | :update="update" |
41 | ></slot> | 33 | ></slot> |
42 | </div> | 34 | </div> |
43 | - <div class="widget-value"> | ||
44 | - <slot name="value" :record="item"></slot> | ||
45 | - </div> | ||
46 | - <div class="widget-label"> | ||
47 | - <slot name="label" :record="item"></slot> | ||
48 | - </div> | ||
49 | </div> | 35 | </div> |
50 | </div> | 36 | </div> |
51 | </div> | 37 | </div> |
@@ -61,14 +47,14 @@ | @@ -61,14 +47,14 @@ | ||
61 | height: 100%; | 47 | height: 100%; |
62 | background-color: #fff; | 48 | background-color: #fff; |
63 | border-radius: 3px; | 49 | border-radius: 3px; |
64 | - box-shadow: 0px 1px 10px 0px rgba(0, 0, 0, 0.1); | 50 | + box-shadow: 0 1px 10px 0 rgba(0, 0, 0, 0.1); |
65 | } | 51 | } |
52 | + | ||
66 | .widget-content { | 53 | .widget-content { |
67 | display: flex; | 54 | display: flex; |
68 | flex-wrap: wrap; | 55 | flex-wrap: wrap; |
69 | justify-content: center; | 56 | justify-content: center; |
70 | align-items: center; | 57 | align-items: center; |
71 | - | ||
72 | width: 100%; | 58 | width: 100%; |
73 | height: 100%; | 59 | height: 100%; |
74 | } | 60 | } |
@@ -94,7 +80,7 @@ | @@ -94,7 +80,7 @@ | ||
94 | .widget-controls-container { | 80 | .widget-controls-container { |
95 | flex: 1 1 auto; | 81 | flex: 1 1 auto; |
96 | width: 100%; | 82 | width: 100%; |
97 | - height: calc(100% - 20px); | 83 | + height: 100%; |
98 | display: flex; | 84 | display: flex; |
99 | align-items: center; | 85 | align-items: center; |
100 | justify-content: center; | 86 | justify-content: center; |
src/views/visual/board/components/WidgetWrapper/type.ts
deleted
100644 → 0
src/views/visual/board/components/help.ts
0 → 100644
1 | +import { | ||
2 | + TextComponent1Config, | ||
3 | + TextComponent3Config, | ||
4 | + TextComponent4Config, | ||
5 | + TextComponent5Config, | ||
6 | + TextComponentDefaultConfig, | ||
7 | + transformTextComponentConfig, | ||
8 | +} from './TextComponent/config'; | ||
9 | +import { ComponentInfo } from '/@/api/dataBoard/model'; | ||
10 | +import { transformPictureConfig } from './PictureComponent/pictureComponent.config'; | ||
11 | +import { | ||
12 | + DashboardComponentLayout, | ||
13 | + Instrument1DefaultConfig, | ||
14 | + Instrument2DefaultConfig, | ||
15 | + instrumentComponent1, | ||
16 | + instrumentComponent2, | ||
17 | + transformDashboardComponentConfig, | ||
18 | +} from './InstrumentComponent/dashBoardComponent.config'; | ||
19 | +import { DigitalComponentDefaultConfig } from './InstrumentComponent/digitalDashBoard.config'; | ||
20 | +import { transformControlConfig } from './ControlComponent/control.config'; | ||
21 | + | ||
22 | +import TextComponent from './TextComponent/TextComponent.vue'; | ||
23 | +import DashBoardComponent from './InstrumentComponent/DashBoardComponent.vue'; | ||
24 | +import PictureComponent from './PictureComponent/PictureComponent.vue'; | ||
25 | +import DigitalDashBoard from './InstrumentComponent/DigitalDashBoard.vue'; | ||
26 | +import ToggleSwitch from './ControlComponent/ToggleSwitch.vue'; | ||
27 | +import SlidingSwitch from './ControlComponent/SlidingSwitch.vue'; | ||
28 | +import SwitchWithIcon from './ControlComponent/SwitchWithIcon.vue'; | ||
29 | +import MapComponent from './MapComponent/MapComponent.vue'; | ||
30 | +import { transfromMapComponentConfig } from './MapComponent/map.config'; | ||
31 | +import { ComponentConfig } from '../types/type'; | ||
32 | +import { FrontComponent, FrontComponentCategory } from '../const/const'; | ||
33 | + | ||
34 | +export const frontComponentDefaultConfigMap = new Map<FrontComponent, Partial<ComponentInfo>>(); | ||
35 | + | ||
36 | +export const frontComponentMap = new Map<FrontComponent, ComponentConfig>(); | ||
37 | + | ||
38 | +frontComponentMap.set(FrontComponent.TEXT_COMPONENT_1, { | ||
39 | + Component: TextComponent, | ||
40 | + ComponentName: '文本组件1', | ||
41 | + ComponentKey: FrontComponent.TEXT_COMPONENT_1, | ||
42 | + ComponentConfig: TextComponent1Config, | ||
43 | + ComponentCategory: FrontComponentCategory.TEXT, | ||
44 | + transformConfig: transformTextComponentConfig, | ||
45 | +}); | ||
46 | + | ||
47 | +frontComponentMap.set(FrontComponent.TEXT_COMPONENT_3, { | ||
48 | + Component: TextComponent, | ||
49 | + ComponentName: '文本组件2', | ||
50 | + ComponentKey: FrontComponent.TEXT_COMPONENT_3, | ||
51 | + ComponentConfig: TextComponent3Config, | ||
52 | + ComponentCategory: FrontComponentCategory.TEXT, | ||
53 | + transformConfig: transformTextComponentConfig, | ||
54 | +}); | ||
55 | + | ||
56 | +frontComponentMap.set(FrontComponent.TEXT_COMPONENT_4, { | ||
57 | + Component: TextComponent, | ||
58 | + ComponentName: '文本组件3', | ||
59 | + ComponentKey: FrontComponent.TEXT_COMPONENT_4, | ||
60 | + ComponentConfig: TextComponent4Config, | ||
61 | + ComponentCategory: FrontComponentCategory.TEXT, | ||
62 | + transformConfig: transformTextComponentConfig, | ||
63 | +}); | ||
64 | + | ||
65 | +frontComponentMap.set(FrontComponent.TEXT_COMPONENT_5, { | ||
66 | + Component: TextComponent, | ||
67 | + ComponentName: '文本组件4', | ||
68 | + ComponentKey: FrontComponent.TEXT_COMPONENT_5, | ||
69 | + ComponentConfig: TextComponent5Config, | ||
70 | + ComponentCategory: FrontComponentCategory.TEXT, | ||
71 | + transformConfig: transformTextComponentConfig, | ||
72 | +}); | ||
73 | + | ||
74 | +frontComponentMap.set(FrontComponent.INSTRUMENT_COMPONENT_1, { | ||
75 | + Component: DashBoardComponent, | ||
76 | + ComponentName: '仪表盘', | ||
77 | + ComponentKey: FrontComponent.INSTRUMENT_COMPONENT_1, | ||
78 | + ComponentConfig: { | ||
79 | + chartOption: instrumentComponent1(Instrument1DefaultConfig), | ||
80 | + componentType: FrontComponent.INSTRUMENT_COMPONENT_1, | ||
81 | + } as DashboardComponentLayout, | ||
82 | + ComponentCategory: FrontComponentCategory.INSTRUMENT, | ||
83 | + transformConfig: transformDashboardComponentConfig, | ||
84 | +}); | ||
85 | + | ||
86 | +frontComponentMap.set(FrontComponent.INSTRUMENT_COMPONENT_2, { | ||
87 | + Component: DashBoardComponent, | ||
88 | + ComponentName: '阶段仪表盘', | ||
89 | + ComponentKey: FrontComponent.INSTRUMENT_COMPONENT_2, | ||
90 | + ComponentConfig: { | ||
91 | + chartOption: instrumentComponent2(Instrument2DefaultConfig), | ||
92 | + componentType: FrontComponent.INSTRUMENT_COMPONENT_2, | ||
93 | + } as DashboardComponentLayout, | ||
94 | + ComponentCategory: FrontComponentCategory.INSTRUMENT, | ||
95 | + transformConfig: transformDashboardComponentConfig, | ||
96 | +}); | ||
97 | + | ||
98 | +frontComponentMap.set(FrontComponent.DIGITAL_DASHBOARD_COMPONENT, { | ||
99 | + Component: DigitalDashBoard, | ||
100 | + ComponentName: '数字仪表盘', | ||
101 | + ComponentKey: FrontComponent.DIGITAL_DASHBOARD_COMPONENT, | ||
102 | + ComponentCategory: FrontComponentCategory.INSTRUMENT, | ||
103 | + transformConfig: transformDashboardComponentConfig, | ||
104 | +}); | ||
105 | + | ||
106 | +frontComponentMap.set(FrontComponent.PICTURE_COMPONENT_1, { | ||
107 | + Component: PictureComponent, | ||
108 | + ComponentName: '图片组件', | ||
109 | + ComponentKey: FrontComponent.PICTURE_COMPONENT_1, | ||
110 | + ComponentCategory: FrontComponentCategory.PICTURE, | ||
111 | + transformConfig: transformPictureConfig, | ||
112 | +}); | ||
113 | + | ||
114 | +frontComponentMap.set(FrontComponent.CONTROL_COMPONENT_SWITCH_WITH_ICON, { | ||
115 | + Component: SwitchWithIcon, | ||
116 | + ComponentName: '控制按钮1', | ||
117 | + ComponentKey: FrontComponent.CONTROL_COMPONENT_SWITCH_WITH_ICON, | ||
118 | + ComponentCategory: FrontComponentCategory.CONTROL, | ||
119 | + transformConfig: transformControlConfig, | ||
120 | +}); | ||
121 | + | ||
122 | +frontComponentMap.set(FrontComponent.CONTROL_COMPONENT_SLIDING_SWITCH, { | ||
123 | + Component: SlidingSwitch, | ||
124 | + ComponentName: '控制按钮2', | ||
125 | + ComponentKey: FrontComponent.CONTROL_COMPONENT_SLIDING_SWITCH, | ||
126 | + ComponentCategory: FrontComponentCategory.CONTROL, | ||
127 | + transformConfig: transformControlConfig, | ||
128 | +}); | ||
129 | + | ||
130 | +frontComponentMap.set(FrontComponent.CONTROL_COMPONENT_TOGGLE_SWITCH, { | ||
131 | + Component: ToggleSwitch, | ||
132 | + ComponentName: '控制按钮3', | ||
133 | + ComponentKey: FrontComponent.CONTROL_COMPONENT_TOGGLE_SWITCH, | ||
134 | + ComponentCategory: FrontComponentCategory.CONTROL, | ||
135 | + transformConfig: transformControlConfig, | ||
136 | +}); | ||
137 | + | ||
138 | +frontComponentMap.set(FrontComponent.MAP_COMPONENT_TRACK, { | ||
139 | + Component: MapComponent, | ||
140 | + ComponentName: '实时轨迹', | ||
141 | + ComponentKey: FrontComponent.MAP_COMPONENT_TRACK, | ||
142 | + ComponentCategory: FrontComponentCategory.MAP, | ||
143 | + transformConfig: transfromMapComponentConfig, | ||
144 | +}); | ||
145 | + | ||
146 | +frontComponentDefaultConfigMap.set(FrontComponent.TEXT_COMPONENT_1, TextComponentDefaultConfig); | ||
147 | +frontComponentDefaultConfigMap.set(FrontComponent.TEXT_COMPONENT_3, TextComponentDefaultConfig); | ||
148 | +frontComponentDefaultConfigMap.set(FrontComponent.TEXT_COMPONENT_4, TextComponentDefaultConfig); | ||
149 | +frontComponentDefaultConfigMap.set(FrontComponent.TEXT_COMPONENT_5, TextComponentDefaultConfig); | ||
150 | + | ||
151 | +frontComponentDefaultConfigMap.set(FrontComponent.INSTRUMENT_COMPONENT_1, Instrument1DefaultConfig); | ||
152 | +frontComponentDefaultConfigMap.set(FrontComponent.INSTRUMENT_COMPONENT_2, Instrument2DefaultConfig); | ||
153 | + | ||
154 | +frontComponentDefaultConfigMap.set( | ||
155 | + FrontComponent.DIGITAL_DASHBOARD_COMPONENT, | ||
156 | + DigitalComponentDefaultConfig | ||
157 | +); | ||
158 | + | ||
159 | +export const getComponentDefaultConfig = (key: FrontComponent) => { | ||
160 | + return frontComponentDefaultConfigMap.get(key) || {}; | ||
161 | +}; |
src/views/visual/board/config/componentMap.ts
deleted
100644 → 0
@@ -4,7 +4,19 @@ export enum MoreActionEvent { | @@ -4,7 +4,19 @@ export enum MoreActionEvent { | ||
4 | DELETE = 'delete', | 4 | DELETE = 'delete', |
5 | } | 5 | } |
6 | 6 | ||
7 | -// export enum | 7 | +export enum VisualBoardPermission { |
8 | + UPDATE = 'api:yt:data_board:update:update', | ||
9 | + DELETE = 'api:yt:data_board:delete', | ||
10 | + CREATE = '', | ||
11 | + DETAIL = 'api:yt:data_component:list', | ||
12 | +} | ||
13 | + | ||
14 | +export enum VisualComponentPermission { | ||
15 | + UPDATE = 'api:yt:data_component:update:update', | ||
16 | + DELETE = 'api:yt:data_component:delete', | ||
17 | + COPY = 'api:yt:dataBoardDetail:copy', | ||
18 | + CREATE = 'api:yt:data_component:add:post', | ||
19 | +} | ||
8 | 20 | ||
9 | export const DEFAULT_MAX_COL = 24; | 21 | export const DEFAULT_MAX_COL = 24; |
10 | export const DEFAULT_WIDGET_WIDTH = 6; | 22 | export const DEFAULT_WIDGET_WIDTH = 6; |
src/views/visual/board/const/const.ts
0 → 100644
1 | +export enum FrontComponentCategory { | ||
2 | + TEXT = 'text', | ||
3 | + PICTURE = 'picture', | ||
4 | + INSTRUMENT = 'instrument', | ||
5 | + CONTROL = 'control', | ||
6 | + MAP = 'map', | ||
7 | +} | ||
8 | + | ||
9 | +export const FrontComponentCategoryName = { | ||
10 | + [FrontComponentCategory.TEXT]: '文本组件', | ||
11 | + [FrontComponentCategory.INSTRUMENT]: '仪表组件', | ||
12 | + [FrontComponentCategory.CONTROL]: '控制组件', | ||
13 | + [FrontComponentCategory.PICTURE]: '图片组件', | ||
14 | + [FrontComponentCategory.MAP]: '地图组件', | ||
15 | +}; | ||
16 | + | ||
17 | +export enum FrontComponent { | ||
18 | + TEXT_COMPONENT_1 = 'text-component-1', | ||
19 | + TEXT_COMPONENT_2 = 'text-component-2', | ||
20 | + TEXT_COMPONENT_3 = 'text-component-3', | ||
21 | + TEXT_COMPONENT_4 = 'text-component-4', | ||
22 | + TEXT_COMPONENT_5 = 'text-component-5', | ||
23 | + INSTRUMENT_COMPONENT_1 = 'instrument-component-1', | ||
24 | + INSTRUMENT_COMPONENT_2 = 'instrument-component-2', | ||
25 | + DIGITAL_DASHBOARD_COMPONENT = 'digital-dashboard-component', | ||
26 | + PICTURE_COMPONENT_1 = 'picture-component-1', | ||
27 | + CONTROL_COMPONENT_TOGGLE_SWITCH = 'control-component-toggle-switch', | ||
28 | + CONTROL_COMPONENT_SWITCH_WITH_ICON = 'control-component-switch-with-icon', | ||
29 | + CONTROL_COMPONENT_SLIDING_SWITCH = 'control-component-sliding-switch', | ||
30 | + MAP_COMPONENT_TRACK = 'map-component-track', | ||
31 | +} | ||
32 | + | ||
33 | +export enum Gradient { | ||
34 | + FIRST = 'first', | ||
35 | + SECOND = 'second', | ||
36 | + THIRD = 'third', | ||
37 | +} | ||
38 | +export enum GradientColor { | ||
39 | + FIRST = '#67e0e3', | ||
40 | + SECOND = '#37a2da', | ||
41 | + THIRD = '#fd666d', | ||
42 | +} | ||
43 | + | ||
44 | +export enum visualOptionField { | ||
45 | + FONT_COLOR = 'fontColor', | ||
46 | + UNIT = 'unit', | ||
47 | + ICON_COLOR = 'iconColor', | ||
48 | + ICON = 'icon', | ||
49 | + FIRST_PHASE_COLOR = 'firstPhaseColor', | ||
50 | + SECOND_PHASE_COLOR = 'secondPhaseColor', | ||
51 | + THIRD_PHASE_COLOR = 'thirdPhaseColor', | ||
52 | + FIRST_PHASE_VALUE = 'firstPhaseValue', | ||
53 | + SECOND_PHASE_VALUE = 'secondPhaseValue', | ||
54 | + THIRD_PHASE_VALUE = 'thirdPhaseValue', | ||
55 | +} |
@@ -2,17 +2,17 @@ | @@ -2,17 +2,17 @@ | ||
2 | import { CopyOutlined, DeleteOutlined, SettingOutlined } from '@ant-design/icons-vue'; | 2 | import { CopyOutlined, DeleteOutlined, SettingOutlined } from '@ant-design/icons-vue'; |
3 | import { Tooltip, Button } from 'ant-design-vue'; | 3 | import { Tooltip, Button } from 'ant-design-vue'; |
4 | import { FormActionType, useForm } from '/@/components/Form'; | 4 | import { FormActionType, useForm } from '/@/components/Form'; |
5 | - import { basicSchema, dataSourceSchema } from '../config/basicConfiguration'; | 5 | + import { basicSchema } from '../config/basicConfiguration'; |
6 | import BasicForm from '/@/components/Form/src/BasicForm.vue'; | 6 | import BasicForm from '/@/components/Form/src/BasicForm.vue'; |
7 | - import { ref, shallowReactive, unref, nextTick, watch } from 'vue'; | 7 | + import { ref, shallowReactive, unref, nextTick, watch, computed } from 'vue'; |
8 | import VisualOptionsModal from './VisualOptionsModal.vue'; | 8 | import VisualOptionsModal from './VisualOptionsModal.vue'; |
9 | import { useModal } from '/@/components/Modal'; | 9 | import { useModal } from '/@/components/Modal'; |
10 | import { buildUUID } from '/@/utils/uuid'; | 10 | import { buildUUID } from '/@/utils/uuid'; |
11 | import type { ComponentInfo, DataSource } from '/@/api/dataBoard/model'; | 11 | import type { ComponentInfo, DataSource } from '/@/api/dataBoard/model'; |
12 | import { useMessage } from '/@/hooks/web/useMessage'; | 12 | import { useMessage } from '/@/hooks/web/useMessage'; |
13 | import { DataBoardLayoutInfo } from '../../types/type'; | 13 | import { DataBoardLayoutInfo } from '../../types/type'; |
14 | - import { FrontComponent } from '../config/help'; | ||
15 | - import { computed } from '@vue/reactivity'; | 14 | + import { getDataSourceComponent } from './DataSourceForm/help'; |
15 | + import { FrontComponent } from '../../const/const'; | ||
16 | 16 | ||
17 | type DataSourceFormEL = { [key: string]: Nullable<FormActionType> }; | 17 | type DataSourceFormEL = { [key: string]: Nullable<FormActionType> }; |
18 | 18 | ||
@@ -20,7 +20,7 @@ | @@ -20,7 +20,7 @@ | ||
20 | 20 | ||
21 | const props = defineProps<{ | 21 | const props = defineProps<{ |
22 | record: DataBoardLayoutInfo; | 22 | record: DataBoardLayoutInfo; |
23 | - frontId?: string; | 23 | + frontId?: FrontComponent; |
24 | defaultConfig?: Partial<ComponentInfo>; | 24 | defaultConfig?: Partial<ComponentInfo>; |
25 | }>(); | 25 | }>(); |
26 | 26 | ||
@@ -39,7 +39,7 @@ | @@ -39,7 +39,7 @@ | ||
39 | const dataSourceEl = shallowReactive<DataSourceFormEL>({} as unknown as DataSourceFormEL); | 39 | const dataSourceEl = shallowReactive<DataSourceFormEL>({} as unknown as DataSourceFormEL); |
40 | 40 | ||
41 | const setFormEl = (el: any, id: string) => { | 41 | const setFormEl = (el: any, id: string) => { |
42 | - if (!dataSourceEl[id] && el) { | 42 | + if (id && el) { |
43 | const { formActionType } = el as unknown as { formActionType: FormActionType }; | 43 | const { formActionType } = el as unknown as { formActionType: FormActionType }; |
44 | dataSourceEl[id] = formActionType; | 44 | dataSourceEl[id] = formActionType; |
45 | } | 45 | } |
@@ -112,8 +112,6 @@ | @@ -112,8 +112,6 @@ | ||
112 | return; | 112 | return; |
113 | } | 113 | } |
114 | 114 | ||
115 | - // const defaultConfig = getComponentDefaultConfig(props.frontId as WidgetComponentType); | ||
116 | - | ||
117 | const componentInfo: ComponentInfo = { | 115 | const componentInfo: ComponentInfo = { |
118 | ...(props.defaultConfig || {}), | 116 | ...(props.defaultConfig || {}), |
119 | ...(item.componentInfo || {}), | 117 | ...(item.componentInfo || {}), |
@@ -177,6 +175,10 @@ | @@ -177,6 +175,10 @@ | ||
177 | ~index && (unref(dataSource)[index].componentInfo = value); | 175 | ~index && (unref(dataSource)[index].componentInfo = value); |
178 | }; | 176 | }; |
179 | 177 | ||
178 | + const dataSourceComponent = computed(() => { | ||
179 | + return getDataSourceComponent(props.frontId as FrontComponent); | ||
180 | + }); | ||
181 | + | ||
180 | defineExpose({ | 182 | defineExpose({ |
181 | getAllDataSourceFieldValue, | 183 | getAllDataSourceFieldValue, |
182 | validate, | 184 | validate, |
@@ -198,17 +200,8 @@ | @@ -198,17 +200,8 @@ | ||
198 | 选择设备 | 200 | 选择设备 |
199 | </div> | 201 | </div> |
200 | <div class="pl-2 flex-auto"> | 202 | <div class="pl-2 flex-auto"> |
201 | - <BasicForm | ||
202 | - :ref="(el) => setFormEl(el, item.id)" | ||
203 | - :schemas="dataSourceSchema" | ||
204 | - class="w-full flex-1 data-source-form" | ||
205 | - :show-action-button-group="false" | ||
206 | - :row-props="{ | ||
207 | - gutter: 10, | ||
208 | - }" | ||
209 | - layout="inline" | ||
210 | - :label-col="{ span: 0 }" | ||
211 | - /> | 203 | + <!-- <BasicDataSourceForm /> --> |
204 | + <component :is="dataSourceComponent" :ref="(el) => setFormEl(el, item.id)" /> | ||
212 | </div> | 205 | </div> |
213 | <div class="flex justify-center gap-3 w-24"> | 206 | <div class="flex justify-center gap-3 w-24"> |
214 | <Tooltip title="复制"> | 207 | <Tooltip title="复制"> |
@@ -12,7 +12,7 @@ | @@ -12,7 +12,7 @@ | ||
12 | import { decode } from '../../config/config'; | 12 | import { decode } from '../../config/config'; |
13 | import { ComponentInfo } from '/@/api/dataBoard/model'; | 13 | import { ComponentInfo } from '/@/api/dataBoard/model'; |
14 | import { useCalcGridLayout } from '../../hook/useCalcGridLayout'; | 14 | import { useCalcGridLayout } from '../../hook/useCalcGridLayout'; |
15 | - import { FrontComponent } from '../config/help'; | 15 | + import { FrontComponent } from '../../const/const'; |
16 | 16 | ||
17 | interface DataComponentRouteParams extends RouteParams { | 17 | interface DataComponentRouteParams extends RouteParams { |
18 | id: string; | 18 | id: string; |
@@ -23,9 +23,9 @@ | @@ -23,9 +23,9 @@ | ||
23 | }>(); | 23 | }>(); |
24 | 24 | ||
25 | const emit = defineEmits(['update', 'create', 'register']); | 25 | const emit = defineEmits(['update', 'create', 'register']); |
26 | - | ||
27 | const ROUTE = useRoute(); | 26 | const ROUTE = useRoute(); |
28 | 27 | ||
28 | + const loading = ref(false); | ||
29 | const { createMessage } = useMessage(); | 29 | const { createMessage } = useMessage(); |
30 | 30 | ||
31 | const boardId = computed(() => { | 31 | const boardId = computed(() => { |
@@ -62,11 +62,15 @@ | @@ -62,11 +62,15 @@ | ||
62 | }; | 62 | }; |
63 | 63 | ||
64 | const handleSubmit = async () => { | 64 | const handleSubmit = async () => { |
65 | - const { getAllDataSourceFieldValue, validate } = unref(basicConfigurationEl)!; | ||
66 | - await validate(); | ||
67 | - const value = getAllDataSourceFieldValue(); | ||
68 | - unref(isEdit) ? handleUpdateComponent(value) : handleAddComponent(value); | ||
69 | - resetForm(); | 65 | + try { |
66 | + const { getAllDataSourceFieldValue, validate } = unref(basicConfigurationEl)!; | ||
67 | + await validate(); | ||
68 | + const value = getAllDataSourceFieldValue(); | ||
69 | + unref(isEdit) ? handleUpdateComponent(value) : handleAddComponent(value); | ||
70 | + resetForm(); | ||
71 | + } catch (error: unknown) { | ||
72 | + window.console.error(error); | ||
73 | + } | ||
70 | }; | 74 | }; |
71 | 75 | ||
72 | const { calcLayoutInfo } = useCalcGridLayout(); | 76 | const { calcLayoutInfo } = useCalcGridLayout(); |
@@ -78,6 +82,7 @@ | @@ -78,6 +82,7 @@ | ||
78 | } | 82 | } |
79 | const layout = calcLayoutInfo(unref(props.layout)); | 83 | const layout = calcLayoutInfo(unref(props.layout)); |
80 | changeOkLoading(true); | 84 | changeOkLoading(true); |
85 | + loading.value = true; | ||
81 | await addDataComponent({ | 86 | await addDataComponent({ |
82 | boardId: unref(boardId), | 87 | boardId: unref(boardId), |
83 | record: { dataBoardId: unref(boardId), frontId: unref(frontId), ...value, layout }, | 88 | record: { dataBoardId: unref(boardId), frontId: unref(frontId), ...value, layout }, |
@@ -90,12 +95,14 @@ | @@ -90,12 +95,14 @@ | ||
90 | // createMessage.error('创建失败'); | 95 | // createMessage.error('创建失败'); |
91 | } finally { | 96 | } finally { |
92 | changeOkLoading(false); | 97 | changeOkLoading(false); |
98 | + loading.value = false; | ||
93 | } | 99 | } |
94 | }; | 100 | }; |
95 | 101 | ||
96 | const handleUpdateComponent = async (value: Recordable) => { | 102 | const handleUpdateComponent = async (value: Recordable) => { |
97 | try { | 103 | try { |
98 | changeOkLoading(true); | 104 | changeOkLoading(true); |
105 | + loading.value = true; | ||
99 | const res = await updateDataComponent({ | 106 | const res = await updateDataComponent({ |
100 | boardId: unref(boardId), | 107 | boardId: unref(boardId), |
101 | record: { | 108 | record: { |
@@ -113,6 +120,7 @@ | @@ -113,6 +120,7 @@ | ||
113 | // createMessage.error('修改失败'); | 120 | // createMessage.error('修改失败'); |
114 | } finally { | 121 | } finally { |
115 | changeOkLoading(false); | 122 | changeOkLoading(false); |
123 | + loading.value = false; | ||
116 | } | 124 | } |
117 | }; | 125 | }; |
118 | 126 | ||
@@ -130,10 +138,11 @@ | @@ -130,10 +138,11 @@ | ||
130 | :destroy-on-close="true" | 138 | :destroy-on-close="true" |
131 | @ok="handleSubmit" | 139 | @ok="handleSubmit" |
132 | @cancel="resetForm" | 140 | @cancel="resetForm" |
141 | + :ok-button-props="{ loading }" | ||
133 | > | 142 | > |
134 | <section> | 143 | <section> |
135 | <Tabs type="card"> | 144 | <Tabs type="card"> |
136 | - <Tabs.TabPane key="1" tab="基础配置"> | 145 | + <Tabs.TabPane key="basicConfig" tab="基础配置"> |
137 | <BasicConfiguration | 146 | <BasicConfiguration |
138 | ref="basicConfigurationEl" | 147 | ref="basicConfigurationEl" |
139 | :front-id="frontId" | 148 | :front-id="frontId" |
@@ -141,7 +150,7 @@ | @@ -141,7 +150,7 @@ | ||
141 | :defaultConfig="componentDefaultConfig" | 150 | :defaultConfig="componentDefaultConfig" |
142 | /> | 151 | /> |
143 | </Tabs.TabPane> | 152 | </Tabs.TabPane> |
144 | - <Tabs.TabPane key="2" tab="可视化配置"> | 153 | + <Tabs.TabPane key="visualConfig" tab="可视化配置"> |
145 | <VisualConfiguration v-model:value="frontId" @change="handleComponentCheckedChange" /> | 154 | <VisualConfiguration v-model:value="frontId" @change="handleComponentCheckedChange" /> |
146 | </Tabs.TabPane> | 155 | </Tabs.TabPane> |
147 | </Tabs> | 156 | </Tabs> |
1 | +<script lang="ts" setup> | ||
2 | + import { ref } from 'vue'; | ||
3 | + import { dataSourceSchema } from '../../config/basicConfiguration'; | ||
4 | + import { FormActionType } from '/@/components/Form'; | ||
5 | + import BasicForm from '/@/components/Form/src/BasicForm.vue'; | ||
6 | + const formEl = ref<Nullable<FormActionType>>(null); | ||
7 | + | ||
8 | + defineExpose({ formActionType: formEl }); | ||
9 | +</script> | ||
10 | + | ||
11 | +<template> | ||
12 | + <BasicForm | ||
13 | + ref="formEl" | ||
14 | + :schemas="dataSourceSchema" | ||
15 | + class="w-full flex-1 data-source-form" | ||
16 | + :show-action-button-group="false" | ||
17 | + :row-props="{ | ||
18 | + gutter: 10, | ||
19 | + }" | ||
20 | + layout="inline" | ||
21 | + :label-col="{ span: 0 }" | ||
22 | + /> | ||
23 | +</template> |
1 | +<script lang="ts" setup> | ||
2 | + import { ref, unref } from 'vue'; | ||
3 | + import { BasicForm, FormActionType } from '/@/components/Form'; | ||
4 | + import { controlFormSchema } from '../../config/basicConfiguration'; | ||
5 | + | ||
6 | + const formEl = ref<Nullable<FormActionType>>(); | ||
7 | + | ||
8 | + const setFormEl = (el: any) => { | ||
9 | + formEl.value = el; | ||
10 | + }; | ||
11 | + | ||
12 | + const getFieldsValue = () => { | ||
13 | + return unref(formEl)!.getFieldsValue(); | ||
14 | + }; | ||
15 | + | ||
16 | + const validate = async () => { | ||
17 | + await unref(formEl)!.validate(); | ||
18 | + }; | ||
19 | + | ||
20 | + const setFieldsValue = async (record: Recordable) => { | ||
21 | + await unref(formEl)!.setFieldsValue(record); | ||
22 | + }; | ||
23 | + | ||
24 | + const clearValidate = async (name?: string | string[]) => { | ||
25 | + await unref(formEl)!.clearValidate(name); | ||
26 | + }; | ||
27 | + defineExpose({ | ||
28 | + formActionType: { getFieldsValue, validate, setFieldsValue, clearValidate }, | ||
29 | + }); | ||
30 | +</script> | ||
31 | + | ||
32 | +<template> | ||
33 | + <div class="w-full flex-1"> | ||
34 | + <BasicForm | ||
35 | + :ref="(el) => setFormEl(el)" | ||
36 | + :schemas="controlFormSchema" | ||
37 | + class="w-full flex-1 data-source-form" | ||
38 | + :show-action-button-group="false" | ||
39 | + :row-props="{ | ||
40 | + gutter: 10, | ||
41 | + }" | ||
42 | + layout="inline" | ||
43 | + :label-col="{ span: 0 }" | ||
44 | + /> | ||
45 | + </div> | ||
46 | +</template> |
1 | +import { Component } from 'vue'; | ||
2 | +import { FrontComponent } from '../../../const/const'; | ||
3 | +import BasicDataSourceForm from './BasicDataSourceForm.vue'; | ||
4 | +import ControlDataSourceForm from './ControlDataSourceForm.vue'; | ||
5 | + | ||
6 | +const dataSourceComponentMap = new Map<FrontComponent, Component>(); | ||
7 | + | ||
8 | +dataSourceComponentMap.set(FrontComponent.CONTROL_COMPONENT_TOGGLE_SWITCH, ControlDataSourceForm); | ||
9 | + | ||
10 | +export const getDataSourceComponent = (frontId: FrontComponent) => { | ||
11 | + if (dataSourceComponentMap.has(frontId)) return dataSourceComponentMap.get(frontId)!; | ||
12 | + return BasicDataSourceForm; | ||
13 | +}; |
1 | <script lang="ts" setup> | 1 | <script lang="ts" setup> |
2 | import { Tabs, List } from 'ant-design-vue'; | 2 | import { Tabs, List } from 'ant-design-vue'; |
3 | import VisualWidgetSelect from './VisualWidgetSelect.vue'; | 3 | import VisualWidgetSelect from './VisualWidgetSelect.vue'; |
4 | - import TextComponent from '../../components/TextComponent/TextComponent.vue'; | ||
5 | - import { textComponentConfig } from '../../components/TextComponent/config'; | ||
6 | - import { instrumentComponentConfig } from '../../components/InstrumentComponent'; | ||
7 | - import { pictureComponentList } from '../../components/PictureComponent'; | ||
8 | - import { getComponentDefaultConfig } from '../config/help'; | ||
9 | - import { WidgetComponentType } from '../config/visualOptions'; | 4 | + import { getComponentDefaultConfig } from '../../components/help'; |
5 | + import { frontComponentMap } from '../../components/help'; | ||
6 | + import { computed } from 'vue'; | ||
7 | + import { | ||
8 | + FrontComponent, | ||
9 | + FrontComponentCategory, | ||
10 | + FrontComponentCategoryName, | ||
11 | + } from '../../const/const'; | ||
12 | + | ||
13 | + interface DataSource { | ||
14 | + category: string; | ||
15 | + categoryName: string; | ||
16 | + list: Recordable[]; | ||
17 | + } | ||
10 | const props = defineProps<{ | 18 | const props = defineProps<{ |
11 | value: string; | 19 | value: string; |
12 | }>(); | 20 | }>(); |
@@ -14,7 +22,25 @@ | @@ -14,7 +22,25 @@ | ||
14 | 22 | ||
15 | const grid = { gutter: 10, column: 1, xs: 1, sm: 2, md: 2, lg: 3, xl: 3, xxl: 4 }; | 23 | const grid = { gutter: 10, column: 1, xs: 1, sm: 2, md: 2, lg: 3, xl: 3, xxl: 4 }; |
16 | 24 | ||
17 | - const handleCheck = (checked: WidgetComponentType) => { | 25 | + const getDataSource = computed(() => { |
26 | + const _dataSource = Array.from(frontComponentMap.values()); | ||
27 | + const category = new Map<FrontComponentCategory, DataSource>(); | ||
28 | + for (const item of _dataSource) { | ||
29 | + if (category.has(item.ComponentCategory)) { | ||
30 | + const value = category.get(item.ComponentCategory)!; | ||
31 | + value.list.push(item); | ||
32 | + continue; | ||
33 | + } | ||
34 | + category.set(item.ComponentCategory, { | ||
35 | + category: item.ComponentCategory, | ||
36 | + categoryName: FrontComponentCategoryName[item.ComponentCategory], | ||
37 | + list: [item], | ||
38 | + }); | ||
39 | + } | ||
40 | + return Array.from(category.values()); | ||
41 | + }); | ||
42 | + | ||
43 | + const handleCheck = (checked: FrontComponent) => { | ||
18 | const defaultConfig = getComponentDefaultConfig(checked); | 44 | const defaultConfig = getComponentDefaultConfig(checked); |
19 | emit('update:value', checked); | 45 | emit('update:value', checked); |
20 | emit('change', defaultConfig); | 46 | emit('change', defaultConfig); |
@@ -24,51 +50,25 @@ | @@ -24,51 +50,25 @@ | ||
24 | <template> | 50 | <template> |
25 | <section> | 51 | <section> |
26 | <Tabs> | 52 | <Tabs> |
27 | - <Tabs.TabPane key="1" tab="文本组件"> | ||
28 | - <List :grid="grid" :data-source="textComponentConfig"> | ||
29 | - <template #renderItem="{ item }"> | ||
30 | - <List.Item class="!flex !justify-center"> | ||
31 | - <VisualWidgetSelect | ||
32 | - :checked-id="props.value" | ||
33 | - :control-id="item.id" | ||
34 | - @change="handleCheck" | ||
35 | - > | ||
36 | - <TextComponent :layout="item" :value="item.value" /> | ||
37 | - </VisualWidgetSelect> | ||
38 | - </List.Item> | ||
39 | - </template> | ||
40 | - </List> | ||
41 | - </Tabs.TabPane> | ||
42 | - <Tabs.TabPane key="2" tab="图片组件"> | ||
43 | - <List :grid="grid" :data-source="pictureComponentList"> | ||
44 | - <template #renderItem="{ item }"> | ||
45 | - <List.Item class="!flex !justify-center"> | ||
46 | - <VisualWidgetSelect | ||
47 | - :checked-id="props.value" | ||
48 | - :control-id="item.id" | ||
49 | - @change="handleCheck" | ||
50 | - > | ||
51 | - <component :is="item.component" /> | ||
52 | - </VisualWidgetSelect> | ||
53 | - </List.Item> | ||
54 | - </template> | ||
55 | - </List> | ||
56 | - </Tabs.TabPane> | ||
57 | - <Tabs.TabPane key="3" tab="仪表组件"> | ||
58 | - <List :grid="grid" :data-source="instrumentComponentConfig"> | 53 | + <Tabs.TabPane |
54 | + v-for="category in getDataSource" | ||
55 | + :key="category.category" | ||
56 | + :tab="category.categoryName" | ||
57 | + > | ||
58 | + <List :grid="grid" :data-source="category.list"> | ||
59 | <template #renderItem="{ item }"> | 59 | <template #renderItem="{ item }"> |
60 | <List.Item class="!flex !justify-center"> | 60 | <List.Item class="!flex !justify-center"> |
61 | <VisualWidgetSelect | 61 | <VisualWidgetSelect |
62 | :checked-id="props.value" | 62 | :checked-id="props.value" |
63 | - :control-id="item.id" | 63 | + :control-id="item.ComponentKey" |
64 | @change="handleCheck" | 64 | @change="handleCheck" |
65 | > | 65 | > |
66 | - <component | ||
67 | - :is="item.component" | ||
68 | - :random="true" | ||
69 | - :layout="item.layout" | ||
70 | - :value="item.value" | ||
71 | - /> | 66 | + <template #default> |
67 | + <component :is="item.Component" :random="true" :layout="item.ComponentConfig" /> | ||
68 | + </template> | ||
69 | + <template #description> | ||
70 | + {{ item.ComponentName || '选择' }} | ||
71 | + </template> | ||
72 | </VisualWidgetSelect> | 72 | </VisualWidgetSelect> |
73 | </List.Item> | 73 | </List.Item> |
74 | </template> | 74 | </template> |
1 | <script lang="ts" setup> | 1 | <script lang="ts" setup> |
2 | import { ref, unref } from 'vue'; | 2 | import { ref, unref } from 'vue'; |
3 | - import { | ||
4 | - WidgetComponentType, | ||
5 | - schemasMap, | ||
6 | - VisualOptionParams, | ||
7 | - visualOptionField, | ||
8 | - Gradient, | ||
9 | - } from '../config/visualOptions'; | 3 | + import { schemasMap, VisualOptionParams } from '../config/visualOptions'; |
10 | import { useForm, BasicForm } from '/@/components/Form'; | 4 | import { useForm, BasicForm } from '/@/components/Form'; |
11 | import { BasicModal, useModalInner } from '/@/components/Modal'; | 5 | import { BasicModal, useModalInner } from '/@/components/Modal'; |
12 | import { ComponentInfo } from '/@/api/dataBoard/model'; | 6 | import { ComponentInfo } from '/@/api/dataBoard/model'; |
13 | import { computed } from '@vue/reactivity'; | 7 | import { computed } from '@vue/reactivity'; |
8 | + import { FrontComponent, Gradient, visualOptionField } from '../../const/const'; | ||
14 | 9 | ||
15 | const emit = defineEmits(['close', 'register']); | 10 | const emit = defineEmits(['close', 'register']); |
16 | 11 | ||
@@ -21,7 +16,7 @@ | @@ -21,7 +16,7 @@ | ||
21 | const recordId = ref(''); | 16 | const recordId = ref(''); |
22 | 17 | ||
23 | const getSchemas = computed(() => { | 18 | const getSchemas = computed(() => { |
24 | - return schemasMap.get((props.value as WidgetComponentType) || 'text-component-1'); | 19 | + return schemasMap.get((props.value as FrontComponent) || 'text-component-1'); |
25 | }); | 20 | }); |
26 | 21 | ||
27 | const [registerForm, method] = useForm({ | 22 | const [registerForm, method] = useForm({ |
@@ -30,16 +30,19 @@ | @@ -30,16 +30,19 @@ | ||
30 | <slot></slot> | 30 | <slot></slot> |
31 | </div> | 31 | </div> |
32 | <Card.Meta> | 32 | <Card.Meta> |
33 | - <template #description> 选择 </template> | 33 | + <template #description> |
34 | + <slot name="description"></slot> | ||
35 | + </template> | ||
34 | </Card.Meta> | 36 | </Card.Meta> |
35 | </Card> | 37 | </Card> |
36 | </template> | 38 | </template> |
37 | 39 | ||
38 | <style scoped> | 40 | <style scoped> |
39 | .widget-select { | 41 | .widget-select { |
40 | - box-shadow: 0px 1px 10px 0px rgba(0, 0, 0, 0.1); | 42 | + box-shadow: 0 1px 10px 0 rgba(0, 0, 0, 0.1); |
41 | border-width: 2px; | 43 | border-width: 2px; |
42 | } | 44 | } |
45 | + | ||
43 | .widget-select:deep(.ant-card-body) { | 46 | .widget-select:deep(.ant-card-body) { |
44 | /* height: 240px; */ | 47 | /* height: 240px; */ |
45 | width: 240px; | 48 | width: 240px; |
@@ -217,3 +217,24 @@ export const dataSourceSchema: FormSchema[] = [ | @@ -217,3 +217,24 @@ export const dataSourceSchema: FormSchema[] = [ | ||
217 | }, | 217 | }, |
218 | }, | 218 | }, |
219 | ]; | 219 | ]; |
220 | + | ||
221 | +export const controlFormSchema: FormSchema[] = [ | ||
222 | + { | ||
223 | + field: DataSourceField.DEVICE_RENAME, | ||
224 | + component: 'Input', | ||
225 | + label: '设备', | ||
226 | + colProps: { span: 8 }, | ||
227 | + componentProps: { | ||
228 | + placeholder: '设备重命名', | ||
229 | + }, | ||
230 | + }, | ||
231 | + { | ||
232 | + field: DataSourceField.ATTRIBUTE_RENAME, | ||
233 | + component: 'Input', | ||
234 | + label: '属性', | ||
235 | + colProps: { span: 8 }, | ||
236 | + componentProps: { | ||
237 | + placeholder: '属性重命名', | ||
238 | + }, | ||
239 | + }, | ||
240 | +]; |
src/views/visual/board/detail/config/help.ts
deleted
100644 → 0
1 | -import { Component } from 'vue'; | ||
2 | -import TextComponent from '../../components/TextComponent/TextComponent.vue'; | ||
3 | -import { | ||
4 | - TextComponent1Config, | ||
5 | - TextComponent2Config, | ||
6 | - TextComponent3Config, | ||
7 | - TextComponent4Config, | ||
8 | - TextComponent5Config, | ||
9 | - TextComponentDefaultConfig, | ||
10 | - transformTextComponentConfig, | ||
11 | -} from '../../components/TextComponent/config'; | ||
12 | -import { ComponentInfo, DataComponentRecord, DataSource } from '/@/api/dataBoard/model'; | ||
13 | -import DashBoardComponent from '../../components/InstrumentComponent/DashBoardComponent.vue'; | ||
14 | -import PictureComponent from '../../components/PictureComponent/PictureComponent.vue'; | ||
15 | -import { transformPictureConfig } from '../../components/PictureComponent/pictureComponent.config'; | ||
16 | -import { WidgetComponentType } from './visualOptions'; | ||
17 | -import { | ||
18 | - DashboardComponentLayout, | ||
19 | - Instrument1DefaultConfig, | ||
20 | - Instrument2DefaultConfig, | ||
21 | - instrumentComponent1, | ||
22 | - instrumentComponent2, | ||
23 | - transformDashboardComponentConfig, | ||
24 | -} from '../../components/InstrumentComponent/dashBoardComponent.config'; | ||
25 | -import DigitalDashBoard from '../../components/InstrumentComponent/DigitalDashBoard.vue'; | ||
26 | -import { DigitalComponentDefaultConfig } from '../../components/InstrumentComponent/digitalDashBoard.config'; | ||
27 | -export enum FrontComponent { | ||
28 | - TEXT_COMPONENT_1 = 'text-component-1', | ||
29 | - TEXT_COMPONENT_2 = 'text-component-2', | ||
30 | - TEXT_COMPONENT_3 = 'text-component-3', | ||
31 | - TEXT_COMPONENT_4 = 'text-component-4', | ||
32 | - TEXT_COMPONENT_5 = 'text-component-5', | ||
33 | - INSTRUMENT_COMPONENT_1 = 'instrument-component-1', | ||
34 | - INSTRUMENT_COMPONENT_2 = 'instrument-component-2', | ||
35 | - DIGITAL_DASHBOARD_COMPONENT = 'digital-dashboard-component', | ||
36 | - PICTURE_COMPONENT_1 = 'picture-component-1', | ||
37 | -} | ||
38 | - | ||
39 | -export interface ComponentConfig { | ||
40 | - Component: Component; | ||
41 | - ComponentConfig: Recordable; | ||
42 | - transformConfig: ( | ||
43 | - ComponentConfig: Recordable, | ||
44 | - record: DataComponentRecord, | ||
45 | - dataSourceRecord: DataSource | ||
46 | - ) => Recordable; | ||
47 | -} | ||
48 | - | ||
49 | -export const frontComponentDefaultConfigMap = new Map< | ||
50 | - WidgetComponentType, | ||
51 | - Partial<ComponentInfo> | ||
52 | ->(); | ||
53 | - | ||
54 | -export const frontComponentMap = new Map<WidgetComponentType, ComponentConfig>(); | ||
55 | - | ||
56 | -frontComponentMap.set(FrontComponent.TEXT_COMPONENT_1, { | ||
57 | - Component: TextComponent, | ||
58 | - ComponentConfig: TextComponent1Config, | ||
59 | - transformConfig: transformTextComponentConfig, | ||
60 | -}); | ||
61 | - | ||
62 | -frontComponentMap.set(FrontComponent.TEXT_COMPONENT_2, { | ||
63 | - Component: TextComponent, | ||
64 | - ComponentConfig: TextComponent2Config, | ||
65 | - transformConfig: transformTextComponentConfig, | ||
66 | -}); | ||
67 | - | ||
68 | -frontComponentMap.set(FrontComponent.TEXT_COMPONENT_3, { | ||
69 | - Component: TextComponent, | ||
70 | - ComponentConfig: TextComponent3Config, | ||
71 | - transformConfig: transformTextComponentConfig, | ||
72 | -}); | ||
73 | - | ||
74 | -frontComponentMap.set(FrontComponent.TEXT_COMPONENT_4, { | ||
75 | - Component: TextComponent, | ||
76 | - ComponentConfig: TextComponent4Config, | ||
77 | - transformConfig: transformTextComponentConfig, | ||
78 | -}); | ||
79 | - | ||
80 | -frontComponentMap.set(FrontComponent.TEXT_COMPONENT_5, { | ||
81 | - Component: TextComponent, | ||
82 | - ComponentConfig: TextComponent5Config, | ||
83 | - transformConfig: transformTextComponentConfig, | ||
84 | -}); | ||
85 | - | ||
86 | -frontComponentMap.set(FrontComponent.INSTRUMENT_COMPONENT_1, { | ||
87 | - Component: DashBoardComponent, | ||
88 | - ComponentConfig: { | ||
89 | - chartOption: instrumentComponent1(), | ||
90 | - componentType: FrontComponent.INSTRUMENT_COMPONENT_1, | ||
91 | - } as DashboardComponentLayout, | ||
92 | - transformConfig: transformDashboardComponentConfig, | ||
93 | -}); | ||
94 | - | ||
95 | -frontComponentMap.set(FrontComponent.INSTRUMENT_COMPONENT_2, { | ||
96 | - Component: DashBoardComponent, | ||
97 | - ComponentConfig: { | ||
98 | - chartOption: instrumentComponent2(), | ||
99 | - componentType: FrontComponent.INSTRUMENT_COMPONENT_2, | ||
100 | - } as DashboardComponentLayout, | ||
101 | - transformConfig: transformDashboardComponentConfig, | ||
102 | -}); | ||
103 | - | ||
104 | -frontComponentMap.set(FrontComponent.DIGITAL_DASHBOARD_COMPONENT, { | ||
105 | - Component: DigitalDashBoard, | ||
106 | - ComponentConfig: {}, | ||
107 | - transformConfig: transformDashboardComponentConfig, | ||
108 | -}); | ||
109 | - | ||
110 | -frontComponentMap.set(FrontComponent.PICTURE_COMPONENT_1, { | ||
111 | - Component: PictureComponent, | ||
112 | - ComponentConfig: {}, | ||
113 | - transformConfig: transformPictureConfig, | ||
114 | -}); | ||
115 | - | ||
116 | -frontComponentDefaultConfigMap.set(FrontComponent.TEXT_COMPONENT_1, TextComponentDefaultConfig); | ||
117 | -frontComponentDefaultConfigMap.set(FrontComponent.TEXT_COMPONENT_2, TextComponentDefaultConfig); | ||
118 | -frontComponentDefaultConfigMap.set(FrontComponent.TEXT_COMPONENT_3, TextComponentDefaultConfig); | ||
119 | -frontComponentDefaultConfigMap.set(FrontComponent.TEXT_COMPONENT_4, TextComponentDefaultConfig); | ||
120 | -frontComponentDefaultConfigMap.set(FrontComponent.TEXT_COMPONENT_5, TextComponentDefaultConfig); | ||
121 | - | ||
122 | -frontComponentDefaultConfigMap.set(FrontComponent.INSTRUMENT_COMPONENT_1, Instrument1DefaultConfig); | ||
123 | -frontComponentDefaultConfigMap.set(FrontComponent.INSTRUMENT_COMPONENT_2, Instrument2DefaultConfig); | ||
124 | - | ||
125 | -frontComponentDefaultConfigMap.set( | ||
126 | - FrontComponent.DIGITAL_DASHBOARD_COMPONENT, | ||
127 | - DigitalComponentDefaultConfig | ||
128 | -); | ||
129 | - | ||
130 | -export const getComponentDefaultConfig = (key: WidgetComponentType) => { | ||
131 | - return frontComponentDefaultConfigMap.get(key) || {}; | ||
132 | -}; |
1 | +import { dateUtil } from '/@/utils/dateUtil'; | ||
2 | + | ||
1 | export interface RadioRecord { | 3 | export interface RadioRecord { |
2 | width: number; | 4 | width: number; |
3 | height: number; | 5 | height: number; |
@@ -16,6 +18,10 @@ export const DEFAULT_RADIO_RECORD: RadioRecord = { | @@ -16,6 +18,10 @@ export const DEFAULT_RADIO_RECORD: RadioRecord = { | ||
16 | 18 | ||
17 | export const DEFAULT_DATE_FORMAT = 'YYYY-MM-DD HH:mm:ss'; | 19 | export const DEFAULT_DATE_FORMAT = 'YYYY-MM-DD HH:mm:ss'; |
18 | 20 | ||
21 | +export const getUpdateTime = (updateTime?: string) => { | ||
22 | + return updateTime ? dateUtil(updateTime).format(DEFAULT_DATE_FORMAT) : '暂无更新时间'; | ||
23 | +}; | ||
24 | + | ||
19 | export const calcScale = ( | 25 | export const calcScale = ( |
20 | width: number, | 26 | width: number, |
21 | height: number, | 27 | height: number, |
1 | -import { InstrumentComponentType } from '../../components/InstrumentComponent/dashBoardComponent.config'; | ||
2 | -import { DigitalDashBoardComponentType } from '../../components/InstrumentComponent/digitalDashBoard.config'; | ||
3 | -import { PictureComponentType } from '../../components/PictureComponent/pictureComponent.config'; | ||
4 | -import { TextComponentType } from '../../components/TextComponent/config'; | 1 | +import { FrontComponent, GradientColor } from '../../const/const'; |
5 | import { FormSchema } from '/@/components/Form'; | 2 | import { FormSchema } from '/@/components/Form'; |
6 | 3 | ||
7 | -export type WidgetComponentType = | ||
8 | - | TextComponentType | ||
9 | - | InstrumentComponentType | ||
10 | - | DigitalDashBoardComponentType | ||
11 | - | PictureComponentType; | ||
12 | - | ||
13 | export interface VisualOptionParams { | 4 | export interface VisualOptionParams { |
14 | [visualOptionField.FONT_COLOR]: string; | 5 | [visualOptionField.FONT_COLOR]: string; |
15 | [visualOptionField.UNIT]: string; | 6 | [visualOptionField.UNIT]: string; |
@@ -23,17 +14,6 @@ export interface VisualOptionParams { | @@ -23,17 +14,6 @@ export interface VisualOptionParams { | ||
23 | [visualOptionField.THIRD_PHASE_VALUE]: string; | 14 | [visualOptionField.THIRD_PHASE_VALUE]: string; |
24 | } | 15 | } |
25 | 16 | ||
26 | -export enum Gradient { | ||
27 | - FIRST = 'first', | ||
28 | - SECOND = 'second', | ||
29 | - THIRD = 'third', | ||
30 | -} | ||
31 | -export enum GradientColor { | ||
32 | - FIRST = '#67e0e3', | ||
33 | - SECOND = '#37a2da', | ||
34 | - THIRD = '#fd666d', | ||
35 | -} | ||
36 | - | ||
37 | export enum visualOptionField { | 17 | export enum visualOptionField { |
38 | FONT_COLOR = 'fontColor', | 18 | FONT_COLOR = 'fontColor', |
39 | UNIT = 'unit', | 19 | UNIT = 'unit', |
@@ -198,13 +178,13 @@ export const modeFour: FormSchema[] = [ | @@ -198,13 +178,13 @@ export const modeFour: FormSchema[] = [ | ||
198 | }, | 178 | }, |
199 | ]; | 179 | ]; |
200 | 180 | ||
201 | -export const schemasMap = new Map<WidgetComponentType, FormSchema[]>(); | 181 | +export const schemasMap = new Map<FrontComponent, FormSchema[]>(); |
202 | 182 | ||
203 | -schemasMap.set('text-component-1', modeOne); | ||
204 | -schemasMap.set('text-component-2', modeOne); | ||
205 | -schemasMap.set('text-component-3', modeOne); | ||
206 | -schemasMap.set('text-component-4', modeTwo); | ||
207 | -schemasMap.set('text-component-5', modeTwo); | ||
208 | -schemasMap.set('instrument-component-1', modeOne); | ||
209 | -schemasMap.set('instrument-component-2', modeThree); | ||
210 | -schemasMap.set('digital-dashboard-component', modeFour); | 183 | +schemasMap.set(FrontComponent.TEXT_COMPONENT_1, modeOne); |
184 | +schemasMap.set(FrontComponent.TEXT_COMPONENT_2, modeOne); | ||
185 | +schemasMap.set(FrontComponent.TEXT_COMPONENT_3, modeOne); | ||
186 | +schemasMap.set(FrontComponent.TEXT_COMPONENT_4, modeTwo); | ||
187 | +schemasMap.set(FrontComponent.TEXT_COMPONENT_5, modeTwo); | ||
188 | +schemasMap.set(FrontComponent.INSTRUMENT_COMPONENT_1, modeOne); | ||
189 | +schemasMap.set(FrontComponent.INSTRUMENT_COMPONENT_2, modeThree); | ||
190 | +schemasMap.set(FrontComponent.DIGITAL_DASHBOARD_COMPONENT, modeFour); |
@@ -16,6 +16,7 @@ | @@ -16,6 +16,7 @@ | ||
16 | DEFAULT_WIDGET_WIDTH, | 16 | DEFAULT_WIDGET_WIDTH, |
17 | isBataBoardSharePage, | 17 | isBataBoardSharePage, |
18 | MoreActionEvent, | 18 | MoreActionEvent, |
19 | + VisualComponentPermission, | ||
19 | } from '../config/config'; | 20 | } from '../config/config'; |
20 | import { | 21 | import { |
21 | addDataComponent, | 22 | addDataComponent, |
@@ -32,11 +33,10 @@ | @@ -32,11 +33,10 @@ | ||
32 | DataSource, | 33 | DataSource, |
33 | Layout, | 34 | Layout, |
34 | } from '/@/api/dataBoard/model'; | 35 | } from '/@/api/dataBoard/model'; |
35 | - import { frontComponentMap } from './config/help'; | 36 | + import { frontComponentMap } from '../components/help'; |
36 | import { calcScale } from './config/util'; | 37 | import { calcScale } from './config/util'; |
37 | import { useMessage } from '/@/hooks/web/useMessage'; | 38 | import { useMessage } from '/@/hooks/web/useMessage'; |
38 | import { DataBoardLayoutInfo } from '../types/type'; | 39 | import { DataBoardLayoutInfo } from '../types/type'; |
39 | - import { WidgetComponentType } from './config/visualOptions'; | ||
40 | import Authority from '/@/components/Authority/src/Authority.vue'; | 40 | import Authority from '/@/components/Authority/src/Authority.vue'; |
41 | import { useSocketConnect } from '../hook/useSocketConnect'; | 41 | import { useSocketConnect } from '../hook/useSocketConnect'; |
42 | import { buildUUID } from '/@/utils/uuid'; | 42 | import { buildUUID } from '/@/utils/uuid'; |
@@ -44,6 +44,7 @@ | @@ -44,6 +44,7 @@ | ||
44 | import trendIcon from '/@/assets/svg/trend.svg'; | 44 | import trendIcon from '/@/assets/svg/trend.svg'; |
45 | import backIcon from '/@/assets/images/back.png'; | 45 | import backIcon from '/@/assets/images/back.png'; |
46 | import { useCalcGridLayout } from '../hook/useCalcGridLayout'; | 46 | import { useCalcGridLayout } from '../hook/useCalcGridLayout'; |
47 | + import { FrontComponent } from '../const/const'; | ||
47 | 48 | ||
48 | const ROUTE = useRoute(); | 49 | const ROUTE = useRoute(); |
49 | 50 | ||
@@ -298,7 +299,7 @@ | @@ -298,7 +299,7 @@ | ||
298 | 299 | ||
299 | const getComponent = (record: DataComponentRecord) => { | 300 | const getComponent = (record: DataComponentRecord) => { |
300 | const frontComponent = record.frontId; | 301 | const frontComponent = record.frontId; |
301 | - const component = frontComponentMap.get(frontComponent as WidgetComponentType); | 302 | + const component = frontComponentMap.get(frontComponent as FrontComponent); |
302 | return component?.Component; | 303 | return component?.Component; |
303 | }; | 304 | }; |
304 | 305 | ||
@@ -307,8 +308,8 @@ | @@ -307,8 +308,8 @@ | ||
307 | dataSourceRecord: DataSource | 308 | dataSourceRecord: DataSource |
308 | ) => { | 309 | ) => { |
309 | const frontComponent = record.frontId; | 310 | const frontComponent = record.frontId; |
310 | - const component = frontComponentMap.get(frontComponent as WidgetComponentType); | ||
311 | - return component?.transformConfig(component.ComponentConfig, record, dataSourceRecord); | 311 | + const component = frontComponentMap.get(frontComponent as FrontComponent); |
312 | + return component?.transformConfig(component.ComponentConfig || {}, record, dataSourceRecord); | ||
312 | }; | 313 | }; |
313 | 314 | ||
314 | const handleUpdate = async (id: string) => { | 315 | const handleUpdate = async (id: string) => { |
@@ -360,9 +361,7 @@ | @@ -360,9 +361,7 @@ | ||
360 | await deleteDataComponent({ dataBoardId, ids: [id] }); | 361 | await deleteDataComponent({ dataBoardId, ids: [id] }); |
361 | createMessage.success('删除成功'); | 362 | createMessage.success('删除成功'); |
362 | await getDataBoardComponent(); | 363 | await getDataBoardComponent(); |
363 | - } catch (error) { | ||
364 | - // createMessage.error('删除失败'); | ||
365 | - } | 364 | + } catch (error) {} |
366 | }; | 365 | }; |
367 | 366 | ||
368 | const [registerHistoryDataModal, historyDataModalMethod] = useModal(); | 367 | const [registerHistoryDataModal, historyDataModalMethod] = useModal(); |
@@ -391,7 +390,7 @@ | @@ -391,7 +390,7 @@ | ||
391 | </div> | 390 | </div> |
392 | </template> | 391 | </template> |
393 | <template #extra> | 392 | <template #extra> |
394 | - <Authority value="api:yt:data_component:add:post"> | 393 | + <Authority :value="VisualComponentPermission.CREATE"> |
395 | <Button v-if="!getIsSharePage" type="primary" @click="handleOpenCreatePanel"> | 394 | <Button v-if="!getIsSharePage" type="primary" @click="handleOpenCreatePanel"> |
396 | 创建组件 | 395 | 创建组件 |
397 | </Button> | 396 | </Button> |
@@ -439,7 +438,6 @@ | @@ -439,7 +438,6 @@ | ||
439 | :data-source="item.record.dataSource" | 438 | :data-source="item.record.dataSource" |
440 | > | 439 | > |
441 | <template #header> | 440 | <template #header> |
442 | - <!-- <div>header</div> --> | ||
443 | <BaseWidgetHeader | 441 | <BaseWidgetHeader |
444 | :record="item.record.dataSource" | 442 | :record="item.record.dataSource" |
445 | :id="item.record.id" | 443 | :id="item.record.id" |
@@ -448,11 +446,6 @@ | @@ -448,11 +446,6 @@ | ||
448 | > | 446 | > |
449 | <template #moreAction> | 447 | <template #moreAction> |
450 | <Tooltip title="趋势"> | 448 | <Tooltip title="趋势"> |
451 | - <!-- <LineChartOutlined | ||
452 | - v-if="!getIsSharePage" | ||
453 | - class="cursor-pointer mx-1" | ||
454 | - @click="handleOpenHistroyDataModal(item.record.dataSource)" | ||
455 | - /> --> | ||
456 | <img | 449 | <img |
457 | :src="trendIcon" | 450 | :src="trendIcon" |
458 | v-if="!getIsSharePage" | 451 | v-if="!getIsSharePage" |
@@ -494,14 +487,18 @@ | @@ -494,14 +487,18 @@ | ||
494 | .vue-grid-item:not(.vue-grid-placeholder) { | 487 | .vue-grid-item:not(.vue-grid-placeholder) { |
495 | background: #fff; | 488 | background: #fff; |
496 | border: none !important; | 489 | border: none !important; |
490 | + | ||
497 | /* border: 1px solid black; */ | 491 | /* border: 1px solid black; */ |
498 | } | 492 | } |
493 | + | ||
499 | .vue-grid-item .resizing { | 494 | .vue-grid-item .resizing { |
500 | opacity: 0.9; | 495 | opacity: 0.9; |
501 | } | 496 | } |
497 | + | ||
502 | .vue-grid-item .static { | 498 | .vue-grid-item .static { |
503 | background: #cce; | 499 | background: #cce; |
504 | } | 500 | } |
501 | + | ||
505 | .vue-grid-item .text { | 502 | .vue-grid-item .text { |
506 | font-size: 24px; | 503 | font-size: 24px; |
507 | text-align: center; | 504 | text-align: center; |
@@ -514,16 +511,20 @@ | @@ -514,16 +511,20 @@ | ||
514 | height: 100%; | 511 | height: 100%; |
515 | width: 100%; | 512 | width: 100%; |
516 | } | 513 | } |
514 | + | ||
517 | .vue-grid-item .no-drag { | 515 | .vue-grid-item .no-drag { |
518 | height: 100%; | 516 | height: 100%; |
519 | width: 100%; | 517 | width: 100%; |
520 | } | 518 | } |
519 | + | ||
521 | .vue-grid-item .minMax { | 520 | .vue-grid-item .minMax { |
522 | font-size: 12px; | 521 | font-size: 12px; |
523 | } | 522 | } |
523 | + | ||
524 | .vue-grid-item .add { | 524 | .vue-grid-item .add { |
525 | cursor: pointer; | 525 | cursor: pointer; |
526 | } | 526 | } |
527 | + | ||
527 | .vue-draggable-handle { | 528 | .vue-draggable-handle { |
528 | position: absolute; | 529 | position: absolute; |
529 | width: 20px; | 530 | width: 20px; |
@@ -540,12 +541,6 @@ | @@ -540,12 +541,6 @@ | ||
540 | cursor: pointer; | 541 | cursor: pointer; |
541 | } | 542 | } |
542 | 543 | ||
543 | - // .container { | ||
544 | - // display: grid; | ||
545 | - // grid-template-columns: 3; | ||
546 | - // grid-row: 3; | ||
547 | - // } | ||
548 | - | ||
549 | .grid-item-layout { | 544 | .grid-item-layout { |
550 | overflow: hidden; | 545 | overflow: hidden; |
551 | border: 1px solid #eee !important; | 546 | border: 1px solid #eee !important; |
@@ -8,6 +8,10 @@ interface GapRecord { | @@ -8,6 +8,10 @@ interface GapRecord { | ||
8 | endIndex: Nullable<number>; | 8 | endIndex: Nullable<number>; |
9 | } | 9 | } |
10 | 10 | ||
11 | +/** | ||
12 | + * @description calculate where to place the component | ||
13 | + * @returns | ||
14 | + */ | ||
11 | export function useCalcGridLayout() { | 15 | export function useCalcGridLayout() { |
12 | const calcLayoutInfo = ( | 16 | const calcLayoutInfo = ( |
13 | layoutInfo: Layout[], | 17 | layoutInfo: Layout[], |
@@ -7,7 +7,7 @@ | @@ -7,7 +7,7 @@ | ||
7 | import { useMessage } from '/@/hooks/web/useMessage'; | 7 | import { useMessage } from '/@/hooks/web/useMessage'; |
8 | import Dropdown from '/@/components/Dropdown/src/Dropdown.vue'; | 8 | import Dropdown from '/@/components/Dropdown/src/Dropdown.vue'; |
9 | import { DropMenu } from '/@/components/Dropdown'; | 9 | import { DropMenu } from '/@/components/Dropdown'; |
10 | - import { DATA_BOARD_SHARE_URL, MoreActionEvent } from './config/config'; | 10 | + import { DATA_BOARD_SHARE_URL, MoreActionEvent, VisualBoardPermission } from './config/config'; |
11 | import { useModal } from '/@/components/Modal'; | 11 | import { useModal } from '/@/components/Modal'; |
12 | import PanelDetailModal from './components/PanelDetailModal.vue'; | 12 | import PanelDetailModal from './components/PanelDetailModal.vue'; |
13 | import { getDataBoardList, deleteDataBoard } from '/@/api/dataBoard'; | 13 | import { getDataBoardList, deleteDataBoard } from '/@/api/dataBoard'; |
@@ -36,7 +36,7 @@ | @@ -36,7 +36,7 @@ | ||
36 | labelWidth: 80, | 36 | labelWidth: 80, |
37 | layout: 'inline', | 37 | layout: 'inline', |
38 | submitButtonOptions: { | 38 | submitButtonOptions: { |
39 | - loading: loading, | 39 | + loading: loading as unknown as boolean, |
40 | }, | 40 | }, |
41 | submitFunc: async () => { | 41 | submitFunc: async () => { |
42 | try { | 42 | try { |
@@ -51,7 +51,7 @@ | @@ -51,7 +51,7 @@ | ||
51 | }, | 51 | }, |
52 | }); | 52 | }); |
53 | 53 | ||
54 | - //分页相关 | 54 | + // about pagination |
55 | const page = ref(1); | 55 | const page = ref(1); |
56 | const pageSize = ref(10); | 56 | const pageSize = ref(10); |
57 | const total = ref(0); | 57 | const total = ref(0); |
@@ -90,8 +90,8 @@ | @@ -90,8 +90,8 @@ | ||
90 | 90 | ||
91 | const { hasPermission } = usePermission(); | 91 | const { hasPermission } = usePermission(); |
92 | const dropMenuList = computed<DropMenu[]>(() => { | 92 | const dropMenuList = computed<DropMenu[]>(() => { |
93 | - const hasUpdatePermission = hasPermission('api:yt:data_board:update:update'); | ||
94 | - const hasDeletePermission = hasPermission('api:yt:data_board:delete'); | 93 | + const hasUpdatePermission = hasPermission(VisualBoardPermission.UPDATE); |
94 | + const hasDeletePermission = hasPermission(VisualBoardPermission.DELETE); | ||
95 | const basicMenu: DropMenu[] = []; | 95 | const basicMenu: DropMenu[] = []; |
96 | if (hasUpdatePermission) | 96 | if (hasUpdatePermission) |
97 | basicMenu.push({ | 97 | basicMenu.push({ |
@@ -147,31 +147,21 @@ | @@ -147,31 +147,21 @@ | ||
147 | }; | 147 | }; |
148 | 148 | ||
149 | const handleRemove = async (record: DataBoardRecord) => { | 149 | const handleRemove = async (record: DataBoardRecord) => { |
150 | - // TODO 删除确认 | ||
151 | try { | 150 | try { |
152 | await deleteDataBoard([record.id]); | 151 | await deleteDataBoard([record.id]); |
153 | createMessage.success('删除成功'); | 152 | createMessage.success('删除成功'); |
154 | await getDatasource(); | 153 | await getDatasource(); |
155 | - } catch (error) { | ||
156 | - // createMessage.error('删除失败'); | ||
157 | - } | 154 | + } catch (error) {} |
158 | }; | 155 | }; |
159 | 156 | ||
160 | const [registerModal, { openModal }] = useModal(); | 157 | const [registerModal, { openModal }] = useModal(); |
161 | 158 | ||
162 | const handleViewBoard = (record: DataBoardRecord) => { | 159 | const handleViewBoard = (record: DataBoardRecord) => { |
163 | - const hasDetailPermission = hasPermission('api:yt:data_component:list'); | 160 | + const hasDetailPermission = hasPermission(VisualBoardPermission.DETAIL); |
164 | if (hasDetailPermission) { | 161 | if (hasDetailPermission) { |
165 | const boardId = encode(record.id); | 162 | const boardId = encode(record.id); |
166 | const boardName = encode(record.name); | 163 | const boardName = encode(record.name); |
167 | router.push(`/visual/board/detail/${boardId}/${boardName}`); | 164 | router.push(`/visual/board/detail/${boardId}/${boardName}`); |
168 | - // router.push({ | ||
169 | - // name: 'visualBoardDetail' | ||
170 | - // params: { | ||
171 | - // boardId: encode(record.id), | ||
172 | - // boardName: encode(record.name), | ||
173 | - // }, | ||
174 | - // }); | ||
175 | } else createMessage.warning('没有权限'); | 165 | } else createMessage.warning('没有权限'); |
176 | }; | 166 | }; |
177 | 167 | ||
@@ -186,8 +176,6 @@ | @@ -186,8 +176,6 @@ | ||
186 | '.ant-spin-container' | 176 | '.ant-spin-container' |
187 | ) as HTMLElement; | 177 | ) as HTMLElement; |
188 | listContainerEl && | 178 | listContainerEl && |
189 | - // (listContainerEl.style.minHeight = listContainerHeight + 'px') && | ||
190 | - // (listContainerEl.style.maxHeight = listContainerHeight + 'px') && | ||
191 | (listContainerEl.style.height = listContainerHeight + 'px') && | 179 | (listContainerEl.style.height = listContainerHeight + 'px') && |
192 | (listContainerEl.style.overflowY = 'auto') && | 180 | (listContainerEl.style.overflowY = 'auto') && |
193 | (listContainerEl.style.overflowX = 'hidden'); | 181 | (listContainerEl.style.overflowX = 'hidden'); |
@@ -210,7 +198,6 @@ | @@ -210,7 +198,6 @@ | ||
210 | <div class="bg-light-100 mb-6 w-full p-3 search-form"> | 198 | <div class="bg-light-100 mb-6 w-full p-3 search-form"> |
211 | <BasicForm class="flex-auto w-full" @register="searchFormRegister" /> | 199 | <BasicForm class="flex-auto w-full" @register="searchFormRegister" /> |
212 | </div> | 200 | </div> |
213 | - <!-- <div> </div> --> | ||
214 | <Spin :spinning="loading"> | 201 | <Spin :spinning="loading"> |
215 | <List | 202 | <List |
216 | ref="listEL" | 203 | ref="listEL" |
@@ -235,7 +222,6 @@ | @@ -235,7 +222,6 @@ | ||
235 | <MoreOutlined class="rotate-90 transform cursor-pointer" /> | 222 | <MoreOutlined class="rotate-90 transform cursor-pointer" /> |
236 | </Dropdown> | 223 | </Dropdown> |
237 | </template> | 224 | </template> |
238 | - <!-- <template #cover>title</template> --> | ||
239 | <section @click="handleViewBoard(item)"> | 225 | <section @click="handleViewBoard(item)"> |
240 | <div class="flex data-card__info"> | 226 | <div class="flex data-card__info"> |
241 | <div> | 227 | <div> |
@@ -247,16 +233,19 @@ | @@ -247,16 +233,19 @@ | ||
247 | </Statistic> | 233 | </Statistic> |
248 | </div> | 234 | </div> |
249 | </div> | 235 | </div> |
250 | - <div class="flex justify-between mt-4 text-sm" style="color: #999999"> | 236 | + <div class="flex justify-between mt-4 text-sm" style="color: #999"> |
251 | <div> | 237 | <div> |
252 | <span> | 238 | <span> |
253 | {{ item.viewType === ViewType.PRIVATE_VIEW ? '私有看板' : '公共看板' }} | 239 | {{ item.viewType === ViewType.PRIVATE_VIEW ? '私有看板' : '公共看板' }} |
254 | </span> | 240 | </span> |
255 | - <!-- <span v-if="item.viewType === ViewType.PUBLIC_VIEW"> | 241 | + <span |
242 | + style="display: none" | ||
243 | + v-if="item.viewType === ViewType.PUBLIC_VIEW && false" | ||
244 | + > | ||
256 | <Tooltip title="点击复制分享链接"> | 245 | <Tooltip title="点击复制分享链接"> |
257 | <ShareAltOutlined class="ml-2" @click.stop="handleCopyShareUrl(item)" /> | 246 | <ShareAltOutlined class="ml-2" @click.stop="handleCopyShareUrl(item)" /> |
258 | </Tooltip> | 247 | </Tooltip> |
259 | - </span> --> | 248 | + </span> |
260 | </div> | 249 | </div> |
261 | <div>{{ item.createTime }}</div> | 250 | <div>{{ item.createTime }}</div> |
262 | </div> | 251 | </div> |
@@ -278,15 +267,17 @@ | @@ -278,15 +267,17 @@ | ||
278 | .data-card:deep(.ant-card-head-title) { | 267 | .data-card:deep(.ant-card-head-title) { |
279 | padding: 0; | 268 | padding: 0; |
280 | } | 269 | } |
270 | + | ||
281 | .data-card:deep(.ant-card-extra) { | 271 | .data-card:deep(.ant-card-extra) { |
282 | padding: 0; | 272 | padding: 0; |
283 | } | 273 | } |
274 | + | ||
284 | .data-card:deep(.ant-card-body) { | 275 | .data-card:deep(.ant-card-body) { |
285 | padding: 20px; | 276 | padding: 20px; |
286 | } | 277 | } |
287 | 278 | ||
288 | .data-card__info { | 279 | .data-card__info { |
289 | - color: #666666; | 280 | + color: #666; |
290 | 281 | ||
291 | &::before { | 282 | &::before { |
292 | content: ''; | 283 | content: ''; |
@@ -299,8 +290,10 @@ | @@ -299,8 +290,10 @@ | ||
299 | 290 | ||
300 | .search-form { | 291 | .search-form { |
301 | width: 100%; | 292 | width: 100%; |
293 | + | ||
302 | form { | 294 | form { |
303 | width: 100%; | 295 | width: 100%; |
296 | + | ||
304 | :deep(.ant-row) { | 297 | :deep(.ant-row) { |
305 | width: 100%; | 298 | width: 100%; |
306 | } | 299 | } |
1 | +import { Component } from 'vue'; | ||
1 | import { Layout } from 'vue3-grid-layout'; | 2 | import { Layout } from 'vue3-grid-layout'; |
3 | +import { FrontComponent, FrontComponentCategory, visualOptionField } from '../const/const'; | ||
4 | +import { RadioRecord } from '../detail/config/util'; | ||
2 | import { DataComponentRecord, DataSource } from '/@/api/dataBoard/model'; | 5 | import { DataComponentRecord, DataSource } from '/@/api/dataBoard/model'; |
3 | 6 | ||
4 | export type FrontDataSourceRecord = DataSource; | 7 | export type FrontDataSourceRecord = DataSource; |
@@ -8,3 +11,39 @@ export type DataBoardLayoutInfo = Layout & { | @@ -8,3 +11,39 @@ export type DataBoardLayoutInfo = Layout & { | ||
8 | width?: number; | 11 | width?: number; |
9 | height?: number; | 12 | height?: number; |
10 | }; | 13 | }; |
14 | + | ||
15 | +export interface ComponentConfig { | ||
16 | + Component: Component; | ||
17 | + ComponentName?: string; | ||
18 | + ComponentKey: FrontComponent; | ||
19 | + ComponentConfig?: Recordable; | ||
20 | + ComponentCategory: FrontComponentCategory; | ||
21 | + transformConfig: ( | ||
22 | + componentConfig: Recordable, | ||
23 | + record: DataComponentRecord, | ||
24 | + dataSourceRecord: DataSource | ||
25 | + ) => Recordable; | ||
26 | +} | ||
27 | + | ||
28 | +export interface VisualOptionParams { | ||
29 | + [visualOptionField.FONT_COLOR]: string; | ||
30 | + [visualOptionField.UNIT]: string; | ||
31 | + [visualOptionField.ICON_COLOR]: string; | ||
32 | + [visualOptionField.ICON]: string; | ||
33 | + [visualOptionField.FIRST_PHASE_COLOR]: string; | ||
34 | + [visualOptionField.SECOND_PHASE_COLOR]: string; | ||
35 | + [visualOptionField.THIRD_PHASE_COLOR]: string; | ||
36 | + [visualOptionField.FIRST_PHASE_VALUE]: string; | ||
37 | + [visualOptionField.SECOND_PHASE_VALUE]: string; | ||
38 | + [visualOptionField.THIRD_PHASE_VALUE]: string; | ||
39 | +} | ||
40 | + | ||
41 | +export interface VisualComponentProps<Layout = Recordable, Value = Recordable> { | ||
42 | + value?: Value; | ||
43 | + layout?: Layout; | ||
44 | + radio?: RadioRecord; | ||
45 | + random?: boolean; | ||
46 | + add?: (key: string, method: Fn) => void; | ||
47 | + update?: () => void; | ||
48 | + remove?: (key: string) => void; | ||
49 | +} |