云查询管理、新登陆页面

dianlixunjian
滕嵩 2024-08-04 09:24:08 +08:00
parent f2b0837ead
commit 445ecde28f
22 changed files with 1941 additions and 1 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 415 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 888 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 311 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 439 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 695 B

42
src/api/sys/cloud.ts Normal file
View File

@ -0,0 +1,42 @@
import { defHttp } from '@/utils/http/axios';
enum Api{
getLeftTree = '/api/SysDataItemDetail/Load',
addLeftItem = '/api/SysDataItemDetail/Add',
delLeftItem = '/api/SysDataItemDetail/Delete',
editLeftItem = '/api/SysDataItemDetail/Update',
LoadPage = '/api/DroneCloudQueryContent/LoadPage',
Get = '/api/DroneCloudQueryContent/Get',
Add = '/api/DroneCloudQueryContent/Add',
Update = '/api/DroneCloudQueryContent/Update',
Delete = '/api/DroneCloudQueryContent/Delete',
}
// 分类
export function getLeftTree(params) {
return defHttp.get({ url: Api.getLeftTree, params });
}
export function addLeftItem(params){
return defHttp.post({ url: Api.addLeftItem + '?code=' + params.itemCode, params });
}
export function delLeftItem(params){
return defHttp.post({ url: Api.delLeftItem + '?id=' + params.id });
}
// 云查询管理
export function LoadPage(params) {
return defHttp.get({ url: Api.LoadPage, params });
}
export function Get(params) {
return defHttp.get({ url: Api.Get, params });
}
export function Add(params) {
return defHttp.post({ url: Api.Add, params });
}
export function Update(params) {
return defHttp.post({ url: Api.Update, params });
}
export function Delete(params) {
return defHttp.post({ url: Api.Delete + '?id=' + params.id , params });
}

View File

@ -36,7 +36,8 @@ export const RootRoute: AppRouteRecordRaw = {
export const LoginRoute: AppRouteRecordRaw = {
path: '/login',
name: 'Login',
component: () => import('@/views/sys/login/Login.vue'),
// component: () => import('@/views/sys/login/Login.vue'),
component: () => import('@/views/sys/login_lindidiaocha/Login.vue'),
meta: {
title: t('routes.basic.login'),
},

View File

@ -0,0 +1,137 @@
<template>
<div class="categories-modal-container">
<a-form
ref="formRef"
:model="props.modalData.data"
:rules="props.modalData.type.indexOf('tree') > -1 ? treeRules : rightRules"
labelAlign="right"
:label-col="{ span: 6 }"
>
<template v-if="props.modalData.type.indexOf('tree') > -1">
<a-form-item label="名称" name="itemName">
<a-input v-model:value="props.modalData.data.itemName" />
</a-form-item>
<a-form-item label="类型" name="itemValue">
<a-select v-model:value="props.modalData.data.itemValue">
<a-select-option value="vector_data">矢量数据</a-select-option>
<a-select-option value="imgage_data">影像数据</a-select-option>
</a-select>
</a-form-item>
</template>
<template v-else>
<a-form-item label="ID" name="id" v-if="false">
<a-input v-model:value="props.modalData.data.id" disabled />
</a-form-item>
<a-form-item label="名称" name="name">
<a-input v-model:value="props.modalData.data.name" />
</a-form-item>
<a-form-item label="图层" name="layer">
<a-select v-model:value="props.modalData.data.layer">
<a-select-option value="1">图层1</a-select-option>
<a-select-option value="2">图层2</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="数据表" name="tableName">
<a-select v-model:value="props.modalData.data.tableName">
<a-select-option value="1">数据表1</a-select-option>
<a-select-option value="2">数据表2</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="叠加图层" name="overlayList">
<a-select v-model:value="props.modalData.data.overlayList" mode="multiple">
<a-select-option value="1" checked>天地图</a-select-option>
<a-select-option value="2">图层2</a-select-option>
<a-select-option value="3">图层3</a-select-option>
<a-select-option value="4">图层4</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="是否分类" name="isClass">
<a-switch
v-model:checked="props.modalData.data.isClass"
checked-children="是"
un-checked-children="否"
checked-value="1"
un-checked-value="0"
/>
</a-form-item>
<a-form-item label="分类字段" name="classField" v-if="props.modalData.data.isClass">
<a-select v-model:value="props.modalData.data.classField">
<a-select-option value="1">字段1</a-select-option>
<a-select-option value="2">字段2</a-select-option>
<a-select-option value="3">字段3</a-select-option>
<a-select-option value="4">字段4</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="分类名称" name="className" v-if="props.modalData.data.isClass">
<a-input v-model:value="props.modalData.data.className" />
</a-form-item>
<a-form-item label="选择面积计算字段" name="areaField">
<a-select v-model:value="props.modalData.data.areaField">
<a-select-option value="1">面积1</a-select-option>
<a-select-option value="2">面积2</a-select-option>
<a-select-option value="3">面积3</a-select-option>
<a-select-option value="4">面积4</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="是否合计" name="isSum">
<a-switch
v-model:checked="props.modalData.data.isSum"
checked-children="是"
un-checked-children="否"
checked-value="1"
un-checked-value="0"
/>
</a-form-item>
</template>
</a-form>
<div class="modal-footer">
<a-button style="margin-right: 10px" @click="closeModal"></a-button>
<a-button type="primary" @click="submit"></a-button>
</div>
</div>
</template>
<script setup lang="ts">
import { defineProps, defineEmits, ref } from 'vue';
const props = defineProps(['modalData', 'modalForm']);
const emit = defineEmits(['closeModal', 'submit']);
const formRef = ref();
const treeRules = {
itemName: [{ required: true, message: '名称不能为空', trigger: 'blur' }],
itemValue: [{ required: true, message: '类型不能为空', trigger: 'blur' }],
};
const rightRules = {
itemName: [{ required: true, message: '分类名称不能为空', trigger: 'blur' }],
itemCode: [{ required: true, message: '所属分类不能为空', trigger: 'blur' }],
};
const submit = () => {
formRef.value
.validate()
.then(() => {
emit('submit');
})
.catch((error) => {
console.log('error', error);
});
};
const closeModal = () => {
emit('closeModal');
formRef.value.resetFields();
};
const clearModalData = () => {
formRef.value.resetFields();
};
defineExpose({
clearModalData,
});
</script>
<style lang="scss" scoped>
.categories-modal-container {
padding: 10px 25px;
.modal-footer {
display: flex;
justify-content: flex-end;
margin-top: 20px;
}
}
</style>

View File

@ -0,0 +1,360 @@
<template>
<div class="page-div categories-page">
<div class="tree-div w-1/5 xl:w-1/6 m-4 mr-0">
<div class="header">
<div class="buttons-div">
<a-button
type="primary"
color="info"
style="margin-right: 10px"
@click="buttonClick('treeAdd')"
>
添加分类
</a-button>
<a-button type="primary" color="error" @click="buttonClick('treeDel')">
删除分类
</a-button>
</div>
</div>
<div class="content">
<div class="showTree">
<BasicTree
ref="treeRef"
:treeData="showLTree"
:loading="lLoading"
:fieldNames="{ key: 'itemValue', title: 'itemName' }"
@select="
(selectedKeys, { node }) => {
getLeftSelectId(node.itemDetailId);
changeTypeId(node.key);
}
"
/>
</div>
</div>
</div>
<div class="right-div w-4/5 xl:w-5/6">
<BasicTable @register="registerTable">
<template #toolbar>
<PermissionBtn @btnEvent="buttonClick"></PermissionBtn>
</template>
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'enabledMark'">
<a-tag v-if="record.enabledMark" color="success"></a-tag>
<a-tag v-else color="error">停用</a-tag>
</template>
</template>
</BasicTable>
</div>
<a-modal
class="categories-modal"
v-model:open="openModal"
:title="modalData.title"
:afterClose="clearModal"
>
<UseModal ref="modalForm" :modalData="modalData" @closeModal="closeModal" @submit="submit" />
</a-modal>
</div>
</template>
<script setup lang="ts">
import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
import UseModal from './Modal/index.vue';
import { BasicTree } from '@/components/Tree';
import { BasicTable, useTable } from '@/components/Table';
import { PermissionBtn } from '@/components/PermissionBtn/index';
import { ref, onMounted, reactive, watch, createVNode, unref } from 'vue';
import {
getLeftTree,
addLeftItem,
delLeftItem,
LoadPage,
Add,
Update,
Delete,
} from '@/api/sys/cloud';
import { columns, emptyRightItem, emptyLeftItem, searchFormSchema } from './util';
import { Modal, message } from 'ant-design-vue';
import dayjs from 'dayjs';
const modalForm = ref();
let lLoading = ref(false);
let typeId = ref('');
let selectTreeId = ref('');
let showLTree = ref([]);
let openModal = ref(false);
const modalData = reactive({
title: '',
data: {},
type: '',
});
const treeRef = ref();
const firstRequestCode = ref('');
const [registerTable, { reload, getSelectRows }] = useTable({
// beforeFetch: (params) => {
// console.log(firstRequestCode.value, 'before');
// if (firstRequestCode.value !== '') {
// params = { ...params, code: firstRequestCode.value };
// } else {
// params = { ...params, code: typeId.value };
// }
// return params;
// },
api: LoadPage,
columns,
formConfig: {
labelWidth: 120,
schemas: searchFormSchema,
},
showIndexColumn: false,
rowSelection: {
type: 'radio',
},
useSearchForm: true,
bordered: true,
showTableSetting: true,
handleSearchInfoFn(info) {
return info;
},
immediate: false,
afterFetch(res) {
firstRequestCode.value = '';
return res;
},
});
const getLeftTreeData = (isMounted) => {
lLoading.value = true;
getLeftTree({ code: 'cloudQueryManagement' })
.then((res) => {
showLTree.value = res;
lLoading.value = false;
if (isMounted && res.length > 0) {
firstRequestCode.value = res[0].key;
typeId.value = res[0].key;
unref(treeRef).setSelectedKeys([res[0].key]);
}
reload();
})
.catch((err) => {
lLoading.value = false;
});
};
onMounted(() => {
getLeftTreeData(true);
});
const changeTypeId = (value) => {
typeId.value = value;
reload();
};
const getLeftSelectId = (value) => {
selectTreeId.value = value;
};
const submit = () => {
let userName = localStorage.getItem('fireUserLoginName');
switch (modalData.type) {
case 'treeAdd':
addLeftItem({
...modalData.data,
createUserName: userName,
modifyUserName: userName,
createDate: dayjs().format('YYYY-MM-DD HH:mm:ss'),
modifyDate: dayjs().format('YYYY-MM-DD HH:mm:ss'),
enabledMark: 1,
sortCode: showLTree.value.length,
})
.then((res) => {
getLeftTreeData(false);
openModal.value = false;
})
.catch((err) => {
console.log(err);
});
break;
case 'btnAdd':
Add({
...modalData.data,
createUserName: userName,
modifyUserName: userName,
createDate: dayjs().format('YYYY-MM-DD HH:mm:ss'),
modifyDate: dayjs().format('YYYY-MM-DD HH:mm:ss'),
})
.then((res) => {
reload();
openModal.value = false;
})
.catch((err) => {
console.log(err);
});
break;
case 'btnEdit':
Update({
...modalData.data,
modifyUserName: userName,
modifyDate: dayjs().format('YYYY-MM-DD HH:mm:ss'),
})
.then((res) => {
reload();
openModal.value = false;
})
.catch((err) => {
console.log(err);
});
break;
default:
break;
}
};
const buttonClick = (diffType) => {
let check = false;
switch (diffType) {
case 'treeAdd':
openModal.value = true;
modalData.title = '添加分组';
modalData.data = emptyLeftItem;
modalData.type = diffType;
break;
case 'treeDel':
check = selectTreeId.value === '' ? true : false;
if (check) {
message.warning('请选择一条分组数据');
return;
}
Modal.confirm({
title: '是否确认删除?',
icon: createVNode(ExclamationCircleOutlined),
onCancel() {},
onOk() {
return delLeftItem({ id: selectTreeId.value })
.then((res) => {
getLeftTreeData(false);
typeId.value = '';
reload();
})
.catch((err) => {
console.log(err);
});
},
});
break;
case 'btnAdd':
openModal.value = true;
modalData.title = '添加';
modalData.data = emptyRightItem;
modalData.type = diffType;
break;
case 'btnDelete':
check = getSelectRows().length !== 1 ? true : false;
if (check) {
message.warning('请选择一条数据');
return;
}
Modal.confirm({
title: '是否确认删除?',
icon: createVNode(ExclamationCircleOutlined),
onCancel() {},
onOk() {
console.log(getSelectRows()[0]);
let id = getSelectRows()[0].id;
return Delete({ id: id })
.then((res) => {
reload();
})
.catch((err) => {
console.log(err);
});
},
});
break;
case 'btnEdit':
if (getSelectRows().length !== 1) {
message.warning('请选择一条数据');
return;
}
let editData = getSelectRows()[0];
console.log(editData);
modalData.title = '编辑';
modalData.data = { ...editData };
modalData.type = diffType;
openModal.value = true;
break;
}
};
const closeModal = () => {
openModal.value = false;
};
const clearModal = () => {
modalForm.value.clearModalData();
};
</script>
<style lang="scss" scoped>
.page-div {
position: relative;
display: flex;
height: calc(100% - 20px);
display: flex;
.tree-div {
background-color: #fff;
display: flex;
flex-direction: column;
.header {
display: flex;
flex-direction: column;
padding: 10px;
border-bottom: 1px solid #eee;
.buttons-div {
display: flex;
justify-content: left;
}
.search-div {
margin-top: 10px;
display: flex;
}
}
.content {
border-radius: 5px;
height: 100%;
overflow: auto;
.showTree {
height: 100%;
overflow: auto;
}
}
}
.right-div {
flex: 1;
display: flex;
flex-direction: column;
}
}
</style>
<style lang="scss">
.categories-page {
.tree-div {
.h-full {
height: auto;
}
.search-div {
.ant-btn-primary {
background-color: #2a7dc9;
}
.ant-input-search-button {
width: 42px;
}
}
}
}
.categories-modal {
.ant-modal-footer > button {
display: none;
}
.ant-modal-footer {
margin-top: 0px;
border-top: 0px;
}
}
// ant-table-header
</style>

View File

@ -0,0 +1,86 @@
export const columns = [
{
title: 'ID',
dataIndex: 'id',
resizable: true,
ifShow: false,
},
{
title: '名称',
dataIndex: 'name',
resizable: true,
width: 100,
},
{
title: '图层',
dataIndex: 'layer',
resizable: true,
width: 100,
},
{
title: '数据表',
dataIndex: 'tableName',
resizable: true,
width: 100,
},
{
title: '叠加图层',
dataIndex: 'overlayList',
resizable: true,
width: 100,
},
{
title: '是否分类',
dataIndex: 'isClass',
resizable: true,
width: 100,
},
{
title: '分类字段',
dataIndex: 'classField',
resizable: true,
width: 100,
},
{
title: '分类名称',
dataIndex: 'className',
resizable: true,
width: 100,
},
{
title: '选择面积计算字段',
dataIndex: 'areaField',
resizable: true,
width: 100,
},
{
title: '是否合计',
dataIndex: 'isSum',
resizable: true,
width: 100,
}
];
export const emptyLeftItem = {
itemName: '',
itemValue: '',
};
export const emptyRightItem = {
id: '',
name: '',
layer: '',
tableName: '',
overlayList: ['1'],
isClass: 0,
classField: '',
className: '',
areaField:'',
isSum: 0,
};
export const searchFormSchema = [
{
field: 'key',
label: '关键字',
component: 'Input',
colProps: { span: 8 },
},
];

View File

@ -0,0 +1,405 @@
<template>
<div style="padding: 24px; overflow-y: hidden">
<a-tabs v-model:activeKey="activeKey">
<a-tab-pane key="imageBoundary" tab="影像边界shp">
<div class="flex-column">
<a-row style="overflow-y: hidden">
<a-col :span="12" style="padding: 20px; border: 1px silver solid; margin-left: 10px">
<a-form
ref="form"
v-modal:model="currentAppForm"
labelAlign="right"
label-width="80px"
:label-col="labelCol"
:wrapper-col="wrapperCol"
size="mini"
>
<a-form-item label="当前版本">
<span style="font-size: 15px; font-weight: bold; color: #000">
<a-input v-model:value="currentAppInfo.edition" :bordered="false" />
</span>
</a-form-item>
<a-form-item label="版本号">
<a-input-number v-model:value="currentAppForm.edition" />
</a-form-item>
<a-form-item label="项目名称">
<a-input
v-model:value="currentAppForm.project_name"
defaultValue="drone_enforcement"
disabled="true"
/>
</a-form-item>
<a-form-item label="上传">
<a-upload
v-model:file-list="fileList"
:name="imageBoundary_name"
:multiple="true"
:customRequest="handleCustomRequest"
:headers="headers"
:progress="progress"
:beforeUpload="beforeUpload"
>
<a-button :loading="imageBoundary_loading"> 点击上传 </a-button>
</a-upload>
{{ fileName }}
<DeleteOutlined v-if="fileName != ''" @click="deleteFileName" />
</a-form-item>
<a-form-item label="描述信息">
<a-textarea
type="textarea"
v-model:value="currentAppForm.description"
:rows="4"
/>
</a-form-item>
<a-form-item label="是否必须更新" label-width="120px">
<a-radio-group v-model:value="currentAppForm.must_update" size="medium">
<a-radio :bordered="false" :value="1"></a-radio>
<a-radio :bordered="false" :value="0"></a-radio>
</a-radio-group>
</a-form-item>
<a-form-item :wrapper-col="{ offset: 10, span: 14 }">
<a-button type="primary" @click="onSubmit"></a-button>
</a-form-item>
</a-form>
</a-col>
</a-row>
</div>
</a-tab-pane>
<a-tab-pane key="imageRelease" tab="影像发布事件">
<div class="flex-column">
<a-row style="overflow-y: hidden">
<a-col :span="12" style="padding: 20px; border: 1px silver solid; margin-left: 10px">
<a-form
ref="fly_form"
v-model:model="fly_currentAppForm"
labelAlign="right"
label-width="80px"
:label-col="labelCol"
:wrapper-col="wrapperCol"
size="mini"
>
<a-form-item label="当前版本">
<span style="font-size: 15px; font-weight: bold; color: #000">
<a-input :bordered="false" />
</span>
</a-form-item>
<a-form-item label="版本号">
<a-input-number v-model:value="fly_currentAppForm.edition" />
</a-form-item>
<a-form-item label="项目名称">
<a-input v-model:value="fly_currentAppForm.project_name" />
</a-form-item>
<a-form-item label="上传">
<a-upload
v-model:file-list="fly_fileList"
:name="imageRelease_name"
:multiple="true"
:customRequest="handleCustomRequest"
:headers="headers"
:progress="progress"
:beforeUpload="beforeUpload"
>
<a-button :loading="imageRelease_loading"> 点击上传 </a-button>
</a-upload>
{{ fly_fileName }}
<DeleteOutlined v-if="fileName != ''" @click="deleteFileName" />
</a-form-item>
<a-form-item label="描述信息">
<a-textarea
type="textarea"
v-model:value="fly_currentAppForm.description"
:rows="4"
/>
</a-form-item>
<a-form-item label="是否必须更新" label-width="120px">
<a-radio-group v-model:value="fly_currentAppForm.must_update" size="medium">
<a-radio :bordered="false" :value="1"></a-radio>
<a-radio :bordered="false" :value="0"></a-radio>
</a-radio-group>
</a-form-item>
<a-form-item :wrapper-col="{ offset: 10, span: 14 }">
<a-button type="primary" @click="onFlyControlSubmit"></a-button>
</a-form-item>
</a-form>
</a-col>
</a-row>
</div>
</a-tab-pane>
<a-tab-pane key="history" tab="历史记录">
<div>
<BasicTable @register="registerTable">
<template #toolbar>
<a-button type="primary" @click="updateimage"></a-button>
</template>
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'enabledMark'">
<a-tag v-if="record.enabledMark" color="success"></a-tag>
<a-tag v-else color="error">停用</a-tag>
</template>
</template>
</BasicTable>
</div>
</a-tab-pane>
</a-tabs>
</div>
</template>
<script lang="ts" setup>
// vue
import { ref, onMounted } from 'vue';
// vben
import { useMessage } from '@/hooks/web/useMessage';
import { DeleteOutlined, UploadOutlined } from '@ant-design/icons-vue';
import { message, Upload } from 'ant-design-vue';
import type { UploadProps } from 'ant-design-vue';
import { BasicTable, useTable } from '@/components/Table';
import { useGlobSetting } from '@/hooks/setting';
import { columns, searchFormSchema } from './util';
// api
import { fun_GetUpdateFiles, fun_AddAppFiles } from '@/api/demo/version';
import { fun_Load, fun_Upload } from '@/api/demo/files';
const { createMessage } = useMessage();
const { apiUrl } = useGlobSetting();
//
const labelCol = { span: 6 };
const wrapperCol = { span: 18 };
// shp-
let currentAppInfo = ref({});
//
let activeKey = ref('imageBoundary');
//
let fileList: any = ref([]);
let fly_fileList: any = ref([]);
const imageBoundary_loading = ref<boolean>(false);
const imageRelease_loading = ref<boolean>(false);
const imageBoundary_name = ref<string>('');
const imageRelease_name = ref<string>('');
//
const fileName = ref('');
const fly_fileName = ref('');
let filePath = '';
let fly_filePath = '';
// shp
const currentAppForm = ref({
edition: '',
description: '',
filepath: '',
must_update: '',
project_name: '',
createuser: '',
createtime: '',
});
//
const fly_currentAppForm = ref({
edition: '',
description: '',
filepath: '',
must_update: '',
project_name: '',
createuser: '',
createtime: '',
});
//
async function getAppInfo() {
fun_GetUpdateFiles({ project: 'drone_enforcement' }).then(async (res) => {
if (res) {
currentAppForm.value.project_name = res.project_name;
currentAppForm.value.description = res.description;
currentAppInfo.value = res;
}
});
deleteFileName();
}
//
const handleCustomRequest = (file, progress) => {
if (activeKey.value === 'imageBoundary') {
fileList.value = [];
fun_Upload(file, progress)
.then((res: any) => {
if (res.data.result.length > 0) {
fileName.value = res.data.result[0].fileName;
filePath = res.data.result[0].filePath;
imageBoundary_loading.value = false;
}
})
.catch((err) => {
imageBoundary_loading.value = false;
file.onError(err);
createMessage.error(err.message);
});
} else if (activeKey.value === 'imageRelease') {
fly_fileList.value = [];
fun_Upload(file, progress)
.then((res: any) => {
if (res.data.result.length > 0) {
fly_fileName.value = res.data.result[0].fileName;
fly_filePath = res.data.result[0].filePath;
imageRelease_loading.value = false;
}
})
.catch((err) => {
imageRelease_loading.value = false;
file.onError(err);
createMessage.error(err.message);
});
}
};
//
const beforeUpload: UploadProps['beforeUpload'] = (file) => {
let extension = file.name.substring(file.name.lastIndexOf('.') + 1);
let size = file.size / 1024 / 1024;
const isApk = extension === 'apk';
const suitableSize = size < 100;
if (activeKey.value === 'imageBoundary') {
imageBoundary_name.value = file.name;
} else {
imageRelease_name.value = file.name;
}
if (!isApk) {
createMessage.error('只能上传后缀是.apk的文件');
}
if (!suitableSize) {
createMessage.error('文件大小不得超过100M');
}
if (isApk && suitableSize) {
if (activeKey.value === 'imageBoundary') {
imageBoundary_loading.value = true;
} else {
imageRelease_loading.value = true;
}
}
return (isApk && suitableSize) || Upload.LIST_IGNORE;
};
//
function deleteFileName() {
// shp-
if (activeKey.value === 'imageBoundary') {
fileName.value = '';
filePath = '';
fileList.value = [];
} else {
// -
fly_fileName.value = '';
fly_filePath = '';
fly_fileList.value = [];
}
}
// shp-
function onSubmit() {
if (fileName.value == '' || filePath == '') {
createMessage.warn(`请选择上传文件!`);
return;
}
if (currentAppForm.value.edition == '') {
createMessage.warn(`请先填写版本号!`);
return;
}
if (currentAppForm.value.project_name != 'drone_enforcement') {
createMessage.warn(`请不要修改项目名称!`);
currentAppForm.value.project_name = 'drone_enforcement';
return;
}
fun_Load({ key: fileName.value }).then((res) => {
if (res.items.length > 0) {
currentAppForm.value.filepath = res.items[0].filePath;
fun_AddAppFiles(currentAppForm.value).then((res2) => {
if (res2) {
createMessage.success(`上传成功!`);
currentAppForm.value = {
createtime: '',
createuser: '',
edition: '',
description: '',
filepath: '',
must_update: '',
project_name: '',
};
fileList.value = [];
getAppInfo();
} else {
createMessage.warn(`接口错误!`);
}
});
} else {
createMessage.warn(`上传文件出现错误!`);
}
});
}
// -
function onFlyControlSubmit() {
if (fly_fileName.value == '' || fly_filePath == '') {
createMessage.warn(`请选择上传文件!`);
return;
}
if (fly_currentAppForm.value.edition == '') {
createMessage.warn(`请先填写版本号!`);
return;
}
if (fly_currentAppForm.value.project_name == '') {
createMessage.warn(`请先填写项目名称!`);
return;
}
fun_Load({ key: fly_fileName.value }).then((res) => {
if (res.items.length > 0) {
fly_currentAppForm.value.filepath = res.items[0].filePath;
fun_AddAppFiles(fly_currentAppForm.value).then((res2) => {
if (res2) {
createMessage.success(`上传成功!`);
fly_currentAppForm.value = {
createtime: '',
createuser: '',
edition: '',
description: '',
filepath: '',
must_update: '',
project_name: '',
};
fly_fileList.value = [];
getAppInfo();
} else {
createMessage.warn(`接口错误!`);
}
});
} else {
createMessage.warn(`上传文件出现错误!`);
}
});
}
//
const [registerTable, { reload, getSelectRows }] = useTable({
// api: getRightTable,
columns,
formConfig: {
labelWidth: 120,
schemas: searchFormSchema,
},
showIndexColumn: false,
rowSelection: {
type: 'radio',
},
useSearchForm: true,
bordered: true,
showTableSetting: true,
handleSearchInfoFn(info) {
return info;
},
immediate: false,
});
onMounted(() => {
//
getAppInfo();
});
</script>

View File

@ -0,0 +1,43 @@
import dayjs from 'dayjs';
export const columns = [
{
title: 'ID',
dataIndex: 'id',
resizable: true,
ifShow: false,
},
{
title: '时间',
dataIndex: 'time',
resizable: true,
width: 100,
},
{
title: '名称',
dataIndex: 'name',
resizable: true,
width: 100,
},
{
title: '地址',
dataIndex: 'geoserver',
resizable: true,
width: 100,
},
];
export const searchFormSchema = [
{
field: '[startTime, endTime]',
label: '日期范围',
component: 'RangePicker',
colProps: { span: 8 },
componentProps: {
format: 'YYYY-MM',
picker: 'month',
placeholder: ['开始日期', '结束日期'],
defaultValue: [dayjs(dayjs(), 'YYYY-MM-DD'), dayjs(dayjs(), 'YYYY-MM-DD')]
},
},
];

View File

@ -0,0 +1,79 @@
<template>
<template v-if="getShow">
<Form class="p-4 enter-x" :model="formData" :rules="getFormRules" ref="formRef">
<FormItem name="account" class="enter-x">
<Input
size="large"
v-model:value="formData.account"
:placeholder="t('sys.login.userName')"
/>
</FormItem>
<FormItem name="mobile" class="enter-x">
<Input size="large" v-model:value="formData.mobile" :placeholder="t('sys.login.mobile')" />
</FormItem>
<FormItem name="sms" class="enter-x">
<CountdownInput
size="large"
v-model:value="formData.sms"
:placeholder="t('sys.login.smsCode')"
/>
</FormItem>
<FormItem>
<Button class="logon" size="large" block @click="handleReset" :loading="loading">
{{ t('common.resetText') }}
</Button>
<Button size="large" block class="mt-4" @click="handleBackLogin">
{{ t('sys.login.backSignIn') }}
</Button>
</FormItem>
</Form>
</template>
</template>
<script lang="ts" setup>
import { reactive, ref, computed, unref } from 'vue';
import LoginFormTitle from './LoginFormTitle.vue';
import { Form, Input, Button } from 'ant-design-vue';
import { CountdownInput } from '@/components/CountDown';
import { useI18n } from '@/hooks/web/useI18n';
import { useLoginState, useFormRules, LoginStateEnum } from './useLogin';
const FormItem = Form.Item;
const { t } = useI18n();
const { handleBackLogin, getLoginState } = useLoginState();
const { getFormRules } = useFormRules();
const formRef = ref();
const loading = ref(false);
const formData = reactive({
account: '',
mobile: '',
sms: '',
});
const getShow = computed(() => unref(getLoginState) === LoginStateEnum.RESET_PASSWORD);
async function handleReset() {
const form = unref(formRef);
if (!form) return;
await form.resetFields();
}
</script>
<style lang="less" scoped>
.logon {
display: flex;
align-items: center;
text-align: center;
justify-content: center;
background: #0f915f;
border-radius: 6px;
font-family: Alibaba PuHuiTi;
font-weight: 500;
font-size: 21px;
color: #ffffff;
}
</style>

View File

@ -0,0 +1,155 @@
<template>
<div class="login" style="background-color: #f0f0f0; width: 100%; height: 100%">
<div class="title">
<img src="/login_lindidiaocha/logo.png" />
<div class="title_span">
<a-col>
<a-row><span class="title_CN">临沂市自然资源综合监管平台</span></a-row>
<a-row>
<span class="title_EN">
Linyi City Natural Resources Comprehensive Supervision Platform
</span>
</a-row>
</a-col>
</div>
</div>
<div class="bg">
<div
class="bg_login"
:style="{
height: `${isRegister ? 600 : 400}px`,
}"
>
<LoginForm />
<ForgetPasswordForm />
<RegisterForm />
<MobileForm />
<QrCodeForm />
</div>
</div>
<div class="bottom">
版权所有临沂市自然资源和规划局 &nbsp;&nbsp;&nbsp;&nbsp; 技术支持山东慧创信息科技有限公司
</div>
</div>
</template>
<script lang="ts" setup>
import { unref } from 'vue';
import { AppDarkModeToggle, AppLocalePicker, AppLogo } from '@/components/Application';
import { useGlobSetting } from '@/hooks/setting';
import { useDesign } from '@/hooks/web/useDesign';
import { useI18n } from '@/hooks/web/useI18n';
import { useLocaleStore } from '@/store/modules/locale';
import { computed } from 'vue';
import ForgetPasswordForm from './ForgetPasswordForm.vue';
import LoginForm from './LoginForm.vue';
import MobileForm from './MobileForm.vue';
import QrCodeForm from './QrCodeForm.vue';
import RegisterForm from './RegisterForm.vue';
import { LoginStateEnum, useLoginState } from './useLogin';
const { getLoginState } = useLoginState();
const isRegister = computed(() => unref(getLoginState) === LoginStateEnum.REGISTER);
defineProps({
sessionTimeout: {
type: Boolean,
},
});
const globSetting = useGlobSetting();
const { prefixCls } = useDesign('login');
const { t } = useI18n();
const localeStore = useLocaleStore();
const showLocale = localeStore.getShowPicker;
const title = computed(() => globSetting?.title ?? '');
</script>
<style lang="less">
.login {
//
-webkit-user-select: none; /* Safari */
-moz-user-select: none; /* Firefox */
-ms-user-select: none; /* IE/Edge */
user-select: none;
}
.title {
position: relative;
display: inline-block;
top: calc((25% - 230px));
left: 143px;
height: 99px;
img {
width: 99px;
margin-right: 28px;
}
&_span {
display: inline-block;
position: relative;
top: 22px;
}
&_CN {
width: 100%;
height: 50px;
font-family: Alibaba PuHuiTi;
font-weight: bold;
font-size: 50px;
color: #131313;
letter-spacing: 3px;
}
&_EN {
position: relative;
top: 10px;
width: 100%;
height: 22px;
font-family: Alibaba PuHuiTi;
font-weight: 300;
font-size: 22px;
color: #131313;
text-shadow: 0px 3px 7px rgba(0, 0, 0, 0.35);
opacity: 0.3;
}
}
.bg {
position: relative;
top: 50px;
width: 100%;
height: calc(100% - 280px);
background-image: url('/login_lindidiaocha/bg.png');
background-position: center center;
background-repeat: no-repeat;
background-size: 100%;
display: flex;
align-items: center;
text-align: center;
&_login {
position: relative;
left: 1170px;
width: 294.1px;
background-color: #ffffff;
border-radius: 5px;
}
}
.bottom {
width: 628px;
height: 18px;
font-family: Alibaba PuHuiTi;
font-weight: 400;
font-size: 18px;
border-radius: 5px;
position: absolute;
bottom: 26px;
display: flex;
align-items: center;
text-align: center;
justify-content: center;
left: calc(50% - 628px / 2);
}
</style>

View File

@ -0,0 +1,203 @@
<template>
<LoginFormTitle class="login_title" />
<Form
class="p-4 enter-x"
:model="formData"
:rules="getFormRules"
ref="formRef"
v-show="getShow"
@keypress.enter="handleLogin"
>
<FormItem name="account">
<Input
size="large"
v-model:value="formData.account"
placeholder="请输入账户名"
class="fix-auto-fill"
>
<template #prefix>
<img src="/public/login_lindidiaocha/account.png" />
</template>
</Input>
</FormItem>
<FormItem name="password">
<InputPassword
size="large"
visibilityToggle
v-model:value="formData.password"
placeholder="密码"
>
<template #prefix>
<img src="/public/login_lindidiaocha/password.png" />
</template>
</InputPassword>
</FormItem>
<ARow>
<ACol :span="12">
<FormItem>
<Checkbox v-model:checked="rememberMe" size="small">
{{ t('sys.login.rememberMe') }}
</Checkbox>
</FormItem>
</ACol>
<ACol :span="12">
<FormItem
:style="{
'text-align': 'right',
}"
>
<Button type="link" size="small" @click="setLoginState(LoginStateEnum.RESET_PASSWORD)">
{{ t('sys.login.forgetPassword') }}
</Button>
</FormItem>
</ACol>
</ARow>
<FormItem>
<Button size="large" block @click="handleLogin" :loading="loading" class="logon">
立即登录
</Button>
</FormItem>
</Form>
<div class="bottom" v-if="getShow">
<Button type="link" block size="small" @click="setLoginState(LoginStateEnum.REGISTER)">
<template #icon>
<img src="/public/login_lindidiaocha/register.png" />
</template>
<span>&nbsp;&nbsp; 用户注册</span>
</Button>
|
<Button type="link" block size="small">
<template #icon>
<img src="/public/login_lindidiaocha/download.png" />
</template>
<span>&nbsp;&nbsp; 下载APP</span>
</Button>
</div>
</template>
<script lang="ts" setup>
import { reactive, ref, unref, computed } from 'vue';
import { Checkbox, Form, Input, Row, Col, Button, Divider } from 'ant-design-vue';
// import {
// GithubFilled,
// WechatFilled,
// AlipayCircleFilled,
// GoogleCircleFilled,
// TwitterCircleFilled,
// } from '@ant-design/icons-vue';
import LoginFormTitle from './LoginFormTitle.vue';
import { useI18n } from '@/hooks/web/useI18n';
import { useMessage } from '@/hooks/web/useMessage';
import { useUserStore } from '@/store/modules/user';
import { LoginStateEnum, useLoginState, useFormRules, useFormValid } from './useLogin';
import { useDesign } from '@/hooks/web/useDesign';
//import { onKeyStroke } from '@vueuse/core';
const ACol = Col;
const ARow = Row;
const FormItem = Form.Item;
const InputPassword = Input.Password;
const { t } = useI18n();
const { notification, createErrorModal } = useMessage();
const { prefixCls } = useDesign('login');
const userStore = useUserStore();
const { setLoginState, getLoginState } = useLoginState();
const { getFormRules } = useFormRules();
const formRef = ref();
const loading = ref(false);
const rememberMe = ref(false);
const formData = reactive({
// account: 'vben',
// password: '123456',
account: '',
password: '',
});
const { validForm } = useFormValid(formRef);
//onKeyStroke('Enter', handleLogin);
const getShow = computed(() => unref(getLoginState) === LoginStateEnum.LOGIN);
async function handleLogin() {
const data = await validForm();
if (!data) return;
try {
loading.value = true;
const userInfo = await userStore.login({
password: data.password,
account: data.account,
mode: 'none', //
});
console.log(userInfo);
localStorage.setItem('fireUserLoginName', userInfo.name);
if (userInfo) {
notification.success({
message: t('sys.login.loginSuccessTitle'),
description: `${t('sys.login.loginSuccessDesc')}: ${userInfo.name}`,
duration: 3,
});
}
} catch (error) {
createErrorModal({
title: t('sys.api.errorTip'),
content: (error as unknown as Error).message || t('sys.api.networkExceptionMsg'),
getContainer: () => document.body.querySelector(`.${prefixCls}`) || document.body,
});
} finally {
loading.value = false;
}
}
</script>
<style lang="less" scoped>
.login_title {
display: flex;
align-items: center;
text-align: center;
justify-content: center;
height: 68px;
font-family: Alibaba PuHuiTi;
font-weight: 900;
font-size: 22px;
color: #131313;
}
.logon {
display: flex;
align-items: center;
text-align: center;
justify-content: center;
background: #0f915f;
border-radius: 6px;
font-family: Alibaba PuHuiTi;
font-weight: 500;
font-size: 21px;
color: #ffffff;
}
.bottom {
position: absolute;
bottom: 0px;
left: 0px;
height: 50px;
width: 100%;
background: #ebf3f1;
Button {
font-family: Microsoft YaHei;
font-weight: 400;
font-size: 14px;
color: #999999;
}
}
</style>

View File

@ -0,0 +1,39 @@
<template>
<div class="login_title">
{{ getFormTitle }}
</div>
</template>
<script lang="ts" setup>
import { computed, unref } from 'vue';
import { useI18n } from '@/hooks/web/useI18n';
import { LoginStateEnum, useLoginState } from './useLogin';
const { t } = useI18n();
const { getLoginState } = useLoginState();
const getFormTitle = computed(() => {
const titleObj = {
[LoginStateEnum.RESET_PASSWORD]: '重置密码',
[LoginStateEnum.LOGIN]: '用户登录',
[LoginStateEnum.REGISTER]: t('sys.login.signUpFormTitle'),
[LoginStateEnum.MOBILE]: t('sys.login.mobileSignInFormTitle'),
[LoginStateEnum.QR_CODE]: t('sys.login.qrSignInFormTitle'),
};
return titleObj[unref(getLoginState)];
});
</script>
<style lang="less" scoped>
.login_title {
display: flex;
align-items: center;
text-align: center;
justify-content: center;
height: 68px;
font-family: Alibaba PuHuiTi;
font-weight: 900;
font-size: 22px;
color: #131313;
}
</style>

View File

@ -0,0 +1,63 @@
<template>
<div v-if="getShow">
<LoginFormTitle class="enter-x" />
<Form class="p-4 enter-x" :model="formData" :rules="getFormRules" ref="formRef">
<FormItem name="mobile" class="enter-x">
<Input
size="large"
v-model:value="formData.mobile"
:placeholder="t('sys.login.mobile')"
class="fix-auto-fill"
/>
</FormItem>
<FormItem name="sms" class="enter-x">
<CountdownInput
size="large"
class="fix-auto-fill"
v-model:value="formData.sms"
:placeholder="t('sys.login.smsCode')"
/>
</FormItem>
<FormItem class="enter-x">
<Button type="primary" size="large" block @click="handleLogin" :loading="loading">
{{ t('sys.login.loginButton') }}
</Button>
<Button size="large" block class="mt-4" @click="handleBackLogin">
{{ t('sys.login.backSignIn') }}
</Button>
</FormItem>
</Form>
</div>
</template>
<script lang="ts" setup>
import { reactive, ref, computed, unref } from 'vue';
import { Form, Input, Button } from 'ant-design-vue';
import { CountdownInput } from '@/components/CountDown';
import LoginFormTitle from './LoginFormTitle.vue';
import { useI18n } from '@/hooks/web/useI18n';
import { useLoginState, useFormRules, useFormValid, LoginStateEnum } from './useLogin';
const FormItem = Form.Item;
const { t } = useI18n();
const { handleBackLogin, getLoginState } = useLoginState();
const { getFormRules } = useFormRules();
const formRef = ref();
const loading = ref(false);
const formData = reactive({
mobile: '',
sms: '',
});
const { validForm } = useFormValid(formRef);
const getShow = computed(() => unref(getLoginState) === LoginStateEnum.MOBILE);
async function handleLogin() {
const data = await validForm();
if (!data) return;
console.log(data);
}
</script>

View File

@ -0,0 +1,31 @@
<template>
<div v-if="getShow">
<LoginFormTitle class="enter-x" />
<div class="enter-x min-w-64 min-h-64">
<QrCode
:value="qrCodeUrl"
class="enter-x flex justify-center xl:justify-start"
:width="280"
/>
<Divider class="enter-x">{{ t('sys.login.scanSign') }}</Divider>
<Button size="large" block class="mt-4 enter-x" @click="handleBackLogin">
{{ t('sys.login.backSignIn') }}
</Button>
</div>
</div>
</template>
<script lang="ts" setup>
import { computed, unref } from 'vue';
import LoginFormTitle from './LoginFormTitle.vue';
import { Button, Divider } from 'ant-design-vue';
import { QrCode } from '@/components/Qrcode';
import { useI18n } from '@/hooks/web/useI18n';
import { useLoginState, LoginStateEnum } from './useLogin';
const qrCodeUrl = 'https://vben.vvbin.cn/login';
const { t } = useI18n();
const { handleBackLogin, getLoginState } = useLoginState();
const getShow = computed(() => unref(getLoginState) === LoginStateEnum.QR_CODE);
</script>

View File

@ -0,0 +1,112 @@
<template>
<div v-if="getShow">
<Form class="p-4 enter-x" :model="formData" :rules="getFormRules" ref="formRef">
<FormItem name="account" class="enter-x">
<Input
class="fix-auto-fill"
size="large"
v-model:value="formData.account"
:placeholder="t('sys.login.userName')"
/>
</FormItem>
<FormItem name="mobile" class="enter-x">
<Input
size="large"
v-model:value="formData.mobile"
:placeholder="t('sys.login.mobile')"
class="fix-auto-fill"
/>
</FormItem>
<FormItem name="sms" class="enter-x">
<CountdownInput
size="large"
class="fix-auto-fill"
v-model:value="formData.sms"
:placeholder="t('sys.login.smsCode')"
/>
</FormItem>
<FormItem name="password" class="enter-x">
<StrengthMeter
size="large"
v-model:value="formData.password"
:placeholder="t('sys.login.password')"
/>
</FormItem>
<FormItem name="confirmPassword" class="enter-x">
<InputPassword
size="large"
visibilityToggle
v-model:value="formData.confirmPassword"
:placeholder="t('sys.login.confirmPassword')"
/>
</FormItem>
<FormItem class="enter-x" name="policy">
<!-- No logic, you need to deal with it yourself -->
<Checkbox v-model:checked="formData.policy" size="small">
{{ t('sys.login.policy') }}
</Checkbox>
</FormItem>
<Button class="logon" size="large" block @click="handleRegister" :loading="loading">
{{ t('sys.login.registerButton') }}
</Button>
<Button size="large" block class="mt-4 enter-x" @click="handleBackLogin">
{{ t('sys.login.backSignIn') }}
</Button>
</Form>
</div>
</template>
<script lang="ts" setup>
import { reactive, ref, unref, computed } from 'vue';
import LoginFormTitle from './LoginFormTitle.vue';
import { Form, Input, Button, Checkbox } from 'ant-design-vue';
import { StrengthMeter } from '@/components/StrengthMeter';
import { CountdownInput } from '@/components/CountDown';
import { useI18n } from '@/hooks/web/useI18n';
import { useLoginState, useFormRules, useFormValid, LoginStateEnum } from './useLogin';
const FormItem = Form.Item;
const InputPassword = Input.Password;
const { t } = useI18n();
const { handleBackLogin, getLoginState } = useLoginState();
const formRef = ref();
const loading = ref(false);
const formData = reactive({
account: '',
password: '',
confirmPassword: '',
mobile: '',
sms: '',
policy: false,
});
const { getFormRules } = useFormRules(formData);
const { validForm } = useFormValid(formRef);
const getShow = computed(() => unref(getLoginState) === LoginStateEnum.REGISTER);
async function handleRegister() {
const data = await validForm();
if (!data) return;
console.log(data);
}
</script>
<style lang="less" scoped>
.logon {
display: flex;
align-items: center;
text-align: center;
justify-content: center;
background: #0f915f;
border-radius: 6px;
font-family: Alibaba PuHuiTi;
font-weight: 500;
font-size: 21px;
color: #ffffff;
}
</style>

View File

@ -0,0 +1,54 @@
<template>
<transition>
<div :class="prefixCls" v-if="true">
<Login sessionTimeout />
</div>
</transition>
</template>
<script lang="ts" setup>
import { onBeforeUnmount, onMounted, ref } from 'vue';
import Login from './Login.vue';
import { useDesign } from '@/hooks/web/useDesign';
import { useUserStore } from '@/store/modules/user';
import { usePermissionStore } from '@/store/modules/permission';
import { useAppStore } from '@/store/modules/app';
import { PermissionModeEnum } from '@/enums/appEnum';
import { type Nullable } from '@vben/types';
const { prefixCls } = useDesign('st-login');
const userStore = useUserStore();
const permissionStore = usePermissionStore();
const appStore = useAppStore();
const userId = ref<Nullable<number | string>>(0);
const isBackMode = () => {
return appStore.getProjectConfig.permissionMode === PermissionModeEnum.BACK;
};
onMounted(() => {
// UserId
userId.value = userStore.getUserInfo?.userId;
console.log('Mounted', userStore.getUserInfo);
});
onBeforeUnmount(() => {
if (userId.value && userId.value !== userStore.getUserInfo.userId) {
// 便
document.location.reload();
} else if (isBackMode() && permissionStore.getLastBuildMenuTime === 0) {
// F5
document.location.reload();
}
});
</script>
<style lang="less" scoped>
@prefix-cls: ~'@{namespace}-st-login';
.@{prefix-cls} {
position: fixed;
z-index: 9999999;
width: 100%;
height: 100%;
background: @component-background;
}
</style>

View File

@ -0,0 +1,130 @@
import type { FormInstance } from 'ant-design-vue/lib/form/Form';
import type {
RuleObject,
NamePath,
Rule as ValidationRule,
} from 'ant-design-vue/lib/form/interface';
import { ref, computed, unref, Ref } from 'vue';
import { useI18n } from '@/hooks/web/useI18n';
export enum LoginStateEnum {
LOGIN,
REGISTER,
RESET_PASSWORD,
MOBILE,
QR_CODE,
}
const currentState = ref(LoginStateEnum.LOGIN);
// 这里也可以优化
// import { createGlobalState } from '@vueuse/core'
export function useLoginState() {
function setLoginState(state: LoginStateEnum) {
currentState.value = state;
}
const getLoginState = computed(() => currentState.value);
function handleBackLogin() {
setLoginState(LoginStateEnum.LOGIN);
}
return { setLoginState, getLoginState, handleBackLogin };
}
export function useFormValid<T extends Object = any>(formRef: Ref<FormInstance>) {
const validate = computed(() => {
const form = unref(formRef);
return form?.validate ?? ((_nameList?: NamePath) => Promise.resolve());
});
async function validForm() {
const form = unref(formRef);
if (!form) return;
const data = await form.validate();
return data as T;
}
return { validate, validForm };
}
export function useFormRules(formData?: Recordable) {
const { t } = useI18n();
const getAccountFormRule = computed(() => createRule(t('sys.login.accountPlaceholder')));
const getPasswordFormRule = computed(() => createRule(t('sys.login.passwordPlaceholder')));
const getSmsFormRule = computed(() => createRule(t('sys.login.smsPlaceholder')));
const getMobileFormRule = computed(() => createRule(t('sys.login.mobilePlaceholder')));
const validatePolicy = async (_: RuleObject, value: boolean) => {
return !value ? Promise.reject(t('sys.login.policyPlaceholder')) : Promise.resolve();
};
const validateConfirmPassword = (password: string) => {
return async (_: RuleObject, value: string) => {
if (!value) {
return Promise.reject(t('sys.login.passwordPlaceholder'));
}
if (value !== password) {
return Promise.reject(t('sys.login.diffPwd'));
}
return Promise.resolve();
};
};
const getFormRules = computed((): { [k: string]: ValidationRule | ValidationRule[] } => {
const accountFormRule = unref(getAccountFormRule);
const passwordFormRule = unref(getPasswordFormRule);
const smsFormRule = unref(getSmsFormRule);
const mobileFormRule = unref(getMobileFormRule);
const mobileRule = {
sms: smsFormRule,
mobile: mobileFormRule,
};
switch (unref(currentState)) {
// register form rules
case LoginStateEnum.REGISTER:
return {
account: accountFormRule,
password: passwordFormRule,
confirmPassword: [
{ validator: validateConfirmPassword(formData?.password), trigger: 'change' },
],
policy: [{ validator: validatePolicy, trigger: 'change' }],
...mobileRule,
};
// reset password form rules
case LoginStateEnum.RESET_PASSWORD:
return {
account: accountFormRule,
...mobileRule,
};
// mobile form rules
case LoginStateEnum.MOBILE:
return mobileRule;
// login form rules
default:
return {
account: accountFormRule,
password: passwordFormRule,
};
}
});
return { getFormRules };
}
function createRule(message: string): ValidationRule[] {
return [
{
required: true,
message,
trigger: 'change',
},
];
}