人员列表
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