Commit 7f2df5aab5a3302d7e3557344776f22d1fb03ed8

Authored by xp.Huang
2 parents 7498544c e42fbe00

Merge branch 'dev-fix-ww' into 'main_dev'

fix: 修复teabmition BUG

See merge request yunteng/thingskit-front!562
@@ -51,6 +51,7 @@ export interface DeviceModel { @@ -51,6 +51,7 @@ export interface DeviceModel {
51 organizationId: string; 51 organizationId: string;
52 customerId?: string; 52 customerId?: string;
53 alias?: string; 53 alias?: string;
  54 + tbDeviceId?: string;
54 } 55 }
55 56
56 export interface DeviceProfileModel { 57 export interface DeviceProfileModel {
@@ -81,11 +81,8 @@ export const genModbusCommand = (data: GenModbusCommandType) => { @@ -81,11 +81,8 @@ export const genModbusCommand = (data: GenModbusCommandType) => {
81 }; 81 };
82 82
83 export const immediateExecute = (data: ImmediateExecuteTaskType) => { 83 export const immediateExecute = (data: ImmediateExecuteTaskType) => {
84 - return defHttp.post<Record<'data', boolean>>(  
85 - {  
86 - url: Api.IMMEDIATE_EXECUTE,  
87 - params: data,  
88 - },  
89 - { joinParamsToUrl: true }  
90 - ); 84 + return defHttp.post<Record<'data', boolean>>({
  85 + url: Api.IMMEDIATE_EXECUTE,
  86 + params: data,
  87 + });
91 }; 88 };
@@ -108,7 +108,7 @@ @@ -108,7 +108,7 @@
108 </script> 108 </script>
109 109
110 <template> 110 <template>
111 - <div class="p-2 bg-gray-200" :style="{ height: `${height - 16}px` }"> 111 + <div class="p-2 bg-gray-200" :style="{ height: `${height}px` }">
112 <div ref="jsonEditorElRef" class="jsoneditor"></div> 112 <div ref="jsonEditorElRef" class="jsoneditor"></div>
113 </div> 113 </div>
114 </template> 114 </template>
@@ -119,6 +119,11 @@ @@ -119,6 +119,11 @@
119 119
120 :deep(.jsoneditor) { 120 :deep(.jsoneditor) {
121 border: none !important; 121 border: none !important;
  122 +
  123 + .ace-jsoneditor,
  124 + textarea.jsoneditor-text {
  125 + min-height: auto;
  126 + }
122 } 127 }
123 } 128 }
124 </style> 129 </style>
@@ -133,6 +133,7 @@ @@ -133,6 +133,7 @@
133 } = props.schema; 133 } = props.schema;
134 134
135 if (isFunction(dynamicRules)) { 135 if (isFunction(dynamicRules)) {
  136 + console.log(dynamicRules(unref(getValues)));
136 return dynamicRules(unref(getValues)) as ValidationRule[]; 137 return dynamicRules(unref(getValues)) as ValidationRule[];
137 } 138 }
138 139
@@ -279,7 +279,6 @@ @@ -279,7 +279,6 @@
279 setSelectedOptions, 279 setSelectedOptions,
280 setSelectedTotal, 280 setSelectedTotal,
281 reloadPending, 281 reloadPending,
282 - reloadPending,  
283 reloadSelected, 282 reloadSelected,
284 }; 283 };
285 284
@@ -408,7 +407,7 @@ @@ -408,7 +407,7 @@
408 :key="item.value" 407 :key="item.value"
409 > 408 >
410 <span> 409 <span>
411 - {{ item.alias + '/' + item.name }} 410 + {{ item.alias || item.name }}
412 </span> 411 </span>
413 </Tag> 412 </Tag>
414 <Tag class="!px-2 !py-1 !bg-gray-50 !border-gray-100" v-if="getSurplusOptionsLength"> 413 <Tag class="!px-2 !py-1 !bg-gray-50 !border-gray-100" v-if="getSurplusOptionsLength">
1 import { BasicColumn, FormSchema } from '/@/components/Table'; 1 import { BasicColumn, FormSchema } from '/@/components/Table';
2 -import { getOrganizationList } from '/@/api/system/system';  
3 -import { copyTransFun } from '/@/utils/fnUtils';  
4 import { findDictItemByCode } from '/@/api/system/dict'; 2 import { findDictItemByCode } from '/@/api/system/dict';
5 - 3 +import { useComponentRegister } from '/@/components/Form';
  4 +import { OrgTreeSelect } from '../../common/OrgTreeSelect';
  5 +useComponentRegister('OrgTreeSelect', OrgTreeSelect);
6 // 表格列数据 6 // 表格列数据
7 export const columns: BasicColumn[] = [ 7 export const columns: BasicColumn[] = [
8 { 8 {
@@ -98,19 +98,8 @@ export const formSchema: FormSchema[] = [ @@ -98,19 +98,8 @@ export const formSchema: FormSchema[] = [
98 { 98 {
99 field: 'organizationId', 99 field: 'organizationId',
100 label: '所属组织', 100 label: '所属组织',
101 - component: 'ApiTreeSelect', 101 + component: 'OrgTreeSelect',
102 required: true, 102 required: true,
103 - componentProps: () => {  
104 - return {  
105 - maxLength: 250,  
106 - placeholder: '请选择所属组织',  
107 - api: async () => {  
108 - const data = await getOrganizationList();  
109 - copyTransFun(data as any as any[]);  
110 - return data;  
111 - },  
112 - };  
113 - },  
114 }, 103 },
115 { 104 {
116 field: 'alarmContactId', 105 field: 'alarmContactId',
1 import { BasicColumn, FormSchema } from '/@/components/Table'; 1 import { BasicColumn, FormSchema } from '/@/components/Table';
2 -import { getOrganizationList } from '/@/api/system/system';  
3 -import { copyTransFun } from '/@/utils/fnUtils';  
4 import { emailRule, phoneRule } from '/@/utils/rules'; 2 import { emailRule, phoneRule } from '/@/utils/rules';
5 - 3 +import { useComponentRegister } from '/@/components/Form';
  4 +import { OrgTreeSelect } from '../../common/OrgTreeSelect';
  5 +useComponentRegister('OrgTreeSelect', OrgTreeSelect);
6 // 表格列数据 6 // 表格列数据
7 export const columns: BasicColumn[] = [ 7 export const columns: BasicColumn[] = [
8 { 8 {
@@ -78,14 +78,7 @@ export const formSchema: FormSchema[] = [ @@ -78,14 +78,7 @@ export const formSchema: FormSchema[] = [
78 field: 'organizationId', 78 field: 'organizationId',
79 label: '所属组织', 79 label: '所属组织',
80 required: true, 80 required: true,
81 - component: 'ApiTreeSelect',  
82 - componentProps: {  
83 - api: async () => {  
84 - const data = await getOrganizationList();  
85 - copyTransFun(data as any as any[]);  
86 - return data;  
87 - },  
88 - }, 81 + component: 'OrgTreeSelect',
89 }, 82 },
90 { 83 {
91 field: 'phone', 84 field: 'phone',
1 -import { BasicColumn, FormSchema } from '/@/components/Table';  
2 -import { getOrganizationList } from '/@/api/system/system';  
3 -import { copyTransFun } from '/@/utils/fnUtils';  
4 -import type { FormSchema as QFormSchema } from '/@/components/Form/index';  
5 -  
6 -import { CameraVideoUrl, CameraMaxLength } from '/@/utils/rules';  
7 -import { h } from 'vue';  
8 -import SnHelpMessage from './SnHelpMessage.vue';  
9 -  
10 -export enum CameraPermission {  
11 - PREVIEW = 'api:yt:video:get',  
12 - CREATE = 'api:yt:video:post',  
13 - UPDATE = 'api:yt:video:update',  
14 - DELETE = 'api:yt:video:delete',  
15 -}  
16 -  
17 -export enum AccessMode {  
18 - ManuallyEnter = 0,  
19 - Streaming = 1,  
20 -}  
21 -  
22 -export enum PlayProtocol {  
23 - HTTP = 0,  
24 - HTTPS = 1,  
25 -}  
26 -  
27 -export enum StreamType {  
28 - MASTER = 0,  
29 - CHILD = 1,  
30 - THIRD = 2,  
31 -}  
32 -  
33 -export enum PageMode {  
34 - SPLIT_SCREEN_MODE = 'splitScreen',  
35 - LIST_MODE = 'listMode',  
36 - FULL_SCREEN_MODE = 'fullScreenMode',  
37 -}  
38 -  
39 -export enum MediaType {  
40 - MP4 = 'mp4',  
41 - M3U8 = 'm3u8',  
42 -}  
43 -  
44 -// 表格列数据  
45 -export const columns: BasicColumn[] = [  
46 - {  
47 - title: '封面',  
48 - dataIndex: 'avatar',  
49 - width: 80,  
50 - slots: { customRender: 'img' },  
51 - },  
52 - {  
53 - title: '名字',  
54 - dataIndex: 'name',  
55 - width: 120,  
56 - },  
57 - {  
58 - title: '摄像头编号/监控点编号',  
59 - dataIndex: 'sn',  
60 - width: 220,  
61 - },  
62 - {  
63 - title: '视频流',  
64 - dataIndex: 'videoUrl',  
65 - width: 120,  
66 - },  
67 - {  
68 - title: '所属组织',  
69 - dataIndex: 'organizationName',  
70 - width: 160,  
71 - },  
72 - {  
73 - title: '获取方式',  
74 - dataIndex: 'accessMode',  
75 - width: 100,  
76 - slots: { customRender: 'accessMode' },  
77 - },  
78 - {  
79 - title: '创建时间',  
80 - dataIndex: 'createTime',  
81 - width: 140,  
82 - },  
83 -];  
84 -  
85 -// 查询字段  
86 -export const searchFormSchema: FormSchema[] = [  
87 - {  
88 - field: 'name',  
89 - label: '摄像头名字',  
90 - component: 'Input',  
91 - colProps: { span: 8 },  
92 - componentProps: {  
93 - maxLength: 36,  
94 - placeholder: '请输入摄像头名字',  
95 - },  
96 - },  
97 -];  
98 -  
99 -// 弹框配置项  
100 -export const formSchema: QFormSchema[] = [  
101 - {  
102 - field: 'avatar',  
103 - label: '视频封面',  
104 - slot: 'iconSelect',  
105 - component: 'Input',  
106 - },  
107 - {  
108 - field: 'name',  
109 - label: '视频名字',  
110 - required: true,  
111 - component: 'Input',  
112 - componentProps: {  
113 - placeholder: '请输入视频名字',  
114 - maxLength: 30,  
115 - },  
116 - rules: [...CameraMaxLength, { required: true, message: '视频名是必填项' }],  
117 - },  
118 - {  
119 - field: 'organizationId',  
120 - label: '所属组织',  
121 - required: true,  
122 - component: 'ApiTreeSelect',  
123 - componentProps: {  
124 - api: async () => {  
125 - const data = await getOrganizationList();  
126 - copyTransFun(data as any as any[]);  
127 - return data;  
128 - },  
129 - },  
130 - },  
131 - {  
132 - label: '视频流获取方式',  
133 - field: 'accessMode',  
134 - component: 'RadioGroup',  
135 - rules: [{ required: true, message: '视频流获取方式为必选项', type: 'number' }],  
136 - defaultValue: AccessMode.ManuallyEnter,  
137 - componentProps({ formActionType }) {  
138 - return {  
139 - defaultValue: AccessMode.ManuallyEnter,  
140 - placeholder: '请选择视频流获取方式',  
141 - options: [  
142 - { label: '手动输入', value: AccessMode.ManuallyEnter },  
143 - { label: '流媒体获取', value: AccessMode.Streaming },  
144 - ],  
145 - onChange() {  
146 - formActionType.setFieldsValue({  
147 - brand: null,  
148 - sn: null,  
149 - videoUrl: null,  
150 - videoPlatformId: null,  
151 - });  
152 - },  
153 - };  
154 - },  
155 - },  
156 - {  
157 - field: 'brand',  
158 - label: '视频厂家',  
159 - component: 'Input',  
160 - ifShow({ values }) {  
161 - return values.accessMode === AccessMode.ManuallyEnter;  
162 - },  
163 - componentProps: {  
164 - maxLength: 36,  
165 - placeholder: '请输入视频厂家',  
166 - },  
167 - },  
168 - {  
169 - field: 'sn',  
170 - label: '摄像头编号',  
171 - required: true,  
172 - component: 'Input',  
173 - rules: [...CameraVideoUrl, { required: true, message: '摄像头编号是必填项' }],  
174 - ifShow({ values }) {  
175 - return values.accessMode === AccessMode.ManuallyEnter;  
176 - },  
177 - componentProps: {  
178 - maxLength: 36,  
179 - placeholder: '请输入摄像头编号',  
180 - },  
181 - },  
182 - {  
183 - field: 'videoUrl',  
184 - label: '视频流',  
185 - component: 'Input',  
186 - required: true,  
187 - ifShow({ values }) {  
188 - return values.accessMode === AccessMode.ManuallyEnter;  
189 - },  
190 - componentProps: {  
191 - placeholder: '请输入视频流',  
192 - maxLength: 255,  
193 - },  
194 - rules: [{ required: true, message: '视频流是必填项' }, ...CameraVideoUrl],  
195 - },  
196 -  
197 - {  
198 - field: 'videoPlatformId',  
199 - label: '流媒体配置',  
200 - component: 'Select',  
201 - ifShow({ values }) {  
202 - return values.accessMode === AccessMode.Streaming;  
203 - },  
204 - slot: 'videoPlatformIdSlot',  
205 - componentProps: {  
206 - placeholder: '请选择流媒体配置',  
207 - },  
208 - },  
209 - {  
210 - field: 'streamType',  
211 - label: '码流',  
212 - component: 'RadioGroup',  
213 - defaultValue: StreamType.MASTER,  
214 - ifShow({ values }) {  
215 - return values.accessMode === AccessMode.Streaming;  
216 - },  
217 - componentProps: {  
218 - placeholder: '请选择码流',  
219 - defaultValue: StreamType.MASTER,  
220 - options: [  
221 - { label: '主码流', value: StreamType.MASTER },  
222 - { label: '子码流', value: StreamType.CHILD },  
223 - { label: '第三码流', value: StreamType.THIRD },  
224 - ],  
225 - },  
226 - },  
227 - {  
228 - field: 'playProtocol',  
229 - label: '播放协议',  
230 - component: 'RadioGroup',  
231 - defaultValue: PlayProtocol.HTTP,  
232 - ifShow({ values }) {  
233 - return values.accessMode === AccessMode.Streaming;  
234 - },  
235 - helpMessage: ['平台使用https的hls协议,需联系海康开放平台专家支持。'],  
236 - componentProps: {  
237 - placeholder: '请选择播放协议',  
238 - defaultValue: PlayProtocol.HTTP,  
239 - options: [  
240 - { label: 'http', value: PlayProtocol.HTTP },  
241 - { label: 'https', value: PlayProtocol.HTTPS },  
242 - ],  
243 - },  
244 - },  
245 - {  
246 - field: 'sn',  
247 - label: h(SnHelpMessage) as any,  
248 - component: 'Input',  
249 - rules: [...CameraVideoUrl, { required: true, message: '摄像头编号是必填项' }],  
250 - ifShow({ values }) {  
251 - return values.accessMode === AccessMode.Streaming;  
252 - },  
253 - componentProps: {  
254 - placeholder: '请输入监控点编号',  
255 - },  
256 - },  
257 -]; 1 +import { BasicColumn, FormSchema } from '/@/components/Table';
  2 +import { FormSchema as QFormSchema, useComponentRegister } from '/@/components/Form/index';
  3 +
  4 +import { CameraVideoUrl, CameraMaxLength } from '/@/utils/rules';
  5 +import { h } from 'vue';
  6 +import SnHelpMessage from './SnHelpMessage.vue';
  7 +import { OrgTreeSelect } from '../../common/OrgTreeSelect';
  8 +
  9 +useComponentRegister('OrgTreeSelect', OrgTreeSelect);
  10 +
  11 +export enum CameraPermission {
  12 + PREVIEW = 'api:yt:video:get',
  13 + CREATE = 'api:yt:video:post',
  14 + UPDATE = 'api:yt:video:update',
  15 + DELETE = 'api:yt:video:delete',
  16 +}
  17 +
  18 +export enum AccessMode {
  19 + ManuallyEnter = 0,
  20 + Streaming = 1,
  21 +}
  22 +
  23 +export enum PlayProtocol {
  24 + HTTP = 0,
  25 + HTTPS = 1,
  26 +}
  27 +
  28 +export enum StreamType {
  29 + MASTER = 0,
  30 + CHILD = 1,
  31 + THIRD = 2,
  32 +}
  33 +
  34 +export enum PageMode {
  35 + SPLIT_SCREEN_MODE = 'splitScreen',
  36 + LIST_MODE = 'listMode',
  37 + FULL_SCREEN_MODE = 'fullScreenMode',
  38 +}
  39 +
  40 +export enum MediaType {
  41 + MP4 = 'mp4',
  42 + M3U8 = 'm3u8',
  43 +}
  44 +
  45 +// 表格列数据
  46 +export const columns: BasicColumn[] = [
  47 + {
  48 + title: '封面',
  49 + dataIndex: 'avatar',
  50 + width: 80,
  51 + slots: { customRender: 'img' },
  52 + },
  53 + {
  54 + title: '名字',
  55 + dataIndex: 'name',
  56 + width: 120,
  57 + },
  58 + {
  59 + title: '摄像头编号/监控点编号',
  60 + dataIndex: 'sn',
  61 + width: 220,
  62 + },
  63 + {
  64 + title: '视频流',
  65 + dataIndex: 'videoUrl',
  66 + width: 120,
  67 + },
  68 + {
  69 + title: '所属组织',
  70 + dataIndex: 'organizationName',
  71 + width: 160,
  72 + },
  73 + {
  74 + title: '获取方式',
  75 + dataIndex: 'accessMode',
  76 + width: 100,
  77 + slots: { customRender: 'accessMode' },
  78 + },
  79 + {
  80 + title: '创建时间',
  81 + dataIndex: 'createTime',
  82 + width: 140,
  83 + },
  84 +];
  85 +
  86 +// 查询字段
  87 +export const searchFormSchema: FormSchema[] = [
  88 + {
  89 + field: 'name',
  90 + label: '摄像头名字',
  91 + component: 'Input',
  92 + colProps: { span: 8 },
  93 + componentProps: {
  94 + maxLength: 36,
  95 + placeholder: '请输入摄像头名字',
  96 + },
  97 + },
  98 +];
  99 +
  100 +// 弹框配置项
  101 +export const formSchema: QFormSchema[] = [
  102 + {
  103 + field: 'avatar',
  104 + label: '视频封面',
  105 + slot: 'iconSelect',
  106 + component: 'Input',
  107 + },
  108 + {
  109 + field: 'name',
  110 + label: '视频名字',
  111 + required: true,
  112 + component: 'Input',
  113 + componentProps: {
  114 + placeholder: '请输入视频名字',
  115 + maxLength: 30,
  116 + },
  117 + rules: [...CameraMaxLength, { required: true, message: '视频名是必填项' }],
  118 + },
  119 + {
  120 + field: 'organizationId',
  121 + label: '所属组织',
  122 + required: true,
  123 + component: 'OrgTreeSelect',
  124 + },
  125 + {
  126 + label: '视频流获取方式',
  127 + field: 'accessMode',
  128 + component: 'RadioGroup',
  129 + rules: [{ required: true, message: '视频流获取方式为必选项', type: 'number' }],
  130 + defaultValue: AccessMode.ManuallyEnter,
  131 + componentProps({ formActionType }) {
  132 + return {
  133 + defaultValue: AccessMode.ManuallyEnter,
  134 + placeholder: '请选择视频流获取方式',
  135 + options: [
  136 + { label: '手动输入', value: AccessMode.ManuallyEnter },
  137 + { label: '流媒体获取', value: AccessMode.Streaming },
  138 + ],
  139 + onChange() {
  140 + formActionType.setFieldsValue({
  141 + brand: null,
  142 + sn: null,
  143 + videoUrl: null,
  144 + videoPlatformId: null,
  145 + });
  146 + },
  147 + };
  148 + },
  149 + },
  150 + {
  151 + field: 'brand',
  152 + label: '视频厂家',
  153 + component: 'Input',
  154 + ifShow({ values }) {
  155 + return values.accessMode === AccessMode.ManuallyEnter;
  156 + },
  157 + componentProps: {
  158 + maxLength: 36,
  159 + placeholder: '请输入视频厂家',
  160 + },
  161 + },
  162 + {
  163 + field: 'sn',
  164 + label: '摄像头编号',
  165 + required: true,
  166 + component: 'Input',
  167 + rules: [...CameraVideoUrl, { required: true, message: '摄像头编号是必填项' }],
  168 + ifShow({ values }) {
  169 + return values.accessMode === AccessMode.ManuallyEnter;
  170 + },
  171 + componentProps: {
  172 + maxLength: 36,
  173 + placeholder: '请输入摄像头编号',
  174 + },
  175 + },
  176 + {
  177 + field: 'videoUrl',
  178 + label: '视频流',
  179 + component: 'Input',
  180 + required: true,
  181 + ifShow({ values }) {
  182 + return values.accessMode === AccessMode.ManuallyEnter;
  183 + },
  184 + componentProps: {
  185 + placeholder: '请输入视频流',
  186 + maxLength: 255,
  187 + },
  188 + rules: [{ required: true, message: '视频流是必填项' }, ...CameraVideoUrl],
  189 + },
  190 +
  191 + {
  192 + field: 'videoPlatformId',
  193 + label: '流媒体配置',
  194 + component: 'Select',
  195 + ifShow({ values }) {
  196 + return values.accessMode === AccessMode.Streaming;
  197 + },
  198 + slot: 'videoPlatformIdSlot',
  199 + componentProps: {
  200 + placeholder: '请选择流媒体配置',
  201 + },
  202 + },
  203 + {
  204 + field: 'streamType',
  205 + label: '码流',
  206 + component: 'RadioGroup',
  207 + defaultValue: StreamType.MASTER,
  208 + ifShow({ values }) {
  209 + return values.accessMode === AccessMode.Streaming;
  210 + },
  211 + componentProps: {
  212 + placeholder: '请选择码流',
  213 + defaultValue: StreamType.MASTER,
  214 + options: [
  215 + { label: '主码流', value: StreamType.MASTER },
  216 + { label: '子码流', value: StreamType.CHILD },
  217 + { label: '第三码流', value: StreamType.THIRD },
  218 + ],
  219 + },
  220 + },
  221 + {
  222 + field: 'playProtocol',
  223 + label: '播放协议',
  224 + component: 'RadioGroup',
  225 + defaultValue: PlayProtocol.HTTP,
  226 + ifShow({ values }) {
  227 + return values.accessMode === AccessMode.Streaming;
  228 + },
  229 + helpMessage: ['平台使用https的hls协议,需联系海康开放平台专家支持。'],
  230 + componentProps: {
  231 + placeholder: '请选择播放协议',
  232 + defaultValue: PlayProtocol.HTTP,
  233 + options: [
  234 + { label: 'http', value: PlayProtocol.HTTP },
  235 + { label: 'https', value: PlayProtocol.HTTPS },
  236 + ],
  237 + },
  238 + },
  239 + {
  240 + field: 'sn',
  241 + label: h(SnHelpMessage) as any,
  242 + component: 'Input',
  243 + rules: [...CameraVideoUrl, { required: true, message: '摄像头编号是必填项' }],
  244 + ifShow({ values }) {
  245 + return values.accessMode === AccessMode.Streaming;
  246 + },
  247 + componentProps: {
  248 + placeholder: '请输入监控点编号',
  249 + },
  250 + },
  251 +];
@@ -5,8 +5,11 @@ @@ -5,8 +5,11 @@
5 import { computed, ref, unref } from 'vue'; 5 import { computed, ref, unref } from 'vue';
6 import OrganizationDrawer from '/@/views/system/organization/OrganizationDrawer.vue'; 6 import OrganizationDrawer from '/@/views/system/organization/OrganizationDrawer.vue';
7 import { useDrawer } from '/@/components/Drawer'; 7 import { useDrawer } from '/@/components/Drawer';
  8 + import { OrganizationListItem } from '/@/api/system/model/systemModel';
  9 + import { useRole } from '/@/hooks/business/useRole';
8 10
9 const [registerDrawer, { openDrawer }] = useDrawer(); 11 const [registerDrawer, { openDrawer }] = useDrawer();
  12 + const { isCustomerUser } = useRole();
10 13
11 const props = withDefaults( 14 const props = withDefaults(
12 defineProps<{ 15 defineProps<{
@@ -19,6 +22,8 @@ @@ -19,6 +22,8 @@
19 } 22 }
20 ); 23 );
21 24
  25 + const needReload = ref(true);
  26 +
22 const emit = defineEmits(['change']); 27 const emit = defineEmits(['change']);
23 28
24 const handleOpenCreate = () => { 29 const handleOpenCreate = () => {
@@ -27,7 +32,9 @@ @@ -27,7 +32,9 @@
27 32
28 const timespan = ref(Date.now()); 33 const timespan = ref(Date.now());
29 34
30 - const getBindProps = computed(() => { 35 + const orgList = ref<Recordable[]>([]);
  36 +
  37 + const getBindProps = computed<Recordable>(() => {
31 const { value, apiTreeSelectProps = {} } = props; 38 const { value, apiTreeSelectProps = {} } = props;
32 const { params = {} } = apiTreeSelectProps; 39 const { params = {} } = apiTreeSelectProps;
33 return { 40 return {
@@ -37,7 +44,17 @@ @@ -37,7 +44,17 @@
37 maxLength: 250, 44 maxLength: 250,
38 ...apiTreeSelectProps, 45 ...apiTreeSelectProps,
39 value, 46 value,
40 - api: getOrganizationList, 47 + api: async (params: OrganizationListItem) => {
  48 + try {
  49 + if (!unref(needReload)) return unref(orgList);
  50 + const result = ((await getOrganizationList(params)) as unknown as Recordable[]) || [];
  51 + orgList.value = result;
  52 + needReload.value = false;
  53 + return result;
  54 + } catch (error) {
  55 + return unref(orgList);
  56 + }
  57 + },
41 params: { ...params, _t: unref(timespan) }, 58 params: { ...params, _t: unref(timespan) },
42 onChange: (...args: any[]) => { 59 onChange: (...args: any[]) => {
43 emit('change', ...args); 60 emit('change', ...args);
@@ -45,7 +62,13 @@ @@ -45,7 +62,13 @@
45 }; 62 };
46 }); 63 });
47 64
  65 + const getShowCreate = computed(() => {
  66 + const { showCreate } = props;
  67 + return unref(isCustomerUser) ? false : showCreate;
  68 + });
  69 +
48 const handleReload = () => { 70 const handleReload = () => {
  71 + needReload.value = true;
49 timespan.value = Date.now(); 72 timespan.value = Date.now();
50 }; 73 };
51 </script> 74 </script>
@@ -53,7 +76,7 @@ @@ -53,7 +76,7 @@
53 <template> 76 <template>
54 <section class="flex"> 77 <section class="flex">
55 <ApiTreeSelect v-bind="getBindProps" /> 78 <ApiTreeSelect v-bind="getBindProps" />
56 - <Button v-if="showCreate" type="link" @click="handleOpenCreate">新增组织</Button>  
57 - <OrganizationDrawer v-if="showCreate" @register="registerDrawer" @success="handleReload" /> 79 + <Button v-if="getShowCreate" type="link" @click="handleOpenCreate">新增组织</Button>
  80 + <OrganizationDrawer v-if="getShowCreate" @register="registerDrawer" @success="handleReload" />
58 </section> 81 </section>
59 </template> 82 </template>
1 import { BasicColumn, FormSchema } from '/@/components/Table'; 1 import { BasicColumn, FormSchema } from '/@/components/Table';
2 -import { getOrganizationList } from '/@/api/system/system';  
3 -import { copyTransFun } from '/@/utils/fnUtils';  
4 import { FileItem } from '/@/components/Form/src/components/ApiUpload.vue'; 2 import { FileItem } from '/@/components/Form/src/components/ApiUpload.vue';
5 import { createImgPreview } from '/@/components/Preview'; 3 import { createImgPreview } from '/@/components/Preview';
6 import { uploadThumbnail } from '/@/api/configuration/center/configurationCenter'; 4 import { uploadThumbnail } from '/@/api/configuration/center/configurationCenter';
  5 +import { useComponentRegister } from '/@/components/Form';
  6 +import { OrgTreeSelect } from '../../common/OrgTreeSelect';
  7 +
  8 +useComponentRegister('OrgTreeSelect', OrgTreeSelect);
7 export enum Platform { 9 export enum Platform {
8 PHONE = 'phone', 10 PHONE = 'phone',
9 PC = 'pc', 11 PC = 'pc',
@@ -126,14 +128,7 @@ export const formSchema: FormSchema[] = [ @@ -126,14 +128,7 @@ export const formSchema: FormSchema[] = [
126 field: 'organizationId', 128 field: 'organizationId',
127 label: '所属组织', 129 label: '所属组织',
128 required: true, 130 required: true,
129 - component: 'ApiTreeSelect',  
130 - componentProps: {  
131 - api: async () => {  
132 - const data = await getOrganizationList();  
133 - copyTransFun(data as any as any[]);  
134 - return data;  
135 - },  
136 - }, 131 + component: 'OrgTreeSelect',
137 }, 132 },
138 { 133 {
139 field: 'platform', 134 field: 'platform',
1 import { FormSchema } from '/@/components/Table'; 1 import { FormSchema } from '/@/components/Table';
2 -import { getOrganizationList } from '/@/api/system/system';  
3 -import { copyTransFun } from '/@/utils/fnUtils';  
4 import { FileItem } from '/@/components/Form/src/components/ApiUpload.vue'; 2 import { FileItem } from '/@/components/Form/src/components/ApiUpload.vue';
5 import { createImgPreview } from '/@/components/Preview'; 3 import { createImgPreview } from '/@/components/Preview';
6 import { uploadThumbnail } from '/@/api/configuration/center/configurationCenter'; 4 import { uploadThumbnail } from '/@/api/configuration/center/configurationCenter';
  5 +import { useComponentRegister } from '/@/components/Form';
  6 +import { OrgTreeSelect } from '../common/OrgTreeSelect';
  7 +
  8 +useComponentRegister('OrgTreeSelect', OrgTreeSelect);
  9 +
7 export enum Platform { 10 export enum Platform {
8 PHONE = 0, 11 PHONE = 0,
9 PC = 1, 12 PC = 1,
@@ -80,29 +83,8 @@ export const formSchema: FormSchema[] = [ @@ -80,29 +83,8 @@ export const formSchema: FormSchema[] = [
80 field: 'organizationId', 83 field: 'organizationId',
81 label: '所属组织', 84 label: '所属组织',
82 required: true, 85 required: true,
83 - component: 'ApiTreeSelect',  
84 - componentProps: {  
85 - api: async () => {  
86 - const data = await getOrganizationList();  
87 - copyTransFun(data as any as any[]);  
88 - return data;  
89 - },  
90 - }, 86 + component: 'OrgTreeSelect',
91 }, 87 },
92 - // {  
93 - // field: 'state',  
94 - // label: '发布状态',  
95 - // required: true,  
96 - // component: 'RadioGroup',  
97 - // defaultValue: Platform.PC,  
98 - // componentProps: {  
99 - // defaultValue: Platform.PC,  
100 - // options: [  
101 - // { label: '未发布', value: Platform.PC },  
102 - // { label: '已发布', value: Platform.PHONE },  
103 - // ],  
104 - // },  
105 - // },  
106 { 88 {
107 field: 'remark', 89 field: 'remark',
108 label: '备注', 90 label: '备注',
@@ -182,7 +182,7 @@ @@ -182,7 +182,7 @@
182 Reflect.set(params, 'scope', 'LATEST_TELEMETRY'); 182 Reflect.set(params, 'scope', 'LATEST_TELEMETRY');
183 Reflect.set(params, 'entityType', 'DEVICE'); 183 Reflect.set(params, 'entityType', 'DEVICE');
184 } 184 }
185 - socketMessage.sendValue.tsSubCmds.push(params); 185 + socketMessage.sendValue.tsSubCmds = [params];
186 const { send, close } = useWebSocket(socketMessage.server, { 186 const { send, close } = useWebSocket(socketMessage.server, {
187 onConnected() { 187 onConnected() {
188 send(JSON.stringify(socketMessage.sendValue)); 188 send(JSON.stringify(socketMessage.sendValue));
1 -import { BasicColumn, FormSchema } from '/@/components/Table';  
2 -import { h } from 'vue';  
3 -import { Tag } from 'ant-design-vue';  
4 -import { findDictItemByCode } from '/@/api/system/dict';  
5 -import { USER_INFO_KEY } from '/@/enums/cacheEnum';  
6 -import { getAuthCache } from '/@/utils/auth';  
7 -import { isAdmin } from '/@/enums/roleEnum';  
8 -  
9 -// 表格配置  
10 -export const columns: BasicColumn[] = [  
11 - {  
12 - title: '接口名称',  
13 - dataIndex: 'interfaceName',  
14 - width: 150,  
15 - },  
16 - {  
17 - title: '接口类型',  
18 - dataIndex: 'interfaceType',  
19 - width: 80,  
20 - format(text) {  
21 - return text === 'SYSTEM' ? '系统默认' : '自定义';  
22 - },  
23 - },  
24 - {  
25 - title: '请求方式',  
26 - dataIndex: 'requestContentType',  
27 - width: 90,  
28 - format(text) {  
29 - return Number(text) === 0 ? '普通请求' : Number(text) === 1 ? 'SQL请求' : 'websocket请求';  
30 - },  
31 - },  
32 - {  
33 - title: '接口内容',  
34 - dataIndex: 'content',  
35 - width: 80,  
36 - slots: { customRender: 'content' },  
37 - },  
38 - {  
39 - title: '状态',  
40 - dataIndex: 'state',  
41 - width: 80,  
42 - customRender: ({ record }) => {  
43 - const color = record.state == 1 ? 'green' : 'red';  
44 - const text = record.state == 1 ? '发布' : '未发布';  
45 - return h(Tag, { color: color }, () => text);  
46 - },  
47 - },  
48 -];  
49 -  
50 -// 查询配置  
51 -export const searchFormSchema: FormSchema[] = [  
52 - {  
53 - field: 'name',  
54 - label: '接口名称',  
55 - component: 'Input',  
56 - colProps: { span: 7 },  
57 - componentProps: {  
58 - maxLength: 36,  
59 - placeholder: '请输入接口名称',  
60 - },  
61 - },  
62 - {  
63 - field: 'state',  
64 - label: '发布状态',  
65 - component: 'Select',  
66 - colProps: { span: 7 },  
67 - componentProps: {  
68 - options: [  
69 - {  
70 - label: '发布',  
71 - value: 1,  
72 - },  
73 - {  
74 - label: '未发布',  
75 - value: 0,  
76 - },  
77 - ],  
78 - placeholder: '请选择发布状态',  
79 - },  
80 - },  
81 - {  
82 - field: 'interfaceType',  
83 - label: '接口类型',  
84 - component: 'Select',  
85 - colProps: { span: 7 },  
86 - componentProps: {  
87 - options: [  
88 - {  
89 - label: '系统默认',  
90 - value: 'SYSTEM',  
91 - },  
92 - {  
93 - label: '自定义',  
94 - value: 'CUSTOM',  
95 - },  
96 - ],  
97 - placeholder: '请选择接口类型',  
98 - },  
99 - ifShow: ({}) => {  
100 - const userInfo: any = getAuthCache(USER_INFO_KEY);  
101 - const role: string = userInfo?.roles[0];  
102 - if (isAdmin(role)) return true;  
103 - else return false;  
104 - },  
105 - },  
106 -];  
107 -  
108 -//表单配置  
109 -export const schemas: FormSchema[] = [  
110 - {  
111 - field: 'interfaceName',  
112 - label: '接口名称',  
113 - colProps: { span: 24 },  
114 - required: true,  
115 - component: 'Input',  
116 - componentProps: {  
117 - maxLength: 255,  
118 - placeholder: '请输入接口名称',  
119 - },  
120 - },  
121 - // {  
122 - // field: 'interfaceType',  
123 - // component: 'ApiRadioGroup',  
124 - // label: '接口类型',  
125 - // required: true,  
126 - // colProps: {  
127 - // span: 8,  
128 - // },  
129 - // defaultValue: 'SYSTEM',  
130 - // componentProps: {  
131 - // api: findDictItemByCode,  
132 - // params: {  
133 - // dictCode: 'interface_Type',  
134 - // },  
135 - // labelField: 'itemText',  
136 - // valueField: 'itemValue',  
137 - // },  
138 - // },  
139 - {  
140 - field: 'interfaceType',  
141 - component: 'ApiRadioGroup',  
142 - label: '接口类型',  
143 - required: true,  
144 - colProps: {  
145 - span: 8,  
146 - },  
147 - defaultValue: 'CUSTOM',  
148 - componentProps: {  
149 - options: [  
150 - {  
151 - label: '系统默认',  
152 - value: 'SYSTEM',  
153 - },  
154 - {  
155 - label: '自定义',  
156 - value: 'CUSTOM',  
157 - },  
158 - ],  
159 - },  
160 - ifShow: ({}) => {  
161 - const userInfo: any = getAuthCache(USER_INFO_KEY);  
162 - const role: string = userInfo?.roles[0];  
163 - if (isAdmin(role)) return true;  
164 - else return false;  
165 - },  
166 - },  
167 - {  
168 - field: 'requestContentType',  
169 - label: '请求方式',  
170 - component: 'ApiSelect',  
171 - required: true,  
172 - colProps: { span: 24 },  
173 - defaultValue: '0',  
174 - componentProps: ({ formActionType }) => {  
175 - const { updateSchema, setFieldsValue } = formActionType;  
176 - return {  
177 - api: findDictItemByCode,  
178 - params: {  
179 - dictCode: 'dataview_select_methods',  
180 - },  
181 - placeholder: '请选择请求方式',  
182 - labelField: 'itemText',  
183 - valueField: 'itemValue',  
184 - getPopupContainer: () => document.body,  
185 - async onChange(e) {  
186 - setFieldsValue({  
187 - requestOriginUrl: '',  
188 - requestHttpTypeAndUrl: {  
189 - requestHttpType: undefined,  
190 - requestUrl: '',  
191 - },  
192 - });  
193 - updateSchema({  
194 - field: 'requestHttpTypeAndUrl',  
195 - componentProps: {  
196 - type: e,  
197 - },  
198 - });  
199 - updateSchema({  
200 - field: 'requestOriginUrl',  
201 - componentProps: {  
202 - placeholder: `${  
203 - e === '0' ? '示例:http://127.0.0.1' : e === '2' ? '示例:ws://127.0.0.1' : ''  
204 - }`,  
205 - },  
206 - });  
207 - },  
208 - };  
209 - },  
210 - },  
211 - {  
212 - field: 'originUrlType',  
213 - label: '地址类型',  
214 - component: 'ApiSelect',  
215 - required: true,  
216 - colProps: { span: 24 },  
217 - defaultValue: 'server_url',  
218 - componentProps: ({ formActionType }) => {  
219 - const { setFieldsValue } = formActionType;  
220 - return {  
221 - placeholder: '请选择地址类型',  
222 - api: findDictItemByCode,  
223 - params: {  
224 - dictCode: 'dataview_select_origin_type',  
225 - },  
226 - labelField: 'itemText',  
227 - valueField: 'itemValue',  
228 - onChange: (e) => {  
229 - if (e) {  
230 - setFieldsValue({  
231 - requestOriginUrl: '',  
232 - });  
233 - }  
234 - },  
235 - };  
236 - },  
237 - },  
238 - {  
239 - field: 'requestOriginUrl',  
240 - label: '源地址',  
241 - colProps: { span: 24 },  
242 - required: true,  
243 - component: 'Input',  
244 - componentProps: ({ formActionType }) => {  
245 - const { getFieldsValue } = formActionType;  
246 - const type = getFieldsValue()?.requestContentType;  
247 - return {  
248 - placeholder: `${  
249 - type === '0' ? '示例:http://127.0.0.1' : type === '2' ? '示例:ws://127.0.0.1' : ''  
250 - }`,  
251 - };  
252 - },  
253 - ifShow: ({ values }) => values['originUrlType'] === 'custom_url',  
254 - },  
255 - {  
256 - field: 'requestHttpTypeAndUrl',  
257 - label: '请求类型&地址',  
258 - component: 'InputGroup',  
259 - required: true,  
260 - colProps: { span: 24 },  
261 - componentProps: ({ formActionType }) => {  
262 - const { getFieldsValue } = formActionType;  
263 - return {  
264 - type: getFieldsValue().requestContentType,  
265 - };  
266 - },  
267 - },  
268 - {  
269 - field: 'fillAddress',  
270 - label: '完整地址',  
271 - component: 'Input',  
272 - slot: 'slotFillAddress',  
273 - colProps: { span: 24 },  
274 - ifShow: ({ values }) => {  
275 - return values['originUrlType'] === 'custom_url' && values['requestOriginUrl'];  
276 - },  
277 - },  
278 - {  
279 - field: 'slotServerAddress',  
280 - label: '完整地址',  
281 - component: 'Input',  
282 - slot: 'slotServerAddress',  
283 - colProps: { span: 24 },  
284 - ifShow: ({ values }) => {  
285 - return values['originUrlType'] === 'server_url';  
286 - },  
287 - },  
288 - {  
289 - field: 'requestSQLKey',  
290 - label: '键名',  
291 - colProps: { span: 6 },  
292 - component: 'Input',  
293 - defaultValue: 'sql',  
294 - componentProps: {  
295 - disabled: true,  
296 - },  
297 - ifShow: ({ values }) => values['requestContentType'] === '1',  
298 - },  
299 - {  
300 - field: 'requestSQLContent',  
301 - label: '键值',  
302 - colProps: { span: 24 },  
303 - component: 'InputTextArea',  
304 - defaultValue: 'select * from where',  
305 - componentProps: {  
306 - maxLength: 255,  
307 - placeholder: '请输入键值',  
308 - rows: 6,  
309 - },  
310 - ifShow: ({ values }) => values['requestContentType'] === '1',  
311 - },  
312 - {  
313 - field: 'slot',  
314 - label: '参数设置',  
315 - component: 'Input',  
316 - slot: 'selectMethods',  
317 - colProps: { span: 24 },  
318 - ifShow: ({ values }) => values['requestContentType'] !== '1',  
319 - },  
320 - {  
321 - field: 'testSlot',  
322 - label: '',  
323 - component: 'Input',  
324 - slot: 'testSql',  
325 - colProps: { span: 24 },  
326 - ifShow: ({ values }) => values['requestContentType'] === '1',  
327 - },  
328 -];  
329 -  
330 -//表格表头配置  
331 -export const editCellTableTHeadConfig = ['序号', '内置参数', '参数名', '是否必须', '操作'];  
332 -export const editTestCellTableTHeadConfig = ['内置参数', '参数名', '参数值'];  
333 -export const editTestCellTableTHeaderConfig = ['序号', '参数名', '参数值', '是否必须', '操作']; 1 +import { BasicColumn, FormSchema } from '/@/components/Table';
  2 +import { h } from 'vue';
  3 +import { Tag } from 'ant-design-vue';
  4 +import { findDictItemByCode } from '/@/api/system/dict';
  5 +import { USER_INFO_KEY } from '/@/enums/cacheEnum';
  6 +import { getAuthCache } from '/@/utils/auth';
  7 +import { isAdmin } from '/@/enums/roleEnum';
  8 +
  9 +// 表格配置
  10 +export const columns: BasicColumn[] = [
  11 + {
  12 + title: '接口名称',
  13 + dataIndex: 'interfaceName',
  14 + width: 150,
  15 + },
  16 + {
  17 + title: '接口类型',
  18 + dataIndex: 'interfaceType',
  19 + width: 80,
  20 + format(text) {
  21 + return text === 'SYSTEM' ? '系统默认' : '自定义';
  22 + },
  23 + },
  24 + {
  25 + title: '请求方式',
  26 + dataIndex: 'requestContentType',
  27 + width: 90,
  28 + format(text) {
  29 + return Number(text) === 0 ? '普通请求' : Number(text) === 1 ? 'SQL请求' : 'websocket请求';
  30 + },
  31 + },
  32 + {
  33 + title: '接口内容',
  34 + dataIndex: 'content',
  35 + width: 80,
  36 + slots: { customRender: 'content' },
  37 + },
  38 + {
  39 + title: '状态',
  40 + dataIndex: 'state',
  41 + width: 80,
  42 + customRender: ({ record }) => {
  43 + const color = record.state == 1 ? 'green' : 'red';
  44 + const text = record.state == 1 ? '发布' : '未发布';
  45 + return h(Tag, { color: color }, () => text);
  46 + },
  47 + },
  48 +];
  49 +
  50 +// 查询配置
  51 +export const searchFormSchema: FormSchema[] = [
  52 + {
  53 + field: 'name',
  54 + label: '接口名称',
  55 + component: 'Input',
  56 + componentProps: {
  57 + maxLength: 36,
  58 + placeholder: '请输入接口名称',
  59 + },
  60 + },
  61 + {
  62 + field: 'state',
  63 + label: '发布状态',
  64 + component: 'Select',
  65 + componentProps: {
  66 + options: [
  67 + {
  68 + label: '发布',
  69 + value: 1,
  70 + },
  71 + {
  72 + label: '未发布',
  73 + value: 0,
  74 + },
  75 + ],
  76 + placeholder: '请选择发布状态',
  77 + },
  78 + },
  79 + {
  80 + field: 'interfaceType',
  81 + label: '接口类型',
  82 + component: 'Select',
  83 + colProps: { span: 7 },
  84 + componentProps: {
  85 + options: [
  86 + {
  87 + label: '系统默认',
  88 + value: 'SYSTEM',
  89 + },
  90 + {
  91 + label: '自定义',
  92 + value: 'CUSTOM',
  93 + },
  94 + ],
  95 + placeholder: '请选择接口类型',
  96 + },
  97 + ifShow: ({}) => {
  98 + const userInfo: any = getAuthCache(USER_INFO_KEY);
  99 + const role: string = userInfo?.roles[0];
  100 + if (isAdmin(role)) return true;
  101 + else return false;
  102 + },
  103 + },
  104 +];
  105 +
  106 +//表单配置
  107 +export const schemas: FormSchema[] = [
  108 + {
  109 + field: 'interfaceName',
  110 + label: '接口名称',
  111 + colProps: { span: 24 },
  112 + required: true,
  113 + component: 'Input',
  114 + componentProps: {
  115 + maxLength: 255,
  116 + placeholder: '请输入接口名称',
  117 + },
  118 + },
  119 + // {
  120 + // field: 'interfaceType',
  121 + // component: 'ApiRadioGroup',
  122 + // label: '接口类型',
  123 + // required: true,
  124 + // colProps: {
  125 + // span: 8,
  126 + // },
  127 + // defaultValue: 'SYSTEM',
  128 + // componentProps: {
  129 + // api: findDictItemByCode,
  130 + // params: {
  131 + // dictCode: 'interface_Type',
  132 + // },
  133 + // labelField: 'itemText',
  134 + // valueField: 'itemValue',
  135 + // },
  136 + // },
  137 + {
  138 + field: 'interfaceType',
  139 + component: 'ApiRadioGroup',
  140 + label: '接口类型',
  141 + required: true,
  142 + colProps: {
  143 + span: 8,
  144 + },
  145 + defaultValue: 'CUSTOM',
  146 + componentProps: {
  147 + options: [
  148 + {
  149 + label: '系统默认',
  150 + value: 'SYSTEM',
  151 + },
  152 + {
  153 + label: '自定义',
  154 + value: 'CUSTOM',
  155 + },
  156 + ],
  157 + },
  158 + ifShow: ({}) => {
  159 + const userInfo: any = getAuthCache(USER_INFO_KEY);
  160 + const role: string = userInfo?.roles[0];
  161 + if (isAdmin(role)) return true;
  162 + else return false;
  163 + },
  164 + },
  165 + {
  166 + field: 'requestContentType',
  167 + label: '请求方式',
  168 + component: 'ApiSelect',
  169 + required: true,
  170 + colProps: { span: 24 },
  171 + defaultValue: '0',
  172 + componentProps: ({ formActionType }) => {
  173 + const { updateSchema, setFieldsValue } = formActionType;
  174 + return {
  175 + api: findDictItemByCode,
  176 + params: {
  177 + dictCode: 'dataview_select_methods',
  178 + },
  179 + placeholder: '请选择请求方式',
  180 + labelField: 'itemText',
  181 + valueField: 'itemValue',
  182 + getPopupContainer: () => document.body,
  183 + async onChange(e) {
  184 + setFieldsValue({
  185 + requestOriginUrl: '',
  186 + requestHttpTypeAndUrl: {
  187 + requestHttpType: undefined,
  188 + requestUrl: '',
  189 + },
  190 + });
  191 + updateSchema({
  192 + field: 'requestHttpTypeAndUrl',
  193 + componentProps: {
  194 + type: e,
  195 + },
  196 + });
  197 + updateSchema({
  198 + field: 'requestOriginUrl',
  199 + componentProps: {
  200 + placeholder: `${
  201 + e === '0' ? '示例:http://127.0.0.1' : e === '2' ? '示例:ws://127.0.0.1' : ''
  202 + }`,
  203 + },
  204 + });
  205 + },
  206 + };
  207 + },
  208 + },
  209 + {
  210 + field: 'originUrlType',
  211 + label: '地址类型',
  212 + component: 'ApiSelect',
  213 + required: true,
  214 + colProps: { span: 24 },
  215 + defaultValue: 'server_url',
  216 + componentProps: ({ formActionType }) => {
  217 + const { setFieldsValue } = formActionType;
  218 + return {
  219 + placeholder: '请选择地址类型',
  220 + api: findDictItemByCode,
  221 + params: {
  222 + dictCode: 'dataview_select_origin_type',
  223 + },
  224 + labelField: 'itemText',
  225 + valueField: 'itemValue',
  226 + onChange: (e) => {
  227 + if (e) {
  228 + setFieldsValue({
  229 + requestOriginUrl: '',
  230 + });
  231 + }
  232 + },
  233 + };
  234 + },
  235 + },
  236 + {
  237 + field: 'requestOriginUrl',
  238 + label: '源地址',
  239 + colProps: { span: 24 },
  240 + required: true,
  241 + component: 'Input',
  242 + componentProps: ({ formActionType }) => {
  243 + const { getFieldsValue } = formActionType;
  244 + const type = getFieldsValue()?.requestContentType;
  245 + return {
  246 + placeholder: `${
  247 + type === '0' ? '示例:http://127.0.0.1' : type === '2' ? '示例:ws://127.0.0.1' : ''
  248 + }`,
  249 + };
  250 + },
  251 + ifShow: ({ values }) => values['originUrlType'] === 'custom_url',
  252 + },
  253 + {
  254 + field: 'requestHttpTypeAndUrl',
  255 + label: '请求类型&地址',
  256 + component: 'InputGroup',
  257 + required: true,
  258 + colProps: { span: 24 },
  259 + componentProps: ({ formActionType }) => {
  260 + const { getFieldsValue } = formActionType;
  261 + return {
  262 + type: getFieldsValue().requestContentType,
  263 + };
  264 + },
  265 + },
  266 + {
  267 + field: 'fillAddress',
  268 + label: '完整地址',
  269 + component: 'Input',
  270 + slot: 'slotFillAddress',
  271 + colProps: { span: 24 },
  272 + ifShow: ({ values }) => {
  273 + return values['originUrlType'] === 'custom_url' && values['requestOriginUrl'];
  274 + },
  275 + },
  276 + {
  277 + field: 'slotServerAddress',
  278 + label: '完整地址',
  279 + component: 'Input',
  280 + slot: 'slotServerAddress',
  281 + colProps: { span: 24 },
  282 + ifShow: ({ values }) => {
  283 + return values['originUrlType'] === 'server_url';
  284 + },
  285 + },
  286 + {
  287 + field: 'requestSQLKey',
  288 + label: '键名',
  289 + colProps: { span: 6 },
  290 + component: 'Input',
  291 + defaultValue: 'sql',
  292 + componentProps: {
  293 + disabled: true,
  294 + },
  295 + ifShow: ({ values }) => values['requestContentType'] === '1',
  296 + },
  297 + {
  298 + field: 'requestSQLContent',
  299 + label: '键值',
  300 + colProps: { span: 24 },
  301 + component: 'InputTextArea',
  302 + defaultValue: 'select * from where',
  303 + componentProps: {
  304 + maxLength: 255,
  305 + placeholder: '请输入键值',
  306 + rows: 6,
  307 + },
  308 + ifShow: ({ values }) => values['requestContentType'] === '1',
  309 + },
  310 + {
  311 + field: 'slot',
  312 + label: '参数设置',
  313 + component: 'Input',
  314 + slot: 'selectMethods',
  315 + colProps: { span: 24 },
  316 + ifShow: ({ values }) => values['requestContentType'] !== '1',
  317 + },
  318 + {
  319 + field: 'testSlot',
  320 + label: '',
  321 + component: 'Input',
  322 + slot: 'testSql',
  323 + colProps: { span: 24 },
  324 + ifShow: ({ values }) => values['requestContentType'] === '1',
  325 + },
  326 +];
  327 +
  328 +//表格表头配置
  329 +export const editCellTableTHeadConfig = ['序号', '内置参数', '参数名', '是否必须', '操作'];
  330 +export const editTestCellTableTHeadConfig = ['内置参数', '参数名', '参数值'];
  331 +export const editTestCellTableTHeaderConfig = ['序号', '参数名', '参数值', '是否必须', '操作'];
1 <template> 1 <template>
2 <div> 2 <div>
3 - <BasicTable @register="registerTable" :row-selection="rowSelection"> 3 + <BasicTable
  4 + @register="registerTable"
  5 + :row-selection="rowSelection"
  6 + class="bg-neutral-100 dark:bg-dark-700"
  7 + >
4 <template #content="{ record }"> 8 <template #content="{ record }">
5 <a-button type="link" class="ml-2" @click="handleRecordContent(record)"> 查看 </a-button> 9 <a-button type="link" class="ml-2" @click="handleRecordContent(record)"> 查看 </a-button>
6 </template> 10 </template>
@@ -108,8 +112,10 @@ @@ -108,8 +112,10 @@
108 showTableSetting: true, 112 showTableSetting: true,
109 bordered: true, 113 bordered: true,
110 formConfig: { 114 formConfig: {
111 - labelWidth: 120, 115 + labelWidth: 80,
112 schemas: searchFormSchema, 116 schemas: searchFormSchema,
  117 + baseColProps: { span: 9 },
  118 + actionColOptions: { span: 6 },
113 }, 119 },
114 useSearchForm: true, 120 useSearchForm: true,
115 actionColumn: { 121 actionColumn: {
@@ -63,12 +63,12 @@ @@ -63,12 +63,12 @@
63 </div> 63 </div>
64 </template> 64 </template>
65 <template #deviceProfile="{ record }"> 65 <template #deviceProfile="{ record }">
66 - <Tag.CheckableTag 66 + <Button
67 @click="!isCustomer ? goDeviceProfile(record.deviceProfile.name) : null" 67 @click="!isCustomer ? goDeviceProfile(record.deviceProfile.name) : null"
68 - style="white-space: normal; height: auto; cursor: pointer" 68 + type="link"
69 > 69 >
70 - <span style="color: #377dff">{{ record.deviceProfile.name }}</span>  
71 - </Tag.CheckableTag> 70 + {{ record.deviceProfile.name }}
  71 + </Button>
72 </template> 72 </template>
73 73
74 <template #deviceType="{ record }"> 74 <template #deviceType="{ record }">
@@ -385,10 +385,10 @@ @@ -385,10 +385,10 @@
385 openGatewayDetailDrawer(true, data); 385 openGatewayDetailDrawer(true, data);
386 }; 386 };
387 387
388 - const handleUpAndDownRecord = (record: Record<'name', string>) => { 388 + const handleUpAndDownRecord = (record: Record<'name' | 'alias', string>) => {
389 ROUTER.push({ 389 ROUTER.push({
390 path: '/operation/onlinerecord', 390 path: '/operation/onlinerecord',
391 - query: { deviceName: record.name }, 391 + query: { deviceName: record.alias || record.name },
392 }); 392 });
393 }; 393 };
394 394
@@ -82,7 +82,7 @@ export const columns: BasicColumn[] = [ @@ -82,7 +82,7 @@ export const columns: BasicColumn[] = [
82 dataIndex: 'name', 82 dataIndex: 'name',
83 width: 120, 83 width: 120,
84 format: (_text: string, record: Recordable) => { 84 format: (_text: string, record: Recordable) => {
85 - return record?.alias ? record?.alias : record?.name; 85 + return record?.alias || record?.name;
86 }, 86 },
87 }, 87 },
88 { 88 {
@@ -150,6 +150,7 @@ @@ -150,6 +150,7 @@
150 deviceProfile: { default: boolean; enabled: boolean; name: string; transportType: string }; 150 deviceProfile: { default: boolean; enabled: boolean; name: string; transportType: string };
151 deviceInfo: { longitude: string; latitude: string; address: string }; 151 deviceInfo: { longitude: string; latitude: string; address: string };
152 deviceType?: string; 152 deviceType?: string;
  153 + alias?: string;
153 deviceProfileId: string; 154 deviceProfileId: string;
154 } 155 }
155 type MarkerList = DeviceInfo & { marker: any; label: any }; 156 type MarkerList = DeviceInfo & { marker: any; label: any };
@@ -376,7 +377,7 @@ @@ -376,7 +377,7 @@
376 width: 330, // 信息窗口宽度 377 width: 330, // 信息窗口宽度
377 height: 0, // 信息窗口高度 378 height: 0, // 信息窗口高度
378 }; 379 };
379 - const { name, organizationDTO, deviceState, deviceProfile, deviceType } = record; 380 + const { name, alias, organizationDTO, deviceState, deviceProfile, deviceType } = record;
380 const { address, longitude, latitude } = record.deviceInfo; 381 const { address, longitude, latitude } = record.deviceInfo;
381 382
382 // 创建信息窗口对象 383 // 创建信息窗口对象
@@ -387,7 +388,7 @@ @@ -387,7 +388,7 @@
387 let infoWindow = new BMap.InfoWindow( 388 let infoWindow = new BMap.InfoWindow(
388 ` 389 `
389 <div style="display:flex;justify-content:space-between; margin:20px 0px;"> 390 <div style="display:flex;justify-content:space-between; margin:20px 0px;">
390 - <div style="font-size:16px;font-weight:bold">${name}</div> 391 + <div style="font-size:16px;font-weight:bold">${alias || name}</div>
391 ${ 392 ${
392 deviceState === 'INACTIVE' 393 deviceState === 'INACTIVE'
393 ? `<div style="display:flex;align-items:center;"><img style="width:15px;height:15px" src="${djh}" class="mr-1">待激活</div>` 394 ? `<div style="display:flex;align-items:center;"><img style="width:15px;height:15px" src="${djh}" class="mr-1">待激活</div>`
1 -import { ref } from 'vue';  
2 -import { BasicColumn, FormSchema } from '/@/components/Table';  
3 -import type { FormSchema as QFormSchema } from '/@/components/Form/index';  
4 -import { getOrganizationList } from '/@/api/system/system';  
5 -import { copyTransFun } from '/@/utils/fnUtils';  
6 -import { findDictItemByCode } from '/@/api/system/dict';  
7 -import { isTiming, isWeek, isMonth, isFixedTime } from './timeConfig';  
8 -import { AggregateDataEnum } from '../../device/localtion/cpns/TimePeriodForm/config';  
9 -import {  
10 - getPacketIntervalByRange,  
11 - getPacketIntervalByValue,  
12 - intervalOption,  
13 -} from '../../device/localtion/cpns/TimePeriodForm/helper';  
14 -import moment, { Moment } from 'moment';  
15 -  
16 -export enum QueryWay {  
17 - LATEST = 'latest',  
18 - TIME_PERIOD = 'timePeriod',  
19 -}  
20 -export enum SchemaFiled {  
21 - WAY = 'queryMode',  
22 - TIME_PERIOD = 'timePeriod',  
23 - KEYS = 'keys',  
24 - DATE_RANGE = 'dataRange',  
25 - START_TS = 'startTs',  
26 - END_TS = 'endTs',  
27 - INTERVAL = 'interval',  
28 - LIMIT = 'limit',  
29 - AGG = 'agg',  
30 - ORDER_BY = 'orderBy',  
31 -}  
32 -export const organizationId = ref('');  
33 -  
34 -// 表格配置  
35 -export const columns: BasicColumn[] = [  
36 - {  
37 - title: '配置名称',  
38 - dataIndex: 'name',  
39 - width: 120,  
40 - },  
41 - {  
42 - title: '所属组织',  
43 - dataIndex: 'organizationDTO.name',  
44 - width: 120,  
45 - },  
46 - {  
47 - title: '数据类型',  
48 - dataIndex: 'dataType',  
49 - width: 120,  
50 - format: (_text: string, record: Recordable) => {  
51 - return record.dataType === 0 ? '原始数据' : '聚合数据';  
52 - },  
53 - },  
54 - {  
55 - title: '配置状态',  
56 - dataIndex: 'status',  
57 - width: 120,  
58 - slots: { customRender: 'configStatus' },  
59 - },  
60 - {  
61 - title: '执行方式',  
62 - dataIndex: 'executeWay',  
63 - width: 160,  
64 - format: (_text: string, record: Recordable) => {  
65 - return record.executeWay === 0 ? '立即执行' : '定时执行';  
66 - },  
67 - },  
68 - {  
69 - title: '执行设备',  
70 - dataIndex: 'devices',  
71 - width: 160,  
72 - slots: { customRender: 'doDeviceSlot' },  
73 - },  
74 - {  
75 - title: '创建人',  
76 - dataIndex: 'createUserName',  
77 - width: 180,  
78 - },  
79 - {  
80 - title: '创建时间',  
81 - dataIndex: 'createTime',  
82 - width: 180,  
83 - },  
84 -];  
85 -export const viewDeviceColumn: BasicColumn[] = [  
86 - {  
87 - title: '设备',  
88 - dataIndex: 'device',  
89 - width: 80,  
90 - },  
91 - {  
92 - title: '属性',  
93 - dataIndex: 'attribute',  
94 - width: 120,  
95 - },  
96 -];  
97 -  
98 -// 查询配置  
99 -export const searchFormSchema: FormSchema[] = [  
100 - {  
101 - field: 'name',  
102 - label: '配置名称',  
103 - component: 'Input',  
104 - colProps: { span: 6 },  
105 - componentProps: {  
106 - maxLength: 36,  
107 - placeholder: '请输入配置名称',  
108 - },  
109 - },  
110 - {  
111 - field: 'status',  
112 - label: '配置状态',  
113 - component: 'Select',  
114 - colProps: { span: 6 },  
115 - componentProps: {  
116 - options: [  
117 - {  
118 - label: '启用',  
119 - value: 1,  
120 - },  
121 - {  
122 - label: '禁用',  
123 - value: 0,  
124 - },  
125 - ],  
126 - placeholder: '请选择配置状态',  
127 - },  
128 - },  
129 - {  
130 - field: 'sendTime',  
131 - label: '创建时间',  
132 - component: 'RangePicker',  
133 - componentProps: {  
134 - showTime: {  
135 - defaultValue: [moment('00:00:00', 'HH:mm:ss'), moment('23:59:59', 'HH:mm:ss')],  
136 - },  
137 - },  
138 - colProps: { span: 6 },  
139 - },  
140 -];  
141 -  
142 -// 新增编辑配置  
143 -export const formSchema: QFormSchema[] = [  
144 - {  
145 - field: 'name',  
146 - label: '报表名称',  
147 - colProps: { span: 24 },  
148 - required: true,  
149 - component: 'Input',  
150 - componentProps: {  
151 - maxLength: 64,  
152 - placeholder: '请输入报表名称',  
153 - },  
154 - },  
155 - {  
156 - field: 'organizationId',  
157 - label: '所属组织',  
158 - colProps: { span: 24 },  
159 - component: 'ApiTreeSelect',  
160 - required: true,  
161 - componentProps: () => {  
162 - return {  
163 - maxLength: 250,  
164 - placeholder: '请选择所属组织',  
165 - api: async () => {  
166 - const data = await getOrganizationList();  
167 - copyTransFun(data as any as any[]);  
168 - return data;  
169 - },  
170 - async onChange(e) {  
171 - organizationId.value = e;  
172 - },  
173 - };  
174 - },  
175 - },  
176 - {  
177 - field: 'remark',  
178 - label: '描述',  
179 - colProps: { span: 24 },  
180 - component: 'InputTextArea',  
181 - componentProps: {  
182 - maxLength: 255,  
183 - placeholder: '请输入描述',  
184 - },  
185 - },  
186 - {  
187 - field: 'executeWay',  
188 - component: 'RadioGroup',  
189 - helpMessage: [  
190 - `立即执行,在创建完报表配置后,启用配置即执行。  
191 - 定时执行,用户定义执行时间,启用后,  
192 - 在满足执行时间条件后,自动执行。`,  
193 - ],  
194 - label: '执行方式',  
195 - colProps: {  
196 - span: 24,  
197 - },  
198 - defaultValue: 0,  
199 - componentProps: ({ formActionType }) => {  
200 - const { updateSchema, setFieldsValue } = formActionType;  
201 - const options = [  
202 - {  
203 - label: '立即执行',  
204 - value: 0,  
205 - },  
206 - {  
207 - label: '定时执行',  
208 - value: 1,  
209 - },  
210 - ];  
211 - return {  
212 - options,  
213 - placeholder: '请选择执行方式',  
214 - onChange(e) {  
215 - let dataCompareOpions: any = [];  
216 - setFieldsValue({  
217 - startTs: 1000,  
218 - interval: 1000,  
219 - });  
220 - if (e.target.value == 0) {  
221 - setFieldsValue({ queryMode: QueryWay.LATEST });  
222 - dataCompareOpions = [  
223 - { label: '固定周期', value: QueryWay.LATEST },  
224 - { label: '自定义周期', value: QueryWay.TIME_PERIOD },  
225 - ];  
226 - updateSchema({  
227 - field: SchemaFiled.WAY,  
228 - componentProps: {  
229 - options: dataCompareOpions,  
230 - },  
231 - });  
232 - } else {  
233 - setFieldsValue({ queryMode: QueryWay.LATEST });  
234 - setFieldsValue({ startTs: 5000 });  
235 - setFieldsValue({ interval: 1000 });  
236 - dataCompareOpions = [{ label: '固定周期', value: QueryWay.LATEST }];  
237 - updateSchema({  
238 - defaultValue: QueryWay.LATEST,  
239 - field: SchemaFiled.WAY,  
240 - componentProps: {  
241 - options: dataCompareOpions,  
242 - },  
243 - });  
244 - }  
245 - },  
246 - maxLength: 250,  
247 - };  
248 - },  
249 - },  
250 - {  
251 - field: 'cycleType',  
252 - component: 'Select',  
253 - label: '周期',  
254 - required: true,  
255 - colProps: { span: 24 },  
256 - defaultValue: 0,  
257 - componentProps: {  
258 - placeholder: '请选择周期',  
259 - options: [  
260 - { label: '每日', value: 0 },  
261 - { label: '每周', value: 1 },  
262 - { label: '每月', value: 2 },  
263 - ],  
264 - },  
265 - ifShow: ({ values }) => isTiming(values.executeWay),  
266 - },  
267 - {  
268 - field: 'currentCycle',  
269 - component: 'ApiSelect',  
270 - label: '每周',  
271 - required: true,  
272 - colProps: { span: 24 },  
273 - defaultValue: '0 0 0 ? * MON',  
274 - componentProps: {  
275 - placeholder: '请选择周期',  
276 - api: findDictItemByCode,  
277 - params: {  
278 - dictCode: 'every_week',  
279 - },  
280 - labelField: 'itemText',  
281 - valueField: 'itemValue',  
282 - },  
283 - ifShow: ({ values }) => isWeek(values.cycleType),  
284 - },  
285 - {  
286 - field: 'cycleTime',  
287 - component: 'ApiSelect',  
288 - label: '每月',  
289 - required: true,  
290 - colProps: { span: 24 },  
291 - defaultValue: '0 0 0 1 * ? *',  
292 - componentProps: {  
293 - placeholder: '请选择月份',  
294 - api: findDictItemByCode,  
295 - params: {  
296 - dictCode: 'every_month',  
297 - },  
298 - labelField: 'itemText',  
299 - valueField: 'itemValue',  
300 - },  
301 - ifShow: ({ values }) => isMonth(values.cycleType),  
302 - },  
303 - {  
304 - field: 'cronTime',  
305 - component: 'ApiSelect',  
306 - label: '时间',  
307 - required: true,  
308 - colProps: { span: 24 },  
309 - defaultValue: '0 0 0 * * ?',  
310 - componentProps: {  
311 - placeholder: '请选择时间',  
312 - api: findDictItemByCode,  
313 - params: {  
314 - dictCode: 'every_day',  
315 - },  
316 - labelField: 'itemText',  
317 - valueField: 'itemValue',  
318 - },  
319 - ifShow: ({ values }) => isTiming(values.executeWay),  
320 - },  
321 - {  
322 - field: 'devices',  
323 - label: '设备',  
324 - component: 'Select',  
325 - slot: 'devices',  
326 - colProps: { span: 24 },  
327 - },  
328 - {  
329 - field: 'dataType',  
330 - label: '数据类型',  
331 - required: true,  
332 - component: 'Select',  
333 - componentProps: ({ formActionType }) => {  
334 - const { updateSchema, setFieldsValue } = formActionType;  
335 - const options = [  
336 - { label: '原始数据', value: 0 },  
337 - { label: '聚合数据', value: 1 },  
338 - ];  
339 - return {  
340 - options,  
341 - onSelect(e) {  
342 - let dataCompareOpions: any = [];  
343 - if (e == 0) {  
344 - setFieldsValue({ agg: 'NONE' });  
345 - dataCompareOpions = [{ label: '空', value: AggregateDataEnum.NONE }];  
346 - updateSchema({  
347 - field: SchemaFiled.AGG,  
348 - componentProps: {  
349 - options: dataCompareOpions,  
350 - },  
351 - });  
352 - } else {  
353 - setFieldsValue({ agg: '' });  
354 - dataCompareOpions = [  
355 - { label: '最小值', value: AggregateDataEnum.MIN },  
356 - { label: '最大值', value: AggregateDataEnum.MAX },  
357 - { label: '平均值', value: AggregateDataEnum.AVG },  
358 - { label: '求和', value: AggregateDataEnum.SUM },  
359 - { label: '计数', value: AggregateDataEnum.COUNT },  
360 - ];  
361 - updateSchema({  
362 - field: SchemaFiled.AGG,  
363 - componentProps: {  
364 - options: dataCompareOpions,  
365 - },  
366 - });  
367 - }  
368 - },  
369 - maxLength: 250,  
370 - placeholder: '请选择属性性质',  
371 - };  
372 - },  
373 - colProps: { span: 24 },  
374 - },  
375 - {  
376 - field: SchemaFiled.AGG,  
377 - label: '聚合条件',  
378 - component: 'Select',  
379 - required: true,  
380 - componentProps: {  
381 - placeholder: '请选择聚合条件',  
382 - getPopupContainer: () => document.body,  
383 - },  
384 - },  
385 - {  
386 - field: 'limit',  
387 - required: true,  
388 - label: '最大条数',  
389 - component: 'InputNumber',  
390 - defaultValue: 100,  
391 - ifShow({ values }) {  
392 - return values[SchemaFiled.AGG] === AggregateDataEnum.NONE;  
393 - },  
394 - colProps: { span: 12 },  
395 - componentProps: {  
396 - placeholder: '请输入最大条数',  
397 - min: 7,  
398 - max: 50000,  
399 - },  
400 - },  
401 - {  
402 - field: SchemaFiled.WAY,  
403 - label: '查询周期',  
404 - component: 'RadioGroup',  
405 - defaultValue: QueryWay.LATEST,  
406 - required: true,  
407 - componentProps({ formActionType }) {  
408 - const { setFieldsValue } = formActionType;  
409 - return {  
410 - placeholder: '请选择查询周期',  
411 - options: [  
412 - { label: '固定周期', value: QueryWay.LATEST },  
413 - { label: '自定义周期', value: QueryWay.TIME_PERIOD },  
414 - ],  
415 - onChange(value) {  
416 - console.log(value);  
417 - value === QueryWay.LATEST  
418 - ? setFieldsValue({  
419 - [SchemaFiled.DATE_RANGE]: [],  
420 - [SchemaFiled.START_TS]: null,  
421 - [SchemaFiled.END_TS]: null,  
422 - })  
423 - : setFieldsValue({ [SchemaFiled.START_TS]: null });  
424 - },  
425 - };  
426 - },  
427 - },  
428 - {  
429 - field: SchemaFiled.DATE_RANGE,  
430 - label: '时间段',  
431 - component: 'RangePicker',  
432 - required: true,  
433 - ifShow({ values }) {  
434 - return values[SchemaFiled.WAY] === QueryWay.TIME_PERIOD && !isFixedTime(values.executeWay);  
435 - },  
436 - // componentProps: {  
437 - // showTime: {  
438 - // defaultValue: [moment('00:00:00', 'HH:mm:ss'), moment('23:59:59', 'HH:mm:ss')],  
439 - // },  
440 - // },  
441 - componentProps({ formActionType }) {  
442 - const { setFieldsValue } = formActionType;  
443 - let dates: Moment[] = [];  
444 - return {  
445 - showTime: {  
446 - defaultValue: [moment('00:00:00', 'HH:mm:ss'), moment('23:59:59', 'HH:mm:ss')],  
447 - },  
448 - onCalendarChange(value: Moment[]) {  
449 - dates = value;  
450 - },  
451 - disabledDate(current: Moment) {  
452 - if (!dates || dates.length === 0 || !current) {  
453 - return false;  
454 - }  
455 - const diffDate = current.diff(dates[0], 'years', true);  
456 - return Math.abs(diffDate) > 1;  
457 - },  
458 - onChange() {  
459 - dates = [];  
460 - setFieldsValue({ dateGroupGap: null });  
461 - },  
462 - getPopupContainer: () => document.body,  
463 - };  
464 - },  
465 - colProps: {  
466 - span: 10,  
467 - },  
468 - },  
469 - {  
470 - field: 'dateGroupGap',  
471 - label: '分组间隔',  
472 - component: 'Select',  
473 - dynamicRules: ({ model }) => {  
474 - return [  
475 - {  
476 - required: model[SchemaFiled.AGG] !== AggregateDataEnum.NONE,  
477 - message: '分组间隔为必填项',  
478 - type: 'number',  
479 - },  
480 - ];  
481 - },  
482 - ifShow({ values }) {  
483 - return values[SchemaFiled.WAY] === QueryWay.TIME_PERIOD && !isFixedTime(values.executeWay);  
484 - },  
485 - componentProps({ formModel, formActionType }) {  
486 - const options =  
487 - formModel[SchemaFiled.WAY] === QueryWay.LATEST  
488 - ? getPacketIntervalByValue(formModel[SchemaFiled.START_TS])  
489 - : getPacketIntervalByRange(formModel[SchemaFiled.DATE_RANGE]);  
490 - if (formModel[SchemaFiled.AGG] !== AggregateDataEnum.NONE) {  
491 - formActionType.setFieldsValue({ [SchemaFiled.LIMIT]: null });  
492 - }  
493 - return {  
494 - options,  
495 - getPopupContainer: () => document.body,  
496 - };  
497 - },  
498 - },  
499 - {  
500 - field: SchemaFiled.START_TS,  
501 - label: '最近时间',  
502 - component: 'Select',  
503 - required: true,  
504 - ifShow({ values }) {  
505 - return values[SchemaFiled.WAY] == QueryWay.LATEST;  
506 - },  
507 - componentProps({ formActionType }) {  
508 - const { setFieldsValue } = formActionType;  
509 - return {  
510 - defaultValue: 1000,  
511 - placeholder: '请选择近期时间',  
512 - options: intervalOption,  
513 - onChange() {  
514 - setFieldsValue({ [SchemaFiled.INTERVAL]: null });  
515 - },  
516 - };  
517 - },  
518 - },  
519 - {  
520 - field: SchemaFiled.INTERVAL,  
521 - label: '间隔时间',  
522 - component: 'Select',  
523 - required: true,  
524 - ifShow({ values }) {  
525 - return values[SchemaFiled.WAY] == QueryWay.LATEST;  
526 - },  
527 - componentProps({ formModel, formActionType }) {  
528 - const options =  
529 - formModel[SchemaFiled.WAY] === QueryWay.LATEST  
530 - ? getPacketIntervalByValue(formModel[SchemaFiled.START_TS])  
531 - : getPacketIntervalByRange(formModel[SchemaFiled.DATE_RANGE]);  
532 - if (formModel[SchemaFiled.AGG] !== AggregateDataEnum.NONE) {  
533 - formActionType.setFieldsValue({ [SchemaFiled.LIMIT]: null });  
534 - }  
535 - return {  
536 - placeholder: '请选择间隔时间',  
537 - options,  
538 - };  
539 - },  
540 - },  
541 -]; 1 +import { ref } from 'vue';
  2 +import { BasicColumn, FormSchema } from '/@/components/Table';
  3 +import { FormSchema as QFormSchema, useComponentRegister } from '/@/components/Form/index';
  4 +import { findDictItemByCode } from '/@/api/system/dict';
  5 +import { isTiming, isWeek, isMonth, isFixedTime } from './timeConfig';
  6 +import { AggregateDataEnum } from '../../device/localtion/cpns/TimePeriodForm/config';
  7 +import {
  8 + getPacketIntervalByRange,
  9 + getPacketIntervalByValue,
  10 + intervalOption,
  11 +} from '../../device/localtion/cpns/TimePeriodForm/helper';
  12 +import moment, { Moment } from 'moment';
  13 +import { OrgTreeSelect } from '../../common/OrgTreeSelect';
  14 +useComponentRegister('OrgTreeSelect', OrgTreeSelect);
  15 +export enum QueryWay {
  16 + LATEST = 'latest',
  17 + TIME_PERIOD = 'timePeriod',
  18 +}
  19 +export enum SchemaFiled {
  20 + WAY = 'queryMode',
  21 + TIME_PERIOD = 'timePeriod',
  22 + KEYS = 'keys',
  23 + DATE_RANGE = 'dataRange',
  24 + START_TS = 'startTs',
  25 + END_TS = 'endTs',
  26 + INTERVAL = 'interval',
  27 + LIMIT = 'limit',
  28 + AGG = 'agg',
  29 + ORDER_BY = 'orderBy',
  30 +}
  31 +export const organizationId = ref('');
  32 +
  33 +// 表格配置
  34 +export const columns: BasicColumn[] = [
  35 + {
  36 + title: '配置名称',
  37 + dataIndex: 'name',
  38 + width: 120,
  39 + },
  40 + {
  41 + title: '所属组织',
  42 + dataIndex: 'organizationDTO.name',
  43 + width: 120,
  44 + },
  45 + {
  46 + title: '数据类型',
  47 + dataIndex: 'dataType',
  48 + width: 120,
  49 + format: (_text: string, record: Recordable) => {
  50 + return record.dataType === 0 ? '原始数据' : '聚合数据';
  51 + },
  52 + },
  53 + {
  54 + title: '配置状态',
  55 + dataIndex: 'status',
  56 + width: 120,
  57 + slots: { customRender: 'configStatus' },
  58 + },
  59 + {
  60 + title: '执行方式',
  61 + dataIndex: 'executeWay',
  62 + width: 160,
  63 + format: (_text: string, record: Recordable) => {
  64 + return record.executeWay === 0 ? '立即执行' : '定时执行';
  65 + },
  66 + },
  67 + {
  68 + title: '执行设备',
  69 + dataIndex: 'devices',
  70 + width: 160,
  71 + slots: { customRender: 'doDeviceSlot' },
  72 + },
  73 + {
  74 + title: '创建人',
  75 + dataIndex: 'createUserName',
  76 + width: 180,
  77 + },
  78 + {
  79 + title: '创建时间',
  80 + dataIndex: 'createTime',
  81 + width: 180,
  82 + },
  83 +];
  84 +export const viewDeviceColumn: BasicColumn[] = [
  85 + {
  86 + title: '设备',
  87 + dataIndex: 'device',
  88 + width: 80,
  89 + },
  90 + {
  91 + title: '属性',
  92 + dataIndex: 'attribute',
  93 + width: 120,
  94 + },
  95 +];
  96 +
  97 +// 查询配置
  98 +export const searchFormSchema: FormSchema[] = [
  99 + {
  100 + field: 'name',
  101 + label: '配置名称',
  102 + component: 'Input',
  103 + colProps: { span: 6 },
  104 + componentProps: {
  105 + maxLength: 36,
  106 + placeholder: '请输入配置名称',
  107 + },
  108 + },
  109 + {
  110 + field: 'status',
  111 + label: '配置状态',
  112 + component: 'Select',
  113 + colProps: { span: 6 },
  114 + componentProps: {
  115 + options: [
  116 + {
  117 + label: '启用',
  118 + value: 1,
  119 + },
  120 + {
  121 + label: '禁用',
  122 + value: 0,
  123 + },
  124 + ],
  125 + placeholder: '请选择配置状态',
  126 + },
  127 + },
  128 + {
  129 + field: 'sendTime',
  130 + label: '创建时间',
  131 + component: 'RangePicker',
  132 + componentProps: {
  133 + showTime: {
  134 + defaultValue: [moment('00:00:00', 'HH:mm:ss'), moment('23:59:59', 'HH:mm:ss')],
  135 + },
  136 + },
  137 + colProps: { span: 6 },
  138 + },
  139 +];
  140 +
  141 +// 新增编辑配置
  142 +export const formSchema: QFormSchema[] = [
  143 + {
  144 + field: 'name',
  145 + label: '报表名称',
  146 + colProps: { span: 24 },
  147 + required: true,
  148 + component: 'Input',
  149 + componentProps: {
  150 + maxLength: 64,
  151 + placeholder: '请输入报表名称',
  152 + },
  153 + },
  154 + {
  155 + field: 'organizationId',
  156 + label: '所属组织',
  157 + colProps: { span: 24 },
  158 + component: 'OrgTreeSelect',
  159 + required: true,
  160 + componentProps: () => {
  161 + return {
  162 + async onChange(e) {
  163 + organizationId.value = e;
  164 + },
  165 + };
  166 + },
  167 + },
  168 + {
  169 + field: 'remark',
  170 + label: '描述',
  171 + colProps: { span: 24 },
  172 + component: 'InputTextArea',
  173 + componentProps: {
  174 + maxLength: 255,
  175 + placeholder: '请输入描述',
  176 + },
  177 + },
  178 + {
  179 + field: 'executeWay',
  180 + component: 'RadioGroup',
  181 + helpMessage: [
  182 + `立即执行,在创建完报表配置后,启用配置即执行。
  183 + 定时执行,用户定义执行时间,启用后,
  184 + 在满足执行时间条件后,自动执行。`,
  185 + ],
  186 + label: '执行方式',
  187 + colProps: {
  188 + span: 24,
  189 + },
  190 + defaultValue: 0,
  191 + componentProps: ({ formActionType }) => {
  192 + const { updateSchema, setFieldsValue } = formActionType;
  193 + const options = [
  194 + {
  195 + label: '立即执行',
  196 + value: 0,
  197 + },
  198 + {
  199 + label: '定时执行',
  200 + value: 1,
  201 + },
  202 + ];
  203 + return {
  204 + options,
  205 + placeholder: '请选择执行方式',
  206 + onChange(e) {
  207 + let dataCompareOpions: any = [];
  208 + setFieldsValue({
  209 + startTs: 1000,
  210 + interval: 1000,
  211 + });
  212 + if (e.target.value == 0) {
  213 + setFieldsValue({ queryMode: QueryWay.LATEST });
  214 + dataCompareOpions = [
  215 + { label: '固定周期', value: QueryWay.LATEST },
  216 + { label: '自定义周期', value: QueryWay.TIME_PERIOD },
  217 + ];
  218 + updateSchema({
  219 + field: SchemaFiled.WAY,
  220 + componentProps: {
  221 + options: dataCompareOpions,
  222 + },
  223 + });
  224 + } else {
  225 + setFieldsValue({ queryMode: QueryWay.LATEST });
  226 + setFieldsValue({ startTs: 5000 });
  227 + setFieldsValue({ interval: 1000 });
  228 + dataCompareOpions = [{ label: '固定周期', value: QueryWay.LATEST }];
  229 + updateSchema({
  230 + defaultValue: QueryWay.LATEST,
  231 + field: SchemaFiled.WAY,
  232 + componentProps: {
  233 + options: dataCompareOpions,
  234 + },
  235 + });
  236 + }
  237 + },
  238 + maxLength: 250,
  239 + };
  240 + },
  241 + },
  242 + {
  243 + field: 'cycleType',
  244 + component: 'Select',
  245 + label: '周期',
  246 + required: true,
  247 + colProps: { span: 24 },
  248 + defaultValue: 0,
  249 + componentProps: {
  250 + placeholder: '请选择周期',
  251 + options: [
  252 + { label: '每日', value: 0 },
  253 + { label: '每周', value: 1 },
  254 + { label: '每月', value: 2 },
  255 + ],
  256 + },
  257 + ifShow: ({ values }) => isTiming(values.executeWay),
  258 + },
  259 + {
  260 + field: 'currentCycle',
  261 + component: 'ApiSelect',
  262 + label: '每周',
  263 + required: true,
  264 + colProps: { span: 24 },
  265 + defaultValue: '0 0 0 ? * MON',
  266 + componentProps: {
  267 + placeholder: '请选择周期',
  268 + api: findDictItemByCode,
  269 + params: {
  270 + dictCode: 'every_week',
  271 + },
  272 + labelField: 'itemText',
  273 + valueField: 'itemValue',
  274 + },
  275 + ifShow: ({ values }) => isWeek(values.cycleType),
  276 + },
  277 + {
  278 + field: 'cycleTime',
  279 + component: 'ApiSelect',
  280 + label: '每月',
  281 + required: true,
  282 + colProps: { span: 24 },
  283 + defaultValue: '0 0 0 1 * ? *',
  284 + componentProps: {
  285 + placeholder: '请选择月份',
  286 + api: findDictItemByCode,
  287 + params: {
  288 + dictCode: 'every_month',
  289 + },
  290 + labelField: 'itemText',
  291 + valueField: 'itemValue',
  292 + },
  293 + ifShow: ({ values }) => isMonth(values.cycleType),
  294 + },
  295 + {
  296 + field: 'cronTime',
  297 + component: 'ApiSelect',
  298 + label: '时间',
  299 + required: true,
  300 + colProps: { span: 24 },
  301 + defaultValue: '0 0 0 * * ?',
  302 + componentProps: {
  303 + placeholder: '请选择时间',
  304 + api: findDictItemByCode,
  305 + params: {
  306 + dictCode: 'every_day',
  307 + },
  308 + labelField: 'itemText',
  309 + valueField: 'itemValue',
  310 + },
  311 + ifShow: ({ values }) => isTiming(values.executeWay),
  312 + },
  313 + {
  314 + field: 'devices',
  315 + label: '设备',
  316 + component: 'Select',
  317 + slot: 'devices',
  318 + colProps: { span: 24 },
  319 + },
  320 + {
  321 + field: 'dataType',
  322 + label: '数据类型',
  323 + required: true,
  324 + component: 'Select',
  325 + componentProps: ({ formActionType }) => {
  326 + const { updateSchema, setFieldsValue } = formActionType;
  327 + const options = [
  328 + { label: '原始数据', value: 0 },
  329 + { label: '聚合数据', value: 1 },
  330 + ];
  331 + return {
  332 + options,
  333 + onSelect(e) {
  334 + let dataCompareOpions: any = [];
  335 + if (e == 0) {
  336 + setFieldsValue({ agg: 'NONE' });
  337 + dataCompareOpions = [{ label: '空', value: AggregateDataEnum.NONE }];
  338 + updateSchema({
  339 + field: SchemaFiled.AGG,
  340 + componentProps: {
  341 + options: dataCompareOpions,
  342 + },
  343 + });
  344 + } else {
  345 + setFieldsValue({ agg: '' });
  346 + dataCompareOpions = [
  347 + { label: '最小值', value: AggregateDataEnum.MIN },
  348 + { label: '最大值', value: AggregateDataEnum.MAX },
  349 + { label: '平均值', value: AggregateDataEnum.AVG },
  350 + { label: '求和', value: AggregateDataEnum.SUM },
  351 + { label: '计数', value: AggregateDataEnum.COUNT },
  352 + ];
  353 + updateSchema({
  354 + field: SchemaFiled.AGG,
  355 + componentProps: {
  356 + options: dataCompareOpions,
  357 + },
  358 + });
  359 + }
  360 + },
  361 + maxLength: 250,
  362 + placeholder: '请选择属性性质',
  363 + };
  364 + },
  365 + colProps: { span: 24 },
  366 + },
  367 + {
  368 + field: SchemaFiled.AGG,
  369 + label: '聚合条件',
  370 + component: 'Select',
  371 + required: true,
  372 + componentProps: {
  373 + placeholder: '请选择聚合条件',
  374 + getPopupContainer: () => document.body,
  375 + },
  376 + },
  377 + {
  378 + field: 'limit',
  379 + required: true,
  380 + label: '最大条数',
  381 + component: 'InputNumber',
  382 + defaultValue: 100,
  383 + ifShow({ values }) {
  384 + return values[SchemaFiled.AGG] === AggregateDataEnum.NONE;
  385 + },
  386 + colProps: { span: 12 },
  387 + componentProps: {
  388 + placeholder: '请输入最大条数',
  389 + min: 7,
  390 + max: 50000,
  391 + },
  392 + },
  393 + {
  394 + field: SchemaFiled.WAY,
  395 + label: '查询周期',
  396 + component: 'RadioGroup',
  397 + defaultValue: QueryWay.LATEST,
  398 + required: true,
  399 + componentProps({ formActionType }) {
  400 + const { setFieldsValue } = formActionType;
  401 + return {
  402 + placeholder: '请选择查询周期',
  403 + options: [
  404 + { label: '固定周期', value: QueryWay.LATEST },
  405 + { label: '自定义周期', value: QueryWay.TIME_PERIOD },
  406 + ],
  407 + onChange(value) {
  408 + console.log(value);
  409 + value === QueryWay.LATEST
  410 + ? setFieldsValue({
  411 + [SchemaFiled.DATE_RANGE]: [],
  412 + [SchemaFiled.START_TS]: null,
  413 + [SchemaFiled.END_TS]: null,
  414 + })
  415 + : setFieldsValue({ [SchemaFiled.START_TS]: null });
  416 + },
  417 + };
  418 + },
  419 + },
  420 + {
  421 + field: SchemaFiled.DATE_RANGE,
  422 + label: '时间段',
  423 + component: 'RangePicker',
  424 + required: true,
  425 + ifShow({ values }) {
  426 + return values[SchemaFiled.WAY] === QueryWay.TIME_PERIOD && !isFixedTime(values.executeWay);
  427 + },
  428 + // componentProps: {
  429 + // showTime: {
  430 + // defaultValue: [moment('00:00:00', 'HH:mm:ss'), moment('23:59:59', 'HH:mm:ss')],
  431 + // },
  432 + // },
  433 + componentProps({ formActionType }) {
  434 + const { setFieldsValue } = formActionType;
  435 + let dates: Moment[] = [];
  436 + return {
  437 + showTime: {
  438 + defaultValue: [moment('00:00:00', 'HH:mm:ss'), moment('23:59:59', 'HH:mm:ss')],
  439 + },
  440 + onCalendarChange(value: Moment[]) {
  441 + dates = value;
  442 + },
  443 + disabledDate(current: Moment) {
  444 + if (!dates || dates.length === 0 || !current) {
  445 + return false;
  446 + }
  447 + const diffDate = current.diff(dates[0], 'years', true);
  448 + return Math.abs(diffDate) > 1;
  449 + },
  450 + onChange() {
  451 + dates = [];
  452 + setFieldsValue({ dateGroupGap: null });
  453 + },
  454 + getPopupContainer: () => document.body,
  455 + };
  456 + },
  457 + colProps: {
  458 + span: 10,
  459 + },
  460 + },
  461 + {
  462 + field: 'dateGroupGap',
  463 + label: '分组间隔',
  464 + component: 'Select',
  465 + dynamicRules: ({ model }) => {
  466 + return [
  467 + {
  468 + required: model[SchemaFiled.AGG] !== AggregateDataEnum.NONE,
  469 + message: '分组间隔为必填项',
  470 + type: 'number',
  471 + },
  472 + ];
  473 + },
  474 + ifShow({ values }) {
  475 + return values[SchemaFiled.WAY] === QueryWay.TIME_PERIOD && !isFixedTime(values.executeWay);
  476 + },
  477 + componentProps({ formModel, formActionType }) {
  478 + const options =
  479 + formModel[SchemaFiled.WAY] === QueryWay.LATEST
  480 + ? getPacketIntervalByValue(formModel[SchemaFiled.START_TS])
  481 + : getPacketIntervalByRange(formModel[SchemaFiled.DATE_RANGE]);
  482 + if (formModel[SchemaFiled.AGG] !== AggregateDataEnum.NONE) {
  483 + formActionType.setFieldsValue({ [SchemaFiled.LIMIT]: null });
  484 + }
  485 + return {
  486 + options,
  487 + getPopupContainer: () => document.body,
  488 + };
  489 + },
  490 + },
  491 + {
  492 + field: SchemaFiled.START_TS,
  493 + label: '最近时间',
  494 + component: 'Select',
  495 + required: true,
  496 + ifShow({ values }) {
  497 + return values[SchemaFiled.WAY] == QueryWay.LATEST;
  498 + },
  499 + componentProps({ formActionType }) {
  500 + const { setFieldsValue } = formActionType;
  501 + return {
  502 + defaultValue: 1000,
  503 + placeholder: '请选择近期时间',
  504 + options: intervalOption,
  505 + onChange() {
  506 + setFieldsValue({ [SchemaFiled.INTERVAL]: null });
  507 + },
  508 + };
  509 + },
  510 + },
  511 + {
  512 + field: SchemaFiled.INTERVAL,
  513 + label: '间隔时间',
  514 + component: 'Select',
  515 + required: true,
  516 + ifShow({ values }) {
  517 + return values[SchemaFiled.WAY] == QueryWay.LATEST;
  518 + },
  519 + componentProps({ formModel, formActionType }) {
  520 + const options =
  521 + formModel[SchemaFiled.WAY] === QueryWay.LATEST
  522 + ? getPacketIntervalByValue(formModel[SchemaFiled.START_TS])
  523 + : getPacketIntervalByRange(formModel[SchemaFiled.DATE_RANGE]);
  524 + if (formModel[SchemaFiled.AGG] !== AggregateDataEnum.NONE) {
  525 + formActionType.setFieldsValue({ [SchemaFiled.LIMIT]: null });
  526 + }
  527 + return {
  528 + placeholder: '请选择间隔时间',
  529 + options,
  530 + };
  531 + },
  532 + },
  533 +];
1 import { FormSchema } from '/@/components/Form'; 1 import { FormSchema } from '/@/components/Form';
2 import { findDictItemByCode } from '/@/api/system/dict'; 2 import { findDictItemByCode } from '/@/api/system/dict';
3 -import { h, ref } from 'vue'; 3 +import { h, ref, unref } from 'vue';
4 import { isExistDataManagerNameApi } from '/@/api/datamanager/dataManagerApi'; 4 import { isExistDataManagerNameApi } from '/@/api/datamanager/dataManagerApi';
5 import { getDeviceProfile } from '/@/api/alarm/position'; 5 import { getDeviceProfile } from '/@/api/alarm/position';
6 import { BasicColumn, BasicTableProps } from '/@/components/Table'; 6 import { BasicColumn, BasicTableProps } from '/@/components/Table';
@@ -8,6 +8,8 @@ import { devicePage } from '/@/api/device/deviceManager'; @@ -8,6 +8,8 @@ import { devicePage } from '/@/api/device/deviceManager';
8 import { Tag } from 'ant-design-vue'; 8 import { Tag } from 'ant-design-vue';
9 import { DeviceRecord } from '/@/api/device/model/deviceModel'; 9 import { DeviceRecord } from '/@/api/device/model/deviceModel';
10 import { FETCH_SETTING } from '/@/components/Table/src/const'; 10 import { FETCH_SETTING } from '/@/components/Table/src/const';
  11 +import { useCopyToClipboard } from '/@/hooks/web/useCopyToClipboard';
  12 +import { useMessage } from '/@/hooks/web/useMessage';
11 13
12 const typeValue = ref(''); 14 const typeValue = ref('');
13 export enum CredentialsEnum { 15 export enum CredentialsEnum {
@@ -100,7 +102,8 @@ const deviceTableFormSchema: FormSchema[] = [ @@ -100,7 +102,8 @@ const deviceTableFormSchema: FormSchema[] = [
100 }, 102 },
101 }, 103 },
102 ]; 104 ];
103 - 105 +const { clipboardRef, isSuccessRef } = useCopyToClipboard();
  106 +const { createMessage } = useMessage();
104 const deviceTableColumn: BasicColumn[] = [ 107 const deviceTableColumn: BasicColumn[] = [
105 { 108 {
106 title: '状态', 109 title: '状态',
@@ -125,8 +128,20 @@ const deviceTableColumn: BasicColumn[] = [ @@ -125,8 +128,20 @@ const deviceTableColumn: BasicColumn[] = [
125 dataIndex: 'name', 128 dataIndex: 'name',
126 customRender: ({ record }) => { 129 customRender: ({ record }) => {
127 return h('div', [ 130 return h('div', [
128 - h('div', `${record.alias}/${record.name}`),  
129 - // h('div', { class: 'text-blue-400 truncate', title: record.sn }, record.sn), 131 + h(
  132 + 'div',
  133 + {
  134 + class: 'cursor-pointer',
  135 + onClick: () => {
  136 + clipboardRef.value = record.name;
  137 + if (unref(isSuccessRef)) createMessage.success('复制成功~');
  138 + },
  139 + },
  140 + [
  141 + h('div', { class: 'text-blue-400 truncate' }, record.alias),
  142 + h('div', { class: 'text-blue-400 truncate' }, record.name),
  143 + ]
  144 + ),
130 ]); 145 ]);
131 }, 146 },
132 }, 147 },
@@ -15,6 +15,10 @@ import { ModelOfMatterParams } from '/@/api/device/model/modelOfMatterModel'; @@ -15,6 +15,10 @@ import { ModelOfMatterParams } from '/@/api/device/model/modelOfMatterModel';
15 import useCommonFun from '../hooks/useCommonFun'; 15 import useCommonFun from '../hooks/useCommonFun';
16 import { DeviceProfileModel } from '/@/api/device/model/deviceModel'; 16 import { DeviceProfileModel } from '/@/api/device/model/deviceModel';
17 import { TransportTypeEnum } from '/@/views/device/profiles/components/TransportDescript/const'; 17 import { TransportTypeEnum } from '/@/views/device/profiles/components/TransportDescript/const';
  18 +import { useComponentRegister } from '/@/components/Form';
  19 +import { OrgTreeSelect } from '/@/views/common/OrgTreeSelect';
  20 +
  21 +useComponentRegister('OrgTreeSelect', OrgTreeSelect);
18 22
19 const { useByProductGetAttribute } = useCommonFun(); 23 const { useByProductGetAttribute } = useCommonFun();
20 export type TOption = { 24 export type TOption = {
@@ -109,13 +113,8 @@ export const formSchema: FormSchema[] = [ @@ -109,13 +113,8 @@ export const formSchema: FormSchema[] = [
109 field: 'organizationId', 113 field: 'organizationId',
110 label: '所属组织', 114 label: '所属组织',
111 colProps: { span: 24 }, 115 colProps: { span: 24 },
112 - component: 'ApiTreeSelect', 116 + component: 'OrgTreeSelect',
113 componentProps: { 117 componentProps: {
114 - api: async () => {  
115 - const data = await screenLinkOrganizationGetApi();  
116 - copyTransFun(data as any as any[]);  
117 - return data;  
118 - },  
119 onChange(value) { 118 onChange(value) {
120 organizationId.value = value; 119 organizationId.value = value;
121 }, 120 },
1 import { TaskTargetEnum, TaskTargetNameEnum, TaskTypeEnum, TaskTypeNameEnum } from '../../config'; 1 import { TaskTargetEnum, TaskTargetNameEnum, TaskTypeEnum, TaskTypeNameEnum } from '../../config';
2 import { findDictItemByCode } from '/@/api/system/dict'; 2 import { findDictItemByCode } from '/@/api/system/dict';
3 -import { FormSchema, useComponentRegister } from '/@/components/Form'; 3 +import { FormSchema, Rule, useComponentRegister } from '/@/components/Form';
4 import { 4 import {
5 DevicePicker, 5 DevicePicker,
6 validateDevicePicker, 6 validateDevicePicker,
@@ -211,14 +211,18 @@ export const formSchemas: FormSchema[] = [ @@ -211,14 +211,18 @@ export const formSchemas: FormSchema[] = [
211 field: FormFieldsEnum.RPC_COMMAND, 211 field: FormFieldsEnum.RPC_COMMAND,
212 component: 'PollCommandInput', 212 component: 'PollCommandInput',
213 label: '自定义数据流', 213 label: '自定义数据流',
214 - rules: [{ required: true, message: '请输入自定义数据流' }],  
215 - dynamicRules: ({ model }) =>  
216 - model[FormFieldsEnum.PUSH_WAY] === PushWayEnum.MQTT ? JSONEditorValidator() : [], 214 + dynamicRules: ({ model }) => {
  215 + const rules: Rule[] = [{ required: true, message: '请输入自定义数据流' }];
  216 + return model[FormFieldsEnum.PUSH_WAY] === PushWayEnum.MQTT
  217 + ? [...rules, ...JSONEditorValidator()]
  218 + : rules;
  219 + },
217 ifShow: ({ model }) => model[FormFieldsEnum.EXECUTE_CONTENT_TYPE] === TaskTypeEnum.CUSTOM, 220 ifShow: ({ model }) => model[FormFieldsEnum.EXECUTE_CONTENT_TYPE] === TaskTypeEnum.CUSTOM,
218 valueField: 'value', 221 valueField: 'value',
219 changeEvent: 'update:value', 222 changeEvent: 'update:value',
220 - componentProps: ({ formModel }) => { 223 + componentProps: ({ formModel, formActionType }) => {
221 const pushMode = Reflect.get(formModel, FormFieldsEnum.PUSH_WAY); 224 const pushMode = Reflect.get(formModel, FormFieldsEnum.PUSH_WAY);
  225 + formActionType?.clearValidate(FormFieldsEnum.RPC_COMMAND);
222 return { 226 return {
223 inputProps: { 227 inputProps: {
224 placeholder: '请输入自定义数据流', 228 placeholder: '请输入自定义数据流',
@@ -232,7 +236,9 @@ export const formSchemas: FormSchema[] = [ @@ -232,7 +236,9 @@ export const formSchemas: FormSchema[] = [
232 component: 'PollCommandInput', 236 component: 'PollCommandInput',
233 label: 'ModbusRTU轮询', 237 label: 'ModbusRTU轮询',
234 rules: [{ required: true, message: '请输入Modbus RTU 轮询指令' }], 238 rules: [{ required: true, message: '请输入Modbus RTU 轮询指令' }],
235 - ifShow: ({ model }) => model[FormFieldsEnum.EXECUTE_CONTENT_TYPE] === TaskTypeEnum.MODBUS_RTU, 239 + ifShow: ({ model }) =>
  240 + model[FormFieldsEnum.EXECUTE_CONTENT_TYPE] === TaskTypeEnum.MODBUS_RTU &&
  241 + model[FormFieldsEnum.PUSH_WAY] === PushWayEnum.TCP,
236 valueField: 'value', 242 valueField: 'value',
237 changeEvent: 'update:value', 243 changeEvent: 'update:value',
238 componentProps: () => { 244 componentProps: () => {
@@ -345,6 +351,7 @@ export const formSchemas: FormSchema[] = [ @@ -345,6 +351,7 @@ export const formSchemas: FormSchema[] = [
345 field: FormFieldsEnum.EXECUTE_TIME_INTERVAL, 351 field: FormFieldsEnum.EXECUTE_TIME_INTERVAL,
346 label: '间隔时间', 352 label: '间隔时间',
347 component: 'InputNumber', 353 component: 'InputNumber',
  354 + rules: [{ required: true, message: '请输入间隔时间', type: 'number' }],
348 ifShow: ({ model }) => model[FormFieldsEnum.EXECUTE_TIME_TYPE] === ExecuteTimeTypeEnum.POLL, 355 ifShow: ({ model }) => model[FormFieldsEnum.EXECUTE_TIME_TYPE] === ExecuteTimeTypeEnum.POLL,
349 componentProps: ({ formModel }) => { 356 componentProps: ({ formModel }) => {
350 const unit = formModel[FormFieldsEnum.POLL_UNIT]; 357 const unit = formModel[FormFieldsEnum.POLL_UNIT];
@@ -78,7 +78,7 @@ export const formSchemas: FormSchema[] = [ @@ -78,7 +78,7 @@ export const formSchemas: FormSchema[] = [
78 const result = await getDevicesByDeviceIds(data!); 78 const result = await getDevicesByDeviceIds(data!);
79 return result.data.map((item) => ({ 79 return result.data.map((item) => ({
80 label: item.alias || item.name, 80 label: item.alias || item.name,
81 - value: 'tbDeviceId', 81 + value: item.tbDeviceId,
82 })); 82 }));
83 } else { 83 } else {
84 const result = await getMeetTheConditionsDevice({ 84 const result = await getMeetTheConditionsDevice({
@@ -87,7 +87,7 @@ export const formSchemas: FormSchema[] = [ @@ -87,7 +87,7 @@ export const formSchemas: FormSchema[] = [
87 }); 87 });
88 return result.map((item) => ({ 88 return result.map((item) => ({
89 label: item.alias || item.name, 89 label: item.alias || item.name,
90 - value: 'tbDeviceId', 90 + value: item.tbDeviceId,
91 })); 91 }));
92 } 92 }
93 } catch (error) { 93 } catch (error) {
1 -import { getOrganizationList } from '/@/api/system/system';  
2 -import { FormSchema } from '/@/components/Form';  
3 -import { copyTransFun } from '/@/utils/fnUtils'; 1 +import { FormSchema, useComponentRegister } from '/@/components/Form';
  2 +import { OrgTreeSelect } from '/@/views/common/OrgTreeSelect';
4 export enum ViewType { 3 export enum ViewType {
5 PRIVATE_VIEW = 'PRIVATE_VIEW', 4 PRIVATE_VIEW = 'PRIVATE_VIEW',
6 PUBLIC_VIEW = 'PUBLIC_VIEW', 5 PUBLIC_VIEW = 'PUBLIC_VIEW',
7 } 6 }
  7 +useComponentRegister('OrgTreeSelect', OrgTreeSelect);
8 8
9 export const formSchema: FormSchema[] = [ 9 export const formSchema: FormSchema[] = [
10 { 10 {
@@ -19,20 +19,9 @@ export const formSchema: FormSchema[] = [ @@ -19,20 +19,9 @@ export const formSchema: FormSchema[] = [
19 }, 19 },
20 { 20 {
21 field: 'organizationId', 21 field: 'organizationId',
22 - component: 'ApiTreeSelect', 22 + component: 'OrgTreeSelect',
23 label: '组织', 23 label: '组织',
24 rules: [{ required: true, message: '组织为必填项' }], 24 rules: [{ required: true, message: '组织为必填项' }],
25 - componentProps() {  
26 - return {  
27 - placeholder: '请选择组织',  
28 - api: async () => {  
29 - const data = await getOrganizationList();  
30 - copyTransFun(data as any as any[]);  
31 - return data;  
32 - },  
33 - getPopupContainer: () => document.body,  
34 - };  
35 - },  
36 }, 25 },
37 { 26 {
38 field: 'remark', 27 field: 'remark',