人员列表
This commit is contained in:
parent
e9c9dcd9c5
commit
019d09df3e
|
|
@ -0,0 +1,45 @@
|
|||
import { request } from '@/api';
|
||||
import type {
|
||||
WorkerListResponse,
|
||||
WorkerFormParams,
|
||||
EditWorkerParams,
|
||||
WorkerRoleOption,
|
||||
WorkerRoleOptionResponse,
|
||||
} from '@/api/types/system/worker.d';
|
||||
|
||||
/**
|
||||
* 获取员工列表
|
||||
* @param params 查询参数(用户名)
|
||||
* @returns Promise<WorkerListResponse> 员工列表数据
|
||||
*/
|
||||
export async function getWorkerListApi(params: { username?: string } = {}): Promise<WorkerListResponse> {
|
||||
return request.get<WorkerListResponse>('/worker/getWorkerList', params);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取员工角色下拉选项
|
||||
* @returns Promise<WorkerRoleOptionResponse> 角色选项列表
|
||||
*/
|
||||
export async function getWorkerRoleIdOptionApi(): Promise<WorkerRoleOptionResponse> {
|
||||
return request.get<WorkerRoleOptionResponse>('/worker/getWorkerRoleIdOptions', undefined, { showMessage: false });
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增员工
|
||||
* @param params 员工表单参数(username、email、role_id)
|
||||
* @returns Promise<void>
|
||||
*/
|
||||
export async function addWorkerApi(params: WorkerFormParams): Promise<void> {
|
||||
return request.post<void>('/worker/addWorker', params);
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑员工
|
||||
* @param params 编辑员工参数(user_id、username、email、status)
|
||||
* @returns Promise<void>
|
||||
*/
|
||||
export async function editWorkerApi(params: EditWorkerParams): Promise<void> {
|
||||
return request.post<void>('/worker/editWorker', params, { showMessage: false });
|
||||
}
|
||||
|
||||
export type { WorkerRoleOption };
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
import type { ApiResponse } from '../index';
|
||||
|
||||
/** 员工角色信息 */
|
||||
export interface WorkerRoleInfo {
|
||||
id: number;
|
||||
title: string;
|
||||
}
|
||||
|
||||
/** 员工列表单条数据 */
|
||||
export interface WorkerItem {
|
||||
id: number;
|
||||
username: string;
|
||||
email: string;
|
||||
role_id: number;
|
||||
status: number; // 1:正常 2:封禁
|
||||
created_at: string;
|
||||
role: WorkerRoleInfo;
|
||||
}
|
||||
|
||||
/** 员工列表响应 */
|
||||
export type WorkerListResponse = WorkerItem[];
|
||||
|
||||
/** 员工角色下拉选项 */
|
||||
export interface WorkerRoleOption {
|
||||
id: number;
|
||||
title: string;
|
||||
}
|
||||
|
||||
/** 员工角色下拉选项响应 */
|
||||
export type WorkerRoleOptionResponse = WorkerRoleOption[];
|
||||
|
||||
/** 新增员工表单参数 */
|
||||
export interface WorkerFormParams {
|
||||
username: string;
|
||||
email: string;
|
||||
role_id: number | null;
|
||||
}
|
||||
|
||||
/** 编辑员工表单参数 */
|
||||
export interface EditWorkerParams {
|
||||
user_id: number;
|
||||
username: string;
|
||||
email: string;
|
||||
status: number; // 1:正常 2:封禁
|
||||
}
|
||||
|
||||
/** 接口返回结构(兼容 data 包裹场景) */
|
||||
export interface WorkerListApiResponse extends ApiResponse<WorkerItem[]> {}
|
||||
export interface WorkerRoleOptionApiResponse extends ApiResponse<WorkerRoleOption[]> {}
|
||||
|
|
@ -0,0 +1,285 @@
|
|||
<template>
|
||||
<div class="system table_form-container">
|
||||
<!-- 搜索 -->
|
||||
<WorkerSearch
|
||||
:search-form="searchForm"
|
||||
:buttonLoading="loading"
|
||||
:search-options="searchOptions"
|
||||
@search="handleSearch"
|
||||
@reset="handleReset"
|
||||
>
|
||||
<template #button>
|
||||
<el-button type="primary" @click="handleAdd" v-auth="'worker_addWorker'">新增员工</el-button>
|
||||
</template>
|
||||
</WorkerSearch>
|
||||
|
||||
<!-- 表格 -->
|
||||
<WorkerTable
|
||||
:table-data="workerList"
|
||||
:columns="tableColumnsOptions"
|
||||
row-key="id"
|
||||
:loading="loading"
|
||||
>
|
||||
<template #status="{ row }">
|
||||
<el-tag :type="row.status === 1 ? 'success' : 'danger'">
|
||||
{{ row.status === 1 ? '正常' : '封禁' }}
|
||||
</el-tag>
|
||||
</template>
|
||||
<template #action="{ row }">
|
||||
<el-button link type="primary" size="small" @click="handleEdit(row)" v-auth="'worker_editWorker'">
|
||||
编辑
|
||||
</el-button>
|
||||
</template>
|
||||
</WorkerTable>
|
||||
|
||||
<!-- 新增/编辑弹窗 -->
|
||||
<WorkerDialog
|
||||
:visible="dialogVisible"
|
||||
:title="dialogTitle"
|
||||
:type="dialogType"
|
||||
:button-loading="submitLoading"
|
||||
@confirm="handleSubmit"
|
||||
@cancel="handleCancel"
|
||||
@close="handleClose"
|
||||
>
|
||||
<WorkerForm
|
||||
:form-data="workerForm"
|
||||
:form-rules="workerFormRules"
|
||||
:form-items="workerFormItemOptions"
|
||||
:options-map="workerFormOptionsMap"
|
||||
ref="workerFormRef"
|
||||
:key="formKey"
|
||||
/>
|
||||
</WorkerDialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
defineOptions({
|
||||
name: 'Worder'
|
||||
})
|
||||
|
||||
import type { FormInstance } from 'element-plus'
|
||||
import { usePageLoading, useButtonLoading } from '@/composables/useLoading'
|
||||
|
||||
const { loading, startLoading, stopLoading } = usePageLoading()
|
||||
const { buttonLoading: submitLoading, startButtonLoading: startSubmitLoading, stopButtonLoading: stopSubmitLoading } = useButtonLoading()
|
||||
|
||||
// 组件
|
||||
import WorkerSearch from '@/components/common/Search.vue'
|
||||
import WorkerTable from '@/components/common/Table.vue'
|
||||
import WorkerDialog from '@/components/common/Dialog.vue'
|
||||
import WorkerForm from '@/components/common/Form.vue'
|
||||
|
||||
// 配置以及表单验证
|
||||
import { search, tableColumns, addFormItem, editFormItem } from './options'
|
||||
import { addRules, editRules } from './rules'
|
||||
|
||||
// 接口
|
||||
import {
|
||||
getWorkerListApi,
|
||||
getWorkerRoleIdOptionApi,
|
||||
addWorkerApi,
|
||||
editWorkerApi,
|
||||
} from '@/api/modules/system/worker'
|
||||
|
||||
/**
|
||||
* @description: 定义搜索数据
|
||||
*/
|
||||
const searchForm = ref({
|
||||
username: '',
|
||||
})
|
||||
const searchOptions = ref(search)
|
||||
|
||||
/**
|
||||
* @description: 定义表格数据
|
||||
*/
|
||||
const workerList = ref<any[]>([])
|
||||
const tableColumnsOptions = ref(tableColumns)
|
||||
|
||||
/**
|
||||
* @description: 定义弹窗数据
|
||||
*/
|
||||
const dialogVisible = ref(false)
|
||||
const dialogTitle = ref('')
|
||||
const dialogType = ref<'add' | 'edit'>('add')
|
||||
// 切换弹窗类型时强制刷新表单组件,避免表单字段切换时旧值残留
|
||||
const formKey = ref(0)
|
||||
|
||||
/**
|
||||
* @description: 定义表单数据
|
||||
*/
|
||||
const workerForm = ref<any>({
|
||||
user_id: 0,
|
||||
username: '',
|
||||
email: '',
|
||||
role_id: null as number | null,
|
||||
status: 1,
|
||||
})
|
||||
const workerFormRef = ref<FormInstance>()
|
||||
const workerFormRules = ref<any>({})
|
||||
const workerFormItemOptions = ref<any[]>([])
|
||||
// 表单下拉选项映射(角色 / 状态)
|
||||
const workerFormOptionsMap = ref<Record<string, { label: string; value: number }[]>>({
|
||||
role_id: [],
|
||||
status: [
|
||||
{ label: '正常', value: 1 },
|
||||
{ label: '封禁', value: 2 },
|
||||
],
|
||||
})
|
||||
|
||||
/**
|
||||
* @description: 角色下拉数据加载
|
||||
*/
|
||||
const fetchRoleOptions = async () => {
|
||||
try {
|
||||
const data: any = await getWorkerRoleIdOptionApi()
|
||||
const list = Array.isArray(data) ? data : (data?.data || [])
|
||||
workerFormOptionsMap.value.role_id = list.map((item: any) => ({
|
||||
label: item.title,
|
||||
value: item.id,
|
||||
}))
|
||||
} catch (err) {
|
||||
console.error('获取员工角色选项失败', err)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: 获取员工列表
|
||||
*/
|
||||
const fetchWorkerList = async () => {
|
||||
startLoading()
|
||||
try {
|
||||
const params: any = {
|
||||
username: searchForm.value.username || undefined,
|
||||
}
|
||||
const data: any = await getWorkerListApi(params)
|
||||
const list = Array.isArray(data) ? data : (data?.data || [])
|
||||
workerList.value = list.map((item: any) => ({
|
||||
...item,
|
||||
roleTitle: item.role?.title || '-',
|
||||
}))
|
||||
} catch (err) {
|
||||
console.error('获取员工列表失败', err)
|
||||
} finally {
|
||||
stopLoading()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: 页面挂载
|
||||
*/
|
||||
onMounted(async () => {
|
||||
await Promise.all([fetchRoleOptions(), fetchWorkerList()])
|
||||
})
|
||||
|
||||
/**
|
||||
* @description: 搜索 / 重置
|
||||
*/
|
||||
const handleSearch = () => {
|
||||
fetchWorkerList()
|
||||
}
|
||||
const handleReset = () => {
|
||||
searchForm.value = { username: '' }
|
||||
fetchWorkerList()
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: 新增
|
||||
* 入参字段:email、role_id
|
||||
*/
|
||||
const handleAdd = () => {
|
||||
dialogVisible.value = true
|
||||
dialogTitle.value = '新增员工'
|
||||
dialogType.value = 'add'
|
||||
workerFormItemOptions.value = addFormItem as any
|
||||
workerFormRules.value = addRules()
|
||||
formKey.value++
|
||||
workerForm.value = {
|
||||
user_id: 0,
|
||||
email: '',
|
||||
role_id: null,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: 编辑
|
||||
* 入参字段:username、email、status
|
||||
*/
|
||||
const handleEdit = (row: any) => {
|
||||
dialogVisible.value = true
|
||||
dialogTitle.value = '编辑员工'
|
||||
dialogType.value = 'edit'
|
||||
workerFormItemOptions.value = editFormItem as any
|
||||
workerFormRules.value = editRules()
|
||||
formKey.value++
|
||||
workerForm.value = {
|
||||
user_id: row.id,
|
||||
username: row.username,
|
||||
email: row.email,
|
||||
status: row.status,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: 提交表单
|
||||
*/
|
||||
const handleSubmit = async () => {
|
||||
startSubmitLoading()
|
||||
try {
|
||||
await workerFormRef.value?.validate()
|
||||
if (dialogType.value === 'add') {
|
||||
const params = {
|
||||
email: workerForm.value.email,
|
||||
role_id: workerForm.value.role_id,
|
||||
}
|
||||
await addWorkerApi(params)
|
||||
ElNotification({
|
||||
message: '新增成功',
|
||||
type: 'success',
|
||||
duration: 2000,
|
||||
customClass: 'global-notification',
|
||||
})
|
||||
} else {
|
||||
const params = {
|
||||
user_id: workerForm.value.user_id,
|
||||
username: workerForm.value.username,
|
||||
email: workerForm.value.email,
|
||||
status: workerForm.value.status,
|
||||
}
|
||||
await editWorkerApi(params)
|
||||
ElNotification({
|
||||
message: '编辑成功',
|
||||
type: 'success',
|
||||
duration: 2000,
|
||||
customClass: 'global-notification',
|
||||
})
|
||||
}
|
||||
dialogVisible.value = false
|
||||
await fetchWorkerList()
|
||||
} catch (err: any) {
|
||||
if (err?.message) {
|
||||
ElNotification({
|
||||
message: err.message || '操作失败',
|
||||
type: 'error',
|
||||
duration: 2000,
|
||||
customClass: 'global-notification',
|
||||
})
|
||||
}
|
||||
} finally {
|
||||
stopSubmitLoading()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: 取消 / 关闭弹窗
|
||||
*/
|
||||
const handleCancel = () => {
|
||||
dialogVisible.value = false
|
||||
}
|
||||
const handleClose = () => {
|
||||
dialogVisible.value = false
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss"></style>
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
/**
|
||||
* @description: 搜索配置
|
||||
*/
|
||||
export const search = [
|
||||
{
|
||||
prop: 'username',
|
||||
label: '用户名',
|
||||
type: 'input' as const,
|
||||
placeholder: '请输入用户名',
|
||||
width: '220px',
|
||||
},
|
||||
]
|
||||
|
||||
/**
|
||||
* @description: 表格列配置
|
||||
*/
|
||||
export const tableColumns = [
|
||||
{ prop: 'username', label: '用户名' },
|
||||
{ prop: 'email', label: '邮箱' },
|
||||
{ prop: 'roleTitle', label: '角色' },
|
||||
{ slotName: 'status', label: '状态' },
|
||||
{ prop: 'created_at', label: '创建时间' },
|
||||
{ slotName: 'action', label: '操作' },
|
||||
]
|
||||
|
||||
/**
|
||||
* @description: 新增员工表单配置
|
||||
* 入参:email(校验格式)、role_id(下拉)
|
||||
*/
|
||||
export const addFormItem = [
|
||||
{
|
||||
prop: 'email',
|
||||
label: '邮箱',
|
||||
type: 'input' as const,
|
||||
placeholder: '请输入邮箱',
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
prop: 'role_id',
|
||||
label: '角色',
|
||||
type: 'select' as const,
|
||||
placeholder: '请选择角色',
|
||||
required: true,
|
||||
},
|
||||
]
|
||||
|
||||
/**
|
||||
* @description: 编辑员工表单配置
|
||||
* 入参:username、email、status
|
||||
*/
|
||||
export const editFormItem = [
|
||||
{
|
||||
prop: 'username',
|
||||
label: '用户名',
|
||||
type: 'input' as const,
|
||||
placeholder: '请输入用户名',
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
prop: 'email',
|
||||
label: '邮箱',
|
||||
type: 'input' as const,
|
||||
placeholder: '请输入邮箱',
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
prop: 'status',
|
||||
label: '状态',
|
||||
type: 'radio' as const,
|
||||
placeholder: '请选择状态',
|
||||
required: true,
|
||||
},
|
||||
]
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
import type { FormRules } from 'element-plus'
|
||||
|
||||
/** 邮箱格式校验 */
|
||||
const emailValidator = (rule: any, value: any, callback: any) => {
|
||||
if (!value) {
|
||||
callback()
|
||||
return
|
||||
}
|
||||
const emailReg = /^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$/
|
||||
if (!emailReg.test(value)) {
|
||||
callback(new Error('邮箱格式不正确'))
|
||||
return
|
||||
}
|
||||
callback()
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: 新增员工表单校验规则
|
||||
* 入参:email、role_id
|
||||
*/
|
||||
export const addRules = (): FormRules => {
|
||||
return {
|
||||
email: [
|
||||
{ required: true, message: '请输入邮箱', trigger: 'blur' },
|
||||
{ validator: emailValidator, trigger: 'blur' },
|
||||
],
|
||||
role_id: [
|
||||
{ required: true, message: '请选择角色', trigger: 'change' },
|
||||
],
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: 编辑员工表单校验规则
|
||||
* 入参:username、email、status
|
||||
*/
|
||||
export const editRules = (): FormRules => {
|
||||
return {
|
||||
username: [
|
||||
{ required: true, message: '请输入用户名', trigger: 'blur' },
|
||||
{ min: 2, max: 50, message: '用户名长度在 2 到 50 个字符', trigger: 'blur' },
|
||||
],
|
||||
email: [
|
||||
{ required: true, message: '请输入邮箱', trigger: 'blur' },
|
||||
{ validator: emailValidator, trigger: 'blur' },
|
||||
],
|
||||
status: [
|
||||
{ required: true, message: '请选择状态', trigger: 'change' },
|
||||
],
|
||||
}
|
||||
}
|
||||
|
||||
/** 兼容旧引用 */
|
||||
export const rules = (): FormRules => editRules()
|
||||
Loading…
Reference in New Issue