Commit e622c0a2 authored by 张伯涛's avatar 张伯涛

用户管理初步调整

parent 71a8ead4
......@@ -13,7 +13,7 @@ import {
import { defHttp } from '@/utils/http/axios';
enum Api {
AccountList = '/system/getAccountList',
AccountList = '/system/user/list',
IsAccountExist = '/system/accountExist',
DeptList = '/system/getDeptList',
setRoleStatus = '/system/setRoleStatus',
......
......@@ -13,7 +13,7 @@ export default {
// The number field name of each page displayed in the background
sizeField: 'pageSize',
// Field name of the form data returned by the interface
listField: 'items',
listField: 'rows',
// Total number of tables returned by the interface field name
totalField: 'total',
},
......
......@@ -167,6 +167,7 @@ const transform: AxiosTransform = {
* @description: 响应拦截器处理
*/
responseInterceptors: (res: AxiosResponse<any>) => {
console.log('ree',res)
return res;
},
......@@ -174,6 +175,7 @@ const transform: AxiosTransform = {
* @description: 响应错误处理
*/
responseInterceptorsCatch: (axiosInstance: AxiosInstance, error: any) => {
console.log('3333333333333333',error)
const { t } = useI18n();
const errorLogStore = useErrorLogStoreWithOut();
errorLogStore.addAjaxErrorInfo(error);
......
......@@ -139,6 +139,7 @@
username: data.account,
mode: 'none', //不要默认的错误提示
});
console.log('userInfo',userInfo)
if (userInfo) {
notification.success({
message: t('sys.login.loginSuccessTitle'),
......@@ -147,6 +148,7 @@
});
}
} catch (error) {
console.log('error',error)
createErrorModal({
title: t('sys.api.errorTip'),
content: (error as unknown as Error).message || t('sys.api.networkExceptionMsg'),
......
<template>
<PageWrapper
:title="`用户` + userId + `的资料`"
content="这是用户资料详情页面。本页面仅用于演示相同路由在tab中打开多个页面并且显示不同的数据"
contentBackground
@back="goBack"
>
<template #extra>
<a-button type="primary" danger> 禁用账号 </a-button>
<a-button type="primary"> 修改密码 </a-button>
</template>
<template #footer>
<a-tabs default-active-key="detail" v-model:activeKey="currentKey">
<a-tab-pane key="detail" tab="用户资料" />
<a-tab-pane key="logs" tab="操作日志" />
</a-tabs>
</template>
<div class="pt-4 m-4 desc-wrap">
<template v-if="currentKey == 'detail'">
<div v-for="i in 10" :key="i">这是用户{{ userId }}资料Tab</div>
</template>
<template v-if="currentKey == 'logs'">
<div v-for="i in 10" :key="i">这是用户{{ userId }}操作日志Tab</div>
</template>
</div>
</PageWrapper>
</template>
<script lang="ts" setup>
import { ref } from 'vue';
import { useRoute } from 'vue-router';
import { PageWrapper } from '@/components/Page';
import { useGo } from '@/hooks/web/usePage';
import { useTabs } from '@/hooks/web/useTabs';
import { Tabs } from 'ant-design-vue';
defineOptions({ name: 'AccountDetail' });
const ATabs = Tabs;
const ATabPane = Tabs.TabPane;
const route = useRoute();
const go = useGo();
// 此处可以得到用户ID
const userId = ref(route.params?.id);
const currentKey = ref('detail');
const { setTitle } = useTabs();
// TODO
// 本页代码仅作演示,实际应当通过userId从接口获得用户的相关资料
// 设置Tab的标题(不会影响页面标题)
setTitle('详情:用户' + userId.value);
// 页面左侧点击返回链接时的操作
function goBack() {
// 本例的效果时点击返回始终跳转到账号列表页,实际应用时可返回上一页
go('/system/account');
}
</script>
<style></style>
<template>
<BasicModal v-bind="$attrs" @register="registerModal" :title="getTitle" @ok="handleSubmit">
<BasicForm @register="registerForm" />
</BasicModal>
</template>
<script lang="ts" setup>
import { ref, computed, unref } from 'vue';
import { BasicModal, useModalInner } from '@/components/Modal';
import { BasicForm, useForm } from '@/components/Form';
import { accountFormSchema } from './account.data';
import { getDeptList } from '@/api/demo/system';
defineOptions({ name: 'AccountModal' });
const emit = defineEmits(['success', 'register']);
const isUpdate = ref(true);
const rowId = ref('');
const [registerForm, { setFieldsValue, updateSchema, resetFields, validate }] = useForm({
labelWidth: 100,
baseColProps: { span: 24 },
schemas: accountFormSchema,
showActionButtonGroup: false,
actionColOptions: {
span: 23,
},
});
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
resetFields();
setModalProps({ confirmLoading: false });
isUpdate.value = !!data?.isUpdate;
if (unref(isUpdate)) {
rowId.value = data.record.id;
setFieldsValue({
...data.record,
});
}
const treeData = await getDeptList();
updateSchema([
{
field: 'pwd',
show: !unref(isUpdate),
},
{
field: 'dept',
componentProps: { treeData },
},
]);
});
const getTitle = computed(() => (!unref(isUpdate) ? '新增账号' : '编辑账号'));
async function handleSubmit() {
try {
const values = await validate();
setModalProps({ confirmLoading: true });
// TODO custom api
console.log(values);
closeModal();
emit('success', { isUpdate: unref(isUpdate), values: { ...values, id: rowId.value } });
} finally {
setModalProps({ confirmLoading: false });
}
}
</script>
<template>
<div class="m-4 mr-0 overflow-hidden bg-white">
<BasicTree
title="部门列表"
toolbar
search
treeWrapperClassName="h-[calc(100%-35px)] overflow-auto"
:clickRowToExpand="false"
:treeData="treeData"
:fieldNames="{ key: 'id', title: 'deptName' }"
@select="handleSelect"
/>
</div>
</template>
<script lang="ts" setup>
import { onMounted, ref } from 'vue';
import { BasicTree, TreeItem } from '@/components/Tree';
import { getDeptList } from '@/api/demo/system';
defineOptions({ name: 'DeptTree' });
const emit = defineEmits(['select']);
const treeData = ref<TreeItem[]>([]);
async function fetch() {
treeData.value = (await getDeptList()) as unknown as TreeItem[];
}
function handleSelect(keys) {
emit('select', keys[0]);
}
onMounted(() => {
fetch();
});
</script>
import { getAllRoleList, isAccountExist } from '@/api/demo/system';
import { BasicColumn, FormSchema } from '@/components/Table';
/**
* transform mock data
* {
* 0: '华东分部',
* '0-0': '华东分部-研发部'
* '0-1': '华东分部-市场部',
* ...
* }
*/
export const deptMap = (() => {
const pDept = ['华东分部', '华南分部', '西北分部'];
const cDept = ['研发部', '市场部', '商务部', '财务部'];
return pDept.reduce((map, p, pIdx) => {
map[pIdx] = p;
cDept.forEach((c, cIndex) => (map[`${pIdx}-${cIndex}`] = `${p}-${c}`));
return map;
}, {});
})();
export const columns: BasicColumn[] = [
{
title: '登录名',
dataIndex: 'username',
width: 120,
},
{
title: '姓名',
dataIndex: 'name',
width: 120,
},
{
title: '手机号',
dataIndex: 'phone',
width: 120,
},
{
title: '状态',
dataIndex: 'flag',
width: 180,
},
{
title: '创建时间',
dataIndex: 'createDate',
width: 200,
},
// {
// title: '所属部门',
// dataIndex: 'dept',
// customRender: ({ value }) => {
// return deptMap[value];
// },
// },
];
export const searchFormSchema: FormSchema[] = [
{
field: 'username',
label: '登录名',
component: 'Input',
colProps: { span: 8 },
},
{
field: 'flag',
label: '状态',
component: 'Select',
componentProps: {
options: [
{ label: '启用', value: '1' },
{ label: '停用', value: '0' },
],
},
colProps: { span: 8 },
},
];
export const accountFormSchema: FormSchema[] = [
{
field: 'account',
label: '用户名',
component: 'Input',
helpMessage: ['本字段演示异步验证', '不能输入带有admin的用户名'],
rules: [
{
required: true,
message: '请输入用户名',
},
{
trigger: 'blur',
validator(_, value) {
return new Promise((resolve, reject) => {
if (!value) return resolve();
isAccountExist(value)
.then(resolve)
.catch((err) => {
reject(err.message || '验证失败');
});
});
},
},
],
},
{
field: 'pwd',
label: '密码',
component: 'InputPassword',
required: true,
ifShow: false,
},
{
label: '角色',
field: 'role',
component: 'ApiSelect',
componentProps: {
api: getAllRoleList,
labelField: 'roleName',
valueField: 'roleValue',
},
required: true,
},
{
field: 'dept',
label: '所属部门',
component: 'TreeSelect',
componentProps: {
fieldNames: {
label: 'deptName',
value: 'id',
},
getPopupContainer: () => document.body,
},
required: true,
},
{
field: 'nickname',
label: '昵称',
component: 'Input',
required: true,
},
{
label: '邮箱',
field: 'email',
component: 'Input',
required: true,
},
{
label: '备注',
field: 'remark',
component: 'InputTextArea',
},
];
<template>
<div>
用戶管理
</div>
<PageWrapper dense contentFullHeight fixedHeight contentClass="flex">
<!-- <DeptTree class="w-1/4 xl:w-1/5" @select="handleSelect" />-->
<BasicTable @register="registerTable" class="w-3/4 xl:w-4/5" :searchInfo="searchInfo">
<template #toolbar>
<a-button type="primary" @click="handleCreate">新增</a-button>
<a-button type="primary" @click="handleExport">导出</a-button>
</template>
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'action'">
<TableAction
:actions="[
{
icon: 'clarity:info-standard-line',
tooltip: '详情',
onClick: handleView.bind(null, record),
},
{
icon: 'clarity:note-edit-line',
tooltip: '编辑',
onClick: handleEdit.bind(null, record),
},
{
icon: 'ant-design:delete-outlined',
color: 'error',
tooltip: '删除',
popConfirm: {
title: '是否确认删除',
placement: 'left',
confirm: handleDelete.bind(null, record),
},
},
]"
/>
</template>
</template>
</BasicTable>
<AccountModal @register="registerModal" @success="handleSuccess" />
</PageWrapper>
</template>
<script lang="ts" setup>
import { reactive } from 'vue';
</script>
import { BasicTable, useTable, TableAction } from '@/components/Table';
import { getAccountList } from '@/api/demo/system';
import { PageWrapper } from '@/components/Page';
import DeptTree from './DeptTree.vue';
import { useModal } from '@/components/Modal';
import AccountModal from './AccountModal.vue';
import { columns, searchFormSchema } from './account.data';
import { useGo } from '@/hooks/web/usePage';
defineOptions({ name: 'AccountManagement' });
const go = useGo();
const [registerModal, { openModal }] = useModal();
const searchInfo = reactive<Recordable>({});
const [registerTable, { reload, updateTableDataRecord, getSearchInfo }] = useTable({
title: '用户管理列表',
api: getAccountList,
rowKey: 'id',
columns,
formConfig: {
labelWidth: 120,
schemas: searchFormSchema,
autoSubmitOnEnter: true,
},
useSearchForm: true,
showTableSetting: false,
bordered: true,
handleSearchInfoFn(info) {
console.log('handleSearchInfoFn', info);
return info;
},
actionColumn: {
width: 120,
title: '操作',
dataIndex: 'action',
// slots: { customRender: 'action' },
},
});
<style scoped>
function handleCreate() {
openModal(true, {
isUpdate: false,
});
}
</style>
function handleEdit(record: Recordable) {
console.log(record);
openModal(true, {
record,
isUpdate: true,
});
}
function handleDelete(record: Recordable) {
console.log(record);
}
function handleExport() {
console.log(getSearchInfo());
}
function handleSuccess({ isUpdate, values }) {
if (isUpdate) {
// 演示不刷新表格直接更新内部数据。
// 注意:updateTableDataRecord要求表格的rowKey属性为string并且存在于每一行的record的keys中
const result = updateTableDataRecord(values.id, values);
console.log(result);
} else {
reload();
}
}
function handleSelect(deptId = '') {
searchInfo.deptId = deptId;
reload();
}
function handleView(record: Recordable) {
go('/system/account_detail/' + record.id);
}
</script>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment