feat: 新增功能: 🚀 员工增删改查完成-动画未做
This commit is contained in:
parent
1da1c78649
commit
e149c57502
|
@ -12,5 +12,6 @@ module.exports = {
|
||||||
'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
|
'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
|
||||||
'vue/multi-word-component-names': 'off',
|
'vue/multi-word-component-names': 'off',
|
||||||
'@typescript-eslint/no-explicit-any': 'off',
|
'@typescript-eslint/no-explicit-any': 'off',
|
||||||
|
'vue/no-mutating-props': 'off',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -22,6 +22,7 @@ declare module 'vue' {
|
||||||
ElMain: typeof import('element-plus/es')['ElMain'];
|
ElMain: typeof import('element-plus/es')['ElMain'];
|
||||||
ElMenu: typeof import('element-plus/es')['ElMenu'];
|
ElMenu: typeof import('element-plus/es')['ElMenu'];
|
||||||
ElMenuItem: typeof import('element-plus/es')['ElMenuItem'];
|
ElMenuItem: typeof import('element-plus/es')['ElMenuItem'];
|
||||||
|
ElPagination: typeof import('element-plus/es')['ElPagination'];
|
||||||
ElRadio: typeof import('element-plus/es')['ElRadio'];
|
ElRadio: typeof import('element-plus/es')['ElRadio'];
|
||||||
ElRadioButton: typeof import('element-plus/es')['ElRadioButton'];
|
ElRadioButton: typeof import('element-plus/es')['ElRadioButton'];
|
||||||
ElRadioGroup: typeof import('element-plus/es')['ElRadioGroup'];
|
ElRadioGroup: typeof import('element-plus/es')['ElRadioGroup'];
|
||||||
|
|
20
src/App.vue
20
src/App.vue
|
@ -2,4 +2,24 @@
|
||||||
<router-view />
|
<router-view />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
const debounce = (callback: (...args: any[]) => void, delay: number) => {
|
||||||
|
let tid: any;
|
||||||
|
return function (...args: any[]) {
|
||||||
|
const ctx = self;
|
||||||
|
tid && clearTimeout(tid);
|
||||||
|
tid = setTimeout(() => {
|
||||||
|
callback.apply(ctx, args);
|
||||||
|
}, delay);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const _ = (window as any).ResizeObserver;
|
||||||
|
(window as any).ResizeObserver = class ResizeObserver extends _ {
|
||||||
|
constructor(callback: (...args: any[]) => void) {
|
||||||
|
callback = debounce(callback, 20);
|
||||||
|
super(callback);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
<style lang="scss"></style>
|
<style lang="scss"></style>
|
||||||
|
|
|
@ -8,6 +8,30 @@ export const reqLogin = (data: any) => {
|
||||||
return Request({ url: '/admin/employee/login', method: 'POST', data });
|
return Request({ url: '/admin/employee/login', method: 'POST', data });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 启用、禁用员工账号
|
||||||
|
* @param data
|
||||||
|
*/
|
||||||
|
export const reqStatus = (data: any) => {
|
||||||
|
return Request({ url: `/admin/employee/status/${data.status}`, method: 'POST', params: { id: data.id } });
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新增员工
|
||||||
|
* @param data
|
||||||
|
*/
|
||||||
|
export const reqAddEmployee = (data: any) => {
|
||||||
|
return Request({ url: `/admin/employee`, method: 'POST', data });
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 编辑员工信息
|
||||||
|
* @param data
|
||||||
|
*/
|
||||||
|
export const reqEditEmployee = (data: any) => {
|
||||||
|
return Request({ url: `/admin/employee`, method: 'PUT', data });
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 员工分页查询
|
* 员工分页查询
|
||||||
* @param params
|
* @param params
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
@charset "UTF-8";
|
@charset "UTF-8";
|
||||||
|
|
||||||
:root {
|
:root {
|
||||||
--el-color-white: #ffffff;
|
--el-color-white: #ffffff;
|
||||||
--el-color-black: #000000;
|
--el-color-black: #000000;
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
@charset "UTF-8";
|
||||||
|
|
||||||
|
@mixin circle() {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: -10px;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
width: 5px;
|
||||||
|
height: 5px;
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.circle-success {
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
@include circle;
|
||||||
|
background-color: var(--el-color-success);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.circle-danger {
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
@include circle;
|
||||||
|
background-color: var(--el-color-danger);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
@use 'circle';
|
|
@ -0,0 +1,15 @@
|
||||||
|
<template>
|
||||||
|
<el-button :bg="true" class="search" color="#1f1f1f" size="large">{{ title }}</el-button>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { defineProps } from 'vue';
|
||||||
|
|
||||||
|
defineProps(['title']);
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.search {
|
||||||
|
margin: 0 0 0 16px;
|
||||||
|
color: #fff !important;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,50 @@
|
||||||
|
<template>
|
||||||
|
<div class="container">
|
||||||
|
<el-button @click="handelCancel">取消</el-button>
|
||||||
|
<el-button :bg="true" class="save" color="#1f1f1f" size="large" @click="handelSave">保存</el-button>
|
||||||
|
<el-button v-if="!$route.query.id" :bg="true" class="handelSaveAndAdd" size="large" type="primary" @click="handelSaveAndAdd">
|
||||||
|
保存并继续添加
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { defineEmits } from 'vue';
|
||||||
|
|
||||||
|
const emit = defineEmits(['save', 'SaveAndAdd', 'cancel']);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 取消
|
||||||
|
*/
|
||||||
|
const handelCancel = () => {
|
||||||
|
emit('cancel');
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* 保存
|
||||||
|
*/
|
||||||
|
const handelSave = () => {
|
||||||
|
emit('save');
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* 保存并添加
|
||||||
|
*/
|
||||||
|
const handelSaveAndAdd = () => {
|
||||||
|
emit('SaveAndAdd');
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.container {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
.save {
|
||||||
|
margin: 0 0 0 16px;
|
||||||
|
color: #fff !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.handelSaveAndAdd {
|
||||||
|
margin: 0 0 0 16px;
|
||||||
|
color: #1f1f1f !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,15 @@
|
||||||
|
<template>
|
||||||
|
<el-button :bg="true" class="search" size="large" type="primary">{{ title }}</el-button>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { defineProps } from 'vue';
|
||||||
|
|
||||||
|
defineProps(['title']);
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.search {
|
||||||
|
margin: 0 0 0 16px;
|
||||||
|
color: #1f1f1f !important;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,41 @@
|
||||||
|
<template>
|
||||||
|
<el-page-header @back="goBack">
|
||||||
|
<template #icon>
|
||||||
|
<el-icon size="20">
|
||||||
|
<Back />
|
||||||
|
</el-icon>
|
||||||
|
</template>
|
||||||
|
<template #title><span class="goBack">返回</span></template>
|
||||||
|
<template #content>
|
||||||
|
<span class="title"> {{ title }} </span>
|
||||||
|
</template>
|
||||||
|
</el-page-header>
|
||||||
|
</template>
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { Back } from '@element-plus/icons-vue';
|
||||||
|
import { defineEmits, defineProps } from 'vue';
|
||||||
|
|
||||||
|
defineProps(['title']);
|
||||||
|
const emits = defineEmits(['back']);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回
|
||||||
|
*/
|
||||||
|
const goBack = () => {
|
||||||
|
emits('back');
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.el-page-header {
|
||||||
|
margin: 0 0 20px 0;
|
||||||
|
|
||||||
|
.goBack {
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,26 @@
|
||||||
|
<template>
|
||||||
|
<el-pagination
|
||||||
|
:current-page="currentPage"
|
||||||
|
:hide-on-single-page="hideOnSinglePage"
|
||||||
|
:page-size="pageSize"
|
||||||
|
:page-sizes="[10, 20, 30, 40]"
|
||||||
|
:total="total"
|
||||||
|
layout="total, sizes, prev, pager, next, jumper"
|
||||||
|
@size-change="handleSizeChange"
|
||||||
|
@current-change="handleCurrentChange"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { defineEmits, defineProps } from 'vue';
|
||||||
|
|
||||||
|
defineProps(['currentPage', 'pageSize', 'total', 'hideOnSinglePage']);
|
||||||
|
|
||||||
|
const emitter = defineEmits(['handleSizeChange', 'handleCurrentChange']);
|
||||||
|
|
||||||
|
const handleSizeChange = (val: number) => {
|
||||||
|
emitter('handleSizeChange', val);
|
||||||
|
};
|
||||||
|
const handleCurrentChange = (val: number) => {
|
||||||
|
emitter('handleCurrentChange', val);
|
||||||
|
};
|
||||||
|
</script>
|
|
@ -0,0 +1,13 @@
|
||||||
|
<template>
|
||||||
|
<footer>
|
||||||
|
<slot />
|
||||||
|
</footer>
|
||||||
|
</template>
|
||||||
|
<script lang="ts" setup></script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
footer {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
margin: 20px 0 0 0;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,19 @@
|
||||||
|
<template>
|
||||||
|
<header>
|
||||||
|
<div class="left">
|
||||||
|
<slot name="left" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="right">
|
||||||
|
<slot name="right" />
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
</template>
|
||||||
|
<script lang="ts" setup></script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
margin: 0 0 20px 0;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<el-table :data="tableData" v-bind="$attrs">
|
<el-table :data="tableData" size="large" v-bind="$attrs">
|
||||||
<el-table-column v-for="item in column" :key="item.prop" v-bind="item">
|
<el-table-column v-for="item in column" :key="item.prop" v-bind="item">
|
||||||
<template v-if="$slots[item.prop]" #default="scope">
|
<template v-if="$slots[item.prop]" #default="scope">
|
||||||
<slot :name="item.prop" v-bind="scope"></slot>
|
<slot :name="item.prop" v-bind="scope"></slot>
|
||||||
|
|
|
@ -40,6 +40,14 @@ const routes: Array<RouteRecordRaw> = [
|
||||||
path: 'employee',
|
path: 'employee',
|
||||||
name: 'employee',
|
name: 'employee',
|
||||||
component: () => import(/* webpackChunkName: "employee" */ '@/views/employee/index.vue'),
|
component: () => import(/* webpackChunkName: "employee" */ '@/views/employee/index.vue'),
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
path: 'add',
|
||||||
|
name: 'employeeAdd',
|
||||||
|
component: () => import(/* webpackChunkName: "employeeAdd" */ '@/views/employee/add-employee.vue'),
|
||||||
|
meta: { title: '添加员工' },
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,12 +1,14 @@
|
||||||
import { defineStore } from 'pinia';
|
import { defineStore } from 'pinia';
|
||||||
import { reqGetEmployeeById, reqGetEmployeePage, reqLogin } from '@/api/employee';
|
import { reqAddEmployee, reqEditEmployee, reqGetEmployeeById, reqGetEmployeePage, reqLogin, reqStatus } from '@/api/employee';
|
||||||
import Cookies from 'js-cookie';
|
import Cookies from 'js-cookie';
|
||||||
import router from '@/router';
|
import router from '@/router';
|
||||||
import { ElMessage } from 'element-plus';
|
import { ElMessage } from 'element-plus';
|
||||||
|
|
||||||
export const employeeStore = defineStore('employeeStore', {
|
export const employeeStore = defineStore('employeeStore', {
|
||||||
state: () => ({
|
state: () => ({
|
||||||
employeeList: [],
|
employeeList: { records: [], total: 0 },
|
||||||
|
employeeDetail: {},
|
||||||
|
requestData: { name: '', page: 1, pageSize: 10 },
|
||||||
}),
|
}),
|
||||||
getters: {},
|
getters: {},
|
||||||
actions: {
|
actions: {
|
||||||
|
@ -29,6 +31,31 @@ export const employeeStore = defineStore('employeeStore', {
|
||||||
ElMessage.error(e.message);
|
ElMessage.error(e.message);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
* 新增员工
|
||||||
|
* @param data
|
||||||
|
*/
|
||||||
|
async addEmployee(data: any) {
|
||||||
|
try {
|
||||||
|
const response: any = await reqAddEmployee(data);
|
||||||
|
if (response.code !== 1) {
|
||||||
|
return Promise.reject(new Error(response.msg));
|
||||||
|
}
|
||||||
|
} catch (e: any) {
|
||||||
|
ElMessage.error(e.message);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 启用、禁用员工账号
|
||||||
|
* @param data
|
||||||
|
*/
|
||||||
|
async changeStatus(data: any) {
|
||||||
|
try {
|
||||||
|
await reqStatus(data);
|
||||||
|
} catch (e: any) {
|
||||||
|
ElMessage.error(e.message);
|
||||||
|
}
|
||||||
|
},
|
||||||
/**
|
/**
|
||||||
* 员工分页查询
|
* 员工分页查询
|
||||||
* @param data
|
* @param data
|
||||||
|
@ -36,7 +63,7 @@ export const employeeStore = defineStore('employeeStore', {
|
||||||
async getEmployeePage(data: any) {
|
async getEmployeePage(data: any) {
|
||||||
try {
|
try {
|
||||||
const response: any = await reqGetEmployeePage(data);
|
const response: any = await reqGetEmployeePage(data);
|
||||||
this.employeeList = response.data.records;
|
this.employeeList = response.data;
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
ElMessage.error(e.message);
|
ElMessage.error(e.message);
|
||||||
}
|
}
|
||||||
|
@ -47,8 +74,30 @@ export const employeeStore = defineStore('employeeStore', {
|
||||||
* @param id
|
* @param id
|
||||||
*/
|
*/
|
||||||
async getEmployeeListById(id: number) {
|
async getEmployeeListById(id: number) {
|
||||||
const response = await reqGetEmployeeById(id);
|
try {
|
||||||
this.employeeList = response.data;
|
const response: any = await reqGetEmployeeById(id);
|
||||||
|
|
||||||
|
if (response.code !== 1) {
|
||||||
|
return Promise.reject(new Error(response.msg));
|
||||||
|
}
|
||||||
|
|
||||||
|
this.employeeDetail = response.data;
|
||||||
|
} catch (e: any) {
|
||||||
|
ElMessage.error(e.message);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async editEmployee(data: any) {
|
||||||
|
try {
|
||||||
|
const response: any = await reqEditEmployee(data);
|
||||||
|
|
||||||
|
if (response.code !== 1) {
|
||||||
|
return Promise.reject(new Error(response.msg));
|
||||||
|
}
|
||||||
|
|
||||||
|
this.employeeDetail = response.data;
|
||||||
|
} catch (e: any) {
|
||||||
|
ElMessage.error(e.message);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -0,0 +1,167 @@
|
||||||
|
<template>
|
||||||
|
<PageHeader :title="title" @back="handelCancel" />
|
||||||
|
<el-form ref="ruleFormRef" :model="form" :rules="rules" label-width="190px" size="large" status-icon>
|
||||||
|
<!--账号-->
|
||||||
|
<el-form-item label="账号" prop="username">
|
||||||
|
<el-input v-model="form.username" clearable />
|
||||||
|
</el-form-item>
|
||||||
|
<!--员工姓名-->
|
||||||
|
<el-form-item label="员工姓名" prop="name">
|
||||||
|
<el-input v-model="form.name" clearable />
|
||||||
|
</el-form-item>
|
||||||
|
<!--手机号-->
|
||||||
|
<el-form-item label="手机号" prop="phone">
|
||||||
|
<el-input v-model="form.phone" clearable />
|
||||||
|
</el-form-item>
|
||||||
|
<!--性别-->
|
||||||
|
<el-form-item label="性别" prop="sex">
|
||||||
|
<el-radio-group v-model="form.sex" placeholder="选择性别">
|
||||||
|
<el-radio label="1">男</el-radio>
|
||||||
|
<el-radio label="0">女</el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
<!--身份证号-->
|
||||||
|
<el-form-item label="身份证号" prop="idNumber">
|
||||||
|
<el-input v-model="form.idNumber" clearable />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<CancelSaveAdd @SaveAndAdd="handelSaveAndAdd(ruleFormRef)" @cancel="handelCancel" @save="handelSave(ruleFormRef)" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { onMounted, reactive, ref, toRaw } from 'vue';
|
||||||
|
import { ElMessage, FormInstance, FormRules } from 'element-plus';
|
||||||
|
import CancelSaveAdd from '@/commpent/button/cancel-save-add.vue';
|
||||||
|
import { employeeStore } from '@/store/employee';
|
||||||
|
import PageHeader from '@/commpent/page-header.vue';
|
||||||
|
import { useRoute, useRouter } from 'vue-router';
|
||||||
|
|
||||||
|
interface RuleForm {
|
||||||
|
idNumber: string;
|
||||||
|
name: string;
|
||||||
|
phone: string;
|
||||||
|
sex: string;
|
||||||
|
username: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const rules = reactive<FormRules<RuleForm>>({
|
||||||
|
name: [
|
||||||
|
{ required: true, message: '请输入员工姓名', trigger: 'blur' },
|
||||||
|
{ min: 3, max: 16, message: '长度为3-16字符', trigger: 'blur' },
|
||||||
|
],
|
||||||
|
username: [{ required: true, message: '请输入账号', trigger: 'blur' }],
|
||||||
|
phone: [
|
||||||
|
{ required: true, message: '请输入手机号', trigger: 'blur', max: 11 },
|
||||||
|
{ pattern: /^1[3456789]\d{9}$/, message: '手机号码格式不正确', trigger: 'change' },
|
||||||
|
],
|
||||||
|
sex: [{ required: true, message: '请选择性别', trigger: 'blur' }],
|
||||||
|
idNumber: [
|
||||||
|
{ required: true, message: '请输入身份证号', trigger: 'blur', max: 18 },
|
||||||
|
{
|
||||||
|
pattern: /(^\d{8}(0\d|10|11|12)([0-2]\d|30|31)\d{3}$)|(^\d{6}(18|19|20)\d{2}(0[1-9]|10|11|12)([0-2]\d|30|31)\d{3}(\d|X|x)$)/,
|
||||||
|
message: '身份证格式不正确',
|
||||||
|
trigger: 'change',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
const store = employeeStore();
|
||||||
|
const router = useRouter();
|
||||||
|
const route = useRoute();
|
||||||
|
const title = ref('添加员工');
|
||||||
|
const ruleFormRef = ref<FormInstance>();
|
||||||
|
const form = reactive<RuleForm>({
|
||||||
|
idNumber: '', // 身份证号
|
||||||
|
name: '', // 姓名
|
||||||
|
phone: '', // 手机号
|
||||||
|
sex: '1', // 性别
|
||||||
|
username: '', // 用户名
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断当前是否有用户id
|
||||||
|
* 如果有合并信息
|
||||||
|
*/
|
||||||
|
const getEmployeeDetail = async () => {
|
||||||
|
if (route.query.id) {
|
||||||
|
title.value = '修改员工信息';
|
||||||
|
await store.getEmployeeListById(route.query.id);
|
||||||
|
Object.assign(form, store.employeeDetail);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置员工信息
|
||||||
|
*/
|
||||||
|
const setEmployeeDetail = async () => {
|
||||||
|
if (route.query.id) {
|
||||||
|
await store.editEmployee(toRaw(form));
|
||||||
|
ElMessage.success('修改员工信息成功');
|
||||||
|
} else {
|
||||||
|
await store.addEmployee(toRaw(form));
|
||||||
|
ElMessage.success('添加员工信息成功');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加员工
|
||||||
|
* @param formEl
|
||||||
|
*/
|
||||||
|
const handelSave = async (formEl: FormInstance | undefined) => {
|
||||||
|
if (!formEl) return;
|
||||||
|
await formEl.validate(async valid => {
|
||||||
|
if (valid) {
|
||||||
|
try {
|
||||||
|
await setEmployeeDetail(); // 修改或添加员工信息
|
||||||
|
await store.getEmployeePage(store.requestData);
|
||||||
|
await router.push('/employee');
|
||||||
|
} catch (e: any) {
|
||||||
|
ElMessage.error(e.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 继续添加员工信息
|
||||||
|
* @param formEl
|
||||||
|
*/
|
||||||
|
const handelSaveAndAdd = async (formEl: FormInstance | undefined) => {
|
||||||
|
if (!formEl) return;
|
||||||
|
await formEl.validate(async valid => {
|
||||||
|
if (valid) {
|
||||||
|
try {
|
||||||
|
await setEmployeeDetail();
|
||||||
|
|
||||||
|
formEl.resetFields();
|
||||||
|
} catch (e: any) {
|
||||||
|
ElMessage.error(e.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回
|
||||||
|
*/
|
||||||
|
const handelCancel = () => {
|
||||||
|
router.push('/employee');
|
||||||
|
};
|
||||||
|
onMounted(() => {
|
||||||
|
getEmployeeDetail();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.el-form {
|
||||||
|
padding: 26px;
|
||||||
|
background: #fff;
|
||||||
|
|
||||||
|
.el-input,
|
||||||
|
.el-select {
|
||||||
|
width: 300px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -1,55 +1,132 @@
|
||||||
<template>
|
<template>
|
||||||
<TablePlus :column="column" :table-data="store.employeeList" stripe>
|
<RouterView />
|
||||||
|
<div v-show="$route.name !== 'employeeAdd'" class="container">
|
||||||
|
<!-- 头部 -->
|
||||||
|
<TableHeader>
|
||||||
|
<template #left>
|
||||||
|
员工姓名:
|
||||||
|
<el-input v-model="store.requestData.name" clearable placeholder="输入员工姓名" size="large" style="width: 200px" />
|
||||||
|
<BlackBtn title="查询" @click="handelSearch" />
|
||||||
|
</template>
|
||||||
|
<template #right>
|
||||||
|
<PrimaryBtn title="+ 添加员工" @click="$router.push('/employee/add')" />
|
||||||
|
</template>
|
||||||
|
</TableHeader>
|
||||||
|
<!-- 表格 -->
|
||||||
|
<TablePlus :column="column" :table-data="store.employeeList.records" stripe>
|
||||||
<template #status="props">
|
<template #status="props">
|
||||||
<span v-show="props.row.status === 1" class="status"><i class="start"></i> 启用</span>
|
<span v-show="props.row.status === 1" class="circle-success">启用</span>
|
||||||
<span v-show="props.row.status === 0" class="status"><i class="disabled"></i> 禁用</span>
|
<span v-show="props.row.status === 0" class="circle-danger"> 禁用</span>
|
||||||
|
</template>
|
||||||
|
<template #op="props">
|
||||||
|
<div v-if="props.row.username !== 'admin'">
|
||||||
|
<el-button link type="primary" @click="handelEdit(props.row.id)">修改</el-button>
|
||||||
|
<el-button v-if="props.row.status === 0" link type="success" @click="handelStatus(1, props.row.id)">启用</el-button>
|
||||||
|
<el-button v-else :disabled="props.row.id === 1" link type="danger" @click="handelStatus(0, props.row.id)">禁用 </el-button>
|
||||||
|
</div>
|
||||||
|
<div v-else>
|
||||||
|
<el-button :disabled="true" link type="info">修改</el-button>
|
||||||
|
<el-button :disabled="true" link type="info">禁用</el-button>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</TablePlus>
|
</TablePlus>
|
||||||
|
<!-- 底部 -->
|
||||||
|
<TableFooter>
|
||||||
|
<Pagination
|
||||||
|
:current-page="store.requestData.page"
|
||||||
|
:hide-on-single-page="false"
|
||||||
|
:page-size="store.requestData.pageSize"
|
||||||
|
:total="store.employeeList.total"
|
||||||
|
@handleCurrentChange="handleCurrentChange"
|
||||||
|
@handleSizeChange="handleSizeChange"
|
||||||
|
/>
|
||||||
|
</TableFooter>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { employeeStore } from '@/store/employee';
|
import { employeeStore } from '@/store/employee';
|
||||||
import { onMounted, reactive, toRaw } from 'vue';
|
import { onMounted, toRaw } from 'vue';
|
||||||
import TablePlus from '@/commpent/table/table-plus.vue';
|
import TablePlus from '@/commpent/table/table-plus.vue';
|
||||||
|
import BlackBtn from '@/commpent/button/black-btn.vue';
|
||||||
|
import Pagination from '@/commpent/pagination.vue';
|
||||||
|
import PrimaryBtn from '@/commpent/button/primary-btn.vue';
|
||||||
|
import TableHeader from '@/commpent/table/table-header.vue';
|
||||||
|
import TableFooter from '@/commpent/table/table-footer.vue';
|
||||||
|
import { ElMessage, ElMessageBox } from 'element-plus';
|
||||||
|
import router from '@/router';
|
||||||
|
|
||||||
const store = employeeStore();
|
|
||||||
const requestData = reactive({
|
|
||||||
name: '',
|
|
||||||
page: 1,
|
|
||||||
pageSize: 10,
|
|
||||||
});
|
|
||||||
const column = [
|
const column = [
|
||||||
{ prop: 'name', label: '员工姓名' },
|
{ prop: 'name', label: '员工姓名' },
|
||||||
{ prop: 'username', label: '账号' },
|
{ prop: 'username', label: '账号' },
|
||||||
{ prop: 'phone', label: '手机号' },
|
{ prop: 'phone', label: '手机号' },
|
||||||
{ prop: 'status', label: '状态' },
|
{ prop: 'status', label: '状态' },
|
||||||
{ prop: 'updateTime', label: '最后登录时间' },
|
{ prop: 'updateTime', label: '最后登录时间' },
|
||||||
|
{ prop: 'op', label: '操作', align: 'center' },
|
||||||
];
|
];
|
||||||
|
const store = employeeStore();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 搜索
|
||||||
|
*/
|
||||||
|
const handelSearch = () => {
|
||||||
|
store.getEmployeePage(toRaw(store.requestData));
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 修改员工信息
|
||||||
|
* @param id
|
||||||
|
*/
|
||||||
|
const handelEdit = (id: number) => {
|
||||||
|
router.push({ path: '/employee/add', query: { id } });
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 启用、禁用员工账号
|
||||||
|
* @param status
|
||||||
|
* @param id
|
||||||
|
*/
|
||||||
|
const handelStatus = (status: number, id: number) => {
|
||||||
|
ElMessageBox.alert('确认调整该账号的状态?', '提示', {
|
||||||
|
showCancelButton: true,
|
||||||
|
confirmButtonText: '确认',
|
||||||
|
cancelButtonText: '取消',
|
||||||
|
callback: async (value: string) => {
|
||||||
|
if (value === 'confirm') {
|
||||||
|
const data = { status, id };
|
||||||
|
await store.changeStatus(data);
|
||||||
|
await store.getEmployeePage(toRaw(store.requestData));
|
||||||
|
ElMessage.success('账号状态更改成功!');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}).catch();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 修改当前分页大小
|
||||||
|
* @param val
|
||||||
|
*/
|
||||||
|
const handleSizeChange = (val: number) => {
|
||||||
|
store.requestData.pageSize = val;
|
||||||
|
store.getEmployeePage(store.requestData);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 修改当前页
|
||||||
|
* @param val
|
||||||
|
*/
|
||||||
|
const handleCurrentChange = (val: number) => {
|
||||||
|
store.requestData.page = val;
|
||||||
|
store.getEmployeePage(store.requestData);
|
||||||
|
};
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
store.getEmployeePage(toRaw(requestData));
|
store.getEmployeePage(store.requestData);
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.status {
|
.container {
|
||||||
position: relative;
|
padding: 26px;
|
||||||
|
background-color: #fff;
|
||||||
i {
|
|
||||||
position: absolute;
|
|
||||||
top: 50%;
|
|
||||||
left: -10px;
|
|
||||||
transform: translateY(-50%);
|
|
||||||
width: 5px;
|
|
||||||
height: 5px;
|
|
||||||
border-radius: 50%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.start {
|
|
||||||
background-color: var(--el-color-success);
|
|
||||||
}
|
|
||||||
|
|
||||||
.disabled {
|
|
||||||
background-color: var(--el-color-danger);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -29,7 +29,7 @@ module.exports = defineConfig({
|
||||||
css: {
|
css: {
|
||||||
loaderOptions: {
|
loaderOptions: {
|
||||||
scss: {
|
scss: {
|
||||||
additionalData: `@use "~@/assets/css/index.scss" as *;`,
|
additionalData: `@use "~@/assets/css/index.scss" as *; @use "~@/assets/css/mixin/index.scss";`,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in New Issue