Commit 263441b367bee19ef6837e6b003dff2f916111f7

Authored by xp.Huang
2 parents c79a9d7e 7743b759

Merge branch 'f-dev' into 'main'

fix:修改Temnition上的问题和优化PC端

See merge request huang/yun-teng-iot-front!249
... ... @@ -146,7 +146,7 @@
146 146 -webkit-transition: opacity 0.4s;
147 147 transition: opacity 0.4s;
148 148
149   - ::v-deep(svg) {
  149 + :deep(svg) {
150 150 margin: auto;
151 151 }
152 152 }
... ...
... ... @@ -344,7 +344,7 @@
344 344 }
345 345
346 346 &-form-container {
347   - padding: 16px 16px 0px 36px;
  347 + padding: 16px 16px 16px 36px;
348 348
349 349 .ant-form {
350 350 padding: 12px 10px 6px 10px;
... ...
... ... @@ -477,14 +477,14 @@
477 477 cursor: pointer;
478 478 position: absolute;
479 479 top: 0.85rem;
480   - left: 1.1vw;
  480 + left: 1.1rem;
481 481 }
482 482 .fold-right {
483 483 z-index: 9999;
484 484 cursor: pointer;
485 485 position: absolute;
486 486 top: 0.85rem;
487   - left: 18.1vw;
  487 + left: 21.6rem;
488 488 }
489 489 @prefix-cls: ~'@{namespace}-basic-tree';
490 490
... ...
... ... @@ -144,7 +144,7 @@
144 144 display: none;
145 145 }
146 146
147   - ::v-deep(.ant-pagination-disabled) {
  147 + :deep(.ant-pagination-disabled) {
148 148 display: inline-block !important;
149 149 }
150 150
... ...
... ... @@ -119,7 +119,35 @@ export const CameraVideoUrl: Rule[] = [
119 119 validator: (_, value: string) => {
120 120 const ChineseRegexp = /[\u4E00-\u9FA5]/;
121 121 if (ChineseRegexp.test(value)) {
122   - return Promise.reject('视频流不能是中文');
  122 + return Promise.reject('输入内容不能是中文');
  123 + }
  124 + return Promise.resolve();
  125 + },
  126 + validateTrigger: 'blur',
  127 + },
  128 +];
  129 +
  130 +export const CameraVideoStreamUrl: Rule[] = [
  131 + {
  132 + required: true,
  133 + validator: (_, value: string) => {
  134 + const ChineseRegexp =
  135 + /^https?:\/\/(.+\/)+.+(\.(swf|avi|flv|mpg|rm|mov|wav|asf|3gp|mkv|rmvb|mp4|m3u8))$/i;
  136 + if (!ChineseRegexp.test(value)) {
  137 + return Promise.reject('请输入正确格式的视频地址');
  138 + }
  139 + return Promise.resolve();
  140 + },
  141 + validateTrigger: 'blur',
  142 + },
  143 +];
  144 +export const CameraNumberUrl: Rule[] = [
  145 + {
  146 + required: true,
  147 + validator: (_, value: string) => {
  148 + const ChineseRegexp = /^[A-Za-z0-9]+$/;
  149 + if (!ChineseRegexp.test(value)) {
  150 + return Promise.reject('请输入正确格式的视频编号');
123 151 }
124 152 return Promise.resolve();
125 153 },
... ...
... ... @@ -37,7 +37,7 @@ export const columns: BasicColumn[] = [
37 37 },
38 38
39 39 {
40   - title: '添加时间',
  40 + title: '创建时间',
41 41 dataIndex: 'createTime',
42 42 width: 180,
43 43 },
... ...
... ... @@ -36,7 +36,7 @@ export const alarmSearchSchemas: FormSchema[] = [
36 36 colProps: { span: 6 },
37 37 componentProps: {
38 38 maxLength: 255,
39   - placeholder: '请输入告警类型',
  39 + placeholder: '请输入告警场景',
40 40 },
41 41 dynamicRules: () => {
42 42 return [
... ...
... ... @@ -3,7 +3,7 @@ import { getOrganizationList } from '/@/api/system/system';
3 3 import { copyTransFun } from '/@/utils/fnUtils';
4 4 import type { FormSchema as QFormSchema } from '/@/components/Form/index';
5 5
6   -import { CameraVideoUrl, CameraMaxLength } from '/@/utils/rules';
  6 +import { CameraMaxLength, CameraVideoStreamUrl, CameraNumberUrl } from '/@/utils/rules';
7 7
8 8 // 表格列数据
9 9 export const columns: BasicColumn[] = [
... ... @@ -104,7 +104,7 @@ export const formSchema: QFormSchema[] = [
104 104 label: '摄像头编号',
105 105 required: true,
106 106 component: 'Input',
107   - rules: CameraVideoUrl,
  107 + rules: CameraNumberUrl,
108 108 componentProps: {
109 109 placeholder: '请输入摄像头编号',
110 110 },
... ... @@ -118,6 +118,6 @@ export const formSchema: QFormSchema[] = [
118 118 placeholder: '请输入视频流',
119 119 maxLength: 255,
120 120 },
121   - rules: CameraVideoUrl,
  121 + rules: CameraVideoStreamUrl,
122 122 },
123 123 ];
... ...
... ... @@ -59,8 +59,12 @@
59 59 <template #title>
60 60 {{
61 61 !isAdmin(role)
62   - ? `告警数:今日新增 ${toThousands(growCardList?.alarmInfo?.todayAdd)}`
63   - : `租户总量:今日新增 ${toThousands(growCardList?.alarmInfo?.todayAdd)}`
  62 + ? `告警数:${growCardList?.alarmInfo?.sumCount} 今日新增 ${toThousands(
  63 + growCardList?.alarmInfo?.todayAdd
  64 + )}`
  65 + : `租户总量:${growCardList?.tenantInfo?.sumCount} 今日新增 ${toThousands(
  66 + growCardList?.alarmInfo?.todayAdd
  67 + )}`
64 68 }}
65 69 </template>
66 70 <img src="/src/assets/images/tip.png" style="width: 1.125rem; height: 1.125rem" />
... ... @@ -106,8 +110,10 @@
106 110 <template #title>
107 111 {{
108 112 !isAdmin(role)
109   - ? `消息数:今日新增 ${toThousands(growCardList?.messageInfo?.todayMessageAdd)}`
110   - : `客户总量:今日新增 ${toThousands(
  113 + ? `消息数:${growCardList?.messageInfo?.messageCount} 今日新增 ${toThousands(
  114 + growCardList?.messageInfo?.todayMessageAdd
  115 + )}`
  116 + : `客户总量:${growCardList?.customerInfo?.sumCount} 今日新增 ${toThousands(
111 117 growCardList?.messageInfo?.todayMessageAdd
112 118 )}`
113 119 }}
... ...
... ... @@ -7,7 +7,7 @@
7 7 centered
8 8 @ok="dispatchCustomer"
9 9 @cancel="resetFields"
10   - :minHeight="100"
  10 + :minHeight="300"
11 11 okText="分配"
12 12 >
13 13 <BasicForm @register="registerForm" />
... ...
... ... @@ -52,7 +52,7 @@
52 52 <template #name="{ record }">
53 53 <div>
54 54 <Tooltip :title="record.name" placement="topRight">
55   - {{ record.name }}
  55 + {{ record.name.slice(0, 13) }}
56 56 </Tooltip>
57 57 </div>
58 58 <Tooltip title="设备SN码" placement="topRight">
... ...
... ... @@ -278,3 +278,9 @@
278 278 },
279 279 });
280 280 </script>
  281 +
  282 +<style lang="less" scoped>
  283 + :deep(.ant-select-selector) {
  284 + max-width: 42rem !important;
  285 + }
  286 +</style>
... ...
... ... @@ -52,7 +52,7 @@ export const MqttSchemas: FormSchema[] = [
52 52 maxRows: 10,
53 53 },
54 54 },
55   - colProps: { span: 22 },
  55 + colProps: { span: 23 },
56 56 },
57 57 {
58 58 field: 'transportPayloadType',
... ... @@ -70,7 +70,7 @@ export const MqttSchemas: FormSchema[] = [
70 70 {
71 71 field: 'useJsonPayloadFormatForDefaultDownlinkTopics',
72 72 label: '',
73   - colProps: { span: 22 },
  73 + colProps: { span: 23 },
74 74 defaultValue: false,
75 75 component: 'Checkbox',
76 76 renderComponentContent: `启用后,平台将默认使用Protobuf有效载荷格式。如果解析失败,平台将尝试使用JSON有效负载格式。用于固件更新期间的向后兼容性。例如,固件的初始版本使用Json,而新版本使用Protobuf。在设备组的固件更新过程中,需要同时支持Protobuf和JSON。兼容性模式会导致性能轻微下降,因此建议在所有设备更新后禁用此模式。`,
... ... @@ -79,7 +79,7 @@ export const MqttSchemas: FormSchema[] = [
79 79 {
80 80 field: 'enableCompatibilityWithJsonPayloadFormat',
81 81 label: '',
82   - colProps: { span: 22 },
  82 + colProps: { span: 23 },
83 83 defaultValue: false,
84 84 component: 'Checkbox',
85 85 renderComponentContent: `启用后,平台将使用Json有效负载格式通过以下主题推送属性和RPC:v1/devices/me/attributes/response/$request_id, v1/devices/me/attributes, v1/devices/me/rpc/request/$request_id,v1/devices/me/rpc/response/$request_id.此设置不会影响使用新(v2)主题发送的属性和rpc订阅:v2/a/res/$request_id, v2/a, v2/r/req/$request_id, v2/r/res/$request_id. Where $request_id是一个整数请求标识符。`,
... ... @@ -90,7 +90,7 @@ export const MqttSchemas: FormSchema[] = [
90 90 {
91 91 field: 'deviceTelemetryProtoSchema',
92 92 label: '遥测数据',
93   - colProps: { span: 22 },
  93 + colProps: { span: 23 },
94 94 component: 'InputTextArea',
95 95 componentProps: {
96 96 autoSize: {
... ... @@ -119,7 +119,7 @@ export const MqttSchemas: FormSchema[] = [
119 119 {
120 120 field: 'deviceAttributesProtoSchema',
121 121 label: 'Attributes',
122   - colProps: { span: 22 },
  122 + colProps: { span: 23 },
123 123 component: 'InputTextArea',
124 124 componentProps: {
125 125 autoSize: {
... ... @@ -140,7 +140,7 @@ export const MqttSchemas: FormSchema[] = [
140 140 {
141 141 field: 'deviceRpcRequestProtoSchema',
142 142 label: 'RPC 请求 ',
143   - colProps: { span: 22 },
  143 + colProps: { span: 23 },
144 144 component: 'InputTextArea',
145 145 componentProps: {
146 146 autoSize: {
... ... @@ -162,7 +162,7 @@ export const MqttSchemas: FormSchema[] = [
162 162 {
163 163 field: 'deviceRpcResponseProtoSchema',
164 164 label: 'RPC 响应',
165   - colProps: { span: 22 },
  165 + colProps: { span: 23 },
166 166 component: 'InputTextArea',
167 167 componentProps: {
168 168 autoSize: {
... ...
... ... @@ -130,4 +130,8 @@
130 130 },
131 131 });
132 132 </script>
133   -<style lang="less" scoped></style>
  133 +<style lang="less" scoped>
  134 + :deep(.ant-row) {
  135 + column-gap: 33px !important;
  136 + }
  137 +</style>
... ...
... ... @@ -7,6 +7,7 @@
7 7 @register="registerDrawer"
8 8 :title="getTitle"
9 9 width="1000px"
  10 + @cancel="handleCancel"
10 11 >
11 12 <div class="step-form-form">
12 13 <a-steps :current="current">
... ... @@ -25,7 +26,7 @@
25 26 @prevSon="handlePrev"
26 27 /></div>
27 28 </div>
28   - <div style="float: right">
  29 + <div style="float: right" v-if="isViewStatus">
29 30 <Button type="primary" @click="handleSubmit" class="mr-2">确认</Button>
30 31 <Button type="default" @click="handleCancel" class="mr-2">取消</Button>
31 32 </div>
... ... @@ -33,15 +34,7 @@
33 34 </div>
34 35 </template>
35 36 <script lang="ts">
36   - import {
37   - defineComponent,
38   - reactive,
39   - ref,
40   - computed,
41   - unref,
42   - getCurrentInstance,
43   - nextTick,
44   - } from 'vue';
  37 + import { defineComponent, reactive, ref, unref, getCurrentInstance, nextTick } from 'vue';
45 38 import { BasicModal, useModalInner } from '/@/components/Modal';
46 39 import { Steps } from 'ant-design-vue';
47 40 import TransferConfigMode from './cpns/transferConfigMode.vue';
... ... @@ -62,6 +55,7 @@
62 55 },
63 56 emits: ['success', 'register'],
64 57 setup(_, { emit }) {
  58 + const isViewStatus = ref(false);
65 59 const { createMessage } = useMessage();
66 60 const { proxy } = getCurrentInstance() as any;
67 61 let allPostForm: any = reactive({});
... ... @@ -82,8 +76,8 @@
82 76 const refTransferConfigParams = ref(null);
83 77 const refTransferConfigMode = ref(null);
84 78 const getModeSelectVal = ref({});
85   - const isUpdate = ref(true);
86   - const getTitle = computed(() => (!unref(isUpdate) ? '新增流转配置' : '编辑数据流转'));
  79 + const isUpdate: any = ref(true);
  80 + const getTitle = ref('');
87 81 const current = ref(0);
88 82 const editPostId = ref('');
89 83 const editType = reactive({
... ... @@ -104,26 +98,40 @@
104 98 };
105 99
106 100 const [registerDrawer, { setModalProps, closeModal }] = useModalInner(async (data) => {
107   - isUpdate.value = !!data?.isUpdate;
  101 + isUpdate.value = data?.isUpdate;
108 102 current.value = 0;
109 103 setModalProps({ confirmLoading: false });
110   -
111   - if (unref(isUpdate)) {
  104 + function commonViewOrEditFunc() {
112 105 editPostId.value = data.record.id;
113 106 editNextType.type = data.record.type;
114 107 editNextType.configuration = data.record;
115 108 editNextType.name = data.record.name;
116 109 editNextType.remark = data.record.remark;
117 110 proxy.$refs.refTransferConfigMode.setStepOneFieldsValueFunc(editNextType);
118   - } else {
119   - nextTick(() => {
  111 + }
  112 + switch (unref(isUpdate)) {
  113 + case 'view':
  114 + commonViewOrEditFunc();
  115 + isViewStatus.value = false;
  116 + getTitle.value = '查看流转配置';
  117 + break;
  118 + case true:
  119 + commonViewOrEditFunc();
  120 + isViewStatus.value = true;
  121 + getTitle.value = '编辑流转配置';
  122 + break;
  123 + case false:
120 124 proxy.$refs.refTransferConfigMode?.customResetStepOneFunc();
121   - });
  125 + isViewStatus.value = true;
  126 + getTitle.value = '新增流转配置';
  127 + break;
122 128 }
123 129 });
124 130 const handleCancel = () => {
125   - defineClearFunc();
126   - closeModal();
  131 + nextTick(() => {
  132 + defineClearFunc();
  133 + closeModal();
  134 + });
127 135 };
128 136 const defineClearFunc = () => {
129 137 nextTick(() => {
... ... @@ -149,6 +157,8 @@
149 157 } catch (e) {
150 158 return e;
151 159 }
  160 + } else {
  161 + proxy.$refs.refTransferConfigParams.editSonValueDataFunc({});
152 162 }
153 163 };
154 164 const handlePrev = () => {
... ... @@ -248,6 +258,7 @@
248 258 getModeSelectVal,
249 259 refTransferConfigParams,
250 260 refTransferConfigMode,
  261 + isViewStatus,
251 262 };
252 263 },
253 264 });
... ...
... ... @@ -243,14 +243,14 @@ export const modeKafkaForm: FormSchema[] = [
243 243 },
244 244 {
245 245 field: '1',
246   - label: '',
  246 + label: '其他属性',
247 247 colProps: { span: 24 },
248 248 slot: 'addValue',
249 249 component: 'Input',
250 250 },
251 251 {
252 252 field: 'addMetadataKeyValuesAsKafkaHeaders',
253   - label: '选择',
  253 + label: '',
254 254 colProps: { span: 12 },
255 255 component: 'Checkbox',
256 256 renderComponentContent: '将消息的元数据以键值对的方式添加到Kafka消息头中',
... ... @@ -282,7 +282,7 @@ export const modeKafkaForm: FormSchema[] = [
282 282 field: 'description',
283 283 label: '说明',
284 284 colProps: { span: 12 },
285   - component: 'Input',
  285 + component: 'InputTextArea',
286 286 componentProps: {
287 287 maxLength: 255,
288 288 placeholder: '请输入说明',
... ... @@ -308,6 +308,7 @@ export const modeMqttForm: FormSchema[] = [
308 308 colProps: { span: 12 },
309 309 required: true,
310 310 component: 'Input',
  311 + defaultValue: 'my-topic',
311 312 componentProps: {
312 313 maxLength: 255,
313 314 placeholder: '请输入Topic pattern',
... ... @@ -319,7 +320,6 @@ export const modeMqttForm: FormSchema[] = [
319 320 colProps: { span: 12 },
320 321 component: 'Input',
321 322 required: true,
322   - defaultValue: 'localhost',
323 323 componentProps: {
324 324 maxLength: 255,
325 325 placeholder: '请输入Host',
... ... @@ -354,12 +354,37 @@ export const modeMqttForm: FormSchema[] = [
354 354 label: 'Client ID',
355 355 colProps: { span: 12 },
356 356 component: 'Input',
357   - componentProps: {
358   - maxLength: 255,
359   - placeholder: '请输入Client ID',
  357 + componentProps: ({ formActionType }) => {
  358 + const { updateSchema } = formActionType;
  359 + return {
  360 + onChange(e) {
  361 + if (e == null || e == undefined) {
  362 + updateSchema({
  363 + field: 'appendClientIdSuffix',
  364 + show: false,
  365 + });
  366 + } else {
  367 + updateSchema({
  368 + field: 'appendClientIdSuffix',
  369 + show: true,
  370 + });
  371 + }
  372 + },
  373 + maxLength: 255,
  374 + placeholder: '请输入Client ID',
  375 + };
360 376 },
361 377 },
362 378 {
  379 + field: 'appendClientIdSuffix',
  380 + label: '',
  381 + colProps: { span: 12 },
  382 + defaultValue: false,
  383 + component: 'Checkbox',
  384 + renderComponentContent: 'Add Service ID as suffix to Client ID',
  385 + show: false,
  386 + },
  387 + {
363 388 field: 'cleanSession',
364 389 label: 'Clean',
365 390 colProps: { span: 12 },
... ... @@ -406,7 +431,7 @@ export const modeMqttForm: FormSchema[] = [
406 431 field: 'password',
407 432 label: '密码',
408 433 colProps: { span: 12 },
409   - component: 'Input',
  434 + component: 'InputPassword',
410 435 componentProps: {
411 436 maxLength: 255,
412 437 placeholder: '请输入密码',
... ... @@ -441,7 +466,7 @@ export const modeMqttForm: FormSchema[] = [
441 466 field: 'password',
442 467 label: 'Password',
443 468 colProps: { span: 12 },
444   - component: 'Input',
  469 + component: 'InputPassword',
445 470 componentProps: {
446 471 maxLength: 255,
447 472 placeholder: '请输入Password',
... ... @@ -452,7 +477,7 @@ export const modeMqttForm: FormSchema[] = [
452 477 field: 'description',
453 478 label: '说明',
454 479 colProps: { span: 12 },
455   - component: 'Input',
  480 + component: 'InputTextArea',
456 481 componentProps: {
457 482 maxLength: 255,
458 483 placeholder: '请输入说明',
... ... @@ -575,7 +600,7 @@ export const modeRabbitMqForm: FormSchema[] = [
575 600 field: 'password',
576 601 label: 'Password',
577 602 colProps: { span: 12 },
578   - component: 'Input',
  603 + component: 'InputPassword',
579 604 defaultValue: 'guest',
580 605 componentProps: {
581 606 maxLength: 255,
... ... @@ -613,12 +638,11 @@ export const modeRabbitMqForm: FormSchema[] = [
613 638 },
614 639 {
615 640 field: '1',
616   - label: '',
  641 + label: '客户端属性',
617 642 colProps: { span: 24 },
618   - component: 'Input',
  643 + component: 'InputTextArea',
619 644 slot: 'addKeyAndValue',
620 645 },
621   -
622 646 {
623 647 field: 'description',
624 648 label: '说明',
... ... @@ -925,7 +949,7 @@ export const modeApiForm: FormSchema[] = [
925 949 field: 'password',
926 950 label: 'Password',
927 951 colProps: { span: 12 },
928   - component: 'Input',
  952 + component: 'InputPassword',
929 953 required: true,
930 954 componentProps: {
931 955 maxLength: 255,
... ... @@ -961,7 +985,7 @@ export const modeApiForm: FormSchema[] = [
961 985 field: 'password',
962 986 label: 'Password',
963 987 colProps: { span: 12 },
964   - component: 'Input',
  988 + component: 'InputPassword',
965 989 componentProps: {
966 990 maxLength: 255,
967 991 placeholder: '请输入Password',
... ... @@ -973,7 +997,7 @@ export const modeApiForm: FormSchema[] = [
973 997 field: 'description',
974 998 label: '说明',
975 999 colProps: { span: 12 },
976   - component: 'Input',
  1000 + component: 'InputTextArea',
977 1001 componentProps: {
978 1002 maxLength: 255,
979 1003 placeholder: '请输入说明',
... ...
... ... @@ -23,57 +23,60 @@
23 23 <template #uploadAdd1="{ field }">
24 24 <span style="display: none">{{ field }}</span>
25 25 <a-upload-dragger
26   - v-model:fileList="fileList"
  26 + v-model:fileList="fileList1"
27 27 name="file"
28   - :multiple="true"
29   - action="https://www.mocky.io/v2/5cc8019d300000980a055e76"
30   - @change="handleChange"
  28 + :multiple="false"
  29 + @change="handleChange('T', $event)"
  30 + :before-upload="() => false"
31 31 >
32 32 <p class="ant-upload-drag-icon">
33 33 <InboxOutlined />
34 34 </p>
35   - <p class="ant-upload-text">Click or drag file to this area to upload</p>
  35 + <p class="ant-upload-text">点击或将文件拖拽到这里上传</p>
36 36 <p class="ant-upload-hint">
37   - Support for a single or bulk upload. Strictly prohibit from uploading company data or
38   - other band files
  37 + 支持扩展名:.jpeg .png .jpg ...
  38 + <br />
  39 + 文件大小:最大支持5M
39 40 </p>
40 41 </a-upload-dragger>
41 42 </template>
42 43 <template #uploadAdd2="{ field }">
43 44 <span style="display: none">{{ field }}</span>
44 45 <a-upload-dragger
45   - v-model:fileList="fileList"
  46 + v-model:fileList="fileList2"
46 47 name="file"
47   - :multiple="true"
48   - action="https://www.mocky.io/v2/5cc8019d300000980a055e76"
49   - @change="handleChange"
  48 + :multiple="false"
  49 + @change="handleChange('F', $event)"
  50 + :before-upload="() => false"
50 51 >
51 52 <p class="ant-upload-drag-icon">
52 53 <InboxOutlined />
53 54 </p>
54   - <p class="ant-upload-text">Click or drag file to this area to upload</p>
  55 + <p class="ant-upload-text">点击或将文件拖拽到这里上传</p>
55 56 <p class="ant-upload-hint">
56   - Support for a single or bulk upload. Strictly prohibit from uploading company data or
57   - other band files
  57 + 支持扩展名:.jpeg .png .jpg ...
  58 + <br />
  59 + 文件大小:最大支持5M
58 60 </p>
59 61 </a-upload-dragger>
60 62 </template>
61 63 <template #uploadAdd3="{ field }">
62 64 <span style="display: none">{{ field }}</span>
63 65 <a-upload-dragger
64   - v-model:fileList="fileList"
  66 + v-model:fileList="fileList3"
65 67 name="file"
66   - :multiple="true"
67   - action="https://www.mocky.io/v2/5cc8019d300000980a055e76"
68   - @change="handleChange"
  68 + :multiple="false"
  69 + @change="handleChange('C', $event)"
  70 + :before-upload="() => false"
69 71 >
70 72 <p class="ant-upload-drag-icon">
71 73 <InboxOutlined />
72 74 </p>
73   - <p class="ant-upload-text">Click or drag file to this area to upload</p>
  75 + <p class="ant-upload-text">点击或将文件拖拽到这里上传</p>
74 76 <p class="ant-upload-hint">
75   - Support for a single or bulk upload. Strictly prohibit from uploading company data or
76   - other band files
  77 + 支持扩展名:.jpeg .png .jpg ...
  78 + <br />
  79 + 文件大小:最大支持5M
77 80 </p>
78 81 </a-upload-dragger>
79 82 </template>
... ... @@ -83,9 +86,12 @@
83 86 <script lang="ts">
84 87 import { defineComponent, ref, reactive, nextTick } from 'vue';
85 88 import { BasicForm, useForm } from '/@/components/Form';
86   - import { modeApiForm, modeApiInseretKeyAndValueForm } from '../config';
  89 + import { modeApiForm, modeApiInseretKeyAndValueForm, CredentialsEnum } from '../config';
87 90 import { InboxOutlined } from '@ant-design/icons-vue';
88 91 import { Upload } from 'ant-design-vue';
  92 + import { useMessage } from '/@/hooks/web/useMessage';
  93 + import { uploadApi } from '/@/api/personal/index';
  94 +
89 95 interface IKeyAndValue {
90 96 key: string;
91 97 value: string;
... ... @@ -98,14 +104,20 @@
98 104 },
99 105 emits: ['next', 'prev', 'register'],
100 106 setup(_, { emit }) {
101   - const fileList = ref<[]>([]);
  107 + const { createMessage } = useMessage();
  108 + let caCertFileName = ref('');
  109 + let privateKeyFileName = ref('');
  110 + let certFileName = ref('');
  111 + let fileList1: any = ref<[]>([]);
  112 + let fileList2: any = ref<[]>([]);
  113 + let fileList3: any = ref<[]>([]);
102 114 const keyAndValueArr = ref<[]>([]);
103 115 const temp = ref({});
104 116 let tempObj = ref({});
105 117 const otherPropertiesValues = reactive({
106 118 headers: {},
107 119 });
108   - const credentialsV = reactive({
  120 + const credentialsV: any = reactive({
109 121 credentials: {
110 122 type: '',
111 123 },
... ... @@ -126,9 +138,7 @@
126 138 },
127 139 resetButtonOptions: {
128 140 text: '上一步',
129   - type: 'primary',
130 141 },
131   -
132 142 resetFunc: customResetFunc,
133 143 submitFunc: customSubmitFunc,
134 144 });
... ... @@ -148,11 +158,25 @@
148 158 setFieldsValue({
149 159 name: v1,
150 160 });
  161 + setFieldsValue({
  162 + password: v.credentials?.password,
  163 + username: v.credentials?.username,
  164 + type: v.credentials?.type,
  165 + });
  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) }];
151 169 };
152 170 const customClearStepTwoValueFunc = async () => {
153 171 nextTick(() => {
154 172 defineClearFunc();
155 173 defineClearKeyAndValueFunc();
  174 + fileList1.value = [];
  175 + fileList2.value = [];
  176 + fileList3.value = [];
  177 + caCertFileName.value = '';
  178 + privateKeyFileName.value = '';
  179 + certFileName.value = '';
156 180 });
157 181 };
158 182 async function customResetFunc() {
... ... @@ -184,7 +208,39 @@
184 208 const removeKeyAndValueFunc = () => {
185 209 keyAndValueArr.value.splice(0, 1);
186 210 };
187   - const handleChange = () => {};
  211 + /**
  212 + * 上传图片
  213 + */
  214 + const handleChange = async (e, { file }) => {
  215 + if (file.status === 'removed') {
  216 + e == 'T'
  217 + ? (fileList1.value = [])
  218 + : e == 'F'
  219 + ? (fileList2.value = [])
  220 + : (fileList3.value = []);
  221 + } else {
  222 + const isLt5M = file.size / 1024 / 1024 < 5;
  223 + if (!isLt5M) {
  224 + createMessage.error('图片大小不能超过5MB!');
  225 + } else {
  226 + e == 'T'
  227 + ? (fileList1.value = [file])
  228 + : e == 'F'
  229 + ? (fileList2.value = [file])
  230 + : (fileList3.value = [file]);
  231 + const formData = new FormData();
  232 + formData.append('file', file);
  233 + const response = await uploadApi(formData);
  234 + if (response.fileStaticUri) {
  235 + e == 'T'
  236 + ? (caCertFileName.value = response.fileStaticUri)
  237 + : e == 'F'
  238 + ? (certFileName.value = response.fileStaticUri)
  239 + : (privateKeyFileName.value = response.fileStaticUri);
  240 + }
  241 + }
  242 + }
  243 + };
188 244
189 245 const getSonValueFunc = async () => {
190 246 sonValues.configuration = await validate();
... ... @@ -192,6 +248,17 @@
192 248 await getDefaultValue();
193 249 }
194 250 credentialsV.credentials.type = sonValues.configuration.type;
  251 + if (credentialsV.credentials.type == CredentialsEnum.IS_BASIC) {
  252 + credentialsV.credentials.username = sonValues.configuration.username;
  253 + credentialsV.credentials.password = sonValues.configuration.password;
  254 + sonValues.configuration.username = undefined;
  255 + sonValues.configuration.password = undefined;
  256 + } else if (credentialsV.credentials.type == CredentialsEnum.IS_PEM) {
  257 + credentialsV.credentials.caCertFileName = caCertFileName.value;
  258 + credentialsV.credentials.certFileName = certFileName.value;
  259 + credentialsV.credentials.privateKeyFileName = privateKeyFileName.value;
  260 + credentialsV.credentials.password = sonValues.configuration.password;
  261 + }
195 262 const kong = {};
196 263 let kongTemp = {};
197 264 keyAndValueArrTemp.value.map((item: any) => {
... ... @@ -211,9 +278,19 @@
211 278 getSonValueFunc,
212 279 keyAndValueArr,
213 280 registerKeyAndValue,
214   - fileList,
215 281 handleChange,
  282 + fileList1,
  283 + fileList2,
  284 + fileList3,
  285 + caCertFileName,
  286 + privateKeyFileName,
  287 + certFileName,
216 288 };
217 289 },
218 290 });
219 291 </script>
  292 +<style lang="less" scoped>
  293 + :deep(.ant-col-24) {
  294 + margin-bottom: 20px !important;
  295 + }
  296 +</style>
... ...
... ... @@ -48,7 +48,7 @@
48 48 setup(_, { emit }) {
49 49 const temp = ref({});
50 50 let tempObj = ref({});
51   - const keyAndValueArr = ref<[]>([]);
  51 + const keyAndValueArr: any = ref<[]>([]);
52 52 const keyAndValueArrTemp = ref<[]>([]);
53 53 const vType = ref('');
54 54 const keyAndValueObj = reactive<IKeyAndValue>({
... ... @@ -72,7 +72,6 @@
72 72 },
73 73 resetButtonOptions: {
74 74 text: '上一步',
75   - type: 'primary',
76 75 },
77 76 resetFunc: customResetFunc,
78 77 });
... ... @@ -114,12 +113,6 @@
114 113 const tempGetKeyAndVal = async () => {
115 114 temp.value = await validateKeyAndValue();
116 115 };
117   - // const defaultAddKeyAndValueFunc = () => {
118   - // if (keyAndValueArr.value.length == 0) {
119   - // keyAndValueArr.value.push(keyAndValueObj as never);
120   - // }
121   - // };
122   - // defaultAddKeyAndValueFunc();
123 116
124 117 const getDefaultValue = async () => {
125 118 await tempGetKeyAndVal();
... ...
... ... @@ -4,57 +4,62 @@
4 4 <template #uploadAdd1="{ field }">
5 5 <span style="display: none">{{ field }}</span>
6 6 <a-upload-dragger
7   - v-model:fileList="fileList"
  7 + v-model:fileList="fileList1"
8 8 name="file"
9   - :multiple="true"
10   - action="https://www.mocky.io/v2/5cc8019d300000980a055e76"
11   - @change="handleChange"
  9 + :multiple="false"
  10 + @change="handleChange('T', $event)"
  11 + :before-upload="() => false"
12 12 >
13 13 <p class="ant-upload-drag-icon">
14 14 <InboxOutlined />
15 15 </p>
16   - <p class="ant-upload-text">Click or drag file to this area to upload</p>
  16 + <p class="ant-upload-text">点击或将文件拖拽到这里上传</p>
17 17 <p class="ant-upload-hint">
18   - Support for a single or bulk upload. Strictly prohibit from uploading company data or
19   - other band files
  18 + 支持扩展名:.jpeg .png .jpg ...
  19 + <br />
  20 + 文件大小:最大支持5M
20 21 </p>
21 22 </a-upload-dragger>
22 23 </template>
  24 + <div style="margin-top: 50px"></div>
23 25 <template #uploadAdd2="{ field }">
24 26 <span style="display: none">{{ field }}</span>
25 27 <a-upload-dragger
26   - v-model:fileList="fileList"
  28 + v-model:fileList="fileList2"
27 29 name="file"
28   - :multiple="true"
29   - action="https://www.mocky.io/v2/5cc8019d300000980a055e76"
30   - @change="handleChange"
  30 + :multiple="false"
  31 + @change="handleChange('F', $event)"
  32 + :before-upload="() => false"
31 33 >
32 34 <p class="ant-upload-drag-icon">
33 35 <InboxOutlined />
34 36 </p>
35   - <p class="ant-upload-text">Click or drag file to this area to upload</p>
  37 + <p class="ant-upload-text">点击或将文件拖拽到这里上传</p>
36 38 <p class="ant-upload-hint">
37   - Support for a single or bulk upload. Strictly prohibit from uploading company data or
38   - other band files
  39 + 支持扩展名:.jpeg .png .jpg ...
  40 + <br />
  41 + 文件大小:最大支持5M
39 42 </p>
40 43 </a-upload-dragger>
41 44 </template>
  45 + <div style="margin-top: 50px"></div>
42 46 <template #uploadAdd3="{ field }">
43 47 <span style="display: none">{{ field }}</span>
44 48 <a-upload-dragger
45   - v-model:fileList="fileList"
  49 + v-model:fileList="fileList3"
46 50 name="file"
47   - :multiple="true"
48   - action="https://www.mocky.io/v2/5cc8019d300000980a055e76"
49   - @change="handleChange"
  51 + :multiple="false"
  52 + @change="handleChange('C', $event)"
  53 + :before-upload="() => false"
50 54 >
51 55 <p class="ant-upload-drag-icon">
52 56 <InboxOutlined />
53 57 </p>
54   - <p class="ant-upload-text">Click or drag file to this area to upload</p>
  58 + <p class="ant-upload-text">点击或将文件拖拽到这里上传</p>
55 59 <p class="ant-upload-hint">
56   - Support for a single or bulk upload. Strictly prohibit from uploading company data or
57   - other band files
  60 + 支持扩展名:.jpeg .png .jpg ...
  61 + <br />
  62 + 文件大小:最大支持5M
58 63 </p>
59 64 </a-upload-dragger>
60 65 </template>
... ... @@ -67,6 +72,8 @@
67 72 import { CredentialsEnum, modeMqttForm } from '../config';
68 73 import { InboxOutlined } from '@ant-design/icons-vue';
69 74 import { Alert, Divider, Descriptions, Upload } from 'ant-design-vue';
  75 + import { uploadApi } from '/@/api/personal/index';
  76 + import { useMessage } from '/@/hooks/web/useMessage';
70 77
71 78 export default defineComponent({
72 79 components: {
... ... @@ -80,8 +87,14 @@
80 87 },
81 88 emits: ['next', 'prev', 'register'],
82 89 setup(_, { emit }) {
83   - const fileList = ref<[]>([]);
84   - const credentialsV = reactive({
  90 + const { createMessage } = useMessage();
  91 + let caCertFileName = ref('');
  92 + let privateKeyFileName = ref('');
  93 + let certFileName = ref('');
  94 + let fileList1: any = ref<[]>([]);
  95 + let fileList2: any = ref<[]>([]);
  96 + let fileList3: any = ref<[]>([]);
  97 + const credentialsV: any = reactive({
85 98 credentials: {
86 99 type: '',
87 100 },
... ... @@ -97,26 +110,67 @@
97 110 },
98 111 resetButtonOptions: {
99 112 text: '上一步',
100   - type: 'primary',
101 113 },
102   -
103 114 resetFunc: customResetFunc,
104 115 submitFunc: customSubmitFunc,
105 116 });
  117 +
  118 + /**
  119 + * 上传图片
  120 + */
  121 + const handleChange = async (e, { file }) => {
  122 + if (file.status === 'removed') {
  123 + e == 'T'
  124 + ? (fileList1.value = [])
  125 + : e == 'F'
  126 + ? (fileList2.value = [])
  127 + : (fileList3.value = []);
  128 + } else {
  129 + const isLt5M = file.size / 1024 / 1024 < 5;
  130 + if (!isLt5M) {
  131 + createMessage.error('图片大小不能超过5MB!');
  132 + } else {
  133 + e == 'T'
  134 + ? (fileList1.value = [file])
  135 + : e == 'F'
  136 + ? (fileList2.value = [file])
  137 + : (fileList3.value = [file]);
  138 + const formData = new FormData();
  139 + formData.append('file', file);
  140 + const response = await uploadApi(formData);
  141 + if (response.fileStaticUri) {
  142 + e == 'T'
  143 + ? (caCertFileName.value = response.fileStaticUri)
  144 + : e == 'F'
  145 + ? (certFileName.value = response.fileStaticUri)
  146 + : (privateKeyFileName.value = response.fileStaticUri);
  147 + }
  148 + }
  149 + }
  150 + };
106 151 const setStepTwoFieldsValueFunc = (v, v1) => {
107 152 setFieldsValue(v);
108 153 setFieldsValue({
109 154 name: v1,
110 155 });
111 156 setFieldsValue({
112   - password: v.credentials.password,
113   - type: v.credentials.type,
114   - username: v.credentials.username,
  157 + password: v.credentials?.password,
  158 + username: v.credentials?.username,
  159 + type: v.credentials?.type,
115 160 });
  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) }];
116 164 };
117 165 const customClearStepTwoValueFunc = async () => {
118 166 nextTick(() => {
119 167 defineClearFunc();
  168 + fileList1.value = [];
  169 + fileList2.value = [];
  170 + fileList3.value = [];
  171 + caCertFileName.value = '';
  172 + privateKeyFileName.value = '';
  173 + certFileName.value = '';
120 174 });
121 175 };
122 176 async function customResetFunc() {
... ... @@ -130,7 +184,6 @@
130 184 } finally {
131 185 }
132 186 }
133   - const handleChange = () => {};
134 187 const getSonValueFunc = async () => {
135 188 sonValues.configuration = await validate();
136 189 credentialsV.credentials.type = sonValues.configuration.type;
... ... @@ -139,6 +192,10 @@
139 192 credentialsV.credentials.password = sonValues.configuration.password;
140 193 sonValues.configuration.username = undefined;
141 194 sonValues.configuration.password = undefined;
  195 + } else if (credentialsV.credentials.type == CredentialsEnum.IS_PEM) {
  196 + credentialsV.credentials.caCertFileName = caCertFileName.value;
  197 + credentialsV.credentials.certFileName = certFileName.value;
  198 + credentialsV.credentials.privateKeyFileName = privateKeyFileName.value;
142 199 }
143 200 Object.assign(sonValues.configuration, credentialsV);
144 201 return sonValues;
... ... @@ -148,9 +205,20 @@
148 205 register,
149 206 setStepTwoFieldsValueFunc,
150 207 customClearStepTwoValueFunc,
151   - fileList,
  208 + fileList1,
  209 + fileList2,
  210 + fileList3,
152 211 handleChange,
  212 + caCertFileName,
  213 + privateKeyFileName,
  214 + certFileName,
153 215 };
154 216 },
155 217 });
156 218 </script>
  219 +
  220 +<style lang="less" scoped>
  221 + :deep(.ant-col-24) {
  222 + margin-bottom: 20px !important;
  223 + }
  224 +</style>
... ...
... ... @@ -42,6 +42,13 @@
42 42 <TableAction
43 43 :actions="[
44 44 {
  45 + label: '查看',
  46 + auth: 'api:yt:convert:config:get',
  47 + icon: 'ant-design:eye-outlined',
  48 + onClick: handleView.bind(null, record),
  49 + ifShow: record.status == 1,
  50 + },
  51 + {
45 52 label: '编辑',
46 53 auth: 'api:yt:convert:config:update',
47 54 icon: 'clarity:note-edit-line',
... ... @@ -301,6 +308,14 @@
301 308 reload();
302 309 }
303 310 };
  311 + function handleView(record: Recordable) {
  312 + nextTick(() => {
  313 + openModal(true, {
  314 + record,
  315 + isUpdate: 'view',
  316 + });
  317 + });
  318 + }
304 319
305 320 return {
306 321 disabledStatus1,
... ... @@ -320,6 +335,7 @@
320 335 singleStopDeleteStatus,
321 336 statusChange,
322 337 disabledSwitch,
  338 + handleView,
323 339 };
324 340 },
325 341 });
... ...
... ... @@ -662,11 +662,11 @@
662 662 <style lang="less" scoped>
663 663 //TODO-fengtao
664 664 ///移除选择框默认样式(24px)否则超出默认宽度会造成页面样式错乱
665   - ::v-deep(.ant-select-selector) {
  665 + :deep(.ant-select-selector) {
666 666 padding-right: 0px !important;
667 667 }
668 668
669   - ::v-deep(.ant-select-selection-overflow) {
  669 + :deep(.ant-select-selection-overflow) {
670 670 max-width: 10vw !important;
671 671 }
672 672 //TODO-fengtao
... ...
... ... @@ -312,7 +312,7 @@
312 312
313 313 <style lang="less" scoped>
314 314 ///移除选择框默认样式(24px)否则超出默认宽度会造成页面样式错乱
315   - ::v-deep(.ant-select-selector) {
  315 + :deep(.ant-select-selector) {
316 316 padding-right: 0px !important;
317 317 }
318 318 </style>
... ...
... ... @@ -5,8 +5,8 @@
5 5 :title="getTitle"
6 6 @register="register"
7 7 width="500px"
8   - showFooter
9 8 @ok="handleSubmit"
  9 + showFooter
10 10 >
11 11 <BasicForm @register="registerForm">
12 12 <template #function>
... ... @@ -27,7 +27,7 @@
27 27 </template>
28 28
29 29 <script lang="ts" setup>
30   - import { ref, computed } from 'vue';
  30 + import { ref, computed, unref } from 'vue';
31 31 import { useDrawerInner, BasicDrawer } from '/@/components/Drawer/index';
32 32 import { useForm, BasicForm } from '/@/components/Form/index';
33 33 import { formSchema } from '../config/config.data';
... ... @@ -40,7 +40,8 @@
40 40 import { beautify } from 'ace-builds/src-noconflict/ext-beautify.js';
41 41
42 42 const emit = defineEmits(['register', 'isStatus', 'success']);
43   - const isUpdate = ref(false);
  43 + const isUpdate: any = ref(false);
  44 + const isView = ref(true);
44 45 const aceEditor = ref();
45 46 const aceRef = ref();
46 47 const getTitle = computed(() => (isUpdate.value ? '编辑转换脚本' : '新增转换脚本'));
... ... @@ -50,9 +51,35 @@
50 51 setDrawerProps({ confirmLoading: false });
51 52 isUpdate.value = data.isUpdate;
52 53 initEditor(data.record?.configuration.jsScript);
53   - if (isUpdate.value) {
54   - editId.value = data.record.id;
55   - setFieldsValue(data.record);
  54 + switch (isUpdate.value) {
  55 + case 'view':
  56 + isView.value = false;
  57 + setDrawerProps({
  58 + showFooter: unref(isView),
  59 + title: '查看转换脚本',
  60 + loading: false,
  61 + });
  62 + editId.value = data.record.id;
  63 + setFieldsValue(data.record);
  64 + break;
  65 + case true:
  66 + isView.value = true;
  67 + setDrawerProps({
  68 + showFooter: unref(isView),
  69 + title: '编辑转换脚本',
  70 + loading: false,
  71 + });
  72 + editId.value = data.record.id;
  73 + setFieldsValue(data.record);
  74 + break;
  75 + case false:
  76 + isView.value = true;
  77 + setDrawerProps({
  78 + showFooter: unref(isView),
  79 + title: '新增转换脚本',
  80 + loading: false,
  81 + });
  82 + break;
56 83 }
57 84 });
58 85 const [registerForm, { validate, setFieldsValue, resetFields }] = useForm({
... ...
... ... @@ -28,10 +28,18 @@
28 28 <TableAction
29 29 :actions="[
30 30 {
  31 + label: '查看',
  32 + auth: 'api:yt:convert:js:get',
  33 + icon: 'ant-design:eye-outlined',
  34 + onClick: handleView.bind(null, record),
  35 + ifShow: record.status == 1,
  36 + },
  37 + {
31 38 label: '编辑',
32 39 auth: 'api:yt:convert:js:update',
33 40 icon: 'clarity:note-edit-line',
34 41 onClick: handleEdit.bind(null, record),
  42 + ifShow: record.status == 0,
35 43 },
36 44 {
37 45 label: '删除',
... ... @@ -59,7 +67,7 @@
59 67 </template>
60 68
61 69 <script lang="ts" setup>
62   - import { ref,nextTick } from 'vue';
  70 + import { ref, nextTick } from 'vue';
63 71 import { Switch } from 'ant-design-vue';
64 72 import { BasicTable, useTable, TableAction } from '/@/components/Table';
65 73 import { columns, searchFormSchema } from './config/config.data';
... ... @@ -130,12 +138,16 @@
130 138 }
131 139 };
132 140 const handleCreate = () => {
133   - openDrawer(true, {
134   - isUpdate: false,
  141 + nextTick(() => {
  142 + openDrawer(true, {
  143 + isUpdate: false,
  144 + });
135 145 });
136 146 };
137 147 const handleEdit = (record: Recordable) => {
138   - openDrawer(true, { isUpdate: true, record });
  148 + nextTick(() => {
  149 + openDrawer(true, { isUpdate: true, record });
  150 + });
139 151 };
140 152 const statusChange = async (checked, record) => {
141 153 setProps({
... ... @@ -159,4 +171,12 @@
159 171 reload();
160 172 }
161 173 };
  174 + function handleView(record: Recordable) {
  175 + nextTick(() => {
  176 + openDrawer(true, {
  177 + record,
  178 + isUpdate: 'view',
  179 + });
  180 + });
  181 + }
162 182 </script>
... ...