Compare commits

..

2 Commits

24 changed files with 10866 additions and 9859 deletions

View File

@ -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',
}, },
}; };

2
auto-imports.d.ts vendored
View File

@ -5,5 +5,5 @@
// Generated by unplugin-auto-import // Generated by unplugin-auto-import
export {} export {}
declare global { declare global {
const ElMessage: typeof import('element-plus/es')['ElMessage'];
} }

43
components.d.ts vendored
View File

@ -6,22 +6,29 @@
export {} export {}
declare module 'vue' { declare module 'vue' {
export interface GlobalComponents { export interface GlobalComponents {
ElAside: typeof import('element-plus/es')['ElAside'] ElAside: typeof import('element-plus/es')['ElAside'];
ElButton: typeof import('element-plus/es')['ElButton'] ElButton: typeof import('element-plus/es')['ElButton'];
ElContainer: typeof import('element-plus/es')['ElContainer'] ElContainer: typeof import('element-plus/es')['ElContainer'];
ElHeader: typeof import('element-plus/es')['ElHeader'] ElDialog: typeof import('element-plus/es')['ElDialog'];
ElIcon: typeof import('element-plus/es')['ElIcon'] ElDropdown: typeof import('element-plus/es')['ElDropdown'];
ElMain: typeof import('element-plus/es')['ElMain'] ElDropdownItem: typeof import('element-plus/es')['ElDropdownItem'];
ElMenu: typeof import('element-plus/es')['ElMenu'] ElDropdownMenu: typeof import('element-plus/es')['ElDropdownMenu'];
ElMenuItem: typeof import('element-plus/es')['ElMenuItem'] ElForm: typeof import('element-plus/es')['ElForm'];
ElMenuItemGroup: typeof import('element-plus/es')['ElMenuItemGroup'] ElFormItem: typeof import('element-plus/es')['ElFormItem'];
ElRadioButton: typeof import('element-plus/es')['ElRadioButton'] ElHeader: typeof import('element-plus/es')['ElHeader'];
ElRadioGroup: typeof import('element-plus/es')['ElRadioGroup'] ElIcon: typeof import('element-plus/es')['ElIcon'];
ElRow: typeof import('element-plus/es')['ElRow'] ElInput: typeof import('element-plus/es')['ElInput'];
ElSubMenu: typeof import('element-plus/es')['ElSubMenu'] ElMain: typeof import('element-plus/es')['ElMain'];
ElText: typeof import('element-plus/es')['ElText'] ElMenu: typeof import('element-plus/es')['ElMenu'];
RouterLink: typeof import('vue-router')['RouterLink'] ElMenuItem: typeof import('element-plus/es')['ElMenuItem'];
RouterView: typeof import('vue-router')['RouterView'] ElPagination: typeof import('element-plus/es')['ElPagination'];
} ElRadio: typeof import('element-plus/es')['ElRadio'];
ElRadioButton: typeof import('element-plus/es')['ElRadioButton'];
ElRadioGroup: typeof import('element-plus/es')['ElRadioGroup'];
ElTable: typeof import('element-plus/es')['ElTable'];
ElTableColumn: typeof import('element-plus/es')['ElTableColumn'];
RouterLink: typeof import('vue-router')['RouterLink'];
RouterView: typeof import('vue-router')['RouterView'];
}
} }

View File

@ -1,26 +0,0 @@
const path = require('path');
module.exports = {
webpack: {
alias: {
'@': path.join(__dirname, 'src'),
},
},
style: {
postcss: {
mode: 'extends',
loaderOptions: {
postcssOptions: {
ident: 'postcss',
plugins: [
// require('postcss-mobile-forever', {
// viewportWidth: 2560,
// appSelector: '#root',
// maxDisplayWidth: 1920,
// }),
],
},
},
},
},
};

View File

@ -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>

View File

@ -9,11 +9,35 @@ export const reqLogin = (data: any) => {
}; };
/** /**
* *
* @param data * @param data
*/ */
export const reqGetEmployeePage = (data: any) => { export const reqStatus = (data: any) => {
return Request({ url: '/admin/employee/page', method: 'GET', params: data }); 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
*/
export const reqGetEmployeePage = (params: any) => {
return Request({ url: '/admin/employee/page', method: 'GET', params });
}; };
/** /**

File diff suppressed because it is too large Load Diff

View File

@ -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);
}
}

View File

@ -0,0 +1 @@
@use 'circle';

View File

@ -41,7 +41,7 @@ const store = headerStore();
max-width: 200px; max-width: 200px;
min-width: 63px; min-width: 63px;
height: 100%; height: 100%;
background: #343744; background: #343744 !important;
.el-menu-item { .el-menu-item {
color: #bfcbd9; color: #bfcbd9;

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -1,6 +1,5 @@
<!-- tablePlus:二次封装table -->
<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>
@ -28,5 +27,3 @@ defineProps<{
column: Column[]; column: Column[];
}>(); }>();
</script> </script>
<style lang="scss" scoped></style>

View File

@ -5,7 +5,6 @@ import { createPinia } from 'pinia';
import ElementPlus from 'element-plus'; import ElementPlus from 'element-plus';
import zhCn from 'element-plus/dist/locale/zh-cn.mjs'; import zhCn from 'element-plus/dist/locale/zh-cn.mjs';
import './assets/css/reset.css'; import './assets/css/reset.css';
import './assets/css/index.scss';
import * as ElementPlusIconsVue from '@element-plus/icons-vue'; import * as ElementPlusIconsVue from '@element-plus/icons-vue';
import '@/config/globalProperties'; import '@/config/globalProperties';

View File

@ -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: '添加员工' },
},
],
}, },
], ],
}, },

View File

@ -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: {
@ -15,14 +17,43 @@ export const employeeStore = defineStore('employeeStore', {
* @param data * @param data
*/ */
async login(data: any) { async login(data: any) {
const response: any = await reqLogin(data); try {
if (response.code === 1) { const response: any = await reqLogin(data);
Cookies.set('token', response.data.token); if (response.code === 1) {
Cookies.set('user_info', JSON.stringify(response.data)); Cookies.set('token', response.data.token);
Cookies.set('username', response.data.name); Cookies.set('user_info', JSON.stringify(response.data));
router.push('/').catch(); Cookies.set('username', response.data.name);
} else { router.push('/').catch();
ElMessage.error(response.msg); } else {
ElMessage.error(response.msg);
}
} catch (e: any) {
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);
} }
}, },
/** /**
@ -30,8 +61,12 @@ export const employeeStore = defineStore('employeeStore', {
* @param data * @param data
*/ */
async getEmployeePage(data: any) { async getEmployeePage(data: any) {
const response: any = await reqGetEmployeePage(data); try {
this.employeeList = response.data.records; const response: any = await reqGetEmployeePage(data);
this.employeeList = response.data;
} catch (e: any) {
ElMessage.error(e.message);
}
}, },
/** /**
@ -39,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);
}
}, },
}, },
}); });

View File

@ -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>

View File

@ -1,55 +1,132 @@
<template> <template>
<TablePlus :column="column" :table-data="store.employeeList" stripe> <RouterView />
<template #status="props"> <div v-show="$route.name !== 'employeeAdd'" class="container">
<span v-show="props.row.status === 1" class="status"><i class="start"></i> 启用</span> <!-- 头部 -->
<span v-show="props.row.status === 0" class="status"><i class="disabled"></i> 禁用</span> <TableHeader>
</template> <template #left>
</TablePlus> 员工姓名
<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">
<span v-show="props.row.status === 1" class="circle-success">启用</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>
</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 TablePlus from '@/commpent/table/table-plus.vue';
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 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>

View File

@ -1,8 +1,8 @@
const {defineConfig} = require('@vue/cli-service'); const { defineConfig } = require('@vue/cli-service');
const AutoImport = require('unplugin-auto-import/webpack'); const AutoImport = require('unplugin-auto-import/webpack');
const Components = require('unplugin-vue-components/webpack'); const Components = require('unplugin-vue-components/webpack');
const {ElementPlusResolver} = require('unplugin-vue-components/resolvers'); const { ElementPlusResolver } = require('unplugin-vue-components/resolvers');
const ElementPlus = require('unplugin-element-plus/webpack') const ElementPlus = require('unplugin-element-plus/webpack');
module.exports = defineConfig({ module.exports = defineConfig({
transpileDependencies: true, transpileDependencies: true,
@ -11,28 +11,28 @@ module.exports = defineConfig({
'/api': { '/api': {
target: 'http://localhost:8080', target: 'http://localhost:8080',
changeOrigin: true, changeOrigin: true,
pathRewrite: {'^/api': ''}, pathRewrite: { '^/api': '' },
}, },
}, },
}, },
chainWebpack: (config) => { chainWebpack: config => {
config.plugin('define').tap((definitions) => { config.plugin('define').tap(definitions => {
Object.assign(definitions[0], { Object.assign(definitions[0], {
__VUE_OPTIONS_API__: 'true', __VUE_OPTIONS_API__: 'true',
__VUE_PROD_DEVTOOLS__: 'false', __VUE_PROD_DEVTOOLS__: 'false',
__VUE_PROD_HYDRATION_MISMATCH_DETAILS__: 'false' __VUE_PROD_HYDRATION_MISMATCH_DETAILS__: 'false',
}) });
return definitions return definitions;
}) });
},
css: {
loaderOptions: {
scss: {
additionalData: `@use "~@/assets/css/index.scss" as *; @use "~@/assets/css/mixin/index.scss";`,
},
},
}, },
// css: {
// loaderOptions: {
// scss: {
// additionalData: `@use "~@/styles/index.scss" as *;`,
// },
// },
// },
configureWebpack: { configureWebpack: {
plugins: [ plugins: [
AutoImport({ AutoImport({