490 lines
13 KiB
Vue
490 lines
13 KiB
Vue
<template>
|
|
<div class="container">
|
|
<Breadcrumb :items="['menu.role', 'menu.role.manage']" />
|
|
|
|
<a-card class="general-card" :title="$t('menu.list.searchTable')">
|
|
<a-row>
|
|
<a-col :flex="1">
|
|
<a-form
|
|
:model="formModel"
|
|
:label-col-props="{ span: 6 }"
|
|
:wrapper-col-props="{ span: 18 }"
|
|
label-align="left"
|
|
>
|
|
<a-row :gutter="16">
|
|
<a-col :span="7">
|
|
<a-form-item
|
|
field="username"
|
|
:label="$t('searchTable.form.username')"
|
|
>
|
|
<a-input
|
|
v-model="formModel.username"
|
|
:placeholder="$t('searchTable.form.username.placeholder')"
|
|
/>
|
|
</a-form-item>
|
|
</a-col>
|
|
|
|
<a-col :span="9">
|
|
<a-form-item
|
|
field="phone"
|
|
:label="$t('searchTable.form.phone')"
|
|
>
|
|
<a-input
|
|
v-model="formModel.phone"
|
|
:placeholder="$t('searchTable.form.phone.placeholder')"
|
|
/>
|
|
</a-form-item>
|
|
</a-col>
|
|
|
|
<a-col :span="8">
|
|
<a-form-item
|
|
field="email"
|
|
:label="$t('searchTable.form.email')"
|
|
>
|
|
<a-input
|
|
v-model="formModel.email"
|
|
:placeholder="$t('searchTable.form.email.placeholder')"
|
|
/>
|
|
</a-form-item>
|
|
</a-col>
|
|
|
|
<!-- <a-col :span="9">
|
|
<a-form-item field="role" :label="$t('searchTable.form.role')">
|
|
<a-select
|
|
v-model="formModel.role"
|
|
:options="roleOptions"
|
|
:placeholder="$t('searchTable.form.role.placeholder')"
|
|
/>
|
|
</a-form-item>
|
|
</a-col> -->
|
|
</a-row>
|
|
</a-form>
|
|
</a-col>
|
|
<a-divider style="height: 84px" direction="vertical" />
|
|
|
|
<!-- 更新和重置按钮 -->
|
|
<a-col :flex="'86px'" style="text-align: right">
|
|
<a-space direction="vertical" :size="18">
|
|
<a-button type="primary" @click="search">
|
|
<template #icon>
|
|
<icon-search />
|
|
</template>
|
|
{{ $t('searchTable.form.search') }}
|
|
</a-button>
|
|
<a-button @click="reset">
|
|
<template #icon>
|
|
<icon-refresh />
|
|
</template>
|
|
{{ $t('searchTable.form.reset') }}
|
|
</a-button>
|
|
</a-space>
|
|
</a-col>
|
|
</a-row>
|
|
|
|
<a-divider style="margin-top: 0" />
|
|
<a-row :gutter="10">
|
|
<a-col :span="9">
|
|
<a-button
|
|
type="primary"
|
|
@click="handleClick"
|
|
style="margin-right: 16px"
|
|
>
|
|
<template #icon>
|
|
<icon-plus />
|
|
</template>
|
|
{{ $t('searchTable.operation.create') }}
|
|
</a-button>
|
|
|
|
<a-button type="primary" status="danger" @click="handleDelete">
|
|
<template #icon>
|
|
<icon-close />
|
|
</template>
|
|
{{ $t('searchTable.operation.delete') }}
|
|
</a-button>
|
|
</a-col>
|
|
</a-row>
|
|
|
|
<a-divider style="margin-top: 16px" />
|
|
<a-table
|
|
row-key="id"
|
|
:loading="loading"
|
|
:pagination="false"
|
|
:columns="(cloneColumns as TableColumnData[])"
|
|
:data="renderData"
|
|
:bordered="false"
|
|
:size="size"
|
|
:row-selection="true"
|
|
@select="selectRow"
|
|
>
|
|
<template #index="{ rowIndex }">
|
|
{{ rowIndex + 1 + (pagination.page - 1) * pagination.size }}
|
|
</template>
|
|
<template #enabled="{ record }">
|
|
<a-switch
|
|
:model-value="record.enabled"
|
|
:checked-value="true"
|
|
:unchecked-value="false"
|
|
@change="enabledStatus(record)"
|
|
/>
|
|
</template>
|
|
<template #operations="{ record }">
|
|
<a-button
|
|
type="text"
|
|
size="small"
|
|
@click="handleClick(record, 'modify')"
|
|
>
|
|
{{ $t('searchTable.columns.operations.detail') }}
|
|
</a-button>
|
|
</template>
|
|
</a-table>
|
|
<a-space direction="vertical" size="large" style="margin-top: 16px">
|
|
<a-pagination
|
|
show-total
|
|
:current="pagination.page"
|
|
@change="onPageChange"
|
|
:page-size="pagination.pageSize"
|
|
:total="pagination.total"
|
|
/>
|
|
</a-space>
|
|
|
|
<a-modal
|
|
v-model:visible="visible"
|
|
:title="dialogTitle"
|
|
:mask-closable="false"
|
|
@cancel="handleCancel"
|
|
:before-ok="handleBeforeOk"
|
|
>
|
|
<a-form :model="formDate">
|
|
<a-form-item field="username" :label="$t('add.user.info.username')">
|
|
<a-input
|
|
v-model="formDate.username"
|
|
:placeholder="$t('add.user.info.username.placeholder')"
|
|
:required="required"
|
|
:rules="[
|
|
{
|
|
required: true,
|
|
message: '用户名不能为空',
|
|
},
|
|
]"
|
|
/>
|
|
</a-form-item>
|
|
<a-form-item field="password" :label="$t('add.user.info.password')">
|
|
<a-input-password
|
|
v-model="formDate.password"
|
|
:placeholder="$t('add.user.info.password.placeholder')"
|
|
:rules="[
|
|
{
|
|
required: true,
|
|
message: '密码不能为空',
|
|
},
|
|
]"
|
|
/>
|
|
</a-form-item>
|
|
<a-form-item field="phone" :label="$t('add.user.info.phone')">
|
|
<a-input
|
|
v-model="formDate.phone"
|
|
:placeholder="$t('add.user.info.phone.placeholder')"
|
|
:rules="[
|
|
{
|
|
required: true,
|
|
message: '手机号码不能为空',
|
|
},
|
|
]"
|
|
/>
|
|
</a-form-item>
|
|
<a-form-item field="email" :label="$t('add.user.info.email')">
|
|
<a-input
|
|
v-model="formDate.email"
|
|
:placeholder="$t('add.user.info.email.placeholder')"
|
|
/>
|
|
</a-form-item>
|
|
<a-form-item field="nickName" :label="$t('add.user.info.nickName')">
|
|
<a-input
|
|
v-model="formDate.nickName"
|
|
:placeholder="$t('add.user.info.nickName.placeholder')"
|
|
/>
|
|
</a-form-item>
|
|
<a-form-item field="address" :label="$t('add.user.info.address')">
|
|
<a-input
|
|
v-model="formDate.address"
|
|
:placeholder="$t('add.user.info.address.placeholder')"
|
|
/>
|
|
</a-form-item>
|
|
<a-form-item field="dept" :label="$t('add.user.info.dept')">
|
|
<a-select
|
|
v-model="formDate.dept"
|
|
:placeholder="$t('add.user.info.dept.placeholder')"
|
|
>
|
|
<a-option value="user">user</a-option>
|
|
<a-option value="auditor">auditor</a-option>
|
|
<a-option value="admin">admin</a-option>
|
|
</a-select>
|
|
</a-form-item>
|
|
</a-form>
|
|
</a-modal>
|
|
</a-card>
|
|
</div>
|
|
</template>
|
|
<script lang="ts" setup>
|
|
import { ref, computed, reactive, watch } from 'vue';
|
|
import { useI18n } from 'vue-i18n';
|
|
import type { SelectOptionData } from '@arco-design/web-vue/es/select/interface';
|
|
import type { TableColumnData } from '@arco-design/web-vue/es/table/interface';
|
|
import { useRoleStore } from '@/store';
|
|
import { ListParams } from '@/api/list';
|
|
import { Pagination } from '@/types/global';
|
|
import { ListRecord } from '@/api/role';
|
|
import { Message } from '@arco-design/web-vue';
|
|
import useLoading from '@/hooks/loading';
|
|
import { status } from 'nprogress';
|
|
import { stat } from 'fs';
|
|
|
|
type SizeProps = 'mini' | 'small' | 'medium' | 'large';
|
|
type Column = TableColumnData & { checked?: true };
|
|
|
|
// 搜索的条件数据
|
|
const generateFormModel = () => {
|
|
return {
|
|
username: '',
|
|
phone: '',
|
|
email: '',
|
|
role: '',
|
|
};
|
|
};
|
|
|
|
const { t } = useI18n();
|
|
const { loading, setLoading } = useLoading();
|
|
const roleStore = useRoleStore();
|
|
const renderData = ref<ListRecord[]>([]);
|
|
const cloneColumns = ref<Column[]>([]);
|
|
const showColumns = ref<Column[]>([]);
|
|
const size = ref<SizeProps>('medium');
|
|
const seleteRowList = ref();
|
|
const visible = ref(false);
|
|
const messageType = ref();
|
|
let formDifer = {};
|
|
const dialogTitle = ref('添加用户');
|
|
const form = () => {
|
|
return {
|
|
id: '',
|
|
username: '',
|
|
password: '',
|
|
phone: '',
|
|
email: '',
|
|
nickName: '',
|
|
address: '',
|
|
dept: '',
|
|
};
|
|
};
|
|
|
|
const formDate = ref(form());
|
|
// 打开弹窗
|
|
const handleClick = (record: any, type: string) => {
|
|
if (type === 'modify') {
|
|
messageType.value = 'modify';
|
|
formDifer = record;
|
|
formDate.value = { ...record };
|
|
dialogTitle.value = '修改用户信息';
|
|
}
|
|
visible.value = true;
|
|
};
|
|
|
|
// 做出只修改的部分
|
|
const diffDataForm = (newData: any, oldData: any) => {
|
|
const result = {}; // 报错修改的字段内容
|
|
Object.keys(oldData).forEach((key) => {
|
|
if (oldData[key] !== newData[key] || key === 'id') {
|
|
result[key] = newData[key];
|
|
}
|
|
});
|
|
return result;
|
|
};
|
|
|
|
// 提交
|
|
const handleBeforeOk = async (done: any) => {
|
|
try {
|
|
formDifer = diffDataForm(formDate.value, formDifer);
|
|
|
|
if (dialogTitle.value === '修改用户信息') {
|
|
const res = await roleStore.updateUser(formDifer);
|
|
if (res.status === 200) {
|
|
Message.success({
|
|
content: t('add.user.info.sucess'),
|
|
duration: 3 * 1000,
|
|
});
|
|
} else {
|
|
Message.error({
|
|
content: t('add.user.info.fail'),
|
|
duration: 3 * 1000,
|
|
});
|
|
}
|
|
} else {
|
|
const res = await roleStore.addUser(formDate.value);
|
|
if (res.status === 200) {
|
|
Message.success({
|
|
content: t('modify.user.info.sucess'),
|
|
duration: 3 * 1000,
|
|
});
|
|
} else {
|
|
Message.error({
|
|
content: t('modify.user.info.fail'),
|
|
duration: 3 * 1000,
|
|
});
|
|
}
|
|
}
|
|
} catch (err) {
|
|
// you can report use errorHandler or other
|
|
} finally {
|
|
formDate.value = form();
|
|
search();
|
|
}
|
|
};
|
|
|
|
// 是否启用
|
|
const enabledStatus = async (record: string) => {
|
|
const res = await roleStore.enabledStatus(record.id);
|
|
search();
|
|
};
|
|
|
|
// 选择
|
|
const selectRow = (rowKeys: string[]) => {
|
|
seleteRowList.value = rowKeys;
|
|
};
|
|
|
|
// 删除
|
|
const handleDelete = async () => {
|
|
const res = await roleStore.deleteUser(seleteRowList.value);
|
|
};
|
|
|
|
// 关闭弹窗
|
|
const handleCancel = () => {
|
|
formDate.value = form();
|
|
visible.value = false;
|
|
dialogTitle.value = '添加用户';
|
|
};
|
|
|
|
// 映射到formModel
|
|
const formModel = ref(generateFormModel());
|
|
|
|
// 基础分页查询的信息
|
|
const basePagination: Pagination = {
|
|
page: 1,
|
|
size: 10,
|
|
};
|
|
|
|
const pagination = reactive({
|
|
...basePagination,
|
|
});
|
|
|
|
//
|
|
const onPageChange = (current: number) => {
|
|
const page = current;
|
|
fetchData({ ...basePagination, page });
|
|
};
|
|
|
|
// 调用接口请求数据
|
|
const fetchData = async (params: { page: 1; size: 10 }) => {
|
|
setLoading(true);
|
|
try {
|
|
const { data } = await roleStore.getUserInfo(params);
|
|
renderData.value = data.list;
|
|
pagination.page = params.page;
|
|
pagination.total = data.total;
|
|
} catch (err) {
|
|
// you can report use errorHandler or other
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
};
|
|
|
|
// 查询
|
|
const search = () => {
|
|
fetchData({
|
|
...basePagination,
|
|
...formModel.value,
|
|
} as unknown as any);
|
|
};
|
|
|
|
search();
|
|
|
|
// 重置
|
|
const reset = () => {
|
|
formModel.value = generateFormModel();
|
|
};
|
|
|
|
// 表格
|
|
const columns = computed<TableColumnData[]>(() => [
|
|
{
|
|
title: t('searchTable.columns.index'),
|
|
dataIndex: 'index',
|
|
slotName: 'index',
|
|
},
|
|
{
|
|
title: t('searchTable.columns.username'),
|
|
dataIndex: 'username',
|
|
},
|
|
{
|
|
title: t('searchTable.columns.phone'),
|
|
dataIndex: 'phone',
|
|
},
|
|
{
|
|
title: t('searchTable.columns.email'),
|
|
dataIndex: 'email',
|
|
},
|
|
{
|
|
title: t('searchTable.columns.nickName'),
|
|
dataIndex: 'nickName',
|
|
},
|
|
{
|
|
title: t('searchTable.columns.address'),
|
|
dataIndex: 'address',
|
|
},
|
|
{
|
|
title: t('searchTable.columns.enabled'),
|
|
dataIndex: 'enabled',
|
|
slotName: 'enabled',
|
|
},
|
|
{
|
|
title: t('searchTable.columns.operations'),
|
|
dataIndex: 'operations',
|
|
slotName: 'operations',
|
|
},
|
|
]);
|
|
|
|
// 将表格数据可视化
|
|
watch(
|
|
() => columns.value,
|
|
(val) => {
|
|
cloneColumns.value = val;
|
|
cloneColumns.value.forEach((item, index) => {
|
|
item.checked = true;
|
|
});
|
|
showColumns.value = cloneColumns.value;
|
|
},
|
|
{ deep: true, immediate: true }
|
|
);
|
|
// 用户身份
|
|
const roleOptions = computed<SelectOptionData[]>(() => [
|
|
{
|
|
label: t('searchTable.form.role.user'),
|
|
vlaue: 'user',
|
|
},
|
|
{
|
|
label: t('searchTable.form.role.auditor'),
|
|
vlaue: 'auditor',
|
|
},
|
|
]);
|
|
</script>
|
|
|
|
<script lang="ts">
|
|
export default {
|
|
name: 'Manage',
|
|
};
|
|
</script>
|
|
|
|
<style scoped lang="less">
|
|
.container {
|
|
padding: 0 20px 20px 20px;
|
|
}
|
|
</style>
|