Commit a044a6684ac935ddf8a572d69edd709a2392ea6b

Authored by fengistao
2 parents f4a6af58 4c14f772

feat:新增设备配置,已调通新增和详情和分页,待调通删除

Showing 43 changed files with 576 additions and 577 deletions
@@ -86,3 +86,10 @@ export const getDeviceToken = () => { @@ -86,3 +86,10 @@ export const getDeviceToken = () => {
86 url: '/common', 86 url: '/common',
87 }); 87 });
88 }; 88 };
  89 +
  90 +// 查询设备详情
  91 +export const getDeviceDetail = (id: string) => {
  92 + return defHttp.get({
  93 + url: DeviceManagerApi.DEVICE_URL + `/${id}`,
  94 + });
  95 +};
@@ -81,9 +81,9 @@ export const setMessageTemplateStatus = ( @@ -81,9 +81,9 @@ export const setMessageTemplateStatus = (
81 defHttp.put<MessageConfigResultModel>({ 81 defHttp.put<MessageConfigResultModel>({
82 url: MessageTemplateApi.TEMPLATE_URL, 82 url: MessageTemplateApi.TEMPLATE_URL,
83 data: { 83 data: {
84 - id: id,  
85 - status: status,  
86 - templatePurpose: templatePurpose,  
87 - messageType: messageType, 84 + id,
  85 + status,
  86 + templatePurpose,
  87 + messageType,
88 }, 88 },
89 }); 89 });
@@ -10,5 +10,5 @@ enum GroupApi { @@ -10,5 +10,5 @@ enum GroupApi {
10 */ 10 */
11 export const findCurrentUserGroups = () => 11 export const findCurrentUserGroups = () =>
12 defHttp.get<GroupListResultModel>({ 12 defHttp.get<GroupListResultModel>({
13 - url: GroupApi.BASE_URL + '/me/organizations', 13 + url: GroupApi.BASE_URL + '/me/list',
14 }); 14 });
  1 +// 全局按需注册组件
1 import type { App } from 'vue'; 2 import type { App } from 'vue';
2 -// import { Icon } from './Icon';  
3 import { Button } from './Button'; 3 import { Button } from './Button';
4 import { 4 import {
5 // Need 5 // Need
  1 +// 将后端返回的字段转换成树组件的ApiSelectTree的对应字段
1 export const copyTransFun = (arr: any[]) => { 2 export const copyTransFun = (arr: any[]) => {
2 arr.forEach((item) => { 3 arr.forEach((item) => {
3 if (item.name) { 4 if (item.name) {
@@ -15,3 +16,22 @@ export const copyTransFun = (arr: any[]) => { @@ -15,3 +16,22 @@ export const copyTransFun = (arr: any[]) => {
15 } 16 }
16 }); 17 });
17 }; 18 };
  19 +
  20 +// 将后端返回的字段转换成树组件的Tree的对应字段
  21 +export const copyTransTreeFun = (arr: any[]) => {
  22 + arr.forEach((item) => {
  23 + if (item.name) {
  24 + item.title = item.name;
  25 + delete item.name;
  26 + }
  27 + if (item.id) {
  28 + item.key = item.id;
  29 + delete item.id;
  30 + }
  31 + if (item.children) {
  32 + if (item.children.length) {
  33 + copyTransTreeFun(item.children);
  34 + }
  35 + }
  36 + });
  37 +};
@@ -46,8 +46,8 @@ @@ -46,8 +46,8 @@
46 46
47 async function handleSubmit() { 47 async function handleSubmit() {
48 try { 48 try {
49 - const values = await validate();  
50 const { createMessage } = useMessage(); 49 const { createMessage } = useMessage();
  50 + const values = await validate();
51 setDrawerProps({ confirmLoading: true }); 51 setDrawerProps({ confirmLoading: true });
52 let saveMessage = '添加成功'; 52 let saveMessage = '添加成功';
53 let updateMessage = '修改成功'; 53 let updateMessage = '修改成功';
@@ -34,11 +34,7 @@ export const columns: BasicColumn[] = [ @@ -34,11 +34,7 @@ export const columns: BasicColumn[] = [
34 dataIndex: 'remark', 34 dataIndex: 'remark',
35 width: 120, 35 width: 120,
36 }, 36 },
37 - {  
38 - title: '添加人',  
39 - dataIndex: 'addPeople',  
40 - width: 180,  
41 - }, 37 +
42 { 38 {
43 title: '添加时间', 39 title: '添加时间',
44 dataIndex: 'createTime', 40 dataIndex: 'createTime',
@@ -90,19 +86,47 @@ export const formSchema: FormSchema[] = [ @@ -90,19 +86,47 @@ export const formSchema: FormSchema[] = [
90 { 86 {
91 field: 'phone', 87 field: 'phone',
92 label: '手机号码', 88 label: '手机号码',
93 - required: true,  
94 component: 'Input', 89 component: 'Input',
95 componentProps: { 90 componentProps: {
96 placeholder: '请输入手机号码', 91 placeholder: '请输入手机号码',
97 }, 92 },
  93 + rules: [
  94 + {
  95 + required: true,
  96 + validator: (_, value: string) => {
  97 + const reg = /^[1][3,4,5,6,7,8,9][0-9]{9}$/;
  98 + if (value === '') {
  99 + return Promise.reject('请输入手机号码');
  100 + } else if (!reg.test(value)) {
  101 + return Promise.reject('请输入正确的手机号码');
  102 + }
  103 + return Promise.resolve();
  104 + },
  105 + trigger: 'blur',
  106 + },
  107 + ],
98 }, 108 },
99 { 109 {
100 field: 'email', 110 field: 'email',
101 - label: '邮箱', 111 + label: '电子邮箱',
102 component: 'Input', 112 component: 'Input',
103 componentProps: { 113 componentProps: {
104 - placeholder: '请输入邮箱', 114 + placeholder: '请输入电子邮箱',
105 }, 115 },
  116 + rules: [
  117 + {
  118 + validator: (_, value: string) => {
  119 + const reg = /^[a-zA-Z0-9_.-]+@[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)*\.[a-zA-Z0-9]{2,6}$/;
  120 + if (value === '') {
  121 + return Promise.resolve();
  122 + } else if (!reg.test(value)) {
  123 + return Promise.reject('请输入正确的电子邮箱');
  124 + }
  125 + return Promise.resolve();
  126 + },
  127 + trigger: 'blur',
  128 + },
  129 + ],
106 }, 130 },
107 { 131 {
108 field: 'wechat', 132 field: 'wechat',
@@ -113,14 +137,6 @@ export const formSchema: FormSchema[] = [ @@ -113,14 +137,6 @@ export const formSchema: FormSchema[] = [
113 }, 137 },
114 }, 138 },
115 { 139 {
116 - field: 'addPeople',  
117 - label: '添加人',  
118 - component: 'Input',  
119 - componentProps: {  
120 - placeholder: '请输入添加人',  
121 - },  
122 - },  
123 - {  
124 field: 'remark', 140 field: 'remark',
125 label: '备注', 141 label: '备注',
126 component: 'InputTextArea', 142 component: 'InputTextArea',
1 <template> 1 <template>
2 - <PageWrapper dense contentFullHeight fixedHeight contentClass="flex">  
3 - <OrganizationIdTree class="w-1/4 xl:w-1/5" @select="handleSelect" />  
4 - <BasicTable @register="registerTable" :searchInfo="searchInfo" class="w-3/4 xl:w-4/5">  
5 - <template #toolbar>  
6 - <a-button type="primary" @click="handleCreateOrEdit(null)"> 新增联系人 </a-button>  
7 - <a-button  
8 - type="primary"  
9 - color="error"  
10 - @click="handleDeleteOrBatchDelete(null)"  
11 - :disabled="hasBatchDelete"  
12 - >  
13 - 批量删除  
14 - </a-button>  
15 - </template>  
16 - <template #action="{ record }">  
17 - <TableAction  
18 - :actions="[  
19 - {  
20 - label: '编辑',  
21 - icon: 'clarity:note-edit-line',  
22 - onClick: handleCreateOrEdit.bind(null, record),  
23 - },  
24 - {  
25 - label: '删除',  
26 - icon: 'ant-design:delete-outlined',  
27 - color: 'error',  
28 - popConfirm: {  
29 - title: '是否确认删除',  
30 - confirm: handleDeleteOrBatchDelete.bind(null, record), 2 + <div>
  3 + <PageWrapper dense contentFullHeight fixedHeight contentClass="flex">
  4 + <OrganizationIdTree class="w-1/4 xl:w-1/5" @select="handleSelect" />
  5 + <BasicTable @register="registerTable" :searchInfo="searchInfo" class="w-3/4 xl:w-4/5">
  6 + <template #toolbar>
  7 + <a-button type="primary" @click="handleCreateOrEdit(null)"> 新增联系人 </a-button>
  8 + <a-button
  9 + type="primary"
  10 + color="error"
  11 + @click="handleDeleteOrBatchDelete(null)"
  12 + :disabled="hasBatchDelete"
  13 + >
  14 + 批量删除
  15 + </a-button>
  16 + </template>
  17 + <template #action="{ record }">
  18 + <TableAction
  19 + :actions="[
  20 + {
  21 + label: '编辑',
  22 + icon: 'clarity:note-edit-line',
  23 + onClick: handleCreateOrEdit.bind(null, record),
31 }, 24 },
32 - },  
33 - ]"  
34 - />  
35 - </template>  
36 - </BasicTable>  
37 - </PageWrapper>  
38 - <ContactDrawer @register="registerDrawer" @success="handleSuccess" /> 25 + {
  26 + label: '删除',
  27 + icon: 'ant-design:delete-outlined',
  28 + color: 'error',
  29 + popConfirm: {
  30 + title: '是否确认删除',
  31 + confirm: handleDeleteOrBatchDelete.bind(null, record),
  32 + },
  33 + },
  34 + ]"
  35 + />
  36 + </template>
  37 + </BasicTable>
  38 + </PageWrapper>
  39 + <ContactDrawer @register="registerDrawer" @success="handleSuccess" />
  40 + </div>
39 </template> 41 </template>
40 42
41 <script lang="ts"> 43 <script lang="ts">
@@ -97,7 +99,7 @@ @@ -97,7 +99,7 @@
97 reload(); 99 reload();
98 }; 100 };
99 // 新增或编辑 101 // 新增或编辑
100 - const handleCreateOrEdit = (record: Recordable) => { 102 + const handleCreateOrEdit = (record: Recordable | null) => {
101 if (record) { 103 if (record) {
102 openDrawer(true, { 104 openDrawer(true, {
103 isUpdate: true, 105 isUpdate: true,
@@ -95,4 +95,10 @@ export const step1Schemas: FormSchema[] = [ @@ -95,4 +95,10 @@ export const step1Schemas: FormSchema[] = [
95 component: 'Input', 95 component: 'Input',
96 show: false, 96 show: false,
97 }, 97 },
  98 + {
  99 + field: 'tbDeviceId',
  100 + label: 'tbDeviceId',
  101 + component: 'Input',
  102 + show: false,
  103 + },
98 ]; 104 ];
1 <template> 1 <template>
2 - <!-- <BasicModal v-bind="$attrs" width="55rem" @register="register" centered /> -->  
3 <BasicDrawer 2 <BasicDrawer
4 v-bind="$attrs" 3 v-bind="$attrs"
5 isDetail 4 isDetail
6 - :title="deviceInfo?.name"  
7 @register="register" 5 @register="register"
8 :destroyOnClose="true" 6 :destroyOnClose="true"
9 @close="closeDrawer" 7 @close="closeDrawer"
10 > 8 >
11 <Tabs v-model:activeKey="activeKey" :size="size" type="card"> 9 <Tabs v-model:activeKey="activeKey" :size="size" type="card">
12 <TabPane key="1" tab="详情" 10 <TabPane key="1" tab="详情"
13 - ><Detail :deviceDetail="deviceInfo" ref="deviceDetailRef" 11 + ><Detail ref="deviceDetailRef" :deviceDetail="deviceDetail"
  12 + /></TabPane>
  13 + <TabPane key="2" tab="实时数据" v-if="deviceDetail?.deviceType !== 'GATEWAY'"
  14 + ><RealTimeData
14 /></TabPane> 15 /></TabPane>
15 - <TabPane key="2" tab="实时数据"><RealTimeData /></TabPane>  
16 <TabPane key="3" tab="告警"><Alarm /></TabPane> 16 <TabPane key="3" tab="告警"><Alarm /></TabPane>
17 - <TabPane key="4" tab="子设备"><ChildDevice /></TabPane> 17 + <TabPane key="4" tab="子设备" v-if="deviceDetail?.deviceType === 'SENSOR'"
  18 + ><ChildDevice
  19 + /></TabPane>
18 </Tabs> 20 </Tabs>
19 </BasicDrawer> 21 </BasicDrawer>
20 </template> 22 </template>
@@ -27,6 +29,7 @@ @@ -27,6 +29,7 @@
27 import RealTimeData from '../tabs/RealTimeData.vue'; 29 import RealTimeData from '../tabs/RealTimeData.vue';
28 import Alarm from '../tabs/Alarm.vue'; 30 import Alarm from '../tabs/Alarm.vue';
29 import ChildDevice from '../tabs/ChildDevice.vue'; 31 import ChildDevice from '../tabs/ChildDevice.vue';
  32 + import { getDeviceDetail } from '/@/api/device/deviceManager';
30 export default defineComponent({ 33 export default defineComponent({
31 name: 'DeviceModal', 34 name: 'DeviceModal',
32 components: { 35 components: {
@@ -42,13 +45,15 @@ @@ -42,13 +45,15 @@
42 setup() { 45 setup() {
43 const activeKey = ref('1'); 46 const activeKey = ref('1');
44 const size = ref('small'); 47 const size = ref('small');
45 - const deviceInfo = ref({});  
46 const deviceDetailRef = ref(); 48 const deviceDetailRef = ref();
  49 + const deviceDetail = ref({});
47 // 详情回显 50 // 详情回显
48 - const [register] = useDrawerInner((data) => {  
49 - deviceInfo.value = data.record;  
50 - const { latitude, longitude, address } = data.record.deviceInfo;  
51 - deviceDetailRef.value.initMap(longitude, latitude, address); 51 + const [register] = useDrawerInner(async (data) => {
  52 + const { id } = data;
  53 + const res = await getDeviceDetail(id);
  54 + deviceDetail.value = res;
  55 + // const { latitude, longitude, address } = data.record.deviceInfo;
  56 + // deviceDetailRef.value.initMap(longitude, latitude, address);
52 }); 57 });
53 58
54 const closeDrawer = () => { 59 const closeDrawer = () => {
@@ -58,9 +63,9 @@ @@ -58,9 +63,9 @@
58 return { 63 return {
59 size, 64 size,
60 activeKey, 65 activeKey,
61 - deviceInfo,  
62 register, 66 register,
63 closeDrawer, 67 closeDrawer,
  68 + deviceDetail,
64 deviceDetailRef, 69 deviceDetailRef,
65 }; 70 };
66 }, 71 },
@@ -9,10 +9,10 @@ @@ -9,10 +9,10 @@
9 centered 9 centered
10 > 10 >
11 <div class="step-form-form"> 11 <div class="step-form-form">
12 - <a-steps :current="current">  
13 - <a-step title="填写设备信息" />  
14 - <a-step title="添加设备凭证" />  
15 - </a-steps> 12 + <Steps :current="current">
  13 + <Step title="填写设备信息" />
  14 + <Step title="添加设备凭证" />
  15 + </Steps>
16 </div> 16 </div>
17 <div class="mt-5"> 17 <div class="mt-5">
18 <DeviceStep1 18 <DeviceStep1
@@ -36,7 +36,7 @@ @@ -36,7 +36,7 @@
36 import { createOrEditDevice, getDeviceToken } from '/@/api/device/deviceManager'; 36 import { createOrEditDevice, getDeviceToken } from '/@/api/device/deviceManager';
37 import DeviceStep1 from '../step/DeviceStep1.vue'; 37 import DeviceStep1 from '../step/DeviceStep1.vue';
38 import DeviceStep2 from '../step/DeviceStep2.vue'; 38 import DeviceStep2 from '../step/DeviceStep2.vue';
39 - import { Steps } from 'ant-design-vue'; 39 + import { Steps, Step } from 'ant-design-vue';
40 import { useMessage } from '/@/hooks/web/useMessage'; 40 import { useMessage } from '/@/hooks/web/useMessage';
41 41
42 export default defineComponent({ 42 export default defineComponent({
@@ -45,8 +45,8 @@ @@ -45,8 +45,8 @@
45 BasicModal, 45 BasicModal,
46 DeviceStep1, 46 DeviceStep1,
47 DeviceStep2, 47 DeviceStep2,
48 - [Steps.name]: Steps,  
49 - [Steps.Step.name]: Steps.Step, 48 + Steps,
  49 + Step,
50 }, 50 },
51 props: { 51 props: {
52 userData: { type: Object }, 52 userData: { type: Object },
@@ -96,6 +96,7 @@ @@ -96,6 +96,7 @@
96 function handleCancel() { 96 function handleCancel() {
97 current.value = 0; 97 current.value = 0;
98 DeviceStep1Ref?.value?.resetFields(); 98 DeviceStep1Ref?.value?.resetFields();
  99 + DeviceStep1Ref.value?.parentResetDevicePic();
99 DeviceStep2Ref?.value?.resetFields(); 100 DeviceStep2Ref?.value?.resetFields();
100 } 101 }
101 // 提交 102 // 提交
@@ -104,23 +105,17 @@ @@ -104,23 +105,17 @@
104 // 验证 105 // 验证
105 const valid = await DeviceStep1Ref.value?.parentValidate(); 106 const valid = await DeviceStep1Ref.value?.parentValidate();
106 if (!valid) return; 107 if (!valid) return;
107 -  
108 stepState.value = DeviceStep1Ref?.value?.parentGetFieldsValue(); 108 stepState.value = DeviceStep1Ref?.value?.parentGetFieldsValue();
109 - handleCancel();  
110 - closeModal();  
111 } else { 109 } else {
112 if (!DeviceStep2Ref?.value?.creaentialsPassword.isCreaentials) { 110 if (!DeviceStep2Ref?.value?.creaentialsPassword.isCreaentials) {
113 const valid = await DeviceStep2Ref?.value?.validate(); 111 const valid = await DeviceStep2Ref?.value?.validate();
114 // 第二页验证通过情况 112 // 第二页验证通过情况
115 if (!valid) return; 113 if (!valid) return;
116 - handleCancel();  
117 - closeModal();  
118 } 114 }
119 } 115 }
120 - // 验证成功 --掉新增或者编辑接口  
121 - const msg = computed(() => (stepState.value.id ? '更新设备成功' : '新增设备成功'));  
122 - console.log(stepState);  
123 - if (stepState.value.id) { 116 + // 验证成功 --调-- 新增或者编辑接口
  117 + const msg = computed(() => (unref(stepState).id ? '更新设备成功' : '新增设备成功'));
  118 + if (unref(stepState).id) {
124 const editData = { 119 const editData = {
125 ...stepState.value, 120 ...stepState.value,
126 deviceInfo: { 121 deviceInfo: {
@@ -131,7 +126,7 @@ @@ -131,7 +126,7 @@
131 await createOrEditDevice(editData); 126 await createOrEditDevice(editData);
132 } else { 127 } else {
133 let deviceToken = await getDeviceToken(); 128 let deviceToken = await getDeviceToken();
134 - // 需要携带唯一的设备token 129 + // 创建需要携带唯一的设备token
135 const createData = { 130 const createData = {
136 ...stepState.value, 131 ...stepState.value,
137 deviceToken, 132 deviceToken,
@@ -140,10 +135,11 @@ @@ -140,10 +135,11 @@
140 ...DeviceStep1Ref.value?.positionState, 135 ...DeviceStep1Ref.value?.positionState,
141 }, 136 },
142 }; 137 };
143 -  
144 await createOrEditDevice(createData); 138 await createOrEditDevice(createData);
145 } 139 }
146 createMessage.success(msg.value); 140 createMessage.success(msg.value);
  141 + handleCancel();
  142 + closeModal();
147 emit('reload'); 143 emit('reload');
148 } 144 }
149 return { 145 return {
@@ -2,24 +2,19 @@ @@ -2,24 +2,19 @@
2 <div class="tabs-detail"> 2 <div class="tabs-detail">
3 <div v-if="deviceDetail?.deviceInfo?.avatar"> 3 <div v-if="deviceDetail?.deviceInfo?.avatar">
4 <p>设备图片</p> 4 <p>设备图片</p>
5 - <Image :src="deviceDetail.deviceInfo.avatar" :width="100" /> 5 + <Image :src="deviceDetail?.deviceInfo?.avatar" />
6 </div> 6 </div>
7 <div> 7 <div>
8 <p>设备信息</p> 8 <p>设备信息</p>
9 - <Table  
10 - bordered  
11 - :columns="columns"  
12 - :data-source="[{ ...deviceDetail, key: 'name' }]"  
13 - :pagination="false"  
14 - /> 9 + <Table bordered :columns="columns" :data-source="[deviceDetail]" :pagination="false" />
15 </div> 10 </div>
16 <div v-if="deviceDetail?.deviceInfo?.address"> 11 <div v-if="deviceDetail?.deviceInfo?.address">
17 <p>设备位置</p> 12 <p>设备位置</p>
18 <div ref="wrapRef" style="height: 400px; width: 90%" class="ml-6"></div> 13 <div ref="wrapRef" style="height: 400px; width: 90%" class="ml-6"></div>
19 </div> 14 </div>
20 <div class="mt-4"> 15 <div class="mt-4">
21 - <a-button type="primary" class="mr-4" @click="copyDeviceId">复制设备ID</a-button>  
22 - <a-button type="primary" @click="copyToken">复制访问令牌</a-button> 16 + <a-button type="primary" class="mr-4" @click="copyTbDeviceId">复制设备ID</a-button>
  17 + <a-button type="primary" @click="copyDeviceToken">复制访问令牌</a-button>
23 </div> 18 </div>
24 </div> 19 </div>
25 </template> 20 </template>
@@ -42,6 +37,7 @@ @@ -42,6 +37,7 @@
42 }, 37 },
43 }, 38 },
44 setup(props) { 39 setup(props) {
  40 + // 地图
45 const BAI_DU_MAP_URL = 41 const BAI_DU_MAP_URL =
46 'https://api.map.baidu.com/getscript?v=3.0&ak=7uOPPyAHn2Y2ZryeQqHtcRqtIY374vKa'; 42 'https://api.map.baidu.com/getscript?v=3.0&ak=7uOPPyAHn2Y2ZryeQqHtcRqtIY374vKa';
47 const wrapRef = ref<HTMLDivElement | null>(null); 43 const wrapRef = ref<HTMLDivElement | null>(null);
@@ -83,13 +79,13 @@ @@ -83,13 +79,13 @@
83 } 79 }
84 const { createMessage } = useMessage(); 80 const { createMessage } = useMessage();
85 const { clipboardRef } = useCopyToClipboard(); 81 const { clipboardRef } = useCopyToClipboard();
86 - const copyDeviceId = () => {  
87 - clipboardRef.value = props.deviceDetail.id; 82 + const copyTbDeviceId = () => {
  83 + clipboardRef.value = props.deviceDetail.tbDeviceId;
88 if (unref(clipboardRef)) { 84 if (unref(clipboardRef)) {
89 createMessage.success('复制成功~'); 85 createMessage.success('复制成功~');
90 } 86 }
91 }; 87 };
92 - const copyToken = () => { 88 + const copyDeviceToken = () => {
93 clipboardRef.value = props.deviceDetail.deviceToken; 89 clipboardRef.value = props.deviceDetail.deviceToken;
94 if (unref(clipboardRef)) { 90 if (unref(clipboardRef)) {
95 createMessage.success('复制成功~'); 91 createMessage.success('复制成功~');
@@ -99,8 +95,8 @@ @@ -99,8 +95,8 @@
99 return { 95 return {
100 columns, 96 columns,
101 wrapRef, 97 wrapRef,
102 - copyDeviceId,  
103 - copyToken, 98 + copyTbDeviceId,
  99 + copyDeviceToken,
104 initMap, 100 initMap,
105 }; 101 };
106 }, 102 },
1 <template> 1 <template>
2 - <PageWrapper dense contentFullHeight fixedHeight contentClass="flex">  
3 - <OrganizationIdTree class="w-1/6 xl:w-1/5" @select="handleSelect" />  
4 - <BasicTable @register="registerTable" class="w-5/6 xl:w-4/5">  
5 - <template #toolbar>  
6 - <a-button type="primary" @click="handleCreate"> 新增设备 </a-button>  
7 - </template>  
8 - <template #deviceProfile="{ record }">  
9 - <!-- <a-button type="link" class="ml-2" @click="goDeviceProfile">  
10 - {{ record.deviceProfile.name }}  
11 - </a-button> -->  
12 - </template>  
13 - <template #organizationId="{ record }">  
14 - {{ record.organizationDTO.name }}  
15 - </template>  
16 - <template #deviceType="{ record }">  
17 - <Tag color="success" class="ml-2">  
18 - {{  
19 - record.deviceType === DeviceTypeEnum.GATEWAY  
20 - ? '网关设备'  
21 - : record.deviceType === DeviceTypeEnum.DIRECT_CONNECTION  
22 - ? '直连设备'  
23 - : '网关子设备'  
24 - }}  
25 - </Tag>  
26 - </template>  
27 - <template #deviceState="{ record }">  
28 - <Tag  
29 - :color="  
30 - record.deviceState == DeviceState.INACTIVE  
31 - ? 'warning'  
32 - : record.deviceState == DeviceState.ONLINE  
33 - ? 'success'  
34 - : 'error'  
35 - "  
36 - class="ml-2"  
37 - >  
38 - {{  
39 - record.deviceState == DeviceState.INACTIVE  
40 - ? '待激活'  
41 - : record.deviceState == DeviceState.ONLINE  
42 - ? '在线'  
43 - : '离线'  
44 - }}  
45 - </Tag>  
46 - </template>  
47 - <template #action="{ record }">  
48 - <TableAction  
49 - :actions="[  
50 - {  
51 - label: '详情',  
52 - icon: 'ant-design:eye-outlined',  
53 - onClick: handleDetail.bind(null, record),  
54 - },  
55 - {  
56 - label: '编辑',  
57 - icon: 'clarity:note-edit-line',  
58 - onClick: handleEdit.bind(null, record),  
59 - },  
60 - {  
61 - label: '删除',  
62 - icon: 'ant-design:delete-outlined',  
63 - color: 'error',  
64 - popConfirm: {  
65 - title: '是否确认删除',  
66 - confirm: handleDelete.bind(null, record), 2 + <div>
  3 + <PageWrapper dense contentFullHeight fixedHeight contentClass="flex">
  4 + <OrganizationIdTree class="w-1/6 xl:w-1/5" @select="handleSelect" />
  5 + <BasicTable @register="registerTable" class="w-5/6 xl:w-4/5">
  6 + <template #toolbar>
  7 + <a-button type="primary" @click="handleCreate"> 新增设备 </a-button>
  8 + </template>
  9 + <template #deviceProfile="{ record }">
  10 + <a-button type="link" class="ml-2" @click="goDeviceProfile">
  11 + {{ record.deviceProfile.name }}
  12 + </a-button>
  13 + </template>
  14 + <template #organizationId="{ record }">
  15 + {{ record.organizationDTO.name }}
  16 + </template>
  17 + <template #deviceType="{ record }">
  18 + <Tag color="success" class="ml-2">
  19 + {{
  20 + record.deviceType === DeviceTypeEnum.GATEWAY
  21 + ? '网关设备'
  22 + : record.deviceType === DeviceTypeEnum.DIRECT_CONNECTION
  23 + ? '直连设备'
  24 + : '网关子设备'
  25 + }}
  26 + </Tag>
  27 + </template>
  28 + <template #deviceState="{ record }">
  29 + <Tag
  30 + :color="
  31 + record.deviceState == DeviceState.INACTIVE
  32 + ? 'warning'
  33 + : record.deviceState == DeviceState.ONLINE
  34 + ? 'success'
  35 + : 'error'
  36 + "
  37 + class="ml-2"
  38 + >
  39 + {{
  40 + record.deviceState == DeviceState.INACTIVE
  41 + ? '待激活'
  42 + : record.deviceState == DeviceState.ONLINE
  43 + ? '在线'
  44 + : '离线'
  45 + }}
  46 + </Tag>
  47 + </template>
  48 + <template #action="{ record }">
  49 + <TableAction
  50 + :actions="[
  51 + {
  52 + label: '详情',
  53 + icon: 'ant-design:eye-outlined',
  54 + onClick: handleDetail.bind(null, record),
67 }, 55 },
68 - },  
69 - ]"  
70 - />  
71 - </template>  
72 - </BasicTable>  
73 - <DeviceDetailDrawer @register="registerDetailDrawer" />  
74 - <DeviceModal @register="registerModal" @success="handleSuccess" @reload="handleReload" />  
75 - </PageWrapper> 56 + {
  57 + label: '编辑',
  58 + icon: 'clarity:note-edit-line',
  59 + onClick: handleEdit.bind(null, record),
  60 + },
  61 + {
  62 + label: '删除',
  63 + icon: 'ant-design:delete-outlined',
  64 + color: 'error',
  65 + popConfirm: {
  66 + title: '是否确认删除',
  67 + confirm: handleDelete.bind(null, record),
  68 + },
  69 + },
  70 + ]"
  71 + />
  72 + </template>
  73 + </BasicTable>
  74 + <DeviceDetailDrawer @register="registerDetailDrawer" />
  75 + <DeviceModal @register="registerModal" @success="handleSuccess" @reload="handleReload" />
  76 + </PageWrapper>
  77 + </div>
76 </template> 78 </template>
77 <script lang="ts"> 79 <script lang="ts">
78 import { defineComponent, reactive } from 'vue'; 80 import { defineComponent, reactive } from 'vue';
@@ -141,8 +143,9 @@ @@ -141,8 +143,9 @@
141 } 143 }
142 144
143 function handleDetail(record: Recordable) { 145 function handleDetail(record: Recordable) {
  146 + const { id } = record;
144 openDrawer(true, { 147 openDrawer(true, {
145 - record, 148 + id,
146 }); 149 });
147 } 150 }
148 151
@@ -14,12 +14,22 @@ export const columns: BasicColumn[] = [ @@ -14,12 +14,22 @@ export const columns: BasicColumn[] = [
14 }, 14 },
15 { 15 {
16 title: '消息类型', 16 title: '消息类型',
17 - dataIndex: 'messageTypeDictText', 17 + dataIndex: 'messageType',
  18 + format: (_, record: Recordable) => {
  19 + return record.messageType === 'PHONE_MESSAGE'
  20 + ? '短信'
  21 + : record.type === 'DING_TALK_MESSAGE'
  22 + ? '钉钉'
  23 + : '邮件';
  24 + },
18 width: 200, 25 width: 200,
19 }, 26 },
20 { 27 {
21 title: '平台类型', 28 title: '平台类型',
22 - dataIndex: 'platformTypeDictText', 29 + dataIndex: 'platformType',
  30 + format: (_, record: Recordable) => {
  31 + return record.platformType === 'ALI_CLOUD' ? '阿里云平台' : '腾讯云平台';
  32 + },
23 width: 180, 33 width: 180,
24 }, 34 },
25 { 35 {
@@ -75,6 +85,9 @@ export const searchFormSchema: FormSchema[] = [ @@ -75,6 +85,9 @@ export const searchFormSchema: FormSchema[] = [
75 label: '消息类型', 85 label: '消息类型',
76 required: true, 86 required: true,
77 component: 'ApiSelect', 87 component: 'ApiSelect',
  88 + colProps: {
  89 + span: 6,
  90 + },
78 componentProps: { 91 componentProps: {
79 api: findDictItemByCode, 92 api: findDictItemByCode,
80 params: { 93 params: {
@@ -94,7 +107,7 @@ export const searchFormSchema: FormSchema[] = [ @@ -94,7 +107,7 @@ export const searchFormSchema: FormSchema[] = [
94 { label: '已禁用', value: 0 }, 107 { label: '已禁用', value: 0 },
95 ], 108 ],
96 }, 109 },
97 - colProps: { span: 8 }, 110 + colProps: { span: 6 },
98 }, 111 },
99 ]; 112 ];
100 113
@@ -214,4 +227,10 @@ export const formSchema: FormSchema[] = [ @@ -214,4 +227,10 @@ export const formSchema: FormSchema[] = [
214 field: 'remark', 227 field: 'remark',
215 component: 'InputTextArea', 228 component: 'InputTextArea',
216 }, 229 },
  230 + {
  231 + label: '租户id',
  232 + field: 'tenantId',
  233 + component: 'Input',
  234 + show: false,
  235 + },
217 ]; 236 ];
@@ -41,11 +41,11 @@ @@ -41,11 +41,11 @@
41 import ConfigDrawer from './ConfigDrawer.vue'; 41 import ConfigDrawer from './ConfigDrawer.vue';
42 import { columns, searchFormSchema } from './config.data'; 42 import { columns, searchFormSchema } from './config.data';
43 import { Modal } from 'ant-design-vue'; 43 import { Modal } from 'ant-design-vue';
44 - import { CodeEditor, JsonPreview } from '/@/components/CodeEditor'; 44 + import { JsonPreview } from '/@/components/CodeEditor';
45 import { useMessage } from '/@/hooks/web/useMessage'; 45 import { useMessage } from '/@/hooks/web/useMessage';
46 export default defineComponent({ 46 export default defineComponent({
47 name: 'MessageConfigManagement', 47 name: 'MessageConfigManagement',
48 - components: { BasicTable, ConfigDrawer, TableAction, CodeEditor }, 48 + components: { BasicTable, ConfigDrawer, TableAction },
49 setup() { 49 setup() {
50 const [registerDrawer, { openDrawer }] = useDrawer(); 50 const [registerDrawer, { openDrawer }] = useDrawer();
51 const { createMessage } = useMessage(); 51 const { createMessage } = useMessage();
1 <template> 1 <template>
2 - <div :class="prefixCls">  
3 - <div :class="`${prefixCls}-bottom`">  
4 - <Tabs>  
5 - <template v-for="item in achieveList" :key="item.key">  
6 - <TabPane :tab="item.name">  
7 - <component :is="item.component" />  
8 - </TabPane>  
9 - </template>  
10 - </Tabs>  
11 - </div> 2 + <div :class="`${prefixCls}-bottom`">
  3 + <Tabs>
  4 + <template v-for="item in achieveList" :key="item.key">
  5 + <TabPane :tab="item.name">
  6 + <component :is="item.component" />
  7 + </TabPane>
  8 + </template>
  9 + </Tabs>
12 </div> 10 </div>
13 </template> 11 </template>
14 12
15 <script lang="ts"> 13 <script lang="ts">
16 - import { Tabs } from 'ant-design-vue'; 14 + import { Tabs, TabPane } from 'ant-design-vue';
17 import { defineComponent } from 'vue'; 15 import { defineComponent } from 'vue';
18 import SmsLog from './item/SmsLog.vue'; 16 import SmsLog from './item/SmsLog.vue';
19 import EmailLog from './item/EmailLog.vue'; 17 import EmailLog from './item/EmailLog.vue';
@@ -22,7 +20,7 @@ @@ -22,7 +20,7 @@
22 export default defineComponent({ 20 export default defineComponent({
23 components: { 21 components: {
24 Tabs, 22 Tabs,
25 - TabPane: Tabs.TabPane, 23 + TabPane,
26 SmsLog, 24 SmsLog,
27 EmailLog, 25 EmailLog,
28 }, 26 },
@@ -38,7 +36,7 @@ @@ -38,7 +36,7 @@
38 .account-center { 36 .account-center {
39 &-bottom { 37 &-bottom {
40 padding: 10px; 38 padding: 10px;
41 - margin: 0 16px 16px 16px; 39 + margin: 16px;
42 background-color: @component-background; 40 background-color: @component-background;
43 border-radius: 3px; 41 border-radius: 3px;
44 } 42 }
src/views/ruleengine/regulationEngine/RuleEngineDrawer.vue renamed from src/views/ruleengine/RuleEngineDrawer.vue
@@ -7,7 +7,7 @@ @@ -7,7 +7,7 @@
7 width="500px" 7 width="500px"
8 @ok="handleSubmit" 8 @ok="handleSubmit"
9 > 9 >
10 - <BasicForm @register="registerForm"/> 10 + <BasicForm @register="registerForm" />
11 </BasicDrawer> 11 </BasicDrawer>
12 </template> 12 </template>
13 <script lang="ts"> 13 <script lang="ts">
@@ -15,8 +15,8 @@ @@ -15,8 +15,8 @@
15 import { BasicForm, useForm } from '/@/components/Form'; 15 import { BasicForm, useForm } from '/@/components/Form';
16 import { formSchema } from './config.data'; 16 import { formSchema } from './config.data';
17 import { BasicDrawer, useDrawerInner } from '/@/components/Drawer'; 17 import { BasicDrawer, useDrawerInner } from '/@/components/Drawer';
18 - import {saveOrEditMessageConfig} from "/@/api/message/config";  
19 - import {useMessage} from "/@/hooks/web/useMessage"; 18 + import { saveOrEditMessageConfig } from '/@/api/message/config';
  19 + import { useMessage } from '/@/hooks/web/useMessage';
20 20
21 export default defineComponent({ 21 export default defineComponent({
22 name: 'ConfigDrawer', 22 name: 'ConfigDrawer',
@@ -25,7 +25,7 @@ @@ -25,7 +25,7 @@
25 setup(_, { emit }) { 25 setup(_, { emit }) {
26 const isUpdate = ref(true); 26 const isUpdate = ref(true);
27 27
28 - const [registerForm, { validate,setFieldsValue,resetFields }] = useForm({ 28 + const [registerForm, { validate, setFieldsValue, resetFields }] = useForm({
29 labelWidth: 120, 29 labelWidth: 120,
30 schemas: formSchema, 30 schemas: formSchema,
31 showActionButtonGroup: false, 31 showActionButtonGroup: false,
@@ -37,8 +37,8 @@ @@ -37,8 +37,8 @@
37 isUpdate.value = !!data?.isUpdate; 37 isUpdate.value = !!data?.isUpdate;
38 if (unref(isUpdate)) { 38 if (unref(isUpdate)) {
39 const config = data.record.config; 39 const config = data.record.config;
40 - for (const key in config){  
41 - Reflect.set(data.record, key+'', config[key]); 40 + for (const key in config) {
  41 + Reflect.set(data.record, key + '', config[key]);
42 } 42 }
43 await setFieldsValue({ 43 await setFieldsValue({
44 ...data.record, 44 ...data.record,
@@ -53,27 +53,27 @@ @@ -53,27 +53,27 @@
53 const values = await validate(); 53 const values = await validate();
54 const { createMessage } = useMessage(); 54 const { createMessage } = useMessage();
55 setDrawerProps({ confirmLoading: true }); 55 setDrawerProps({ confirmLoading: true });
56 - let config={};  
57 - if(values.messageType === 'PHONE_MESSAGE'){  
58 - config ={  
59 - "accessKeyId":values.accessKeyId,  
60 - "accessKeySecret":values.accessKeySecret,  
61 - }  
62 - }else if(values.messageType === 'EMAIL_MESSAGE'){  
63 - config ={  
64 - "host":values.host,  
65 - "port":values.port,  
66 - "username":values.username,  
67 - "password":values.password,  
68 - } 56 + let config = {};
  57 + if (values.messageType === 'PHONE_MESSAGE') {
  58 + config = {
  59 + accessKeyId: values.accessKeyId,
  60 + accessKeySecret: values.accessKeySecret,
  61 + };
  62 + } else if (values.messageType === 'EMAIL_MESSAGE') {
  63 + config = {
  64 + host: values.host,
  65 + port: values.port,
  66 + username: values.username,
  67 + password: values.password,
  68 + };
69 } 69 }
70 Reflect.set(values, 'config', config); 70 Reflect.set(values, 'config', config);
71 - let saveMessage = "添加成功";  
72 - let updateMessage = "修改成功"; 71 + let saveMessage = '添加成功';
  72 + let updateMessage = '修改成功';
73 await saveOrEditMessageConfig(values, unref(isUpdate)); 73 await saveOrEditMessageConfig(values, unref(isUpdate));
74 closeDrawer(); 74 closeDrawer();
75 emit('success'); 75 emit('success');
76 - createMessage.success(unref(isUpdate)?updateMessage:saveMessage); 76 + createMessage.success(unref(isUpdate) ? updateMessage : saveMessage);
77 } finally { 77 } finally {
78 setDrawerProps({ confirmLoading: false }); 78 setDrawerProps({ confirmLoading: false });
79 } 79 }
src/views/ruleengine/regulationEngine/config.data.ts renamed from src/views/ruleengine/config.data.ts
1 <template> 1 <template>
2 - <div> 2 + <div class="p-4">
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>
@@ -91,11 +91,7 @@ @@ -91,11 +91,7 @@
91 title: '设备列表', 91 title: '设备列表',
92 api: devicePage, 92 api: devicePage,
93 columns, 93 columns,
94 - formConfig: {  
95 - labelWidth: 120,  
96 - schemas: searchFormSchema,  
97 - },  
98 - useSearchForm: true, 94 + useSearchForm: false,
99 showTableSetting: true, 95 showTableSetting: true,
100 bordered: true, 96 bordered: true,
101 showIndexColumn: false, 97 showIndexColumn: false,
1 <template> 1 <template>
2 - <PageWrapper title="我的通知详情">  
3 - <Description @register="register1" class="mt-4" />  
4 - </PageWrapper> 2 + <div>
  3 + <PageWrapper title="我的通知详情">
  4 + <Description @register="register1" class="mt-4" />
  5 + </PageWrapper>
  6 + </div>
5 </template> 7 </template>
6 <script lang="ts"> 8 <script lang="ts">
7 import { defineComponent, watch, ref } from 'vue'; 9 import { defineComponent, watch, ref } from 'vue';
1 <template> 1 <template>
2 - <BasicDrawer  
3 - v-bind="$attrs"  
4 - @register="registerDrawer"  
5 - :showFooter="false"  
6 - :title="getTitle"  
7 - width="1000px"  
8 - >  
9 - <DetailChild :emitChildData="childData" />  
10 - <BasicTable :columns="columns" :dataSource="tableData">  
11 - <span></span>  
12 - </BasicTable>  
13 - </BasicDrawer> 2 + <div>
  3 + <BasicDrawer
  4 + v-bind="$attrs"
  5 + @register="registerDrawer"
  6 + :showFooter="false"
  7 + :title="getTitle"
  8 + width="1000px"
  9 + >
  10 + <DetailChild :emitChildData="childData" />
  11 + <BasicTable :columns="columns" :dataSource="tableData">
  12 + <span></span>
  13 + </BasicTable>
  14 + </BasicDrawer>
  15 + </div>
14 </template> 16 </template>
15 <script lang="ts"> 17 <script lang="ts">
16 import { defineComponent, ref, computed, unref } from 'vue'; 18 import { defineComponent, ref, computed, unref } from 'vue';
@@ -61,7 +61,7 @@ @@ -61,7 +61,7 @@
61 import { notifyGetTableApi, notifyDeleteApi } from '/@/api/stationnotification/stationnotifyApi'; 61 import { notifyGetTableApi, notifyDeleteApi } from '/@/api/stationnotification/stationnotifyApi';
62 62
63 export default defineComponent({ 63 export default defineComponent({
64 - name: 'index', 64 + name: 'Index',
65 components: { BasicTable, NotifyManagerDrawer, TableAction, tableViewChild }, 65 components: { BasicTable, NotifyManagerDrawer, TableAction, tableViewChild },
66 setup() { 66 setup() {
67 let isJudgeStatus = ref(true); 67 let isJudgeStatus = ref(true);
1 <template> 1 <template>
2 - <BasicDrawer  
3 - v-bind="$attrs"  
4 - @register="registerDrawer"  
5 - :showFooter="false"  
6 - :title="getTitle"  
7 - width="800px"  
8 - >  
9 - <BasicForm :showResetButton="false" :showSubmitButton="false" @register="registerForm">  
10 - <template #add>  
11 - <Button style="margin-left: 30px; margin-top: 80px" type="primary" @click="handleCancel"  
12 - >取消</Button  
13 - >  
14 - <Button style="margin-left: 30px" type="primary" @click="handleSaveDraft">保存草稿</Button>  
15 - <Button style="margin-left: 30px" type="primary" @click="handleSend">发布通知</Button>  
16 - </template>  
17 - </BasicForm>  
18 - </BasicDrawer> 2 + <div>
  3 + <BasicDrawer
  4 + v-bind="$attrs"
  5 + @register="registerDrawer"
  6 + :showFooter="false"
  7 + :title="getTitle"
  8 + width="800px"
  9 + >
  10 + <BasicForm :showResetButton="false" :showSubmitButton="false" @register="registerForm">
  11 + <template #add>
  12 + <Button style="margin-left: 30px; margin-top: 80px" type="primary" @click="handleCancel"
  13 + >取消</Button
  14 + >
  15 + <Button style="margin-left: 30px" type="primary" @click="handleSaveDraft"
  16 + >保存草稿</Button
  17 + >
  18 + <Button style="margin-left: 30px" type="primary" @click="handleSend">发布通知</Button>
  19 + </template>
  20 + </BasicForm>
  21 + </BasicDrawer>
  22 + </div>
19 </template> 23 </template>
20 <script lang="ts"> 24 <script lang="ts">
21 import { defineComponent, ref, computed, unref, reactive, watch } from 'vue'; 25 import { defineComponent, ref, computed, unref, reactive, watch } from 'vue';
1 <template> 1 <template>
2 - <BasicDrawer  
3 - v-bind="$attrs"  
4 - @register="registerDrawer"  
5 - :showFooter="false"  
6 - :title="getTitle"  
7 - width="800px"  
8 - >  
9 - <PageWrapper title="站内通知详情">  
10 - <Description @register="register1" class="mt-4" />  
11 - </PageWrapper>  
12 - </BasicDrawer> 2 + <div>
  3 + <BasicDrawer
  4 + v-bind="$attrs"
  5 + @register="registerDrawer"
  6 + :showFooter="false"
  7 + :title="getTitle"
  8 + width="800px"
  9 + >
  10 + <PageWrapper title="站内通知详情">
  11 + <Description @register="register1" class="mt-4" />
  12 + </PageWrapper>
  13 + </BasicDrawer>
  14 + </div>
13 </template> 15 </template>
14 <script lang="ts"> 16 <script lang="ts">
15 import { defineComponent, ref, computed, unref } from 'vue'; 17 import { defineComponent, ref, computed, unref } from 'vue';
1 -<template>  
2 - <PageWrapper title="关于">  
3 - <template #headerContent>  
4 - <div class="flex justify-between items-center">  
5 - <span class="flex-1">  
6 - <a :href="GITHUB_URL" target="_blank">{{ name }}</a>  
7 - 是一个基于Vue3.0、Vite、 Ant-Design-Vue 、TypeScript  
8 - 的后台解决方案,目标是为中大型项目开发,提供现成的开箱解决方案及丰富的示例,原则上不会限制任何代码用于商用。  
9 - </span>  
10 - </div>  
11 - </template>  
12 - <Description @register="infoRegister" class="enter-y" />  
13 - <Description @register="register" class="my-4 enter-y" />  
14 - <Description @register="registerDev" class="enter-y" />  
15 - </PageWrapper>  
16 -</template>  
17 -<script lang="ts" setup>  
18 - import { h } from 'vue';  
19 - import { Tag } from 'ant-design-vue';  
20 - import { PageWrapper } from '/@/components/Page';  
21 - import { Description, DescItem, useDescription } from '/@/components/Description/index';  
22 - import { GITHUB_URL, SITE_URL, DOC_URL } from '/@/settings/siteSetting';  
23 -  
24 - const { pkg, lastBuildTime } = __APP_INFO__;  
25 -  
26 - const { dependencies, devDependencies, name, version } = pkg;  
27 -  
28 - const schema: DescItem[] = [];  
29 - const devSchema: DescItem[] = [];  
30 -  
31 - const commonTagRender = (color: string) => (curVal) => h(Tag, { color }, () => curVal);  
32 - const commonLinkRender = (text: string) => (href) => h('a', { href, target: '_blank' }, text);  
33 -  
34 - const infoSchema: DescItem[] = [  
35 - {  
36 - label: '版本',  
37 - field: 'version',  
38 - render: commonTagRender('blue'),  
39 - },  
40 - {  
41 - label: '最后编译时间',  
42 - field: 'lastBuildTime',  
43 - render: commonTagRender('blue'),  
44 - },  
45 - {  
46 - label: '文档地址',  
47 - field: 'doc',  
48 - render: commonLinkRender('文档地址'),  
49 - },  
50 - {  
51 - label: '预览地址',  
52 - field: 'preview',  
53 - render: commonLinkRender('预览地址'),  
54 - },  
55 - {  
56 - label: 'Github',  
57 - field: 'github',  
58 - render: commonLinkRender('Github'),  
59 - },  
60 - ];  
61 -  
62 - const infoData = {  
63 - version,  
64 - lastBuildTime,  
65 - doc: DOC_URL,  
66 - preview: SITE_URL,  
67 - github: GITHUB_URL,  
68 - };  
69 -  
70 - Object.keys(dependencies).forEach((key) => {  
71 - schema.push({ field: key, label: key });  
72 - });  
73 -  
74 - Object.keys(devDependencies).forEach((key) => {  
75 - devSchema.push({ field: key, label: key });  
76 - });  
77 -  
78 - const [register] = useDescription({  
79 - title: '生产环境依赖',  
80 - data: dependencies,  
81 - schema: schema,  
82 - column: 3,  
83 - });  
84 -  
85 - const [registerDev] = useDescription({  
86 - title: '开发环境依赖',  
87 - data: devDependencies,  
88 - schema: devSchema,  
89 - column: 3,  
90 - });  
91 -  
92 - const [infoRegister] = useDescription({  
93 - title: '项目信息',  
94 - data: infoData,  
95 - schema: infoSchema,  
96 - column: 2,  
97 - });  
98 -</script>  
@@ -10,7 +10,6 @@ @@ -10,7 +10,6 @@
10 import { Description, useDescription } from '/@/components/Description/index'; 10 import { Description, useDescription } from '/@/components/Description/index';
11 import { useI18n } from '/@/hooks/web/useI18n'; 11 import { useI18n } from '/@/hooks/web/useI18n';
12 import { getDescSchema } from './data'; 12 import { getDescSchema } from './data';
13 -  
14 defineProps({ 13 defineProps({
15 info: { 14 info: {
16 type: Object as PropType<ErrorLogInfo>, 15 type: Object as PropType<ErrorLogInfo>,
@@ -3,7 +3,6 @@ @@ -3,7 +3,6 @@
3 <template v-for="src in imgList" :key="src"> 3 <template v-for="src in imgList" :key="src">
4 <img :src="src" v-show="false" /> 4 <img :src="src" v-show="false" />
5 </template> 5 </template>
6 - <DetailModal :info="rowInfo" @register="registerModal" />  
7 <BasicTable @register="register" class="error-handle-table"> 6 <BasicTable @register="register" class="error-handle-table">
8 <template #toolbar> 7 <template #toolbar>
9 <a-button @click="fireVueError" type="primary"> 8 <a-button @click="fireVueError" type="primary">
@@ -24,6 +23,7 @@ @@ -24,6 +23,7 @@
24 /> 23 />
25 </template> 24 </template>
26 </BasicTable> 25 </BasicTable>
  26 + <DetailModal :info="rowInfo" @register="registerModal" />
27 </div> 27 </div>
28 </template> 28 </template>
29 29
1 <template> 1 <template>
2 - <transition name="fade-bottom" mode="out-in">  
3 - <LockPage v-if="getIsLock" />  
4 - </transition> 2 + <div>
  3 + <transition name="fade-bottom" mode="out-in">
  4 + <LockPage v-if="getIsLock" />
  5 + </transition>
  6 + </div>
5 </template> 7 </template>
6 <script lang="ts" setup> 8 <script lang="ts" setup>
7 import { computed } from 'vue'; 9 import { computed } from 'vue';
1 <template> 1 <template>
2 - <LoginFormTitle v-show="getShow" class="enter-x" />  
3 - <Form  
4 - class="p-4 enter-x"  
5 - :model="formData"  
6 - :rules="getFormRules"  
7 - ref="formRef"  
8 - v-show="getShow"  
9 - @keypress.enter="handleLogin"  
10 - >  
11 - <FormItem name="account" class="enter-x">  
12 - <Input  
13 - size="large"  
14 - v-model:value="formData.account"  
15 - :placeholder="t('sys.login.userName')"  
16 - class="fix-auto-fill"  
17 - />  
18 - </FormItem>  
19 - <FormItem name="password" class="enter-x">  
20 - <InputPassword  
21 - size="large"  
22 - visibilityToggle  
23 - v-model:value="formData.password"  
24 - :placeholder="t('sys.login.password')"  
25 - />  
26 - </FormItem> 2 + <div>
  3 + <LoginFormTitle v-show="getShow" class="enter-x" />
  4 + <Form
  5 + class="p-4 enter-x"
  6 + :model="formData"
  7 + :rules="getFormRules"
  8 + ref="formRef"
  9 + v-show="getShow"
  10 + @keypress.enter="handleLogin"
  11 + >
  12 + <FormItem name="account" class="enter-x">
  13 + <Input
  14 + size="large"
  15 + v-model:value="formData.account"
  16 + :placeholder="t('sys.login.userName')"
  17 + class="fix-auto-fill"
  18 + />
  19 + </FormItem>
  20 + <FormItem name="password" class="enter-x">
  21 + <InputPassword
  22 + size="large"
  23 + visibilityToggle
  24 + v-model:value="formData.password"
  25 + :placeholder="t('sys.login.password')"
  26 + />
  27 + </FormItem>
27 28
28 - <FormItem class="enter-x">  
29 - <Button type="primary" size="large" block @click="handleLogin" :loading="loading">  
30 - {{ t('sys.login.loginButton') }}  
31 - </Button>  
32 - </FormItem>  
33 - <ARow type="flex" justify="space-between">  
34 - <ACol :md="11" :xs="24">  
35 - <Button block @click="setLoginState(LoginStateEnum.MOBILE)">  
36 - {{ t('sys.login.mobileSignInFormTitle') }} 29 + <FormItem class="enter-x">
  30 + <Button type="primary" size="large" block @click="handleLogin" :loading="loading">
  31 + {{ t('sys.login.loginButton') }}
37 </Button> 32 </Button>
38 - </ACol>  
39 - <ACol :md="11" :xs="24">  
40 - <Button block @click="setLoginState(LoginStateEnum.QR_CODE)">  
41 - {{ t('sys.login.qrSignInFormTitle') }}  
42 - </Button>  
43 - </ACol>  
44 - </ARow>  
45 - <ARow class="enter-x">  
46 - <ACol :span="12">  
47 - <FormItem />  
48 - </ACol>  
49 - <ACol :span="12">  
50 - <FormItem :style="{ 'text-align': 'right' }">  
51 - <!-- No logic, you need to deal with it yourself -->  
52 - <Button type="link" size="small" @click="setLoginState(LoginStateEnum.RESET_PASSWORD)">  
53 - {{ t('sys.login.forgetPassword') }} 33 + </FormItem>
  34 + <ARow type="flex" justify="space-between">
  35 + <ACol :md="11" :xs="24">
  36 + <Button block @click="setLoginState(LoginStateEnum.MOBILE)">
  37 + {{ t('sys.login.mobileSignInFormTitle') }}
  38 + </Button>
  39 + </ACol>
  40 + <ACol :md="11" :xs="24">
  41 + <Button block @click="setLoginState(LoginStateEnum.QR_CODE)">
  42 + {{ t('sys.login.qrSignInFormTitle') }}
54 </Button> 43 </Button>
55 - </FormItem>  
56 - </ACol>  
57 - </ARow>  
58 - </Form> 44 + </ACol>
  45 + </ARow>
  46 + <ARow class="enter-x">
  47 + <ACol :span="12">
  48 + <FormItem />
  49 + </ACol>
  50 + <ACol :span="12">
  51 + <FormItem :style="{ 'text-align': 'right' }">
  52 + <!-- No logic, you need to deal with it yourself -->
  53 + <Button type="link" size="small" @click="setLoginState(LoginStateEnum.RESET_PASSWORD)">
  54 + {{ t('sys.login.forgetPassword') }}
  55 + </Button>
  56 + </FormItem>
  57 + </ACol>
  58 + </ARow>
  59 + </Form>
  60 + </div>
59 </template> 61 </template>
60 <script lang="ts" setup> 62 <script lang="ts" setup>
61 import { reactive, ref, toRaw, unref, computed } from 'vue'; 63 import { reactive, ref, toRaw, unref, computed } from 'vue';
1 <template> 1 <template>
2 - <PageWrapper :title="`用户资料`" contentBackground @back="goBack">  
3 - <Description size="middle" @register="register" />  
4 - </PageWrapper> 2 + <div>
  3 + <PageWrapper :title="`用户资料`" contentBackground @back="goBack">
  4 + <Description size="middle" @register="register" />
  5 + </PageWrapper>
  6 + </div>
5 </template> 7 </template>
6 8
7 <script> 9 <script>
@@ -11,7 +11,6 @@ @@ -11,7 +11,6 @@
11 <BasicTree 11 <BasicTree
12 v-model:value="model[field]" 12 v-model:value="model[field]"
13 :treeData="organizationTreeData" 13 :treeData="organizationTreeData"
14 - :replaceFields="{ title: 'name' }"  
15 :checked-keys="checkGroup" 14 :checked-keys="checkGroup"
16 checkable 15 checkable
17 toolbar 16 toolbar
@@ -26,15 +25,12 @@ @@ -26,15 +25,12 @@
26 import { BasicModal, useModalInner } from '/@/components/Modal'; 25 import { BasicModal, useModalInner } from '/@/components/Modal';
27 import { BasicForm, useForm } from '/@/components/Form/index'; 26 import { BasicForm, useForm } from '/@/components/Form/index';
28 import { accountFormSchema } from './account.data'; 27 import { accountFormSchema } from './account.data';
29 - import {  
30 - findCurrentUserRelation,  
31 - getOrganizationList,  
32 - SaveOrUpdateUserInfo,  
33 - } from '/@/api/system/system'; 28 + import { findCurrentUserRelation, SaveOrUpdateUserInfo } from '/@/api/system/system';
34 import { BasicTree, TreeItem } from '/@/components/Tree'; 29 import { BasicTree, TreeItem } from '/@/components/Tree';
35 import { findCurrentUserGroups } from '/@/api/system/group'; 30 import { findCurrentUserGroups } from '/@/api/system/group';
36 import { RoleOrOrganizationParam } from '/@/api/system/model/systemModel'; 31 import { RoleOrOrganizationParam } from '/@/api/system/model/systemModel';
37 import { useMessage } from '/@/hooks/web/useMessage'; 32 import { useMessage } from '/@/hooks/web/useMessage';
  33 + import { copyTransTreeFun } from '/@/utils/fnUtils';
38 export default defineComponent({ 34 export default defineComponent({
39 name: 'AccountModal', 35 name: 'AccountModal',
40 components: { BasicModal, BasicForm, BasicTree }, 36 components: { BasicModal, BasicForm, BasicTree },
@@ -58,24 +54,13 @@ @@ -58,24 +54,13 @@
58 setModalProps({ confirmLoading: false }); 54 setModalProps({ confirmLoading: false });
59 isUpdate.value = !!data?.isUpdate; 55 isUpdate.value = !!data?.isUpdate;
60 const groupListModel = await findCurrentUserGroups(); 56 const groupListModel = await findCurrentUserGroups();
61 -  
62 if (unref(organizationTreeData).length === 0) { 57 if (unref(organizationTreeData).length === 0) {
63 - let treeValues = new Array<TreeItem>();  
64 - groupListModel.map((item) => {  
65 - const groupData = {  
66 - name: item.name,  
67 - key: item.id,  
68 - id: item.id,  
69 - children: item.children as any as TreeItem[],  
70 - };  
71 - treeValues.push(groupData);  
72 - });  
73 - organizationTreeData.value = treeValues; 58 + copyTransTreeFun(groupListModel);
  59 + organizationTreeData.value = groupListModel;
74 } 60 }
75 61
76 if (unref(isUpdate)) { 62 if (unref(isUpdate)) {
77 rowId.value = data.record.id; 63 rowId.value = data.record.id;
78 -  
79 const roleParams = new RoleOrOrganizationParam(rowId.value, true, false); 64 const roleParams = new RoleOrOrganizationParam(rowId.value, true, false);
80 findCurrentUserRelation(roleParams).then((result) => { 65 findCurrentUserRelation(roleParams).then((result) => {
81 console.log(result); 66 console.log(result);
@@ -88,21 +73,13 @@ @@ -88,21 +73,13 @@
88 const organizationParams = new RoleOrOrganizationParam(rowId.value, false, true); 73 const organizationParams = new RoleOrOrganizationParam(rowId.value, false, true);
89 checkGroup.value = await findCurrentUserRelation(organizationParams); 74 checkGroup.value = await findCurrentUserRelation(organizationParams);
90 } 75 }
91 - const deptData = await getOrganizationList();  
92 await updateSchema([ 76 await updateSchema([
93 { 77 {
94 field: 'username', 78 field: 'username',
95 dynamicDisabled: unref(isUpdate), 79 dynamicDisabled: unref(isUpdate),
96 }, 80 },
97 - {  
98 - field: 'organizationIds',  
99 - componentProps: {  
100 - treeData: deptData,  
101 - },  
102 - },  
103 ]); 81 ]);
104 }); 82 });
105 -  
106 const getTitle = computed(() => (!unref(isUpdate) ? '新增账号' : '编辑账号')); 83 const getTitle = computed(() => (!unref(isUpdate) ? '新增账号' : '编辑账号'));
107 84
108 async function handleSubmit() { 85 async function handleSubmit() {
@@ -126,8 +103,8 @@ @@ -126,8 +103,8 @@
126 return { 103 return {
127 registerModal, 104 registerModal,
128 registerForm, 105 registerForm,
129 - getTitle,  
130 handleSubmit, 106 handleSubmit,
  107 + getTitle,
131 organizationTreeData, 108 organizationTreeData,
132 checkGroup, 109 checkGroup,
133 }; 110 };
@@ -133,14 +133,42 @@ export const accountFormSchema: FormSchema[] = [ @@ -133,14 +133,42 @@ export const accountFormSchema: FormSchema[] = [
133 field: 'phoneNumber', 133 field: 'phoneNumber',
134 component: 'Input', 134 component: 'Input',
135 colProps: { span: 12 }, 135 colProps: { span: 12 },
136 - required: true, 136 + rules: [
  137 + {
  138 + required: true,
  139 + validator: (_, value: string) => {
  140 + const reg = /^[1][3,4,5,6,7,8,9][0-9]{9}$/;
  141 + if (value === '') {
  142 + return Promise.reject('请输入手机号码');
  143 + } else if (!reg.test(value)) {
  144 + return Promise.reject('手机号码不正确');
  145 + }
  146 + return Promise.resolve();
  147 + },
  148 + trigger: 'blur',
  149 + },
  150 + ],
137 }, 151 },
138 { 152 {
139 label: '邮箱', 153 label: '邮箱',
140 field: 'email', 154 field: 'email',
141 component: 'Input', 155 component: 'Input',
142 colProps: { span: 12 }, 156 colProps: { span: 12 },
143 - required: true, 157 + rules: [
  158 + {
  159 + required: true,
  160 + validator: (_, value: string) => {
  161 + const reg = /^[a-zA-Z0-9_.-]+@[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)*\.[a-zA-Z0-9]{2,6}$/;
  162 + if (value === '') {
  163 + return Promise.resolve();
  164 + } else if (!reg.test(value)) {
  165 + return Promise.reject('电子邮箱格式不正确');
  166 + }
  167 + return Promise.resolve();
  168 + },
  169 + trigger: 'blur',
  170 + },
  171 + ],
144 }, 172 },
145 { 173 {
146 field: 'accountExpireTime', 174 field: 'accountExpireTime',
1 <template> 1 <template>
2 - <PageWrapper dense contentFullHeight fixedHeight contentClass="flex">  
3 - <OrganizationIdTree class="w-1/4 xl:w-1/5" @select="handleSelect" />  
4 - <BasicTable @register="registerTable" class="w-3/4 xl:w-4/5" :searchInfo="searchInfo">  
5 - <template #toolbar>  
6 - <a-button type="primary" @click="handleCreate">新增账号</a-button>  
7 - </template>  
8 - <template #status="{ record }">  
9 - <Tag  
10 - :color="  
11 - record.userStatusEnum === 'NORMAL'  
12 - ? 'green'  
13 - : record.userStatusEnum === 'DISABLED'  
14 - ? 'red'  
15 - : 'orange'  
16 - "  
17 - >  
18 - {{  
19 - record.userStatusEnum === 'NORMAL'  
20 - ? '正常'  
21 - : record.userStatusEnum === 'DISABLED'  
22 - ? '已禁用'  
23 - : '已过期'  
24 - }}  
25 - </Tag>  
26 - </template>  
27 - <template #action="{ record }">  
28 - <TableAction  
29 - :actions="[  
30 - {  
31 - label: '用户详情',  
32 - icon: 'clarity:info-standard-line',  
33 - tooltip: '用户详情',  
34 - onClick: handleView.bind(null, record),  
35 - ifShow: record.level != 0,  
36 - },  
37 - {  
38 - label: '编辑',  
39 - icon: 'clarity:note-edit-line',  
40 - tooltip: '编辑',  
41 - onClick: handleEdit.bind(null, record),  
42 - ifShow: record.level != 0,  
43 - },  
44 - {  
45 - label: '删除',  
46 - icon: 'ant-design:delete-outlined',  
47 - color: 'error',  
48 - tooltip: '删除',  
49 - ifShow: record.level != 0,  
50 - popConfirm: {  
51 - title: '是否确认删除',  
52 - confirm: handleDelete.bind(null, record), 2 + <div>
  3 + <PageWrapper dense contentFullHeight fixedHeight contentClass="flex">
  4 + <OrganizationIdTree class="w-1/4 xl:w-1/5" @select="handleSelect" />
  5 + <BasicTable @register="registerTable" class="w-3/4 xl:w-4/5" :searchInfo="searchInfo">
  6 + <template #toolbar>
  7 + <a-button type="primary" @click="handleCreate">新增账号</a-button>
  8 + </template>
  9 + <template #status="{ record }">
  10 + <Tag
  11 + :color="
  12 + record.userStatusEnum === 'NORMAL'
  13 + ? 'green'
  14 + : record.userStatusEnum === 'DISABLED'
  15 + ? 'red'
  16 + : 'orange'
  17 + "
  18 + >
  19 + {{
  20 + record.userStatusEnum === 'NORMAL'
  21 + ? '正常'
  22 + : record.userStatusEnum === 'DISABLED'
  23 + ? '已禁用'
  24 + : '已过期'
  25 + }}
  26 + </Tag>
  27 + </template>
  28 + <template #action="{ record }">
  29 + <TableAction
  30 + :actions="[
  31 + {
  32 + label: '用户详情',
  33 + icon: 'clarity:info-standard-line',
  34 + tooltip: '用户详情',
  35 + onClick: handleView.bind(null, record),
  36 + ifShow: record.level != 0,
53 }, 37 },
54 - },  
55 - ]"  
56 - />  
57 - </template>  
58 - </BasicTable>  
59 - <AccountModal @register="registerModal" @success="handleSuccess" />  
60 - </PageWrapper> 38 + {
  39 + label: '编辑',
  40 + icon: 'clarity:note-edit-line',
  41 + tooltip: '编辑',
  42 + onClick: handleEdit.bind(null, record),
  43 + ifShow: record.level != 0,
  44 + },
  45 + {
  46 + label: '删除',
  47 + icon: 'ant-design:delete-outlined',
  48 + color: 'error',
  49 + tooltip: '删除',
  50 + ifShow: record.level != 0,
  51 + popConfirm: {
  52 + title: '是否确认删除',
  53 + confirm: handleDelete.bind(null, record),
  54 + },
  55 + },
  56 + ]"
  57 + />
  58 + </template>
  59 + </BasicTable>
  60 + <AccountModal @register="registerModal" @success="handleSuccess" />
  61 + </PageWrapper>
  62 + </div>
61 </template> 63 </template>
62 <script lang="ts"> 64 <script lang="ts">
63 import { defineComponent, reactive } from 'vue'; 65 import { defineComponent, reactive } from 'vue';
1 <template> 1 <template>
2 - <BasicDrawer v-bind="$attrs" @register="register" width="60%" title="字典值配置">  
3 - <div style="background-color: #f0f2f5">  
4 - <BasicTable @register="registerTable">  
5 - <template #toolbar>  
6 - <a-button type="primary" @click="handleCreate"> 新增字典值 </a-button>  
7 - </template>  
8 - <template #action="{ record }">  
9 - <TableAction  
10 - :actions="[  
11 - {  
12 - label: '编辑',  
13 - icon: 'clarity:note-edit-line',  
14 - onClick: handleEdit.bind(null, record),  
15 - },  
16 - {  
17 - label: '删除',  
18 - icon: 'ant-design:delete-outlined',  
19 - color: 'error',  
20 - popConfirm: {  
21 - title: '是否确认删除',  
22 - confirm: handleDelete.bind(null, record), 2 + <div>
  3 + <BasicDrawer v-bind="$attrs" @register="register" width="60%" title="字典值配置">
  4 + <div style="background-color: #f0f2f5">
  5 + <BasicTable @register="registerTable">
  6 + <template #toolbar>
  7 + <a-button type="primary" @click="handleCreate"> 新增字典值 </a-button>
  8 + </template>
  9 + <template #action="{ record }">
  10 + <TableAction
  11 + :actions="[
  12 + {
  13 + label: '编辑',
  14 + icon: 'clarity:note-edit-line',
  15 + onClick: handleEdit.bind(null, record),
23 }, 16 },
24 - ifShow: record.status == 0,  
25 - },  
26 - ]"  
27 - />  
28 - </template>  
29 - </BasicTable>  
30 - <ItemDrawer @register="registerDrawer" @success="handleSuccess" />  
31 - </div>  
32 - </BasicDrawer> 17 + {
  18 + label: '删除',
  19 + icon: 'ant-design:delete-outlined',
  20 + color: 'error',
  21 + popConfirm: {
  22 + title: '是否确认删除',
  23 + confirm: handleDelete.bind(null, record),
  24 + },
  25 + ifShow: record.status == 0,
  26 + },
  27 + ]"
  28 + />
  29 + </template>
  30 + </BasicTable>
  31 + <ItemDrawer @register="registerDrawer" @success="handleSuccess" />
  32 + </div>
  33 + </BasicDrawer>
  34 + </div>
33 </template> 35 </template>
34 <script lang="ts"> 36 <script lang="ts">
35 import { defineComponent } from 'vue'; 37 import { defineComponent } from 'vue';
1 <template> 1 <template>
2 - <div>  
3 - <!-- register 用于注册 useTable,如果需要使用useTable提供的 api,必须将 register 传入组件的 onRegister-->  
4 - <!-- @fetch-success接口请求成功后触发 --> 2 + <div class="p-4">
5 <BasicTable @register="registerTable" @fetch-success="onFetchSuccess"> 3 <BasicTable @register="registerTable" @fetch-success="onFetchSuccess">
6 - <!-- 通过模板,加载工具栏 -->  
7 <template #toolbar> 4 <template #toolbar>
8 <a-button type="primary" @click="handleCreate"> 5 <a-button type="primary" @click="handleCreate">
9 {{ getI18nCreateMenu }} 6 {{ getI18nCreateMenu }}
10 </a-button> 7 </a-button>
11 - <!-- 新增菜单-->  
12 </template> 8 </template>
13 -  
14 - <!-- 表格单项,操作 -->  
15 <template #action="{ record }"> 9 <template #action="{ record }">
16 <TableAction 10 <TableAction
17 :actions="[ 11 :actions="[
@@ -23,7 +17,7 @@ @@ -23,7 +17,7 @@
23 icon: 'ant-design:delete-outlined', 17 icon: 'ant-design:delete-outlined',
24 color: 'error', 18 color: 'error',
25 popConfirm: { 19 popConfirm: {
26 - title: getDeleteTitle(), //是否确认删除//getDeleteTitle() 20 + title: getDeleteTitle(),
27 confirm: handleDelete.bind(null, record), 21 confirm: handleDelete.bind(null, record),
28 }, 22 },
29 }, 23 },
@@ -112,7 +106,6 @@ @@ -112,7 +106,6 @@
112 * @param record 106 * @param record
113 */ 107 */
114 function handleEdit(record: Recordable) { 108 function handleEdit(record: Recordable) {
115 - console.log('----------------------------333-------------' + record.parentId);  
116 openDrawer(true, { 109 openDrawer(true, {
117 record, 110 record,
118 isUpdate: true, 111 isUpdate: true,
1 <template> 1 <template>
2 - <div> 2 + <div class="p-4">
3 <BasicTable @register="registerTable" @fetch-success="onFetchSuccess"> 3 <BasicTable @register="registerTable" @fetch-success="onFetchSuccess">
4 <template #toolbar> 4 <template #toolbar>
5 <a-button type="primary" @click="handleCreate"> 5 <a-button type="primary" @click="handleCreate">
1 <template> 1 <template>
2 - <PageWrapper title="修改当前用户密码" content="修改成功后会自动退出当前登录!">  
3 - <div class="py-8 bg-white flex flex-col justify-center items-center">  
4 - <BasicForm @register="register" />  
5 - <div class="flex justify-center">  
6 - <a-button @click="resetFields"> 重置 </a-button>  
7 - <a-button class="!ml-4" type="primary" @click="handleSubmit"> 确认 </a-button> 2 + <div>
  3 + <PageWrapper title="修改当前用户密码" content="修改成功后会自动退出当前登录!" class="p-4">
  4 + <div class="py-8 bg-white flex flex-col justify-center items-center">
  5 + <BasicForm @register="register" />
  6 + <div class="flex justify-center">
  7 + <a-button @click="resetFields"> 重置 </a-button>
  8 + <a-button class="!ml-4" type="primary" @click="handleSubmit"> 确认 </a-button>
  9 + </div>
8 </div> 10 </div>
9 - </div>  
10 - </PageWrapper> 11 + </PageWrapper>
  12 + </div>
11 </template> 13 </template>
12 <script lang="ts"> 14 <script lang="ts">
13 import { defineComponent, ref } from 'vue'; 15 import { defineComponent, ref } from 'vue';
1 <template> 1 <template>
2 - <div class="p-4"> 2 + <div>
3 <BasicTable @register="tenantTable"> 3 <BasicTable @register="tenantTable">
4 <template #toolbar> 4 <template #toolbar>
5 <a-button type="primary" @click="handleCreate"> 新增租户</a-button> 5 <a-button type="primary" @click="handleCreate"> 新增租户</a-button>
@@ -68,14 +68,14 @@ @@ -68,14 +68,14 @@
68 <script lang="ts"> 68 <script lang="ts">
69 import { defineComponent } from 'vue'; 69 import { defineComponent } from 'vue';
70 import { BasicTable, TableImg, TableAction, useTable, FormSchema } from '/@/components/Table'; 70 import { BasicTable, TableImg, TableAction, useTable, FormSchema } from '/@/components/Table';
71 - import { Avatar, Tag } from 'ant-design-vue'; 71 + import { Tag } from 'ant-design-vue';
72 import { getBasicColumns } from './tenantBaseColumns'; 72 import { getBasicColumns } from './tenantBaseColumns';
73 import { deleteTenant, getTenantPage } from '/@/api/tenant/tenantApi'; 73 import { deleteTenant, getTenantPage } from '/@/api/tenant/tenantApi';
74 import { useDrawer } from '/@/components/Drawer'; 74 import { useDrawer } from '/@/components/Drawer';
75 import TenantDrawer from './TenantDrawer.vue'; 75 import TenantDrawer from './TenantDrawer.vue';
76 import TenantAdminDrawer from './TenantAdminDrawer.vue'; 76 import TenantAdminDrawer from './TenantAdminDrawer.vue';
77 export default defineComponent({ 77 export default defineComponent({
78 - components: { BasicTable, Avatar, TableImg, Tag, TableAction, TenantDrawer, TenantAdminDrawer }, 78 + components: { BasicTable, TableImg, Tag, TableAction, TenantDrawer, TenantAdminDrawer },
79 setup() { 79 setup() {
80 const [tenantDrawer, { openDrawer: openDrawer }] = useDrawer(); 80 const [tenantDrawer, { openDrawer: openDrawer }] = useDrawer();
81 const [tenantAdminDrawer, { openDrawer: openTenantAdminDrawer }] = useDrawer(); 81 const [tenantAdminDrawer, { openDrawer: openTenantAdminDrawer }] = useDrawer();
@@ -255,6 +255,20 @@ export const schemas: FormSchema[] = [ @@ -255,6 +255,20 @@ export const schemas: FormSchema[] = [
255 componentProps: { 255 componentProps: {
256 placeholder: '请输入联系电话', 256 placeholder: '请输入联系电话',
257 }, 257 },
  258 + rules: [
  259 + {
  260 + validator: (_, value: string) => {
  261 + const reg = /^[1][3,4,5,6,7,8,9][0-9]{9}$/;
  262 + if (value === '') {
  263 + return Promise.resolve();
  264 + } else if (!reg.test(value)) {
  265 + return Promise.reject('请输入正确的手机号码');
  266 + }
  267 + return Promise.resolve();
  268 + },
  269 + trigger: 'blur',
  270 + },
  271 + ],
258 }, 272 },
259 { 273 {
260 field: 'qrcode', 274 field: 'qrcode',
src/views/tenant/platform/cpns/AppDraw.vue renamed from src/views/tenant/platform/components/AppDraw.vue
src/views/tenant/platform/cpns/CVIDraw.vue renamed from src/views/tenant/platform/components/CVIDraw.vue
src/views/tenant/platform/cpns/EnterpriseInfo.vue renamed from src/views/tenant/platform/components/EnterpriseInfo.vue
@@ -24,9 +24,9 @@ @@ -24,9 +24,9 @@
24 > 24 >
25 </div> 25 </div>
26 </Upload> 26 </Upload>
27 - </template></BasicForm  
28 - ></Card  
29 - > 27 + </template>
  28 + </BasicForm>
  29 + </Card>
30 <Loading v-bind="compState" /> 30 <Loading v-bind="compState" />
31 <a-button 31 <a-button
32 @click="handleUpdateInfo" 32 @click="handleUpdateInfo"
@@ -66,7 +66,7 @@ @@ -66,7 +66,7 @@
66 loading: false, 66 loading: false,
67 tip: '拼命加载中...', 67 tip: '拼命加载中...',
68 }); 68 });
69 - const [registerForm, { getFieldsValue, setFieldsValue, updateSchema }] = useForm({ 69 + const [registerForm, { getFieldsValue, setFieldsValue, updateSchema, validate }] = useForm({
70 labelWidth: 80, 70 labelWidth: 80,
71 schemas, 71 schemas,
72 showResetButton: false, 72 showResetButton: false,
@@ -102,7 +102,6 @@ @@ -102,7 +102,6 @@
102 // 更新 102 // 更新
103 const handleUpdateInfo = async () => { 103 const handleUpdateInfo = async () => {
104 try { 104 try {
105 - compState.value.loading = true;  
106 const fieldsValue = getFieldsValue(); 105 const fieldsValue = getFieldsValue();
107 const newFieldValue = { 106 const newFieldValue = {
108 ...fieldsValue, 107 ...fieldsValue,
@@ -112,13 +111,14 @@ @@ -112,13 +111,14 @@
112 codeTown: fieldsValue.nameTown, 111 codeTown: fieldsValue.nameTown,
113 qrCode: qrcodePic.value, 112 qrCode: qrcodePic.value,
114 }; 113 };
  114 + // 表单校验
  115 + await validate();
  116 + compState.value.loading = true;
115 await updateEnterPriseDetail(newFieldValue); 117 await updateEnterPriseDetail(newFieldValue);
116 compState.value.loading = false; 118 compState.value.loading = false;
117 createMessage.success('更新信息成功'); 119 createMessage.success('更新信息成功');
118 setEnterPriseInfo(newFieldValue); 120 setEnterPriseInfo(newFieldValue);
119 - } catch (e) {  
120 - createMessage.error('更新信息失败');  
121 - } 121 + } catch (e) {}
122 }; 122 };
123 123
124 const userStore = useUserStore(); 124 const userStore = useUserStore();
@@ -20,9 +20,9 @@ @@ -20,9 +20,9 @@
20 <script lang="ts" setup> 20 <script lang="ts" setup>
21 import { Tabs, TabPane, Card } from 'ant-design-vue'; 21 import { Tabs, TabPane, Card } from 'ant-design-vue';
22 import { ref } from 'vue'; 22 import { ref } from 'vue';
23 - import EnterpriseInfo from './components/EnterpriseInfo.vue';  
24 - import CVIDraw from './components/CVIDraw.vue';  
25 - import AppDraw from './components/AppDraw.vue'; 23 + import EnterpriseInfo from './cpns/EnterpriseInfo.vue';
  24 + import CVIDraw from './cpns/CVIDraw.vue';
  25 + import AppDraw from './cpns/AppDraw.vue';
26 const activeKey = ref('企业信息'); 26 const activeKey = ref('企业信息');
27 </script> 27 </script>
28 28