Commit dec40da981ad0b97b0a2235f89ec97abb96bc449

Authored by 1400859700@qq.com
2 parents 37a80607 8484ee22

fix:所有字段验证失效问题

Showing 99 changed files with 3970 additions and 1108 deletions
@@ -6,12 +6,18 @@ VITE_PUBLIC_PATH = / @@ -6,12 +6,18 @@ VITE_PUBLIC_PATH = /
6 6
7 # Cross-domain proxy, you can configure multiple 7 # Cross-domain proxy, you can configure multiple
8 # Please note that no line breaks 8 # Please note that no line breaks
9 -# VITE_PROXY = [["/api","http://192.168.10.118:8080/api"],["/upload","http://192.168.10.116:3300/upload"]]  
10 -VITE_PROXY = [["/api","http://101.133.234.90:8080/api"],["/upload","http://192.168.10.116:3300/upload"]]  
11 -# VITE_PROXY=[["/api","https://vvbin.cn/test"]] 9 +
  10 +# 本地
  11 +# VITE_PROXY = [["/api","http://localhost:8080/api"]]
  12 +
  13 +# 线上
  14 +VITE_PROXY = [["/api","http://101.133.234.90:8080/api"]]
  15 +
  16 +# 实时数据的ws地址
  17 +VITE_WEB_SOCKET = ws://101.133.234.90:8080/api/ws/plugins/telemetry?token=
12 18
13 # Delete console 19 # Delete console
14 -VITE_DROP_CONSOLE = false 20 +VITE_DROP_CONSOLE = true
15 21
16 # Basic interface address SPA 22 # Basic interface address SPA
17 VITE_GLOB_API_URL=/api 23 VITE_GLOB_API_URL=/api
@@ -10,26 +10,29 @@ VITE_DROP_CONSOLE = true @@ -10,26 +10,29 @@ VITE_DROP_CONSOLE = true
10 # Whether to enable gzip or brotli compression 10 # Whether to enable gzip or brotli compression
11 # Optional: gzip | brotli | none 11 # Optional: gzip | brotli | none
12 # If you need multiple forms, you can use `,` to separate 12 # If you need multiple forms, you can use `,` to separate
13 -VITE_BUILD_COMPRESS = 'none' 13 +VITE_BUILD_COMPRESS = 'gzip'
14 14
15 # Whether to delete origin files when using compress, default false 15 # Whether to delete origin files when using compress, default false
16 VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE = false 16 VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE = false
17 17
18 # Basic interface address SPA 18 # Basic interface address SPA
19 -VITE_GLOB_API_URL=/api 19 +VITE_GLOB_API_URL=http://localhost:8080/api
20 20
21 # File upload address, optional 21 # File upload address, optional
22 # It can be forwarded by nginx or write the actual address directly 22 # It can be forwarded by nginx or write the actual address directly
23 -VITE_GLOB_UPLOAD_URL=/upload 23 +VITE_GLOB_UPLOAD_URL=http://localhost:8080/upload
24 24
25 # Interface prefix 25 # Interface prefix
26 -VITE_GLOB_API_URL_PREFIX=/v1 26 +VITE_GLOB_API_URL_PREFIX=/yt
27 27
28 # Whether to enable image compression 28 # Whether to enable image compression
29 -VITE_USE_IMAGEMIN= true 29 +VITE_USE_IMAGEMIN= false
30 30
31 # use pwa 31 # use pwa
32 VITE_USE_PWA = false 32 VITE_USE_PWA = false
33 33
34 # Is it compatible with older browsers 34 # Is it compatible with older browsers
35 -VITE_LEGACY = false 35 +VITE_LEGACY = true
  36 +
  37 +# 实时数据的ws地址
  38 +VITE_WEB_SOCKET = ws://101.133.234.90:8080/api/ws/plugins/telemetry?token=
1 -import { BasicPageParams, BasicFetchResult } from '/@/api/model/baseModel';  
2 -/**  
3 - * @description: Request list interface parameters  
4 - */  
5 -export type MessageConfigParams = BasicPageParams & MessageParams;  
6 -  
7 -export type MessageParams = {  
8 - status?: number;  
9 - messageType?: string;  
10 -};  
11 -  
12 -export interface MessageConfig {  
13 - id: string;  
14 - configName: string;  
15 - messageType: string;  
16 - platformType: string;  
17 - config: ConfigParams;  
18 - createTime: string;  
19 - updateTime: string;  
20 - status: number;  
21 -}  
22 -export interface ConfigParams {  
23 - host: string;  
24 - port: number;  
25 - username: string;  
26 - password: string;  
27 - accessKeyId: string;  
28 - accessKeySecret: string;  
29 -}  
30 -  
31 -/**  
32 - * @description: Request list return value  
33 - */  
34 -export type MessageConfigResultModel = BasicFetchResult<MessageConfig>;  
35 -  
36 -export type MessageConfigResult = MessageConfig;  
@@ -30,3 +30,14 @@ export const getDeviceDataKeys = (id: string) => { @@ -30,3 +30,14 @@ export const getDeviceDataKeys = (id: string) => {
30 } 30 }
31 ); 31 );
32 }; 32 };
  33 +// 获取设备状态,在线 or 离线时间
  34 +export const getDeviceActiveTime = (entityId: string) => {
  35 + return defHttp.get(
  36 + {
  37 + url: `/plugins/telemetry/DEVICE/${entityId}/values/attributes?keys=active`,
  38 + },
  39 + {
  40 + joinPrefix: false,
  41 + }
  42 + );
  43 +};
  1 +import { BasicPageParams } from './../model/baseModel';
  2 +import { defHttp } from '/@/utils/http/axios';
  3 +enum HomeEnum {
  4 + home = '/homepage/left/top',
  5 + TenantExpireTimeList = '/homepage/right',
  6 + EntitiesQueryFind = '/entitiesQuery/find',
  7 +}
  8 +
  9 +export const getHomeData = () => {
  10 + return defHttp.get({
  11 + url: HomeEnum.home,
  12 + });
  13 +};
  14 +
  15 +// 获取即将过期租户列表
  16 +export const getTenantExpireTimeList = (params: BasicPageParams) => {
  17 + return defHttp.get({
  18 + url: HomeEnum.TenantExpireTimeList,
  19 + params,
  20 + });
  21 +};
  22 +
  23 +// 获取entities实体ID
  24 +export const getEntitiesId = () => {
  25 + return defHttp.post(
  26 + {
  27 + url: HomeEnum.EntitiesQueryFind,
  28 + data: {
  29 + entityFilter: {
  30 + type: 'apiUsageState',
  31 + resolveMultiple: false,
  32 + },
  33 + pageLink: {
  34 + pageSize: 1,
  35 + page: 0,
  36 + sortOrder: {
  37 + key: {
  38 + type: 'ENTITY_FIELD',
  39 + key: 'createdTime',
  40 + },
  41 + direction: 'DESC',
  42 + },
  43 + },
  44 + entityFields: [
  45 + {
  46 + type: 'ENTITY_FIELD',
  47 + key: 'name',
  48 + },
  49 + {
  50 + type: 'ENTITY_FIELD',
  51 + key: 'label',
  52 + },
  53 + {
  54 + type: 'ENTITY_FIELD',
  55 + key: 'additionalInfo',
  56 + },
  57 + ],
  58 + },
  59 + },
  60 + {
  61 + joinPrefix: false,
  62 + }
  63 + );
  64 +};
1 -import { defHttp } from '/@/utils/http/axios';  
2 -  
3 -enum Api {  
4 - // The address does not exist  
5 - Error = '/error',  
6 -}  
7 -  
8 -/**  
9 - * @description: Trigger ajax error  
10 - */  
11 -  
12 -export const fireErrorApi = () => defHttp.get({ url: Api.Error });  
1 -import { defHttp } from '/@/utils/http/axios';  
2 -  
3 -enum Api {  
4 - TREE_OPTIONS_LIST = '/tree/getDemoOptions',  
5 -}  
6 -  
7 -/**  
8 - * @description: Get sample options value  
9 - */  
10 -export const treeOptionsListApi = (params?: Recordable) =>  
11 - defHttp.get<Recordable[]>({ url: Api.TREE_OPTIONS_LIST, params });  
1 -import { UploadApiResult } from './model/uploadModel'; 1 +import { FileUploadResponse } from './model/uploadModel';
2 import { IPutPersonal } from './model/index'; 2 import { IPutPersonal } from './model/index';
3 import { defHttp } from '/@/utils/http/axios'; 3 import { defHttp } from '/@/utils/http/axios';
4 -import { UploadFileParams } from '/#/axios';  
5 4
6 enum API { 5 enum API {
7 - BaseUploadUrl = '/api/yt/oss/upload', 6 + BaseUploadUrl = '/oss/upload',
8 PutPersonalUrl = '/user/center', 7 PutPersonalUrl = '/user/center',
9 GetPersonalUrl = '/user/', 8 GetPersonalUrl = '/user/',
10 } 9 }
11 -/**  
12 - * @description: Upload interface  
13 - */  
14 -export const uploadApi = (  
15 - params: UploadFileParams,  
16 - onUploadProgress: (progressEvent: ProgressEvent) => void  
17 -) => {  
18 - return defHttp.uploadFile<UploadApiResult>(  
19 - {  
20 - url: API.BaseUploadUrl,  
21 - onUploadProgress,  
22 - },  
23 - params  
24 - ); 10 +export const uploadApi = (file) => {
  11 + return defHttp.post<FileUploadResponse>({ url: API.BaseUploadUrl, params: file });
25 }; 12 };
26 13
27 export const personalGet = (id: string) => { 14 export const personalGet = (id: string) => {
1 -export interface UploadApiResult {  
2 - message: string;  
3 - code: number;  
4 - url: string; 1 +export interface FileUploadResponse {
  2 + fileName: string;
  3 + fileDownloadUri: string;
  4 + fileType: string;
  5 + size: number;
  6 + fileStaticUri: string;
5 } 7 }
@@ -17,7 +17,7 @@ enum Api { @@ -17,7 +17,7 @@ enum Api {
17 export const getMenuList = () => { 17 export const getMenuList = () => {
18 const userStore = useUserStore(); 18 const userStore = useUserStore();
19 let url = Api.GetMenuList; 19 let url = Api.GetMenuList;
20 - if (userStore.getRoleList.find((v) => v == RoleEnum.ROLE_SYS_ADMIN)) { 20 + if (userStore.getRoleList.find((v) => v == RoleEnum.SYS_ADMIN)) {
21 url = Api.SysAdminMenuList; 21 url = Api.SysAdminMenuList;
22 } 22 }
23 return defHttp.get<getMenuListResultModel>({ url }); 23 return defHttp.get<getMenuListResultModel>({ url });
@@ -4,13 +4,14 @@ @@ -4,13 +4,14 @@
4 --> 4 -->
5 5
6 <template> 6 <template>
7 - <div class="anticon" :class="getAppLogoClass" @click="goHome">  
8 - <img :src="getLogo" /> 7 + <div class="application" :class="getAppLogoClass">
  8 + <img v-if="getLogo" :src="getLogo" />
  9 + <img v-else src="/src/assets/images/logo.png" />
9 <span 10 <span
10 class="ml-2 md:opacity-100" 11 class="ml-2 md:opacity-100"
11 :class="getTitleClass" 12 :class="getTitleClass"
12 v-show="showTitle" 13 v-show="showTitle"
13 - style="white-space: nowrap" 14 + style="white-space: nowrap; font-size: small"
14 > 15 >
15 {{ getTitle }} 16 {{ getTitle }}
16 </span> 17 </span>
@@ -19,10 +20,8 @@ @@ -19,10 +20,8 @@
19 <script lang="ts" setup> 20 <script lang="ts" setup>
20 import { computed, unref } from 'vue'; 21 import { computed, unref } from 'vue';
21 import { useGlobSetting } from '/@/hooks/setting'; 22 import { useGlobSetting } from '/@/hooks/setting';
22 - import { useGo } from '/@/hooks/web/usePage';  
23 import { useMenuSetting } from '/@/hooks/setting/useMenuSetting'; 23 import { useMenuSetting } from '/@/hooks/setting/useMenuSetting';
24 import { useDesign } from '/@/hooks/web/useDesign'; 24 import { useDesign } from '/@/hooks/web/useDesign';
25 - import { PageEnum } from '/@/enums/pageEnum';  
26 import { useUserStore } from '/@/store/modules/user'; 25 import { useUserStore } from '/@/store/modules/user';
27 const props = defineProps({ 26 const props = defineProps({
28 /** 27 /**
@@ -43,7 +42,6 @@ @@ -43,7 +42,6 @@
43 const { getCollapsedShowTitle } = useMenuSetting(); 42 const { getCollapsedShowTitle } = useMenuSetting();
44 const userStore = useUserStore(); 43 const userStore = useUserStore();
45 const { title } = useGlobSetting(); 44 const { title } = useGlobSetting();
46 - const go = useGo();  
47 45
48 const getAppLogoClass = computed(() => [ 46 const getAppLogoClass = computed(() => [
49 prefixCls, 47 prefixCls,
@@ -56,12 +54,8 @@ @@ -56,12 +54,8 @@
56 'xs:opacity-0': !props.alwaysShowTitle, 54 'xs:opacity-0': !props.alwaysShowTitle,
57 }, 55 },
58 ]); 56 ]);
59 -  
60 - function goHome() {  
61 - go(userStore.getUserInfo.homePath || PageEnum.BASE_HOME);  
62 - }  
63 const getLogo = computed(() => { 57 const getLogo = computed(() => {
64 - return userStore.platInfo?.logo ?? '/src/assets/images/logo.png'; 58 + return userStore.platInfo?.logo;
65 }); 59 });
66 const getTitle = computed(() => { 60 const getTitle = computed(() => {
67 // 设置icon 61 // 设置icon
@@ -82,7 +76,6 @@ @@ -82,7 +76,6 @@
82 padding-left: 7px; 76 padding-left: 7px;
83 cursor: pointer; 77 cursor: pointer;
84 transition: all 0.2s ease; 78 transition: all 0.2s ease;
85 -  
86 &.light { 79 &.light {
87 border-bottom: 1px solid @border-color-base; 80 border-bottom: 1px solid @border-color-base;
88 } 81 }
1 export enum RoleEnum { 1 export enum RoleEnum {
2 - ROLE_SYS_ADMIN = 'SYS_ADMIN',  
3 - ROLE_TENANT_ADMIN = 'TENANT_ADMIN',  
4 - ROLE_NORMAL_USER = 'CUSTOMER_USER',  
5 - ROLE_PLATFORM_ADMIN = 'PLATFORM_ADMIN', 2 + SYS_ADMIN = 'SYS_ADMIN',
  3 + PLATFORM_ADMIN = 'PLATFORM_ADMIN',
  4 + TENANT_ADMIN = 'TENANT_ADMIN',
  5 + CUSTOMER_USER = 'CUSTOMER_USER',
  6 +}
  7 +
  8 +export function isAdmin(role: string) {
  9 + if (role === RoleEnum.SYS_ADMIN || role === RoleEnum.PLATFORM_ADMIN) {
  10 + return true;
  11 + } else if (role === RoleEnum.TENANT_ADMIN || role === RoleEnum.CUSTOMER_USER) {
  12 + return false;
  13 + }
6 } 14 }
  1 +import { ref, computed } from 'vue';
  2 +import { useMessage } from '/@/hooks/web/useMessage';
  3 +/**
  4 + *
  5 + * @param deleteFn 要删除的API接口方法
  6 + * @param handleSuccess 刷新表格的方法
  7 + * @returns {
  8 + * hasBatchDelete: 是否可以删除
  9 + * selectionOptions 表格复选框配置项
  10 + * handleDeleteOrBatchDelete 删除方法,适用单一删除和批量删除。参数为null为批量删除
  11 + * }
  12 + *
  13 + */
  14 +export interface selectionOptions {
  15 + rowKey: string;
  16 + clickToRowSelect: boolean;
  17 + rowSelection: {
  18 + onChange: (selectedRowKeys: string[]) => void;
  19 + type: 'radio' | 'checkbox';
  20 + };
  21 +}
  22 +export const useBatchDelete = (
  23 + deleteFn: (deleteIds: string[]) => Promise<void>,
  24 + handleSuccess: () => void
  25 +) => {
  26 + const { createMessage } = useMessage();
  27 + const selectedRowIds = ref<string[]>([]);
  28 + const hasBatchDelete = computed(() => selectedRowIds.value.length <= 0);
  29 + // 复选框事件
  30 + const onSelectRowChange = (selectedRowKeys: string[]) => {
  31 + selectedRowIds.value = selectedRowKeys;
  32 + };
  33 + const handleDeleteOrBatchDelete = async (record: Recordable | null) => {
  34 + if (record) {
  35 + try {
  36 + await deleteFn([record.id]);
  37 + createMessage.success('删除联系人成功');
  38 + handleSuccess();
  39 + } catch (e) {
  40 + createMessage.error('删除失败');
  41 + }
  42 + } else {
  43 + try {
  44 + await deleteFn(selectedRowIds.value);
  45 + createMessage.success('批量删除联系人成功');
  46 + selectedRowIds.value = [];
  47 + handleSuccess();
  48 + } catch (e) {
  49 + createMessage.info('删除失败');
  50 + }
  51 + }
  52 + };
  53 + const selectionOptions: selectionOptions = {
  54 + rowKey: 'id',
  55 + clickToRowSelect: false,
  56 + rowSelection: {
  57 + onChange: onSelectRowChange,
  58 + type: 'checkbox',
  59 + },
  60 + };
  61 + return { hasBatchDelete, selectionOptions, handleDeleteOrBatchDelete };
  62 +};
@@ -78,6 +78,7 @@ @@ -78,6 +78,7 @@
78 78
79 .ant-badge { 79 .ant-badge {
80 font-size: 18px; 80 font-size: 18px;
  81 + display: none;
81 82
82 .ant-badge-multiple-words { 83 .ant-badge-multiple-words {
83 padding: 0 4px; 84 padding: 0 4px;
1 import { FormSchema } from '/@/components/Table'; 1 import { FormSchema } from '/@/components/Table';
  2 +import { phoneRule, emailRule } from '/@/utils/rules';
2 3
3 export const formSchema: FormSchema[] = [ 4 export const formSchema: FormSchema[] = [
4 { 5 {
5 - field: 'nickName', 6 + field: 'realName',
6 label: '用户昵称', 7 label: '用户昵称',
7 colProps: { span: 13 }, 8 colProps: { span: 13 },
8 required: true, 9 required: true,
@@ -20,6 +21,7 @@ export const formSchema: FormSchema[] = [ @@ -20,6 +21,7 @@ export const formSchema: FormSchema[] = [
20 componentProps: { 21 componentProps: {
21 placeholder: '请输入手机号码', 22 placeholder: '请输入手机号码',
22 }, 23 },
  24 + rules: phoneRule,
23 }, 25 },
24 { 26 {
25 field: 'email', 27 field: 'email',
@@ -30,5 +32,6 @@ export const formSchema: FormSchema[] = [ @@ -30,5 +32,6 @@ export const formSchema: FormSchema[] = [
30 componentProps: { 32 componentProps: {
31 placeholder: '请输入邮箱', 33 placeholder: '请输入邮箱',
32 }, 34 },
  35 + rules: emailRule,
33 }, 36 },
34 ]; 37 ];
1 <template> 1 <template>
2 <BasicModal 2 <BasicModal
3 :useWrapper="true" 3 :useWrapper="true"
4 - width="80vw" 4 + width="82vw"
5 :height="compHeight" 5 :height="compHeight"
6 v-bind="$attrs" 6 v-bind="$attrs"
7 @register="registerModal" 7 @register="registerModal"
@@ -22,15 +22,34 @@ @@ -22,15 +22,34 @@
22 ><p style="font-size: 17px; margin-top: 7px; margin-left: 10px">个人信息</p></div 22 ><p style="font-size: 17px; margin-top: 7px; margin-left: 10px">个人信息</p></div
23 > 23 >
24 <div class="change-avatar" style="text-align: center"> 24 <div class="change-avatar" style="text-align: center">
25 - <div class="mb-2">头像</div>  
26 - <CropperAvatar  
27 - :uploadApi="uploadApi"  
28 - :value="avatar"  
29 - btnText="更换头像"  
30 - :btnProps="{ preIcon: 'ant-design:cloud-upload-outlined' }"  
31 - @change="updateAvatar"  
32 - width="150"  
33 - /> 25 + <div class="mb-2" style="font-weight: 700">个人头像</div>
  26 + <Upload
  27 + style="width: 20vw"
  28 + name="avatar"
  29 + list-type="picture-card"
  30 + class="avatar-uploader"
  31 + :show-upload-list="false"
  32 + :customRequest="customUploadqrcodePic"
  33 + :before-upload="beforeUploadqrcodePic"
  34 + >
  35 + <img
  36 + style="text-align: center; border-radius: 50%; width: 10vw; height: 15vh"
  37 + v-if="peresonalPic"
  38 + :src="peresonalPic"
  39 + alt="avatar"
  40 + />
  41 + <div v-else>
  42 + <div style="margin-top: 30px">
  43 + <PlusOutlined style="font-size: 30px" />
  44 + </div>
  45 + <div
  46 + class="ant-upload-text flex"
  47 + style="width: 280px; height: 130px; align-items: center"
  48 + >
  49 + 支持.PNG、.JPG、.SVG格式,建议尺寸为300px × 300px(及以上),大小不超过2M。</div
  50 + >
  51 + </div>
  52 + </Upload>
34 </div> 53 </div>
35 <Description 54 <Description
36 class="mt-8" 55 class="mt-8"
@@ -66,13 +85,13 @@ @@ -66,13 +85,13 @@
66 import { BasicForm, useForm } from '/@/components/Form/index'; 85 import { BasicForm, useForm } from '/@/components/Form/index';
67 import { formSchema } from './config'; 86 import { formSchema } from './config';
68 import { Description, DescItem, useDescription } from '/@/components/Description/index'; 87 import { Description, DescItem, useDescription } from '/@/components/Description/index';
69 - import { CropperAvatar } from '/@/components/Cropper';  
70 - import defaultImage from '/@/assets/images/logo.png';  
71 import { uploadApi, personalPut } from '/@/api/personal/index'; 88 import { uploadApi, personalPut } from '/@/api/personal/index';
72 import { useMessage } from '/@/hooks/web/useMessage'; 89 import { useMessage } from '/@/hooks/web/useMessage';
73 import { USER_INFO_KEY } from '/@/enums/cacheEnum'; 90 import { USER_INFO_KEY } from '/@/enums/cacheEnum';
74 import { getAuthCache } from '/@/utils/auth'; 91 import { getAuthCache } from '/@/utils/auth';
75 - import { useUserStore } from '/@/store/modules/user'; 92 + import { Upload } from 'ant-design-vue';
  93 + import { PlusOutlined } from '@ant-design/icons-vue';
  94 + import type { FileItem } from '/@/components/Upload/src/typing';
76 95
77 const schema: DescItem[] = [ 96 const schema: DescItem[] = [
78 { 97 {
@@ -102,68 +121,91 @@ @@ -102,68 +121,91 @@
102 ]; 121 ];
103 export default defineComponent({ 122 export default defineComponent({
104 name: 'index', 123 name: 'index',
105 - components: { BasicModal, BasicForm, Description, CropperAvatar },  
106 - setup() {  
107 - const userStore = useUserStore(); 124 + components: { BasicModal, BasicForm, Description, Upload, PlusOutlined },
  125 + emits: ['refreshPersonl', 'register'],
  126 + setup(_, { emit }) {
108 const userInfo = getAuthCache(USER_INFO_KEY); 127 const userInfo = getAuthCache(USER_INFO_KEY);
109 const { createMessage } = useMessage(); 128 const { createMessage } = useMessage();
110 const getPersonalValue: any = ref({}); 129 const getPersonalValue: any = ref({});
111 const getPersonalDetailValue: any = ref({}); 130 const getPersonalDetailValue: any = ref({});
112 - const avatarUrl: any = ref(''); 131 + const updatePersonalData: any = ref({});
113 const getBackendV: any = ref({}); 132 const getBackendV: any = ref({});
114 const [registerDesc] = useDescription({ 133 const [registerDesc] = useDescription({
115 title: '个人详情', 134 title: '个人详情',
116 schema: schema, 135 schema: schema,
117 }); 136 });
118 137
119 - const [registerModal, { closeModal }] = useModalInner();  
120 - const [registerForm, { validate, resetFields }] = useForm({ 138 + const peresonalPic = ref();
  139 +
  140 + const customUploadqrcodePic = async ({ file }) => {
  141 + if (beforeUploadqrcodePic(file)) {
  142 + const formData = new FormData();
  143 + formData.append('file', file);
  144 + const response = await uploadApi(formData);
  145 + if (response.fileStaticUri) {
  146 + peresonalPic.value = response.fileStaticUri;
  147 + }
  148 + }
  149 + };
  150 +
  151 + const beforeUploadqrcodePic = (file: FileItem) => {
  152 + const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png';
  153 + if (!isJpgOrPng) {
  154 + createMessage.error('只能上传图片文件!');
  155 + }
  156 + const isLt2M = (file.size as number) / 1024 / 1024 < 2;
  157 + if (!isLt2M) {
  158 + createMessage.error('图片大小不能超过2MB!');
  159 + }
  160 + return isJpgOrPng && isLt2M;
  161 + };
  162 +
  163 + const [registerForm, { validate, resetFields, setFieldsValue }] = useForm({
121 showActionButtonGroup: false, 164 showActionButtonGroup: false,
122 schemas: formSchema, 165 schemas: formSchema,
123 }); 166 });
124 - const avatar = computed(() => {  
125 - const { avatar } = userStore.getUserInfo;  
126 - return avatar || defaultImage; 167 +
  168 + const [registerModal, { closeModal }] = useModalInner(async (data) => {
  169 + (peresonalPic.value = data.userInfo.avatar),
  170 + setFieldsValue({
  171 + realName: data.userInfo.realName,
  172 + phoneNumber: data.userInfo.phoneNumber,
  173 + email: data.userInfo.email,
  174 + });
  175 + if (data.userInfo) {
  176 + getPersonalDetailValue.value = data.userInfo;
  177 + }
  178 + if (Object.keys(updatePersonalData.value).length != 0) {
  179 + getPersonalDetailValue.value = updatePersonalData.value;
  180 + peresonalPic.value = updatePersonalData.value.avatar;
  181 + setFieldsValue({
  182 + realName: updatePersonalData.value.realName,
  183 + phoneNumber: updatePersonalData.value.phoneNumber,
  184 + email: updatePersonalData.value.email,
  185 + });
  186 + }
127 }); 187 });
128 const handleSubmit = async () => { 188 const handleSubmit = async () => {
129 - // console.log(userStore.getUserInfo);  
130 const getUserInfo = await userInfo; 189 const getUserInfo = await userInfo;
131 - // console.log(getUserInfo);  
132 getPersonalValue.value = await validate(); 190 getPersonalValue.value = await validate();
133 getPersonalValue.value.id = getUserInfo.userId; 191 getPersonalValue.value.id = getUserInfo.userId;
134 getPersonalValue.value.username = getBackendV.value.username; 192 getPersonalValue.value.username = getBackendV.value.username;
135 - getPersonalValue.value.avatar = avatarUrl.value;  
136 - await personalPut(getPersonalValue.value); 193 + getPersonalValue.value.avatar = peresonalPic.value;
  194 + const data = await personalPut(getPersonalValue.value);
  195 + updatePersonalData.value = data;
137 createMessage.success('修改成功'); 196 createMessage.success('修改成功');
138 closeModal(); 197 closeModal();
139 resetFields(); 198 resetFields();
  199 + emit('refreshPersonl', updatePersonalData.value);
140 }; 200 };
141 - const updateAvatar = async (v) => {  
142 - avatarUrl.value = v.data.fileStaticUri;  
143 - // console.log(avatarUrl.value);  
144 - // await personalPut({ avatar: v });  
145 - };  
146 - const getPersonalDetail = async () => {  
147 - try {  
148 - const getUserInfo = await userInfo;  
149 - getPersonalDetailValue.value = getUserInfo;  
150 - } catch (e) {  
151 - return e;  
152 - }  
153 - };  
154 - getPersonalDetail();  
155 -  
156 - // onMounted(async () => {  
157 - // getPersonalDetail();  
158 - // });  
159 const compHeight = computed(() => { 201 const compHeight = computed(() => {
160 return 1000; 202 return 1000;
161 }); 203 });
162 return { 204 return {
163 - uploadApi, 205 + peresonalPic,
  206 + beforeUploadqrcodePic,
  207 + customUploadqrcodePic,
164 compHeight, 208 compHeight,
165 - updateAvatar,  
166 - avatar,  
167 handleSubmit, 209 handleSubmit,
168 getPersonalDetailValue, 210 getPersonalDetailValue,
169 registerDesc, 211 registerDesc,
@@ -174,4 +216,22 @@ @@ -174,4 +216,22 @@
174 }, 216 },
175 }); 217 });
176 </script> 218 </script>
177 -<style lang="less"></style> 219 +<style scoped lang="less">
  220 + .change-avatar {
  221 + /deep/ .ant-upload-select-picture-card {
  222 + display: inherit;
  223 + float: none;
  224 + width: 10vw;
  225 + height: 17vh;
  226 + margin-right: 8px;
  227 + margin-bottom: 8px;
  228 + text-align: center;
  229 + vertical-align: top;
  230 + background-color: #fafafa;
  231 + border: 1px dashed #d9d9d9;
  232 + border-radius: 50%;
  233 + cursor: pointer;
  234 + transition: border-color 0.3s ease;
  235 + }
  236 + }
  237 +</style>
1 <template> 1 <template>
2 <Dropdown placement="bottomLeft" :overlayClassName="`${prefixCls}-dropdown-overlay`"> 2 <Dropdown placement="bottomLeft" :overlayClassName="`${prefixCls}-dropdown-overlay`">
3 <span :class="[prefixCls, `${prefixCls}--${theme}`]" class="flex"> 3 <span :class="[prefixCls, `${prefixCls}--${theme}`]" class="flex">
4 - <img :class="`${prefixCls}__header`" :src="getUserInfo.avatar" /> 4 + <img
  5 + :class="`${prefixCls}__header`"
  6 + :src="refreshPersonlData.avatar ? refreshPersonlData.avatar : getUserInfo.avatar"
  7 + />
5 <span :class="`${prefixCls}__info hidden md:block`"> 8 <span :class="`${prefixCls}__info hidden md:block`">
6 <span :class="`${prefixCls}__name `" class="truncate"> 9 <span :class="`${prefixCls}__name `" class="truncate">
7 - {{ getUserInfo.realName }} 10 + {{ refreshPersonlData.realName ? refreshPersonlData.realName : getUserInfo.realName }}
8 </span> 11 </span>
9 </span> 12 </span>
10 </span> 13 </span>
@@ -12,12 +15,10 @@ @@ -12,12 +15,10 @@
12 <template #overlay> 15 <template #overlay>
13 <Menu @click="handleMenuClick"> 16 <Menu @click="handleMenuClick">
14 <MenuItem 17 <MenuItem
15 - key="doc"  
16 - :text="t('layout.header.dropdownItemDoc')" 18 + key="personal"
  19 + :text="t('layout.header.dropdownItemPersonal')"
17 icon="ion:document-text-outline" 20 icon="ion:document-text-outline"
18 - v-if="getShowDoc"  
19 /> 21 />
20 - <MenuDivider v-if="getShowDoc" />  
21 <MenuItem 22 <MenuItem
22 v-if="getUseLockPage" 23 v-if="getUseLockPage"
23 key="lock" 24 key="lock"
@@ -29,22 +30,21 @@ @@ -29,22 +30,21 @@
29 :text="t('layout.header.dropdownItemLoginOut')" 30 :text="t('layout.header.dropdownItemLoginOut')"
30 icon="ion:power-outline" 31 icon="ion:power-outline"
31 /> 32 />
32 - <MenuItem  
33 - key="personal"  
34 - :text="t('layout.header.dropdownItemPersonal')"  
35 - icon="ion:build-outlined"  
36 - />  
37 </Menu> 33 </Menu>
38 </template> 34 </template>
39 </Dropdown> 35 </Dropdown>
40 <LockAction @register="register" /> 36 <LockAction @register="register" />
41 - <PersonalChild @register="registerPersonal" /> 37 + <PersonalChild
  38 + @refreshPersonl="refreshPersonlFunc"
  39 + ref="personalRef"
  40 + @register="registerPersonal"
  41 + />
42 </template> 42 </template>
43 <script lang="ts"> 43 <script lang="ts">
44 // components 44 // components
45 import { Dropdown, Menu } from 'ant-design-vue'; 45 import { Dropdown, Menu } from 'ant-design-vue';
46 46
47 - import { defineComponent, computed } from 'vue'; 47 + import { defineComponent, computed, getCurrentInstance, ref, reactive } from 'vue';
48 48
49 import { DOC_URL } from '/@/settings/siteSetting'; 49 import { DOC_URL } from '/@/settings/siteSetting';
50 50
@@ -53,13 +53,12 @@ @@ -53,13 +53,12 @@
53 import { useI18n } from '/@/hooks/web/useI18n'; 53 import { useI18n } from '/@/hooks/web/useI18n';
54 import { useDesign } from '/@/hooks/web/useDesign'; 54 import { useDesign } from '/@/hooks/web/useDesign';
55 import { useModal } from '/@/components/Modal'; 55 import { useModal } from '/@/components/Modal';
56 -  
57 import headerImg from '/@/assets/images/header.jpg'; 56 import headerImg from '/@/assets/images/header.jpg';
58 import { propTypes } from '/@/utils/propTypes'; 57 import { propTypes } from '/@/utils/propTypes';
59 import { openWindow } from '/@/utils'; 58 import { openWindow } from '/@/utils';
60 -  
61 import { createAsyncComponent } from '/@/utils/factory/createAsyncComponent'; 59 import { createAsyncComponent } from '/@/utils/factory/createAsyncComponent';
62 - 60 + import { USER_INFO_KEY } from '/@/enums/cacheEnum';
  61 + import { getAuthCache } from '/@/utils/auth';
63 type MenuEvent = 'logout' | 'doc' | 'lock' | 'personal'; 62 type MenuEvent = 'logout' | 'doc' | 'lock' | 'personal';
64 63
65 export default defineComponent({ 64 export default defineComponent({
@@ -68,7 +67,6 @@ @@ -68,7 +67,6 @@
68 Dropdown, 67 Dropdown,
69 Menu, 68 Menu,
70 MenuItem: createAsyncComponent(() => import('./DropMenuItem.vue')), 69 MenuItem: createAsyncComponent(() => import('./DropMenuItem.vue')),
71 - MenuDivider: Menu.Divider,  
72 LockAction: createAsyncComponent(() => import('../lock/LockModal.vue')), 70 LockAction: createAsyncComponent(() => import('../lock/LockModal.vue')),
73 PersonalChild: createAsyncComponent(() => import('../personal/index.vue')), 71 PersonalChild: createAsyncComponent(() => import('../personal/index.vue')),
74 }, 72 },
@@ -76,14 +74,21 @@ @@ -76,14 +74,21 @@
76 theme: propTypes.oneOf(['dark', 'light']), 74 theme: propTypes.oneOf(['dark', 'light']),
77 }, 75 },
78 setup() { 76 setup() {
  77 + const refreshPersonlData = reactive({
  78 + avatar: '',
  79 + realName: '',
  80 + });
  81 + const userInfo = getAuthCache(USER_INFO_KEY);
  82 + const { proxy } = getCurrentInstance();
  83 + const personalRef = ref(null);
79 const { prefixCls } = useDesign('header-user-dropdown'); 84 const { prefixCls } = useDesign('header-user-dropdown');
80 const { t } = useI18n(); 85 const { t } = useI18n();
81 const { getShowDoc, getUseLockPage } = useHeaderSetting(); 86 const { getShowDoc, getUseLockPage } = useHeaderSetting();
82 const userStore = useUserStore(); 87 const userStore = useUserStore();
83 88
84 const getUserInfo = computed(() => { 89 const getUserInfo = computed(() => {
85 - const { realName = '', avatar, desc } = userStore.getUserInfo || {};  
86 - return { realName, avatar: avatar || headerImg, desc }; 90 + const { realName = '', avatar } = userStore.getUserInfo || {};
  91 + return { realName, avatar: avatar || headerImg };
87 }); 92 });
88 93
89 const [register, { openModal }] = useModal(); 94 const [register, { openModal }] = useModal();
@@ -122,11 +127,21 @@ @@ -122,11 +127,21 @@
122 127
123 const openPersonalFunc = () => { 128 const openPersonalFunc = () => {
124 setTimeout(() => { 129 setTimeout(() => {
125 - openModalPersonal(true); 130 + openModalPersonal(true, {
  131 + userInfo,
  132 + });
126 }, 10); 133 }, 10);
127 }; 134 };
128 135
  136 + const refreshPersonlFunc = (v) => {
  137 + refreshPersonlData.avatar = v.avatar;
  138 + refreshPersonlData.realName = v.realName;
  139 + };
  140 +
129 return { 141 return {
  142 + refreshPersonlData,
  143 + refreshPersonlFunc,
  144 + personalRef,
130 registerPersonal, 145 registerPersonal,
131 openPersonalFunc, 146 openPersonalFunc,
132 prefixCls, 147 prefixCls,
@@ -21,43 +21,18 @@ @@ -21,43 +21,18 @@
21 </transition> 21 </transition>
22 </template> 22 </template>
23 </RouterView> 23 </RouterView>
24 - <!-- <BasicModal  
25 - @register="register"  
26 - v-bind="$attrs"  
27 - :mask="true"  
28 - :showCancelBtn="false"  
29 - :showOkBtn="false"  
30 - :canFullscreen="false"  
31 - :closable="false"  
32 - :maskStyle="maskColor"  
33 - :height="600"  
34 - :width="1500"  
35 - :maskClosable="false"  
36 - title="请您修改初始密码"  
37 - :helpMessage="['请您修改初始密码']"  
38 - :keyboard="false"  
39 - >  
40 - <PasswordDialog />  
41 - </BasicModal> --> 24 +
42 <FrameLayout v-if="getCanEmbedIFramePage" /> 25 <FrameLayout v-if="getCanEmbedIFramePage" />
43 </template> 26 </template>
44 27
45 <script lang="ts"> 28 <script lang="ts">
46 - import { computed, defineComponent, unref, onMounted } from 'vue';  
47 - // import PasswordDialog from '/@/views/system/password/index.vue';  
48 - 29 + import { computed, defineComponent, unref } from 'vue';
49 import FrameLayout from '/@/layouts/iframe/index.vue'; 30 import FrameLayout from '/@/layouts/iframe/index.vue';
50 -  
51 import { useRootSetting } from '/@/hooks/setting/useRootSetting'; 31 import { useRootSetting } from '/@/hooks/setting/useRootSetting';
52 -  
53 import { useTransitionSetting } from '/@/hooks/setting/useTransitionSetting'; 32 import { useTransitionSetting } from '/@/hooks/setting/useTransitionSetting';
54 import { useMultipleTabSetting } from '/@/hooks/setting/useMultipleTabSetting'; 33 import { useMultipleTabSetting } from '/@/hooks/setting/useMultipleTabSetting';
55 import { getTransitionName } from './transition'; 34 import { getTransitionName } from './transition';
56 -  
57 import { useMultipleTabStore } from '/@/store/modules/multipleTab'; 35 import { useMultipleTabStore } from '/@/store/modules/multipleTab';
58 - // import { BasicModal, useModal } from '/@/components/Modal';  
59 - // import { USER_INFO_KEY } from '/@/enums/cacheEnum';  
60 - // import { getAuthCache } from '/@/utils/auth';  
61 export default defineComponent({ 36 export default defineComponent({
62 name: 'PageLayout', 37 name: 'PageLayout',
63 components: { FrameLayout }, 38 components: { FrameLayout },
@@ -78,17 +53,6 @@ @@ -78,17 +53,6 @@
78 return tabStore.getCachedTabList; 53 return tabStore.getCachedTabList;
79 }); 54 });
80 55
81 - // const [register, { openModal }] = useModal();  
82 - // const maskColor = ref({ backgroundColor: 'grey' });  
83 - // const statusModel = ref(false);  
84 - onMounted(() => {  
85 - // const userInfo = getAuthCache(USER_INFO_KEY);  
86 - // if (userInfo.needSetPwd == true) {  
87 - // statusModel.value = true;  
88 - // openModal(statusModel.value);  
89 - // }  
90 - });  
91 -  
92 return { 56 return {
93 getTransitionName, 57 getTransitionName,
94 openCache, 58 openCache,
@@ -96,8 +60,6 @@ @@ -96,8 +60,6 @@
96 getBasicTransition, 60 getBasicTransition,
97 getCaches, 61 getCaches,
98 getCanEmbedIFramePage, 62 getCanEmbedIFramePage,
99 - // register,  
100 - // maskColor,  
101 }; 63 };
102 }, 64 },
103 }); 65 });
@@ -12,7 +12,7 @@ export default { @@ -12,7 +12,7 @@ export default {
12 networkExceptionMsg: 12 networkExceptionMsg:
13 'Please check if your network connection is normal! The network is abnormal', 13 'Please check if your network connection is normal! The network is abnormal',
14 14
15 - errMsg401: 'no permission', 15 + errMsg401: '',
16 errMsg403: 'not authorized', 16 errMsg403: 'not authorized',
17 errMsg404: 'the resource was not found!', 17 errMsg404: 'the resource was not found!',
18 errMsg405: 'Network request error, request method not allowed!', 18 errMsg405: 'Network request error, request method not allowed!',
@@ -10,8 +10,7 @@ export default { @@ -10,8 +10,7 @@ export default {
10 apiRequestFailed: '请求出错,请稍候重试', 10 apiRequestFailed: '请求出错,请稍候重试',
11 networkException: '网络异常', 11 networkException: '网络异常',
12 networkExceptionMsg: '网络异常,请检查您的网络连接是否正常!', 12 networkExceptionMsg: '网络异常,请检查您的网络连接是否正常!',
13 -  
14 - errMsg401: '没有权限!', 13 + errMsg401: '',
15 errMsg403: '未授权', 14 errMsg403: '未授权',
16 errMsg404: '未找到该资源!', 15 errMsg404: '未找到该资源!',
17 errMsg405: '网络请求错误,请求方法未允许!', 16 errMsg405: '网络请求错误,请求方法未允许!',
@@ -14,13 +14,7 @@ import { setupStore } from '/@/store'; @@ -14,13 +14,7 @@ import { setupStore } from '/@/store';
14 import { setupGlobDirectives } from '/@/directives'; 14 import { setupGlobDirectives } from '/@/directives';
15 import { setupI18n } from '/@/locales/setupI18n'; 15 import { setupI18n } from '/@/locales/setupI18n';
16 import { registerGlobComp } from '/@/components/registerGlobComp'; 16 import { registerGlobComp } from '/@/components/registerGlobComp';
17 -// Do not introduce on-demand in local development?  
18 -// In the local development for introduce on-demand, the number of browser requests will increase by about 20%.  
19 -// Which may slow down the browser refresh.  
20 -// Therefore, all are introduced in local development, and only introduced on demand in the production environment  
21 -if (import.meta.env.DEV) {  
22 - import('ant-design-vue/dist/antd.less');  
23 -} 17 +import 'ant-design-vue/dist/antd.less';
24 18
25 async function bootstrap() { 19 async function bootstrap() {
26 const app = createApp(App); 20 const app = createApp(App);
@@ -129,7 +129,6 @@ export const useUserStore = defineStore({ @@ -129,7 +129,6 @@ export const useUserStore = defineStore({
129 try { 129 try {
130 const { goHome = true, mode, ...loginParams } = params; 130 const { goHome = true, mode, ...loginParams } = params;
131 const data = await loginApi(loginParams, mode); 131 const data = await loginApi(loginParams, mode);
132 - console.log(data);  
133 return this.process(data, goHome); 132 return this.process(data, goHome);
134 } catch (error) { 133 } catch (error) {
135 return Promise.reject(error); 134 return Promise.reject(error);
@@ -10,7 +10,6 @@ import { SessionTimeoutProcessingEnum } from '/@/enums/appEnum'; @@ -10,7 +10,6 @@ import { SessionTimeoutProcessingEnum } from '/@/enums/appEnum';
10 const { createMessage, createErrorModal } = useMessage(); 10 const { createMessage, createErrorModal } = useMessage();
11 const error = createMessage.error!; 11 const error = createMessage.error!;
12 const stp = projectSetting.sessionTimeoutProcessing; 12 const stp = projectSetting.sessionTimeoutProcessing;
13 -  
14 export function checkStatus( 13 export function checkStatus(
15 status: number, 14 status: number,
16 msg: string, 15 msg: string,
@@ -19,7 +18,6 @@ export function checkStatus( @@ -19,7 +18,6 @@ export function checkStatus(
19 const { t } = useI18n(); 18 const { t } = useI18n();
20 const userStore = useUserStoreWithOut(); 19 const userStore = useUserStoreWithOut();
21 let errMessage = ''; 20 let errMessage = '';
22 -  
23 switch (status) { 21 switch (status) {
24 case 400: 22 case 400:
25 errMessage = `${msg}`; 23 errMessage = `${msg}`;
@@ -10,58 +10,17 @@ import { useGlobSetting } from '/@/hooks/setting'; @@ -10,58 +10,17 @@ import { useGlobSetting } from '/@/hooks/setting';
10 import { useMessage } from '/@/hooks/web/useMessage'; 10 import { useMessage } from '/@/hooks/web/useMessage';
11 import { RequestEnum, ContentTypeEnum } from '/@/enums/httpEnum'; 11 import { RequestEnum, ContentTypeEnum } from '/@/enums/httpEnum';
12 import { isString } from '/@/utils/is'; 12 import { isString } from '/@/utils/is';
13 -import { getJwtToken, getAuthCache } from '/@/utils/auth'; 13 +import { getJwtToken } from '/@/utils/auth';
14 import { setObjToUrlParams, deepMerge } from '/@/utils'; 14 import { setObjToUrlParams, deepMerge } from '/@/utils';
15 import { useErrorLogStoreWithOut } from '/@/store/modules/errorLog'; 15 import { useErrorLogStoreWithOut } from '/@/store/modules/errorLog';
16 import { useI18n } from '/@/hooks/web/useI18n'; 16 import { useI18n } from '/@/hooks/web/useI18n';
17 import { joinTimestamp, formatRequestDate } from './helper'; 17 import { joinTimestamp, formatRequestDate } from './helper';
18 import { PageEnum } from '/@/enums/pageEnum'; 18 import { PageEnum } from '/@/enums/pageEnum';
19 -import { REFRESH_TOKEN_KEY } from '/@/enums/cacheEnum';  
20 import { router } from '/@/router'; 19 import { router } from '/@/router';
21 20
22 -// import { useUserStore } from '/@/store/modules/user';  
23 -// const userStore = useUserStore();  
24 -// console.log(userStore.userInfo);  
25 -  
26 -// YUNTENG IOT__DEVELOPMENT__2.7.1__COMMON__LOCAL__KEY__  
27 -  
28 -function timestampToTime(timestamp) {  
29 - const date = new Date(timestamp); //时间戳为10位需*1000,时间戳为13位的话不需乘1000  
30 - const Y = date.getFullYear() + '-';  
31 - const M = (date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1) + '-';  
32 - const D = date.getDate() + ' ';  
33 - const h = date.getHours() + ':';  
34 - const m = date.getMinutes() + ':';  
35 - const s = date.getSeconds();  
36 - return Y + M + D + h + m + s;  
37 -}  
38 -  
39 -function convertToDate() {  
40 - const date = new Date();  
41 - const y = date.getFullYear();  
42 - let m = date.getMonth() + 1;  
43 - let d = date.getDate();  
44 - let h = date.getHours();  
45 - let min = date.getMinutes();  
46 - let s = date.getSeconds();  
47 - m = m < 10 ? '0' + m : m; //月小于10,加0  
48 - d = d < 10 ? '0' + d : d; //day小于10,加0  
49 - h = h < 10 ? '0' + h : h;  
50 - min = min < 10 ? '0' + min : min;  
51 - s = s < 10 ? '0' + s : s;  
52 - return y + '-' + m + '-' + d + ' ' + h + ':' + min + ':' + s;  
53 -}  
54 -  
55 const globSetting = useGlobSetting(); 21 const globSetting = useGlobSetting();
56 const urlPrefix = globSetting.urlPrefix; 22 const urlPrefix = globSetting.urlPrefix;
57 const { createMessage, createErrorModal } = useMessage(); 23 const { createMessage, createErrorModal } = useMessage();
58 -const getJwtTokenInfo = getAuthCache(REFRESH_TOKEN_KEY);  
59 -const getExiper = window.localStorage.getItem(  
60 - 'UNDEFINED__DEVELOPMENT__2.7.1__COMMON__LOCAL__KEY__'  
61 -);  
62 -const getExiperValue = JSON.parse(getExiper);  
63 -const expireTime = timestampToTime(getExiperValue.expire);  
64 -const nowTime = convertToDate();  
65 24
66 /** 25 /**
67 * @description: 数据处理,方便区分多种处理方式 26 * @description: 数据处理,方便区分多种处理方式
@@ -162,32 +121,13 @@ const transform: AxiosTransform = { @@ -162,32 +121,13 @@ const transform: AxiosTransform = {
162 const msg: string = response?.data?.msg ?? ''; 121 const msg: string = response?.data?.msg ?? '';
163 const err: string = error?.toString?.() ?? ''; 122 const err: string = error?.toString?.() ?? '';
164 let errMessage = ''; 123 let errMessage = '';
165 -  
166 try { 124 try {
167 - if (response.data.code === '401' || response.data.msg === 'tenant has expired') {  
168 - if (expireTime < nowTime) {  
169 - // console.log('过期');  
170 - createMessage.error('token已经过期,请退回登录');  
171 - } else {  
172 - // console.log('未过期');  
173 - }  
174 - if (getJwtTokenInfo) {  
175 - if (PageEnum.BASE_LOGIN) {  
176 - router.push(PageEnum.BASE_LOGIN);  
177 - }  
178 - }  
179 - // router.beforeEach((to, from, next) => {  
180 - // if (getJwtTokenInfo) {  
181 - // if (to.path !== '/login') {  
182 - // // doRefresh();  
183 - // next({ path: '/' });  
184 - // }  
185 - // }  
186 - // });  
187 - } else {  
188 - // doRefresh(); 125 + console.log(response.data);
  126 + if (response.data.status == '401' || response.data.message == '"Authentication failed"') {
  127 + window.localStorage.clear();
  128 + window.sessionStorage.clear();
  129 + router.push(PageEnum.BASE_HOME);
189 } 130 }
190 -  
191 if (code === 'ECONNABORTED' && message.indexOf('timeout') !== -1) { 131 if (code === 'ECONNABORTED' && message.indexOf('timeout') !== -1) {
192 errMessage = t('sys.api.apiTimeoutMessage'); 132 errMessage = t('sys.api.apiTimeoutMessage');
193 } 133 }
@@ -60,3 +60,171 @@ export const EmailRegexp = /^[a-zA-Z0-9_.-]+@[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)*\.[a @@ -60,3 +60,171 @@ export const EmailRegexp = /^[a-zA-Z0-9_.-]+@[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)*\.[a
60 60
61 // 手机号正则 61 // 手机号正则
62 export const PhoneRegexp = /^[1][3,4,5,6,7,8,9][0-9]{9}$/; 62 export const PhoneRegexp = /^[1][3,4,5,6,7,8,9][0-9]{9}$/;
  63 +
  64 +//站内通知
  65 +export const NotificationTitleMaxLength: Rule[] = [
  66 + {
  67 + required: true,
  68 + validator: (_, value: string) => {
  69 + if (String(value).length > 50) {
  70 + return Promise.reject('标题长度不超过200字');
  71 + }
  72 + return Promise.resolve();
  73 + },
  74 + validateTrigger: 'blur',
  75 + },
  76 +];
  77 +
  78 +export const NotificationContentMaxLength: Rule[] = [
  79 + {
  80 + required: true,
  81 + validator: (_, value: string) => {
  82 + if (String(value).length > 50) {
  83 + return Promise.reject('内容长度不超过50字');
  84 + }
  85 + return Promise.resolve();
  86 + },
  87 + validateTrigger: 'blur',
  88 + },
  89 +];
  90 +
  91 +export const DeviceNameMaxLength: Rule[] = [
  92 + {
  93 + required: true,
  94 + validator: (_, value: string) => {
  95 + if (String(value).length > 30) {
  96 + return Promise.reject('设备名称长度不超过30字');
  97 + }
  98 + return Promise.resolve();
  99 + },
  100 + validateTrigger: 'blur',
  101 + },
  102 +];
  103 +
  104 +export const DeviceProfileIdMaxLength: Rule[] = [
  105 + {
  106 + required: true,
  107 + validator: (_, value: string) => {
  108 + if (String(value).length > 36) {
  109 + return Promise.reject('设备配置长度不超过36字');
  110 + }
  111 + return Promise.resolve();
  112 + },
  113 + validateTrigger: 'blur',
  114 + },
  115 +];
  116 +
  117 +export const DeviceOrgIdMaxLength: Rule[] = [
  118 + {
  119 + required: true,
  120 + validator: (_, value: string) => {
  121 + if (String(value).length > 36) {
  122 + return Promise.reject('组织长度不超过36字');
  123 + }
  124 + return Promise.resolve();
  125 + },
  126 + validateTrigger: 'blur',
  127 + },
  128 +];
  129 +
  130 +export const DeviceLabelMaxLength: Rule[] = [
  131 + {
  132 + required: true,
  133 + validator: (_, value: string) => {
  134 + if (String(value).length > 255) {
  135 + return Promise.reject('设备标签不超过255字');
  136 + }
  137 + return Promise.resolve();
  138 + },
  139 + validateTrigger: 'blur',
  140 + },
  141 +];
  142 +export const DeviceDescriptionlMaxLength: Rule[] = [
  143 + {
  144 + required: true,
  145 + validator: (_, value: string) => {
  146 + if (String(value).length > 500) {
  147 + return Promise.reject('备注不超过500字');
  148 + }
  149 + return Promise.resolve();
  150 + },
  151 + validateTrigger: 'blur',
  152 + },
  153 +];
  154 +export const DeviceIdMaxLength: Rule[] = [
  155 + {
  156 + required: true,
  157 + validator: (_, value: string) => {
  158 + if (String(value).length > 36) {
  159 + return Promise.reject('id不超过36字');
  160 + }
  161 + return Promise.resolve();
  162 + },
  163 + validateTrigger: 'blur',
  164 + },
  165 +];
  166 +
  167 +export const DeviceTenantIdMaxLength: Rule[] = [
  168 + {
  169 + required: true,
  170 + validator: (_, value: string) => {
  171 + if (String(value).length > 36) {
  172 + return Promise.reject('租户Code不超过36字');
  173 + }
  174 + return Promise.resolve();
  175 + },
  176 + validateTrigger: 'blur',
  177 + },
  178 +];
  179 +
  180 +export const DeviceTbDeviceIdMaxLength: Rule[] = [
  181 + {
  182 + required: true,
  183 + validator: (_, value: string) => {
  184 + if (String(value).length > 36) {
  185 + return Promise.reject('tbDeviceId不超过36字');
  186 + }
  187 + return Promise.resolve();
  188 + },
  189 + validateTrigger: 'blur',
  190 + },
  191 +];
  192 +
  193 +export const DeviceUserNameMaxLength: Rule[] = [
  194 + {
  195 + required: true,
  196 + validator: (_, value: string) => {
  197 + if (String(value).length > 50) {
  198 + return Promise.reject('用户名长度不超过50字');
  199 + }
  200 + return Promise.resolve();
  201 + },
  202 + validateTrigger: 'blur',
  203 + },
  204 +];
  205 +
  206 +export const DeviceQueryUserNameMaxLength: Rule[] = [
  207 + {
  208 + required: true,
  209 + validator: (_, value: string) => {
  210 + if (String(value).length > 50) {
  211 + return Promise.reject('设备名称长度不超过50字');
  212 + }
  213 + return Promise.resolve();
  214 + },
  215 + validateTrigger: 'blur',
  216 + },
  217 +];
  218 +
  219 +export const DeviceProfileQueryUserNameMaxLength: Rule[] = [
  220 + {
  221 + required: true,
  222 + validator: (_, value: string) => {
  223 + if (String(value).length > 255) {
  224 + return Promise.reject('配置名称长度不超过255字');
  225 + }
  226 + return Promise.resolve();
  227 + },
  228 + validateTrigger: 'blur',
  229 + },
  230 +];
@@ -33,6 +33,23 @@ export const alarmSearchSchemas: FormSchema[] = [ @@ -33,6 +33,23 @@ export const alarmSearchSchemas: FormSchema[] = [
33 label: '告警类型', 33 label: '告警类型',
34 component: 'Input', 34 component: 'Input',
35 colProps: { span: 6 }, 35 colProps: { span: 6 },
  36 + componentProps: {
  37 + maxLength: 255,
  38 + placeholder: '请输入告警类型',
  39 + },
  40 + dynamicRules: () => {
  41 + return [
  42 + {
  43 + required: false,
  44 + validator: (_, value) => {
  45 + if (String(value).length > 255) {
  46 + return Promise.reject('字数不超过255个字');
  47 + }
  48 + return Promise.resolve();
  49 + },
  50 + },
  51 + ];
  52 + },
36 }, 53 },
37 { 54 {
38 field: 'endTime', 55 field: 'endTime',
@@ -51,7 +51,6 @@ @@ -51,7 +51,6 @@
51 severity: alarmLevel(data.severity), 51 severity: alarmLevel(data.severity),
52 status: statusType(data.status), 52 status: statusType(data.status),
53 }); 53 });
54 - console.log(data.status);  
55 alarmStatus.value = data.status; 54 alarmStatus.value = data.status;
56 alarmId.value = data.id; 55 alarmId.value = data.id;
57 }); 56 });
@@ -41,6 +41,7 @@ export const formSchema: FormSchema[] = [ @@ -41,6 +41,7 @@ export const formSchema: FormSchema[] = [
41 label: '', 41 label: '',
42 component: 'Input', 42 component: 'Input',
43 componentProps: { 43 componentProps: {
  44 + maxLength: 255,
44 placeholder: '请输入设备名称', 45 placeholder: '请输入设备名称',
45 }, 46 },
46 }, 47 },
@@ -34,8 +34,16 @@ @@ -34,8 +34,16 @@
34 :canFullscreen="false" 34 :canFullscreen="false"
35 > 35 >
36 <BasicForm @register="registerForm" /> 36 <BasicForm @register="registerForm" />
37 - <div ref="chartRef" :style="{ height: '600px', width }"></div> 37 + <Alert
  38 + v-if="!isNull"
  39 + message="当前时间节点暂无历史数据"
  40 + description="请尝试选择其他时间段查询历史数据"
  41 + type="warning"
  42 + show-icon
  43 + />
  44 + <div v-show="isNull" ref="chartRef" :style="{ height: '600px', width }"></div>
38 </BasicModal> 45 </BasicModal>
  46 + <DeviceDetailDrawer @register="registerDetailDrawer" />
39 </div> 47 </div>
40 </template> 48 </template>
41 <script lang="ts"> 49 <script lang="ts">
@@ -44,22 +52,30 @@ @@ -44,22 +52,30 @@
44 import { formSchema, columns } from './config.data'; 52 import { formSchema, columns } from './config.data';
45 import { BasicTable, useTable } from '/@/components/Table'; 53 import { BasicTable, useTable } from '/@/components/Table';
46 import { devicePage } from '/@/api/alarm/contact/alarmContact'; 54 import { devicePage } from '/@/api/alarm/contact/alarmContact';
47 - import { Tag } from 'ant-design-vue'; 55 + import { Tag, Alert } from 'ant-design-vue';
48 import { DeviceState } from '/@/api/device/model/deviceModel'; 56 import { DeviceState } from '/@/api/device/model/deviceModel';
49 import { BAI_DU_MAP_URL } from '/@/utils/fnUtils'; 57 import { BAI_DU_MAP_URL } from '/@/utils/fnUtils';
50 import { useModal, BasicModal } from '/@/components/Modal'; 58 import { useModal, BasicModal } from '/@/components/Modal';
51 import { BasicForm, useForm } from '/@/components/Form'; 59 import { BasicForm, useForm } from '/@/components/Form';
52 import { schemas } from './config.data'; 60 import { schemas } from './config.data';
53 import { useECharts } from '/@/hooks/web/useECharts'; 61 import { useECharts } from '/@/hooks/web/useECharts';
54 - import { getDeviceHistoryInfo, getDeviceDataKeys } from '/@/api/alarm/position'; 62 + import {
  63 + getDeviceHistoryInfo,
  64 + getDeviceDataKeys,
  65 + getDeviceActiveTime,
  66 + } from '/@/api/alarm/position';
  67 + import { useDrawer } from '/@/components/Drawer';
  68 + import DeviceDetailDrawer from '/@/views/device/manage/cpns/modal/DeviceDetailDrawer.vue';
55 import moment from 'moment'; 69 import moment from 'moment';
56 export default defineComponent({ 70 export default defineComponent({
57 name: 'BaiduMap', 71 name: 'BaiduMap',
58 components: { 72 components: {
59 BasicTable, 73 BasicTable,
60 Tag, 74 Tag,
  75 + Alert,
61 BasicModal, 76 BasicModal,
62 BasicForm, 77 BasicForm,
  78 + DeviceDetailDrawer,
63 }, 79 },
64 props: { 80 props: {
65 width: { 81 width: {
@@ -74,7 +90,10 @@ @@ -74,7 +90,10 @@
74 setup() { 90 setup() {
75 const wrapRef = ref<HTMLDivElement | null>(null); 91 const wrapRef = ref<HTMLDivElement | null>(null);
76 const { toPromise } = useScript({ src: BAI_DU_MAP_URL }); 92 const { toPromise } = useScript({ src: BAI_DU_MAP_URL });
77 - const entityId = ref(''); 93 + const [registerDetailDrawer, { openDrawer }] = useDrawer();
  94 +
  95 + let entityId = '';
  96 + let globalRecord: any = {};
78 async function initMap() { 97 async function initMap() {
79 await toPromise(); 98 await toPromise();
80 await nextTick(); 99 await nextTick();
@@ -101,13 +120,14 @@ @@ -101,13 +120,14 @@
101 }, 120 },
102 }); 121 });
103 // 点击表格某一行触发 122 // 点击表格某一行触发
104 - const deviceRowClick = (record) => {  
105 - entityId.value = record.tbDeviceId; 123 + const deviceRowClick = async (record) => {
  124 + entityId = record.tbDeviceId;
  125 + globalRecord = record;
106 const BMap = (window as any).BMap; 126 const BMap = (window as any).BMap;
107 const wrapEl = unref(wrapRef); 127 const wrapEl = unref(wrapRef);
108 const map = new BMap.Map(wrapEl); 128 const map = new BMap.Map(wrapEl);
109 if (record.deviceInfo.address) { 129 if (record.deviceInfo.address) {
110 - const { name, organizationDTO, updateTime, deviceState, deviceProfile } = record; 130 + const { name, organizationDTO, deviceState, deviceProfile } = record;
111 const { longitude, latitude, address } = record.deviceInfo; 131 const { longitude, latitude, address } = record.deviceInfo;
112 const point = new BMap.Point(longitude, latitude); 132 const point = new BMap.Point(longitude, latitude);
113 let options = { 133 let options = {
@@ -117,6 +137,10 @@ @@ -117,6 +137,10 @@
117 map.centerAndZoom(point, 15); 137 map.centerAndZoom(point, 15);
118 map.enableScrollWheelZoom(true); 138 map.enableScrollWheelZoom(true);
119 // 创建信息窗口对象 139 // 创建信息窗口对象
  140 + const res = await getDeviceActiveTime(entityId);
  141 +
  142 + let { value: activeStatus, lastUpdateTs } = res[0];
  143 + lastUpdateTs = moment(lastUpdateTs).format('YYYY-MM-DD HH:mm:ss');
120 let infoWindow = new BMap.InfoWindow( 144 let infoWindow = new BMap.InfoWindow(
121 ` 145 `
122 <div style="display:flex;justify-content:space-between; margin:20px 0px;"> 146 <div style="display:flex;justify-content:space-between; margin:20px 0px;">
@@ -132,10 +156,9 @@ @@ -132,10 +156,9 @@
132 <div>所属组织:${organizationDTO.name}</div> 156 <div>所属组织:${organizationDTO.name}</div>
133 <div style="margin-top:6px;">接入协议:${deviceProfile.transportType}</div> 157 <div style="margin-top:6px;">接入协议:${deviceProfile.transportType}</div>
134 <div style="margin-top:6px;">设备位置:${address}</div> 158 <div style="margin-top:6px;">设备位置:${address}</div>
135 - <div style="margin-top:6px;">下线时间:${updateTime}</div>  
136 - <div style="display:flex;justify-content:space-between; margin-top:10px">  
137 - <button style="color:#fff;background-color:#409eff;padding:4px; border-radius:4px;">设备信息</button>  
138 - <button style="color:#fff;background-color:#409eff;padding:4px; border-radius:4px;">报警记录</button> 159 + <div style="margin-top:6px;">${activeStatus ? '在' : '离'}线时间:${lastUpdateTs}</div>
  160 + <div style="display:flex;justify-content:end; margin-top:10px">
  161 + <button onclick="openDeviceInfoDrawer()" style="margin-right:10px;color:#fff;background-color:#409eff;padding:4px; border-radius:4px;">设备信息</button>
139 <button onclick="openHistoryModal()" style="color:#fff;background-color:#409eff;padding:4px; border-radius:4px;">历史数据</button> 162 <button onclick="openHistoryModal()" style="color:#fff;background-color:#409eff;padding:4px; border-radius:4px;">历史数据</button>
140 </div> 163 </div>
141 `, 164 `,
@@ -185,13 +208,20 @@ @@ -185,13 +208,20 @@
185 endTs = Date.now(); 208 endTs = Date.now();
186 // 发送请求 209 // 发送请求
187 const res = await getDeviceHistoryInfo({ 210 const res = await getDeviceHistoryInfo({
188 - entityId: entityId.value, 211 + entityId,
189 keys: keys.join(), 212 keys: keys.join(),
190 startTs, 213 startTs,
191 endTs, 214 endTs,
192 interval, 215 interval,
193 agg, 216 agg,
194 }); 217 });
  218 + // 判断对象是否为空
  219 + if (Object.keys(res).length === 0) {
  220 + isNull.value = false;
  221 + return;
  222 + } else {
  223 + isNull.value = true;
  224 + }
195 // 处理数据 225 // 处理数据
196 for (const key in res) { 226 for (const key in res) {
197 for (const item1 of res[key]) { 227 for (const item1 of res[key]) {
@@ -250,24 +280,38 @@ @@ -250,24 +280,38 @@
250 280
251 const chartRef = ref<HTMLDivElement | null>(null); 281 const chartRef = ref<HTMLDivElement | null>(null);
252 const { setOptions } = useECharts(chartRef as Ref<HTMLDivElement>); 282 const { setOptions } = useECharts(chartRef as Ref<HTMLDivElement>);
253 - 283 + const isNull = ref(true);
  284 + // 设备信息
  285 + const openDeviceInfoDrawer = async () => {
  286 + const { id, tbDeviceId } = globalRecord;
  287 + openDrawer(true, {
  288 + id,
  289 + tbDeviceId,
  290 + });
  291 + };
254 const openHistoryModal = async () => { 292 const openHistoryModal = async () => {
255 openModal(true); 293 openModal(true);
256 -  
257 // 收集参数 294 // 收集参数
258 const dataArray: any[] = []; 295 const dataArray: any[] = [];
259 const startTs = Date.now() - 86400000; //最近一天 296 const startTs = Date.now() - 86400000; //最近一天
260 const endTs = Date.now(); 297 const endTs = Date.now();
261 // 发送请求 298 // 发送请求
262 - keys = await getDeviceDataKeys(entityId.value); 299 + keys = await getDeviceDataKeys(entityId);
263 const res = await getDeviceHistoryInfo({ 300 const res = await getDeviceHistoryInfo({
264 - entityId: entityId.value, 301 + entityId,
265 keys: keys.join(), 302 keys: keys.join(),
266 startTs, 303 startTs,
267 endTs, 304 endTs,
268 interval: 7200000, //间隔两小时 305 interval: 7200000, //间隔两小时
269 agg: 'AVG', 306 agg: 'AVG',
270 }); 307 });
  308 + // 判断对象是否为空
  309 + if (Object.keys(res).length === 0) {
  310 + isNull.value = false;
  311 + return;
  312 + } else {
  313 + isNull.value = true;
  314 + }
271 // 处理数据 315 // 处理数据
272 for (const key in res) { 316 for (const key in res) {
273 for (const item1 of res[key]) { 317 for (const item1 of res[key]) {
@@ -327,12 +371,14 @@ @@ -327,12 +371,14 @@
327 agg: 'AVG', 371 agg: 'AVG',
328 }); 372 });
329 }; 373 };
  374 +
330 const cancelHistoryModal = () => { 375 const cancelHistoryModal = () => {
331 resetFields(); 376 resetFields();
332 setOptions({}); 377 setOptions({});
333 }; 378 };
334 onMounted(() => { 379 onMounted(() => {
335 initMap(); 380 initMap();
  381 + (window as any).openDeviceInfoDrawer = openDeviceInfoDrawer;
336 (window as any).openHistoryModal = openHistoryModal; 382 (window as any).openHistoryModal = openHistoryModal;
337 }); 383 });
338 return { 384 return {
@@ -343,7 +389,9 @@ @@ -343,7 +389,9 @@
343 registerModal, 389 registerModal,
344 registerForm, 390 registerForm,
345 chartRef, 391 chartRef,
  392 + isNull,
346 cancelHistoryModal, 393 cancelHistoryModal,
  394 + registerDetailDrawer,
347 }; 395 };
348 }, 396 },
349 }); 397 });
@@ -56,6 +56,7 @@ export const searchFormSchema: FormSchema[] = [ @@ -56,6 +56,7 @@ export const searchFormSchema: FormSchema[] = [
56 component: 'Input', 56 component: 'Input',
57 colProps: { span: 6 }, 57 colProps: { span: 6 },
58 componentProps: { 58 componentProps: {
  59 + maxLength: 36,
59 placeholder: '请输入联系人姓名', 60 placeholder: '请输入联系人姓名',
60 }, 61 },
61 }, 62 },
@@ -70,6 +71,7 @@ export const formSchema: FormSchema[] = [ @@ -70,6 +71,7 @@ export const formSchema: FormSchema[] = [
70 component: 'Input', 71 component: 'Input',
71 componentProps: { 72 componentProps: {
72 placeholder: '请输入联系人姓名', 73 placeholder: '请输入联系人姓名',
  74 + maxLength: 255,
73 }, 75 },
74 }, 76 },
75 { 77 {
@@ -108,6 +110,7 @@ export const formSchema: FormSchema[] = [ @@ -108,6 +110,7 @@ export const formSchema: FormSchema[] = [
108 component: 'Input', 110 component: 'Input',
109 componentProps: { 111 componentProps: {
110 placeholder: '请输入微信号', 112 placeholder: '请输入微信号',
  113 + maxLength: 255,
111 }, 114 },
112 }, 115 },
113 { 116 {
@@ -115,7 +118,8 @@ export const formSchema: FormSchema[] = [ @@ -115,7 +118,8 @@ export const formSchema: FormSchema[] = [
115 label: '备注', 118 label: '备注',
116 component: 'InputTextArea', 119 component: 'InputTextArea',
117 componentProps: { 120 componentProps: {
118 - placeholder: '', 121 + placeholder: '请输入备注',
  122 + maxLength: 255,
119 }, 123 },
120 }, 124 },
121 { 125 {
@@ -123,5 +127,8 @@ export const formSchema: FormSchema[] = [ @@ -123,5 +127,8 @@ export const formSchema: FormSchema[] = [
123 label: '', 127 label: '',
124 component: 'Input', 128 component: 'Input',
125 show: false, 129 show: false,
  130 + componentProps: {
  131 + maxLength: 36,
  132 + },
126 }, 133 },
127 ]; 134 ];
  1 +<template>
  2 + 123
  3 + <div ref="chartRef" :style="{ height, width }"></div>
  4 +</template>
  5 +<script lang="ts" setup>
  6 + import { ref, Ref, withDefaults } from 'vue';
  7 + import { useECharts } from '/@/hooks/web/useECharts';
  8 +
  9 + interface Props {
  10 + width?: string;
  11 + height?: string;
  12 + }
  13 + withDefaults(defineProps<Props>(), {
  14 + width: '100%',
  15 + height: '280px',
  16 + });
  17 +
  18 + const chartRef = ref<HTMLDivElement | null>(null);
  19 + const { setOptions } = useECharts(chartRef as Ref<HTMLDivElement>);
  20 +</script>
1 <template> 1 <template>
2 - <div class="md:flex justify-between">  
3 - <template v-for="(item, index) in growCardList" :key="item.title">  
4 - <div  
5 - class="growCardItem md:w-1/3 w-full !md:mt-0 !mt-4 bg-white"  
6 - :class="index === 0 ? '!md:ml-0' : '!md:ml-4'" 2 + <div class="md:flex">
  3 + <Card size="small" class="md:w-1/3 w-full !md:mt-0 !mt-4 !md:mr-4">
  4 + <div class="flex" style="height: 100px">
  5 + <div class="mr-4"
  6 + ><img src="/src/assets/images/device-count.png" style="width: 5rem; height: 5rem"
  7 + /></div>
  8 + <div class="flex-auto">
  9 + <div class="flex justify-between" style="align-items: center">
  10 + <div style="font-size: 1.625rem; color: #333">{{
  11 + growCardList?.deviceInfo?.sumCount
  12 + }}</div>
  13 + <img src="/src/assets/images/tip.png" style="width: 1.4rem; height: 1.4rem" />
  14 + </div>
  15 + <div> 设备数(个) </div>
  16 + <div class="flex mt-2">
  17 + <div class="flex mr-1" style="align-items: center; font-size: 0.75rem"
  18 + ><img src="/src/assets/images/online.png" class="mr-1" />
  19 + <span>在线{{ growCardList?.deviceInfo?.onLine }}</span>
  20 + </div>
  21 + <div class="flex mr-1" style="align-items: center; font-size: 0.75rem">
  22 + <img src="/src/assets/images/offline.png" class="mr-1" />
  23 + <span> 离线{{ growCardList?.deviceInfo?.offLine }} </span>
  24 + </div>
  25 + <div class="flex mr-1" style="align-items: center; font-size: 0.75rem">
  26 + <img src="/src/assets/images/inactive.png" class="mr-1" />
  27 + <span> 未激活{{ growCardList?.deviceInfo?.inActive }} </span>
  28 + </div>
  29 + </div>
  30 + </div>
  31 + </div>
  32 + <div class="ml-2 pt-4" style="border-top: 2px solid #f0f2f5">
  33 + 今日新增 {{ growCardList?.deviceInfo?.todayAdd }}</div
  34 + >
  35 + </Card>
  36 + <Card size="small" class="md:w-1/3 w-full !md:mt-0 !mt-4 !md:mr-4">
  37 + <div class="flex" style="height: 100px">
  38 + <div class="mr-4">
  39 + <img
  40 + v-if="!isAdmin(role)"
  41 + src="/src/assets/images/alarm-count.png"
  42 + style="width: 5rem; height: 5rem"
  43 + />
  44 + <img v-else src="/src/assets/images/zh.png" style="width: 5rem; height: 5rem" />
  45 + </div>
  46 + <div class="flex-auto">
  47 + <div class="flex justify-between" style="align-items: center">
  48 + <div v-if="!isAdmin(role)" style="font-size: 1.625rem; color: #333">{{
  49 + growCardList?.alarmInfo?.sumCount
  50 + }}</div>
  51 + <div style="font-size: 1.625rem; color: #333">{{
  52 + growCardList?.tenantInfo?.sumCount
  53 + }}</div>
  54 + <img src="/src/assets/images/tip.png" style="width: 1.4rem; height: 1.4rem" />
  55 + </div>
  56 + <div> {{ !isAdmin(role) ? `${currentMonth}月告警数(条)` : '租户总量(个)' }}</div>
  57 + </div>
  58 + </div>
  59 + <div v-if="!isAdmin(role)" class="ml-2 pt-4" style="border-top: 2px solid #f0f2f5">
  60 + 今日新增 {{ growCardList?.alarmInfo?.todayAdd }}</div
  61 + >
  62 + <div v-else class="ml-2 pt-4" style="border-top: 2px solid #f0f2f5">
  63 + 今日新增 {{ growCardList?.tenantInfo?.todayAdd }}</div
7 > 64 >
8 - <div  
9 - class="  
10 - growCardItem-top  
11 - border border-solid border-t-0 border-r-0 border-l-0 border-b-1  
12 - dark:border-#ccc  
13 - light:border-#F2F2F5  
14 - "  
15 - >  
16 - <img :src="item.imgUrl" style="width: 5rem; height: 5rem" />  
17 - <div class="growCardItem-right">  
18 - <div class="flex justify-between ml-3">  
19 - <div style="font-size: 1.625rem; color: #333">{{ item.value }}</div>  
20 - <img src="../../../../assets/images/tip.png" style="width: 1.4rem; height: 1.4rem" /> 65 + </Card>
  66 + <Card size="small" class="md:w-1/3 w-full !md:mt-0 !mt-4">
  67 + <div class="flex" style="height: 100px">
  68 + <div class="mr-4"
  69 + ><img
  70 + v-if="!isAdmin(role)"
  71 + src="/src/assets/images/msg-count.png"
  72 + style="width: 5rem; height: 5rem"
  73 + /><img v-else src="/src/assets/images/kf.png" style="width: 5rem; height: 5rem" />
  74 + </div>
  75 + <div v-if="!isAdmin(role)" style="display: flex; align-items: center">
  76 + <div>
  77 + <div class="flex" style="align-items: center">
  78 + {{ `${currentMonth}月数据点(条)` }}
  79 + <span style="font-size: 1.625rem; color: #333">
  80 + {{ growCardList?.messageInfo?.dataPointsCount }}</span
  81 + >
21 </div> 82 </div>
22 - <div class="ml-3">{{ item.title }}</div>  
23 - <div class="ml-1.5 mt-3 flex flex-nowrap" style="width: 15rem" v-if="item.offLine">  
24 - <div class="count">  
25 - <img  
26 - src="../../../../assets/images/online.png"  
27 - style="width: 0.6rem; height: 0.6rem"  
28 - class="mr-1"  
29 - />  
30 - 在线 {{ item.onLine }}  
31 - </div>  
32 - <div class="count">  
33 - <img  
34 - src="../../../../assets/images/offline.png"  
35 - style="width: 0.6rem; height: 0.6rem"  
36 - class="mr-1"  
37 - />  
38 - 离线 {{ item.offLine }}  
39 - </div>  
40 - <div class="count">  
41 - <img  
42 - src="../../../../assets/images/inactive.png"  
43 - style="width: 0.6rem; height: 0.6rem"  
44 - class="mr-1"  
45 - />  
46 - 未激活 {{ item.inactive }}  
47 - </div> 83 + <div class="flex" style="align-items: center">
  84 + {{ `${currentMonth}月消息量(条)` }}
  85 + <span style="font-size: 1.625rem; color: #333">
  86 + {{ growCardList?.messageInfo?.messageCount }}</span
  87 + >
48 </div> 88 </div>
49 </div> 89 </div>
50 </div> 90 </div>
51 - <div class="growCardItem-bottom"> 今日新增 {{ item.newDay }}</div> 91 + <div class="flex-auto" v-else>
  92 + <div class="flex justify-between" style="align-items: center">
  93 + <div style="font-size: 1.625rem; color: #333">{{
  94 + growCardList?.customerInfo?.sumCount
  95 + }}</div>
  96 + <img src="/src/assets/images/tip.png" style="width: 1.4rem; height: 1.4rem" />
  97 + </div>
  98 + <div>客户总量(个)</div>
  99 + </div>
  100 + </div>
  101 + <div v-if="!isAdmin(role)" class="ml-2 pt-4" style="border-top: 2px solid #f0f2f5">
  102 + 今日新增
  103 + <span class="ml-8">数据点 ({{ growCardList?.messageInfo?.todayDataPointsAdd }})</span>
  104 + <span class="ml-8">消息量 ({{ growCardList?.messageInfo?.todayMessageAdd }})</span>
52 </div> 105 </div>
53 - </template> 106 + <div v-else class="ml-2 pt-4" style="border-top: 2px solid #f0f2f5">
  107 + 今日新增 {{ growCardList?.customerInfo?.todayAdd }}</div
  108 + >
  109 + </Card>
54 </div> 110 </div>
55 </template> 111 </template>
56 <script lang="ts" setup> 112 <script lang="ts" setup>
57 - import { growCardList } from '../data';  
58 -</script>  
59 -  
60 -<style scoped lang="less">  
61 - .growCardItem {  
62 - height: 11.187rem;  
63 - color: #666;  
64 - .growCardItem-top {  
65 - display: flex;  
66 - margin: 1.25rem;  
67 - padding-bottom: 0.625rem;  
68 - .growCardItem-right {  
69 - width: 18.75rem;  
70 - .count {  
71 - display: flex;  
72 - font-size: 0.75rem;  
73 - align-items: center;  
74 - margin-left: 0.5rem;  
75 - }  
76 - }  
77 - }  
78 - .growCardItem-bottom {  
79 - margin-left: 1.25rem;  
80 - } 113 + import { ref, onMounted, computed } from 'vue';
  114 + import { Card } from 'ant-design-vue';
  115 + import { getHomeData } from '/@/api/dashboard';
  116 + import { isAdmin } from '/@/enums/roleEnum';
  117 + defineProps<{
  118 + role: string;
  119 + }>();
  120 + defineExpose({
  121 + isAdmin,
  122 + });
  123 + interface CardList {
  124 + deviceInfo: {
  125 + sumCount: number;
  126 + onLine: number;
  127 + offLine: number;
  128 + inActive: number;
  129 + todayAdd: number;
  130 + };
  131 + tenantInfo?: { sumCount: number; todayAdd: number };
  132 + customerInfo?: { sumCount: number; todayAdd: number };
  133 + alarmInfo?: {
  134 + sumCount: number;
  135 + todayAdd: number;
  136 + };
  137 + messageInfo?: {
  138 + dataPointsCount: number;
  139 + messageCount: number;
  140 + todayDataPointsAdd: number;
  141 + todayMessageAdd: number;
  142 + };
81 } 143 }
82 -</style> 144 + const growCardList = ref<CardList>();
  145 + onMounted(async () => {
  146 + const res = await getHomeData();
  147 + growCardList.value = res;
  148 + });
  149 + // 获取当前月份0-11 +1
  150 + const currentMonth = computed(() => {
  151 + return new Date().getMonth() + 1;
  152 + });
  153 +</script>
1 <template> 1 <template>
2 - <Card title="帮助文档">  
3 - <div>  
4 - <template v-for="item in helpDoc" :key="item.title">  
5 - <AnchorLink v-bind="item" />  
6 - </template>  
7 - </div>  
8 - <Card  
9 - :tab-list="tabListTitle"  
10 - v-bind="$attrs"  
11 - :active-tab-key="activeKey"  
12 - :bordered="false"  
13 - @tabChange="onTabChange"  
14 - :bodyStyle="{ padding: 0 }"  
15 - >  
16 - <div v-if="activeKey === 'tab1'">  
17 - <List item-layout="horizontal" :dataSource="dataSource">  
18 - <template #renderItem="{ item }">  
19 - <ListItem>  
20 - <ListItemMeta>  
21 - <template #avatar>  
22 - <Avatar src="https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png" />  
23 - </template>  
24 - <template #description>  
25 - <span  
26 - @click="go('/stationnotification/mynotification')"  
27 - class="cursor-pointer noticeTitle"  
28 - >{{ item.sysNotice.title }}  
29 - </span>  
30 - </template>  
31 - <template #title>  
32 - <span>{{ item.user.realName }}</span> 2 + <div>
  3 + <Card title="帮助文档" v-if="!isAdmin(role)">
  4 + <div>
  5 + <template v-for="item in helpDoc" :key="item.title">
  6 + <AnchorLink v-bind="item" />
  7 + </template>
  8 + </div>
  9 + <Card
  10 + v-if="!isAdmin(role)"
  11 + :tab-list="tabListTitle"
  12 + v-bind="$attrs"
  13 + :active-tab-key="activeKey"
  14 + :bordered="false"
  15 + @tabChange="onTabChange"
  16 + :bodyStyle="{ padding: 0 }"
  17 + >
  18 + <div v-if="activeKey === 'tab1'">
  19 + <List item-layout="horizontal" :dataSource="dataSource">
  20 + <template #renderItem="{ item }">
  21 + <ListItem>
  22 + <ListItemMeta>
  23 + <template #avatar>
  24 + <Avatar
  25 + src="https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png"
  26 + />
  27 + </template>
  28 + <template #description>
  29 + <span
  30 + class="cursor-pointer noticeTitle"
  31 + @click="go('/stationnotification/mynotification')"
  32 + >{{ item.sysNotice.title }}
  33 + </span>
  34 + </template>
  35 + <template #title>
  36 + <span>{{ item.user.realName }}</span>
  37 + </template>
  38 + </ListItemMeta>
  39 + <template #extra>
  40 + <Time :value="item.sysNotice.senderDate" />
33 </template> 41 </template>
34 - </ListItemMeta>  
35 - <template #extra>  
36 - <Time :value="item.sysNotice.senderDate" />  
37 - </template>  
38 - </ListItem>  
39 - </template>  
40 - </List>  
41 - <Card hoverable title="联系我们" :bordered="false">  
42 - <template #cover>  
43 - <img :src="getQrCode" alt="" style="width: 150px; height: 150px; margin: 50px auto" />  
44 - </template>  
45 - <CardMeta>  
46 - <template #description>  
47 - <p>联系人: {{ getContacts }}</p>  
48 - <p>联系电话: {{ getTel }}</p>  
49 - <p>联系地址: {{ getAddress }} </p> 42 + </ListItem>
50 </template> 43 </template>
51 - </CardMeta>  
52 - </Card>  
53 - </div> 44 + </List>
  45 + <Card hoverable title="联系我们" :bordered="false">
  46 + <template #cover>
  47 + <img :src="getQrCode" alt="" style="width: 150px; height: 150px; margin: 50px auto" />
  48 + </template>
  49 + <CardMeta>
  50 + <template #description>
  51 + <p>联系人: {{ getContacts }}</p>
  52 + <p>联系电话: {{ getTel }}</p>
  53 + <p>联系地址: {{ getAddress }} </p>
  54 + </template>
  55 + </CardMeta>
  56 + </Card>
  57 + </div>
  58 + </Card>
  59 + </Card>
  60 +
  61 + <Card v-if="isAdmin(role)">
  62 + <Descriptions title="租户消息量TOP10" :column="1">
  63 + <template v-for="(item, index) in 10" :key="index">
  64 + <DescriptionsItem>
  65 + <span
  66 + class="mr-2"
  67 + style="
  68 + width: 1.25rem;
  69 + height: 1.25rem;
  70 + border: 1px solid;
  71 + color: #0b55f1;
  72 + border-radius: 50%;
  73 + display: flex;
  74 + align-items: center;
  75 + justify-content: center;
  76 + "
  77 + :style="{
  78 + color:
  79 + index === 0
  80 + ? '#f0a16e'
  81 + : index === 1
  82 + ? '#868585'
  83 + : index === 2
  84 + ? '#e78739'
  85 + : '#4e84f5',
  86 + backgroundColor:
  87 + index === 0 ? '#fed36a' : index === 1 ? '#CBCAC9' : index === 2 ? '#F1B889' : '',
  88 + borderColor:
  89 + index === 0
  90 + ? '#fdee7d'
  91 + : index === 1
  92 + ? '#e6e6e5'
  93 + : index === 2
  94 + ? '#f8c296'
  95 + : '#0b55f1;',
  96 + }"
  97 + >{{ index + 1 }}</span
  98 + >兰州天兆猪业</DescriptionsItem
  99 + >
  100 + </template>
  101 + </Descriptions>
  102 + </Card>
  103 + <Card v-if="isAdmin(role)">
  104 + <BasicTable @register="registerTable" />
54 </Card> 105 </Card>
55 - </Card> 106 + </div>
56 </template> 107 </template>
57 108
58 <script lang="ts"> 109 <script lang="ts">
59 import { defineComponent, ref, computed, onMounted } from 'vue'; 110 import { defineComponent, ref, computed, onMounted } from 'vue';
60 - import { Card, AnchorLink, List, ListItem, ListItemMeta, Avatar, CardMeta } from 'ant-design-vue'; 111 + import { Card, Anchor, List, Avatar, Descriptions } from 'ant-design-vue';
61 import { useUserStore } from '/@/store/modules/user'; 112 import { useUserStore } from '/@/store/modules/user';
62 import { getEnterPriseDetail } from '/@/api/oem'; 113 import { getEnterPriseDetail } from '/@/api/oem';
63 import { notifyMyGetrPageApi } from '/@/api/stationnotification/stationnotifyApi'; 114 import { notifyMyGetrPageApi } from '/@/api/stationnotification/stationnotifyApi';
64 import { Time } from '/@/components/Time'; 115 import { Time } from '/@/components/Time';
65 import { useGo } from '/@/hooks/web/usePage'; 116 import { useGo } from '/@/hooks/web/usePage';
  117 + import { BasicTable, useTable } from '/@/components/Table';
  118 + import { columns } from './props';
  119 + import { isAdmin } from '/@/enums/roleEnum';
  120 + import { getTenantExpireTimeList } from '/@/api/dashboard';
66 export default defineComponent({ 121 export default defineComponent({
67 components: { 122 components: {
68 Card, 123 Card,
69 - AnchorLink, 124 + CardMeta: Card.Meta,
  125 + AnchorLink: Anchor.Link,
70 List, 126 List,
71 - ListItem,  
72 - ListItemMeta, 127 + ListItem: List.Item,
  128 + ListItemMeta: List.Item.Meta,
  129 + Descriptions,
  130 + DescriptionsItem: Descriptions.Item,
73 Avatar, 131 Avatar,
74 Time, 132 Time,
75 - CardMeta, 133 + BasicTable,
76 }, 134 },
77 - setup() {  
78 - onMounted(async () => {  
79 - const res = await getEnterPriseDetail();  
80 - userStore.setEnterPriseInfo(res);  
81 - }); 135 + props: {
  136 + role: {
  137 + type: String,
  138 + required: true,
  139 + },
  140 + },
  141 + setup(props) {
  142 + // 通知数据
  143 + const dataSource = ref([]);
  144 + const go = useGo();
  145 +
82 const helpDoc = ref([ 146 const helpDoc = ref([
83 { 147 {
84 title: '如何接入设备?', 148 title: '如何接入设备?',
@@ -109,6 +173,18 @@ @@ -109,6 +173,18 @@
109 activeKey.value = key; 173 activeKey.value = key;
110 }; 174 };
111 175
  176 + const [registerTable, { redoHeight }] = useTable({
  177 + api: getTenantExpireTimeList,
  178 + title: '本月即将过期租户',
  179 + showIndexColumn: false,
  180 + useSearchForm: false,
  181 + columns,
  182 + fetchSetting: {
  183 + listField: 'expireTenant.items',
  184 + totalField: 'expireTenant.total',
  185 + },
  186 + });
  187 +
112 const userStore = useUserStore(); 188 const userStore = useUserStore();
113 const getContacts = computed(() => { 189 const getContacts = computed(() => {
114 return userStore.enterPriseInfo?.contacts; 190 return userStore.enterPriseInfo?.contacts;
@@ -122,32 +198,35 @@ @@ -122,32 +198,35 @@
122 const getQrCode = computed(() => { 198 const getQrCode = computed(() => {
123 return userStore.enterPriseInfo?.qrCode; 199 return userStore.enterPriseInfo?.qrCode;
124 }); 200 });
125 -  
126 - // 通知数据  
127 - const dataSource = ref([]);  
128 - const go = useGo();  
129 onMounted(async () => { 201 onMounted(async () => {
130 - const res = await notifyMyGetrPageApi({ page: 1, pageSize: 5 });  
131 - dataSource.value = res.items; 202 + if (isAdmin(props.role)) return;
  203 +
  204 + const res = await getEnterPriseDetail();
  205 + const notice = await notifyMyGetrPageApi({ page: 1, pageSize: 5 });
  206 + userStore.setEnterPriseInfo(res);
  207 + dataSource.value = notice.items;
132 }); 208 });
133 209
134 return { 210 return {
135 activeKey, 211 activeKey,
136 tabListTitle, 212 tabListTitle,
137 - onTabChange,  
138 helpDoc, 213 helpDoc,
139 getQrCode, 214 getQrCode,
140 getContacts, 215 getContacts,
141 getAddress, 216 getAddress,
142 getTel, 217 getTel,
143 dataSource, 218 dataSource,
  219 + onTabChange,
144 go, 220 go,
  221 + registerTable,
  222 + isAdmin,
  223 + redoHeight,
145 }; 224 };
146 }, 225 },
147 }); 226 });
148 </script> 227 </script>
149 228
150 -<style lang="less" scoped> 229 +<style scoped>
151 .noticeTitle:hover { 230 .noticeTitle:hover {
152 border-bottom: 1px solid #ccc; 231 border-bottom: 1px solid #ccc;
153 } 232 }
@@ -4,59 +4,347 @@ @@ -4,59 +4,347 @@
4 v-bind="$attrs" 4 v-bind="$attrs"
5 :active-tab-key="activeKey" 5 :active-tab-key="activeKey"
6 @tabChange="onTabChange" 6 @tabChange="onTabChange"
  7 + v-if="!isAdmin(role)"
7 > 8 >
8 <template #tabBarExtraContent> 9 <template #tabBarExtraContent>
9 <div class="extra-date"> 10 <div class="extra-date">
10 - <template v-for="(item, index) in dateList" :key="item">  
11 - <span @click="changeDate(index)" :class="{ active: index === activeIndex }">{{  
12 - item  
13 - }}</span> 11 + <template v-for="(item, index) in dateList" :key="item.value">
  12 + <span
  13 + @click="quickQueryDate(index, item.value)"
  14 + :class="{ active: index === activeIndex }"
  15 + >{{ item.label }}</span
  16 + >
14 </template> 17 </template>
15 - <DatePicker @change="onDateChange" /> 18 + <DatePicker @change="onDateChange" v-model:value="dateValue" />
16 </div> 19 </div>
17 </template> 20 </template>
18 - <div v-if="activeKey === 'tab1'">  
19 - <p class="center">告警数</p>  
20 - <VisitAnalysis /> 21 + <div v-show="activeKey === '1'">
  22 + <!-- 折线图 -->
  23 + <VisitAnalysis :alarmList="state.alarmList" />
21 </div> 24 </div>
22 - <div v-else>  
23 - <p class="center">消息数</p>  
24 - <VisitAnalysisBar /> 25 + <div v-show="activeKey === '2'">
  26 + <!-- 柱形图 -->
  27 + <VisitAnalysisBar :dataPointList="state.dataPointList" :messageList="state.messageList" />
25 </div> 28 </div>
26 </Card> 29 </Card>
  30 + <Card v-bind="$attrs" v-if="isAdmin(role)" title="租户趋势">
  31 + <TenantTrend />
  32 + </Card>
  33 + <Card v-bind="$attrs" v-if="isAdmin(role)" title="客户趋势">
  34 + <CustomerTrend />
  35 + </Card>
27 </template> 36 </template>
28 <script lang="ts" setup> 37 <script lang="ts" setup>
29 - import { ref } from 'vue'; 38 + import { ref, reactive } from 'vue';
30 import { Card, DatePicker } from 'ant-design-vue'; 39 import { Card, DatePicker } from 'ant-design-vue';
31 import VisitAnalysis from './VisitAnalysis.vue'; 40 import VisitAnalysis from './VisitAnalysis.vue';
32 import VisitAnalysisBar from './VisitAnalysisBar.vue'; 41 import VisitAnalysisBar from './VisitAnalysisBar.vue';
33 -  
34 - const activeKey = ref('tab1');  
35 - 42 + import { isAdmin } from '/@/enums/roleEnum';
  43 + import { useWebSocket } from '@vueuse/core';
  44 + import { getAuthCache } from '/@/utils/auth';
  45 + import CustomerTrend from './CustomerTrend.vue';
  46 + import TenantTrend from './TenantTrend.vue';
  47 + import { JWT_TOKEN_KEY } from '/@/enums/cacheEnum';
  48 + import { formatToDateTime } from '/@/utils/dateUtil';
  49 + import { getEntitiesId } from '/@/api/dashboard/index';
  50 + defineExpose({
  51 + isAdmin,
  52 + });
  53 + const props = defineProps<{
  54 + role: string;
  55 + }>();
  56 + const activeKey = ref('1');
  57 + let entityId = null;
  58 + // 图表tab切换选项卡
36 const tabListTitle = [ 59 const tabListTitle = [
37 { 60 {
38 - key: 'tab1', 61 + key: '1',
39 tab: '告警数统计', 62 tab: '告警数统计',
40 }, 63 },
41 { 64 {
42 - key: 'tab2', 65 + key: '2',
43 tab: '消息量统计', 66 tab: '消息量统计',
44 }, 67 },
45 ]; 68 ];
46 - const dateList = ref(['1小时', '1天', '7天', '30天']);  
47 - const activeIndex = ref(0);  
48 - function onTabChange(key) { 69 + // 快速选择日期
  70 + const activeIndex = ref(3);
  71 + const dateValue = ref();
  72 + const dateList = ref([
  73 + { label: '1小时', value: 3600000 },
  74 + { label: '1天', value: 86400000 },
  75 + { label: '7天', value: 604800000 },
  76 + { label: '30天', value: 2592000000 },
  77 + ]);
  78 + // web Socket
  79 + const token: string = getAuthCache(JWT_TOKEN_KEY);
  80 + const state = reactive({
  81 + server: `${import.meta.env.VITE_WEB_SOCKET}${token}`,
  82 + alarmList: new Array<[number, string]>(),
  83 + alarmItem: new Array<[number, string]>(),
  84 + dataPointList: new Array<[number, string]>(),
  85 + messageList: new Array<[number, string]>(),
  86 + dataPoint: new Array<[number, string]>(),
  87 + MsgCount: new Array<[number, string]>(),
  88 + });
  89 + const { send, close } = useWebSocket(state.server, {
  90 + async onConnected() {
  91 + if (isAdmin(props.role)) return;
  92 + const res = await getEntitiesId();
  93 + entityId = res.data[0].entityId;
  94 + const sendValue = JSON.stringify({
  95 + entityDataCmds: [
  96 + {
  97 + query: {
  98 + entityFilter: {
  99 + type: 'singleEntity',
  100 + singleEntity: entityId,
  101 + },
  102 + pageLink: {
  103 + pageSize: 1024,
  104 + page: 0,
  105 + sortOrder: {
  106 + key: {
  107 + type: 'ENTITY_FIELD',
  108 + key: 'createdTime',
  109 + },
  110 + direction: 'DESC',
  111 + },
  112 + },
  113 + entityFields: [
  114 + {
  115 + type: 'ENTITY_FIELD',
  116 + key: 'name',
  117 + },
  118 + {
  119 + type: 'ENTITY_FIELD',
  120 + key: 'label',
  121 + },
  122 + {
  123 + type: 'ENTITY_FIELD',
  124 + key: 'additionalInfo',
  125 + },
  126 + ],
  127 + latestValues: [
  128 + {
  129 + type: 'TIME_SERIES',
  130 + key: 'createdAlarmsCountHourly',
  131 + },
  132 + ],
  133 + },
  134 + cmdId: activeKey.value,
  135 + },
  136 + ],
  137 + });
  138 + const sendValue1 = JSON.stringify({
  139 + entityDataCmds: [
  140 + {
  141 + cmdId: activeKey.value,
  142 + historyCmd: {
  143 + keys: ['createdAlarmsCountHourly'],
  144 + startTs: Date.now() - 2592000000,
  145 + endTs: Date.now(),
  146 + interval: 86400000,
  147 + agg: 'COUNT',
  148 + },
  149 + },
  150 + ],
  151 + });
  152 + send(sendValue);
  153 + send(sendValue1);
  154 + console.log('建立连接了');
  155 + },
  156 + onMessage(_, e) {
  157 + const { data, update } = JSON.parse(e.data);
  158 + console.log('来新消息了', data, update);
  159 + if (activeKey.value === '1') {
  160 + if (data) {
  161 + const { createdAlarmsCountHourly } = data.data[0].latest.TIME_SERIES;
  162 + state.alarmItem = [createdAlarmsCountHourly.ts, createdAlarmsCountHourly.value];
  163 + state.alarmList.push([createdAlarmsCountHourly.ts, createdAlarmsCountHourly.value]);
  164 + }
  165 + if (update) {
  166 + const { createdAlarmsCountHourly } = update[0].timeseries;
  167 + const newArray: any = [];
  168 + for (const item of createdAlarmsCountHourly) {
  169 + newArray.push([item.ts, item.value]);
  170 + }
  171 + state.alarmList = newArray;
  172 + }
  173 + } else {
  174 + if (data) {
  175 + const { transportDataPointsCountHourly, transportMsgCountHourly } =
  176 + data.data[0].latest.TIME_SERIES;
  177 + state.dataPoint = [
  178 + transportDataPointsCountHourly.ts,
  179 + transportDataPointsCountHourly.value,
  180 + ];
  181 + state.MsgCount = [
  182 + transportDataPointsCountHourly.ts,
  183 + transportDataPointsCountHourly.value,
  184 + ];
  185 + state.dataPointList.push([
  186 + transportDataPointsCountHourly.ts,
  187 + transportDataPointsCountHourly.value,
  188 + ]);
  189 + state.messageList.push([transportMsgCountHourly.ts, transportMsgCountHourly.value]);
  190 + }
  191 + if (update) {
  192 + const { transportDataPointsCountHourly, transportMsgCountHourly } = update[0].timeseries;
  193 + const newArray: any[] = [];
  194 + const newArray1: any[] = [];
  195 + for (const item of transportDataPointsCountHourly) {
  196 + newArray.push([item.ts, item.value]);
  197 + }
  198 + for (const item of transportMsgCountHourly) {
  199 + newArray1.push([item.ts, item.value]);
  200 + }
  201 + state.dataPointList = newArray;
  202 + state.messageList = newArray1;
  203 + }
  204 + }
  205 + },
  206 + onDisconnected() {
  207 + console.log('断开连接了');
  208 + close();
  209 + },
  210 + });
  211 +
  212 + // 切换tab页
  213 + function onTabChange(key: string) {
49 activeKey.value = key; 214 activeKey.value = key;
  215 + activeIndex.value = 3;
  216 + dateValue.value = '';
  217 + const sendValue = JSON.stringify({
  218 + entityDataCmds: [
  219 + {
  220 + cmdId: activeKey.value,
  221 + historyCmd: {
  222 + keys:
  223 + activeKey.value === '1'
  224 + ? ['createdAlarmsCountHourly']
  225 + : ['transportMsgCountHourly', 'transportDataPointsCountHourly'],
  226 + startTs: Date.now() - 2592000000,
  227 + endTs: Date.now(),
  228 + interval: 86400000,
  229 + agg: 'COUNT',
  230 + },
  231 + },
  232 + ],
  233 + });
  234 + if (key === '2') {
  235 + const sendMessageValue = JSON.stringify({
  236 + entityDataCmds: [
  237 + {
  238 + query: {
  239 + entityFilter: {
  240 + type: 'singleEntity',
  241 + singleEntity: entityId,
  242 + },
  243 + pageLink: {
  244 + pageSize: 1024,
  245 + page: 0,
  246 + sortOrder: {
  247 + key: {
  248 + type: 'ENTITY_FIELD',
  249 + key: 'createdTime',
  250 + },
  251 + direction: 'DESC',
  252 + },
  253 + },
  254 + entityFields: [
  255 + {
  256 + type: 'ENTITY_FIELD',
  257 + key: 'name',
  258 + },
  259 + {
  260 + type: 'ENTITY_FIELD',
  261 + key: 'label',
  262 + },
  263 + {
  264 + type: 'ENTITY_FIELD',
  265 + key: 'additionalInfo',
  266 + },
  267 + ],
  268 + latestValues: [
  269 + {
  270 + type: 'TIME_SERIES',
  271 + key: 'transportMsgCountHourly',
  272 + },
  273 + {
  274 + type: 'TIME_SERIES',
  275 + key: 'transportDataPointsCountHourly',
  276 + },
  277 + ],
  278 + },
  279 + cmdId: activeKey.value,
  280 + },
  281 + ],
  282 + });
  283 + send(sendMessageValue);
  284 + }
  285 + send(sendValue);
50 } 286 }
51 - function onDateChange(date, dateString) {  
52 - console.log(date, dateString); 287 + // 选择日期
  288 + function onDateChange(_, dateString) {
  289 + activeIndex.value = -1;
  290 + const dateTime = Number(formatToDateTime(dateString, 'x'));
  291 + // 动态发送ws数据
  292 + const sendValue = JSON.stringify({
  293 + entityDataCmds: [
  294 + {
  295 + cmdId: activeKey.value,
  296 + historyCmd: {
  297 + keys:
  298 + activeKey.value === '1'
  299 + ? ['createdAlarmsCountHourly']
  300 + : ['transportMsgCountHourly', 'transportDataPointsCountHourly'],
  301 + startTs: dateTime,
  302 + endTs: dateTime + 86400000,
  303 + interval: 7200000,
  304 + limit: 12,
  305 + agg: 'COUNT',
  306 + },
  307 + },
  308 + ],
  309 + });
  310 + send(sendValue);
53 } 311 }
54 - function changeDate(index: number) { 312 + // 快速选择时间
  313 + function quickQueryDate(index: number, value: number) {
  314 + if (activeIndex.value === index) return;
55 activeIndex.value = index; 315 activeIndex.value = index;
  316 + dateValue.value = '';
  317 + let interval = 300000;
  318 + if (value === 86400000) {
  319 + interval = 7200000;
  320 + } else if (value === 604800000 || value === 2592000000) {
  321 + interval = 86400000;
  322 + }
  323 + // 动态发送ws数据
  324 + const sendValue = JSON.stringify({
  325 + entityDataCmds: [
  326 + {
  327 + cmdId: activeKey.value,
  328 + historyCmd: {
  329 + keys:
  330 + activeKey.value === '1'
  331 + ? ['createdAlarmsCountHourly']
  332 + : ['transportMsgCountHourly', 'transportDataPointsCountHourly'],
  333 + startTs: Date.now() - value,
  334 + endTs: Date.now(),
  335 + interval,
  336 + agg: 'COUNT',
  337 + },
  338 + },
  339 + ],
  340 + });
  341 + send(sendValue);
  342 +
  343 + console.log(JSON.parse(sendValue), '----interval', state.alarmList);
56 } 344 }
57 </script> 345 </script>
58 346
59 -<style scoped lang="less"> 347 +<style lang="less">
60 .center { 348 .center {
61 display: flex; 349 display: flex;
62 justify-content: center; 350 justify-content: center;
  1 +<template>
  2 + 123
  3 + <div ref="chartRef" :style="{ height, width }"></div>
  4 +</template>
  5 +<script lang="ts" setup>
  6 + import { ref, Ref, withDefaults } from 'vue';
  7 + import { useECharts } from '/@/hooks/web/useECharts';
  8 +
  9 + interface Props {
  10 + width?: string;
  11 + height?: string;
  12 + }
  13 + withDefaults(defineProps<Props>(), {
  14 + width: '100%',
  15 + height: '280px',
  16 + });
  17 +
  18 + const chartRef = ref<HTMLDivElement | null>(null);
  19 + const { setOptions } = useECharts(chartRef as Ref<HTMLDivElement>);
  20 +</script>
1 <template> 1 <template>
2 - <div ref="chartRef" :style="{ height, width }"></div> 2 + <div>
  3 + <p class="center">告警数</p>
  4 + <div ref="chartRef" :style="{ height, width }" v-show="alarmList.length"></div>
  5 + <div v-show="!alarmList.length">暂无数据</div>
  6 + </div>
3 </template> 7 </template>
4 <script lang="ts" setup> 8 <script lang="ts" setup>
5 - import { onMounted, ref, Ref } from 'vue'; 9 + import { onMounted, ref, Ref, withDefaults, watch } from 'vue';
6 import { useECharts } from '/@/hooks/web/useECharts'; 10 import { useECharts } from '/@/hooks/web/useECharts';
7 - import { basicProps } from './props';  
8 11
9 - defineProps({  
10 - ...basicProps, 12 + interface Props {
  13 + width?: string;
  14 + height?: string;
  15 + alarmList: [number, string][];
  16 + }
  17 + const props = withDefaults(defineProps<Props>(), {
  18 + width: '100%',
  19 + height: '280px',
  20 + alarmList: () => [],
11 }); 21 });
  22 +
12 const chartRef = ref<HTMLDivElement | null>(null); 23 const chartRef = ref<HTMLDivElement | null>(null);
13 const { setOptions } = useECharts(chartRef as Ref<HTMLDivElement>); 24 const { setOptions } = useECharts(chartRef as Ref<HTMLDivElement>);
14 25
@@ -16,79 +27,60 @@ @@ -16,79 +27,60 @@
16 setOptions({ 27 setOptions({
17 tooltip: { 28 tooltip: {
18 trigger: 'axis', 29 trigger: 'axis',
19 - axisPointer: {  
20 - lineStyle: {  
21 - width: 1,  
22 - color: '#019680',  
23 - },  
24 - },  
25 }, 30 },
  31 + grid: {
  32 + left: '3%',
  33 + right: '4%',
  34 + bottom: '3%',
  35 + containLabel: true,
  36 + },
  37 +
26 xAxis: { 38 xAxis: {
27 - type: 'category',  
28 - boundaryGap: false,  
29 - data: [  
30 - '6:00',  
31 - '7:00',  
32 - '8:00',  
33 - '9:00',  
34 - '10:00',  
35 - '11:00',  
36 - '12:00',  
37 - '13:00',  
38 - '14:00',  
39 - '15:00',  
40 - '16:00',  
41 - '17:00',  
42 - '18:00',  
43 - '19:00',  
44 - '20:00',  
45 - '21:00',  
46 - '22:00',  
47 - '23:00',  
48 - ],  
49 - splitLine: {  
50 - show: true,  
51 - lineStyle: {  
52 - width: 1,  
53 - type: 'solid',  
54 - color: 'rgba(226,226,226,0.5)',  
55 - },  
56 - },  
57 - axisTick: {  
58 - show: false,  
59 - }, 39 + type: 'time',
  40 + },
  41 + yAxis: {
  42 + type: 'value',
60 }, 43 },
61 - yAxis: [  
62 - {  
63 - type: 'value',  
64 - max: 80000,  
65 - splitNumber: 4,  
66 - axisTick: {  
67 - show: false,  
68 - },  
69 - splitArea: {  
70 - show: true,  
71 - areaStyle: {  
72 - color: ['rgba(255,255,255,0.2)', 'rgba(226,226,226,0.2)'],  
73 - },  
74 - },  
75 - },  
76 - ],  
77 - grid: { left: '1%', right: '1%', top: '2 %', bottom: 0, containLabel: true },  
78 series: [ 44 series: [
79 { 45 {
80 - smooth: true,  
81 - data: [  
82 - 111, 222, 4000, 18000, 33333, 55555, 66666, 33333, 14000, 36000, 66666, 44444, 22222,  
83 - 11111, 4000, 2000, 500, 333, 222, 111,  
84 - ],  
85 - type: 'line',  
86 - areaStyle: {},  
87 - itemStyle: {  
88 - color: '#5ab1ef',  
89 - }, 46 + name: '告警数',
  47 + type: 'bar',
  48 + stack: 'Total',
  49 + data: props.alarmList,
90 }, 50 },
91 ], 51 ],
92 }); 52 });
93 }); 53 });
  54 + watch(
  55 + () => props.alarmList,
  56 + (newValue) => {
  57 + console.log(newValue);
  58 + setOptions({
  59 + tooltip: {
  60 + trigger: 'axis',
  61 + },
  62 + grid: {
  63 + left: '3%',
  64 + right: '4%',
  65 + bottom: '3%',
  66 + containLabel: true,
  67 + },
  68 +
  69 + xAxis: {
  70 + type: 'time',
  71 + },
  72 + yAxis: {
  73 + type: 'value',
  74 + },
  75 + series: [
  76 + {
  77 + name: '告警数',
  78 + type: 'bar',
  79 + stack: 'Total',
  80 + data: newValue,
  81 + },
  82 + ],
  83 + });
  84 + }
  85 + );
94 </script> 86 </script>
1 <template> 1 <template>
2 - <div ref="chartRef" :style="{ height, width }"></div> 2 + <div>
  3 + <p class="center">消息量</p>
  4 + <div ref="chartRef" :style="{ height, width }" v-show="dataPointList.length"></div>
  5 + <div v-show="!dataPointList.length">暂无数据</div>
  6 + </div>
3 </template> 7 </template>
4 <script lang="ts" setup> 8 <script lang="ts" setup>
5 - import { onMounted, ref, Ref } from 'vue'; 9 + import { ref, Ref, watch, withDefaults } from 'vue';
6 import { useECharts } from '/@/hooks/web/useECharts'; 10 import { useECharts } from '/@/hooks/web/useECharts';
7 - import { basicProps } from './props';  
8 -  
9 - defineProps({  
10 - ...basicProps, 11 + type DataItem = [number, string];
  12 + interface Props {
  13 + width?: string;
  14 + height?: string;
  15 + dataPointList: DataItem[];
  16 + messageList: DataItem[];
  17 + }
  18 + const props = withDefaults(defineProps<Props>(), {
  19 + width: '100%',
  20 + height: '280px',
  21 + dataPointList: () => [],
  22 + messageList: () => [],
11 }); 23 });
12 -  
13 const chartRef = ref<HTMLDivElement | null>(null); 24 const chartRef = ref<HTMLDivElement | null>(null);
14 const { setOptions } = useECharts(chartRef as Ref<HTMLDivElement>); 25 const { setOptions } = useECharts(chartRef as Ref<HTMLDivElement>);
15 - onMounted(() => {  
16 - setOptions({  
17 - tooltip: {  
18 - trigger: 'axis',  
19 - axisPointer: {  
20 - lineStyle: {  
21 - width: 1,  
22 - color: '#019680', 26 + watch(
  27 + () => [props.dataPointList, props.messageList],
  28 + ([newValue, newValue1]) => {
  29 + // 计算总量
  30 + let dataPointTotal = 0;
  31 + let messageTotal = 0;
  32 + for (const item of newValue) {
  33 + dataPointTotal += Number(item[1]);
  34 + }
  35 + for (const item of newValue1) {
  36 + messageTotal += Number(item[1]);
  37 + }
  38 + setOptions({
  39 + tooltip: {
  40 + trigger: 'axis',
  41 + axisPointer: {
  42 + type: 'shadow',
23 }, 43 },
24 }, 44 },
25 - },  
26 - grid: { left: '1%', right: '1%', top: '2 %', bottom: 0, containLabel: true },  
27 - xAxis: {  
28 - type: 'category',  
29 - data: [  
30 - '1月',  
31 - '2月',  
32 - '3月',  
33 - '4月',  
34 - '5月',  
35 - '6月',  
36 - '7月',  
37 - '8月',  
38 - '9月',  
39 - '10月',  
40 - '11月',  
41 - '12月',  
42 - ],  
43 - },  
44 - yAxis: {  
45 - type: 'value',  
46 - max: 8000,  
47 - splitNumber: 4,  
48 - },  
49 - series: [  
50 - {  
51 - data: [3000, 2000, 3333, 5000, 3200, 4200, 3200, 2100, 3000, 5100, 6000, 3200, 4800],  
52 - type: 'bar',  
53 - barMaxWidth: 80, 45 + xAxis: {
  46 + type: 'time',
54 }, 47 },
55 - ],  
56 - });  
57 - }); 48 + legend: {
  49 + data: ['传输数据点', '传输消息量'],
  50 + left: '5%',
  51 + orient: 'vertical',
  52 + formatter: (name) => {
  53 + return name === '传输数据点' ? `${name} ${dataPointTotal}` : `${name} ${messageTotal}`;
  54 + },
  55 + },
  56 +
  57 + yAxis: {},
  58 + grid: {
  59 + left: '3%',
  60 + right: '4%',
  61 + bottom: '3%',
  62 + containLabel: true,
  63 + },
  64 + series: [
  65 + {
  66 + name: '传输数据点',
  67 + type: 'bar',
  68 + stack: 'total',
  69 + data: newValue,
  70 + color: '#9fe080',
  71 + },
  72 + {
  73 + name: '传输消息量',
  74 + type: 'bar',
  75 + stack: 'total',
  76 + data: newValue1,
  77 + color: '#5c7bd9',
  78 + },
  79 + ],
  80 + });
  81 + }
  82 + );
58 </script> 83 </script>
1 import { PropType } from 'vue'; 1 import { PropType } from 'vue';
2 - 2 +import type { BasicColumn } from '/@/components/Table';
3 export interface BasicProps { 3 export interface BasicProps {
4 width: string; 4 width: string;
5 height: string; 5 height: string;
@@ -14,3 +14,16 @@ export const basicProps = { @@ -14,3 +14,16 @@ export const basicProps = {
14 default: '280px', 14 default: '280px',
15 }, 15 },
16 }; 16 };
  17 +
  18 +export const columns: BasicColumn[] = [
  19 + {
  20 + title: '租户名称',
  21 + dataIndex: 'name',
  22 + width: 120,
  23 + },
  24 + {
  25 + title: '过期时间',
  26 + dataIndex: 'tenantExpireTime',
  27 + width: 120,
  28 + },
  29 +];
1 -export interface GrowCardItem {  
2 - imgUrl: string;  
3 - title: string;  
4 - value: string;  
5 - onLine?: number;  
6 - offLine?: number;  
7 - inactive?: number;  
8 - newDay: string;  
9 -}  
10 -  
11 -export const growCardList: GrowCardItem[] = [  
12 - {  
13 - imgUrl: '/src/assets/images/device-count.png',  
14 - title: '设备数(个)',  
15 - value: '10,000',  
16 - onLine: 2000,  
17 - offLine: 3000,  
18 - inactive: 4000,  
19 - newDay: '123,45',  
20 - },  
21 - {  
22 - imgUrl: '/src/assets/images/alarm-count.png',  
23 - title: '11月告警数(条)',  
24 - value: '11,000',  
25 - newDay: '167,45',  
26 - },  
27 - {  
28 - imgUrl: '/src/assets/images/msg-count.png',  
29 - title: '11月消息量(条)',  
30 - value: '12,000',  
31 - newDay: '198,45',  
32 - },  
33 -];  
1 <template> 1 <template>
2 <div class="p-4 md:flex"> 2 <div class="p-4 md:flex">
3 <div class="md:w-7/10 w-full !mr-4 enter-y"> 3 <div class="md:w-7/10 w-full !mr-4 enter-y">
4 - <GrowCard :loading="loading" class="enter-y" />  
5 - <SiteAnalysis class="!my-4 enter-y" :loading="loading" />  
6 - <div class="md:flex enter-y"> 4 + <GrowCard :loading="loading" class="enter-y" :role="role" />
  5 + <SiteAnalysis class="!my-4 enter-y" :loading="loading" :role="role" />
  6 + <div class="md:flex enter-y" v-if="!isAdmin(role)">
7 <Card title="核心流程指南" style="width: 100%"> 7 <Card title="核心流程指南" style="width: 100%">
8 - <img alt="核心流程指南" src="../../../assets/images/flow.png" /> 8 + <img alt="核心流程指南" src="/src/assets/images/flow.png" />
9 </Card> 9 </Card>
10 </div> 10 </div>
11 </div> 11 </div>
12 <div class="md:w-3/10 w-full enter-y"> 12 <div class="md:w-3/10 w-full enter-y">
13 - <HelpDoc /> 13 + <HelpDoc :role="role" />
14 </div> 14 </div>
15 </div> 15 </div>
16 </template> 16 </template>
@@ -20,8 +20,19 @@ @@ -20,8 +20,19 @@
20 import SiteAnalysis from './components/SiteAnalysis.vue'; 20 import SiteAnalysis from './components/SiteAnalysis.vue';
21 import { Card } from 'ant-design-vue'; 21 import { Card } from 'ant-design-vue';
22 import HelpDoc from './components/HelpDoc.vue'; 22 import HelpDoc from './components/HelpDoc.vue';
  23 + import { USER_INFO_KEY } from '/@/enums/cacheEnum';
  24 + import { getAuthCache } from '/@/utils/auth';
  25 + import { isAdmin } from '/@/enums/roleEnum';
  26 + defineExpose({
  27 + isAdmin,
  28 + });
23 29
  30 + const userInfo: any = getAuthCache(USER_INFO_KEY);
  31 + const role: string = userInfo.roles[0];
24 const loading = ref(true); 32 const loading = ref(true);
  33 +
  34 + console.log(role);
  35 +
25 setTimeout(() => { 36 setTimeout(() => {
26 loading.value = false; 37 loading.value = false;
27 }, 1500); 38 }, 1500);
@@ -3,6 +3,7 @@ import { findDictItemByCode } from '/@/api/system/dict'; @@ -3,6 +3,7 @@ import { findDictItemByCode } from '/@/api/system/dict';
3 import { deviceProfile } from '/@/api/device/deviceManager'; 3 import { deviceProfile } from '/@/api/device/deviceManager';
4 import { getOrganizationList } from '/@/api/system/system'; 4 import { getOrganizationList } from '/@/api/system/system';
5 import { copyTransFun } from '/@/utils/fnUtils'; 5 import { copyTransFun } from '/@/utils/fnUtils';
  6 +
6 // 第一步的表单 7 // 第一步的表单
7 export const step1Schemas: FormSchema[] = [ 8 export const step1Schemas: FormSchema[] = [
8 { 9 {
@@ -17,6 +18,7 @@ export const step1Schemas: FormSchema[] = [ @@ -17,6 +18,7 @@ export const step1Schemas: FormSchema[] = [
17 required: true, 18 required: true,
18 component: 'Input', 19 component: 'Input',
19 componentProps: { 20 componentProps: {
  21 + placeholder: '设备名称',
20 maxLength: 30, 22 maxLength: 30,
21 }, 23 },
22 }, 24 },
@@ -26,6 +28,7 @@ export const step1Schemas: FormSchema[] = [ @@ -26,6 +28,7 @@ export const step1Schemas: FormSchema[] = [
26 required: true, 28 required: true,
27 component: 'ApiSelect', 29 component: 'ApiSelect',
28 componentProps: { 30 componentProps: {
  31 + placeholder: '设备类型',
29 api: findDictItemByCode, 32 api: findDictItemByCode,
30 params: { 33 params: {
31 dictCode: 'device_type', 34 dictCode: 'device_type',
@@ -64,6 +67,20 @@ export const step1Schemas: FormSchema[] = [ @@ -64,6 +67,20 @@ export const step1Schemas: FormSchema[] = [
64 component: 'Input', 67 component: 'Input',
65 componentProps: { 68 componentProps: {
66 maxLength: 255, 69 maxLength: 255,
  70 + placeholder: '请输入设备标签',
  71 + },
  72 + dynamicRules: () => {
  73 + return [
  74 + {
  75 + required: false,
  76 + validator: (_, value) => {
  77 + if (String(value).length > 255) {
  78 + return Promise.reject('字数不超过255个字');
  79 + }
  80 + return Promise.resolve();
  81 + },
  82 + },
  83 + ];
67 }, 84 },
68 }, 85 },
69 { 86 {
@@ -76,24 +93,92 @@ export const step1Schemas: FormSchema[] = [ @@ -76,24 +93,92 @@ export const step1Schemas: FormSchema[] = [
76 field: 'description', 93 field: 'description',
77 label: '备注', 94 label: '备注',
78 component: 'InputTextArea', 95 component: 'InputTextArea',
  96 + componentProps: {
  97 + maxLength: 500,
  98 + placeholder: '请输入备注',
  99 + },
  100 + dynamicRules: () => {
  101 + return [
  102 + {
  103 + required: false,
  104 + validator: (_, value) => {
  105 + if (String(value).length > 500) {
  106 + return Promise.reject('字数不超过500个字');
  107 + }
  108 + return Promise.resolve();
  109 + },
  110 + },
  111 + ];
  112 + },
79 }, 113 },
80 { 114 {
81 field: 'id', 115 field: 'id',
82 label: 'id', 116 label: 'id',
83 component: 'Input', 117 component: 'Input',
84 show: false, 118 show: false,
  119 + componentProps: {
  120 + maxLength: 36,
  121 + placeholder: '请输入id',
  122 + },
  123 + dynamicRules: () => {
  124 + return [
  125 + {
  126 + required: false,
  127 + validator: (_, value) => {
  128 + if (String(value).length > 36) {
  129 + return Promise.reject('字数不超过36个字');
  130 + }
  131 + return Promise.resolve();
  132 + },
  133 + },
  134 + ];
  135 + },
85 }, 136 },
86 { 137 {
87 field: 'tenantId', 138 field: 'tenantId',
88 label: '租户Code', 139 label: '租户Code',
89 component: 'Input', 140 component: 'Input',
90 show: false, 141 show: false,
  142 + componentProps: {
  143 + maxLength: 36,
  144 + placeholder: '请输入租户Code',
  145 + },
  146 + dynamicRules: () => {
  147 + return [
  148 + {
  149 + required: false,
  150 + validator: (_, value) => {
  151 + if (String(value).length > 36) {
  152 + return Promise.reject('字数不超过36个字');
  153 + }
  154 + return Promise.resolve();
  155 + },
  156 + },
  157 + ];
  158 + },
91 }, 159 },
92 { 160 {
93 field: 'tbDeviceId', 161 field: 'tbDeviceId',
94 label: 'tbDeviceId', 162 label: 'tbDeviceId',
95 component: 'Input', 163 component: 'Input',
96 show: false, 164 show: false,
  165 + componentProps: {
  166 + maxLength: 36,
  167 + placeholder: '请输入tbDeviceId',
  168 + },
  169 + dynamicRules: () => {
  170 + return [
  171 + {
  172 + required: false,
  173 + validator: (_, value) => {
  174 + if (String(value).length > 36) {
  175 + return Promise.reject('字数不超过36个字');
  176 + }
  177 + return Promise.resolve();
  178 + },
  179 + },
  180 + ];
  181 + },
97 }, 182 },
98 ]; 183 ];
99 184
@@ -244,6 +329,10 @@ export const step2Schemas: FormSchema[] = [ @@ -244,6 +329,10 @@ export const step2Schemas: FormSchema[] = [
244 field: 'credentialsId', 329 field: 'credentialsId',
245 required: true, 330 required: true,
246 ifShow: false, 331 ifShow: false,
  332 + componentProps: {
  333 + maxLength: 36,
  334 + placeholder: '请输入访问令牌',
  335 + },
247 }, 336 },
248 { 337 {
249 label: 'RSA公钥', 338 label: 'RSA公钥',
@@ -251,6 +340,10 @@ export const step2Schemas: FormSchema[] = [ @@ -251,6 +340,10 @@ export const step2Schemas: FormSchema[] = [
251 field: 'publicKey', 340 field: 'publicKey',
252 required: true, 341 required: true,
253 ifShow: false, 342 ifShow: false,
  343 + componentProps: {
  344 + maxLength: 36,
  345 + placeholder: '请输入RSA公钥',
  346 + },
254 }, 347 },
255 { 348 {
256 label: '客户端ID', 349 label: '客户端ID',
@@ -258,6 +351,10 @@ export const step2Schemas: FormSchema[] = [ @@ -258,6 +351,10 @@ export const step2Schemas: FormSchema[] = [
258 field: 'clientId', 351 field: 'clientId',
259 required: true, 352 required: true,
260 ifShow: false, 353 ifShow: false,
  354 + componentProps: {
  355 + maxLength: 36,
  356 + placeholder: '请输入客户端ID',
  357 + },
261 }, 358 },
262 { 359 {
263 label: '用户名', 360 label: '用户名',
@@ -265,11 +362,32 @@ export const step2Schemas: FormSchema[] = [ @@ -265,11 +362,32 @@ export const step2Schemas: FormSchema[] = [
265 field: 'username', 362 field: 'username',
266 required: true, 363 required: true,
267 ifShow: false, 364 ifShow: false,
  365 + componentProps: {
  366 + maxLength: 255,
  367 + placeholder: '请输入用户名',
  368 + },
268 }, 369 },
269 { 370 {
270 label: '密码', 371 label: '密码',
271 component: 'InputPassword', 372 component: 'InputPassword',
272 field: 'password', 373 field: 'password',
  374 + componentProps: {
  375 + maxLength: 36,
  376 + placeholder: '请输入密码',
  377 + },
  378 + dynamicRules: () => {
  379 + return [
  380 + {
  381 + required: false,
  382 + validator: (_, value) => {
  383 + if (String(value).length > 36) {
  384 + return Promise.reject('字数不超过36个字');
  385 + }
  386 + return Promise.resolve();
  387 + },
  388 + },
  389 + ];
  390 + },
273 ifShow: false, 391 ifShow: false,
274 }, 392 },
275 ]; 393 ];
@@ -409,6 +527,10 @@ export const TokenSchemas: FormSchema[] = [ @@ -409,6 +527,10 @@ export const TokenSchemas: FormSchema[] = [
409 field: 'credentialsId', 527 field: 'credentialsId',
410 required: true, 528 required: true,
411 ifShow: false, 529 ifShow: false,
  530 + componentProps: {
  531 + maxLength: 36,
  532 + placeholder: '请输入访问令牌',
  533 + },
412 }, 534 },
413 { 535 {
414 label: 'RSA公钥', 536 label: 'RSA公钥',
@@ -416,6 +538,10 @@ export const TokenSchemas: FormSchema[] = [ @@ -416,6 +538,10 @@ export const TokenSchemas: FormSchema[] = [
416 field: 'publicKey', 538 field: 'publicKey',
417 required: true, 539 required: true,
418 ifShow: false, 540 ifShow: false,
  541 + componentProps: {
  542 + maxLength: 36,
  543 + placeholder: '请输入RSA公钥',
  544 + },
419 }, 545 },
420 { 546 {
421 label: '客户端ID', 547 label: '客户端ID',
@@ -423,6 +549,10 @@ export const TokenSchemas: FormSchema[] = [ @@ -423,6 +549,10 @@ export const TokenSchemas: FormSchema[] = [
423 field: 'clientId', 549 field: 'clientId',
424 required: true, 550 required: true,
425 ifShow: false, 551 ifShow: false,
  552 + componentProps: {
  553 + maxLength: 36,
  554 + placeholder: '请输入客户端ID',
  555 + },
426 }, 556 },
427 { 557 {
428 label: '用户名', 558 label: '用户名',
@@ -430,23 +560,78 @@ export const TokenSchemas: FormSchema[] = [ @@ -430,23 +560,78 @@ export const TokenSchemas: FormSchema[] = [
430 field: 'username', 560 field: 'username',
431 required: true, 561 required: true,
432 ifShow: false, 562 ifShow: false,
  563 + componentProps: {
  564 + maxLength: 255,
  565 + placeholder: '请输入用户名',
  566 + },
433 }, 567 },
434 { 568 {
435 label: '密码', 569 label: '密码',
436 component: 'InputPassword', 570 component: 'InputPassword',
437 field: 'password', 571 field: 'password',
438 ifShow: false, 572 ifShow: false,
  573 + componentProps: {
  574 + maxLength: 36,
  575 + placeholder: '请输入密码',
  576 + },
  577 + dynamicRules: () => {
  578 + return [
  579 + {
  580 + required: false,
  581 + validator: (_, value) => {
  582 + if (String(value).length > 36) {
  583 + return Promise.reject('字数不超过36个字');
  584 + }
  585 + return Promise.resolve();
  586 + },
  587 + },
  588 + ];
  589 + },
439 }, 590 },
440 { 591 {
441 label: 'id', 592 label: 'id',
442 component: 'Input', 593 component: 'Input',
443 field: 'id', 594 field: 'id',
444 show: false, 595 show: false,
  596 + componentProps: {
  597 + maxLength: 36,
  598 + placeholder: '请输入id',
  599 + },
  600 + dynamicRules: () => {
  601 + return [
  602 + {
  603 + required: false,
  604 + validator: (_, value) => {
  605 + if (String(value).length > 36) {
  606 + return Promise.reject('字数不超过36个字');
  607 + }
  608 + return Promise.resolve();
  609 + },
  610 + },
  611 + ];
  612 + },
445 }, 613 },
446 { 614 {
447 label: 'tbDeviceId', 615 label: 'tbDeviceId',
448 component: 'Input', 616 component: 'Input',
449 field: 'tbDeviceId', 617 field: 'tbDeviceId',
450 show: false, 618 show: false,
  619 + componentProps: {
  620 + maxLength: 36,
  621 + placeholder: '请输入tbDeviceId',
  622 + },
  623 + dynamicRules: () => {
  624 + return [
  625 + {
  626 + required: false,
  627 + validator: (_, value) => {
  628 + if (String(value).length > 36) {
  629 + return Promise.reject('字数不超过36个字');
  630 + }
  631 + return Promise.resolve();
  632 + },
  633 + },
  634 + ];
  635 + },
451 }, 636 },
452 ]; 637 ];
1 import { formatToDateTime } from '/@/utils/dateUtil'; 1 import { formatToDateTime } from '/@/utils/dateUtil';
2 import { FormSchema } from '/@/components/Form'; 2 import { FormSchema } from '/@/components/Form';
3 import { BasicColumn } from '/@/components/Table'; 3 import { BasicColumn } from '/@/components/Table';
  4 +
4 import { DeviceTypeEnum } from '/@/api/device/model/deviceModel'; 5 import { DeviceTypeEnum } from '/@/api/device/model/deviceModel';
5 6
6 export const columns: BasicColumn[] = [ 7 export const columns: BasicColumn[] = [
@@ -8,25 +9,20 @@ export const columns: BasicColumn[] = [ @@ -8,25 +9,20 @@ export const columns: BasicColumn[] = [
8 title: '设备名称', 9 title: '设备名称',
9 dataIndex: 'name', 10 dataIndex: 'name',
10 width: 120, 11 width: 120,
11 - key: 'name',  
12 }, 12 },
13 { 13 {
14 title: '设备标签', 14 title: '设备标签',
15 dataIndex: 'label', 15 dataIndex: 'label',
16 width: 100, 16 width: 100,
17 - key: 'label',  
18 }, 17 },
19 { 18 {
20 title: '设备配置', 19 title: '设备配置',
21 dataIndex: 'deviceProfile.name', 20 dataIndex: 'deviceProfile.name',
22 width: 160, 21 width: 160,
23 - key: 'deviceProfile.name',  
24 }, 22 },
25 -  
26 { 23 {
27 title: '设备类型', 24 title: '设备类型',
28 dataIndex: 'deviceType', 25 dataIndex: 'deviceType',
29 - key: 'deviceType',  
30 customRender({ text }) { 26 customRender({ text }) {
31 return text === DeviceTypeEnum.GATEWAY 27 return text === DeviceTypeEnum.GATEWAY
32 ? '网关设备' 28 ? '网关设备'
@@ -39,7 +35,6 @@ export const columns: BasicColumn[] = [ @@ -39,7 +35,6 @@ export const columns: BasicColumn[] = [
39 title: '描述', 35 title: '描述',
40 dataIndex: 'description', 36 dataIndex: 'description',
41 width: 180, 37 width: 180,
42 - key: 'description',  
43 }, 38 },
44 ]; 39 ];
45 // 实时数据表格 40 // 实时数据表格
@@ -95,6 +90,9 @@ export const alarmSearchSchemas: FormSchema[] = [ @@ -95,6 +90,9 @@ export const alarmSearchSchemas: FormSchema[] = [
95 label: '告警类型', 90 label: '告警类型',
96 component: 'Input', 91 component: 'Input',
97 colProps: { span: 6 }, 92 colProps: { span: 6 },
  93 + componentProps: {
  94 + maxLength: 36,
  95 + },
98 }, 96 },
99 { 97 {
100 field: 'endTime', 98 field: 'endTime',
@@ -208,6 +206,9 @@ export const alarmSchemasForm: FormSchema[] = [ @@ -208,6 +206,9 @@ export const alarmSchemasForm: FormSchema[] = [
208 field: 'details', 206 field: 'details',
209 label: '详情', 207 label: '详情',
210 component: 'InputTextArea', 208 component: 'InputTextArea',
  209 + componentProps: {
  210 + maxLength: 255,
  211 + },
211 }, 212 },
212 ]; 213 ];
213 214
@@ -218,12 +219,18 @@ export const childDeviceSchemas: FormSchema[] = [ @@ -218,12 +219,18 @@ export const childDeviceSchemas: FormSchema[] = [
218 label: '设备配置', 219 label: '设备配置',
219 component: 'Select', 220 component: 'Select',
220 colProps: { span: 12 }, 221 colProps: { span: 12 },
  222 + componentProps: {
  223 + maxLength: 255,
  224 + },
221 }, 225 },
222 { 226 {
223 field: 'icon', 227 field: 'icon',
224 label: '设备名称', 228 label: '设备名称',
225 component: 'Input', 229 component: 'Input',
226 colProps: { span: 12 }, 230 colProps: { span: 12 },
  231 + componentProps: {
  232 + maxLength: 255,
  233 + },
227 }, 234 },
228 ]; 235 ];
229 export const childDeviceColumns: BasicColumn[] = [ 236 export const childDeviceColumns: BasicColumn[] = [
  1 +import { formatToDate } from '/@/utils/dateUtil';
1 import { BasicColumn } from '/@/components/Table'; 2 import { BasicColumn } from '/@/components/Table';
2 import { FormSchema } from '/@/components/Table'; 3 import { FormSchema } from '/@/components/Table';
3 import { DeviceTypeEnum, DeviceState } from '/@/api/device/model/deviceModel'; 4 import { DeviceTypeEnum, DeviceState } from '/@/api/device/model/deviceModel';
  5 +
4 // 表格列数据 6 // 表格列数据
5 export const columns: BasicColumn[] = [ 7 export const columns: BasicColumn[] = [
6 { 8 {
@@ -19,6 +21,7 @@ export const columns: BasicColumn[] = [ @@ -19,6 +21,7 @@ export const columns: BasicColumn[] = [
19 dataIndex: 'deviceProfile.name', 21 dataIndex: 'deviceProfile.name',
20 width: 160, 22 width: 160,
21 slots: { customRender: 'deviceProfile' }, 23 slots: { customRender: 'deviceProfile' },
  24 + ellipsis: true,
22 }, 25 },
23 26
24 { 27 {
@@ -36,10 +39,16 @@ export const columns: BasicColumn[] = [ @@ -36,10 +39,16 @@ export const columns: BasicColumn[] = [
36 width: 120, 39 width: 120,
37 slots: { customRender: 'deviceState' }, 40 slots: { customRender: 'deviceState' },
38 }, 41 },
39 -  
40 { 42 {
41 title: '最后连接时间', 43 title: '最后连接时间',
42 - dataIndex: 'lastConnectTime', 44 + dataIndex: 'lastOnlineTime',
  45 + format: (text) => formatToDate(text, 'YYYY-MM-DD HH:mm:ss'),
  46 + width: 180,
  47 + },
  48 + {
  49 + title: '最后断开时间',
  50 + dataIndex: 'lastOfflineTime',
  51 + format: (text) => formatToDate(text, 'YYYY-MM-DD HH:mm:ss'),
43 width: 180, 52 width: 180,
44 }, 53 },
45 ]; 54 ];
@@ -76,6 +85,23 @@ export const searchFormSchema: FormSchema[] = [ @@ -76,6 +85,23 @@ export const searchFormSchema: FormSchema[] = [
76 field: 'name', 85 field: 'name',
77 label: '设备名称', 86 label: '设备名称',
78 component: 'Input', 87 component: 'Input',
79 - colProps: { span: 6 }, 88 + colProps: { span: 7 },
  89 + componentProps: {
  90 + maxLength: 255,
  91 + placeholder: '请输入设备名称',
  92 + },
  93 + dynamicRules: () => {
  94 + return [
  95 + {
  96 + required: false,
  97 + validator: (_, value) => {
  98 + if (String(value).length > 255) {
  99 + return Promise.reject('字数不超过255个字');
  100 + }
  101 + return Promise.resolve();
  102 + },
  103 + },
  104 + ];
  105 + },
80 }, 106 },
81 ]; 107 ];
@@ -6,7 +6,7 @@ @@ -6,7 +6,7 @@
6 :destroyOnClose="true" 6 :destroyOnClose="true"
7 @close="closeDrawer" 7 @close="closeDrawer"
8 :title="deviceDetail.name" 8 :title="deviceDetail.name"
9 - width="78%" 9 + width="70%"
10 > 10 >
11 <Tabs v-model:activeKey="activeKey" :size="size" type="card"> 11 <Tabs v-model:activeKey="activeKey" :size="size" type="card">
12 <TabPane key="1" tab="详情" 12 <TabPane key="1" tab="详情"
@@ -26,7 +26,7 @@ @@ -26,7 +26,7 @@
26 import { defineComponent, ref } from 'vue'; 26 import { defineComponent, ref } from 'vue';
27 import { BasicDrawer, useDrawerInner } from '/@/components/Drawer'; 27 import { BasicDrawer, useDrawerInner } from '/@/components/Drawer';
28 28
29 - import { Tabs, TabPane } from 'ant-design-vue'; 29 + import { Tabs } from 'ant-design-vue';
30 import Detail from '../tabs/Detail.vue'; 30 import Detail from '../tabs/Detail.vue';
31 import RealTimeData from '../tabs/RealTimeData.vue'; 31 import RealTimeData from '../tabs/RealTimeData.vue';
32 import Alarm from '../tabs/Alarm.vue'; 32 import Alarm from '../tabs/Alarm.vue';
@@ -37,13 +37,12 @@ @@ -37,13 +37,12 @@
37 components: { 37 components: {
38 BasicDrawer, 38 BasicDrawer,
39 Tabs, 39 Tabs,
40 - TabPane, 40 + TabPane: Tabs.TabPane,
41 Detail, 41 Detail,
42 RealTimeData, 42 RealTimeData,
43 Alarm, 43 Alarm,
44 ChildDevice, 44 ChildDevice,
45 }, 45 },
46 -  
47 emits: ['reload', 'register'], 46 emits: ['reload', 'register'],
48 setup() { 47 setup() {
49 const activeKey = ref('1'); 48 const activeKey = ref('1');
@@ -39,9 +39,10 @@ @@ -39,9 +39,10 @@
39 import { createOrEditDevice } from '/@/api/device/deviceManager'; 39 import { createOrEditDevice } from '/@/api/device/deviceManager';
40 import DeviceStep1 from '../step/DeviceStep1.vue'; 40 import DeviceStep1 from '../step/DeviceStep1.vue';
41 import DeviceStep2 from '../step/DeviceStep2.vue'; 41 import DeviceStep2 from '../step/DeviceStep2.vue';
42 - import { Steps, Step } from 'ant-design-vue'; 42 + import { Steps } from 'ant-design-vue';
43 import { useMessage } from '/@/hooks/web/useMessage'; 43 import { useMessage } from '/@/hooks/web/useMessage';
44 import { credentialTypeEnum } from '../../config/data'; 44 import { credentialTypeEnum } from '../../config/data';
  45 +
45 export default defineComponent({ 46 export default defineComponent({
46 name: 'DeviceModal', 47 name: 'DeviceModal',
47 components: { 48 components: {
@@ -49,7 +50,7 @@ @@ -49,7 +50,7 @@
49 DeviceStep1, 50 DeviceStep1,
50 DeviceStep2, 51 DeviceStep2,
51 Steps, 52 Steps,
52 - Step, 53 + Step: Steps.Step,
53 }, 54 },
54 props: { 55 props: {
55 userData: { type: Object }, 56 userData: { type: Object },
@@ -44,6 +44,13 @@ @@ -44,6 +44,13 @@
44 labelWidth: 120, 44 labelWidth: 120,
45 schemas: alarmSearchSchemas, 45 schemas: alarmSearchSchemas,
46 }, 46 },
  47 + showTableSetting: true,
  48 + tableSetting: {
  49 + redo: true,
  50 + size: false,
  51 + setting: false,
  52 + fullScreen: false,
  53 + },
47 useSearchForm: true, 54 useSearchForm: true,
48 bordered: true, 55 bordered: true,
49 showIndexColumn: false, 56 showIndexColumn: false,
@@ -10,8 +10,8 @@ @@ -10,8 +10,8 @@
10 bordered 10 bordered
11 :columns="columns" 11 :columns="columns"
12 :data-source="[deviceDetail]" 12 :data-source="[deviceDetail]"
  13 + :rowKey="(_, index) => index"
13 :pagination="false" 14 :pagination="false"
14 - rowKey="tbDeviceId"  
15 style="width: 800px" 15 style="width: 800px"
16 /> 16 />
17 </div> 17 </div>
@@ -23,7 +23,7 @@ @@ -23,7 +23,7 @@
23 </div> 23 </div>
24 <div v-if="deviceDetail?.deviceInfo?.address" class="mt-4"> 24 <div v-if="deviceDetail?.deviceInfo?.address" class="mt-4">
25 <p>设备位置</p> 25 <p>设备位置</p>
26 - <div ref="wrapRef" style="height: 400px; width: 90%"></div> 26 + <div ref="wrapRef" style="height: 400px; width: 100%"></div>
27 </div> 27 </div>
28 </div> 28 </div>
29 </template> 29 </template>
@@ -24,7 +24,7 @@ @@ -24,7 +24,7 @@
24 setup(props) { 24 setup(props) {
25 const token: string = getAuthCache(JWT_TOKEN_KEY); 25 const token: string = getAuthCache(JWT_TOKEN_KEY);
26 const state = reactive({ 26 const state = reactive({
27 - server: `ws://101.133.234.90:8080/api/ws/plugins/telemetry?token=${token}`, 27 + server: `${import.meta.env.VITE_WEB_SOCKET}${token}`,
28 sendValue: JSON.stringify({ 28 sendValue: JSON.stringify({
29 attrSubCmds: [], 29 attrSubCmds: [],
30 tsSubCmds: [ 30 tsSubCmds: [
@@ -8,7 +8,7 @@ @@ -8,7 +8,7 @@
8 @cancel="handleCancel" 8 @cancel="handleCancel"
9 > 9 >
10 <div class="step-form-form"> 10 <div class="step-form-form">
11 - <a-steps :current="current"> 11 + <a-steps :current="current" @change="handleChange">
12 <a-step title="设备配置" /> 12 <a-step title="设备配置" />
13 <a-step title="传输配置" /> 13 <a-step title="传输配置" />
14 <a-step title="告警配置" /> 14 <a-step title="告警配置" />
@@ -34,10 +34,9 @@ @@ -34,10 +34,9 @@
34 @next="handleStep3Next" 34 @next="handleStep3Next"
35 @redo="handleRedo" 35 @redo="handleRedo"
36 /></div> 36 /></div>
37 -  
38 <div v-show="current === 3"> 37 <div v-show="current === 3">
39 - <DeviceProfileStep4 ref="DeviceProfileStep4Ref" @prev="handleStepPrev"  
40 - /></div> 38 + <DeviceProfileStep4 ref="DeviceProfileStep4Ref" @prev="handleStepPrev" />
  39 + </div>
41 </div> 40 </div>
42 </BasicModal> 41 </BasicModal>
43 </template> 42 </template>
@@ -86,13 +85,21 @@ @@ -86,13 +85,21 @@
86 const current = ref(0); 85 const current = ref(0);
87 const isUpdate = ref(true); 86 const isUpdate = ref(true);
88 const getTitle = computed(() => (!unref(isUpdate) ? '新增设备配置' : '编辑设备配置')); 87 const getTitle = computed(() => (!unref(isUpdate) ? '新增设备配置' : '编辑设备配置'));
  88 + const handleChange = (v) => {
  89 + console.log(v);
  90 + };
89 const [register, { closeModal }] = useModalInner(async (data) => { 91 const [register, { closeModal }] = useModalInner(async (data) => {
90 isUpdate.value = !!data?.isUpdate; 92 isUpdate.value = !!data?.isUpdate;
91 if (!unref(isUpdate)) { 93 if (!unref(isUpdate)) {
92 current.value = 0; 94 current.value = 0;
  95 + proxy.$refs.DeviceProfileStep3Ref.clearProfileDataFunc();
  96 + proxy.$refs.DeviceProfileStep3Ref.addAlarmRule();
  97 + // proxy.$refs.DeviceProfileStep4Ref.customResetAndFunc();
  98 +
93 switch (current.value) { 99 switch (current.value) {
94 case 0: 100 case 0:
95 proxy.$refs.DeviceProfileStep1Ref.customResetFunc(); 101 proxy.$refs.DeviceProfileStep1Ref.customResetFunc();
  102 + proxy.$refs.DeviceProfileStep1Ref.resetIconFunc();
96 break; 103 break;
97 case 1: 104 case 1:
98 proxy.$refs.DeviceProfileStep2Ref.customResetAndFunc(); 105 proxy.$refs.DeviceProfileStep2Ref.customResetAndFunc();
@@ -109,32 +116,15 @@ @@ -109,32 +116,15 @@
109 } 116 }
110 if (unref(isUpdate)) { 117 if (unref(isUpdate)) {
111 current.value = 0; 118 current.value = 0;
  119 + proxy.$refs.DeviceProfileStep3Ref.clearProfileDataFunc();
  120 + proxy.$refs.DeviceProfileStep3Ref.addAlarmRule();
112 postEditId.value = data.record.id; 121 postEditId.value = data.record.id;
113 const getBackendData = await deviceConfigGetDetail(postEditId.value); 122 const getBackendData = await deviceConfigGetDetail(postEditId.value);
114 editEchoData.value = { ...getBackendData }; 123 editEchoData.value = { ...getBackendData };
115 - console.log(editEchoData.value);  
116 switch (current.value) { 124 switch (current.value) {
117 case 0: 125 case 0:
118 proxy.$refs.DeviceProfileStep1Ref.resetFieldsFunc(editEchoData.value); 126 proxy.$refs.DeviceProfileStep1Ref.resetFieldsFunc(editEchoData.value);
119 - break;  
120 - case 1:  
121 - proxy.$refs.DeviceProfileStep2Ref.resetFieldsFunc({  
122 - transportType: editEchoData.value.profileData.transportConfiguration.type,  
123 - });  
124 - break;  
125 - case 2:  
126 - proxy.$refs.DeviceProfileStep3Ref.retryRegisterFormFunc({  
127 - alarmType: editEchoData.value.profileData?.alarms[0].alarmType,  
128 - });  
129 - proxy.$refs.DeviceProfileStep3Ref.retryRegisterFormHighSettingmFunc(  
130 - editEchoData.value  
131 - );  
132 - proxy.$refs.DeviceProfileStep3Ref.retryRegisterFormCreateAlarmFunc(  
133 - editEchoData.value  
134 - );  
135 - break;  
136 - case 3:  
137 - proxy.$refs.DeviceProfileStep4Ref.resetFieldsFunc(editEchoData.value); 127 + proxy.$refs.DeviceProfileStep1Ref.editIconFunc(editEchoData.value.icon);
138 break; 128 break;
139 } 129 }
140 } 130 }
@@ -142,18 +132,132 @@ @@ -142,18 +132,132 @@
142 function handleStepPrev() { 132 function handleStepPrev() {
143 current.value--; 133 current.value--;
144 } 134 }
145 - function handleStepNext1(v) { 135 + function handleStepNext1(v, v1) {
  136 + console.log(v, v1);
146 current.value++; 137 current.value++;
147 getStepOneData.value = v; 138 getStepOneData.value = v;
  139 + getStepOneData.value.icon = v1;
  140 + console.log(getStepOneData.value);
  141 + if (unref(isUpdate)) {
  142 + proxy.$refs.DeviceProfileStep2Ref.resetFieldsFunc({
  143 + transportType: editEchoData.value.profileData.transportConfiguration.type,
  144 + });
  145 + } else {
  146 + // proxy.$refs.DeviceProfileStep2Ref.customResetAndFunc();
  147 + }
148 } 148 }
149 function handleStep2Next(v) { 149 function handleStep2Next(v) {
150 current.value++; 150 current.value++;
  151 +
151 getStepTwoData.value = v; 152 getStepTwoData.value = v;
152 - proxy.$refs.DeviceProfileStep3Ref.addAlarmRule(); 153 + if (unref(isUpdate)) {
  154 + proxy.$refs.DeviceProfileStep3Ref.retryRegisterFormFunc({
  155 + alarmType: editEchoData.value.profileData.alarms[0].alarmType,
  156 + });
  157 + proxy.$refs.DeviceProfileStep3Ref.retryRegisterFormHighSettingmFunc({
  158 + propagate: editEchoData.value.profileData.alarms[0].propagate,
  159 + propagateRelationTypes:
  160 + editEchoData.value.profileData?.alarms[0].propagateRelationTypes,
  161 + });
  162 + const getKey = Object.keys(editEchoData.value.profileData?.alarms[0].createRules);
  163 + proxy.$refs.DeviceProfileStep3Ref.retryRegisterFormCreateAlarmFunc({
  164 + default: getKey[0],
  165 + });
  166 + const findDay = [
  167 + { label: '等于', value: 'EQUAL' },
  168 + { label: '不等于', value: 'NOT_EQUAL' },
  169 + { label: '开始于', value: 'STARTS_WITH' },
  170 + { label: '结束于', value: 'ENDS_WITH' },
  171 + { label: '包含', value: 'CONTAINS' },
  172 + { label: '不包含', value: 'NOT_CONTAINS' },
  173 + { label: '等于', value: 'EQUAL' },
  174 + { label: '不等于', value: 'NOT_EQUAL' },
  175 + { label: '大于', value: 'GREATER' },
  176 + { label: '小于', value: 'LESS' },
  177 + { label: '大于或等于', value: 'GREATER_OR_EQUAL' },
  178 + { label: '小于或等于', value: 'LESS_OR_EQUAL' },
  179 + ];
  180 + const findRuleByValue = findDay.find((f) => {
  181 + if (
  182 + f.value ==
  183 + editEchoData.value.profileData?.alarms[0].createRules[getKey[0]].condition
  184 + .condition[0].predicate.operation
  185 + ) {
  186 + return f.label;
  187 + }
  188 + });
  189 + const findClearRuleByValue = findDay.find((f) => {
  190 + if (
  191 + f.value ==
  192 + editEchoData.value.profileData?.alarms[0].clearRule.condition.condition[0].predicate
  193 + .operation
  194 + ) {
  195 + return f.label;
  196 + }
  197 + });
  198 + proxy.$refs.DeviceProfileStep3Ref.retryRulesFormDataFunc(
  199 + `
  200 + 键名:${
  201 + editEchoData.value.profileData?.alarms[0].createRules[getKey[0]].condition
  202 + .condition[0].key.key
  203 + }...操作:${findRuleByValue?.label}...值:${
  204 + editEchoData.value.profileData?.alarms[0].createRules[getKey[0]].condition
  205 + .condition[0].predicate.value.defaultValue
  206 + }
  207 + `
  208 + );
  209 + proxy.$refs.DeviceProfileStep3Ref.retryEnableFormDataFunc(`始终启用`);
  210 + proxy.$refs.DeviceProfileStep3Ref.retryTemplateFormDataFunc(
  211 + `
  212 + 报警详细信息:${
  213 + editEchoData.value.profileData?.alarms[0].createRules[getKey[0]].alarmDetails
  214 + }
  215 + `
  216 + );
  217 + //清除报警
  218 + proxy.$refs.DeviceProfileStep3Ref.retryRulesClearFormDataFunc(
  219 + `
  220 + 键名:${editEchoData.value.profileData?.alarms[0].clearRule.condition.condition[0].key.key}...操作:${findClearRuleByValue?.label}...值:${editEchoData.value.profileData?.alarms[0].clearRule.condition.condition[0].predicate.value.defaultValue}
  221 + `
  222 + );
  223 + proxy.$refs.DeviceProfileStep3Ref.retryEnableClearFormDataFunc(`始终启用`);
  224 + proxy.$refs.DeviceProfileStep3Ref.retryTemplateClearFormDataFunc(
  225 + `
  226 + 报警详细信息:${editEchoData.value.profileData?.alarms[0].clearRule.alarmDetails}
  227 + `
  228 + );
  229 + } else {
  230 + proxy.$refs.DeviceProfileStep3Ref.resetRegisterFormFunc();
  231 + proxy.$refs.DeviceProfileStep3Ref.resetRegisterFormHighSettingmFunc();
  232 + proxy.$refs.DeviceProfileStep3Ref.resetRegisterFormCreateAlarmFunc();
  233 + proxy.$refs.DeviceProfileStep3Ref.resetRulesFormDataFunc();
  234 + proxy.$refs.DeviceProfileStep3Ref.resetEnableFormDataFunc();
  235 + proxy.$refs.DeviceProfileStep3Ref.resetTemplateFormDataFunc();
  236 + proxy.$refs.DeviceProfileStep3Ref.resetRulesClearFormDataFunc();
  237 + proxy.$refs.DeviceProfileStep3Ref.resetEnableClearFormDataFunc();
  238 + proxy.$refs.DeviceProfileStep3Ref.resetTemplateClearFormDataFunc();
  239 + }
153 } 240 }
154 function handleStep3Next(v) { 241 function handleStep3Next(v) {
155 current.value++; 242 current.value++;
156 getStepThreeData.value = v; 243 getStepThreeData.value = v;
  244 + try {
  245 + if (unref(isUpdate)) {
  246 + setTimeout(() => {
  247 + proxy.$refs.DeviceProfileStep4Ref.resetFieldsFunc({
  248 + alarmContactId: editEchoData.value.alarmProfile.alarmContactId,
  249 + messageMode: editEchoData.value.alarmProfile.messageMode,
  250 + });
  251 + }, 1000);
  252 + }
  253 + // if (!unref(isUpdate)) {
  254 + // setTimeout(() => {
  255 + // proxy.$refs.DeviceProfileStep4Ref.customResetAndFunc();
  256 + // }, 1000);
  257 + // }
  258 + } catch (e) {
  259 + return e;
  260 + }
157 } 261 }
158 function handleRedo() { 262 function handleRedo() {
159 current.value = 0; 263 current.value = 0;
@@ -197,6 +301,7 @@ @@ -197,6 +301,7 @@
197 return; 301 return;
198 }; 302 };
199 return { 303 return {
  304 + handleChange,
200 DeviceProfileStep2Ref, 305 DeviceProfileStep2Ref,
201 DeviceProfileStep3Ref, 306 DeviceProfileStep3Ref,
202 DeviceProfileStep4Ref, 307 DeviceProfileStep4Ref,
@@ -2,8 +2,9 @@ import { BasicColumn } from '/@/components/Table'; @@ -2,8 +2,9 @@ import { BasicColumn } from '/@/components/Table';
2 import { FormSchema } from '/@/components/Table'; 2 import { FormSchema } from '/@/components/Table';
3 import { findDictItemByCode } from '/@/api/system/dict'; 3 import { findDictItemByCode } from '/@/api/system/dict';
4 import { MessageEnum } from '/@/enums/messageEnum'; 4 import { MessageEnum } from '/@/enums/messageEnum';
5 -import { getOrganizationList } from '/@/api/system/system';  
6 -import { copyTransFun } from '/@/utils/fnUtils'; 5 +// import { getOrganizationList } from '/@/api/system/system';
  6 +// import { copyTransFun } from '/@/utils/fnUtils';
  7 +import { numberRule } from '/@/utils/rules';
7 8
8 export const columns: BasicColumn[] = [ 9 export const columns: BasicColumn[] = [
9 { 10 {
@@ -30,23 +31,27 @@ export const columns: BasicColumn[] = [ @@ -30,23 +31,27 @@ export const columns: BasicColumn[] = [
30 31
31 export const searchFormSchema: FormSchema[] = [ 32 export const searchFormSchema: FormSchema[] = [
32 { 33 {
33 - field: 'organizationId',  
34 - label: '请选择组织',  
35 - component: 'ApiTreeSelect',  
36 - colProps: { span: 6 },  
37 - componentProps: {  
38 - api: async () => {  
39 - const data = await getOrganizationList();  
40 - copyTransFun(data as any as any[]);  
41 - return data;  
42 - },  
43 - },  
44 - },  
45 - {  
46 field: 'name', 34 field: 'name',
47 label: '配置名称', 35 label: '配置名称',
48 component: 'Input', 36 component: 'Input',
49 colProps: { span: 8 }, 37 colProps: { span: 8 },
  38 + componentProps: {
  39 + maxLength: 255,
  40 + placeholder: '请输入配置名称',
  41 + },
  42 + dynamicRules: () => {
  43 + return [
  44 + {
  45 + required: false,
  46 + validator: (_, value) => {
  47 + if (String(value).length > 255) {
  48 + return Promise.reject('字数不超过255个字');
  49 + }
  50 + return Promise.resolve();
  51 + },
  52 + },
  53 + ];
  54 + },
50 }, 55 },
51 ]; 56 ];
52 57
@@ -63,6 +68,10 @@ export const formSchema: FormSchema[] = [ @@ -63,6 +68,10 @@ export const formSchema: FormSchema[] = [
63 label: '配置名称', 68 label: '配置名称',
64 required: true, 69 required: true,
65 component: 'Input', 70 component: 'Input',
  71 + componentProps: {
  72 + maxLength: 255,
  73 + placeholder: '请输入配置名称',
  74 + },
66 }, 75 },
67 { 76 {
68 field: 'messageType', 77 field: 'messageType',
@@ -98,6 +107,11 @@ export const formSchema: FormSchema[] = [ @@ -98,6 +107,11 @@ export const formSchema: FormSchema[] = [
98 label: 'accessKeyId', 107 label: 'accessKeyId',
99 required: true, 108 required: true,
100 component: 'Input', 109 component: 'Input',
  110 + componentProps: {
  111 + maxLength: 36,
  112 + placeholder: '请输入accessKeyId',
  113 + },
  114 +
101 ifShow: ({ values }) => isMessage(Reflect.get(values, 'messageType')), 115 ifShow: ({ values }) => isMessage(Reflect.get(values, 'messageType')),
102 }, 116 },
103 { 117 {
@@ -105,6 +119,11 @@ export const formSchema: FormSchema[] = [ @@ -105,6 +119,11 @@ export const formSchema: FormSchema[] = [
105 label: 'accessKeySecret', 119 label: 'accessKeySecret',
106 required: true, 120 required: true,
107 component: 'Input', 121 component: 'Input',
  122 + componentProps: {
  123 + maxLength: 36,
  124 + placeholder: '请输入accessKeySecret',
  125 + },
  126 +
108 ifShow: ({ values }) => isMessage(Reflect.get(values, 'messageType')), 127 ifShow: ({ values }) => isMessage(Reflect.get(values, 'messageType')),
109 }, 128 },
110 { 129 {
@@ -113,6 +132,11 @@ export const formSchema: FormSchema[] = [ @@ -113,6 +132,11 @@ export const formSchema: FormSchema[] = [
113 defaultValue: 'smtp.163.com', 132 defaultValue: 'smtp.163.com',
114 required: true, 133 required: true,
115 component: 'Input', 134 component: 'Input',
  135 + componentProps: {
  136 + maxLength: 36,
  137 + placeholder: '请输入accessKeySecret',
  138 + },
  139 +
116 ifShow: ({ values }) => isEmail(Reflect.get(values, 'messageType')), 140 ifShow: ({ values }) => isEmail(Reflect.get(values, 'messageType')),
117 }, 141 },
118 { 142 {
@@ -121,6 +145,12 @@ export const formSchema: FormSchema[] = [ @@ -121,6 +145,12 @@ export const formSchema: FormSchema[] = [
121 defaultValue: 25, 145 defaultValue: 25,
122 required: true, 146 required: true,
123 component: 'InputNumber', 147 component: 'InputNumber',
  148 + rules: numberRule,
  149 + componentProps: {
  150 + maxLength: 36,
  151 + placeholder: '请输入端口',
  152 + },
  153 +
124 ifShow: ({ values }) => isEmail(Reflect.get(values, 'messageType')), 154 ifShow: ({ values }) => isEmail(Reflect.get(values, 'messageType')),
125 }, 155 },
126 { 156 {
@@ -128,6 +158,11 @@ export const formSchema: FormSchema[] = [ @@ -128,6 +158,11 @@ export const formSchema: FormSchema[] = [
128 label: '用户名', 158 label: '用户名',
129 required: true, 159 required: true,
130 component: 'Input', 160 component: 'Input',
  161 + componentProps: {
  162 + maxLength: 255,
  163 + placeholder: '请输入用户名',
  164 + },
  165 +
131 ifShow: ({ values }) => isEmail(Reflect.get(values, 'messageType')), 166 ifShow: ({ values }) => isEmail(Reflect.get(values, 'messageType')),
132 }, 167 },
133 { 168 {
@@ -142,12 +177,46 @@ export const formSchema: FormSchema[] = [ @@ -142,12 +177,46 @@ export const formSchema: FormSchema[] = [
142 label: '消息配置', 177 label: '消息配置',
143 component: 'Input', 178 component: 'Input',
144 show: false, 179 show: false,
  180 + componentProps: {
  181 + maxLength: 255,
  182 + placeholder: '请输入消息配置',
  183 + },
  184 + dynamicRules: () => {
  185 + return [
  186 + {
  187 + required: false,
  188 + validator: (_, value) => {
  189 + if (String(value).length > 255) {
  190 + return Promise.reject('字数不超过255个字');
  191 + }
  192 + return Promise.resolve();
  193 + },
  194 + },
  195 + ];
  196 + },
145 }, 197 },
146 { 198 {
147 field: 'id', 199 field: 'id',
148 label: '主键', 200 label: '主键',
149 component: 'Input', 201 component: 'Input',
150 show: false, 202 show: false,
  203 + componentProps: {
  204 + maxLength: 36,
  205 + placeholder: '请输入主键',
  206 + },
  207 + dynamicRules: () => {
  208 + return [
  209 + {
  210 + required: false,
  211 + validator: (_, value) => {
  212 + if (String(value).length > 36) {
  213 + return Promise.reject('字数不超过36个字');
  214 + }
  215 + return Promise.resolve();
  216 + },
  217 + },
  218 + ];
  219 + },
151 }, 220 },
152 { 221 {
153 field: 'status', 222 field: 'status',
@@ -165,5 +234,22 @@ export const formSchema: FormSchema[] = [ @@ -165,5 +234,22 @@ export const formSchema: FormSchema[] = [
165 label: '备注', 234 label: '备注',
166 field: 'remark', 235 field: 'remark',
167 component: 'InputTextArea', 236 component: 'InputTextArea',
  237 + componentProps: {
  238 + maxLength: 255,
  239 + placeholder: '请输入备注',
  240 + },
  241 + dynamicRules: () => {
  242 + return [
  243 + {
  244 + required: false,
  245 + validator: (_, value) => {
  246 + if (String(value).length > 255) {
  247 + return Promise.reject('字数不超过255个字');
  248 + }
  249 + return Promise.resolve();
  250 + },
  251 + },
  252 + ];
  253 + },
168 }, 254 },
169 ]; 255 ];
@@ -21,65 +21,69 @@ @@ -21,65 +21,69 @@
21 /></TabPane> 21 /></TabPane>
22 <TabPane key="3" tab="报警规则"> 22 <TabPane key="3" tab="报警规则">
23 <div style="padding-top: 10px"> 23 <div style="padding-top: 10px">
24 - <div style="border-radius: 10px; border: 1px solid grey">  
25 - <BasicForm  
26 - :showSubmitButton="false"  
27 - :showResetButton="false"  
28 - @register="registerStep3Schemas"  
29 - />  
30 - <BasicForm  
31 - :showSubmitButton="false"  
32 - :showResetButton="false"  
33 - @register="registerStep3HighSetting"  
34 - />  
35 - <BasicForm  
36 - :showSubmitButton="false"  
37 - :showResetButton="false"  
38 - @register="registerStep3CreateAlarm"  
39 - />  
40 - <BasicForm  
41 - :showSubmitButton="false"  
42 - :showResetButton="false"  
43 - @register="registerStep3RuleAlarm"  
44 - />  
45 - <BasicForm  
46 - :showSubmitButton="false"  
47 - :showResetButton="false"  
48 - @register="registerStep3Condition"  
49 - />  
50 - <BasicForm  
51 - :showSubmitButton="false"  
52 - :showResetButton="false"  
53 - @register="registerStep3Enable"  
54 - />  
55 - <BasicForm  
56 - :showSubmitButton="false"  
57 - :showResetButton="false"  
58 - @register="registerStep3TemplateDetail"  
59 - /> 24 + <div style="border-radius: 10px; border: 1px solid #f0f0f0">
  25 + <div style="margin-left: 15px">
  26 + <BasicForm
  27 + :showSubmitButton="false"
  28 + :showResetButton="false"
  29 + @register="registerStep3Schemas"
  30 + />
  31 + <BasicForm
  32 + :showSubmitButton="false"
  33 + :showResetButton="false"
  34 + @register="registerStep3HighSetting"
  35 + />
  36 + <BasicForm
  37 + :showSubmitButton="false"
  38 + :showResetButton="false"
  39 + @register="registerStep3CreateAlarm"
  40 + />
  41 + <BasicForm
  42 + :showSubmitButton="false"
  43 + :showResetButton="false"
  44 + @register="registerStep3RuleAlarm"
  45 + />
  46 + <BasicForm
  47 + :showSubmitButton="false"
  48 + :showResetButton="false"
  49 + @register="registerStep3Condition"
  50 + />
  51 + <BasicForm
  52 + :showSubmitButton="false"
  53 + :showResetButton="false"
  54 + @register="registerStep3Enable"
  55 + />
  56 + <BasicForm
  57 + :showSubmitButton="false"
  58 + :showResetButton="false"
  59 + @register="registerStep3TemplateDetail"
  60 + />
  61 + </div>
60 </div> 62 </div>
61 - <div style="border-radius: 10px; border: 1px solid grey; margin-top: 15px"> 63 + <div style="border-radius: 10px; border: 1px solid #f0f0f0; margin-top: 15px">
62 <p>清除报警规则</p> 64 <p>清除报警规则</p>
63 - <BasicForm  
64 - :showSubmitButton="false"  
65 - :showResetButton="false"  
66 - @register="registerStep3ClearRuleAlarm"  
67 - />  
68 - <BasicForm  
69 - :showSubmitButton="false"  
70 - :showResetButton="false"  
71 - @register="registerStep3ClearCondition"  
72 - />  
73 - <BasicForm  
74 - :showSubmitButton="false"  
75 - :showResetButton="false"  
76 - @register="registerStep3ClearEnable"  
77 - />  
78 - <BasicForm  
79 - :showSubmitButton="false"  
80 - :showResetButton="false"  
81 - @register="registerStep3ClearTemplateDetail"  
82 - /> 65 + <div style="margin-left: 15px">
  66 + <BasicForm
  67 + :showSubmitButton="false"
  68 + :showResetButton="false"
  69 + @register="registerStep3ClearRuleAlarm"
  70 + />
  71 + <BasicForm
  72 + :showSubmitButton="false"
  73 + :showResetButton="false"
  74 + @register="registerStep3ClearCondition"
  75 + />
  76 + <BasicForm
  77 + :showSubmitButton="false"
  78 + :showResetButton="false"
  79 + @register="registerStep3ClearEnable"
  80 + />
  81 + <BasicForm
  82 + :showSubmitButton="false"
  83 + :showResetButton="false"
  84 + @register="registerStep3ClearTemplateDetail"
  85 + />
  86 + </div>
83 </div> 87 </div>
84 </div> 88 </div>
85 </TabPane> 89 </TabPane>
@@ -93,7 +97,7 @@ @@ -93,7 +97,7 @@
93 <script lang="ts"> 97 <script lang="ts">
94 import { defineComponent, ref, computed, watch } from 'vue'; 98 import { defineComponent, ref, computed, watch } from 'vue';
95 import { BasicModal, useModalInner } from '/@/components/Modal'; 99 import { BasicModal, useModalInner } from '/@/components/Modal';
96 - import { Tabs, TabPane } from 'ant-design-vue'; 100 + import { Tabs } from 'ant-design-vue';
97 import { deviceConfigGetDetail } from '/@/api/device/deviceConfigApi'; 101 import { deviceConfigGetDetail } from '/@/api/device/deviceConfigApi';
98 import { BasicForm, useForm } from '/@/components/Form/index'; 102 import { BasicForm, useForm } from '/@/components/Form/index';
99 import { 103 import {
@@ -116,14 +120,14 @@ @@ -116,14 +120,14 @@
116 120
117 export default defineComponent({ 121 export default defineComponent({
118 name: 'ConfigDrawer', 122 name: 'ConfigDrawer',
119 - components: { Tabs, TabPane, BasicModal, BasicForm }, 123 + components: { Tabs, TabPane: Tabs.TabPane, BasicModal, BasicForm },
120 emits: ['success', 'register'], 124 emits: ['success', 'register'],
121 setup() { 125 setup() {
122 const activeKey = ref('1'); 126 const activeKey = ref('1');
123 const isUpdate = ref(true); 127 const isUpdate = ref(true);
124 const descInfo: any = ref(null); 128 const descInfo: any = ref(null);
125 const dataInfo: any = ref(''); 129 const dataInfo: any = ref('');
126 - const [registerDetail, { setFieldsValue: setRegisterDetail }] = useForm({ 130 + const [registerDetail, { resetFields, setFieldsValue: setRegisterDetail }] = useForm({
127 schemas: step1Schemas, 131 schemas: step1Schemas,
128 actionColOptions: { 132 actionColOptions: {
129 span: 24, 133 span: 24,
@@ -219,8 +223,10 @@ @@ -219,8 +223,10 @@
219 const [register] = useModalInner(async (data) => { 223 const [register] = useModalInner(async (data) => {
220 activeKey.value = '1'; 224 activeKey.value = '1';
221 isUpdate.value = !!data?.isUpdate; 225 isUpdate.value = !!data?.isUpdate;
222 - descInfo.value = await deviceConfigGetDetail(data.record.id); 226 + const getV = await deviceConfigGetDetail(data.record.id);
  227 + descInfo.value = getV;
223 try { 228 try {
  229 + resetFields();
224 await setRegisterDetail({ ...descInfo.value }); 230 await setRegisterDetail({ ...descInfo.value });
225 } catch (e) { 231 } catch (e) {
226 return e; 232 return e;
@@ -229,84 +235,90 @@ @@ -229,84 +235,90 @@
229 const handleChange = (v) => { 235 const handleChange = (v) => {
230 try { 236 try {
231 switch (v) { 237 switch (v) {
232 - case '1':  
233 - setRegisterDetail({ ...descInfo.value });  
234 - break; 238 + // case '1':
  239 + // setRegisterDetail({ ...descInfo.value });
  240 + // break;
235 case '2': 241 case '2':
236 setRegisterTrans({ 242 setRegisterTrans({
237 transportType: descInfo.value.profileData?.transportConfiguration.type, 243 transportType: descInfo.value.profileData?.transportConfiguration.type,
238 }); 244 });
239 break; 245 break;
240 case '3': 246 case '3':
241 - setRegisterStep3Schemas({  
242 - alarmType: descInfo.value.profileData?.alarms[0].alarmType,  
243 - });  
244 - setRegisterStep3HighSetting({  
245 - propagate: descInfo.value.profileData?.alarms[0].propagate,  
246 - propagateRelationTypes:  
247 - descInfo.value.profileData?.alarms[0].propagateRelationTypes,  
248 - });  
249 - const getKey = Object.keys(descInfo.value.profileData?.alarms[0].createRules);  
250 - setRegisterStep3CreateAlarm({  
251 - default: getKey[0],  
252 - });  
253 - setRegisterStep3RuleAlarm({  
254 - type: descInfo.value.profileData?.alarms[0].createRules[getKey[0]].condition  
255 - .condition[0].key.type,  
256 - key1: descInfo.value.profileData?.alarms[0].createRules[getKey[0]].condition  
257 - .condition[0].key.key,  
258 - type1:  
259 - descInfo.value.profileData?.alarms[0].createRules[getKey[0]].condition  
260 - .condition[0].valueType,  
261 - value1:  
262 - descInfo.value.profileData?.alarms[0].createRules[getKey[0]].condition  
263 - .condition[0].predicate.value.defaultValue,  
264 - operation:  
265 - descInfo.value.profileData?.alarms[0].createRules[getKey[0]].condition  
266 - .condition[0].predicate.operation,  
267 - });  
268 - setRegisterStep3Condition({  
269 - conditionType:  
270 - descInfo.value.profileData?.alarms[0].createRules[getKey[0]].condition.spec.type,  
271 - });  
272 - setRegisterStep3Enable({  
273 - schedule:  
274 - descInfo.value.profileData?.alarms[0].createRules[getKey[0]].schedule.type,  
275 - });  
276 - setRegisterStep3TemplateDetail({  
277 - alarmDetails:  
278 - descInfo.value.profileData?.alarms[0].createRules[getKey[0]].alarmDetails,  
279 - });  
280 - //清楚报警  
281 - setRegisterStep3ClearRuleAlarm({  
282 - type: descInfo.value.profileData?.alarms[0].clearRule.condition.condition[0].key  
283 - .type,  
284 - key1: descInfo.value.profileData?.alarms[0].clearRule.condition.condition[0].key  
285 - .key,  
286 - type1:  
287 - descInfo.value.profileData?.alarms[0].clearRule.condition.condition[0].valueType,  
288 - value1:  
289 - descInfo.value.profileData?.alarms[0].clearRule.condition.condition[0].predicate  
290 - .value.defaultValue,  
291 - operation:  
292 - descInfo.value.profileData?.alarms[0].clearRule.condition.condition[0].predicate  
293 - .operation,  
294 - });  
295 - setRegisterStep3ClearCondition({  
296 - conditionType: descInfo.value.profileData?.alarms[0].clearRule.condition.spec.type,  
297 - });  
298 - setRegisterStep3ClearEnable({  
299 - schedule: descInfo.value.profileData?.alarms[0].clearRule.schedule.type,  
300 - });  
301 - setRegisterStep3ClearTemplateDetail({  
302 - alarmDetails: descInfo.value.profileData?.alarms[0].clearRule.alarmDetails,  
303 - });  
304 - break; 247 + setTimeout(() => {
  248 + setRegisterStep3Schemas({
  249 + alarmType: descInfo.value.profileData?.alarms[0]?.alarmType,
  250 + });
  251 + setRegisterStep3HighSetting({
  252 + propagate: descInfo.value.profileData?.alarms[0]?.propagate,
  253 + propagateRelationTypes:
  254 + descInfo.value.profileData?.alarms[0]?.propagateRelationTypes,
  255 + });
  256 + const getKey = Object.keys(descInfo.value.profileData?.alarms[0]?.createRules);
  257 + setRegisterStep3CreateAlarm({
  258 + default: getKey[0],
  259 + });
  260 + setRegisterStep3RuleAlarm({
  261 + type: descInfo.value.profileData?.alarms[0].createRules[getKey[0]].condition
  262 + .condition[0].key.type,
  263 + key1: descInfo.value.profileData?.alarms[0].createRules[getKey[0]].condition
  264 + .condition[0].key.key,
  265 + type1:
  266 + descInfo.value.profileData?.alarms[0].createRules[getKey[0]].condition
  267 + .condition[0].valueType,
  268 + value1:
  269 + descInfo.value.profileData?.alarms[0].createRules[getKey[0]].condition
  270 + .condition[0].predicate.value.defaultValue,
  271 + operation:
  272 + descInfo.value.profileData?.alarms[0].createRules[getKey[0]].condition
  273 + .condition[0].predicate.operation,
  274 + });
  275 + setRegisterStep3Condition({
  276 + conditionType:
  277 + descInfo.value.profileData?.alarms[0].createRules[getKey[0]].condition.spec
  278 + .type,
  279 + });
  280 + setRegisterStep3Enable({
  281 + schedule:
  282 + descInfo.value.profileData?.alarms[0].createRules[getKey[0]].schedule.type,
  283 + });
  284 + setRegisterStep3TemplateDetail({
  285 + alarmDetails:
  286 + descInfo.value.profileData?.alarms[0].createRules[getKey[0]].alarmDetails,
  287 + });
  288 + //清除报警
  289 + setRegisterStep3ClearRuleAlarm({
  290 + type: descInfo.value.profileData?.alarms[0].clearRule.condition.condition[0].key
  291 + .type,
  292 + key1: descInfo.value.profileData?.alarms[0].clearRule.condition.condition[0].key
  293 + .key,
  294 + type1:
  295 + descInfo.value.profileData?.alarms[0].clearRule.condition.condition[0]
  296 + .valueType,
  297 + value1:
  298 + descInfo.value.profileData?.alarms[0].clearRule.condition.condition[0].predicate
  299 + .value.defaultValue,
  300 + operation:
  301 + descInfo.value.profileData?.alarms[0].clearRule.condition.condition[0].predicate
  302 + .operation,
  303 + });
  304 + setRegisterStep3ClearCondition({
  305 + conditionType:
  306 + descInfo.value.profileData?.alarms[0].clearRule.condition.spec.type,
  307 + });
  308 + setRegisterStep3ClearEnable({
  309 + schedule: descInfo.value.profileData?.alarms[0].clearRule.schedule.type,
  310 + });
  311 + setRegisterStep3ClearTemplateDetail({
  312 + alarmDetails: descInfo.value.profileData?.alarms[0].clearRule.alarmDetails,
  313 + });
  314 + }, 1000);
305 case '4': 315 case '4':
306 - setRegisterContact({  
307 - alarmContactId: descInfo.value.alarmProfile.alarmContactId,  
308 - messageMode: descInfo.value.alarmProfile.messageMode,  
309 - }); 316 + setTimeout(() => {
  317 + setRegisterContact({
  318 + alarmContactId: descInfo.value?.alarmProfile?.alarmContactId,
  319 + messageMode: descInfo.value?.alarmProfile?.messageMode,
  320 + });
  321 + }, 1000);
310 break; 322 break;
311 } 323 }
312 } catch (e) { 324 } catch (e) {
@@ -45,12 +45,12 @@ @@ -45,12 +45,12 @@
45 </BasicTable> 45 </BasicTable>
46 <DeviceProfileModal v-if="isJudgeStatus" @register="registerModal" @success="handleSuccess" /> 46 <DeviceProfileModal v-if="isJudgeStatus" @register="registerModal" @success="handleSuccess" />
47 <DeviceConfigDetail @register="registerModalDetail" @success="handleSuccess" /> 47 <DeviceConfigDetail @register="registerModalDetail" @success="handleSuccess" />
48 - <ExpExcelModal @register="register1" @success="defaultHeader" /> 48 + <!-- <ExpExcelModal @register="register1" @success="defaultHeader" /> -->
49 </div> 49 </div>
50 </template> 50 </template>
51 <script lang="ts"> 51 <script lang="ts">
52 import { defineComponent, ref, reactive } from 'vue'; 52 import { defineComponent, ref, reactive } from 'vue';
53 - import { BasicTable, useTable, TableAction } from '/@/components/Table'; 53 + import { BasicTable, useTable, TableAction, BasicColumn } from '/@/components/Table';
54 import { columns, searchFormSchema } from './device.profile.data'; 54 import { columns, searchFormSchema } from './device.profile.data';
55 import { useMessage } from '/@/hooks/web/useMessage'; 55 import { useMessage } from '/@/hooks/web/useMessage';
56 import { deviceConfigGetQuery, deviceConfigDelete } from '/@/api/device/deviceConfigApi'; 56 import { deviceConfigGetQuery, deviceConfigDelete } from '/@/api/device/deviceConfigApi';
@@ -58,7 +58,7 @@ @@ -58,7 +58,7 @@
58 import DeviceProfileModal from '/@/views/device/profile/DeviceProfileModal.vue'; 58 import DeviceProfileModal from '/@/views/device/profile/DeviceProfileModal.vue';
59 import DeviceConfigDetail from '/@/views/device/profile/deviceConfigDetail.vue'; 59 import DeviceConfigDetail from '/@/views/device/profile/deviceConfigDetail.vue';
60 import { ImpExcel, ExcelData } from '/@/components/Excel'; 60 import { ImpExcel, ExcelData } from '/@/components/Excel';
61 - import { jsonToSheetXlsx, ExportModalResult } from '/@/components/Excel'; 61 + // import { jsonToSheetXlsx, ExportModalResult } from '/@/components/Excel';
62 62
63 export default defineComponent({ 63 export default defineComponent({
64 name: 'DeviceProfileManagement', 64 name: 'DeviceProfileManagement',
@@ -156,23 +156,23 @@ @@ -156,23 +156,23 @@
156 isJudgeStatus.value = false; 156 isJudgeStatus.value = false;
157 } 157 }
158 158
159 - function defaultHeader({ filename, bookType }: ExportModalResult) {  
160 - // 默认Object.keys(data[0])作为header  
161 - jsonToSheetXlsx({  
162 - data,  
163 - filename,  
164 - write2excelOpts: {  
165 - bookType,  
166 - },  
167 - });  
168 - } 159 + // function defaultHeader({ filename, bookType }: ExportModalResult) {
  160 + // // 默认Object.keys(data[0])作为header
  161 + // jsonToSheetXlsx({
  162 + // data,
  163 + // filename,
  164 + // write2excelOpts: {
  165 + // bookType,
  166 + // },
  167 + // });
  168 + // }
169 169
170 - const [register1, { openModal: openModalExcel }] = useModal(); 170 + // const [register1, { openModal: openModalExcel }] = useModal();
171 const handleExport = (record: Recordable) => { 171 const handleExport = (record: Recordable) => {
172 console.log(record); 172 console.log(record);
173 - setTimeout(() => {  
174 - openModalExcel();  
175 - }, 50); 173 + // setTimeout(() => {
  174 + // openModalExcel();
  175 + // }, 50);
176 }; 176 };
177 function handleImport() { 177 function handleImport() {
178 console.log('record'); 178 console.log('record');
@@ -182,8 +182,8 @@ @@ -182,8 +182,8 @@
182 } 182 }
183 return { 183 return {
184 registerModalDetail, 184 registerModalDetail,
185 - register1,  
186 - defaultHeader, 185 + // register1,
  186 + // defaultHeader,
187 useSelectionChange, 187 useSelectionChange,
188 handleTableDel, 188 handleTableDel,
189 isJudgeStatus, 189 isJudgeStatus,
1 <template> 1 <template>
2 <div class="step1"> 2 <div class="step1">
3 <div class="step1-form"> 3 <div class="step1-form">
  4 + <div
  5 + style="
  6 + width: 12vw;
  7 + height: 24vh;
  8 + margin-left: 25px;
  9 + display: flex;
  10 + justify-content: space-between;
  11 + align-items: center;
  12 + "
  13 + >
  14 + <div style="width: 4vw; height: 24vh">请上传图片</div>
  15 + <div style="width: 8vw; height: 24vh">
  16 + <Upload
  17 + style="width: 20vw"
  18 + name="avatar"
  19 + list-type="picture-card"
  20 + class="avatar-uploader"
  21 + :show-upload-list="false"
  22 + :customRequest="customUploadqrcodePic"
  23 + :before-upload="beforeUploadqrcodePic"
  24 + >
  25 + <img
  26 + style="text-align: center; border-radius: 50%; width: 10vw; height: 15vh"
  27 + v-if="peresonalPic"
  28 + :src="peresonalPic"
  29 + alt="avatar"
  30 + />
  31 + <div v-else>
  32 + <div style="margin-top: 30px">
  33 + <PlusOutlined style="font-size: 30px" />
  34 + </div>
  35 + <div
  36 + class="ant-upload-text flex"
  37 + style="width: 280px; height: 130px; align-items: center"
  38 + >
  39 + 支持.PNG、.JPG、.JPEG格式,建议大小不超过2M。</div
  40 + >
  41 + </div>
  42 + </Upload>
  43 + </div>
  44 + </div>
4 <BasicForm @register="register" /> 45 <BasicForm @register="register" />
5 </div> 46 </div>
6 </div> 47 </div>
7 </template> 48 </template>
8 <script lang="ts"> 49 <script lang="ts">
9 - import { defineComponent } from 'vue'; 50 + import { defineComponent, ref } from 'vue';
10 import { BasicForm, useForm } from '/@/components/Form'; 51 import { BasicForm, useForm } from '/@/components/Form';
11 import { step1Schemas } from './data'; 52 import { step1Schemas } from './data';
12 import { Select, Input, Divider } from 'ant-design-vue'; 53 import { Select, Input, Divider } from 'ant-design-vue';
  54 + import { uploadApi } from '/@/api/personal/index';
  55 + import { Upload } from 'ant-design-vue';
  56 + import { PlusOutlined } from '@ant-design/icons-vue';
  57 + import { useMessage } from '/@/hooks/web/useMessage';
  58 + import type { FileItem } from '/@/components/Upload/src/typing';
13 59
14 export default defineComponent({ 60 export default defineComponent({
15 components: { 61 components: {
@@ -18,9 +64,13 @@ @@ -18,9 +64,13 @@
18 [Input.name]: Input, 64 [Input.name]: Input,
19 [Input.Group.name]: Input.Group, 65 [Input.Group.name]: Input.Group,
20 [Divider.name]: Divider, 66 [Divider.name]: Divider,
  67 + Upload,
  68 + PlusOutlined,
21 }, 69 },
22 emits: ['next', 'resetFunc'], 70 emits: ['next', 'resetFunc'],
23 setup(_, { emit }) { 71 setup(_, { emit }) {
  72 + const { createMessage } = useMessage();
  73 +
24 const [register, { validate, setFieldsValue, resetFields }] = useForm({ 74 const [register, { validate, setFieldsValue, resetFields }] = useForm({
25 labelWidth: 100, 75 labelWidth: 100,
26 schemas: step1Schemas, 76 schemas: step1Schemas,
@@ -36,16 +86,59 @@ @@ -36,16 +86,59 @@
36 const resetFieldsFunc = (v) => { 86 const resetFieldsFunc = (v) => {
37 setFieldsValue(v); 87 setFieldsValue(v);
38 }; 88 };
  89 + const peresonalPic = ref();
  90 +
  91 + const resetIconFunc = () => {
  92 + peresonalPic.value = '';
  93 + };
  94 +
  95 + const editIconFunc = (v) => {
  96 + peresonalPic.value = v;
  97 + };
  98 +
  99 + const customUploadqrcodePic = async ({ file }) => {
  100 + if (beforeUploadqrcodePic(file)) {
  101 + const formData = new FormData();
  102 + formData.append('file', file);
  103 + const response = await uploadApi(formData);
  104 + if (response.fileStaticUri) {
  105 + peresonalPic.value = response.fileStaticUri;
  106 + }
  107 + }
  108 + };
  109 +
  110 + const beforeUploadqrcodePic = (file: FileItem) => {
  111 + const isJpgOrPng =
  112 + file.type === 'image/jpeg' || file.type === 'image/png' || file.type === 'image/jpg';
  113 + if (!isJpgOrPng) {
  114 + createMessage.error('只能上传图片文件!');
  115 + }
  116 + const isLt2M = (file.size as number) / 1024 / 1024 < 2;
  117 + if (!isLt2M) {
  118 + createMessage.error('图片大小不能超过5MB!');
  119 + }
  120 + return isJpgOrPng && isLt2M;
  121 + };
39 async function customSubmitFunc() { 122 async function customSubmitFunc() {
40 try { 123 try {
41 const values = await validate(); 124 const values = await validate();
42 - emit('next', values); 125 + emit('next', values, peresonalPic.value);
43 } catch (error) {} 126 } catch (error) {}
44 } 127 }
45 const customResetFunc = async () => { 128 const customResetFunc = async () => {
46 await resetFields(); 129 await resetFields();
47 }; 130 };
48 - return { register, resetFieldsFunc, customResetFunc }; 131 + return {
  132 + editIconFunc,
  133 + resetIconFunc,
  134 + register,
  135 + resetFieldsFunc,
  136 + customResetFunc,
  137 + uploadApi,
  138 + peresonalPic,
  139 + beforeUploadqrcodePic,
  140 + customUploadqrcodePic,
  141 + };
49 }, 142 },
50 }); 143 });
51 </script> 144 </script>
@@ -31,7 +31,7 @@ @@ -31,7 +31,7 @@
31 <template v-for="(childItem, createIndex) in item.alarms" :key="childItem.id"> 31 <template v-for="(childItem, createIndex) in item.alarms" :key="childItem.id">
32 <div class="aic" style="border: 1px solid #bfbfbf"> 32 <div class="aic" style="border: 1px solid #bfbfbf">
33 <div class="w-3/4"> 33 <div class="w-3/4">
34 - <div style="margin-left: -30px; margin-top: 20px" 34 + <div style="margin-left: -33px; margin-top: 20px"
35 ><BasicForm @register="registerFormCreateAlarm" /> 35 ><BasicForm @register="registerFormCreateAlarm" />
36 </div> 36 </div>
37 <div style="margin-left: 5px; margin-top: -50px"> 37 <div style="margin-left: 5px; margin-top: -50px">
@@ -78,7 +78,7 @@ @@ -78,7 +78,7 @@
78 <div style="height: 20px"></div> 78 <div style="height: 20px"></div>
79 <p>清除报警规则</p> 79 <p>清除报警规则</p>
80 <template 80 <template
81 - v-for="(childClearItem, clearIndexItem) in item.alarms[clearIndex].clearRule" 81 + v-for="(childClearItem, clearIndexItem) in item.clearRule"
82 :key="childClearItem.id" 82 :key="childClearItem.id"
83 > 83 >
84 <div class="aic mb-1" style="border: 1px solid #bfbfbf"> 84 <div class="aic mb-1" style="border: 1px solid #bfbfbf">
@@ -222,12 +222,20 @@ @@ -222,12 +222,20 @@
222 const ruleClearTemplateData: any = ref(null); 222 const ruleClearTemplateData: any = ref(null);
223 const enableClearTemplateData: any = ref(null); 223 const enableClearTemplateData: any = ref(null);
224 const detailClearTemplateData: any = ref(null); 224 const detailClearTemplateData: any = ref(null);
  225 + const scheduleCustomValue: any = ref({});
  226 + const scheduleCustomClearValue: any = ref({});
225 const clearIndex = ref(-1); 227 const clearIndex = ref(-1);
  228 + const getSchduleCustomValue: any = ref([]);
  229 + const getSchduleClearCustomValue: any = ref([]);
226 //告警列表 230 //告警列表
227 let profileData = ref<IProfileData[]>([]); 231 let profileData = ref<IProfileData[]>([]);
228 const log = (e) => { 232 const log = (e) => {
229 console.log(e); 233 console.log(e);
230 }; 234 };
  235 + //编辑清空操作
  236 + const clearProfileDataFunc = () => {
  237 + unref(profileData).splice(0, 1);
  238 + };
231 //删除告警配置 239 //删除告警配置
232 const deleteAlarmRule = (index: number) => { 240 const deleteAlarmRule = (index: number) => {
233 unref(profileData).splice(index, 1); 241 unref(profileData).splice(index, 1);
@@ -254,26 +262,27 @@ @@ -254,26 +262,27 @@
254 id: Date.now() + Math.random() + '', 262 id: Date.now() + Math.random() + '',
255 alarmType: '', 263 alarmType: '',
256 createRules: {}, 264 createRules: {},
257 - clearRule: [  
258 - {  
259 - id: Date.now() + Math.random() + '',  
260 - alarmDetails: '',  
261 - dashboardId: {  
262 - id: '',  
263 - entityType: '',  
264 - },  
265 - propagate: '',  
266 - propagateRelationTypes: [''],  
267 - schedule: {  
268 - type: 'string',  
269 - },  
270 - condition: {},  
271 - },  
272 - ], 265 +
273 propagate: false, 266 propagate: false,
274 propagateRelationTypes: [''], 267 propagateRelationTypes: [''],
275 }, 268 },
276 ], 269 ],
  270 + clearRule: [
  271 + {
  272 + id: Date.now() + Math.random() + '',
  273 + alarmDetails: '',
  274 + dashboardId: {
  275 + id: '',
  276 + entityType: '',
  277 + },
  278 + propagate: '',
  279 + propagateRelationTypes: [''],
  280 + schedule: {
  281 + type: 'string',
  282 + },
  283 + condition: {},
  284 + },
  285 + ],
277 }); 286 });
278 }; 287 };
279 //TODO Mobile dashboard: 288 //TODO Mobile dashboard:
@@ -342,6 +351,25 @@ @@ -342,6 +351,25 @@
342 const resetRegisterFormCreateAlarmFunc = () => { 351 const resetRegisterFormCreateAlarmFunc = () => {
343 resetRegisterFormCreateAlarm(); 352 resetRegisterFormCreateAlarm();
344 }; 353 };
  354 + const resetRulesFormDataFunc = () => {
  355 + ruleTemplateData.value = ``;
  356 + };
  357 + const resetEnableFormDataFunc = () => {
  358 + enableTemplateData.value = ``;
  359 + };
  360 + const resetTemplateFormDataFunc = () => {
  361 + detailTemplateData.value = ``;
  362 + };
  363 + const resetRulesClearFormDataFunc = () => {
  364 + ruleClearTemplateData.value = ``;
  365 + };
  366 + const resetEnableClearFormDataFunc = () => {
  367 + enableClearTemplateData.value = ``;
  368 + };
  369 + const resetTemplateClearFormDataFunc = () => {
  370 + detailClearTemplateData.value = ``;
  371 + };
  372 +
345 //回显表单数据 373 //回显表单数据
346 const retryRegisterFormFunc = (v) => { 374 const retryRegisterFormFunc = (v) => {
347 setRegisterForm(v); 375 setRegisterForm(v);
@@ -352,6 +380,25 @@ @@ -352,6 +380,25 @@
352 const retryRegisterFormCreateAlarmFunc = (v) => { 380 const retryRegisterFormCreateAlarmFunc = (v) => {
353 setRegisterFormCreateAlarm(v); 381 setRegisterFormCreateAlarm(v);
354 }; 382 };
  383 + const retryRulesFormDataFunc = (v) => {
  384 + ruleTemplateData.value = v;
  385 + };
  386 + const retryEnableFormDataFunc = (v) => {
  387 + enableTemplateData.value = v;
  388 + };
  389 + const retryTemplateFormDataFunc = (v) => {
  390 + detailTemplateData.value = v;
  391 + };
  392 + const retryRulesClearFormDataFunc = (v) => {
  393 + ruleClearTemplateData.value = v;
  394 + };
  395 + const retryEnableClearFormDataFunc = (v) => {
  396 + enableClearTemplateData.value = v;
  397 + };
  398 + const retryTemplateClearFormDataFunc = (v) => {
  399 + detailClearTemplateData.value = v;
  400 + };
  401 +
355 const tempValue1: string = ref<string>(''); 402 const tempValue1: string = ref<string>('');
356 // 添加‘创建条件’ 403 // 添加‘创建条件’
357 const addCreateRole = (index: number) => { 404 const addCreateRole = (index: number) => {
@@ -400,27 +447,26 @@ @@ -400,27 +447,26 @@
400 }; 447 };
401 }, 448 },
402 }); 449 });
403 -  
404 unref(profileData)[index].alarms.push({ 450 unref(profileData)[index].alarms.push({
405 id: Date.now() + Math.random() + '', 451 id: Date.now() + Math.random() + '',
406 alarmType: '', 452 alarmType: '',
407 createRules: {}, 453 createRules: {},
408 - clearRule: [  
409 - {  
410 - id: Date.now() + Math.random() + '',  
411 - alarmDetails: '',  
412 - dashboardId: {  
413 - id: '',  
414 - entityType: '',  
415 - },  
416 - propagate: '',  
417 - propagateRelationTypes: [''],  
418 - schedule: {  
419 - type: 'string',  
420 - },  
421 - condition: {},  
422 - },  
423 - ], 454 + // clearRule: [
  455 + // {
  456 + // id: Date.now() + Math.random() + '',
  457 + // alarmDetails: '',
  458 + // dashboardId: {
  459 + // id: '',
  460 + // entityType: '',
  461 + // },
  462 + // propagate: '',
  463 + // propagateRelationTypes: [''],
  464 + // schedule: {
  465 + // type: 'string',
  466 + // },
  467 + // condition: {},
  468 + // },
  469 + // ],
424 propagate: false, 470 propagate: false,
425 propagateRelationTypes: [''], 471 propagateRelationTypes: [''],
426 }); 472 });
@@ -486,12 +532,23 @@ @@ -486,12 +532,23 @@
486 console.log(e); 532 console.log(e);
487 } 533 }
488 }); 534 });
  535 + const findDayCustomByValue = findDay.map((f, i) => {
  536 + try {
  537 + if (f.value == v.daysOfWeek1[i]) {
  538 + return f.label;
  539 + }
  540 + } catch (e) {
  541 + console.log(e);
  542 + }
  543 + });
489 enableTemplateData.value = 544 enableTemplateData.value =
490 - v.startsOn == undefined 545 + v.schedule == 'ANY_TIME'
491 ? `始终启用` 546 ? `始终启用`
492 - : ` 547 + : v.schedule == 'SPECIFIC_TIME'
  548 + ? `
493 开始时间:${v.startsOn},结束时间:${v.endsOn},天数:${findDayByValue} 549 开始时间:${v.startsOn},结束时间:${v.endsOn},天数:${findDayByValue}
494 - `; 550 + `
  551 + : `天数:${findDayCustomByValue},开始时间: ${v.startsOn1},结束时间:${v.endsOn1}`;
495 }; 552 };
496 //规则条件 553 //规则条件
497 const getAllFieldsRuleFunc = (v, v1) => { 554 const getAllFieldsRuleFunc = (v, v1) => {
@@ -516,7 +573,7 @@ @@ -516,7 +573,7 @@
516 } 573 }
517 }); 574 });
518 ruleTemplateData.value = ` 575 ruleTemplateData.value = `
519 - 键名:${v.key1}...操作:${findRuleByValue?.label}...值:${v.value1} 576 + 键名:${v.key1} 操作:${findRuleByValue?.label} 值:${v.value1}
520 `; 577 `;
521 578
522 ruleLastObj.value = v1; 579 ruleLastObj.value = v1;
@@ -607,11 +664,23 @@ @@ -607,11 +664,23 @@
607 console.log(e); 664 console.log(e);
608 } 665 }
609 }); 666 });
  667 + const findDayCustomByValue = findDay.map((f, i) => {
  668 + try {
  669 + if (f.value == v.daysOfWeek1[i]) {
  670 + return f.label;
  671 + }
  672 + } catch (e) {
  673 + console.log(e);
  674 + }
  675 + });
610 enableClearTemplateData.value = 676 enableClearTemplateData.value =
611 - v.startsOn == undefined 677 + v.schedule == 'ANY_TIME'
612 ? `始终启用` 678 ? `始终启用`
613 - : `开始时间:${v.startsOn},结束时间:${v.endsOn},天数:${findDayByValue}  
614 - `; 679 + : v.schedule == 'SPECIFIC_TIME'
  680 + ? `
  681 + 开始时间:${v.startsOn},结束时间:${v.endsOn},天数:${findDayByValue}
  682 + `
  683 + : `天数:${findDayCustomByValue},开始时间: ${v.startsOn1},结束时间:${v.endsOn1}`;
615 }; 684 };
616 //规则条件 685 //规则条件
617 const getAllClearFieldsRuleFunc = (v, v1) => { 686 const getAllClearFieldsRuleFunc = (v, v1) => {
@@ -636,7 +705,7 @@ @@ -636,7 +705,7 @@
636 } 705 }
637 }); 706 });
638 ruleClearTemplateData.value = ` 707 ruleClearTemplateData.value = `
639 - 键名:${v.key1}...操作:${findRuleByValue?.label}...值:${v.value1} 708 + 键名:${v.key1} 操作:${findRuleByValue?.label} 值:${v.value1}
640 `; 709 `;
641 710
642 ruleLastObj.value = v1; 711 ruleLastObj.value = v1;
@@ -677,7 +746,7 @@ @@ -677,7 +746,7 @@
677 }; 746 };
678 Object.assign(addClearitionalObj.value, getValueConditon); 747 Object.assign(addClearitionalObj.value, getValueConditon);
679 }; 748 };
680 - //用于生成uuid 749 + //生成uuid
681 function generateUUID() { 750 function generateUUID() {
682 let d = new Date().getTime(); 751 let d = new Date().getTime();
683 if (window.performance && typeof window.performance.now === 'function') { 752 if (window.performance && typeof window.performance.now === 'function') {
@@ -691,28 +760,111 @@ @@ -691,28 +760,111 @@
691 return uuid; 760 return uuid;
692 } 761 }
693 const handleFormStep3toStep4Next = async () => { 762 const handleFormStep3toStep4Next = async () => {
  763 + console.log(enableObj.value);
694 try { 764 try {
  765 + if (enableObj.value.schedule == 'CUSTOM') {
  766 + for (let i in enableObj.value) {
  767 + console.log(enableObj.value[i]);
  768 + console.log(i);
  769 + // let o = {};
  770 + // if(enableObj.value[i]=='1')
  771 + // o[i] = enableObj.value[i];
  772 + // getSchduleCustomValue.value.push(o);
  773 + // getSchduleCustomValue.value.push(enableObj.value[i]);
  774 + }
  775 + console.log(getSchduleCustomValue.value);
  776 + // switch (enableObj.value.daysOfWeek1[0]) {
  777 + // case '1':
  778 + // getSchduleCustomValue.value.push({
  779 + // enabled: true,
  780 + // dayOfWeek: enableObj.value.daysOfWeek1[0],
  781 + // startsOn: enableObj.value.startsOn1,
  782 + // endsOn: enableObj.value.endsOn1,
  783 + // });
  784 + // break;
  785 + // case '2':
  786 + // getSchduleCustomValue.value.push({
  787 + // enabled: true,
  788 + // dayOfWeek: enableObj.value.daysOfWeek2[0],
  789 + // startsOn: enableObj.value.startsOn2,
  790 + // endsOn: enableObj.value.endsOn2,
  791 + // });
  792 + // break;
  793 + // case '3':
  794 + // getSchduleCustomValue.value.push({
  795 + // enabled: true,
  796 + // dayOfWeek: enableObj.value.daysOfWeek3[0],
  797 + // startsOn: enableObj.value.startsOn3,
  798 + // endsOn: enableObj.value.endsOn3,
  799 + // });
  800 + // break;
  801 + // }
  802 + scheduleCustomValue.value = {
  803 + type: enableObj.value.schedule,
  804 + timezone: enableObj.value.timezone,
  805 + items: getSchduleCustomValue.value,
  806 + };
  807 + }
  808 + //清除报警规则---报警日程表
  809 + if (enableClearObj.value.schedule == 'CUSTOM') {
  810 + switch (enableClearObj.value.daysOfWeek1[0]) {
  811 + case '1':
  812 + getSchduleClearCustomValue.value.push({
  813 + enabled: true,
  814 + dayOfWeek: enableClearObj.value.daysOfWeek1[0],
  815 + startsOn: enableClearObj.value.startsOn1,
  816 + endsOn: enableClearObj.value.endsOn1,
  817 + });
  818 + break;
  819 + case '2':
  820 + getSchduleClearCustomValue.value.push({
  821 + enabled: true,
  822 + dayOfWeek: enableClearObj.value.daysOfWeek2[0],
  823 + startsOn: enableClearObj.value.startsOn2,
  824 + endsOn: enableClearObj.value.endsOn2,
  825 + });
  826 + break;
  827 + case '3':
  828 + getSchduleClearCustomValue.value.push({
  829 + enabled: true,
  830 + dayOfWeek: enableClearObj.value.daysOfWeek3[0],
  831 + startsOn: enableClearObj.value.startsOn3,
  832 + endsOn: enableClearObj.value.endsOn3,
  833 + });
  834 + break;
  835 + }
  836 + scheduleCustomClearValue.value = {
  837 + type: enableClearObj.value.schedule,
  838 + timezone: enableClearObj.value.timezone,
  839 + items: getSchduleClearCustomValue.value,
  840 + };
  841 + }
695 const scheduleClearValue = { 842 const scheduleClearValue = {
696 type: enableClearObj.value.schedule, 843 type: enableClearObj.value.schedule,
697 daysOfWeek: enableClearObj.value.daysOfWeek, 844 daysOfWeek: enableClearObj.value.daysOfWeek,
698 - // endsOn: enableClearObj.value.endsOn,  
699 - // startsOn: enableClearObj.value.startOn, 845 + endsOn: enableClearObj.value.endsOn,
  846 + startsOn: enableClearObj.value.startOn,
700 timezone: enableClearObj.value.timezone, 847 timezone: enableClearObj.value.timezone,
701 }; 848 };
702 const getClearSchedule = { 849 const getClearSchedule = {
703 - schedule: scheduleClearValue, 850 + schedule:
  851 + enableClearObj.value.schedule == 'CUSTOM'
  852 + ? scheduleCustomClearValue.value
  853 + : scheduleClearValue,
704 }; 854 };
705 const getClearAdditionalProp = Object.assign({}, detailClearObj.value, getClearSchedule); 855 const getClearAdditionalProp = Object.assign({}, detailClearObj.value, getClearSchedule);
706 const scheduleValue = { 856 const scheduleValue = {
707 type: enableObj.value.schedule, 857 type: enableObj.value.schedule,
708 daysOfWeek: enableObj.value.daysOfWeek, 858 daysOfWeek: enableObj.value.daysOfWeek,
709 - // endsOn: enableObj.value.endsOn,  
710 - // startsOn: enableObj.value.startOn, 859 + endsOn: enableObj.value.endsOn,
  860 + startsOn: enableObj.value.startOn,
711 timezone: enableObj.value.timezone, 861 timezone: enableObj.value.timezone,
712 }; 862 };
713 const getSchedule = { 863 const getSchedule = {
714 - schedule: scheduleValue, 864 + schedule:
  865 + enableObj.value.schedule == 'CUSTOM' ? scheduleCustomValue.value : scheduleValue,
715 }; 866 };
  867 +
716 const getAdditionalProp = Object.assign({}, detailObj.value, getSchedule); 868 const getAdditionalProp = Object.assign({}, detailObj.value, getSchedule);
717 const getScheduleAndAlarmDetails = Object.assign( 869 const getScheduleAndAlarmDetails = Object.assign(
718 {}, 870 {},
@@ -746,7 +898,7 @@ @@ -746,7 +898,7 @@
746 console.log(valueRegisterFormCreateAlarm); 898 console.log(valueRegisterFormCreateAlarm);
747 const getValueRegisterFormHighSetting = { 899 const getValueRegisterFormHighSetting = {
748 propagate: valueRegisterFormHighSetting?.propagate, 900 propagate: valueRegisterFormHighSetting?.propagate,
749 - propagateRelationTypes: [valueRegisterFormHighSetting?.propagateRelationTypes], 901 + propagateRelationTypes: [valueRegisterFormHighSetting?.propagateRelationTypes].flat(1),
750 }; 902 };
751 Object.assign( 903 Object.assign(
752 emptyObj.value, 904 emptyObj.value,
@@ -756,7 +908,9 @@ @@ -756,7 +908,9 @@
756 getClearRulesAllObj, 908 getClearRulesAllObj,
757 objectId 909 objectId
758 ); 910 );
759 - alarmss.value.push(emptyObj.value); 911 + if (alarmss.value.length == 0) {
  912 + alarmss.value.push(emptyObj.value);
  913 + }
760 const getAlarms = { 914 const getAlarms = {
761 alarms: alarmss.value, 915 alarms: alarmss.value,
762 }; 916 };
@@ -795,7 +949,11 @@ @@ -795,7 +949,11 @@
795 isRuleAlarmRuleConditions.value = 4; 949 isRuleAlarmRuleConditions.value = 4;
796 setTimeout(() => { 950 setTimeout(() => {
797 openModal4(true); 951 openModal4(true);
798 - proxy.$refs.getChildData1.resetDataFunc(); 952 + try {
  953 + proxy.$refs.getChildData1.resetDataFunc();
  954 + } catch (e) {
  955 + return e;
  956 + }
799 }, 50); 957 }, 50);
800 }; 958 };
801 const handleOpenClearEnableRule = () => { 959 const handleOpenClearEnableRule = () => {
@@ -814,6 +972,19 @@ @@ -814,6 +972,19 @@
814 }; 972 };
815 973
816 return { 974 return {
  975 + resetEnableClearFormDataFunc,
  976 + resetTemplateClearFormDataFunc,
  977 + resetRulesClearFormDataFunc,
  978 + resetEnableFormDataFunc,
  979 + resetTemplateFormDataFunc,
  980 + resetRulesFormDataFunc,
  981 + retryEnableClearFormDataFunc,
  982 + retryTemplateClearFormDataFunc,
  983 + retryRulesClearFormDataFunc,
  984 + retryEnableFormDataFunc,
  985 + retryTemplateFormDataFunc,
  986 + retryRulesFormDataFunc,
  987 + clearProfileDataFunc,
817 clearIndex, 988 clearIndex,
818 retryRegisterFormFunc, 989 retryRegisterFormFunc,
819 retryRegisterFormHighSettingmFunc, 990 retryRegisterFormHighSettingmFunc,
@@ -99,7 +99,7 @@ export const formSchema: FormSchema[] = [ @@ -99,7 +99,7 @@ export const formSchema: FormSchema[] = [
99 { 99 {
100 field: 'conditionType', 100 field: 'conditionType',
101 label: '条件类型', 101 label: '条件类型',
102 - colProps: { span: 24 }, 102 + colProps: { span: 13 },
103 component: 'Select', 103 component: 'Select',
104 componentProps: { 104 componentProps: {
105 placeholder: '请选择报警日程表', 105 placeholder: '请选择报警日程表',
@@ -177,11 +177,28 @@ export const formSchema: FormSchema[] = [ @@ -177,11 +177,28 @@ export const formSchema: FormSchema[] = [
177 { 177 {
178 field: 'defaultValue', 178 field: 'defaultValue',
179 label: '持续时间值', 179 label: '持续时间值',
180 - colProps: { span: 24 }, 180 + colProps: { span: 13 },
181 component: 'Input', 181 component: 'Input',
182 componentProps: { 182 componentProps: {
  183 + maxLength: 16,
183 placeholder: '请输入持续时间值(请输入数字)', 184 placeholder: '请输入持续时间值(请输入数字)',
184 }, 185 },
  186 + dynamicRules: () => {
  187 + return [
  188 + {
  189 + validator: (_, value) => {
  190 + if (!value) {
  191 + return Promise.reject('持续时间值不能为空');
  192 + }
  193 + const pwdRegex = new RegExp(/-?\d+/);
  194 + if (!pwdRegex.test(value)) {
  195 + return Promise.reject('只能为数字,且最长不超过16位');
  196 + }
  197 + return Promise.resolve();
  198 + },
  199 + },
  200 + ];
  201 + },
185 ifShow: ({ values }) => isWenDu(Reflect.get(values, 'conditionType')), 202 ifShow: ({ values }) => isWenDu(Reflect.get(values, 'conditionType')),
186 show: ({ values }) => { 203 show: ({ values }) => {
187 return !values.field5; 204 return !values.field5;
@@ -210,7 +227,7 @@ export const formSchema: FormSchema[] = [ @@ -210,7 +227,7 @@ export const formSchema: FormSchema[] = [
210 { 227 {
211 field: 'unit', 228 field: 'unit',
212 label: '时间单位', 229 label: '时间单位',
213 - colProps: { span: 24 }, 230 + colProps: { span: 13 },
214 component: 'Select', 231 component: 'Select',
215 componentProps: { 232 componentProps: {
216 placeholder: '请选择时间单位', 233 placeholder: '请选择时间单位',
@@ -226,12 +243,28 @@ export const formSchema: FormSchema[] = [ @@ -226,12 +243,28 @@ export const formSchema: FormSchema[] = [
226 { 243 {
227 field: 'defaultValue', 244 field: 'defaultValue',
228 label: '事件计数值必填', 245 label: '事件计数值必填',
229 - colProps: { span: 24 }, 246 + colProps: { span: 13 },
230 component: 'Input', 247 component: 'Input',
231 componentProps: { 248 componentProps: {
  249 + maxLength: 2147483637,
232 placeholder: '请输入事件计数值(应在1到2147483637之间)', 250 placeholder: '请输入事件计数值(应在1到2147483637之间)',
233 }, 251 },
234 - rules: [{ message: '事件计数应在1到2147483637之间', trigger: 'blur' }], 252 + dynamicRules: () => {
  253 + return [
  254 + {
  255 + validator: (_, value) => {
  256 + if (!value) {
  257 + return Promise.reject('事件计数不能为空');
  258 + }
  259 + const pwdRegex = new RegExp(/-?\d+/);
  260 + if (!pwdRegex.test(value)) {
  261 + return Promise.reject('只能为数字,且最长不超过16位');
  262 + }
  263 + return Promise.resolve();
  264 + },
  265 + },
  266 + ];
  267 + },
235 ifShow: ({ values }) => isTimeAll(Reflect.get(values, 'conditionType')), 268 ifShow: ({ values }) => isTimeAll(Reflect.get(values, 'conditionType')),
236 show: ({ values }) => { 269 show: ({ values }) => {
237 return !values.field6; 270 return !values.field6;
@@ -240,6 +273,7 @@ export const formSchema: FormSchema[] = [ @@ -240,6 +273,7 @@ export const formSchema: FormSchema[] = [
240 { 273 {
241 field: 'inherit', 274 field: 'inherit',
242 label: '', 275 label: '',
  276 + colProps: { span: 13 },
243 component: 'Checkbox', 277 component: 'Checkbox',
244 renderComponentContent: 'Inherit from owner', 278 renderComponentContent: 'Inherit from owner',
245 ifShow: ({ values }) => 279 ifShow: ({ values }) =>
@@ -48,7 +48,7 @@ export const formSchema: FormSchema[] = [ @@ -48,7 +48,7 @@ export const formSchema: FormSchema[] = [
48 { 48 {
49 field: 'type', 49 field: 'type',
50 label: '键类型', 50 label: '键类型',
51 - colProps: { span: 24 }, 51 + colProps: { span: 13 },
52 component: 'Select', 52 component: 'Select',
53 componentProps: { 53 componentProps: {
54 placeholder: '请选择键类型', 54 placeholder: '请选择键类型',
@@ -62,49 +62,80 @@ export const formSchema: FormSchema[] = [ @@ -62,49 +62,80 @@ export const formSchema: FormSchema[] = [
62 { 62 {
63 field: 'key1', 63 field: 'key1',
64 label: '键名', 64 label: '键名',
65 - colProps: { span: 24 }, 65 + colProps: { span: 13 },
66 component: 'Input', 66 component: 'Input',
67 componentProps: { 67 componentProps: {
  68 + maxLength: 255,
68 placeholder: '请输入键名', 69 placeholder: '请输入键名',
69 - // options: [  
70 - // { label: 'active', value: 'active' },  
71 - // { label: 'inactivityAlarmTime', value: 'inactivityAlarmTime' },  
72 - // { label: 'lastActivityTime', value: 'lastActivityTime' },  
73 - // { label: 'lastConnectTime', value: 'lastConnectTime' },  
74 - // { label: 'lastDisconnectTime', value: 'lastDisconnectTime' },  
75 - // ],  
76 }, 70 },
  71 + dynamicRules: () => {
  72 + return [
  73 + {
  74 + required: false,
  75 + validator: (_, value) => {
  76 + if (String(value).length > 255) {
  77 + return Promise.reject('字数不超过255个字');
  78 + }
  79 + return Promise.resolve();
  80 + },
  81 + },
  82 + ];
  83 + },
  84 +
77 ifShow: ({ values }) => isShiDu(Reflect.get(values, 'type')), 85 ifShow: ({ values }) => isShiDu(Reflect.get(values, 'type')),
78 }, 86 },
79 { 87 {
80 field: 'key1', 88 field: 'key1',
81 label: '键名', 89 label: '键名',
82 - colProps: { span: 24 }, 90 + colProps: { span: 13 },
83 component: 'Input', 91 component: 'Input',
84 componentProps: { 92 componentProps: {
  93 + maxLength: 255,
85 placeholder: '请输入键名', 94 placeholder: '请输入键名',
86 - // options: [  
87 - // { label: 'CO2', value: 'CO2' },  
88 - // { label: 'temp', value: 'temp' },  
89 - // { label: 'wet', value: 'wet' },  
90 - // ], 95 + },
  96 + dynamicRules: () => {
  97 + return [
  98 + {
  99 + required: false,
  100 + validator: (_, value) => {
  101 + if (String(value).length > 255) {
  102 + return Promise.reject('字数不超过255个字');
  103 + }
  104 + return Promise.resolve();
  105 + },
  106 + },
  107 + ];
91 }, 108 },
92 ifShow: ({ values }) => isWenDu(Reflect.get(values, 'type')), 109 ifShow: ({ values }) => isWenDu(Reflect.get(values, 'type')),
93 }, 110 },
94 { 111 {
95 field: 'key1', 112 field: 'key1',
96 label: '键名', 113 label: '键名',
97 - colProps: { span: 24 }, 114 + colProps: { span: 13 },
98 component: 'Input', 115 component: 'Input',
99 componentProps: { 116 componentProps: {
  117 + maxLength: 255,
100 placeholder: '请输入键名', 118 placeholder: '请输入键名',
101 }, 119 },
  120 + dynamicRules: () => {
  121 + return [
  122 + {
  123 + required: false,
  124 + validator: (_, value) => {
  125 + if (String(value).length > 255) {
  126 + return Promise.reject('字数不超过255个字');
  127 + }
  128 + return Promise.resolve();
  129 + },
  130 + },
  131 + ];
  132 + },
102 ifShow: ({ values }) => isTimeAll(Reflect.get(values, 'type')), 133 ifShow: ({ values }) => isTimeAll(Reflect.get(values, 'type')),
103 }, 134 },
104 { 135 {
105 field: 'type1', 136 field: 'type1',
106 label: '值类型', 137 label: '值类型',
107 - colProps: { span: 24 }, 138 + colProps: { span: 13 },
108 component: 'Select', 139 component: 'Select',
109 componentProps: { 140 componentProps: {
110 placeholder: '请选择值类型', 141 placeholder: '请选择值类型',
@@ -122,7 +153,7 @@ export const formSchema: FormSchema[] = [ @@ -122,7 +153,7 @@ export const formSchema: FormSchema[] = [
122 { 153 {
123 field: 'operation', 154 field: 'operation',
124 label: '操作', 155 label: '操作',
125 - colProps: { span: 24 }, 156 + colProps: { span: 13 },
126 component: 'Select', 157 component: 'Select',
127 componentProps: { 158 componentProps: {
128 placeholder: '请选择操作', 159 placeholder: '请选择操作',
@@ -141,7 +172,7 @@ export const formSchema: FormSchema[] = [ @@ -141,7 +172,7 @@ export const formSchema: FormSchema[] = [
141 field: '', 172 field: '',
142 label: '大小写', 173 label: '大小写',
143 component: 'Checkbox', 174 component: 'Checkbox',
144 - colProps: { span: 24 }, 175 + colProps: { span: 13 },
145 renderComponentContent: '忽略大小写', 176 renderComponentContent: '忽略大小写',
146 ifShow: ({ values }) => isString(Reflect.get(values, 'type1')), 177 ifShow: ({ values }) => isString(Reflect.get(values, 'type1')),
147 }, 178 },
@@ -180,11 +211,28 @@ export const formSchema: FormSchema[] = [ @@ -180,11 +211,28 @@ export const formSchema: FormSchema[] = [
180 { 211 {
181 field: 'value1', 212 field: 'value1',
182 label: '默认值', 213 label: '默认值',
183 - colProps: { span: 24 }, 214 + colProps: { span: 13 },
184 component: 'Input', 215 component: 'Input',
185 componentProps: { 216 componentProps: {
  217 + maxLength: 16,
186 placeholder: '请输入默认值(数字)', 218 placeholder: '请输入默认值(数字)',
187 }, 219 },
  220 + dynamicRules: () => {
  221 + return [
  222 + {
  223 + validator: (_, value) => {
  224 + if (!value) {
  225 + return Promise.reject('默认值不能为空');
  226 + }
  227 + const pwdRegex = new RegExp(/-?\d+/);
  228 + if (!pwdRegex.test(value)) {
  229 + return Promise.reject('只能为数字,且最长不超过16位');
  230 + }
  231 + return Promise.resolve();
  232 + },
  233 + },
  234 + ];
  235 + },
188 ifShow: ({ values }) => isString(Reflect.get(values, 'type1')), 236 ifShow: ({ values }) => isString(Reflect.get(values, 'type1')),
189 show: ({ values }) => { 237 show: ({ values }) => {
190 return !values.field5; 238 return !values.field5;
@@ -203,7 +251,7 @@ export const formSchema: FormSchema[] = [ @@ -203,7 +251,7 @@ export const formSchema: FormSchema[] = [
203 { 251 {
204 field: 'operation', 252 field: 'operation',
205 label: '操作', 253 label: '操作',
206 - colProps: { span: 24 }, 254 + colProps: { span: 13 },
207 component: 'Select', 255 component: 'Select',
208 componentProps: { 256 componentProps: {
209 placeholder: '请选择操作', 257 placeholder: '请选择操作',
@@ -254,11 +302,27 @@ export const formSchema: FormSchema[] = [ @@ -254,11 +302,27 @@ export const formSchema: FormSchema[] = [
254 { 302 {
255 field: 'value1', 303 field: 'value1',
256 label: '值', 304 label: '值',
257 - colProps: { span: 24 }, 305 + colProps: { span: 13 },
258 component: 'Input', 306 component: 'Input',
259 componentProps: { 307 componentProps: {
260 placeholder: '请输入值(数字)', 308 placeholder: '请输入值(数字)',
261 }, 309 },
  310 + dynamicRules: () => {
  311 + return [
  312 + {
  313 + validator: (_, value) => {
  314 + if (!value) {
  315 + return Promise.reject('值');
  316 + }
  317 + const pwdRegex = new RegExp(/-?\d+/);
  318 + if (!pwdRegex.test(value)) {
  319 + return Promise.reject('只能为数字,且最长不超过16位');
  320 + }
  321 + return Promise.resolve();
  322 + },
  323 + },
  324 + ];
  325 + },
262 ifShow: ({ values }) => isNumeric(Reflect.get(values, 'type1')), 326 ifShow: ({ values }) => isNumeric(Reflect.get(values, 'type1')),
263 show: ({ values }) => { 327 show: ({ values }) => {
264 return !values.field6; 328 return !values.field6;
@@ -278,7 +342,7 @@ export const formSchema: FormSchema[] = [ @@ -278,7 +342,7 @@ export const formSchema: FormSchema[] = [
278 { 342 {
279 field: 'operation', 343 field: 'operation',
280 label: '操作', 344 label: '操作',
281 - colProps: { span: 24 }, 345 + colProps: { span: 13 },
282 component: 'Select', 346 component: 'Select',
283 componentProps: { 347 componentProps: {
284 placeholder: '请选择操作', 348 placeholder: '请选择操作',
@@ -292,6 +356,7 @@ export const formSchema: FormSchema[] = [ @@ -292,6 +356,7 @@ export const formSchema: FormSchema[] = [
292 { 356 {
293 field: '', 357 field: '',
294 label: '默认值', 358 label: '默认值',
  359 + colProps: { span: 13 },
295 component: 'Checkbox', 360 component: 'Checkbox',
296 renderComponentContent: '真', 361 renderComponentContent: '真',
297 ifShow: ({ values }) => isBoolean(Reflect.get(values, 'type1')), 362 ifShow: ({ values }) => isBoolean(Reflect.get(values, 'type1')),
@@ -344,7 +409,7 @@ export const formSchema: FormSchema[] = [ @@ -344,7 +409,7 @@ export const formSchema: FormSchema[] = [
344 { 409 {
345 field: 'operation', 410 field: 'operation',
346 label: '操作', 411 label: '操作',
347 - colProps: { span: 24 }, 412 + colProps: { span: 13 },
348 component: 'Select', 413 component: 'Select',
349 componentProps: { 414 componentProps: {
350 placeholder: '请选择操作', 415 placeholder: '请选择操作',
@@ -364,7 +429,7 @@ export const formSchema: FormSchema[] = [ @@ -364,7 +429,7 @@ export const formSchema: FormSchema[] = [
364 component: 'DatePicker', 429 component: 'DatePicker',
365 label: '请选择日期', 430 label: '请选择日期',
366 colProps: { 431 colProps: {
367 - span: 12, 432 + span: 13,
368 }, 433 },
369 ifShow: ({ values }) => isComplex(Reflect.get(values, 'type1')), 434 ifShow: ({ values }) => isComplex(Reflect.get(values, 'type1')),
370 show: ({ values }) => { 435 show: ({ values }) => {
@@ -376,7 +441,7 @@ export const formSchema: FormSchema[] = [ @@ -376,7 +441,7 @@ export const formSchema: FormSchema[] = [
376 component: 'TimePicker', 441 component: 'TimePicker',
377 label: '请选择时间', 442 label: '请选择时间',
378 colProps: { 443 colProps: {
379 - span: 8, 444 + span: 13,
380 }, 445 },
381 ifShow: ({ values }) => isComplex(Reflect.get(values, 'type1')), 446 ifShow: ({ values }) => isComplex(Reflect.get(values, 'type1')),
382 show: ({ values }) => { 447 show: ({ values }) => {
@@ -4,10 +4,11 @@ export const formSchema: FormSchema[] = [ @@ -4,10 +4,11 @@ export const formSchema: FormSchema[] = [
4 { 4 {
5 field: 'alarmDetails', 5 field: 'alarmDetails',
6 label: '报警详细信息', 6 label: '报警详细信息',
7 - colProps: { span: 12 }, 7 + colProps: { span: 13 },
8 required: true, 8 required: true,
9 component: 'Input', 9 component: 'Input',
10 componentProps: { 10 componentProps: {
  11 + maxLength: 255,
11 placeholder: '请输入报警详细信息', 12 placeholder: '请输入报警详细信息',
12 }, 13 },
13 }, 14 },
@@ -42,16 +42,16 @@ export const formSchema: FormSchema[] = [ @@ -42,16 +42,16 @@ export const formSchema: FormSchema[] = [
42 field: 'timezone', 42 field: 'timezone',
43 label: '时区', 43 label: '时区',
44 colProps: { span: 12 }, 44 colProps: { span: 12 },
45 -  
46 required: true, 45 required: true,
47 component: 'Select', 46 component: 'Select',
  47 + defaultValue: 'Asia/Shanghai (UTC+08:00)',
48 componentProps: { 48 componentProps: {
49 placeholder: '请选择时区', 49 placeholder: '请选择时区',
50 options: [ 50 options: [
51 - { label: 'Africa/Abidjan (UTC+00:00)', value: 'Africa/Abidjan (UTC+00:00)' },  
52 - { label: 'Africa/Accra (UTC+00:00)', value: 'Africa/Accra (UTC+00:00)' },  
53 - { label: 'Africa/Addis Ababa (UTC+03:00)', value: 'Africa/Addis Ababa (UTC+03:00)' },  
54 - { label: 'Africa/Asmara (UTC+03:00)', value: 'Africa/Asmara (UTC+03:00)' }, 51 + { label: 'Asia/Shanghai (UTC+08:00)', value: 'Asia/Shanghai' },
  52 + { label: 'Africa/Accra (UTC+00:00)', value: 'Africa/Accra' },
  53 + { label: 'Africa/Addis Ababa (UTC+03:00)', value: 'Africa/Addis Ababa' },
  54 + { label: 'Africa/Asmara (UTC+03:00)', value: 'Africa/Asmara' },
55 ], 55 ],
56 }, 56 },
57 ifShow: ({ values }) => 57 ifShow: ({ values }) =>
@@ -60,18 +60,28 @@ export const formSchema: FormSchema[] = [ @@ -60,18 +60,28 @@ export const formSchema: FormSchema[] = [
60 60
61 { 61 {
62 field: 'daysOfWeek1', 62 field: 'daysOfWeek1',
63 - component: 'Checkbox',  
64 - label: '星期一', 63 + component: 'CheckboxGroup',
  64 + label: '天',
65 colProps: { 65 colProps: {
66 span: 8, 66 span: 8,
67 }, 67 },
68 - renderComponentContent: '', 68 + componentProps: {
  69 + options: [
  70 + {
  71 + label: '星期一',
  72 + value: '1',
  73 + },
  74 + ],
  75 + },
69 ifShow: ({ values }) => isTimeAll(Reflect.get(values, 'schedule')), 76 ifShow: ({ values }) => isTimeAll(Reflect.get(values, 'schedule')),
70 }, 77 },
71 { 78 {
72 field: 'startsOn1', 79 field: 'startsOn1',
73 component: 'TimePicker', 80 component: 'TimePicker',
74 label: '开始时间选择', 81 label: '开始时间选择',
  82 + componentProps: {
  83 + valueFormat: 'HH:mm:ss',
  84 + },
75 colProps: { 85 colProps: {
76 span: 8, 86 span: 8,
77 }, 87 },
@@ -81,6 +91,9 @@ export const formSchema: FormSchema[] = [ @@ -81,6 +91,9 @@ export const formSchema: FormSchema[] = [
81 field: 'endsOn1', 91 field: 'endsOn1',
82 component: 'TimePicker', 92 component: 'TimePicker',
83 label: '结束时间选择', 93 label: '结束时间选择',
  94 + componentProps: {
  95 + valueFormat: 'HH:mm:ss',
  96 + },
84 colProps: { 97 colProps: {
85 span: 8, 98 span: 8,
86 }, 99 },
@@ -89,18 +102,28 @@ export const formSchema: FormSchema[] = [ @@ -89,18 +102,28 @@ export const formSchema: FormSchema[] = [
89 102
90 { 103 {
91 field: 'daysOfWeek2', 104 field: 'daysOfWeek2',
92 - component: 'Checkbox',  
93 - label: '星期二', 105 + component: 'CheckboxGroup',
  106 + label: '天',
94 colProps: { 107 colProps: {
95 span: 8, 108 span: 8,
96 }, 109 },
97 - renderComponentContent: '', 110 + componentProps: {
  111 + options: [
  112 + {
  113 + label: '星期二',
  114 + value: '2',
  115 + },
  116 + ],
  117 + },
98 ifShow: ({ values }) => isTimeAll(Reflect.get(values, 'schedule')), 118 ifShow: ({ values }) => isTimeAll(Reflect.get(values, 'schedule')),
99 }, 119 },
100 { 120 {
101 field: 'startsOn2', 121 field: 'startsOn2',
102 component: 'TimePicker', 122 component: 'TimePicker',
103 label: '开始时间选择', 123 label: '开始时间选择',
  124 + componentProps: {
  125 + valueFormat: 'HH:mm:ss',
  126 + },
104 colProps: { 127 colProps: {
105 span: 8, 128 span: 8,
106 }, 129 },
@@ -110,6 +133,9 @@ export const formSchema: FormSchema[] = [ @@ -110,6 +133,9 @@ export const formSchema: FormSchema[] = [
110 field: 'endsOn2', 133 field: 'endsOn2',
111 component: 'TimePicker', 134 component: 'TimePicker',
112 label: '结束时间选择', 135 label: '结束时间选择',
  136 + componentProps: {
  137 + valueFormat: 'HH:mm:ss',
  138 + },
113 colProps: { 139 colProps: {
114 span: 8, 140 span: 8,
115 }, 141 },
@@ -117,18 +143,28 @@ export const formSchema: FormSchema[] = [ @@ -117,18 +143,28 @@ export const formSchema: FormSchema[] = [
117 }, 143 },
118 { 144 {
119 field: 'daysOfWeek3', 145 field: 'daysOfWeek3',
120 - component: 'Checkbox',  
121 - label: '星期三', 146 + component: 'CheckboxGroup',
  147 + label: '天',
122 colProps: { 148 colProps: {
123 span: 8, 149 span: 8,
124 }, 150 },
125 - renderComponentContent: '', 151 + componentProps: {
  152 + options: [
  153 + {
  154 + label: '星期三',
  155 + value: '3',
  156 + },
  157 + ],
  158 + },
126 ifShow: ({ values }) => isTimeAll(Reflect.get(values, 'schedule')), 159 ifShow: ({ values }) => isTimeAll(Reflect.get(values, 'schedule')),
127 }, 160 },
128 { 161 {
129 field: 'startsOn3', 162 field: 'startsOn3',
130 component: 'TimePicker', 163 component: 'TimePicker',
131 label: '开始时间选择', 164 label: '开始时间选择',
  165 + componentProps: {
  166 + valueFormat: 'HH:mm:ss',
  167 + },
132 colProps: { 168 colProps: {
133 span: 8, 169 span: 8,
134 }, 170 },
@@ -138,6 +174,9 @@ export const formSchema: FormSchema[] = [ @@ -138,6 +174,9 @@ export const formSchema: FormSchema[] = [
138 field: 'endsOn3', 174 field: 'endsOn3',
139 component: 'TimePicker', 175 component: 'TimePicker',
140 label: '结束时间选择', 176 label: '结束时间选择',
  177 + componentProps: {
  178 + valueFormat: 'HH:mm:ss',
  179 + },
141 colProps: { 180 colProps: {
142 span: 8, 181 span: 8,
143 }, 182 },
@@ -145,18 +184,28 @@ export const formSchema: FormSchema[] = [ @@ -145,18 +184,28 @@ export const formSchema: FormSchema[] = [
145 }, 184 },
146 { 185 {
147 field: 'daysOfWeek4', 186 field: 'daysOfWeek4',
148 - component: 'Checkbox',  
149 - label: '星期四', 187 + component: 'CheckboxGroup',
  188 + label: '天',
150 colProps: { 189 colProps: {
151 span: 8, 190 span: 8,
152 }, 191 },
153 - renderComponentContent: '', 192 + componentProps: {
  193 + options: [
  194 + {
  195 + label: '星期四',
  196 + value: '4',
  197 + },
  198 + ],
  199 + },
154 ifShow: ({ values }) => isTimeAll(Reflect.get(values, 'schedule')), 200 ifShow: ({ values }) => isTimeAll(Reflect.get(values, 'schedule')),
155 }, 201 },
156 { 202 {
157 field: 'startsOn4', 203 field: 'startsOn4',
158 component: 'TimePicker', 204 component: 'TimePicker',
159 label: '开始时间选择', 205 label: '开始时间选择',
  206 + componentProps: {
  207 + valueFormat: 'HH:mm:ss',
  208 + },
160 colProps: { 209 colProps: {
161 span: 8, 210 span: 8,
162 }, 211 },
@@ -166,6 +215,9 @@ export const formSchema: FormSchema[] = [ @@ -166,6 +215,9 @@ export const formSchema: FormSchema[] = [
166 field: 'endsOn4', 215 field: 'endsOn4',
167 component: 'TimePicker', 216 component: 'TimePicker',
168 label: '结束时间选择', 217 label: '结束时间选择',
  218 + componentProps: {
  219 + valueFormat: 'HH:mm:ss',
  220 + },
169 colProps: { 221 colProps: {
170 span: 8, 222 span: 8,
171 }, 223 },
@@ -173,18 +225,28 @@ export const formSchema: FormSchema[] = [ @@ -173,18 +225,28 @@ export const formSchema: FormSchema[] = [
173 }, 225 },
174 { 226 {
175 field: 'daysOfWeek5', 227 field: 'daysOfWeek5',
176 - component: 'Checkbox',  
177 - label: '星期五', 228 + component: 'CheckboxGroup',
  229 + label: '天',
178 colProps: { 230 colProps: {
179 span: 8, 231 span: 8,
180 }, 232 },
181 - renderComponentContent: '', 233 + componentProps: {
  234 + options: [
  235 + {
  236 + label: '星期五',
  237 + value: '5',
  238 + },
  239 + ],
  240 + },
182 ifShow: ({ values }) => isTimeAll(Reflect.get(values, 'schedule')), 241 ifShow: ({ values }) => isTimeAll(Reflect.get(values, 'schedule')),
183 }, 242 },
184 { 243 {
185 field: 'startsOn5', 244 field: 'startsOn5',
186 component: 'TimePicker', 245 component: 'TimePicker',
187 label: '开始时间选择', 246 label: '开始时间选择',
  247 + componentProps: {
  248 + valueFormat: 'HH:mm:ss',
  249 + },
188 colProps: { 250 colProps: {
189 span: 8, 251 span: 8,
190 }, 252 },
@@ -194,6 +256,9 @@ export const formSchema: FormSchema[] = [ @@ -194,6 +256,9 @@ export const formSchema: FormSchema[] = [
194 field: 'endsOn5', 256 field: 'endsOn5',
195 component: 'TimePicker', 257 component: 'TimePicker',
196 label: '结束时间选择', 258 label: '结束时间选择',
  259 + componentProps: {
  260 + valueFormat: 'HH:mm:ss',
  261 + },
197 colProps: { 262 colProps: {
198 span: 8, 263 span: 8,
199 }, 264 },
@@ -201,18 +266,28 @@ export const formSchema: FormSchema[] = [ @@ -201,18 +266,28 @@ export const formSchema: FormSchema[] = [
201 }, 266 },
202 { 267 {
203 field: 'daysOfWeek6', 268 field: 'daysOfWeek6',
204 - component: 'Checkbox',  
205 - label: '星期六', 269 + component: 'CheckboxGroup',
  270 + label: '天',
206 colProps: { 271 colProps: {
207 span: 8, 272 span: 8,
208 }, 273 },
209 - renderComponentContent: '', 274 + componentProps: {
  275 + options: [
  276 + {
  277 + label: '星期六',
  278 + value: '6',
  279 + },
  280 + ],
  281 + },
210 ifShow: ({ values }) => isTimeAll(Reflect.get(values, 'schedule')), 282 ifShow: ({ values }) => isTimeAll(Reflect.get(values, 'schedule')),
211 }, 283 },
212 { 284 {
213 field: 'startsOn6', 285 field: 'startsOn6',
214 component: 'TimePicker', 286 component: 'TimePicker',
215 label: '开始时间选择', 287 label: '开始时间选择',
  288 + componentProps: {
  289 + valueFormat: 'HH:mm:ss',
  290 + },
216 colProps: { 291 colProps: {
217 span: 8, 292 span: 8,
218 }, 293 },
@@ -222,6 +297,9 @@ export const formSchema: FormSchema[] = [ @@ -222,6 +297,9 @@ export const formSchema: FormSchema[] = [
222 field: 'endsOn6', 297 field: 'endsOn6',
223 component: 'TimePicker', 298 component: 'TimePicker',
224 label: '结束时间选择', 299 label: '结束时间选择',
  300 + componentProps: {
  301 + valueFormat: 'HH:mm:ss',
  302 + },
225 colProps: { 303 colProps: {
226 span: 8, 304 span: 8,
227 }, 305 },
@@ -229,18 +307,28 @@ export const formSchema: FormSchema[] = [ @@ -229,18 +307,28 @@ export const formSchema: FormSchema[] = [
229 }, 307 },
230 { 308 {
231 field: 'daysOfWeek7', 309 field: 'daysOfWeek7',
232 - component: 'Checkbox',  
233 - label: '星期七', 310 + component: 'CheckboxGroup',
  311 + label: '天',
234 colProps: { 312 colProps: {
235 span: 8, 313 span: 8,
236 }, 314 },
237 - renderComponentContent: '', 315 + componentProps: {
  316 + options: [
  317 + {
  318 + label: '星期七',
  319 + value: '7',
  320 + },
  321 + ],
  322 + },
238 ifShow: ({ values }) => isTimeAll(Reflect.get(values, 'schedule')), 323 ifShow: ({ values }) => isTimeAll(Reflect.get(values, 'schedule')),
239 }, 324 },
240 { 325 {
241 field: 'startsOn7', 326 field: 'startsOn7',
242 component: 'TimePicker', 327 component: 'TimePicker',
243 label: '开始时间选择', 328 label: '开始时间选择',
  329 + componentProps: {
  330 + valueFormat: 'HH:mm:ss',
  331 + },
244 colProps: { 332 colProps: {
245 span: 8, 333 span: 8,
246 }, 334 },
@@ -250,6 +338,9 @@ export const formSchema: FormSchema[] = [ @@ -250,6 +338,9 @@ export const formSchema: FormSchema[] = [
250 field: 'endsOn7', 338 field: 'endsOn7',
251 component: 'TimePicker', 339 component: 'TimePicker',
252 label: '结束时间选择', 340 label: '结束时间选择',
  341 + componentProps: {
  342 + valueFormat: 'HH:mm:ss',
  343 + },
253 colProps: { 344 colProps: {
254 span: 8, 345 span: 8,
255 }, 346 },
@@ -13,7 +13,8 @@ export const step1Schemas: FormSchema[] = [ @@ -13,7 +13,8 @@ export const step1Schemas: FormSchema[] = [
13 required: true, 13 required: true,
14 component: 'Input', 14 component: 'Input',
15 componentProps: { 15 componentProps: {
16 - maxLength: 30, 16 + maxLength: 255,
  17 + placeholder: '请输入配置名称',
17 }, 18 },
18 }, 19 },
19 //规则链(string) 20 //规则链(string)
@@ -37,17 +38,6 @@ export const step1Schemas: FormSchema[] = [ @@ -37,17 +38,6 @@ export const step1Schemas: FormSchema[] = [
37 immediate: true, 38 immediate: true,
38 }, 39 },
39 }, 40 },
40 - // {  
41 - // field: 'icon',  
42 - // component: 'Upload',  
43 - // label: '请上传图片',  
44 - // colProps: {  
45 - // span: 8,  
46 - // },  
47 - // componentProps: {  
48 - // // api: uploadApi,  
49 - // },  
50 - // },  
51 { 41 {
52 field: 'defaultQueueName', 42 field: 'defaultQueueName',
53 label: '处理队列', 43 label: '处理队列',
@@ -65,6 +55,23 @@ export const step1Schemas: FormSchema[] = [ @@ -65,6 +55,23 @@ export const step1Schemas: FormSchema[] = [
65 label: '描述', 55 label: '描述',
66 field: 'description', 56 field: 'description',
67 component: 'InputTextArea', 57 component: 'InputTextArea',
  58 + componentProps: {
  59 + maxLength: 255,
  60 + placeholder: '请输入描述',
  61 + },
  62 + dynamicRules: () => {
  63 + return [
  64 + {
  65 + required: false,
  66 + validator: (_, value) => {
  67 + if (String(value).length > 255) {
  68 + return Promise.reject('字数不超过255个字');
  69 + }
  70 + return Promise.resolve();
  71 + },
  72 + },
  73 + ];
  74 + },
68 }, 75 },
69 ]; 76 ];
70 77
@@ -96,8 +103,22 @@ export const step3Schemas: FormSchema[] = [ @@ -96,8 +103,22 @@ export const step3Schemas: FormSchema[] = [
96 span: 12, 103 span: 12,
97 }, 104 },
98 componentProps: { 105 componentProps: {
  106 + maxLength: 255,
99 placeholder: '请输入报警类型', 107 placeholder: '请输入报警类型',
100 }, 108 },
  109 + dynamicRules: () => {
  110 + return [
  111 + {
  112 + required: false,
  113 + validator: (_, value) => {
  114 + if (String(value).length > 255) {
  115 + return Promise.reject('字数不超过255个字');
  116 + }
  117 + return Promise.resolve();
  118 + },
  119 + },
  120 + ];
  121 + },
101 }, 122 },
102 ]; 123 ];
103 124
@@ -116,7 +137,21 @@ export const step3ViewHighSetting: FormSchema[] = [ @@ -116,7 +137,21 @@ export const step3ViewHighSetting: FormSchema[] = [
116 span: 11, 137 span: 11,
117 }, 138 },
118 componentProps: { 139 componentProps: {
119 - placeholder: '要传递的关联类型', 140 + maxLength: 255,
  141 + placeholder: '请输入关联类型',
  142 + },
  143 + dynamicRules: () => {
  144 + return [
  145 + {
  146 + required: false,
  147 + validator: (_, value) => {
  148 + if (String(value).length > 255) {
  149 + return Promise.reject('字数不超过255个字');
  150 + }
  151 + return Promise.resolve();
  152 + },
  153 + },
  154 + ];
120 }, 155 },
121 }, 156 },
122 ]; 157 ];
@@ -136,7 +171,21 @@ export const step3HighSetting: FormSchema[] = [ @@ -136,7 +171,21 @@ export const step3HighSetting: FormSchema[] = [
136 span: 11, 171 span: 11,
137 }, 172 },
138 componentProps: { 173 componentProps: {
139 - placeholder: '要传递的关联类型', 174 + maxLength: 255,
  175 + placeholder: '请输入关联类型',
  176 + },
  177 + dynamicRules: () => {
  178 + return [
  179 + {
  180 + required: false,
  181 + validator: (_, value) => {
  182 + if (String(value).length > 255) {
  183 + return Promise.reject('字数不超过255个字');
  184 + }
  185 + return Promise.resolve();
  186 + },
  187 + },
  188 + ];
140 }, 189 },
141 ifShow: ({ values }) => !!values.propagate, 190 ifShow: ({ values }) => !!values.propagate,
142 }, 191 },
@@ -152,7 +201,7 @@ export const step3CreateAlarm: FormSchema[] = [ @@ -152,7 +201,7 @@ export const step3CreateAlarm: FormSchema[] = [
152 colProps: { 201 colProps: {
153 span: 16, 202 span: 16,
154 }, 203 },
155 - componentProps({ formModel }) { 204 + componentProps() {
156 return { 205 return {
157 placeholder: '请选择严重程度', 206 placeholder: '请选择严重程度',
158 options: [ 207 options: [
@@ -216,7 +265,9 @@ export const alertContactsSchemas: FormSchema[] = [ @@ -216,7 +265,9 @@ export const alertContactsSchemas: FormSchema[] = [
216 field: 'alarmContactId', 265 field: 'alarmContactId',
217 label: '告警通知联系人', 266 label: '告警通知联系人',
218 component: 'ApiSelect', 267 component: 'ApiSelect',
  268 + required: true,
219 componentProps: { 269 componentProps: {
  270 + placeholder: '请选择告警通知联系人',
220 api: alarmContactGetPage, 271 api: alarmContactGetPage,
221 labelField: 'username', 272 labelField: 'username',
222 valueField: 'id', 273 valueField: 'id',
@@ -229,6 +280,7 @@ export const alertContactsSchemas: FormSchema[] = [ @@ -229,6 +280,7 @@ export const alertContactsSchemas: FormSchema[] = [
229 required: true, 280 required: true,
230 component: 'ApiSelect', 281 component: 'ApiSelect',
231 componentProps: { 282 componentProps: {
  283 + placeholder: '请选择告警通知方式',
232 api: findDictItemByCode, 284 api: findDictItemByCode,
233 params: { 285 params: {
234 dictCode: 'message_type', 286 dictCode: 'message_type',
@@ -26,7 +26,7 @@ interface IAlarms { @@ -26,7 +26,7 @@ interface IAlarms {
26 id: string; 26 id: string;
27 alarmType: string; 27 alarmType: string;
28 createRules: ICreateRule; 28 createRules: ICreateRule;
29 - clearRule?: IClearRule[]; 29 + // clearRule?: IClearRule[];
30 propagate: boolean; 30 propagate: boolean;
31 propagateRelationTypes: string[]; 31 propagateRelationTypes: string[];
32 } 32 }
@@ -36,4 +36,5 @@ export interface IProfileData { @@ -36,4 +36,5 @@ export interface IProfileData {
36 transportConfiguration?: ITansportConfiguration; 36 transportConfiguration?: ITansportConfiguration;
37 provisionConfiguration?: provisionConfigurationD; 37 provisionConfiguration?: provisionConfigurationD;
38 alarms?: IAlarms[]; 38 alarms?: IAlarms[];
  39 + clearRule?: IClearRule[];
39 } 40 }
1 -import { MessageTypeEnum } from '/@/api/tenant/tenantInfo';  
2 import { BasicColumn } from '/@/components/Table'; 1 import { BasicColumn } from '/@/components/Table';
3 import { FormSchema } from '/@/components/Table'; 2 import { FormSchema } from '/@/components/Table';
4 import { h } from 'vue'; 3 import { h } from 'vue';
@@ -115,6 +114,10 @@ export const formSchema: FormSchema[] = [ @@ -115,6 +114,10 @@ export const formSchema: FormSchema[] = [
115 label: '配置名称', 114 label: '配置名称',
116 required: true, 115 required: true,
117 component: 'Input', 116 component: 'Input',
  117 + componentProps: {
  118 + maxLength: 30,
  119 + placeholder: '请输入配置名称',
  120 + },
118 }, 121 },
119 { 122 {
120 field: 'messageType', 123 field: 'messageType',
@@ -150,12 +153,22 @@ export const formSchema: FormSchema[] = [ @@ -150,12 +153,22 @@ export const formSchema: FormSchema[] = [
150 label: 'accessKeyId', 153 label: 'accessKeyId',
151 required: true, 154 required: true,
152 component: 'Input', 155 component: 'Input',
  156 + componentProps: {
  157 + maxLength: 36,
  158 + placeholder: '请输入accessKeyId',
  159 + },
  160 +
153 ifShow: ({ values }) => isMessage(Reflect.get(values, 'messageType')), 161 ifShow: ({ values }) => isMessage(Reflect.get(values, 'messageType')),
154 }, 162 },
155 { 163 {
156 field: 'accessKeySecret', 164 field: 'accessKeySecret',
157 label: 'accessKeySecret', 165 label: 'accessKeySecret',
158 required: true, 166 required: true,
  167 + componentProps: {
  168 + maxLength: 36,
  169 + placeholder: '请输入accessKeySecret',
  170 + },
  171 +
159 component: 'Input', 172 component: 'Input',
160 ifShow: ({ values }) => isMessage(Reflect.get(values, 'messageType')), 173 ifShow: ({ values }) => isMessage(Reflect.get(values, 'messageType')),
161 }, 174 },
@@ -165,6 +178,11 @@ export const formSchema: FormSchema[] = [ @@ -165,6 +178,11 @@ export const formSchema: FormSchema[] = [
165 defaultValue: 'smtp.163.com', 178 defaultValue: 'smtp.163.com',
166 required: true, 179 required: true,
167 component: 'Input', 180 component: 'Input',
  181 + componentProps: {
  182 + maxLength: 36,
  183 + placeholder: '请输入服务器地址',
  184 + },
  185 +
168 ifShow: ({ values }) => isEmail(Reflect.get(values, 'messageType')), 186 ifShow: ({ values }) => isEmail(Reflect.get(values, 'messageType')),
169 }, 187 },
170 { 188 {
@@ -172,6 +190,11 @@ export const formSchema: FormSchema[] = [ @@ -172,6 +190,11 @@ export const formSchema: FormSchema[] = [
172 label: '端口', 190 label: '端口',
173 defaultValue: 25, 191 defaultValue: 25,
174 required: true, 192 required: true,
  193 + componentProps: {
  194 + maxLength: 36,
  195 + placeholder: '请输入端口',
  196 + },
  197 +
175 component: 'InputNumber', 198 component: 'InputNumber',
176 ifShow: ({ values }) => isEmail(Reflect.get(values, 'messageType')), 199 ifShow: ({ values }) => isEmail(Reflect.get(values, 'messageType')),
177 }, 200 },
@@ -179,6 +202,11 @@ export const formSchema: FormSchema[] = [ @@ -179,6 +202,11 @@ export const formSchema: FormSchema[] = [
179 field: 'username', 202 field: 'username',
180 label: '用户名', 203 label: '用户名',
181 required: true, 204 required: true,
  205 + componentProps: {
  206 + maxLength: 255,
  207 + placeholder: '请输入用户名',
  208 + },
  209 +
182 component: 'Input', 210 component: 'Input',
183 ifShow: ({ values }) => isEmail(Reflect.get(values, 'messageType')), 211 ifShow: ({ values }) => isEmail(Reflect.get(values, 'messageType')),
184 }, 212 },
@@ -186,6 +214,7 @@ export const formSchema: FormSchema[] = [ @@ -186,6 +214,7 @@ export const formSchema: FormSchema[] = [
186 field: 'password', 214 field: 'password',
187 label: '密码', 215 label: '密码',
188 required: true, 216 required: true,
  217 +
189 component: 'InputPassword', 218 component: 'InputPassword',
190 ifShow: ({ values }) => isEmail(Reflect.get(values, 'messageType')), 219 ifShow: ({ values }) => isEmail(Reflect.get(values, 'messageType')),
191 }, 220 },
@@ -194,12 +223,46 @@ export const formSchema: FormSchema[] = [ @@ -194,12 +223,46 @@ export const formSchema: FormSchema[] = [
194 label: '消息配置', 223 label: '消息配置',
195 component: 'Input', 224 component: 'Input',
196 show: false, 225 show: false,
  226 + componentProps: {
  227 + maxLength: 255,
  228 + placeholder: '请输入消息配置',
  229 + },
  230 + dynamicRules: () => {
  231 + return [
  232 + {
  233 + required: false,
  234 + validator: (_, value) => {
  235 + if (String(value).length > 255) {
  236 + return Promise.reject('字数不超过255个字');
  237 + }
  238 + return Promise.resolve();
  239 + },
  240 + },
  241 + ];
  242 + },
197 }, 243 },
198 { 244 {
199 field: 'id', 245 field: 'id',
200 label: '主键', 246 label: '主键',
201 component: 'Input', 247 component: 'Input',
202 show: false, 248 show: false,
  249 + componentProps: {
  250 + maxLength: 36,
  251 + placeholder: '请输入主键',
  252 + },
  253 + dynamicRules: () => {
  254 + return [
  255 + {
  256 + required: false,
  257 + validator: (_, value) => {
  258 + if (String(value).length > 36) {
  259 + return Promise.reject('字数不超过255个字');
  260 + }
  261 + return Promise.resolve();
  262 + },
  263 + },
  264 + ];
  265 + },
203 }, 266 },
204 { 267 {
205 field: 'status', 268 field: 'status',
@@ -216,6 +279,24 @@ export const formSchema: FormSchema[] = [ @@ -216,6 +279,24 @@ export const formSchema: FormSchema[] = [
216 { 279 {
217 label: '备注', 280 label: '备注',
218 field: 'remark', 281 field: 'remark',
  282 + componentProps: {
  283 + maxLength: 255,
  284 + placeholder: '请输入备注',
  285 + },
  286 + dynamicRules: () => {
  287 + return [
  288 + {
  289 + required: false,
  290 + validator: (_, value) => {
  291 + if (String(value).length > 255) {
  292 + return Promise.reject('字数不超过255个字');
  293 + }
  294 + return Promise.resolve();
  295 + },
  296 + },
  297 + ];
  298 + },
  299 +
219 component: 'InputTextArea', 300 component: 'InputTextArea',
220 }, 301 },
221 { 302 {
@@ -223,5 +304,22 @@ export const formSchema: FormSchema[] = [ @@ -223,5 +304,22 @@ export const formSchema: FormSchema[] = [
223 field: 'tenantId', 304 field: 'tenantId',
224 component: 'Input', 305 component: 'Input',
225 show: false, 306 show: false,
  307 + componentProps: {
  308 + maxLength: 36,
  309 + placeholder: '请输入租户ID',
  310 + },
  311 + dynamicRules: () => {
  312 + return [
  313 + {
  314 + required: false,
  315 + validator: (_, value) => {
  316 + if (String(value).length > 36) {
  317 + return Promise.reject('字数不超过255个字');
  318 + }
  319 + return Promise.resolve();
  320 + },
  321 + },
  322 + ];
  323 + },
226 }, 324 },
227 ]; 325 ];
src/views/message/records/data.ts renamed from src/views/message/records/data.tsx
@@ -15,37 +15,3 @@ export const achieveList: TabItem[] = [ @@ -15,37 +15,3 @@ export const achieveList: TabItem[] = [
15 component: 'EmailLog', 15 component: 'EmailLog',
16 }, 16 },
17 ]; 17 ];
18 -  
19 -export const actions: any[] = [  
20 - { icon: 'clarity:star-line', text: '156', color: '#018ffb' },  
21 - { icon: 'bx:bxs-like', text: '156', color: '#459ae8' },  
22 - { icon: 'bx:bxs-message-dots', text: '2', color: '#42d27d' },  
23 -];  
24 -  
25 -export const articleList = (() => {  
26 - const result: any[] = [];  
27 - for (let i = 0; i < 4; i++) {  
28 - result.push({  
29 - title: 'Vben Admin',  
30 - description: ['Vben', '设计语言', 'Typescript'],  
31 - content: '基于Vue Next, TypeScript, Ant Design实现的一套完整的企业级后台管理系统。',  
32 - time: '2020-11-14 11:20',  
33 - });  
34 - }  
35 - return result;  
36 -})();  
37 -  
38 -export const applicationList = (() => {  
39 - const result: any[] = [];  
40 - for (let i = 0; i < 8; i++) {  
41 - result.push({  
42 - title: 'Vben Admin',  
43 - icon: 'emojione-monotone:letter-a',  
44 - color: '#1890ff',  
45 - active: '100',  
46 - new: '1,799',  
47 - download: 'bx:bx-download',  
48 - });  
49 - }  
50 - return result;  
51 -})();  
@@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@
11 </template> 11 </template>
12 12
13 <script lang="ts"> 13 <script lang="ts">
14 - import { Tabs, TabPane } from 'ant-design-vue'; 14 + import { Tabs } from 'ant-design-vue';
15 import { defineComponent } from 'vue'; 15 import { defineComponent } from 'vue';
16 import SmsLog from './item/SmsLog.vue'; 16 import SmsLog from './item/SmsLog.vue';
17 import EmailLog from './item/EmailLog.vue'; 17 import EmailLog from './item/EmailLog.vue';
@@ -20,7 +20,7 @@ @@ -20,7 +20,7 @@
20 export default defineComponent({ 20 export default defineComponent({
21 components: { 21 components: {
22 Tabs, 22 Tabs,
23 - TabPane, 23 + TabPane: Tabs.TabPane,
24 SmsLog, 24 SmsLog,
25 EmailLog, 25 EmailLog,
26 }, 26 },
@@ -3,6 +3,14 @@ @@ -3,6 +3,14 @@
3 <BasicTable @register="registerTable"> 3 <BasicTable @register="registerTable">
4 <template #toolbar> 4 <template #toolbar>
5 <a-button type="primary" @click="handleCreate"> 导出 </a-button> 5 <a-button type="primary" @click="handleCreate"> 导出 </a-button>
  6 + <a-button
  7 + type="primary"
  8 + color="error"
  9 + @click="handleDeleteOrBatchDelete(null)"
  10 + :disabled="hasBatchDelete"
  11 + >
  12 + 批量删除
  13 + </a-button>
6 </template> 14 </template>
7 <template #action="{ record }"> 15 <template #action="{ record }">
8 <TableAction 16 <TableAction
@@ -18,7 +26,7 @@ @@ -18,7 +26,7 @@
18 color: 'error', 26 color: 'error',
19 popConfirm: { 27 popConfirm: {
20 title: '是否确认删除', 28 title: '是否确认删除',
21 - confirm: handleDelete.bind(null, record), 29 + confirm: handleDeleteOrBatchDelete.bind(null, record),
22 }, 30 },
23 }, 31 },
24 ]" 32 ]"
@@ -33,16 +41,19 @@ @@ -33,16 +41,19 @@
33 import { BasicTable, useTable, TableAction } from '/@/components/Table'; 41 import { BasicTable, useTable, TableAction } from '/@/components/Table';
34 import { useDrawerInner } from '/@/components/Drawer'; 42 import { useDrawerInner } from '/@/components/Drawer';
35 import { columns, searchFormSchema } from './email.data'; 43 import { columns, searchFormSchema } from './email.data';
36 - import { useMessage } from '/@/hooks/web/useMessage';  
37 import { mailLogPage, deleteMailLog } from '/@/api/message/records'; 44 import { mailLogPage, deleteMailLog } from '/@/api/message/records';
38 import { useModal } from '/@/components/Modal'; 45 import { useModal } from '/@/components/Modal';
39 import EmailDetail from '/@/views/message/records/item/EmailDetail.vue'; 46 import EmailDetail from '/@/views/message/records/item/EmailDetail.vue';
  47 + import { useBatchDelete } from '/@/hooks/web/useBatchDelete';
40 export default defineComponent({ 48 export default defineComponent({
41 name: 'EmailLog', 49 name: 'EmailLog',
42 components: { EmailDetail, BasicTable, TableAction }, 50 components: { EmailDetail, BasicTable, TableAction },
43 setup() { 51 setup() {
44 const [registerModal, { openModal }] = useModal(); 52 const [registerModal, { openModal }] = useModal();
45 - const { createMessage } = useMessage(); 53 + const { hasBatchDelete, selectionOptions, handleDeleteOrBatchDelete } = useBatchDelete(
  54 + deleteMailLog,
  55 + handleSuccess
  56 + );
46 const [register] = useDrawerInner(() => {}); 57 const [register] = useDrawerInner(() => {});
47 const [registerTable, { reload }] = useTable({ 58 const [registerTable, { reload }] = useTable({
48 title: '邮件发送列表', 59 title: '邮件发送列表',
@@ -64,7 +75,7 @@ @@ -64,7 +75,7 @@
64 slots: { customRender: 'action' }, 75 slots: { customRender: 'action' },
65 fixed: 'right', 76 fixed: 'right',
66 }, 77 },
67 - immediate: true, 78 + ...selectionOptions,
68 }); 79 });
69 80
70 function handleCreate() {} 81 function handleCreate() {}
@@ -75,14 +86,6 @@ @@ -75,14 +86,6 @@
75 }); 86 });
76 } 87 }
77 88
78 - function handleDelete(record: Recordable) {  
79 - let ids = [record.id];  
80 - deleteMailLog(ids).then((result) => {  
81 - createMessage.success(result.message);  
82 - handleSuccess();  
83 - });  
84 - }  
85 -  
86 function handleSuccess() { 89 function handleSuccess() {
87 reload(); 90 reload();
88 } 91 }
@@ -92,7 +95,8 @@ @@ -92,7 +95,8 @@
92 registerTable, 95 registerTable,
93 registerModal, 96 registerModal,
94 handleCreate, 97 handleCreate,
95 - handleDelete, 98 + hasBatchDelete,
  99 + handleDeleteOrBatchDelete,
96 handleModal, 100 handleModal,
97 handleSuccess, 101 handleSuccess,
98 }; 102 };
@@ -2,7 +2,15 @@ @@ -2,7 +2,15 @@
2 <div style="background-color: #f0f2f5"> 2 <div style="background-color: #f0f2f5">
3 <BasicTable @register="registerTable"> 3 <BasicTable @register="registerTable">
4 <template #toolbar> 4 <template #toolbar>
5 - <a-button type="primary" @click="handleCreate"> 导出 </a-button> 5 + <a-button type="primary" @click="handleExport"> 导出 </a-button>
  6 + <a-button
  7 + type="primary"
  8 + color="error"
  9 + @click="handleDeleteOrBatchDelete(null)"
  10 + :disabled="hasBatchDelete"
  11 + >
  12 + 批量删除
  13 + </a-button>
6 </template> 14 </template>
7 <template #action="{ record }"> 15 <template #action="{ record }">
8 <TableAction 16 <TableAction
@@ -18,7 +26,7 @@ @@ -18,7 +26,7 @@
18 color: 'error', 26 color: 'error',
19 popConfirm: { 27 popConfirm: {
20 title: '是否确认删除', 28 title: '是否确认删除',
21 - confirm: handleDelete.bind(null, record), 29 + confirm: handleDeleteOrBatchDelete.bind(null, record),
22 }, 30 },
23 }, 31 },
24 ]" 32 ]"
@@ -29,21 +37,22 @@ @@ -29,21 +37,22 @@
29 </template> 37 </template>
30 <script lang="ts"> 38 <script lang="ts">
31 import { defineComponent, h } from 'vue'; 39 import { defineComponent, h } from 'vue';
32 -  
33 import { BasicTable, useTable, TableAction } from '/@/components/Table'; 40 import { BasicTable, useTable, TableAction } from '/@/components/Table';
34 - import { useDrawerInner } from '/@/components/Drawer';  
35 import { columns, searchFormSchema } from './sms.data'; 41 import { columns, searchFormSchema } from './sms.data';
36 import { Modal } from 'ant-design-vue'; 42 import { Modal } from 'ant-design-vue';
37 - import { useMessage } from '/@/hooks/web/useMessage';  
38 import { smsLogPage, deleteSmsLog } from '/@/api/message/records'; 43 import { smsLogPage, deleteSmsLog } from '/@/api/message/records';
39 import { JsonPreview } from '/@/components/CodeEditor'; 44 import { JsonPreview } from '/@/components/CodeEditor';
  45 + import { useBatchDelete } from '/@/hooks/web/useBatchDelete';
40 46
41 export default defineComponent({ 47 export default defineComponent({
42 name: 'SmsLog', 48 name: 'SmsLog',
43 components: { BasicTable, TableAction }, 49 components: { BasicTable, TableAction },
44 setup() { 50 setup() {
45 - const { createMessage } = useMessage();  
46 - const [register] = useDrawerInner(() => {}); 51 + // 批量删除的hooks
  52 + const { hasBatchDelete, handleDeleteOrBatchDelete, selectionOptions } = useBatchDelete(
  53 + deleteSmsLog,
  54 + handleSuccess
  55 + );
47 const [registerTable, { reload }] = useTable({ 56 const [registerTable, { reload }] = useTable({
48 title: '短信发送列表', 57 title: '短信发送列表',
49 api: smsLogPage, 58 api: smsLogPage,
@@ -64,10 +73,8 @@ @@ -64,10 +73,8 @@
64 slots: { customRender: 'action' }, 73 slots: { customRender: 'action' },
65 fixed: 'right', 74 fixed: 'right',
66 }, 75 },
  76 + ...selectionOptions,
67 }); 77 });
68 -  
69 - function handleCreate() {}  
70 -  
71 function handleQuery(record: Recordable) { 78 function handleQuery(record: Recordable) {
72 Modal.info({ 79 Modal.info({
73 title: '当前配置', 80 title: '当前配置',
@@ -75,26 +82,19 @@ @@ -75,26 +82,19 @@
75 content: h(JsonPreview, { data: JSON.parse(JSON.stringify(record.templateParam)) }), 82 content: h(JsonPreview, { data: JSON.parse(JSON.stringify(record.templateParam)) }),
76 }); 83 });
77 } 84 }
78 -  
79 - function handleDelete(record: Recordable) {  
80 - let ids = [record.id];  
81 - deleteSmsLog(ids).then((result) => {  
82 - createMessage.success(result.message);  
83 - handleSuccess();  
84 - });  
85 - }  
86 - 85 + // 导出 TODO:待做
  86 + const handleExport = () => {};
  87 + // 刷新表格
87 function handleSuccess() { 88 function handleSuccess() {
88 reload(); 89 reload();
89 } 90 }
90 91
91 return { 92 return {
92 - register, 93 + hasBatchDelete,
93 registerTable, 94 registerTable,
94 - handleCreate,  
95 - handleDelete,  
96 - handleSuccess, 95 + handleExport,
97 handleQuery, 96 handleQuery,
  97 + handleDeleteOrBatchDelete,
98 }; 98 };
99 }, 99 },
100 }); 100 });
@@ -51,6 +51,24 @@ export const searchFormSchema: FormSchema[] = [ @@ -51,6 +51,24 @@ export const searchFormSchema: FormSchema[] = [
51 field: 'emailSubject', 51 field: 'emailSubject',
52 label: '邮件主题', 52 label: '邮件主题',
53 component: 'Input', 53 component: 'Input',
  54 + componentProps: {
  55 + maxLength: 255,
  56 + placeholder: '请输入邮件主题',
  57 + },
  58 + dynamicRules: () => {
  59 + return [
  60 + {
  61 + required: false,
  62 + validator: (_, value) => {
  63 + if (String(value).length > 255) {
  64 + return Promise.reject('字数不超过255个字');
  65 + }
  66 + return Promise.resolve();
  67 + },
  68 + },
  69 + ];
  70 + },
  71 +
54 colProps: { span: 6 }, 72 colProps: { span: 6 },
55 }, 73 },
56 { 74 {
@@ -52,6 +52,9 @@ export const searchFormSchema: FormSchema[] = [ @@ -52,6 +52,9 @@ export const searchFormSchema: FormSchema[] = [
52 label: '发送手机', 52 label: '发送手机',
53 component: 'Input', 53 component: 'Input',
54 colProps: { span: 6 }, 54 colProps: { span: 6 },
  55 + componentProps: {
  56 + maxLength: 36,
  57 + },
55 }, 58 },
56 { 59 {
57 field: 'sendTime', 60 field: 'sendTime',
@@ -24,12 +24,45 @@ @@ -24,12 +24,45 @@
24 label: '用途', 24 label: '用途',
25 component: 'Input', 25 component: 'Input',
26 show: false, 26 show: false,
  27 + componentProps: {
  28 + maxLength: 36,
  29 + placeholder: '请输入用途',
  30 + },
  31 + dynamicRules: () => {
  32 + return [
  33 + {
  34 + required: false,
  35 + validator: (_, value) => {
  36 + if (String(value).length > 36) {
  37 + return Promise.reject('字数不超过36个字');
  38 + }
  39 + return Promise.resolve();
  40 + },
  41 + },
  42 + ];
  43 + },
27 }, 44 },
28 { 45 {
29 field: 'messageType', 46 field: 'messageType',
30 component: 'Input', 47 component: 'Input',
31 label: 'messageType', 48 label: 'messageType',
32 show: false, 49 show: false,
  50 + componentProps: {
  51 + maxLength: 36,
  52 + },
  53 + dynamicRules: () => {
  54 + return [
  55 + {
  56 + required: false,
  57 + validator: (_, value) => {
  58 + if (String(value).length > 36) {
  59 + return Promise.reject('字数不超过36个字');
  60 + }
  61 + return Promise.resolve();
  62 + },
  63 + },
  64 + ];
  65 + },
33 }, 66 },
34 { 67 {
35 field: 'phoneNumbers', 68 field: 'phoneNumbers',
@@ -50,6 +83,23 @@ @@ -50,6 +83,23 @@
50 field: 'remark', 83 field: 'remark',
51 component: 'InputTextArea', 84 component: 'InputTextArea',
52 label: '备注', 85 label: '备注',
  86 + componentProps: {
  87 + maxLength: 255,
  88 + placeholder: '请输入备注',
  89 + },
  90 + dynamicRules: () => {
  91 + return [
  92 + {
  93 + required: false,
  94 + validator: (_, value) => {
  95 + if (String(value).length > 255) {
  96 + return Promise.reject('字数不超过255个字');
  97 + }
  98 + return Promise.resolve();
  99 + },
  100 + },
  101 + ];
  102 + },
53 }, 103 },
54 ]; 104 ];
55 export default defineComponent({ 105 export default defineComponent({
@@ -95,12 +95,46 @@ export const searchFormSchema: FormSchema[] = [ @@ -95,12 +95,46 @@ export const searchFormSchema: FormSchema[] = [
95 label: '模板名称', 95 label: '模板名称',
96 component: 'Input', 96 component: 'Input',
97 colProps: { span: 8 }, 97 colProps: { span: 8 },
  98 + componentProps: {
  99 + maxLength: 32,
  100 + placeholder: '请输入模板名称',
  101 + },
  102 + dynamicRules: () => {
  103 + return [
  104 + {
  105 + required: false,
  106 + validator: (_, value) => {
  107 + if (String(value).length > 32) {
  108 + return Promise.reject('字数不超过32个字');
  109 + }
  110 + return Promise.resolve();
  111 + },
  112 + },
  113 + ];
  114 + },
98 }, 115 },
99 { 116 {
100 field: 'templateCode', 117 field: 'templateCode',
101 label: '模板编码', 118 label: '模板编码',
102 component: 'Input', 119 component: 'Input',
103 colProps: { span: 8 }, 120 colProps: { span: 8 },
  121 + componentProps: {
  122 + maxLength: 20,
  123 + placeholder: '请输入模板编码',
  124 + },
  125 + dynamicRules: () => {
  126 + return [
  127 + {
  128 + required: false,
  129 + validator: (_, value) => {
  130 + if (String(value).length > 20) {
  131 + return Promise.reject('字数不超过20个字');
  132 + }
  133 + return Promise.resolve();
  134 + },
  135 + },
  136 + ];
  137 + },
104 }, 138 },
105 ]; 139 ];
106 140
@@ -110,6 +144,23 @@ export const formSchema: FormSchema[] = [ @@ -110,6 +144,23 @@ export const formSchema: FormSchema[] = [
110 label: '主键', 144 label: '主键',
111 component: 'Input', 145 component: 'Input',
112 show: false, 146 show: false,
  147 + componentProps: {
  148 + maxLength: 36,
  149 + placeholder: '请输入主键',
  150 + },
  151 + dynamicRules: () => {
  152 + return [
  153 + {
  154 + required: false,
  155 + validator: (_, value) => {
  156 + if (String(value).length > 36) {
  157 + return Promise.reject('字数不超过36个字');
  158 + }
  159 + return Promise.resolve();
  160 + },
  161 + },
  162 + ];
  163 + },
113 }, 164 },
114 { 165 {
115 field: 'messageType', 166 field: 'messageType',
@@ -145,12 +196,21 @@ export const formSchema: FormSchema[] = [ @@ -145,12 +196,21 @@ export const formSchema: FormSchema[] = [
145 label: '模板名称', 196 label: '模板名称',
146 required: true, 197 required: true,
147 component: 'Input', 198 component: 'Input',
  199 + componentProps: {
  200 + maxLength: 32,
  201 + placeholder: '请输入模板名称',
  202 + },
148 }, 203 },
149 { 204 {
150 field: 'templateCode', 205 field: 'templateCode',
151 label: '模板编号', 206 label: '模板编号',
152 required: true, 207 required: true,
153 component: 'Input', 208 component: 'Input',
  209 + componentProps: {
  210 + maxLength: 20,
  211 + placeholder: '请输入模板编号',
  212 + },
  213 +
154 ifShow: ({ values }) => isMessage(Reflect.get(values, 'messageType')), 214 ifShow: ({ values }) => isMessage(Reflect.get(values, 'messageType')),
155 }, 215 },
156 { 216 {
@@ -158,6 +218,11 @@ export const formSchema: FormSchema[] = [ @@ -158,6 +218,11 @@ export const formSchema: FormSchema[] = [
158 label: '签名', 218 label: '签名',
159 required: true, 219 required: true,
160 component: 'Input', 220 component: 'Input',
  221 + componentProps: {
  222 + maxLength: 32,
  223 + placeholder: '请输入签名',
  224 + },
  225 +
161 ifShow: ({ values }) => isMessage(Reflect.get(values, 'messageType')), 226 ifShow: ({ values }) => isMessage(Reflect.get(values, 'messageType')),
162 }, 227 },
163 { 228 {
@@ -180,5 +245,22 @@ export const formSchema: FormSchema[] = [ @@ -180,5 +245,22 @@ export const formSchema: FormSchema[] = [
180 label: '租户ID', 245 label: '租户ID',
181 component: 'Input', 246 component: 'Input',
182 show: false, 247 show: false,
  248 + componentProps: {
  249 + maxLength: 36,
  250 + placeholder: '请输入租户ID',
  251 + },
  252 + dynamicRules: () => {
  253 + return [
  254 + {
  255 + required: false,
  256 + validator: (_, value) => {
  257 + if (String(value).length > 36) {
  258 + return Promise.reject('字数不超过36个字');
  259 + }
  260 + return Promise.resolve();
  261 + },
  262 + },
  263 + ];
  264 + },
183 }, 265 },
184 ]; 266 ];
@@ -54,7 +54,14 @@ @@ -54,7 +54,14 @@
54 const getValueData: any = ref({}); 54 const getValueData: any = ref({});
55 const [ 55 const [
56 registerCondition, 56 registerCondition,
57 - { resetFields, updateSchema, appendSchemaByField, removeSchemaByFiled, getFieldsValue }, 57 + {
  58 + setFieldsValue,
  59 + resetFields,
  60 + updateSchema,
  61 + appendSchemaByField,
  62 + removeSchemaByFiled,
  63 + getFieldsValue,
  64 + },
58 ] = useForm({ 65 ] = useForm({
59 labelWidth: 100, 66 labelWidth: 100,
60 schemas: useConditionDrawerSchema, 67 schemas: useConditionDrawerSchema,
@@ -69,7 +76,7 @@ @@ -69,7 +76,7 @@
69 async (newV) => { 76 async (newV) => {
70 const options = await screenLinkPageByDeptIdGetDevice({ organizationId: newV }); 77 const options = await screenLinkPageByDeptIdGetDevice({ organizationId: newV });
71 options.items.forEach((v) => { 78 options.items.forEach((v) => {
72 - return (v.value = v.id); 79 + return (v.value = v.id), (v.label = v.name);
73 }); 80 });
74 updateSchema({ 81 updateSchema({
75 field: 'deviceId', 82 field: 'deviceId',
@@ -79,7 +86,10 @@ @@ -79,7 +86,10 @@
79 }); 86 });
80 } 87 }
81 ); 88 );
82 - 89 + //回显数据
  90 + const setFieldsFormValue = (v) => {
  91 + setFieldsValue(v);
  92 + };
83 function getAllFields(getV) { 93 function getAllFields(getV) {
84 const values = getFieldsValue(); 94 const values = getFieldsValue();
85 getValueData.value = values; 95 getValueData.value = values;
@@ -301,7 +311,7 @@ @@ -301,7 +311,7 @@
301 ]); 311 ]);
302 n.value--; 312 n.value--;
303 } 313 }
304 - return { registerCondition, add, del, getAllFields, funcResetFields }; 314 + return { setFieldsFormValue, registerCondition, add, del, getAllFields, funcResetFields };
305 }, 315 },
306 }); 316 });
307 </script> 317 </script>
@@ -48,7 +48,14 @@ @@ -48,7 +48,14 @@
48 const getValueData: any = ref({}); 48 const getValueData: any = ref({});
49 const [ 49 const [
50 registerAction, 50 registerAction,
51 - { resetFields, updateSchema, appendSchemaByField, getFieldsValue, removeSchemaByFiled }, 51 + {
  52 + setFieldsValue,
  53 + resetFields,
  54 + updateSchema,
  55 + appendSchemaByField,
  56 + getFieldsValue,
  57 + removeSchemaByFiled,
  58 + },
52 ] = useForm({ 59 ] = useForm({
53 labelWidth: 100, 60 labelWidth: 100,
54 schemas: useActionDrawerSchema, 61 schemas: useActionDrawerSchema,
@@ -63,7 +70,7 @@ @@ -63,7 +70,7 @@
63 async (newV) => { 70 async (newV) => {
64 const options = await screenLinkPageByDeptIdGetDevice({ organizationId: newV }); 71 const options = await screenLinkPageByDeptIdGetDevice({ organizationId: newV });
65 options.items.forEach((v) => { 72 options.items.forEach((v) => {
66 - return (v.value = v.id); 73 + return (v.value = v.id), (v.label = v.name);
67 }); 74 });
68 updateSchema({ 75 updateSchema({
69 field: 'deviceId', 76 field: 'deviceId',
@@ -73,6 +80,10 @@ @@ -73,6 +80,10 @@
73 }); 80 });
74 } 81 }
75 ); 82 );
  83 + //回显数据
  84 + const setFieldsFormValue = (v) => {
  85 + setFieldsValue(v);
  86 + };
76 function getAllFields(getV) { 87 function getAllFields(getV) {
77 const values = getFieldsValue(); 88 const values = getFieldsValue();
78 getValueData.value = values; 89 getValueData.value = values;
@@ -225,7 +236,7 @@ @@ -225,7 +236,7 @@
225 n.value--; 236 n.value--;
226 } 237 }
227 238
228 - return { registerAction, add, del, getAllFields, funcResetFields }; 239 + return { setFieldsFormValue, registerAction, add, del, getAllFields, funcResetFields };
229 }, 240 },
230 }); 241 });
231 </script> 242 </script>
@@ -61,9 +61,18 @@ @@ -61,9 +61,18 @@
61 props: ['deviceInfo'], 61 props: ['deviceInfo'],
62 setup(props) { 62 setup(props) {
63 const getValueData: any = ref({}); 63 const getValueData: any = ref({});
  64 + const getPushValueData: any = ref([]);
  65 + // const newMapGetPushValueData: any = ref([]);
64 const [ 66 const [
65 registerTrigger, 67 registerTrigger,
66 - { resetFields, appendSchemaByField, removeSchemaByFiled, getFieldsValue, updateSchema }, 68 + {
  69 + setFieldsValue,
  70 + resetFields,
  71 + appendSchemaByField,
  72 + removeSchemaByFiled,
  73 + getFieldsValue,
  74 + updateSchema,
  75 + },
67 ] = useForm({ 76 ] = useForm({
68 labelWidth: 100, 77 labelWidth: 100,
69 schemas: useTriggerDrawerSchema, 78 schemas: useTriggerDrawerSchema,
@@ -78,7 +87,7 @@ @@ -78,7 +87,7 @@
78 async (newV) => { 87 async (newV) => {
79 const options = await screenLinkPageByDeptIdGetDevice({ organizationId: newV }); 88 const options = await screenLinkPageByDeptIdGetDevice({ organizationId: newV });
80 options.items.forEach((v) => { 89 options.items.forEach((v) => {
81 - return (v.value = v.id); 90 + return (v.value = v.id), (v.label = v.name);
82 }); 91 });
83 updateSchema({ 92 updateSchema({
84 field: 'deviceId', 93 field: 'deviceId',
@@ -88,19 +97,42 @@ @@ -88,19 +97,42 @@
88 }); 97 });
89 } 98 }
90 ); 99 );
  100 + //回显数据
  101 + const setFieldsFormValue = (v) => {
  102 + setFieldsValue(v);
  103 + };
  104 + // //去除字符串的数字
  105 + // function trimNumber(str) {
  106 + // return str.replace(/\d+/g, '');
  107 + // }
  108 + // function unique(arr) {
  109 + // return Array.from(new Set(arr));
  110 + // }
91 function getAllFields(getV) { 111 function getAllFields(getV) {
92 const values = getFieldsValue(); 112 const values = getFieldsValue();
93 getValueData.value = values; 113 getValueData.value = values;
94 - console.log(getValueData.value);  
95 getV = getValueData.value; 114 getV = getValueData.value;
  115 + getPushValueData.value.push(getV);
  116 + console.log(getPushValueData.value);
96 return getV; 117 return getV;
97 } 118 }
98 function funcResetFields() { 119 function funcResetFields() {
99 resetFields(); 120 resetFields();
100 } 121 }
  122 + const addString: any = ref('tiggerEvent1') || ref('tiggerEvent2') || ref('tiggerEvent3');
101 123
102 const n = ref(1); 124 const n = ref(1);
103 function add() { 125 function add() {
  126 + const values = getFieldsValue();
  127 + getPushValueData.value.push(values);
  128 + console.log(getPushValueData.value);
  129 + // newMapGetPushValueData.value = getPushValueData.value.map((m) => {
  130 + // const getKeys = Object.keys(m);
  131 + // getKeys.map((f) => {
  132 + // return unique(trimNumber(f));
  133 + // });
  134 + // });
  135 + // console.log(newMapGetPushValueData.value);
104 appendSchemaByField( 136 appendSchemaByField(
105 { 137 {
106 field: `kong${n.value}`, 138 field: `kong${n.value}`,
@@ -137,9 +169,9 @@ @@ -137,9 +169,9 @@
137 placeholder: '请选择设备', 169 placeholder: '请选择设备',
138 }, 170 },
139 ifShow: ({ values }) => 171 ifShow: ({ values }) =>
140 - !isTime(Reflect.get(values, `tiggerEvent${n.value}`)) &&  
141 - !isScene(Reflect.get(values, `tiggerEvent${n.value}`)) &&  
142 - !isHand(Reflect.get(values, `tiggerEvent${n.value}`)), 172 + !isTime(Reflect.get(values, addString.value)) &&
  173 + !isScene(Reflect.get(values, addString.value)) &&
  174 + !isHand(Reflect.get(values, addString.value)),
143 colProps: { 175 colProps: {
144 span: 12, 176 span: 12,
145 }, 177 },
@@ -157,7 +189,7 @@ @@ -157,7 +189,7 @@
157 colProps: { 189 colProps: {
158 span: 12, 190 span: 12,
159 }, 191 },
160 - ifShow: ({ values }) => isTime(Reflect.get(values, `tiggerEvent${n.value}`)), 192 + ifShow: ({ values }) => isTime(Reflect.get(values, addString.value)),
161 }, 193 },
162 '' 194 ''
163 ); 195 );
@@ -174,9 +206,9 @@ @@ -174,9 +206,9 @@
174 ], 206 ],
175 }, 207 },
176 ifShow: ({ values }) => 208 ifShow: ({ values }) =>
177 - !isTime(Reflect.get(values, `tiggerEvent${n.value}`)) &&  
178 - !isScene(Reflect.get(values, `tiggerEvent${n.value}`)) &&  
179 - !isHand(Reflect.get(values, `tiggerEvent${n.value}`)), 209 + !isTime(Reflect.get(values, addString.value)) &&
  210 + !isScene(Reflect.get(values, addString.value)) &&
  211 + !isHand(Reflect.get(values, addString.value)),
180 colProps: { span: 12 }, 212 colProps: { span: 12 },
181 }, 213 },
182 '' 214 ''
@@ -197,9 +229,9 @@ @@ -197,9 +229,9 @@
197 colProps: { span: 12 }, 229 colProps: { span: 12 },
198 ifShow: ({ values }) => 230 ifShow: ({ values }) =>
199 isUpAndDown(Reflect.get(values, `touchWay${n.value}`)) && 231 isUpAndDown(Reflect.get(values, `touchWay${n.value}`)) &&
200 - !isTime(Reflect.get(values, `tiggerEvent${n.value}`)) &&  
201 - !isScene(Reflect.get(values, `tiggerEvent${n.value}`)) &&  
202 - !isHand(Reflect.get(values, `tiggerEvent${n.value}`)), 232 + !isTime(Reflect.get(values, addString.value)) &&
  233 + !isScene(Reflect.get(values, addString.value)) &&
  234 + !isHand(Reflect.get(values, addString.value)),
203 }, 235 },
204 '' 236 ''
205 ); 237 );
@@ -217,9 +249,9 @@ @@ -217,9 +249,9 @@
217 }, 249 },
218 colProps: { span: 12 }, 250 colProps: { span: 12 },
219 ifShow: ({ values }) => 251 ifShow: ({ values }) =>
220 - !isTime(Reflect.get(values, `tiggerEvent${n.value}`)) &&  
221 - !isScene(Reflect.get(values, `tiggerEvent${n.value}`)) &&  
222 - !isHand(Reflect.get(values, `tiggerEvent${n.value}`)) && 252 + !isTime(Reflect.get(values, addString.value)) &&
  253 + !isScene(Reflect.get(values, addString.value)) &&
  254 + !isHand(Reflect.get(values, addString.value)) &&
223 !isUpAndDown(Reflect.get(values, `touchWay${n.value}`)), 255 !isUpAndDown(Reflect.get(values, `touchWay${n.value}`)),
224 }, 256 },
225 '' 257 ''
@@ -242,9 +274,9 @@ @@ -242,9 +274,9 @@
242 ifShow: ({ values }) => 274 ifShow: ({ values }) =>
243 isWenDu(Reflect.get(values, 'attributeChoose')) && 275 isWenDu(Reflect.get(values, 'attributeChoose')) &&
244 !isUpAndDown(Reflect.get(values, `touchWay${n.value}`)) && 276 !isUpAndDown(Reflect.get(values, `touchWay${n.value}`)) &&
245 - !isTime(Reflect.get(values, `tiggerEvent${n.value}`)) &&  
246 - !isScene(Reflect.get(values, `tiggerEvent${n.value}`)) &&  
247 - !isHand(Reflect.get(values, `tiggerEvent${n.value}`)), 277 + !isTime(Reflect.get(values, addString.value)) &&
  278 + !isScene(Reflect.get(values, addString.value)) &&
  279 + !isHand(Reflect.get(values, addString.value)),
248 colProps: { span: 12 }, 280 colProps: { span: 12 },
249 }, 281 },
250 '' 282 ''
@@ -260,9 +292,9 @@ @@ -260,9 +292,9 @@
260 ifShow: ({ values }) => 292 ifShow: ({ values }) =>
261 isWenDu(Reflect.get(values, 'attributeChoose')) && 293 isWenDu(Reflect.get(values, 'attributeChoose')) &&
262 !isUpAndDown(Reflect.get(values, `touchWay${n.value}`)) && 294 !isUpAndDown(Reflect.get(values, `touchWay${n.value}`)) &&
263 - !isTime(Reflect.get(values, `tiggerEvent${n.value}`)) &&  
264 - !isScene(Reflect.get(values, `tiggerEvent${n.value}`)) &&  
265 - !isHand(Reflect.get(values, `tiggerEvent${n.value}`)), 295 + !isTime(Reflect.get(values, addString.value)) &&
  296 + !isScene(Reflect.get(values, addString.value)) &&
  297 + !isHand(Reflect.get(values, addString.value)),
266 colProps: { 298 colProps: {
267 span: 12, 299 span: 12,
268 }, 300 },
@@ -277,7 +309,7 @@ @@ -277,7 +309,7 @@
277 colProps: { 309 colProps: {
278 span: 12, 310 span: 12,
279 }, 311 },
280 - ifShow: ({ values }) => isScene(Reflect.get(values, `tiggerEvent${n.value}`)), 312 + ifShow: ({ values }) => isScene(Reflect.get(values, addString.value)),
281 componentProps: { 313 componentProps: {
282 placeholder: '请输入场景触发器', 314 placeholder: '请输入场景触发器',
283 options: [ 315 options: [
@@ -300,7 +332,7 @@ @@ -300,7 +332,7 @@
300 componentProps: { 332 componentProps: {
301 placeholder: '暂不实现', 333 placeholder: '暂不实现',
302 }, 334 },
303 - ifShow: ({ values }) => isHand(Reflect.get(values, `tiggerEvent${n.value}`)), 335 + ifShow: ({ values }) => isHand(Reflect.get(values, addString.value)),
304 }, 336 },
305 '' 337 ''
306 ); 338 );
@@ -336,7 +368,7 @@ @@ -336,7 +368,7 @@
336 ]); 368 ]);
337 n.value--; 369 n.value--;
338 } 370 }
339 - return { registerTrigger, add, del, getAllFields, funcResetFields }; 371 + return { setFieldsFormValue, registerTrigger, add, del, getAllFields, funcResetFields };
340 }, 372 },
341 }); 373 });
342 </script> 374 </script>
@@ -147,6 +147,7 @@ export const formSchema: FormSchema[] = [ @@ -147,6 +147,7 @@ export const formSchema: FormSchema[] = [
147 required: true, 147 required: true,
148 component: 'Input', 148 component: 'Input',
149 componentProps: { 149 componentProps: {
  150 + maxLength: 36,
150 placeholder: '请输入场景联动名称', 151 placeholder: '请输入场景联动名称',
151 }, 152 },
152 }, 153 },
@@ -200,8 +201,22 @@ export const formSchema: FormSchema[] = [ @@ -200,8 +201,22 @@ export const formSchema: FormSchema[] = [
200 colProps: { span: 24 }, 201 colProps: { span: 24 },
201 component: 'InputTextArea', 202 component: 'InputTextArea',
202 componentProps: { 203 componentProps: {
  204 + maxLength: 255,
203 placeholder: '请输入描述', 205 placeholder: '请输入描述',
204 }, 206 },
  207 + dynamicRules: () => {
  208 + return [
  209 + {
  210 + required: false,
  211 + validator: (_, value) => {
  212 + if (String(value).length > 255) {
  213 + return Promise.reject('字数不超过255个字');
  214 + }
  215 + return Promise.resolve();
  216 + },
  217 + },
  218 + ];
  219 + },
205 }, 220 },
206 ]; 221 ];
207 222
@@ -225,7 +240,21 @@ export const searchFormSchema: FormSchema[] = [ @@ -225,7 +240,21 @@ export const searchFormSchema: FormSchema[] = [
225 component: 'Input', 240 component: 'Input',
226 colProps: { span: 8 }, 241 colProps: { span: 8 },
227 componentProps: { 242 componentProps: {
228 - placeholder: '请输入场景联动状态', 243 + maxLength: 36,
  244 + placeholder: '请输入名称',
  245 + },
  246 + dynamicRules: () => {
  247 + return [
  248 + {
  249 + required: false,
  250 + validator: (_, value) => {
  251 + if (String(value).length > 36) {
  252 + return Promise.reject('字数不超过36个字');
  253 + }
  254 + return Promise.resolve();
  255 + },
  256 + },
  257 + ];
229 }, 258 },
230 }, 259 },
231 { 260 {
@@ -263,9 +292,14 @@ export const useTriggerDrawerSchema: FormSchema[] = [ @@ -263,9 +292,14 @@ export const useTriggerDrawerSchema: FormSchema[] = [
263 field: 'deviceId', 292 field: 'deviceId',
264 label: '', 293 label: '',
265 component: 'Select', 294 component: 'Select',
266 - componentProps: {  
267 - placeholder: '请选择设备', 295 + componentProps() {
  296 + return {
  297 + placeholder: '请选择设备',
  298 + };
268 }, 299 },
  300 + // componentProps: {
  301 + // placeholder: '请选择设备',
  302 + // },
269 ifShow: ({ values }) => 303 ifShow: ({ values }) =>
270 !isTime(Reflect.get(values, 'triggerEvent')) && 304 !isTime(Reflect.get(values, 'triggerEvent')) &&
271 !isScene(Reflect.get(values, 'triggerEvent')) && 305 !isScene(Reflect.get(values, 'triggerEvent')) &&
@@ -279,8 +313,23 @@ export const useTriggerDrawerSchema: FormSchema[] = [ @@ -279,8 +313,23 @@ export const useTriggerDrawerSchema: FormSchema[] = [
279 component: 'Input', 313 component: 'Input',
280 label: '', 314 label: '',
281 componentProps: { 315 componentProps: {
  316 + maxLength: 255,
282 placeholder: '请输入Cron表达式', 317 placeholder: '请输入Cron表达式',
283 }, 318 },
  319 + dynamicRules: () => {
  320 + return [
  321 + {
  322 + required: false,
  323 + validator: (_, value) => {
  324 + if (String(value).length > 255) {
  325 + return Promise.reject('字数不超过255个字');
  326 + }
  327 + return Promise.resolve();
  328 + },
  329 + },
  330 + ];
  331 + },
  332 +
284 colProps: { 333 colProps: {
285 span: 12, 334 span: 12,
286 }, 335 },
@@ -367,8 +416,23 @@ export const useTriggerDrawerSchema: FormSchema[] = [ @@ -367,8 +416,23 @@ export const useTriggerDrawerSchema: FormSchema[] = [
367 component: 'Input', 416 component: 'Input',
368 label: '', 417 label: '',
369 componentProps: { 418 componentProps: {
  419 + maxLength: 16,
370 placeholder: '请输入比较值', 420 placeholder: '请输入比较值',
371 }, 421 },
  422 + dynamicRules: () => {
  423 + return [
  424 + {
  425 + required: false,
  426 + validator: (_, value) => {
  427 + if (String(value).length > 16) {
  428 + return Promise.reject('字数不超过16个字');
  429 + }
  430 + return Promise.resolve();
  431 + },
  432 + },
  433 + ];
  434 + },
  435 +
372 ifShow: ({ values }) => 436 ifShow: ({ values }) =>
373 isWenDu(Reflect.get(values, 'attributeChoose')) && 437 isWenDu(Reflect.get(values, 'attributeChoose')) &&
374 !isUpAndDown(Reflect.get(values, 'touchWay')) && 438 !isUpAndDown(Reflect.get(values, 'touchWay')) &&
@@ -399,7 +463,7 @@ export const useTriggerDrawerSchema: FormSchema[] = [ @@ -399,7 +463,7 @@ export const useTriggerDrawerSchema: FormSchema[] = [
399 }, 463 },
400 464
401 { 465 {
402 - field: '', 466 + field: 'no3',
403 label: '', 467 label: '',
404 component: 'ApiSelect', 468 component: 'ApiSelect',
405 colProps: { 469 colProps: {
@@ -518,8 +582,23 @@ export const useConditionDrawerSchema: FormSchema[] = [ @@ -518,8 +582,23 @@ export const useConditionDrawerSchema: FormSchema[] = [
518 component: 'Input', 582 component: 'Input',
519 label: '', 583 label: '',
520 componentProps: { 584 componentProps: {
  585 + maxLength: 16,
521 placeholder: '请输入比较值', 586 placeholder: '请输入比较值',
522 }, 587 },
  588 + dynamicRules: () => {
  589 + return [
  590 + {
  591 + required: false,
  592 + validator: (_, value) => {
  593 + if (String(value).length > 16) {
  594 + return Promise.reject('字数不超过16个字');
  595 + }
  596 + return Promise.resolve();
  597 + },
  598 + },
  599 + ];
  600 + },
  601 +
523 ifShow: ({ values }) => 602 ifShow: ({ values }) =>
524 isShiDu(Reflect.get(values, 'property')) && !isTimeAll(Reflect.get(values, 'status')), 603 isShiDu(Reflect.get(values, 'property')) && !isTimeAll(Reflect.get(values, 'status')),
525 colProps: { 604 colProps: {
@@ -550,8 +629,22 @@ export const useConditionDrawerSchema: FormSchema[] = [ @@ -550,8 +629,22 @@ export const useConditionDrawerSchema: FormSchema[] = [
550 component: 'Input', 629 component: 'Input',
551 label: '', 630 label: '',
552 componentProps: { 631 componentProps: {
  632 + maxLength: 16,
553 placeholder: '请输入比较值', 633 placeholder: '请输入比较值',
554 }, 634 },
  635 + dynamicRules: () => {
  636 + return [
  637 + {
  638 + required: false,
  639 + validator: (_, value) => {
  640 + if (String(value).length > 16) {
  641 + return Promise.reject('字数不超过16个字');
  642 + }
  643 + return Promise.resolve();
  644 + },
  645 + },
  646 + ];
  647 + },
555 ifShow: ({ values }) => 648 ifShow: ({ values }) =>
556 isWenDu(Reflect.get(values, 'property')) && !isTimeAll(Reflect.get(values, 'status')), 649 isWenDu(Reflect.get(values, 'property')) && !isTimeAll(Reflect.get(values, 'status')),
557 colProps: { 650 colProps: {
@@ -602,8 +695,22 @@ export const useActionDrawerSchema: FormSchema[] = [ @@ -602,8 +695,22 @@ export const useActionDrawerSchema: FormSchema[] = [
602 component: 'Input', 695 component: 'Input',
603 label: '', 696 label: '',
604 componentProps: { 697 componentProps: {
  698 + maxLength: 255,
605 placeholder: '请输入下发指定', 699 placeholder: '请输入下发指定',
606 }, 700 },
  701 + dynamicRules: () => {
  702 + return [
  703 + {
  704 + required: false,
  705 + validator: (_, value) => {
  706 + if (String(value).length > 255) {
  707 + return Promise.reject('字数不超过255个字');
  708 + }
  709 + return Promise.resolve();
  710 + },
  711 + },
  712 + ];
  713 + },
607 ifShow: ({ values }) => 714 ifShow: ({ values }) =>
608 !isScene(Reflect.get(values, 'outTarget')) && !isMsg(Reflect.get(values, 'outTarget')), 715 !isScene(Reflect.get(values, 'outTarget')) && !isMsg(Reflect.get(values, 'outTarget')),
609 colProps: { 716 colProps: {
@@ -71,6 +71,34 @@ @@ -71,6 +71,34 @@
71 await setFieldsValue({ 71 await setFieldsValue({
72 ...data.record, 72 ...data.record,
73 }); 73 });
  74 + try {
  75 + proxy.$refs.getTriggerChildData.setFieldsFormValue({
  76 + triggerEvent: data.record.triggers[0].triggerEvent,
  77 + attributeChoose: data.record?.triggers[0].attributeChoose,
  78 + touchWay: data.record?.triggers[0].touchWay,
  79 + deviceId: data.record?.triggers[0].deviceId,
  80 + compare: data.record?.triggers[0].compare,
  81 + value: data.record?.triggers[0].value,
  82 + sceneLinkageId: data.record?.triggers[0].sceneLinkageId,
  83 + });
  84 + proxy.$refs.getConditionChildData.setFieldsFormValue({
  85 + status: data.record?.doConditions[0].status,
  86 + deviceId: data.record?.doConditions[0].deviceId,
  87 + createTime: data.record?.doConditions[0].createTime,
  88 + updateTime: data.record?.doConditions[0].updateTime,
  89 + property: data.record?.doConditions[0].property,
  90 + compare: data.record?.doConditions[0].compare,
  91 + value: data.record?.doConditions[0].value,
  92 + });
  93 + proxy.$refs.getChildData.setFieldsFormValue({
  94 + outTarget: data.record?.doActions[0].outTarget,
  95 + deviceId: data.record?.doActions[0].deviceId,
  96 + command: data.record?.doActions[0].command,
  97 + sceneLinkageId: data.record?.doActions[0].sceneLinkageId,
  98 + });
  99 + } catch (e) {
  100 + return e;
  101 + }
74 } else { 102 } else {
75 await resetFields(); 103 await resetFields();
76 } 104 }
@@ -88,7 +116,6 @@ @@ -88,7 +116,6 @@
88 triggersArray.push(getTriggerChildValues); 116 triggersArray.push(getTriggerChildValues);
89 doConditionsArray.push(getconditionChildValues); 117 doConditionsArray.push(getconditionChildValues);
90 getValuesFormData = getFieldsValue(); 118 getValuesFormData = getFieldsValue();
91 - console.log('触发器',triggersArray)  
92 Object.assign(getAllFormData, getValuesFormData); 119 Object.assign(getAllFormData, getValuesFormData);
93 getAllFormData.triggers = triggersArray; 120 getAllFormData.triggers = triggersArray;
94 getAllFormData.doConditions = doConditionsArray; 121 getAllFormData.doConditions = doConditionsArray;
@@ -95,6 +95,7 @@ export const formSchema: FormSchema[] = [ @@ -95,6 +95,7 @@ export const formSchema: FormSchema[] = [
95 component: 'Input', 95 component: 'Input',
96 componentProps: { 96 componentProps: {
97 placeholder: '请输入标题', 97 placeholder: '请输入标题',
  98 + maxLength: 200,
98 }, 99 },
99 }, 100 },
100 { 101 {
@@ -158,9 +159,10 @@ export const searchFormSchema: FormSchema[] = [ @@ -158,9 +159,10 @@ export const searchFormSchema: FormSchema[] = [
158 { 159 {
159 field: 'type', 160 field: 'type',
160 label: '', 161 label: '',
161 - colProps: { span: 8 }, 162 + colProps: { span: 4 },
162 component: 'Select', 163 component: 'Select',
163 componentProps: { 164 componentProps: {
  165 + placeholder: '请选择类型',
164 options: [ 166 options: [
165 { 167 {
166 label: '公告', 168 label: '公告',
@@ -11,9 +11,9 @@ @@ -11,9 +11,9 @@
11 <a-button @click="fireResourceError" type="primary"> 11 <a-button @click="fireResourceError" type="primary">
12 {{ t('sys.errorLog.fireResourceError') }} 12 {{ t('sys.errorLog.fireResourceError') }}
13 </a-button> 13 </a-button>
14 - <a-button @click="fireAjaxError" type="primary"> 14 + <!-- <a-button @click="fireAjaxError" type="primary">
15 {{ t('sys.errorLog.fireAjaxError') }} 15 {{ t('sys.errorLog.fireAjaxError') }}
16 - </a-button> 16 + </a-button> -->
17 </template> 17 </template>
18 <template #action="{ record }"> 18 <template #action="{ record }">
19 <TableAction 19 <TableAction
@@ -36,7 +36,7 @@ @@ -36,7 +36,7 @@
36 import { useMessage } from '/@/hooks/web/useMessage'; 36 import { useMessage } from '/@/hooks/web/useMessage';
37 import { useI18n } from '/@/hooks/web/useI18n'; 37 import { useI18n } from '/@/hooks/web/useI18n';
38 import { useErrorLogStore } from '/@/store/modules/errorLog'; 38 import { useErrorLogStore } from '/@/store/modules/errorLog';
39 - import { fireErrorApi } from '/@/api/demo/error'; 39 + // import { fireErrorApi } from '/@/api/demo/error';
40 import { getColumns } from './data'; 40 import { getColumns } from './data';
41 import { cloneDeep } from 'lodash-es'; 41 import { cloneDeep } from 'lodash-es';
42 42
@@ -86,7 +86,7 @@ @@ -86,7 +86,7 @@
86 imgList.value.push(`${new Date().getTime()}.png`); 86 imgList.value.push(`${new Date().getTime()}.png`);
87 } 87 }
88 88
89 - async function fireAjaxError() {  
90 - await fireErrorApi();  
91 - } 89 + // async function fireAjaxError() {
  90 + // await fireErrorApi();
  91 + // }
92 </script> 92 </script>
@@ -12,10 +12,10 @@ @@ -12,10 +12,10 @@
12 import { PageWrapper } from '/@/components/Page'; 12 import { PageWrapper } from '/@/components/Page';
13 import { useGo } from '/@/hooks/web/usePage'; 13 import { useGo } from '/@/hooks/web/usePage';
14 import { Description } from '../../../components/Description'; 14 import { Description } from '../../../components/Description';
15 - import { useTabs } from '/@/hooks/web/useTabs';  
16 import { getAccountInfo } from '../../../api/system/system'; 15 import { getAccountInfo } from '../../../api/system/system';
17 import { accountSchema } from './account.detail.data'; 16 import { accountSchema } from './account.detail.data';
18 import { useDescription } from '../../../components/Description'; 17 import { useDescription } from '../../../components/Description';
  18 + import { useTabs } from '/@/hooks/web/useTabs';
19 const accountData = {}; 19 const accountData = {};
20 export default defineComponent({ 20 export default defineComponent({
21 name: 'AccountDetail', 21 name: 'AccountDetail',
@@ -23,11 +23,10 @@ @@ -23,11 +23,10 @@
23 setup() { 23 setup() {
24 const route = useRoute(); 24 const route = useRoute();
25 const go = useGo(); 25 const go = useGo();
26 - const { setTitle } = useTabs(); 26 + const { setTitle, close } = useTabs();
27 const [register, methods] = useDescription({ 27 const [register, methods] = useDescription({
28 title: '账号基础信息', 28 title: '账号基础信息',
29 data: accountData, 29 data: accountData,
30 - bordered: false,  
31 schema: accountSchema, 30 schema: accountSchema,
32 column: 3, 31 column: 3,
33 }); 32 });
@@ -52,11 +51,10 @@ @@ -52,11 +51,10 @@
52 // 页面左侧点击返回链接时的操作 51 // 页面左侧点击返回链接时的操作
53 function goBack() { 52 function goBack() {
54 // 本例的效果时点击返回始终跳转到账号列表页,实际应用时可返回上一页 53 // 本例的效果时点击返回始终跳转到账号列表页,实际应用时可返回上一页
  54 + close();
55 go('/system/account'); 55 go('/system/account');
56 } 56 }
57 return { goBack, accountSchema, accountData, register }; 57 return { goBack, accountSchema, accountData, register };
58 }, 58 },
59 }); 59 });
60 </script> 60 </script>
61 -  
62 -<style></style>  
@@ -43,12 +43,44 @@ export const searchFormSchema: FormSchema[] = [ @@ -43,12 +43,44 @@ export const searchFormSchema: FormSchema[] = [
43 label: '用户名', 43 label: '用户名',
44 component: 'Input', 44 component: 'Input',
45 colProps: { span: 8 }, 45 colProps: { span: 8 },
  46 + componentProps: {
  47 + maxLength: 255,
  48 + },
  49 + dynamicRules: () => {
  50 + return [
  51 + {
  52 + required: false,
  53 + validator: (_, value) => {
  54 + if (String(value).length > 255) {
  55 + return Promise.reject('字数不超过255个字');
  56 + }
  57 + return Promise.resolve();
  58 + },
  59 + },
  60 + ];
  61 + },
46 }, 62 },
47 { 63 {
48 field: 'realName', 64 field: 'realName',
49 label: '姓名', 65 label: '姓名',
50 component: 'Input', 66 component: 'Input',
51 colProps: { span: 8 }, 67 colProps: { span: 8 },
  68 + componentProps: {
  69 + maxLength: 255,
  70 + },
  71 + dynamicRules: () => {
  72 + return [
  73 + {
  74 + required: false,
  75 + validator: (_, value) => {
  76 + if (String(value).length > 255) {
  77 + return Promise.reject('字数不超过255个字');
  78 + }
  79 + return Promise.resolve();
  80 + },
  81 + },
  82 + ];
  83 + },
52 }, 84 },
53 ]; 85 ];
54 86
@@ -58,6 +90,22 @@ export const accountFormSchema: FormSchema[] = [ @@ -58,6 +90,22 @@ export const accountFormSchema: FormSchema[] = [
58 label: 'id', 90 label: 'id',
59 component: 'Input', 91 component: 'Input',
60 show: false, 92 show: false,
  93 + componentProps: {
  94 + maxLength: 36,
  95 + },
  96 + dynamicRules: () => {
  97 + return [
  98 + {
  99 + required: false,
  100 + validator: (_, value) => {
  101 + if (String(value).length > 36) {
  102 + return Promise.reject('字数不超过36个字');
  103 + }
  104 + return Promise.resolve();
  105 + },
  106 + },
  107 + ];
  108 + },
61 }, 109 },
62 { 110 {
63 field: 'username', 111 field: 'username',
@@ -108,6 +156,9 @@ export const accountFormSchema: FormSchema[] = [ @@ -108,6 +156,9 @@ export const accountFormSchema: FormSchema[] = [
108 component: 'Input', 156 component: 'Input',
109 colProps: { span: 12 }, 157 colProps: { span: 12 },
110 required: true, 158 required: true,
  159 + componentProps: {
  160 + maxLength: 255,
  161 + },
111 }, 162 },
112 { 163 {
113 label: '角色', 164 label: '角色',
@@ -170,5 +221,21 @@ export const accountFormSchema: FormSchema[] = [ @@ -170,5 +221,21 @@ export const accountFormSchema: FormSchema[] = [
170 label: ' ', 221 label: ' ',
171 component: 'Input', 222 component: 'Input',
172 slot: 'organizationId', 223 slot: 'organizationId',
  224 + componentProps: {
  225 + maxLength: 36,
  226 + },
  227 + dynamicRules: () => {
  228 + return [
  229 + {
  230 + required: false,
  231 + validator: (_, value) => {
  232 + if (String(value).length > 36) {
  233 + return Promise.reject('字数不超过36个字');
  234 + }
  235 + return Promise.resolve();
  236 + },
  237 + },
  238 + ];
  239 + },
173 }, 240 },
174 ]; 241 ];
@@ -35,12 +35,44 @@ export const searchFormSchema: FormSchema[] = [ @@ -35,12 +35,44 @@ export const searchFormSchema: FormSchema[] = [
35 label: '字典名称', 35 label: '字典名称',
36 component: 'Input', 36 component: 'Input',
37 colProps: { span: 6 }, 37 colProps: { span: 6 },
  38 + componentProps: {
  39 + maxLength: 32,
  40 + },
  41 + dynamicRules: () => {
  42 + return [
  43 + {
  44 + required: false,
  45 + validator: (_, value) => {
  46 + if (String(value).length > 32) {
  47 + return Promise.reject('字数不超过32个字');
  48 + }
  49 + return Promise.resolve();
  50 + },
  51 + },
  52 + ];
  53 + },
38 }, 54 },
39 { 55 {
40 field: 'dictCode', 56 field: 'dictCode',
41 label: '字典编码', 57 label: '字典编码',
42 component: 'Input', 58 component: 'Input',
43 colProps: { span: 6 }, 59 colProps: { span: 6 },
  60 + componentProps: {
  61 + maxLength: 32,
  62 + },
  63 + dynamicRules: () => {
  64 + return [
  65 + {
  66 + required: false,
  67 + validator: (_, value) => {
  68 + if (String(value).length > 32) {
  69 + return Promise.reject('字数不超过32个字');
  70 + }
  71 + return Promise.resolve();
  72 + },
  73 + },
  74 + ];
  75 + },
44 }, 76 },
45 ]; 77 ];
46 78
@@ -50,16 +82,38 @@ export const formSchema: FormSchema[] = [ @@ -50,16 +82,38 @@ export const formSchema: FormSchema[] = [
50 label: '字典名称', 82 label: '字典名称',
51 required: true, 83 required: true,
52 component: 'Input', 84 component: 'Input',
  85 + componentProps: {
  86 + maxLength: 32,
  87 + },
53 }, 88 },
54 { 89 {
55 field: 'dictCode', 90 field: 'dictCode',
56 label: '字典编码', 91 label: '字典编码',
57 required: true, 92 required: true,
58 component: 'Input', 93 component: 'Input',
  94 + componentProps: {
  95 + maxLength: 32,
  96 + },
59 }, 97 },
60 { 98 {
61 label: '备注', 99 label: '备注',
62 field: 'description', 100 field: 'description',
63 component: 'InputTextArea', 101 component: 'InputTextArea',
  102 + componentProps: {
  103 + maxLength: 255,
  104 + },
  105 + dynamicRules: () => {
  106 + return [
  107 + {
  108 + required: false,
  109 + validator: (_, value) => {
  110 + if (String(value).length > 255) {
  111 + return Promise.reject('字数不超过255个字');
  112 + }
  113 + return Promise.resolve();
  114 + },
  115 + },
  116 + ];
  117 + },
64 }, 118 },
65 ]; 119 ];
@@ -67,12 +67,44 @@ export const searchFormSchema: FormSchema[] = [ @@ -67,12 +67,44 @@ export const searchFormSchema: FormSchema[] = [
67 label: '文本值', 67 label: '文本值',
68 component: 'Input', 68 component: 'Input',
69 colProps: { span: 6 }, 69 colProps: { span: 6 },
  70 + componentProps: {
  71 + maxLength: 32,
  72 + },
  73 + dynamicRules: () => {
  74 + return [
  75 + {
  76 + required: false,
  77 + validator: (_, value) => {
  78 + if (String(value).length > 32) {
  79 + return Promise.reject('字数不超过32个字');
  80 + }
  81 + return Promise.resolve();
  82 + },
  83 + },
  84 + ];
  85 + },
70 }, 86 },
71 { 87 {
72 field: 'dictId', 88 field: 'dictId',
73 label: '文本值', 89 label: '文本值',
74 component: 'Input', 90 component: 'Input',
75 show: false, 91 show: false,
  92 + componentProps: {
  93 + maxLength: 36,
  94 + },
  95 + dynamicRules: () => {
  96 + return [
  97 + {
  98 + required: false,
  99 + validator: (_, value) => {
  100 + if (String(value).length > 36) {
  101 + return Promise.reject('字数不超过36个字');
  102 + }
  103 + return Promise.resolve();
  104 + },
  105 + },
  106 + ];
  107 + },
76 }, 108 },
77 ]; 109 ];
78 110
@@ -82,18 +114,53 @@ export const formSchema: FormSchema[] = [ @@ -82,18 +114,53 @@ export const formSchema: FormSchema[] = [
82 label: '文本值', 114 label: '文本值',
83 required: true, 115 required: true,
84 component: 'Input', 116 component: 'Input',
  117 + componentProps: {
  118 + maxLength: 32,
  119 + },
  120 + dynamicRules: () => {
  121 + return [
  122 + {
  123 + required: true,
  124 + validator: (_, value) => {
  125 + if (String(value).length > 32) {
  126 + return Promise.reject('字数不超过32个字');
  127 + }
  128 + return Promise.resolve();
  129 + },
  130 + },
  131 + ];
  132 + },
85 }, 133 },
86 { 134 {
87 field: 'itemValue', 135 field: 'itemValue',
88 label: '字典值', 136 label: '字典值',
89 required: true, 137 required: true,
90 component: 'Input', 138 component: 'Input',
  139 + componentProps: {
  140 + maxLength: 32,
  141 + },
  142 + dynamicRules: () => {
  143 + return [
  144 + {
  145 + required: true,
  146 + validator: (_, value) => {
  147 + if (String(value).length > 32) {
  148 + return Promise.reject('字数不超过32个字');
  149 + }
  150 + return Promise.resolve();
  151 + },
  152 + },
  153 + ];
  154 + },
91 }, 155 },
92 { 156 {
93 field: 'sort', 157 field: 'sort',
94 label: '排序', 158 label: '排序',
95 component: 'InputNumber', 159 component: 'InputNumber',
96 defaultValue: 1, 160 defaultValue: 1,
  161 + componentProps: {
  162 + maxLength: 32,
  163 + },
97 }, 164 },
98 { 165 {
99 field: 'status', 166 field: 'status',
@@ -111,5 +178,21 @@ export const formSchema: FormSchema[] = [ @@ -111,5 +178,21 @@ export const formSchema: FormSchema[] = [
111 label: '备注', 178 label: '备注',
112 field: 'description', 179 field: 'description',
113 component: 'InputTextArea', 180 component: 'InputTextArea',
  181 + componentProps: {
  182 + maxLength: 255,
  183 + },
  184 + dynamicRules: () => {
  185 + return [
  186 + {
  187 + required: false,
  188 + validator: (_, value) => {
  189 + if (String(value).length > 255) {
  190 + return Promise.reject('字数不超过255个字');
  191 + }
  192 + return Promise.resolve();
  193 + },
  194 + },
  195 + ];
  196 + },
114 }, 197 },
115 ]; 198 ];
@@ -80,6 +80,22 @@ export const searchFormSchema: FormSchema[] = [ @@ -80,6 +80,22 @@ export const searchFormSchema: FormSchema[] = [
80 // label: '菜单名称', 80 // label: '菜单名称',
81 component: 'Input', 81 component: 'Input',
82 colProps: { span: 8 }, 82 colProps: { span: 8 },
  83 + componentProps: {
  84 + maxLength: 255,
  85 + },
  86 + dynamicRules: () => {
  87 + return [
  88 + {
  89 + required: false,
  90 + validator: (_, value) => {
  91 + if (String(value).length > 255) {
  92 + return Promise.reject('字数不超过255个字');
  93 + }
  94 + return Promise.resolve();
  95 + },
  96 + },
  97 + ];
  98 + },
83 }, 99 },
84 { 100 {
85 field: 'status', 101 field: 'status',
@@ -123,6 +139,10 @@ export const formSchema: FormSchema[] = [ @@ -123,6 +139,10 @@ export const formSchema: FormSchema[] = [
123 label: t('routes.common.system.tableTitleSystemMenuName'), //菜单名称 139 label: t('routes.common.system.tableTitleSystemMenuName'), //菜单名称
124 component: 'Input', 140 component: 'Input',
125 required: true, 141 required: true,
  142 + componentProps: {
  143 + maxLength: 255,
  144 + placeholder: '请输入title',
  145 + },
126 }, 146 },
127 147
128 { 148 {
@@ -144,6 +164,9 @@ export const formSchema: FormSchema[] = [ @@ -144,6 +164,9 @@ export const formSchema: FormSchema[] = [
144 label: t('routes.common.system.tableTitleSystemSort'), //排序 164 label: t('routes.common.system.tableTitleSystemSort'), //排序
145 component: 'InputNumber', 165 component: 'InputNumber',
146 required: true, 166 required: true,
  167 + componentProps: {
  168 + maxLength: 32,
  169 + },
147 }, 170 },
148 { 171 {
149 field: 'icon', 172 field: 'icon',
@@ -159,18 +182,54 @@ export const formSchema: FormSchema[] = [ @@ -159,18 +182,54 @@ export const formSchema: FormSchema[] = [
159 component: 'Input', 182 component: 'Input',
160 required: true, 183 required: true,
161 ifShow: ({ values }) => !isButton(Reflect.get(values, 'menuType')), 184 ifShow: ({ values }) => !isButton(Reflect.get(values, 'menuType')),
  185 + componentProps: {
  186 + maxLength: 255,
  187 + palceholder: '请输入path',
  188 + },
162 }, 189 },
163 { 190 {
164 field: 'component', 191 field: 'component',
165 label: t('routes.common.system.menuEditPagesComponentsPath'), //组件路径 192 label: t('routes.common.system.menuEditPagesComponentsPath'), //组件路径
166 component: 'Input', 193 component: 'Input',
167 ifShow: ({ values }) => isMenu(Reflect.get(values, 'menuType')), 194 ifShow: ({ values }) => isMenu(Reflect.get(values, 'menuType')),
  195 + componentProps: {
  196 + maxLength: 100,
  197 + },
  198 + dynamicRules: () => {
  199 + return [
  200 + {
  201 + required: false,
  202 + validator: (_, value) => {
  203 + if (String(value).length > 100) {
  204 + return Promise.reject('字数不超过100个字');
  205 + }
  206 + return Promise.resolve();
  207 + },
  208 + },
  209 + ];
  210 + },
168 }, 211 },
169 { 212 {
170 field: 'permission', 213 field: 'permission',
171 label: t('routes.common.system.tableTitleSystemPermissionTag'), //权限标识 214 label: t('routes.common.system.tableTitleSystemPermissionTag'), //权限标识
172 component: 'Input', 215 component: 'Input',
173 ifShow: ({ values }) => !isDir(Reflect.get(values, 'menuType')), 216 ifShow: ({ values }) => !isDir(Reflect.get(values, 'menuType')),
  217 + componentProps: {
  218 + maxLength: 100,
  219 + },
  220 + dynamicRules: () => {
  221 + return [
  222 + {
  223 + required: false,
  224 + validator: (_, value) => {
  225 + if (String(value).length > 100) {
  226 + return Promise.reject('字数不超过100个字');
  227 + }
  228 + return Promise.resolve();
  229 + },
  230 + },
  231 + ];
  232 + },
174 }, 233 },
175 { 234 {
176 field: 'status', 235 field: 'status',
@@ -45,22 +45,61 @@ export const formSchema: FormSchema[] = [ @@ -45,22 +45,61 @@ export const formSchema: FormSchema[] = [
45 label: t('routes.common.organization.queryOrganizationName'), 45 label: t('routes.common.organization.queryOrganizationName'),
46 component: 'Input', 46 component: 'Input',
47 required: true, 47 required: true,
  48 + componentProps: {
  49 + maxLength: 255,
  50 + placeholder: '请输入name',
  51 + },
48 }, 52 },
49 { 53 {
50 field: 'sort', 54 field: 'sort',
51 label: t('routes.common.common.sort'), //排序 55 label: t('routes.common.common.sort'), //排序
52 component: 'InputNumber', 56 component: 'InputNumber',
53 required: true, 57 required: true,
  58 + componentProps: {
  59 + maxLength: 32,
  60 + },
54 }, 61 },
55 { 62 {
56 label: t('routes.common.common.remark'), //备注 63 label: t('routes.common.common.remark'), //备注
57 field: 'remark', 64 field: 'remark',
58 component: 'InputTextArea', 65 component: 'InputTextArea',
  66 + componentProps: {
  67 + maxLength: 255,
  68 + },
  69 + dynamicRules: () => {
  70 + return [
  71 + {
  72 + required: false,
  73 + validator: (_, value) => {
  74 + if (String(value).length > 255) {
  75 + return Promise.reject('字数不超过255个字');
  76 + }
  77 + return Promise.resolve();
  78 + },
  79 + },
  80 + ];
  81 + },
59 }, 82 },
60 { 83 {
61 label: '租户ID', 84 label: '租户ID',
62 field: 'tenantId', 85 field: 'tenantId',
63 component: 'Input', 86 component: 'Input',
64 show: false, 87 show: false,
  88 + componentProps: {
  89 + maxLength: 36,
  90 + },
  91 + dynamicRules: () => {
  92 + return [
  93 + {
  94 + required: false,
  95 + validator: (_, value) => {
  96 + if (String(value).length > 36) {
  97 + return Promise.reject('字数不超过36个字');
  98 + }
  99 + return Promise.resolve();
  100 + },
  101 + },
  102 + ];
  103 + },
65 }, 104 },
66 ]; 105 ];
@@ -16,7 +16,7 @@ @@ -16,7 +16,7 @@
16 label: '删除', 16 label: '删除',
17 icon: 'ant-design:delete-outlined', 17 icon: 'ant-design:delete-outlined',
18 color: 'error', 18 color: 'error',
19 - ifShow: record.roleType != RoleEnum.ROLE_SYS_ADMIN, 19 + ifShow: record.roleType != RoleEnum.SYS_ADMIN,
20 popConfirm: { 20 popConfirm: {
21 title: '是否确认删除', 21 title: '是否确认删除',
22 confirm: handleDelete.bind(null, record), 22 confirm: handleDelete.bind(null, record),
@@ -67,6 +67,22 @@ export const searchFormSchema: FormSchema[] = [ @@ -67,6 +67,22 @@ export const searchFormSchema: FormSchema[] = [
67 label: '角色名称', 67 label: '角色名称',
68 component: 'Input', 68 component: 'Input',
69 colProps: { span: 8 }, 69 colProps: { span: 8 },
  70 + componentProps: {
  71 + maxLength: 255,
  72 + },
  73 + dynamicRules: () => {
  74 + return [
  75 + {
  76 + required: false,
  77 + validator: (_, value) => {
  78 + if (String(value).length > 255) {
  79 + return Promise.reject('字数不超过255个字');
  80 + }
  81 + return Promise.resolve();
  82 + },
  83 + },
  84 + ];
  85 + },
70 }, 86 },
71 { 87 {
72 field: 'status', 88 field: 'status',
@@ -88,6 +104,9 @@ export const formSchema: FormSchema[] = [ @@ -88,6 +104,9 @@ export const formSchema: FormSchema[] = [
88 label: '角色名称', 104 label: '角色名称',
89 required: true, 105 required: true,
90 component: 'Input', 106 component: 'Input',
  107 + componentProps: {
  108 + maxLength: 255,
  109 + },
91 }, 110 },
92 { 111 {
93 field: 'status', 112 field: 'status',
@@ -105,11 +124,43 @@ export const formSchema: FormSchema[] = [ @@ -105,11 +124,43 @@ export const formSchema: FormSchema[] = [
105 label: '备注', 124 label: '备注',
106 field: 'remark', 125 field: 'remark',
107 component: 'InputTextArea', 126 component: 'InputTextArea',
  127 + componentProps: {
  128 + maxLength: 255,
  129 + },
  130 + dynamicRules: () => {
  131 + return [
  132 + {
  133 + required: false,
  134 + validator: (_, value) => {
  135 + if (String(value).length > 255) {
  136 + return Promise.reject('字数不超过255个字');
  137 + }
  138 + return Promise.resolve();
  139 + },
  140 + },
  141 + ];
  142 + },
108 }, 143 },
109 { 144 {
110 label: ' ', 145 label: ' ',
111 field: 'menu', 146 field: 'menu',
112 slot: 'menu', 147 slot: 'menu',
113 component: 'Input', 148 component: 'Input',
  149 + componentProps: {
  150 + maxLength: 255,
  151 + },
  152 + dynamicRules: () => {
  153 + return [
  154 + {
  155 + required: false,
  156 + validator: (_, value) => {
  157 + if (String(value).length > 255) {
  158 + return Promise.reject('字数不超过255个字');
  159 + }
  160 + return Promise.resolve();
  161 + },
  162 + },
  163 + ];
  164 + },
114 }, 165 },
115 ]; 166 ];
@@ -171,7 +171,7 @@ @@ -171,7 +171,7 @@
171 showIndexColumn: false, 171 showIndexColumn: false,
172 searchInfo: { 172 searchInfo: {
173 tenantId, 173 tenantId,
174 - roleType: RoleEnum.ROLE_TENANT_ADMIN, 174 + roleType: RoleEnum.TENANT_ADMIN,
175 }, 175 },
176 actionColumn: { 176 actionColumn: {
177 width: 100, 177 width: 100,
@@ -35,6 +35,9 @@ @@ -35,6 +35,9 @@
35 label: 'id:', 35 label: 'id:',
36 show: false, 36 show: false,
37 component: 'Input', 37 component: 'Input',
  38 + componentProps: {
  39 + maxLength: 36,
  40 + },
38 }, 41 },
39 { 42 {
40 field: 'username', 43 field: 'username',
@@ -76,6 +79,9 @@ @@ -76,6 +79,9 @@
76 label: '真实名字', 79 label: '真实名字',
77 required: true, 80 required: true,
78 component: 'Input', 81 component: 'Input',
  82 + componentProps: {
  83 + maxLength: 255,
  84 + },
79 }, 85 },
80 { 86 {
81 field: 'phoneNumber', 87 field: 'phoneNumber',
@@ -94,7 +94,7 @@ @@ -94,7 +94,7 @@
94 await updateSchema({ field: 'title', componentProps: { disabled: false } }); 94 await updateSchema({ field: 'title', componentProps: { disabled: false } });
95 //如果是编辑操作,设置页面数据 95 //如果是编辑操作,设置页面数据
96 if (unref(isUpdate)) { 96 if (unref(isUpdate)) {
97 - console.log(data.record); 97 + // console.log(data.record);
98 getTenantRoles(data.record.tenantId).then((result) => { 98 getTenantRoles(data.record.tenantId).then((result) => {
99 Reflect.set(data.record, 'roleIds', result); 99 Reflect.set(data.record, 'roleIds', result);
100 //为表单赋值 100 //为表单赋值
@@ -46,12 +46,44 @@ export const tenantFormSchema: FormSchema[] = [ @@ -46,12 +46,44 @@ export const tenantFormSchema: FormSchema[] = [
46 label: 'id', 46 label: 'id',
47 slot: 'iconSelect', 47 slot: 'iconSelect',
48 component: 'Input', 48 component: 'Input',
  49 + componentProps: {
  50 + maxLength: 36,
  51 + },
  52 + dynamicRules: () => {
  53 + return [
  54 + {
  55 + required: false,
  56 + validator: (_, value) => {
  57 + if (String(value).length > 36) {
  58 + return Promise.reject('字数不超过36个字');
  59 + }
  60 + return Promise.resolve();
  61 + },
  62 + },
  63 + ];
  64 + },
49 show: false, 65 show: false,
50 }, 66 },
51 { 67 {
52 field: 'tenantId', 68 field: 'tenantId',
53 label: 'tenantId', 69 label: 'tenantId',
54 component: 'Input', 70 component: 'Input',
  71 + componentProps: {
  72 + maxLength: 36,
  73 + },
  74 + dynamicRules: () => {
  75 + return [
  76 + {
  77 + required: false,
  78 + validator: (_, value) => {
  79 + if (String(value).length > 36) {
  80 + return Promise.reject('字数不超过36个字');
  81 + }
  82 + return Promise.resolve();
  83 + },
  84 + },
  85 + ];
  86 + },
55 show: false, 87 show: false,
56 }, 88 },
57 { 89 {
@@ -59,12 +91,32 @@ export const tenantFormSchema: FormSchema[] = [ @@ -59,12 +91,32 @@ export const tenantFormSchema: FormSchema[] = [
59 label: '租户图标: ', 91 label: '租户图标: ',
60 slot: 'iconSelect', 92 slot: 'iconSelect',
61 component: 'Input', 93 component: 'Input',
  94 + componentProps: {
  95 + maxLength: 255,
  96 + },
  97 + dynamicRules: () => {
  98 + return [
  99 + {
  100 + required: false,
  101 + validator: (_, value) => {
  102 + if (String(value).length > 255) {
  103 + return Promise.reject('字数不超过255个字');
  104 + }
  105 + return Promise.resolve();
  106 + },
  107 + },
  108 + ];
  109 + },
62 }, 110 },
63 { 111 {
64 field: 'name', 112 field: 'name',
65 label: '租户名称:', 113 label: '租户名称:',
66 required: true, 114 required: true,
67 component: 'Input', 115 component: 'Input',
  116 + componentProps: {
  117 + maxLength: 255,
  118 + placeholder: '请输入租户名称',
  119 + },
68 }, 120 },
69 { 121 {
70 field: 'roleIds', 122 field: 'roleIds',
@@ -75,7 +127,7 @@ export const tenantFormSchema: FormSchema[] = [ @@ -75,7 +127,7 @@ export const tenantFormSchema: FormSchema[] = [
75 mode: 'multiple', 127 mode: 'multiple',
76 api: getAllRoleList, 128 api: getAllRoleList,
77 params: { 129 params: {
78 - roleType: RoleEnum.ROLE_TENANT_ADMIN, 130 + roleType: RoleEnum.TENANT_ADMIN,
79 }, 131 },
80 labelField: 'name', 132 labelField: 'name',
81 valueField: 'id', 133 valueField: 'id',
@@ -106,5 +158,21 @@ export const tenantFormSchema: FormSchema[] = [ @@ -106,5 +158,21 @@ export const tenantFormSchema: FormSchema[] = [
106 label: '备注: ', 158 label: '备注: ',
107 field: 'description', 159 field: 'description',
108 component: 'InputTextArea', 160 component: 'InputTextArea',
  161 + componentProps: {
  162 + maxLength: 500,
  163 + },
  164 + dynamicRules: () => {
  165 + return [
  166 + {
  167 + required: false,
  168 + validator: (_, value) => {
  169 + if (String(value).length > 500) {
  170 + return Promise.reject('字数不超过500个字');
  171 + }
  172 + return Promise.resolve();
  173 + },
  174 + },
  175 + ];
  176 + },
109 }, 177 },
110 ]; 178 ];
@@ -8,8 +8,22 @@ export const schemas: FormSchema[] = [ @@ -8,8 +8,22 @@ export const schemas: FormSchema[] = [
8 span: 24, 8 span: 24,
9 }, 9 },
10 componentProps: { 10 componentProps: {
  11 + maxLength: 255,
11 placeholder: '请输入平台名称', 12 placeholder: '请输入平台名称',
12 }, 13 },
  14 + dynamicRules: () => {
  15 + return [
  16 + {
  17 + required: false,
  18 + validator: (_, value) => {
  19 + if (String(value).length > 255) {
  20 + return Promise.reject('字数不超过255个字');
  21 + }
  22 + return Promise.resolve();
  23 + },
  24 + },
  25 + ];
  26 + },
13 }, 27 },
14 { 28 {
15 field: 'logo', 29 field: 'logo',
@@ -9,8 +9,22 @@ export const schemas: FormSchema[] = [ @@ -9,8 +9,22 @@ export const schemas: FormSchema[] = [
9 span: 24, 9 span: 24,
10 }, 10 },
11 componentProps: { 11 componentProps: {
  12 + maxLength: 255,
12 placeholder: '请输入平台名称', 13 placeholder: '请输入平台名称',
13 }, 14 },
  15 + dynamicRules: () => {
  16 + return [
  17 + {
  18 + required: false,
  19 + validator: (_, value) => {
  20 + if (String(value).length > 255) {
  21 + return Promise.reject('字数不超过255个字');
  22 + }
  23 + return Promise.resolve();
  24 + },
  25 + },
  26 + ];
  27 + },
14 }, 28 },
15 { 29 {
16 field: 'logo', 30 field: 'logo',
@@ -55,6 +69,23 @@ export const schemas: FormSchema[] = [ @@ -55,6 +69,23 @@ export const schemas: FormSchema[] = [
55 colProps: { 69 colProps: {
56 span: 24, 70 span: 24,
57 }, 71 },
  72 + componentProps: {
  73 + maxLength: 100,
  74 + placeholder: '请输入页面底部版权信息',
  75 + },
  76 + dynamicRules: () => {
  77 + return [
  78 + {
  79 + required: false,
  80 + validator: (_, value) => {
  81 + if (String(value).length > 100) {
  82 + return Promise.reject('字数不超过100个字');
  83 + }
  84 + return Promise.resolve();
  85 + },
  86 + },
  87 + ];
  88 + },
58 }, 89 },
59 { 90 {
60 field: 'presentedOurselves', 91 field: 'presentedOurselves',
@@ -63,6 +94,23 @@ export const schemas: FormSchema[] = [ @@ -63,6 +94,23 @@ export const schemas: FormSchema[] = [
63 colProps: { 94 colProps: {
64 span: 24, 95 span: 24,
65 }, 96 },
  97 + componentProps: {
  98 + maxLength: 50,
  99 + placeholder: '请输入备案信息',
  100 + },
  101 + dynamicRules: () => {
  102 + return [
  103 + {
  104 + required: false,
  105 + validator: (_, value) => {
  106 + if (String(value).length > 50) {
  107 + return Promise.reject('字数不超过50个字');
  108 + }
  109 + return Promise.resolve();
  110 + },
  111 + },
  112 + ];
  113 + },
66 }, 114 },
67 { 115 {
68 field: 'domain', 116 field: 'domain',
@@ -71,5 +119,22 @@ export const schemas: FormSchema[] = [ @@ -71,5 +119,22 @@ export const schemas: FormSchema[] = [
71 colProps: { 119 colProps: {
72 span: 24, 120 span: 24,
73 }, 121 },
  122 + componentProps: {
  123 + maxLength: 100,
  124 + placeholder: '请输入绑定域名',
  125 + },
  126 + dynamicRules: () => {
  127 + return [
  128 + {
  129 + required: false,
  130 + validator: (_, value) => {
  131 + if (String(value).length > 100) {
  132 + return Promise.reject('字数不超过100个字');
  133 + }
  134 + return Promise.resolve();
  135 + },
  136 + },
  137 + ];
  138 + },
74 }, 139 },
75 ]; 140 ];
@@ -11,8 +11,22 @@ export const schemas: FormSchema[] = [ @@ -11,8 +11,22 @@ export const schemas: FormSchema[] = [
11 span: 24, 11 span: 24,
12 }, 12 },
13 componentProps: { 13 componentProps: {
  14 + maxLength: 100,
14 placeholder: '请输入公司名称', 15 placeholder: '请输入公司名称',
15 }, 16 },
  17 + dynamicRules: () => {
  18 + return [
  19 + {
  20 + required: false,
  21 + validator: (_, value) => {
  22 + if (String(value).length > 100) {
  23 + return Promise.reject('字数不超过100个字');
  24 + }
  25 + return Promise.resolve();
  26 + },
  27 + },
  28 + ];
  29 + },
16 }, 30 },
17 { 31 {
18 field: 'abbreviation', 32 field: 'abbreviation',
@@ -22,8 +36,22 @@ export const schemas: FormSchema[] = [ @@ -22,8 +36,22 @@ export const schemas: FormSchema[] = [
22 span: 24, 36 span: 24,
23 }, 37 },
24 componentProps: { 38 componentProps: {
  39 + maxLength: 100,
25 placeholder: '请输入公司简称', 40 placeholder: '请输入公司简称',
26 }, 41 },
  42 + dynamicRules: () => {
  43 + return [
  44 + {
  45 + required: false,
  46 + validator: (_, value) => {
  47 + if (String(value).length > 100) {
  48 + return Promise.reject('字数不超过100个字');
  49 + }
  50 + return Promise.resolve();
  51 + },
  52 + },
  53 + ];
  54 + },
27 }, 55 },
28 { 56 {
29 field: 'officialWebsite', 57 field: 'officialWebsite',
@@ -33,8 +61,22 @@ export const schemas: FormSchema[] = [ @@ -33,8 +61,22 @@ export const schemas: FormSchema[] = [
33 span: 24, 61 span: 24,
34 }, 62 },
35 componentProps: { 63 componentProps: {
  64 + maxLength: 255,
36 placeholder: '请输入公司官网', 65 placeholder: '请输入公司官网',
37 }, 66 },
  67 + dynamicRules: () => {
  68 + return [
  69 + {
  70 + required: false,
  71 + validator: (_, value) => {
  72 + if (String(value).length > 255) {
  73 + return Promise.reject('字数不超过255个字');
  74 + }
  75 + return Promise.resolve();
  76 + },
  77 + },
  78 + ];
  79 + },
38 }, 80 },
39 { 81 {
40 field: 'email', 82 field: 'email',
@@ -57,10 +99,24 @@ export const schemas: FormSchema[] = [ @@ -57,10 +99,24 @@ export const schemas: FormSchema[] = [
57 span: 24, 99 span: 24,
58 }, 100 },
59 componentProps: { 101 componentProps: {
  102 + maxLength: 500,
60 placeholder: '请输入公司简介', 103 placeholder: '请输入公司简介',
61 autoSize: { minRows: 8, maxRows: 12 }, 104 autoSize: { minRows: 8, maxRows: 12 },
62 showCount: true, 105 showCount: true,
63 }, 106 },
  107 + dynamicRules: () => {
  108 + return [
  109 + {
  110 + required: false,
  111 + validator: (_, value) => {
  112 + if (String(value).length > 500) {
  113 + return Promise.reject('字数不超过500个字');
  114 + }
  115 + return Promise.resolve();
  116 + },
  117 + },
  118 + ];
  119 + },
64 }, 120 },
65 { 121 {
66 field: 'nameCountry', 122 field: 'nameCountry',
@@ -244,8 +300,22 @@ export const schemas: FormSchema[] = [ @@ -244,8 +300,22 @@ export const schemas: FormSchema[] = [
244 span: 24, 300 span: 24,
245 }, 301 },
246 componentProps: { 302 componentProps: {
  303 + maxLength: 100,
247 placeholder: '请输入详细地址', 304 placeholder: '请输入详细地址',
248 }, 305 },
  306 + dynamicRules: () => {
  307 + return [
  308 + {
  309 + required: false,
  310 + validator: (_, value) => {
  311 + if (String(value).length > 100) {
  312 + return Promise.reject('字数不超过100个字');
  313 + }
  314 + return Promise.resolve();
  315 + },
  316 + },
  317 + ];
  318 + },
249 }, 319 },
250 320
251 { 321 {
@@ -256,8 +326,22 @@ export const schemas: FormSchema[] = [ @@ -256,8 +326,22 @@ export const schemas: FormSchema[] = [
256 span: 24, 326 span: 24,
257 }, 327 },
258 componentProps: { 328 componentProps: {
  329 + maxLength: 25,
259 placeholder: '请输入联系人', 330 placeholder: '请输入联系人',
260 }, 331 },
  332 + dynamicRules: () => {
  333 + return [
  334 + {
  335 + required: false,
  336 + validator: (_, value) => {
  337 + if (String(value).length > 25) {
  338 + return Promise.reject('字数不超过25个字');
  339 + }
  340 + return Promise.resolve();
  341 + },
  342 + },
  343 + ];
  344 + },
261 }, 345 },
262 { 346 {
263 field: 'tel', 347 field: 'tel',
@@ -275,6 +359,24 @@ export const schemas: FormSchema[] = [ @@ -275,6 +359,24 @@ export const schemas: FormSchema[] = [
275 field: 'qrcode', 359 field: 'qrcode',
276 label: '二维码', 360 label: '二维码',
277 component: 'Input', 361 component: 'Input',
  362 + componentProps: {
  363 + maxLength: 255,
  364 + placeholder: '请输入二维码',
  365 + },
  366 + dynamicRules: () => {
  367 + return [
  368 + {
  369 + required: false,
  370 + validator: (_, value) => {
  371 + if (String(value).length > 255) {
  372 + return Promise.reject('字数不超过255个字');
  373 + }
  374 + return Promise.resolve();
  375 + },
  376 + },
  377 + ];
  378 + },
  379 +
278 colProps: { 380 colProps: {
279 span: 24, 381 span: 24,
280 }, 382 },
@@ -285,5 +387,22 @@ export const schemas: FormSchema[] = [ @@ -285,5 +387,22 @@ export const schemas: FormSchema[] = [
285 label: '唯一id', 387 label: '唯一id',
286 component: 'Input', 388 component: 'Input',
287 show: false, 389 show: false,
  390 + componentProps: {
  391 + maxLength: 36,
  392 + placeholder: '请输入平台名称',
  393 + },
  394 + dynamicRules: () => {
  395 + return [
  396 + {
  397 + required: false,
  398 + validator: (_, value) => {
  399 + if (String(value).length > 36) {
  400 + return Promise.reject('字数不超过36个字');
  401 + }
  402 + return Promise.resolve();
  403 + },
  404 + },
  405 + ];
  406 + },
288 }, 407 },
289 ]; 408 ];
@@ -2,9 +2,9 @@ @@ -2,9 +2,9 @@
2 <div class="platform flex"> 2 <div class="platform flex">
3 <Card class="tab-card" :bordered="false"> 3 <Card class="tab-card" :bordered="false">
4 <Tabs v-model:activeKey="activeKey" tab-position="left"> 4 <Tabs v-model:activeKey="activeKey" tab-position="left">
5 - <TabPane key="企业信息" tab="企业信息" />  
6 - <TabPane key="平台定制" tab="平台定制" />  
7 - <TabPane key="APP定制" tab="APP定制" /> 5 + <Tabs.TabPane key="企业信息" tab="企业信息" />
  6 + <Tabs.TabPane key="平台定制" tab="平台定制" />
  7 + <Tabs.TabPane key="APP定制" tab="APP定制" />
8 </Tabs> 8 </Tabs>
9 </Card> 9 </Card>
10 10
@@ -18,7 +18,7 @@ @@ -18,7 +18,7 @@
18 </template> 18 </template>
19 19
20 <script lang="ts" setup> 20 <script lang="ts" setup>
21 - import { Tabs, TabPane, Card } from 'ant-design-vue'; 21 + import { Tabs, Card } from 'ant-design-vue';
22 import { ref } from 'vue'; 22 import { ref } from 'vue';
23 import EnterpriseInfo from './cpns/EnterpriseInfo.vue'; 23 import EnterpriseInfo from './cpns/EnterpriseInfo.vue';
24 import CVIDraw from './cpns/CVIDraw.vue'; 24 import CVIDraw from './cpns/CVIDraw.vue';
@@ -156,7 +156,7 @@ @@ -156,7 +156,7 @@
156 name: values.name, 156 name: values.name,
157 remark: values.remark, 157 remark: values.remark,
158 status: values.status, 158 status: values.status,
159 - roleType: RoleEnum.ROLE_TENANT_ADMIN, 159 + roleType: RoleEnum.TENANT_ADMIN,
160 menu: allCheckedKeys.value as string[], 160 menu: allCheckedKeys.value as string[],
161 }; 161 };
162 console.log(req, '请求参数'); 162 console.log(req, '请求参数');
@@ -67,14 +67,47 @@ export const searchFormSchema: FormSchema[] = [ @@ -67,14 +67,47 @@ export const searchFormSchema: FormSchema[] = [
67 label: '角色名称', 67 label: '角色名称',
68 component: 'Input', 68 component: 'Input',
69 colProps: { span: 8 }, 69 colProps: { span: 8 },
  70 + componentProps: {
  71 + maxLength: 255,
  72 + placeholder: '请输入角色名称',
  73 + },
  74 + dynamicRules: () => {
  75 + return [
  76 + {
  77 + required: false,
  78 + validator: (_, value) => {
  79 + if (String(value).length > 255) {
  80 + return Promise.reject('字数不超过255个字');
  81 + }
  82 + return Promise.resolve();
  83 + },
  84 + },
  85 + ];
  86 + },
70 }, 87 },
71 { 88 {
72 field: 'roleType', 89 field: 'roleType',
73 label: '', 90 label: '',
74 component: 'Input', 91 component: 'Input',
75 colProps: { span: 8 }, 92 colProps: { span: 8 },
76 - defaultValue: RoleEnum.ROLE_TENANT_ADMIN, 93 + defaultValue: RoleEnum.TENANT_ADMIN,
77 ifShow: false, 94 ifShow: false,
  95 + componentProps: {
  96 + maxLength: 20,
  97 + },
  98 + dynamicRules: () => {
  99 + return [
  100 + {
  101 + required: false,
  102 + validator: (_, value) => {
  103 + if (String(value).length > 20) {
  104 + return Promise.reject('字数不超过20个字');
  105 + }
  106 + return Promise.resolve();
  107 + },
  108 + },
  109 + ];
  110 + },
78 }, 111 },
79 { 112 {
80 field: 'status', 113 field: 'status',
@@ -96,6 +129,10 @@ export const formSchema: FormSchema[] = [ @@ -96,6 +129,10 @@ export const formSchema: FormSchema[] = [
96 label: '角色名称', 129 label: '角色名称',
97 required: true, 130 required: true,
98 component: 'Input', 131 component: 'Input',
  132 + componentProps: {
  133 + maxLength: 255,
  134 + placeholder: '请输入角色名称',
  135 + },
99 }, 136 },
100 { 137 {
101 field: 'status', 138 field: 'status',
@@ -113,11 +150,44 @@ export const formSchema: FormSchema[] = [ @@ -113,11 +150,44 @@ export const formSchema: FormSchema[] = [
113 label: '备注', 150 label: '备注',
114 field: 'remark', 151 field: 'remark',
115 component: 'InputTextArea', 152 component: 'InputTextArea',
  153 + componentProps: {
  154 + maxLength: 255,
  155 + placeholder: '请输入备注',
  156 + },
  157 + dynamicRules: () => {
  158 + return [
  159 + {
  160 + required: false,
  161 + validator: (_, value) => {
  162 + if (String(value).length > 255) {
  163 + return Promise.reject('字数不超过255个字');
  164 + }
  165 + return Promise.resolve();
  166 + },
  167 + },
  168 + ];
  169 + },
116 }, 170 },
117 { 171 {
118 label: ' ', 172 label: ' ',
119 field: 'menu', 173 field: 'menu',
120 slot: 'menu', 174 slot: 'menu',
121 component: 'Input', 175 component: 'Input',
  176 + componentProps: {
  177 + maxLength: 255,
  178 + },
  179 + dynamicRules: () => {
  180 + return [
  181 + {
  182 + required: false,
  183 + validator: (_, value) => {
  184 + if (String(value).length > 255) {
  185 + return Promise.reject('字数不超过255个字');
  186 + }
  187 + return Promise.resolve();
  188 + },
  189 + },
  190 + ];
  191 + },
122 }, 192 },
123 ]; 193 ];
@@ -37,8 +37,22 @@ export const searchFormSchema: FormSchema[] = [ @@ -37,8 +37,22 @@ export const searchFormSchema: FormSchema[] = [
37 colProps: { span: 8 }, 37 colProps: { span: 8 },
38 component: 'Input', 38 component: 'Input',
39 componentProps: { 39 componentProps: {
  40 + maxLength: 255,
40 placeholder: '请输入租户配置名称', 41 placeholder: '请输入租户配置名称',
41 }, 42 },
  43 + dynamicRules: () => {
  44 + return [
  45 + {
  46 + required: false,
  47 + validator: (_, value) => {
  48 + if (String(value).length > 255) {
  49 + return Promise.reject('字数不超过255个字');
  50 + }
  51 + return Promise.resolve();
  52 + },
  53 + },
  54 + ];
  55 + },
42 }, 56 },
43 ]; 57 ];
44 export const formSchema: FormSchema[] = [ 58 export const formSchema: FormSchema[] = [
@@ -49,7 +63,8 @@ export const formSchema: FormSchema[] = [ @@ -49,7 +63,8 @@ export const formSchema: FormSchema[] = [
49 required: true, 63 required: true,
50 component: 'Input', 64 component: 'Input',
51 componentProps: { 65 componentProps: {
52 - placeholder: '名称', 66 + maxLength: 255,
  67 + placeholder: '请输入名称',
53 }, 68 },
54 }, 69 },
55 { 70 {
@@ -70,7 +85,21 @@ export const formSchema: FormSchema[] = [ @@ -70,7 +85,21 @@ export const formSchema: FormSchema[] = [
70 colProps: { span: 24 }, 85 colProps: { span: 24 },
71 component: 'InputTextArea', 86 component: 'InputTextArea',
72 componentProps: { 87 componentProps: {
  88 + maxLength: 255,
73 placeholder: '请输入说明', 89 placeholder: '请输入说明',
74 }, 90 },
  91 + dynamicRules: () => {
  92 + return [
  93 + {
  94 + required: false,
  95 + validator: (_, value) => {
  96 + if (String(value).length > 255) {
  97 + return Promise.reject('字数不超过255个字');
  98 + }
  99 + return Promise.resolve();
  100 + },
  101 + },
  102 + ];
  103 + },
75 }, 104 },
76 ]; 105 ];
1 import { FormSchema } from '/@/components/Table'; 1 import { FormSchema } from '/@/components/Table';
2 -// import { numberRule } from '/@/utils/rules'; 2 +import { numberRule } from '/@/utils/rules';
3 3
4 export const formSchema: FormSchema[] = [ 4 export const formSchema: FormSchema[] = [
5 { 5 {
@@ -23,6 +23,7 @@ export const formSchema: FormSchema[] = [ @@ -23,6 +23,7 @@ export const formSchema: FormSchema[] = [
23 componentProps: { 23 componentProps: {
24 placeholder: '请输入最大设备数(请输入数字)', 24 placeholder: '请输入最大设备数(请输入数字)',
25 }, 25 },
  26 + rules: numberRule,
26 }, 27 },
27 { 28 {
28 field: 'maxAssets', 29 field: 'maxAssets',
@@ -34,6 +35,7 @@ export const formSchema: FormSchema[] = [ @@ -34,6 +35,7 @@ export const formSchema: FormSchema[] = [
34 componentProps: { 35 componentProps: {
35 placeholder: '请输入最大资产(请输入数字)', 36 placeholder: '请输入最大资产(请输入数字)',
36 }, 37 },
  38 + rules: numberRule,
37 }, 39 },
38 { 40 {
39 field: 'maxCustomers', 41 field: 'maxCustomers',
@@ -45,6 +47,7 @@ export const formSchema: FormSchema[] = [ @@ -45,6 +47,7 @@ export const formSchema: FormSchema[] = [
45 componentProps: { 47 componentProps: {
46 placeholder: '请输入最大客户数(请输入数字)', 48 placeholder: '请输入最大客户数(请输入数字)',
47 }, 49 },
  50 + rules: numberRule,
48 }, 51 },
49 { 52 {
50 field: 'maxUsers', 53 field: 'maxUsers',
@@ -56,6 +59,7 @@ export const formSchema: FormSchema[] = [ @@ -56,6 +59,7 @@ export const formSchema: FormSchema[] = [
56 componentProps: { 59 componentProps: {
57 placeholder: '请输入最大用户数(请输入数字)', 60 placeholder: '请输入最大用户数(请输入数字)',
58 }, 61 },
  62 + rules: numberRule,
59 }, 63 },
60 { 64 {
61 field: 'maxDashboards', 65 field: 'maxDashboards',
@@ -67,6 +71,7 @@ export const formSchema: FormSchema[] = [ @@ -67,6 +71,7 @@ export const formSchema: FormSchema[] = [
67 componentProps: { 71 componentProps: {
68 placeholder: '请输入仪表板的最大数量(请输入数字)', 72 placeholder: '请输入仪表板的最大数量(请输入数字)',
69 }, 73 },
  74 + rules: numberRule,
70 }, 75 },
71 { 76 {
72 field: 'maxRuleChains', 77 field: 'maxRuleChains',
@@ -78,6 +83,7 @@ export const formSchema: FormSchema[] = [ @@ -78,6 +83,7 @@ export const formSchema: FormSchema[] = [
78 componentProps: { 83 componentProps: {
79 placeholder: '请输入最大规则链数(请输入数字)', 84 placeholder: '请输入最大规则链数(请输入数字)',
80 }, 85 },
  86 + rules: numberRule,
81 }, 87 },
82 { 88 {
83 field: 'maxResourcesInBytes', 89 field: 'maxResourcesInBytes',
@@ -89,6 +95,7 @@ export const formSchema: FormSchema[] = [ @@ -89,6 +95,7 @@ export const formSchema: FormSchema[] = [
89 componentProps: { 95 componentProps: {
90 placeholder: '请输入(请输入数字)', 96 placeholder: '请输入(请输入数字)',
91 }, 97 },
  98 + rules: numberRule,
92 }, 99 },
93 { 100 {
94 field: 'maxOtaPackagesInBytes', 101 field: 'maxOtaPackagesInBytes',
@@ -100,6 +107,7 @@ export const formSchema: FormSchema[] = [ @@ -100,6 +107,7 @@ export const formSchema: FormSchema[] = [
100 componentProps: { 107 componentProps: {
101 placeholder: '请输入(请输入数字)', 108 placeholder: '请输入(请输入数字)',
102 }, 109 },
  110 + rules: numberRule,
103 }, 111 },
104 { 112 {
105 field: 'maxTransportMessages', 113 field: 'maxTransportMessages',
@@ -111,6 +119,7 @@ export const formSchema: FormSchema[] = [ @@ -111,6 +119,7 @@ export const formSchema: FormSchema[] = [
111 componentProps: { 119 componentProps: {
112 placeholder: '请输入最大传输消息数(请输入数字)', 120 placeholder: '请输入最大传输消息数(请输入数字)',
113 }, 121 },
  122 + rules: numberRule,
114 }, 123 },
115 { 124 {
116 field: 'maxTransportDataPoints', 125 field: 'maxTransportDataPoints',
@@ -122,6 +131,7 @@ export const formSchema: FormSchema[] = [ @@ -122,6 +131,7 @@ export const formSchema: FormSchema[] = [
122 componentProps: { 131 componentProps: {
123 placeholder: '请输入传输数据点的最大数量(请输入数字)', 132 placeholder: '请输入传输数据点的最大数量(请输入数字)',
124 }, 133 },
  134 + rules: numberRule,
125 }, 135 },
126 { 136 {
127 field: 'maxREExecutions', 137 field: 'maxREExecutions',
@@ -133,6 +143,7 @@ export const formSchema: FormSchema[] = [ @@ -133,6 +143,7 @@ export const formSchema: FormSchema[] = [
133 componentProps: { 143 componentProps: {
134 placeholder: '请输入最大规则引擎数(请输入数字)', 144 placeholder: '请输入最大规则引擎数(请输入数字)',
135 }, 145 },
  146 + rules: numberRule,
136 }, 147 },
137 148
138 { 149 {
@@ -145,6 +156,7 @@ export const formSchema: FormSchema[] = [ @@ -145,6 +156,7 @@ export const formSchema: FormSchema[] = [
145 componentProps: { 156 componentProps: {
146 placeholder: '请输入最大JavaScript执行数(请输入数字)', 157 placeholder: '请输入最大JavaScript执行数(请输入数字)',
147 }, 158 },
  159 + rules: numberRule,
148 }, 160 },
149 { 161 {
150 field: 'maxDPStorageDays', 162 field: 'maxDPStorageDays',
@@ -156,6 +168,7 @@ export const formSchema: FormSchema[] = [ @@ -156,6 +168,7 @@ export const formSchema: FormSchema[] = [
156 componentProps: { 168 componentProps: {
157 placeholder: '请输入最大日存储数据点数(请输入数字)', 169 placeholder: '请输入最大日存储数据点数(请输入数字)',
158 }, 170 },
  171 + rules: numberRule,
159 }, 172 },
160 { 173 {
161 field: 'defaultStorageTtlDays', 174 field: 'defaultStorageTtlDays',
@@ -167,6 +180,7 @@ export const formSchema: FormSchema[] = [ @@ -167,6 +180,7 @@ export const formSchema: FormSchema[] = [
167 componentProps: { 180 componentProps: {
168 placeholder: '请输入默认存储 TTL 天数(请输入数字)', 181 placeholder: '请输入默认存储 TTL 天数(请输入数字)',
169 }, 182 },
  183 + rules: numberRule,
170 }, 184 },
171 { 185 {
172 field: 'alarmsTtlDays', 186 field: 'alarmsTtlDays',
@@ -178,6 +192,7 @@ export const formSchema: FormSchema[] = [ @@ -178,6 +192,7 @@ export const formSchema: FormSchema[] = [
178 componentProps: { 192 componentProps: {
179 placeholder: '请输入Alams TTL days(请输入数字)', 193 placeholder: '请输入Alams TTL days(请输入数字)',
180 }, 194 },
  195 + rules: numberRule,
181 }, 196 },
182 { 197 {
183 field: 'rpcTtlDays', 198 field: 'rpcTtlDays',
@@ -189,6 +204,7 @@ export const formSchema: FormSchema[] = [ @@ -189,6 +204,7 @@ export const formSchema: FormSchema[] = [
189 componentProps: { 204 componentProps: {
190 placeholder: '请输入RPC TTL days(请输入数字)', 205 placeholder: '请输入RPC TTL days(请输入数字)',
191 }, 206 },
  207 + rules: numberRule,
192 }, 208 },
193 { 209 {
194 field: 'maxRuleNodeExecutionsPerMessage', 210 field: 'maxRuleNodeExecutionsPerMessage',
@@ -200,6 +216,7 @@ export const formSchema: FormSchema[] = [ @@ -200,6 +216,7 @@ export const formSchema: FormSchema[] = [
200 componentProps: { 216 componentProps: {
201 placeholder: '请输入每条消息的最大规则节点执行数(请输入数字)', 217 placeholder: '请输入每条消息的最大规则节点执行数(请输入数字)',
202 }, 218 },
  219 + rules: numberRule,
203 }, 220 },
204 { 221 {
205 field: 'maxEmails', 222 field: 'maxEmails',
@@ -210,6 +227,7 @@ export const formSchema: FormSchema[] = [ @@ -210,6 +227,7 @@ export const formSchema: FormSchema[] = [
210 componentProps: { 227 componentProps: {
211 placeholder: '请输入发送的最大电子邮件数(请输入数字)', 228 placeholder: '请输入发送的最大电子邮件数(请输入数字)',
212 }, 229 },
  230 + rules: numberRule,
213 }, 231 },
214 { 232 {
215 field: 'maxSms', 233 field: 'maxSms',
@@ -221,6 +239,7 @@ export const formSchema: FormSchema[] = [ @@ -221,6 +239,7 @@ export const formSchema: FormSchema[] = [
221 componentProps: { 239 componentProps: {
222 placeholder: '请输入发送的最大短信数(请输入数字)', 240 placeholder: '请输入发送的最大短信数(请输入数字)',
223 }, 241 },
  242 + rules: numberRule,
224 }, 243 },
225 { 244 {
226 field: 'maxCreatedAlarms', 245 field: 'maxCreatedAlarms',
@@ -232,6 +251,7 @@ export const formSchema: FormSchema[] = [ @@ -232,6 +251,7 @@ export const formSchema: FormSchema[] = [
232 componentProps: { 251 componentProps: {
233 placeholder: '请输入maxCreatedAlarms(请输入数字)', 252 placeholder: '请输入maxCreatedAlarms(请输入数字)',
234 }, 253 },
  254 + rules: numberRule,
235 }, 255 },
236 { 256 {
237 field: 'transportTenantMsgRateLimit', 257 field: 'transportTenantMsgRateLimit',