Commit 818b1fa501b4ab522c17aa60d76ba2cd4c472301
Merge branch 'f-dev' into 'main'
feat:数据流转新增其他属性 和pem上传文件 pref:优化Tree箭头等其他优化 See merge request huang/yun-teng-iot-front!252
Showing
15 changed files
with
257 additions
and
365 deletions
... | ... | @@ -27,6 +27,8 @@ import { BasicUpload } from '/@/components/Upload'; |
27 | 27 | import { StrengthMeter } from '/@/components/StrengthMeter'; |
28 | 28 | import { IconPicker } from '/@/components/Icon'; |
29 | 29 | import { CountdownInput } from '/@/components/CountDown'; |
30 | +//自定义组件 | |
31 | +import JAddInput from './jeecg/components/JAddInput.vue'; | |
30 | 32 | |
31 | 33 | const componentMap = new Map<ComponentType, Component>(); |
32 | 34 | |
... | ... | @@ -61,6 +63,8 @@ componentMap.set('IconPicker', IconPicker); |
61 | 63 | componentMap.set('InputCountDown', CountdownInput); |
62 | 64 | |
63 | 65 | componentMap.set('Upload', BasicUpload); |
66 | +//注册自定义组件 | |
67 | +componentMap.set('JAddInput', JAddInput); | |
64 | 68 | |
65 | 69 | export function add(compName: ComponentType, component: Component) { |
66 | 70 | componentMap.set(compName, component); | ... | ... |
1 | +<template> | |
2 | + <div v-for="(param, index) in dynamicInput.params" :key="index" style="display: flex"> | |
3 | + <a-input | |
4 | + placeholder="请输入参数key" | |
5 | + v-model:value="param.label" | |
6 | + style="width: 30%; margin-bottom: 5px" | |
7 | + @input="emitChange" | |
8 | + /> | |
9 | + <a-input | |
10 | + placeholder="请输入参数value" | |
11 | + v-model:value="param.value" | |
12 | + style="width: 30%; margin: 0 0 5px 5px" | |
13 | + @input="emitChange" | |
14 | + /> | |
15 | + <MinusCircleOutlined | |
16 | + v-if="dynamicInput.params.length > min" | |
17 | + class="dynamic-delete-button" | |
18 | + @click="remove(param)" | |
19 | + style="width: 50px" | |
20 | + /> | |
21 | + </div> | |
22 | + <div> | |
23 | + <a-button type="dashed" style="width: 60%" @click="add"> | |
24 | + <PlusOutlined /> | |
25 | + 新增 | |
26 | + </a-button> | |
27 | + </div> | |
28 | +</template> | |
29 | +<script lang="ts"> | |
30 | + import { MinusCircleOutlined, PlusOutlined } from '@ant-design/icons-vue'; | |
31 | + import { defineComponent, reactive, UnwrapRef, watchEffect } from 'vue'; | |
32 | + import { propTypes } from '/@/utils/propTypes'; | |
33 | + import { isEmpty } from '/@/utils/is'; | |
34 | + | |
35 | + interface Params { | |
36 | + label: string; | |
37 | + value: string; | |
38 | + } | |
39 | + | |
40 | + export default defineComponent({ | |
41 | + name: 'JAddInput', | |
42 | + components: { | |
43 | + MinusCircleOutlined, | |
44 | + PlusOutlined, | |
45 | + }, | |
46 | + //--------------不继承Antd Design Vue Input的所有属性 否则控制台报大片警告-------------- | |
47 | + inheritAttrs: false, | |
48 | + props: { | |
49 | + value: propTypes.object.def({}), | |
50 | + //自定义删除按钮多少才会显示 | |
51 | + min: propTypes.integer.def(0), | |
52 | + }, | |
53 | + emits: ['change', 'update:value'], | |
54 | + setup(props, { emit }) { | |
55 | + //input动态数据 | |
56 | + const dynamicInput: UnwrapRef<{ params: Params[] }> = reactive({ params: [] }); | |
57 | + //删除Input | |
58 | + const remove = (item: Params) => { | |
59 | + let index = dynamicInput.params.indexOf(item); | |
60 | + if (index !== -1) { | |
61 | + dynamicInput.params.splice(index, 1); | |
62 | + } | |
63 | + emitChange(); | |
64 | + }; | |
65 | + //新增Input | |
66 | + const add = () => { | |
67 | + dynamicInput.params.push({ | |
68 | + label: '', | |
69 | + value: '', | |
70 | + }); | |
71 | + emitChange(); | |
72 | + }; | |
73 | + | |
74 | + //监听传入数据value | |
75 | + watchEffect(() => { | |
76 | + initVal(); | |
77 | + }); | |
78 | + | |
79 | + /** | |
80 | + * 初始化数值 | |
81 | + */ | |
82 | + function initVal() { | |
83 | + dynamicInput.params = []; | |
84 | + if (props.value) { | |
85 | + let jsonObj = props.value; | |
86 | + Object.keys(jsonObj).forEach((key) => { | |
87 | + dynamicInput.params.push({ label: key, value: jsonObj[key] }); | |
88 | + }); | |
89 | + } | |
90 | + // if (props.value && props.value.indexOf('{') == 0) { | |
91 | + // let jsonObj = JSON.parse(props.value); | |
92 | + // Object.keys(jsonObj).forEach((key) => { | |
93 | + // dynamicInput.params.push({ label: key, value: jsonObj[key] }); | |
94 | + // }); | |
95 | + // } | |
96 | + } | |
97 | + /** | |
98 | + * 数值改变 | |
99 | + */ | |
100 | + function emitChange() { | |
101 | + let obj = {}; | |
102 | + if (dynamicInput.params.length > 0) { | |
103 | + dynamicInput.params.forEach((item) => { | |
104 | + obj[item['label']] = item['value']; | |
105 | + }); | |
106 | + } | |
107 | + emit('change', isEmpty(obj) ? '' : obj); | |
108 | + emit('update:value', isEmpty(obj) ? '' : obj); | |
109 | + // emit('change', isEmpty(obj) ? '' : JSON.stringify(obj)); | |
110 | + // emit('update:value', isEmpty(obj) ? '' : JSON.stringify(obj)); | |
111 | + } | |
112 | + | |
113 | + return { | |
114 | + dynamicInput, | |
115 | + emitChange, | |
116 | + remove, | |
117 | + add, | |
118 | + }; | |
119 | + }, | |
120 | + }); | |
121 | +</script> | |
122 | +<style scoped> | |
123 | + .dynamic-delete-button { | |
124 | + cursor: pointer; | |
125 | + position: relative; | |
126 | + top: 4px; | |
127 | + font-size: 24px; | |
128 | + color: #999; | |
129 | + transition: all 0.3s; | |
130 | + } | |
131 | + | |
132 | + .dynamic-delete-button:hover { | |
133 | + color: #777; | |
134 | + } | |
135 | + | |
136 | + .dynamic-delete-button[disabled] { | |
137 | + cursor: not-allowed; | |
138 | + opacity: 0.5; | |
139 | + } | |
140 | +</style> | ... | ... |
... | ... | @@ -473,14 +473,14 @@ |
473 | 473 | </script> |
474 | 474 | <style lang="less"> |
475 | 475 | .fold-left { |
476 | - z-index: 9999; | |
476 | + z-index: 1; | |
477 | 477 | cursor: pointer; |
478 | 478 | position: absolute; |
479 | 479 | top: 0.85rem; |
480 | 480 | left: 1.1rem; |
481 | 481 | } |
482 | 482 | .fold-right { |
483 | - z-index: 9999; | |
483 | + z-index: 1; | |
484 | 484 | cursor: pointer; |
485 | 485 | position: absolute; |
486 | 486 | top: 0.85rem; | ... | ... |
... | ... | @@ -32,7 +32,7 @@ export const CoapSchemas: FormSchema[] = [ |
32 | 32 | { |
33 | 33 | field: 'coapDeviceType', |
34 | 34 | component: 'Select', |
35 | - label: 'CoAP类型', | |
35 | + label: 'CoAP 设备类型', | |
36 | 36 | defaultValue: 'DEFAULT', |
37 | 37 | componentProps: { |
38 | 38 | options: [ |
... | ... | @@ -45,7 +45,7 @@ export const CoapSchemas: FormSchema[] = [ |
45 | 45 | { |
46 | 46 | field: 'transportPayloadType', |
47 | 47 | component: 'Select', |
48 | - label: '设备消息', | |
48 | + label: 'CoAP 设备消息 Payload', | |
49 | 49 | defaultValue: 'JSON', |
50 | 50 | componentProps: { |
51 | 51 | options: [ |
... | ... | @@ -59,14 +59,14 @@ export const CoapSchemas: FormSchema[] = [ |
59 | 59 | { |
60 | 60 | field: 'powerMode', |
61 | 61 | component: 'Select', |
62 | - label: '模式', | |
62 | + label: 'Power Saving Mode', | |
63 | 63 | defaultValue: 'DRX', |
64 | 64 | componentProps: { |
65 | 65 | options: [ |
66 | - { label: 'Power Saving Mode', value: 'PSM' }, | |
67 | - { label: 'Discontinuous Reception', value: 'DRX' }, | |
66 | + { label: 'Power Saving Mode (PSM)', value: 'PSM' }, | |
67 | + { label: 'Discontinuous Reception (DRX)', value: 'DRX' }, | |
68 | 68 | { |
69 | - label: 'Extended Discontinuous Reception', | |
69 | + label: 'Extended Discontinuous Reception (eDRX)', | |
70 | 70 | value: 'E_DRX', |
71 | 71 | }, |
72 | 72 | ], |
... | ... | @@ -76,7 +76,7 @@ export const CoapSchemas: FormSchema[] = [ |
76 | 76 | { |
77 | 77 | field: 'psmActivityTimer', |
78 | 78 | component: 'InputNumber', |
79 | - label: 'Timer', | |
79 | + label: 'PSM Activity Timer', | |
80 | 80 | required: true, |
81 | 81 | defaultValue: '10', |
82 | 82 | componentProps: { |
... | ... | @@ -132,7 +132,7 @@ export const CoapSchemas: FormSchema[] = [ |
132 | 132 | { |
133 | 133 | field: 'pagingTransmissionWindow', |
134 | 134 | component: 'InputNumber', |
135 | - label: 'Paging', | |
135 | + label: 'Paging Transmission Window', | |
136 | 136 | required: true, |
137 | 137 | defaultValue: '10', |
138 | 138 | componentProps: { |
... | ... | @@ -159,7 +159,7 @@ export const CoapSchemas: FormSchema[] = [ |
159 | 159 | }, |
160 | 160 | { |
161 | 161 | field: 'deviceTelemetryProtoSchema', |
162 | - label: '遥测数据', | |
162 | + label: '遥测数据 proto schema', | |
163 | 163 | colProps: { span: 22 }, |
164 | 164 | component: 'InputTextArea', |
165 | 165 | componentProps: { |
... | ... | @@ -189,7 +189,7 @@ export const CoapSchemas: FormSchema[] = [ |
189 | 189 | }, |
190 | 190 | { |
191 | 191 | field: 'deviceAttributesProtoSchema', |
192 | - label: 'Attributes', | |
192 | + label: 'Attributes proto schema', | |
193 | 193 | colProps: { span: 22 }, |
194 | 194 | component: 'InputTextArea', |
195 | 195 | componentProps: { |
... | ... | @@ -211,7 +211,7 @@ export const CoapSchemas: FormSchema[] = [ |
211 | 211 | }, |
212 | 212 | { |
213 | 213 | field: 'deviceRpcRequestProtoSchema', |
214 | - label: 'RPC 请求 ', | |
214 | + label: 'RPC 请求 proto schema', | |
215 | 215 | colProps: { span: 22 }, |
216 | 216 | component: 'InputTextArea', |
217 | 217 | componentProps: { |
... | ... | @@ -234,7 +234,7 @@ export const CoapSchemas: FormSchema[] = [ |
234 | 234 | }, |
235 | 235 | { |
236 | 236 | field: 'deviceRpcResponseProtoSchema', |
237 | - label: 'RPC 响应', | |
237 | + label: 'RPC 响应 proto schema', | |
238 | 238 | colProps: { span: 22 }, |
239 | 239 | component: 'InputTextArea', |
240 | 240 | componentProps: { | ... | ... |
... | ... | @@ -20,7 +20,7 @@ export const MqttSchemas: FormSchema[] = [ |
20 | 20 | { |
21 | 21 | field: 'deviceTelemetryTopic', |
22 | 22 | component: 'Input', |
23 | - label: '筛选器', | |
23 | + label: '遥测数据 topic 筛选器', | |
24 | 24 | required: true, |
25 | 25 | defaultValue: 'v1/devices/me/telemetry', |
26 | 26 | componentProps: { |
... | ... | @@ -32,7 +32,7 @@ export const MqttSchemas: FormSchema[] = [ |
32 | 32 | field: 'deviceAttributesTopic', |
33 | 33 | component: 'Input', |
34 | 34 | required: true, |
35 | - label: 'topic filter', | |
35 | + label: 'Attributes topic filter', | |
36 | 36 | defaultValue: 'v1/devices/me/attributes', |
37 | 37 | componentProps: { |
38 | 38 | placeholder: '请输入Attributes topic 筛选器', |
... | ... | @@ -42,22 +42,13 @@ export const MqttSchemas: FormSchema[] = [ |
42 | 42 | { |
43 | 43 | field: 'desc', |
44 | 44 | component: 'InputTextArea', |
45 | - label: '描述', | |
46 | - defaultValue: `支持单[+]和多级[#]通配符。[+] is suitable for any topic filter level。例如: | |
47 | - v1/devices/+/telemetry or | |
48 | - +/devices/+/attributes。[#]可以替换 topic filter 本身,并且必须是 topic 的最后一个符号。例如:# or v1/devices/me/#。 | |
49 | - `, | |
50 | - componentProps: { | |
51 | - autoSize: { | |
52 | - maxRows: 10, | |
53 | - }, | |
54 | - }, | |
55 | - colProps: { span: 23 }, | |
45 | + label: '', | |
46 | + slot: 'descSlot', | |
56 | 47 | }, |
57 | 48 | { |
58 | 49 | field: 'transportPayloadType', |
59 | 50 | component: 'Select', |
60 | - label: '设备信息', | |
51 | + label: 'MQTT 设备 Payload', | |
61 | 52 | defaultValue: 'JSON', |
62 | 53 | componentProps: { |
63 | 54 | options: [ |
... | ... | @@ -89,7 +80,7 @@ export const MqttSchemas: FormSchema[] = [ |
89 | 80 | }, |
90 | 81 | { |
91 | 82 | field: 'deviceTelemetryProtoSchema', |
92 | - label: '遥测数据', | |
83 | + label: '遥测数据 proto schema', | |
93 | 84 | colProps: { span: 23 }, |
94 | 85 | component: 'InputTextArea', |
95 | 86 | componentProps: { |
... | ... | @@ -118,7 +109,7 @@ export const MqttSchemas: FormSchema[] = [ |
118 | 109 | }, |
119 | 110 | { |
120 | 111 | field: 'deviceAttributesProtoSchema', |
121 | - label: 'Attributes', | |
112 | + label: 'Attributes proto schema', | |
122 | 113 | colProps: { span: 23 }, |
123 | 114 | component: 'InputTextArea', |
124 | 115 | componentProps: { |
... | ... | @@ -139,7 +130,7 @@ export const MqttSchemas: FormSchema[] = [ |
139 | 130 | }, |
140 | 131 | { |
141 | 132 | field: 'deviceRpcRequestProtoSchema', |
142 | - label: 'RPC 请求 ', | |
133 | + label: 'RPC 请求 proto schema', | |
143 | 134 | colProps: { span: 23 }, |
144 | 135 | component: 'InputTextArea', |
145 | 136 | componentProps: { |
... | ... | @@ -161,7 +152,7 @@ export const MqttSchemas: FormSchema[] = [ |
161 | 152 | }, |
162 | 153 | { |
163 | 154 | field: 'deviceRpcResponseProtoSchema', |
164 | - label: 'RPC 响应', | |
155 | + label: 'RPC 响应 proto schema', | |
165 | 156 | colProps: { span: 23 }, |
166 | 157 | component: 'InputTextArea', |
167 | 158 | componentProps: { | ... | ... |
... | ... | @@ -9,7 +9,17 @@ |
9 | 9 | " |
10 | 10 | > |
11 | 11 | <div style="margin-top: 1.2vh"> |
12 | - <BasicForm :showResetButton="false" :showSubmitButton="false" @register="register" /> | |
12 | + <BasicForm :showResetButton="false" :showSubmitButton="false" @register="register"> | |
13 | + <template #descSlot> | |
14 | + <div style="width: 47rem; margin-left: 2rem"> | |
15 | + <p> | |
16 | + 支持单[+]和多级[#]通配符。 [+] is suitable for any topic filter | |
17 | + level。例如:v1/devices/+/telemetry or +/devices/+/attributes。 [#]可以替换 topic | |
18 | + filter 本身,并且必须是 topic 的最后一个符号。例如:# or v1/devices/me/#。 | |
19 | + </p> | |
20 | + </div> | |
21 | + </template> | |
22 | + </BasicForm> | |
13 | 23 | </div> |
14 | 24 | </div> |
15 | 25 | </template> |
... | ... | @@ -51,7 +61,7 @@ |
51 | 61 | }); |
52 | 62 | |
53 | 63 | const [register, { validate, resetFields, setFieldsValue }] = useForm({ |
54 | - labelWidth: 80, | |
64 | + labelWidth: 180, | |
55 | 65 | schemas: MqttSchemas, |
56 | 66 | actionColOptions: { |
57 | 67 | span: 14, |
... | ... | @@ -131,7 +141,7 @@ |
131 | 141 | }); |
132 | 142 | </script> |
133 | 143 | <style lang="less" scoped> |
134 | - :deep(.ant-row) { | |
135 | - column-gap: 33px !important; | |
136 | - } | |
144 | + // :deep(.ant-row) { | |
145 | + // column-gap: 33px !important; | |
146 | + // } | |
137 | 147 | </style> | ... | ... |
... | ... | @@ -236,6 +236,9 @@ |
236 | 236 | closeModal(); |
237 | 237 | } else { |
238 | 238 | await addOrEditFunc(); |
239 | + if (allPostForm.configuration == undefined || allPostForm.configuration == null) { | |
240 | + return createMessage.error('数据流转下一步配置项必填'); | |
241 | + } | |
239 | 242 | await postAddConvertApi(allPostForm); |
240 | 243 | createMessage.success('数据流转编辑成功'); |
241 | 244 | emit('success'); | ... | ... |
... | ... | @@ -55,31 +55,6 @@ export const modeForm: FormSchema[] = [ |
55 | 55 | }, |
56 | 56 | ]; |
57 | 57 | |
58 | -export const modeKafkaInseretKeyAndValueForm: FormSchema[] = [ | |
59 | - { | |
60 | - field: 'key', | |
61 | - label: 'Key', | |
62 | - colProps: { span: 12 }, | |
63 | - required: true, | |
64 | - component: 'Input', | |
65 | - componentProps: { | |
66 | - maxLength: 255, | |
67 | - placeholder: '请输入Key', | |
68 | - }, | |
69 | - }, | |
70 | - { | |
71 | - field: 'value', | |
72 | - label: 'Value', | |
73 | - colProps: { span: 12 }, | |
74 | - required: true, | |
75 | - component: 'Input', | |
76 | - componentProps: { | |
77 | - maxLength: 255, | |
78 | - placeholder: '请输入Value', | |
79 | - }, | |
80 | - }, | |
81 | -]; | |
82 | - | |
83 | 58 | export const modeApiInseretKeyAndValueForm: FormSchema[] = [ |
84 | 59 | { |
85 | 60 | field: 'key', |
... | ... | @@ -116,7 +91,7 @@ export const modeKafkaForm: FormSchema[] = [ |
116 | 91 | maxLength: 255, |
117 | 92 | placeholder: '请输入名称', |
118 | 93 | }, |
119 | - dynamicRules: ({ values }) => { | |
94 | + dynamicRules: () => { | |
120 | 95 | return [ |
121 | 96 | { |
122 | 97 | required: true, |
... | ... | @@ -242,11 +217,10 @@ export const modeKafkaForm: FormSchema[] = [ |
242 | 217 | }, |
243 | 218 | }, |
244 | 219 | { |
245 | - field: '1', | |
220 | + field: 'otherProperties', | |
246 | 221 | label: '其他属性', |
247 | 222 | colProps: { span: 24 }, |
248 | - slot: 'addValue', | |
249 | - component: 'Input', | |
223 | + component: 'JAddInput', | |
250 | 224 | }, |
251 | 225 | { |
252 | 226 | field: 'addMetadataKeyValuesAsKafkaHeaders', |
... | ... | @@ -496,7 +470,7 @@ export const modeRabbitMqForm: FormSchema[] = [ |
496 | 470 | maxLength: 255, |
497 | 471 | placeholder: '请输入名称', |
498 | 472 | }, |
499 | - dynamicRules: ({ values }) => { | |
473 | + dynamicRules: () => { | |
500 | 474 | return [ |
501 | 475 | { |
502 | 476 | required: true, |
... | ... | @@ -637,11 +611,10 @@ export const modeRabbitMqForm: FormSchema[] = [ |
637 | 611 | }, |
638 | 612 | }, |
639 | 613 | { |
640 | - field: '1', | |
614 | + field: 'clientProperties', | |
641 | 615 | label: '客户端属性', |
642 | 616 | colProps: { span: 24 }, |
643 | - component: 'InputTextArea', | |
644 | - slot: 'addKeyAndValue', | |
617 | + component: 'JAddInput', | |
645 | 618 | }, |
646 | 619 | { |
647 | 620 | field: 'description', |
... | ... | @@ -784,7 +757,7 @@ export const modeApiForm: FormSchema[] = [ |
784 | 757 | label: 'Password', |
785 | 758 | colProps: { span: 12 }, |
786 | 759 | required: true, |
787 | - component: 'Input', | |
760 | + component: 'InputPassword', | |
788 | 761 | componentProps: { |
789 | 762 | maxLength: 255, |
790 | 763 | placeholder: '请输入Proxy password', |
... | ... | @@ -854,35 +827,11 @@ export const modeApiForm: FormSchema[] = [ |
854 | 827 | }, |
855 | 828 | }, |
856 | 829 | { |
857 | - field: 'Header', | |
858 | - label: 'Header', | |
859 | - colProps: { span: 12 }, | |
860 | - required: true, | |
861 | - component: 'Input', | |
862 | - defaultValue: 'Content-Type', | |
863 | - componentProps: { | |
864 | - maxLength: 255, | |
865 | - placeholder: 'Content-Type', | |
866 | - }, | |
867 | - }, | |
868 | - { | |
869 | - field: 'Value', | |
870 | - label: 'Value', | |
871 | - colProps: { span: 12 }, | |
872 | - required: true, | |
873 | - component: 'Input', | |
874 | - defaultValue: 'application/json', | |
875 | - componentProps: { | |
876 | - maxLength: 255, | |
877 | - placeholder: 'application/json', | |
878 | - }, | |
879 | - }, | |
880 | - { | |
881 | - field: '1', | |
882 | - label: '', | |
830 | + field: 'headers', | |
831 | + label: 'Headers', | |
883 | 832 | colProps: { span: 24 }, |
884 | - component: 'Input', | |
885 | - slot: 'addKeyAndValue', | |
833 | + defaultValue: { 'Content-Type': 'application/json' }, | |
834 | + component: 'JAddInput', | |
886 | 835 | }, |
887 | 836 | |
888 | 837 | { | ... | ... |
1 | 1 | <template> |
2 | 2 | <div class="transfer-config-mode"> |
3 | 3 | <BasicForm :showSubmitButton="false" @register="register"> |
4 | - <template #addKeyAndValue="{ field }"> | |
5 | - <span style="display: none">{{ field }}</span> | |
6 | - <div> | |
7 | - <div> | |
8 | - <template v-for="(item, index) in keyAndValueArr" :key="index"> | |
9 | - <span style="display: none">{{ item + index }}</span> | |
10 | - <BasicForm | |
11 | - :showResetButton="false" | |
12 | - :showSubmitButton="false" | |
13 | - @register="registerKeyAndValue" | |
14 | - /> | |
15 | - </template> | |
16 | - <div> | |
17 | - <a-button type="primary" class="mr-4" @click="addKeyAndValueFunc">添加</a-button> | |
18 | - <a-button color="error" @click="removeKeyAndValueFunc">删除</a-button> | |
19 | - </div> | |
20 | - </div> | |
21 | - </div> | |
22 | - </template> | |
23 | 4 | <template #uploadAdd1="{ field }"> |
24 | 5 | <span style="display: none">{{ field }}</span> |
25 | 6 | <a-upload-dragger |
... | ... | @@ -86,16 +67,12 @@ |
86 | 67 | <script lang="ts"> |
87 | 68 | import { defineComponent, ref, reactive, nextTick } from 'vue'; |
88 | 69 | import { BasicForm, useForm } from '/@/components/Form'; |
89 | - import { modeApiForm, modeApiInseretKeyAndValueForm, CredentialsEnum } from '../config'; | |
70 | + import { modeApiForm, CredentialsEnum } from '../config'; | |
90 | 71 | import { InboxOutlined } from '@ant-design/icons-vue'; |
91 | 72 | import { Upload } from 'ant-design-vue'; |
92 | 73 | import { useMessage } from '/@/hooks/web/useMessage'; |
93 | 74 | import { uploadApi } from '/@/api/personal/index'; |
94 | 75 | |
95 | - interface IKeyAndValue { | |
96 | - key: string; | |
97 | - value: string; | |
98 | - } | |
99 | 76 | export default defineComponent({ |
100 | 77 | components: { |
101 | 78 | BasicForm, |
... | ... | @@ -111,27 +88,16 @@ |
111 | 88 | let fileList1: any = ref<[]>([]); |
112 | 89 | let fileList2: any = ref<[]>([]); |
113 | 90 | let fileList3: any = ref<[]>([]); |
114 | - const keyAndValueArr = ref<[]>([]); | |
115 | - const temp = ref({}); | |
116 | - let tempObj = ref({}); | |
117 | - const otherPropertiesValues = reactive({ | |
118 | - headers: {}, | |
119 | - }); | |
120 | 91 | const credentialsV: any = reactive({ |
121 | 92 | credentials: { |
122 | 93 | type: '', |
123 | 94 | }, |
124 | 95 | }); |
125 | - const keyAndValueArrTemp = ref<[]>([]); | |
126 | - const keyAndValueObj = reactive<IKeyAndValue>({ | |
127 | - key: '', | |
128 | - value: '', | |
129 | - }); | |
130 | 96 | const sonValues: any = reactive({ |
131 | 97 | configuration: {}, |
132 | 98 | }); |
133 | 99 | const [register, { validate, setFieldsValue, resetFields: defineClearFunc }] = useForm({ |
134 | - labelWidth: 80, | |
100 | + labelWidth: 120, | |
135 | 101 | schemas: modeApiForm, |
136 | 102 | actionColOptions: { |
137 | 103 | span: 14, |
... | ... | @@ -143,16 +109,6 @@ |
143 | 109 | submitFunc: customSubmitFunc, |
144 | 110 | }); |
145 | 111 | |
146 | - const [ | |
147 | - registerKeyAndValue, | |
148 | - { validate: validateKeyAndValue, resetFields: defineClearKeyAndValueFunc }, | |
149 | - ] = useForm({ | |
150 | - labelWidth: 80, | |
151 | - schemas: modeApiInseretKeyAndValueForm, | |
152 | - actionColOptions: { | |
153 | - span: 14, | |
154 | - }, | |
155 | - }); | |
156 | 112 | const setStepTwoFieldsValueFunc = (v, v1) => { |
157 | 113 | setFieldsValue(v); |
158 | 114 | setFieldsValue({ |
... | ... | @@ -163,14 +119,16 @@ |
163 | 119 | username: v.credentials?.username, |
164 | 120 | type: v.credentials?.type, |
165 | 121 | }); |
166 | - fileList1.value = [{ name: v.credentials?.caCertFileName.slice(39) }]; | |
167 | - fileList2.value = [{ name: v.credentials?.certFileName.slice(39) }]; | |
168 | - fileList3.value = [{ name: v.credentials?.privateKeyFileName.slice(39) }]; | |
122 | + fileList1.value = [{ name: v.credentials?.caCertFileName.slice(39), uid: '4' }]; | |
123 | + fileList2.value = [{ name: v.credentials?.certFileName.slice(39), uid: '5' }]; | |
124 | + fileList3.value = [{ name: v.credentials?.privateKeyFileName.slice(39), uid: '6' }]; | |
125 | + caCertFileName.value = v.credentials?.caCertFileName; | |
126 | + certFileName.value = v.credentials?.certFileName; | |
127 | + privateKeyFileName.value = v.credentials?.privateKeyFileName; | |
169 | 128 | }; |
170 | 129 | const customClearStepTwoValueFunc = async () => { |
171 | 130 | nextTick(() => { |
172 | 131 | defineClearFunc(); |
173 | - defineClearKeyAndValueFunc(); | |
174 | 132 | fileList1.value = []; |
175 | 133 | fileList2.value = []; |
176 | 134 | fileList3.value = []; |
... | ... | @@ -190,24 +148,6 @@ |
190 | 148 | } finally { |
191 | 149 | } |
192 | 150 | } |
193 | - const tempGetKeyAndVal = async () => { | |
194 | - temp.value = await validateKeyAndValue(); | |
195 | - }; | |
196 | - | |
197 | - const getDefaultValue = async () => { | |
198 | - await tempGetKeyAndVal(); | |
199 | - keyAndValueArrTemp.value.push(temp.value as never); | |
200 | - }; | |
201 | - | |
202 | - const addKeyAndValueFunc = async () => { | |
203 | - keyAndValueArr.value.push(keyAndValueObj as never); | |
204 | - await tempGetKeyAndVal(); | |
205 | - tempObj.value = temp.value; | |
206 | - keyAndValueArrTemp.value.push(tempObj.value as never); | |
207 | - }; | |
208 | - const removeKeyAndValueFunc = () => { | |
209 | - keyAndValueArr.value.splice(0, 1); | |
210 | - }; | |
211 | 151 | /** |
212 | 152 | * 上传图片 |
213 | 153 | */ |
... | ... | @@ -244,9 +184,6 @@ |
244 | 184 | |
245 | 185 | const getSonValueFunc = async () => { |
246 | 186 | sonValues.configuration = await validate(); |
247 | - if (keyAndValueArrTemp.value.length != 0) { | |
248 | - await getDefaultValue(); | |
249 | - } | |
250 | 187 | credentialsV.credentials.type = sonValues.configuration.type; |
251 | 188 | if (credentialsV.credentials.type == CredentialsEnum.IS_BASIC) { |
252 | 189 | credentialsV.credentials.username = sonValues.configuration.username; |
... | ... | @@ -259,25 +196,14 @@ |
259 | 196 | credentialsV.credentials.privateKeyFileName = privateKeyFileName.value; |
260 | 197 | credentialsV.credentials.password = sonValues.configuration.password; |
261 | 198 | } |
262 | - const kong = {}; | |
263 | - let kongTemp = {}; | |
264 | - keyAndValueArrTemp.value.map((item: any) => { | |
265 | - kong[item.key] = item.value; | |
266 | - }); | |
267 | - kongTemp = JSON.parse(JSON.stringify(kong)); | |
268 | - otherPropertiesValues.headers = kongTemp; | |
269 | - Object.assign(sonValues.configuration, otherPropertiesValues, credentialsV); | |
199 | + Object.assign(sonValues.configuration, credentialsV); | |
270 | 200 | return sonValues; |
271 | 201 | }; |
272 | 202 | return { |
273 | 203 | register, |
274 | 204 | setStepTwoFieldsValueFunc, |
275 | 205 | customClearStepTwoValueFunc, |
276 | - addKeyAndValueFunc, | |
277 | - removeKeyAndValueFunc, | |
278 | 206 | getSonValueFunc, |
279 | - keyAndValueArr, | |
280 | - registerKeyAndValue, | |
281 | 207 | handleChange, |
282 | 208 | fileList1, |
283 | 209 | fileList2, | ... | ... |
1 | 1 | <template> |
2 | 2 | <div class="transfer-config-mode"> |
3 | - <BasicForm :showSubmitButton="false" @register="register"> | |
4 | - <template #addValue="{ field }"> | |
5 | - <span style="display: none">{{ field }}</span> | |
6 | - <div> | |
7 | - <div> | |
8 | - <div v-if="keyAndValueArr.length > 0"> | |
9 | - <template v-for="(item, index) in keyAndValueArr" :key="index"> | |
10 | - <span style="display: none">{{ item + index }}</span> | |
11 | - <BasicForm | |
12 | - :showResetButton="false" | |
13 | - :showSubmitButton="false" | |
14 | - @register="registerKeyAndValue" | |
15 | - /> | |
16 | - </template> | |
17 | - </div> | |
18 | - <div> | |
19 | - <a-button type="primary" class="mr-4" @click="addKeyAndValueFunc">添加</a-button> | |
20 | - <a-button color="error" @click="removeKeyAndValueFunc">删除</a-button> | |
21 | - </div> | |
22 | - </div> | |
23 | - </div> | |
24 | - </template> | |
25 | - </BasicForm> | |
3 | + <BasicForm :showSubmitButton="false" @register="register" /> | |
26 | 4 | </div> |
27 | 5 | </template> |
28 | 6 | <script lang="ts"> |
29 | 7 | import { defineComponent, ref, reactive, nextTick } from 'vue'; |
30 | 8 | import { BasicForm, useForm } from '/@/components/Form'; |
31 | - import { modeKafkaForm, modeKafkaInseretKeyAndValueForm } from '../config'; | |
9 | + import { modeKafkaForm } from '../config'; | |
32 | 10 | import { Alert, Divider, Descriptions } from 'ant-design-vue'; |
33 | 11 | |
34 | - interface IKeyAndValue { | |
35 | - key: string; | |
36 | - value: string; | |
37 | - } | |
38 | - | |
39 | 12 | export default defineComponent({ |
40 | 13 | components: { |
41 | 14 | BasicForm, |
... | ... | @@ -46,26 +19,15 @@ |
46 | 19 | }, |
47 | 20 | emits: ['next', 'prev', 'register'], |
48 | 21 | setup(_, { emit }) { |
49 | - const temp = ref({}); | |
50 | - let tempObj = ref({}); | |
51 | 22 | const keyAndValueArr: any = ref<[]>([]); |
52 | - const keyAndValueArrTemp = ref<[]>([]); | |
53 | 23 | const vType = ref(''); |
54 | - const keyAndValueObj = reactive<IKeyAndValue>({ | |
55 | - key: '', | |
56 | - value: '', | |
57 | - }); | |
58 | 24 | const sonValues = reactive({ |
59 | 25 | configuration: {}, |
60 | 26 | }); |
61 | - const otherPropertiesValues = reactive({ | |
62 | - otherProperties: {}, | |
63 | - }); | |
64 | 27 | const clearName = ref(''); |
65 | - | |
66 | 28 | const [register, { validate, setFieldsValue, resetFields: defineClearFunc, clearValidate }] = |
67 | 29 | useForm({ |
68 | - labelWidth: 80, | |
30 | + labelWidth: 120, | |
69 | 31 | schemas: modeKafkaForm, |
70 | 32 | actionColOptions: { |
71 | 33 | span: 14, |
... | ... | @@ -76,17 +38,6 @@ |
76 | 38 | resetFunc: customResetFunc, |
77 | 39 | }); |
78 | 40 | |
79 | - const [ | |
80 | - registerKeyAndValue, | |
81 | - { validate: validateKeyAndValue, resetFields: defineClearKeyAndValueFunc }, | |
82 | - ] = useForm({ | |
83 | - labelWidth: 80, | |
84 | - schemas: modeKafkaInseretKeyAndValueForm, | |
85 | - actionColOptions: { | |
86 | - span: 14, | |
87 | - }, | |
88 | - }); | |
89 | - | |
90 | 41 | const clearValidateFunc = async () => { |
91 | 42 | await clearValidate(['name']); |
92 | 43 | }; |
... | ... | @@ -103,46 +54,15 @@ |
103 | 54 | const customClearStepTwoValueFunc = async () => { |
104 | 55 | nextTick(() => { |
105 | 56 | defineClearFunc(); |
106 | - defineClearKeyAndValueFunc(); | |
107 | 57 | }); |
108 | 58 | }; |
109 | 59 | async function customResetFunc() { |
110 | 60 | emit('prev'); |
111 | 61 | } |
112 | - | |
113 | - const tempGetKeyAndVal = async () => { | |
114 | - temp.value = await validateKeyAndValue(); | |
115 | - }; | |
116 | - | |
117 | - const getDefaultValue = async () => { | |
118 | - await tempGetKeyAndVal(); | |
119 | - keyAndValueArrTemp.value.push(temp.value as never); | |
120 | - }; | |
121 | - | |
122 | - const addKeyAndValueFunc = async () => { | |
123 | - keyAndValueArr.value.push(keyAndValueObj as never); | |
124 | - await tempGetKeyAndVal(); | |
125 | - tempObj.value = temp.value; | |
126 | - keyAndValueArrTemp.value.push(tempObj.value as never); | |
127 | - }; | |
128 | - const removeKeyAndValueFunc = () => { | |
129 | - keyAndValueArr.value.splice(0, 1); | |
130 | - }; | |
131 | - | |
132 | 62 | const getSonValueFunc = async () => { |
133 | 63 | try { |
134 | 64 | sonValues.configuration = await validate(); |
135 | - if (keyAndValueArrTemp.value.length != 0) { | |
136 | - await getDefaultValue(); | |
137 | - } | |
138 | - const kong = {}; | |
139 | - let kongTemp = {}; | |
140 | - keyAndValueArrTemp.value.map((item: any) => { | |
141 | - kong[item.key] = item.value; | |
142 | - }); | |
143 | - kongTemp = JSON.parse(JSON.stringify(kong)); | |
144 | - otherPropertiesValues.otherProperties = kongTemp; | |
145 | - Object.assign(sonValues.configuration, otherPropertiesValues); | |
65 | + Object.assign(sonValues.configuration); | |
146 | 66 | return sonValues; |
147 | 67 | } catch (e) { |
148 | 68 | return e; |
... | ... | @@ -155,9 +75,6 @@ |
155 | 75 | register, |
156 | 76 | setStepTwoFieldsValueFunc, |
157 | 77 | customClearStepTwoValueFunc, |
158 | - addKeyAndValueFunc, | |
159 | - registerKeyAndValue, | |
160 | - removeKeyAndValueFunc, | |
161 | 78 | customResetFunc, |
162 | 79 | }; |
163 | 80 | }, | ... | ... |
... | ... | @@ -6,6 +6,7 @@ |
6 | 6 | <a-upload-dragger |
7 | 7 | v-model:fileList="fileList1" |
8 | 8 | name="file" |
9 | + :key="1" | |
9 | 10 | :multiple="false" |
10 | 11 | @change="handleChange('T', $event)" |
11 | 12 | :before-upload="() => false" |
... | ... | @@ -27,6 +28,7 @@ |
27 | 28 | <a-upload-dragger |
28 | 29 | v-model:fileList="fileList2" |
29 | 30 | name="file" |
31 | + :key="2" | |
30 | 32 | :multiple="false" |
31 | 33 | @change="handleChange('F', $event)" |
32 | 34 | :before-upload="() => false" |
... | ... | @@ -48,6 +50,7 @@ |
48 | 50 | <a-upload-dragger |
49 | 51 | v-model:fileList="fileList3" |
50 | 52 | name="file" |
53 | + :key="3" | |
51 | 54 | :multiple="false" |
52 | 55 | @change="handleChange('C', $event)" |
53 | 56 | :before-upload="() => false" |
... | ... | @@ -103,7 +106,7 @@ |
103 | 106 | configuration: {}, |
104 | 107 | }); |
105 | 108 | const [register, { validate, setFieldsValue, resetFields: defineClearFunc }] = useForm({ |
106 | - labelWidth: 80, | |
109 | + labelWidth: 120, | |
107 | 110 | schemas: modeMqttForm, |
108 | 111 | actionColOptions: { |
109 | 112 | span: 14, |
... | ... | @@ -158,9 +161,27 @@ |
158 | 161 | username: v.credentials?.username, |
159 | 162 | type: v.credentials?.type, |
160 | 163 | }); |
161 | - fileList1.value = [{ name: v.credentials?.caCertFileName.slice(39) }]; | |
162 | - fileList2.value = [{ name: v.credentials?.certFileName.slice(39) }]; | |
163 | - fileList3.value = [{ name: v.credentials?.privateKeyFileName.slice(39) }]; | |
164 | + fileList1.value = [ | |
165 | + { | |
166 | + name: v.credentials?.caCertFileName.slice(39), | |
167 | + uid: '1', | |
168 | + }, | |
169 | + ]; | |
170 | + fileList2.value = [ | |
171 | + { | |
172 | + name: v.credentials?.certFileName.slice(39), | |
173 | + uid: '2', | |
174 | + }, | |
175 | + ]; | |
176 | + fileList3.value = [ | |
177 | + { | |
178 | + name: v.credentials?.privateKeyFileName.slice(39), | |
179 | + uid: '3', | |
180 | + }, | |
181 | + ]; | |
182 | + caCertFileName.value = v.credentials?.caCertFileName; | |
183 | + certFileName.value = v.credentials?.certFileName; | |
184 | + privateKeyFileName.value = v.credentials?.privateKeyFileName; | |
164 | 185 | }; |
165 | 186 | const customClearStepTwoValueFunc = async () => { |
166 | 187 | nextTick(() => { | ... | ... |
1 | 1 | <template> |
2 | 2 | <div class="transfer-config-mode"> |
3 | - <BasicForm :showSubmitButton="false" @register="register"> | |
4 | - <template #addKeyAndValue="{ field }"> | |
5 | - <span style="display: none">{{ field }}</span> | |
6 | - <div> | |
7 | - <div> | |
8 | - <template v-for="(item, index) in keyAndValueArr" :key="index"> | |
9 | - <span style="display: none">{{ item + index }}</span> | |
10 | - <BasicForm | |
11 | - :showResetButton="false" | |
12 | - :showSubmitButton="false" | |
13 | - @register="registerKeyAndValue" | |
14 | - /> | |
15 | - </template> | |
16 | - <div> | |
17 | - <a-button type="primary" class="mr-4" @click="addKeyAndValueFunc">添加</a-button> | |
18 | - <a-button color="error" @click="removeKeyAndValueFunc">删除</a-button> | |
19 | - </div> | |
20 | - </div> | |
21 | - </div> | |
22 | - </template> | |
23 | - </BasicForm> | |
3 | + <BasicForm :showSubmitButton="false" @register="register" /> | |
24 | 4 | </div> |
25 | 5 | </template> |
26 | 6 | <script lang="ts"> |
27 | - import { defineComponent, ref, reactive, nextTick } from 'vue'; | |
7 | + import { defineComponent, reactive, nextTick } from 'vue'; | |
28 | 8 | import { BasicForm, useForm } from '/@/components/Form'; |
29 | - import { modeRabbitMqForm, modeKafkaInseretKeyAndValueForm } from '../config'; | |
9 | + import { modeRabbitMqForm } from '../config'; | |
30 | 10 | |
31 | - interface IKeyAndValue { | |
32 | - key: string; | |
33 | - value: string; | |
34 | - } | |
35 | 11 | export default defineComponent({ |
36 | 12 | components: { |
37 | 13 | BasicForm, |
38 | 14 | }, |
39 | 15 | emits: ['next', 'prev', 'register'], |
40 | 16 | setup(_, { emit }) { |
41 | - const temp = ref({}); | |
42 | - let tempObj = ref({}); | |
43 | - const otherPropertiesValues = reactive({ | |
44 | - clientProperties: {}, | |
45 | - }); | |
46 | - | |
47 | - const keyAndValueArrTemp = ref<[]>([]); | |
48 | - const keyAndValueObj = reactive<IKeyAndValue>({ | |
49 | - key: '', | |
50 | - value: '', | |
51 | - }); | |
52 | - const keyAndValueArr = ref<[]>([]); | |
53 | 17 | const sonValues = reactive({ |
54 | 18 | configuration: {}, |
55 | 19 | }); |
56 | 20 | |
57 | 21 | const [register, { validate, setFieldsValue, resetFields: defineClearFunc }] = useForm({ |
58 | - labelWidth: 80, | |
22 | + labelWidth: 120, | |
59 | 23 | schemas: modeRabbitMqForm, |
60 | 24 | actionColOptions: { |
61 | 25 | span: 14, |
62 | 26 | }, |
63 | 27 | resetButtonOptions: { |
64 | 28 | text: '上一步', |
65 | - type: 'primary', | |
66 | 29 | }, |
67 | 30 | |
68 | 31 | resetFunc: customResetFunc, |
69 | 32 | submitFunc: customSubmitFunc, |
70 | 33 | }); |
71 | 34 | |
72 | - const [registerKeyAndValue, { validate: validateKeyAndValue }] = useForm({ | |
73 | - labelWidth: 80, | |
74 | - schemas: modeKafkaInseretKeyAndValueForm, | |
75 | - actionColOptions: { | |
76 | - span: 14, | |
77 | - }, | |
78 | - }); | |
79 | - | |
80 | 35 | const setStepTwoFieldsValueFunc = (v, v1) => { |
81 | 36 | setFieldsValue(v); |
82 | 37 | setFieldsValue({ |
... | ... | @@ -99,37 +54,10 @@ |
99 | 54 | } finally { |
100 | 55 | } |
101 | 56 | } |
102 | - const tempGetKeyAndVal = async () => { | |
103 | - temp.value = await validateKeyAndValue(); | |
104 | - }; | |
105 | - | |
106 | - const getDefaultValue = async () => { | |
107 | - await tempGetKeyAndVal(); | |
108 | - keyAndValueArrTemp.value.push(temp.value as never); | |
109 | - }; | |
110 | 57 | |
111 | - const addKeyAndValueFunc = async () => { | |
112 | - keyAndValueArr.value.push(keyAndValueObj as never); | |
113 | - await tempGetKeyAndVal(); | |
114 | - tempObj.value = temp.value; | |
115 | - keyAndValueArrTemp.value.push(tempObj.value as never); | |
116 | - }; | |
117 | - const removeKeyAndValueFunc = () => { | |
118 | - keyAndValueArr.value.splice(0, 1); | |
119 | - }; | |
120 | 58 | const getSonValueFunc = async () => { |
121 | 59 | sonValues.configuration = await validate(); |
122 | - if (keyAndValueArrTemp.value.length != 0) { | |
123 | - await getDefaultValue(); | |
124 | - } | |
125 | - const kong = {}; | |
126 | - let kongTemp = {}; | |
127 | - keyAndValueArrTemp.value.map((item: any) => { | |
128 | - kong[item.key] = item.value; | |
129 | - }); | |
130 | - kongTemp = JSON.parse(JSON.stringify(kong)); | |
131 | - otherPropertiesValues.clientProperties = kongTemp; | |
132 | - Object.assign(sonValues.configuration, otherPropertiesValues); | |
60 | + Object.assign(sonValues.configuration); | |
133 | 61 | return sonValues; |
134 | 62 | }; |
135 | 63 | |
... | ... | @@ -138,10 +66,6 @@ |
138 | 66 | register, |
139 | 67 | setStepTwoFieldsValueFunc, |
140 | 68 | customClearStepTwoValueFunc, |
141 | - keyAndValueArr, | |
142 | - registerKeyAndValue, | |
143 | - addKeyAndValueFunc, | |
144 | - removeKeyAndValueFunc, | |
145 | 69 | }; |
146 | 70 | }, |
147 | 71 | }); | ... | ... |
... | ... | @@ -12,16 +12,22 @@ |
12 | 12 | <a-button type="primary" @click="handleAdd"> 添加流转 </a-button> |
13 | 13 | </Authority> |
14 | 14 | <Authority value="api:yt:convert:config:delete"> |
15 | - <a-button | |
16 | - type="primary" | |
17 | - color="error" | |
18 | - @click="handleDeleteOrBatchDelete(null)" | |
19 | - :disabled="singleStopDeleteStatus || hasBatchDelete" | |
15 | + <Popconfirm | |
16 | + title="您确定要批量删除数据" | |
17 | + ok-text="确定" | |
18 | + cancel-text="取消" | |
19 | + @confirm="handleDeleteOrBatchDelete(null)" | |
20 | 20 | > |
21 | - <span :style="{ color: singleStopDeleteStatus || hasBatchDelete ? 'grey' : 'white' }" | |
22 | - >批量删除</span | |
21 | + <a-button | |
22 | + type="primary" | |
23 | + color="error" | |
24 | + :disabled="singleStopDeleteStatus || hasBatchDelete" | |
23 | 25 | > |
24 | - </a-button> | |
26 | + <span :style="{ color: singleStopDeleteStatus || hasBatchDelete ? 'grey' : 'white' }" | |
27 | + >批量删除</span | |
28 | + > | |
29 | + </a-button> | |
30 | + </Popconfirm> | |
25 | 31 | </Authority> |
26 | 32 | <a-button |
27 | 33 | :disabled="disabledStatus2" |
... | ... | @@ -104,11 +110,11 @@ |
104 | 110 | import { useMessage } from '/@/hooks/web/useMessage'; |
105 | 111 | import { Authority } from '/@/components/Authority'; |
106 | 112 | import { useBatchDelete } from '/@/hooks/web/useBatchDelete'; |
107 | - import { Switch } from 'ant-design-vue'; | |
113 | + import { Switch, Popconfirm } from 'ant-design-vue'; | |
108 | 114 | |
109 | 115 | export default defineComponent({ |
110 | 116 | name: 'Index', |
111 | - components: { BasicTable, TableAction, DataTransferDrawer, Authority, Switch }, | |
117 | + components: { BasicTable, TableAction, DataTransferDrawer, Authority, Switch, Popconfirm }, | |
112 | 118 | setup() { |
113 | 119 | const disabledSwitch = ref(false); |
114 | 120 | const enableObj = reactive({ | ... | ... |