管理员模块完成

master
BINGWU 9 months ago
parent 531cb14eb2
commit ac1563c168

@ -49,6 +49,7 @@ declare module 'vue' {
ElTableColumn: typeof import('element-plus/es')['ElTableColumn']
ElTag: typeof import('element-plus/es')['ElTag']
ElTimePicker: typeof import('element-plus/es')['ElTimePicker']
ElTre: typeof import('element-plus/es')['ElTre']
ElTree: typeof import('element-plus/es')['ElTree']
ElUpload: typeof import('element-plus/es')['ElUpload']
ExportExcelCom: typeof import('./src/components/excel/ExportExcelCom.vue')['default']

File diff suppressed because it is too large Load Diff

@ -2,21 +2,35 @@
* @Author: BINGWU
* @Date: 2024-04-11 16:31:41
* @LastEditors: BINGWU HuJiaCheng2003@163.com
* @LastEditTime: 2024-05-13 23:50:42
* @LastEditTime: 2024-05-19 20:47:45
* @FilePath: \employee-information-management-system\app\src\api\user.js
* @Describe:
* @Mark: (˶ ˶)
*/
import http from '@/utils/http'
const getUser = () => {
import { deleteRequest } from '@/utils/http'
const getUser = (_id) => {
return http.get('/user/get', {
params: {
_id: '66136094633f0524859aa797'
_id
}
})
}
const loginUser = (params) => {
return http.post('/user/login', params)
}
export { getUser, loginUser }
const createUser = (params) => {
return http.post('/user/create', params)
}
const updateUser = (params) => {
return http.put('/user/update', params)
}
const deleteUser = (params) => {
return deleteRequest('/user/delete', params)
}
const getAllUser = (params) => {
return http.get('/user/get-all', {
params
})
}
export { getUser, loginUser, createUser, getAllUser, updateUser, deleteUser }

@ -73,14 +73,9 @@
v-for="(item, index) in props.dropdownData"
:key="index"
>
<!-- 权限控制 item.auth-->
<div v-permission="item.auth">
<el-dropdown-item
:command="item.command"
:icon="item.icon"
>{{ item.actionName }}</el-dropdown-item
>
</div>
<el-dropdown-item :command="item.command" :icon="item.icon">{{
item.actionName
}}</el-dropdown-item>
</template>
</el-dropdown-menu>
</template>

@ -91,6 +91,15 @@ export const asideData = [
]
}
]
export const keys = {
employeeAdmin: [1, 3, 11],
customAdmin: [],
feedbackAdmin: [1, 11, 5],
rewardAdmin: [1, 4, 11],
requestAdmin: [1, 11, 8]
}
export function generateNested(nodes, parentId = 0) {
const result = []
for (const node of nodes) {
@ -103,4 +112,38 @@ export function generateNested(nodes, parentId = 0) {
}
}
return result
}
}
export const getCommonElementIds = (data) => {
const dataIndices = new Set()
// Flatten data to get all indices, including children
function addIndices(arr) {
for (const item of arr) {
dataIndices.add(item.index)
if (item.children) {
addIndices(item.children)
}
}
}
addIndices(data)
const commonIds = []
// Traverse asideData to find common elements
function findCommonIds(arr) {
for (const item of arr) {
if (dataIndices.has(item.index)) {
commonIds.push(item.id)
}
if (item.children) {
findCommonIds(item.children)
}
}
}
findCommonIds(asideData)
return commonIds
}

@ -0,0 +1,98 @@
// 路由数据
export const routerData = [
{
path: 'home',
name: 'home',
meta: {
// 路由组件的路径
url: '../views/HomeView.vue',
id: 1
}
},
//
{
path: 'user-manage',
name: 'user-manage',
meta: {
// 路由组件的路径
url: '../views/UserManageView.vue',
id: 2
}
},
{
path: 'employee-manage',
name: 'employee-manage',
meta: {
// 路由组件的路径
url: '../views/EmployeeManageView.vue',
id: 3
}
},
{
path: 'reward-manage',
name: 'reward-manage',
meta: {
// 路由组件的路径
url: '../views/RewardManageView.vue',
id: 4
}
},
// 二级
{
path: 'feedback/manage',
name: 'feedback-manage',
meta: {
// 路由组件的路径
url: '../views/feedback/FeedbackManageView.vue',
id: 6
}
},
{
path: 'feedback/view',
name: 'feedback-view',
meta: {
// 路由组件的路径
url: '../views/feedback/FeedbackView.vue',
id: 7
}
},
{
path: 'request/manage',
name: 'request-manage',
meta: {
// 路由组件的路径
url: '../views/request/RequestManageView.vue',
id: 9
}
},
{
path: 'request/view',
name: 'request-view',
meta: {
// 路由组件的路径
url: '../views/request/RequestView.vue',
id: 10
}
},
{
path: 'person/password',
name: 'person-password',
meta: {
// 路由组件的路径
url: '../views/PersonInfo/ChangePasswordView.vue',
id: 12
}
},
{
path: 'person/avatar',
name: 'person-avatar',
meta: {
// 路由组件的路径
url: '../views/PersonInfo/ChangeAvatarView.vue',
id: 13
}
}
]
export const getRouterDataByIds = (idArray) => {
return routerData.filter((route) => idArray.includes(route.meta.id))
}

@ -2,7 +2,7 @@
* @Author: BINGWU
* @Date: 2024-02-15 14:18:43
* @LastEditors: BINGWU HuJiaCheng2003@163.com
* @LastEditTime: 2024-05-14 23:55:39
* @LastEditTime: 2024-05-19 17:08:21
* @FilePath: \employee-information-management-system\app\src\stores\modules\user.js
* @Describe:
* @Mark: (˶ ˶)
@ -18,259 +18,200 @@ const useUserStore = defineStore(
token.value = newToken
}
// 模拟后台返回的侧边栏数据
const asideData = ref([
{
index: '/home',
icon: 'icon iconfont icon-shujutongji',
name: '数据统计'
},
//
{
index: '/user-manage',
icon: 'icon iconfont icon-yonghuguanli',
name: '用户管理'
},
{
index: '/employee-manage',
icon: 'icon iconfont icon-shenfenzhongxin-xinxiguanlizhigongxinxiguanli',
name: '职工管理'
},
{
index: '/reward-manage',
icon: 'icon iconfont icon-gerenjixiao',
name: '绩效管理'
},
// 二级
{
index: '/feedback',
icon: 'icon iconfont icon-fankui',
name: '员工反馈与投诉管理',
children: [
{
index: '/feedback/manage',
name: '投诉管理'
},
{
index: '/feedback/view',
name: '员工反馈'
}
]
},
{
index: '/request',
icon: 'icon iconfont icon-qingjiashenqing',
name: '请假管理',
children: [
{
index: '/request/manage',
name: '请假信息管理'
},
{
index: '/request/view',
name: '个人请假信息'
}
]
},
{
index: '/person',
icon: 'icon iconfont icon-gerenxinxiguanli',
name: '个人信息管理',
children: [
{
index: '/person/password',
name: '修改密码'
},
{
index: '/person/avatar',
name: '修改个人信息'
}
]
}
])
const asideData = ref([])
// const asideData = ref([
// {
// index: '/home',
// icon: 'icon iconfont icon-shujutongji',
// name: '数据统计'
// },
// //
// {
// index: '/user-manage',
// icon: 'icon iconfont icon-yonghuguanli',
// name: '用户管理'
// },
// {
// index: '/employee-manage',
// icon: 'icon iconfont icon-shenfenzhongxin-xinxiguanlizhigongxinxiguanli',
// name: '职工管理'
// },
// {
// index: '/reward-manage',
// icon: 'icon iconfont icon-gerenjixiao',
// name: '绩效管理'
// },
// // 二级
// {
// index: '/feedback',
// icon: 'icon iconfont icon-fankui',
// name: '员工反馈与投诉管理',
// children: [
// {
// index: '/feedback/manage',
// name: '投诉管理'
// },
// {
// index: '/feedback/view',
// name: '员工反馈'
// }
// ]
// },
// {
// index: '/request',
// icon: 'icon iconfont icon-qingjiashenqing',
// name: '请假管理',
// children: [
// {
// index: '/request/manage',
// name: '请假信息管理'
// },
// {
// index: '/request/view',
// name: '个人请假信息'
// }
// ]
// },
// {
// index: '/person',
// icon: 'icon iconfont icon-gerenxinxiguanli',
// name: '个人信息管理',
// children: [
// {
// index: '/person/password',
// name: '修改密码'
// },
// {
// index: '/person/avatar',
// name: '修改个人信息'
// }
// ]
// }
// ])
// 模拟后台返回的路由数据
const routerData = ref([
{
path: 'home',
name: 'home',
meta: {
// 路由组件的路径
url: '../views/HomeView.vue'
}
},
{
path: 'international',
name: 'international',
const routerData = ref([])
// const routerData = ref([
// {
// path: 'home',
// name: 'home',
// meta: {
// // 路由组件的路径
// url: '../views/HomeView.vue'
// }
// },
// {
// path: 'table/main-table1',
// name: 'main-table',
// meta: {
// name: '表格1',
// url: '../views/table/MainTableView.vue'
// }
// },
// {
// path: 'excel',
// name: 'excel',
meta: {
name: '国际化',
url: '../views/InternationalView.vue'
}
},
{
path: 'table/main-table1',
name: 'main-table',
meta: {
name: '表格1',
url: '../views/table/MainTableView.vue'
}
},
{
path: 'excel',
name: 'excel',
// meta: {
// name: 'excel',
// url: '../views/ExcelView.vue'
// }
// },
meta: {
name: 'excel',
url: '../views/ExcelView.vue'
}
},
{
path: 'file',
name: 'file',
// {
// path: 'tx-yun',
// name: 'tx-yun',
meta: {
name: 'file',
url: '../views/FileView.vue'
}
},
// meta: {
// name: 'tx-yun',
// url: '../views/TxView.vue'
// }
// },
{
path: 'rich-text',
name: 'rich-text',
// {
// path: 'preview-picture',
// name: 'preview-picture',
meta: {
name: 'rich-text',
url: '../views/RichTextView.vue'
}
},
{
path: 'permission',
name: 'permission',
// meta: {
// name: 'preview-picture',
// url: '../views/PreviewPictureView.vue'
// }
// },
meta: {
name: 'permission',
url: '../views/PermissionView.vue'
}
},
{
path: 'tx-yun',
name: 'tx-yun',
meta: {
name: 'tx-yun',
url: '../views/TxView.vue'
}
},
{
path: 'progress',
name: 'progress',
meta: {
name: 'progress',
url: '../views/ProgressView.vue'
}
},
{
path: 'preview-picture',
name: 'preview-picture',
meta: {
name: 'preview-picture',
url: '../views/PreviewPictureView.vue'
}
},
// 三级路由
{
path: 'menu/menu-1-1',
name: 'child-menu',
meta: {
name: '菜单1-1',
url: '../views/FatherMenu/FatherMenuView.vue'
}
},
{
path: '/menu/menu-1-1/menu-1-3-1',
name: 'father-menu',
meta: {
name: '菜单1-3-1',
url: '../views/FatherMenu/ChildMenu/ChildMenuView.vue'
}
},
//
{
path: 'user-manage',
name: 'user-manage',
meta: {
// 路由组件的路径
url: '../views/UserManageView.vue'
}
},
{
path: 'employee-manage',
name: 'employee-manage',
meta: {
// 路由组件的路径
url: '../views/EmployeeManageView.vue'
}
},
{
path: 'reward-manage',
name: 'reward-manage',
meta: {
// 路由组件的路径
url: '../views/RewardManageView.vue'
}
},
// 二级
{
path: 'feedback/manage',
name: 'feedback-manage',
meta: {
// 路由组件的路径
url: '../views/feedback/FeedbackManageView.vue'
}
},
{
path: 'feedback/view',
name: 'feedback-view',
meta: {
// 路由组件的路径
url: '../views/feedback/FeedbackView.vue'
}
},
{
path: 'request/manage',
name: 'request-manage',
meta: {
// 路由组件的路径
url: '../views/request/RequestManageView.vue'
}
},
{
path: 'request/view',
name: 'request-view',
meta: {
// 路由组件的路径
url: '../views/request/RequestView.vue'
}
},
{
path: 'person/password',
name: 'person-password',
meta: {
// 路由组件的路径
url: '../views/PersonInfo/ChangePasswordView.vue'
}
},
{
path: 'person/avatar',
name: 'person-avatar',
meta: {
// 路由组件的路径
url: '../views/PersonInfo/ChangeAvatarView.vue'
}
}
])
// //
// {
// path: 'user-manage',
// name: 'user-manage',
// meta: {
// // 路由组件的路径
// url: '../views/UserManageView.vue'
// }
// },
// {
// path: 'employee-manage',
// name: 'employee-manage',
// meta: {
// // 路由组件的路径
// url: '../views/EmployeeManageView.vue'
// }
// },
// {
// path: 'reward-manage',
// name: 'reward-manage',
// meta: {
// // 路由组件的路径
// url: '../views/RewardManageView.vue'
// }
// },
// // 二级
// {
// path: 'feedback/manage',
// name: 'feedback-manage',
// meta: {
// // 路由组件的路径
// url: '../views/feedback/FeedbackManageView.vue'
// }
// },
// {
// path: 'feedback/view',
// name: 'feedback-view',
// meta: {
// // 路由组件的路径
// url: '../views/feedback/FeedbackView.vue'
// }
// },
// {
// path: 'request/manage',
// name: 'request-manage',
// meta: {
// // 路由组件的路径
// url: '../views/request/RequestManageView.vue'
// }
// },
// {
// path: 'request/view',
// name: 'request-view',
// meta: {
// // 路由组件的路径
// url: '../views/request/RequestView.vue'
// }
// },
// {
// path: 'person/password',
// name: 'person-password',
// meta: {
// // 路由组件的路径
// url: '../views/PersonInfo/ChangePasswordView.vue'
// }
// },
// {
// path: 'person/avatar',
// name: 'person-avatar',
// meta: {
// // 路由组件的路径
// url: '../views/PersonInfo/ChangeAvatarView.vue'
// }
// }
// ])
// 动态添加路由
const addUserRoute = (router, modules) => {
routerData.value.forEach((item) => {

@ -2,12 +2,13 @@
* @Author: BINGWU
* @Date: 2024-01-23 21:37:43
* @LastEditors: BINGWU HuJiaCheng2003@163.com
* @LastEditTime: 2024-05-14 00:01:39
* @LastEditTime: 2024-05-19 20:53:05
* @FilePath: \employee-information-management-system\app\src\utils\http.js
* @Describe:
* @Mark: (˶ ˶)
*/
import axios from 'axios'
import { getUserStore } from '@/stores'
const instance = axios.create({
baseURL: '/api'
})
@ -16,8 +17,9 @@ const instance = axios.create({
instance.interceptors.request.use(
(config) => {
// 在发送请求之前做些什么
config.headers.Authorization =
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjI3MTI3Mjk3MTIsImlhdCI6MTcxMjcyOTcxMywiZGF0YSI6eyJ1c2VybmFtZSI6IkFsZ2ZkZ2RmZ2RpY2UiLCJwYXNzd29yZCI6IjEyZ2RmZ2QzIiwicm9sZV9kYXRhIjoiZGVmYXVsdCJ9fQ.cLo2NZ01z2umdbmnDBBuyekFrT8yTyvzBv8gHifzhKU'
const userStore = getUserStore()
config.headers.Authorization = userStore.token
return config
},
(error) => {
@ -42,5 +44,14 @@ instance.interceptors.response.use(
return Promise.reject(error)
}
)
// 单独封装delet请求
export const deleteRequest = (url, params) => {
const userStore = getUserStore()
return axios.delete('/api' + url, {
data: params,
headers: {
Authorization: userStore.token
}
})
}
export default instance

@ -1,88 +0,0 @@
<template>
<div class="excel">
<h3>导出</h3>
<ExportExcelCom @handleExportData="handleExportData"></ExportExcelCom>
<h3>导入</h3>
<ImportExcelCom @importData="importData"></ImportExcelCom>
<h3>表格</h3>
<BaseTableCom
:columnData="columnData"
:showSelect="true"
:tableData="tableData"
ref="baseTableComRef"
></BaseTableCom>
</div>
</template>
<script setup>
import ExportExcelCom from '@/components/excel/ExportExcelCom.vue'
import ImportExcelCom from '@/components/excel/ImportExcelCom.vue'
import BaseTableCom from '@/components/table/BaseTableCom.vue'
import { ref } from 'vue'
const baseTableComRef = ref(null)
//
const importData = (excelFilesData) => {
console.log('已被导入的文件的数据', excelFilesData)
ElMessage({
showClose: true,
message: '处理导入的数据',
type: 'success'
})
tableData.value = tableData.value.concat(excelFilesData)
}
//
let exportData = []
//
const columnData = [
{
prop: 'age',
label: '年龄'
},
{
prop: 'name',
label: '性别'
},
{
prop: 'hobby',
label: '爱好'
},
{
prop: 'project',
label: '专业'
}
]
const tableData = ref([
{
age: 18,
name: '永远18岁',
hobby: '夹声音',
project: '唱歌'
},
{
age: 19,
name: '永远18岁',
hobby: '夹声音',
project: '唱歌'
},
{
age: 20,
name: '永远18岁',
hobby: '夹声音',
project: '唱歌'
},
{
age: 21,
name: '永远18岁',
hobby: '夹声音',
project: '唱歌'
}
])
//
const handleExportData = (exportFile, fileName, fileExtension) => {
// exportData
exportData = baseTableComRef.value.getSelectRows()
exportFile(exportData, fileName, fileExtension)
}
</script>
<style lang="scss" scoped></style>

@ -1,20 +0,0 @@
<!--
* @Author: BINGWU
* @Date: 2024-02-01 00:31:58
* @LastEditors: BINGWU HuJiaCheng2003@163.com
* @LastEditTime: 2024-02-10 21:21:20
* @FilePath: \bingwu-admin\src\views\FatherMenu\ChiladMenu\ChildMenuView.vue
* @Describe:
* @Mark: (˶ ˶)
-->
<template>
<div>
ChildMenu
<!-- <RouterView /> -->
</div>
</template>
<script setup>
</script>
<style lang="scss" scoped></style>

@ -1,16 +0,0 @@
<!--
* @Author: BINGWU
* @Date: 2024-02-01 00:31:24
* @LastEditors: BINGWU HuJiaCheng2003@163.com
* @LastEditTime: 2024-02-01 00:32:18
* @FilePath: \bingwu-admin\src\views\FatherMenu\FatherMenu.vue
* @Describe:
* @Mark: (˶ ˶)
-->
<template>
<div>FatherMenu</div>
</template>
<script setup></script>
<style lang="scss" scoped></style>

@ -1,54 +0,0 @@
<template>
<div class="file">
<UploadFileCom
ref="uploadFileComRef"
accept=".jpg,.jpeg,.png"
@handleConfirm="handleConfirm"
>
<template #tip>选择文件的提示</template>
</UploadFileCom>
<div style="margin: 50px 0">
<el-button
@click="
() => {
const files = uploadFileComRef.getSelectFiles()
console.log('files:', files)
}
"
>获取已被选择的文件</el-button
>
</div>
<ProgressLiteCom ref="progressLiteComRef"></ProgressLiteCom>
</div>
</template>
<script setup>
import UploadFileCom from '@/components/file/UploadFileCom.vue'
import ProgressLiteCom from '@/components/progress/ProgressLiteCom.vue'
import { ref, toRaw } from 'vue'
const uploadFileComRef = ref([])
const progressLiteComRef = ref(null)
//
const handleConfirm = (selectFiles) => {
// toRawproxy
console.log('confirm', toRaw(selectFiles))
uploadFileComRef.value.offDialog()
ElMessage({
showClose: true,
message: '点击了确认按钮',
type: 'success'
})
//
const startWork = progressLiteComRef.value.start()
setTimeout(() => {
progressLiteComRef.value.end(startWork)
}, 3000)
}
</script>
<style lang="scss" scoped>
.file {
width: 30%;
}
</style>

@ -1,3 +1,12 @@
<!--
* @Author: BINGWU
* @Date: 2024-04-10 16:15:37
* @LastEditors: BINGWU HuJiaCheng2003@163.com
* @LastEditTime: 2024-05-19 17:07:18
* @FilePath: \employee-information-management-system\app\src\views\LoginView.vue
* @Describe:
* @Mark: (˶ ˶)
-->
<template>
<div class="login">
<div class="content">
@ -18,7 +27,7 @@
import { ref } from 'vue'
import { useRouter } from 'vue-router'
import { getUserStore } from '@/stores'
import { loginUser } from '@/api/user'
import { loginUser, getUser } from '@/api/user'
const modules = import.meta.glob('../views/**/**.vue')
const router = useRouter()
const userStore = getUserStore()
@ -30,14 +39,20 @@ const login = () => {
loginUser({
...formData.value
})
.then((res) => {
.then(async (res) => {
const { token, _id } = res.data
ElMessage({
message: res.data.msg,
type: 'success',
plain: true
})
userStore.setToken(token)
const data = await getUser(_id)
const { asideData, routerData } = data.data
userStore.addUserRoute(router, modules)
userStore.setToken('my-token')
userStore.asideData = asideData
userStore.routerData = routerData
router.push('/home')
})
.catch((message) => {

@ -1,55 +0,0 @@
<!--
* @Author: BINGWU
* @Date: 2024-02-15 14:28:56
* @LastEditors: BINGWU HuJiaCheng2003@163.com
* @LastEditTime: 2024-02-16 21:12:52
* @FilePath: \bingwu-admin\src\views\PermissionView.vue
* @Describe:
* @Mark: (˶ ˶)
-->
<template>
<div class="permission">
<h1>按钮的权限管理</h1>
<!-- 四个按钮有a,b,c,d权限 -->
<el-button v-permission="'a'">a</el-button>
<el-button v-permission="'b'">b</el-button>
<el-button v-permission="'c'">c</el-button>
<el-button v-permission="'d'">d</el-button>
<hr />
<h4>用户切换</h4>
<el-button
type="primary"
@click="
() => {
swictUser('cxk')
}
"
>切换为用户cxk</el-button
>
<el-button
type="primary"
@click="
() => {
swictUser('admin')
}
"
>切换为用户admin</el-button
>
</div>
</template>
<script setup>
import { getUserStore } from '@/stores'
const userStore = getUserStore()
const swictUser = (usename) => {
userStore.switchUser(usename)
//
location.reload()
ElMessage({
message: `切换为用户${usename}`,
type: 'success'
})
}
</script>
<style lang="scss" scoped></style>

@ -1,36 +0,0 @@
<!--
* @Author: BINGWU
* @Date: 2024-02-17 16:32:46
* @LastEditors: BINGWU HuJiaCheng2003@163.com
* @LastEditTime: 2024-02-17 18:01:52
* @FilePath: \bingwu-admin\src\views\PreviewPictureView.vue
* @Describe:
* @Mark: (˶ ˶)
-->
<template>
<div class="preview-picture">
<PreviewPictureCom ref="previewPictureComRef"> </PreviewPictureCom>
<div style="margin-top: 60px">
<el-button @click="getFileData" type="primary">获取图片文件</el-button>
</div>
</div>
</template>
<script setup>
import PreviewPictureCom from '@/components/PreviewPictureCom.vue'
import { ref } from 'vue'
const previewPictureComRef = ref(null)
const getFileData = () => {
const fileData = previewPictureComRef.value.fileFn().getFile()
const url = previewPictureComRef.value.imageUrlFn().getImageUrl()
console.log('file-data: ', fileData)
console.log('url: ', url.value)
previewPictureComRef.value
.imageUrlFn()
.setImageUrl(
'https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg'
)
}
</script>
<style lang="scss" scoped></style>

@ -1,54 +0,0 @@
<!--
* @Author: BINGWU
* @Date: 2024-02-17 19:59:25
* @LastEditors: BINGWU HuJiaCheng2003@163.com
* @LastEditTime: 2024-02-22 21:25:38
* @FilePath: \bingwu-admin\src\views\ProgressView.vue
* @Describe:
* @Mark: (˶ ˶)
-->
<template>
<div class="progress">
<h5>进度条</h5>
<ProgressLiteCom
ref="progressLiteComRef"
:time="data.time"
:increment="data.increment"
:progress-type="data.progressType"
></ProgressLiteCom>
<div style="margin-top: 60px">
<el-button @click="test" type="primary">测试</el-button>
</div>
</div>
</template>
<script setup>
import ProgressLiteCom from '@/components/progress/ProgressLiteCom.vue'
import { ref } from 'vue'
const progressLiteComRef = ref(null)
const data = {
//
time: 500,
// (100)
increment: 8,
//
progressType: {
type1: true,
type2: true,
type3: true
}
}
const test = () => {
//
const startWork = progressLiteComRef.value.start()
setTimeout(() => {
progressLiteComRef.value.end(startWork, 'error', '上传失败')
}, 4000)
}
</script>
<style lang="scss" scoped>
.progress {
width: 20%;
}
</style>

@ -1,73 +0,0 @@
<!--
* @Author: BINGWU
* @Date: 2024-02-10 22:40:07
* @LastEditors: BINGWU HuJiaCheng2003@163.com
* @LastEditTime: 2024-02-16 21:59:15
* @FilePath: \bingwu-admin\src\views\RichTextView.vue
* @Describe:
* @Mark: (˶ ˶)
-->
<template>
<div class="rich-text">
<div style="border: 1px solid #ccc">
<Toolbar
style="border-bottom: 1px solid #ccc"
:editor="editorRef"
:defaultConfig="toolbarConfig"
:mode="mode"
/>
<Editor
style="height: 500px; overflow-y: hidden"
v-model="valueHtml"
:defaultConfig="editorConfig"
:mode="mode"
@onCreated="handleCreated"
/>
</div>
</div>
</template>
<script setup>
import '@wangeditor/editor/dist/css/style.css' // css
import { onBeforeUnmount, ref, shallowRef, onMounted } from 'vue'
import { Editor, Toolbar } from '@wangeditor/editor-for-vue'
// shallowRef
const editorRef = shallowRef()
// HTML
const valueHtml = ref('<p>hello</p>')
// ajax
onMounted(() => {
setTimeout(() => {
valueHtml.value = '<p>模拟 Ajax 异步设置内容</p>'
}, 1500)
})
const toolbarConfig = {}
const editorConfig = { placeholder: '请输入内容...', MENU_CONF: {} }
editorConfig.MENU_CONF['uploadImage'] = {
server: '/api/upload-image',
fieldName: 'custom-field-name'
}
//
onBeforeUnmount(() => {
const editor = editorRef.value
if (editor == null) return
editor.destroy()
})
const handleCreated = (editor) => {
editorRef.value = editor // editor
}
const mode = 'default'
</script>
<style lang="scss" scoped>
.rich-text {
width: 50%;
}
</style>

@ -1,75 +0,0 @@
<template>
<div>
<h1>腾讯储存桶测试</h1>
<el-upload
class="avatar-uploader"
:show-file-list="false"
:auto-upload="false"
:on-change="uploaderFile"
>
<img v-if="imageUrl" :src="imageUrl" class="avatar" />
<el-icon v-else class="avatar-uploader-icon"><Plus /></el-icon>
</el-upload>
<div style="margin-top: 60px">
<el-button @click="submit" type="primary">提交</el-button>
</div>
<h5>进度条</h5>
<ProgressCom ref="progressComRef"></ProgressCom>
</div>
</template>
<script setup>
import ProgressCom from '@/components/progress/ProgressCom.vue'
import { smallFileUpload, largeFileUpload } from '@/utils/tencentCloud'
import { ref } from 'vue'
//
const progressComRef = ref(null)
const uploadFile = ref(null)
const imageUrl = ref('')
const uploaderFile = (file) => {
console.log('file', file)
uploadFile.value = file
}
const update = (data) => {
progressComRef.value.changePercentage(data)
}
const submit = () => {
//
progressComRef.value.openProgress()
smallFileUpload(uploadFile.value, '', update).then((res) => {
progressComRef.value.offProgress()
imageUrl.value = res
})
}
</script>
<style lang="scss" scoped>
:deep(.avatar-uploader .avatar) {
width: 178px;
height: 178px;
display: block;
}
:deep(.avatar-uploader .el-upload) {
border: 1px dashed var(--el-border-color);
border-radius: 6px;
cursor: pointer;
position: relative;
overflow: hidden;
transition: var(--el-transition-duration-fast);
}
:deep(.avatar-uploader .el-upload:hover) {
border-color: var(--el-color-primary);
}
:deep(.el-icon.avatar-uploader-icon) {
font-size: 28px;
color: #8c939d;
width: 178px;
height: 178px;
text-align: center;
}
</style>

@ -2,25 +2,111 @@
* @Author: BINGWU
* @Date: 2024-04-11 16:53:10
* @LastEditors: BINGWU HuJiaCheng2003@163.com
* @LastEditTime: 2024-04-11 16:53:18
* @FilePath: \app\src\views\UserManageView.vue
* @LastEditTime: 2024-05-19 20:35:29
* @FilePath: \employee-information-management-system\app\src\views\UserManageView.vue
* @Describe:
* @Mark: (˶ ˶)
-->
<template>
<div class="user-manage">
<el-button type="primary">添加用户</el-button>
<el-button type="primary" @click="openDialog"></el-button>
<div clase="table">
<BaseTableCom></BaseTableCom>
<BaseTableCom
ref="baseTableComRef"
:column-data="columnData"
:show-pagination="true"
:page-sizes="[5, 8]"
:table-data="tableData"
:dropdown-data="dropdownData"
:total="total"
@update-table-data="updateTableData"
></BaseTableCom>
</div>
<UserFormCom></UserFormCom>
<UserFormCom
ref="userFormComRef"
:title="title"
@update-table-data="getTableData"
></UserFormCom>
</div>
</template>
<script setup>
import { ref } from 'vue'
import { ref, onMounted } from 'vue'
import UserFormCom from './components/form/UserFormCom.vue'
import BaseTableCom from '@/components/table/BaseTableCom.vue'
import { getAllUser, deleteUser } from '@/api/user'
import { getCommonElementIds } from '@/db/asideData'
const userFormComRef = ref(null)
const tableData = ref([])
const total = ref(0)
const title = ref()
const baseTableComRef = ref(null)
const dropdownData = [
{
command: 'command1',
handleAction: (row) => {
returnData(row, '查看')
},
icon: 'View',
actionName: '查看'
},
{
command: 'command2',
handleAction: (row) => {
returnData(row, '修改')
},
icon: 'Edit',
actionName: '修改'
},
{
command: 'command3',
handleAction: async (row) => {
const { _id } = row
await deleteUser({ _ids: [_id] })
await getTableData()
},
icon: 'Delete',
actionName: '删除'
}
]
const columnData = [
{
prop: 'username',
label: '用户名'
},
{
prop: 'userType',
label: '用户类型'
}
]
const openDialog = () => {
title.value = '添加'
userFormComRef.value.openDialog()
}
const getTableData = async (params = null) => {
if (!params) {
const { currentPage, pageSize } = baseTableComRef.value.getPaginationData()
params = { pageIndex: currentPage, pageSize }
}
const res = await getAllUser(params)
const { data } = res.data
tableData.value = data
total.value = res.data.total
}
const updateTableData = async (pageSize, pageIndex) => {
await getTableData({ pageSize, pageIndex })
}
const returnData = (row, newTiltle) => {
title.value = newTiltle
const { asideData, username, password, userType, _id } = row
const keys = getCommonElementIds(asideData)
userFormComRef.value.openDialog(keys, username, password, userType, _id)
}
onMounted(async () => {
await getTableData({ pageSize: 5, pageIndex: 1 })
})
</script>
<style lang="scss" scoped></style>

@ -1,35 +1,66 @@
<!--
* @Author: BINGWU
* @Date: 2024-05-14 23:46:48
* @LastEditors: BINGWU HuJiaCheng2003@163.com
* @LastEditTime: 2024-05-19 20:16:24
* @FilePath: \employee-information-management-system\app\src\views\components\form\UserFormCom.vue
* @Describe:
* @Mark: (˶ ˶)
-->
<template>
<div class="UserFormCom">
<div class="user-form">
<el-dialog
v-model="dialogVisible"
title="Tips"
:title="props.title + '用户'"
width="500"
:before-close="handleClose"
>
<el-form :model="form" label-width="auto" style="max-width: 600px">
<el-form-item label="用户名">
<el-input type="text" v-model="formData.username" />
<el-form
:model="formData"
:rules="rules"
label-width="auto"
style="max-width: 600px"
ref="formRef"
>
<el-form-item label="用户名" prop="username">
<el-input
type="text"
v-model="formData.username"
:disabled="title === '查看'"
/>
</el-form-item>
<el-form-item label="密码">
<el-input type="password" v-model="formData.password" />
<el-form-item label="密码" prop="password">
<el-input type="password" show-password v-model="formData.password" />
</el-form-item>
<el-form-item label="角色类型">
<el-input type="text" v-model="formData.userType" />
<el-form-item label="角色类型" prop="userType" required>
<el-radio-group
v-model="formData.userType"
@change="handleRadioChange"
:disabled="title === '查看'"
>
<el-radio label="employeeAdmin">员工管理员</el-radio>
<el-radio label="rewardAdmin">员工绩效管理员</el-radio>
<el-radio label="requestAdmin">员工请假信息管理员</el-radio>
<el-radio label="feedbackAdmin">员工反馈信息管理员</el-radio>
<el-radio label="customAdmin">自定义管理员</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="菜单权限">
<el-tree
style="max-width: 600px"
:data="asideData"
show-checkbox
node-key="id"
default-expand-all
:props="defaultProps"
ref="elTreeRef"
/>
<el-form-item label="菜单权限" prop="asideData" required>
<div class="tree-content">
<el-tree
style="max-width: 600px"
:data="asideData"
show-checkbox
node-key="id"
default-expand-all
:props="defaultProps"
ref="elTreeRef"
/>
</div>
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<div class="dialog-footer" v-show="title !== '查看'">
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" @click="handleConfirm"> </el-button>
</div>
@ -39,17 +70,35 @@
</template>
<script setup>
import { ref } from 'vue'
import { asideData, generateNested } from '@/db/asideData'
const formData = ref({ name: '', password: '', userType: '' })
const dialogVisible = ref(true)
import { ref, reactive, computed, nextTick } from 'vue'
import { getRouterDataByIds } from '@/db/routerData'
import { asideData, generateNested, keys } from '@/db/asideData'
import { createUser, updateUser } from '@/api/user'
import axios from 'axios'
const formData = reactive({
name: '',
password: '',
userType: '',
asideData: ['default']
})
const dialogVisible = ref(false)
const props = defineProps({
title: {
type: String,
default: '添加'
}
})
const elTreeRef = ref(null)
const formRef = ref(null)
let newId = ''
const defaultProps = {
children: 'children',
label: 'name'
}
const handleConfirm = () => {
const checkedKeys = computed(() => {
return elTreeRef.value.getCheckedKeys()
})
const getAsideData = () => {
const checkedNodes = elTreeRef.value.getCheckedNodes()
const tree = generateNested(checkedNodes)
const newTree = tree.map((item) => {
@ -63,8 +112,124 @@ const handleConfirm = () => {
}
return newItem
})
console.log('data1', newTree)
return newTree
}
const validateUserType = (rules, value, callback) => {
if (value) {
callback()
} else {
callback(new Error('请选择一个角色类型'))
}
}
const validateAsideData = (rules, value, callback) => {
if (checkedKeys.value.length) {
callback()
} else {
callback(new Error('至少选择一个菜单'))
}
}
const rules = ref({
username: [
{ required: true, message: '请输入用户名', trigger: 'blur' },
{ min: 5, max: 10, message: '长度为5~10个字符', trigger: 'blur' }
],
password: [
{ required: true, message: '请输入密码', trigger: 'blur' },
{ min: 5, max: 10, message: '长度为5~10个字符', trigger: 'blur' }
],
userType: [{ validator: validateUserType, trigger: 'blur' }],
asideData: [{ validator: validateAsideData, trigger: 'blur' }]
})
const emits = defineEmits(['updateTableData'])
const handleConfirm = () => {
formRef.value
.validate()
.then(async () => {
let message = ''
const asideData = getAsideData()
const routerData = getRouterDataByIds(checkedKeys.value)
if (props.title === '添加') {
const res = await axios.get(
'https://api.thecatapi.com/v1/images/search'
)
const avatar = res.data[0].url
const params = {
asideData,
routerData,
userType: formData.userType,
username: formData.username,
password: formData.password,
avatar
}
const {
data: { msg }
} = await createUser(params)
message = msg
} else if (props.title === '修改') {
const params = {
asideData,
routerData,
userType: formData.userType,
username: formData.username,
password: formData.password
}
const {
data: { msg }
} = await updateUser({
data: params,
_id: newId
})
message = msg
}
ElMessage({
message,
type: 'success'
})
emits('updateTableData')
offDialog()
})
.catch(() => {})
}
const setCheckedKeys = (keys = []) => {
nextTick(() => {
elTreeRef.value.setCheckedKeys(keys)
})
}
const handleRadioChange = (value) => {
setCheckedKeys(keys[value])
}
const openDialog = (keys, username, password, userType, _id) => {
dialogVisible.value = true
nextTick(() => {
formRef.value.clearValidate()
})
if (keys) {
setCheckedKeys(keys)
}
newId = _id
formData.userType = userType
formData.password = password
formData.username = username
}
const handleClose = () => {
setCheckedKeys()
offDialog()
}
const offDialog = () => (dialogVisible.value = false)
defineExpose({
openDialog,
offDialog
})
</script>
<style lang="scss" scoped></style>
<style lang="scss" scoped>
.user-form {
.tree-content {
width: 100%;
border: 1px solid #e5e6e7;
border-radius: 2px;
}
}
</style>

@ -1,195 +0,0 @@
<template>
<div class="main-table">
<BaseTableCom
:tableData="tableData"
:columnData="columnData"
:dropdownData="dropdownData"
:showSelect="true"
:pageSizes="[10, 15, 20]"
:total="100"
:showPagination="true"
messageBoxContent="确认要切换状态吗?"
messageBoxTitle="警告"
@updateSwitchState="updateSwitchState"
@updateTableData="updateTableData"
ref="baseTableComRef"
></BaseTableCom>
<div style="margin-top: 40px">
<el-button
@click="
() => {
// /
baseTableComRef.changeTableLoading()
}
"
>表格加载动画</el-button
>
<el-button
@click="
() => {
//
const rows = baseTableComRef.getSelectRows()
console.log('被勾选的行', rows)
}
"
>获取被勾选的行</el-button
>
<el-button
@click="
() => {
//
const paginationData = baseTableComRef.getPaginationData()
console.log('分页数据', paginationData)
}
"
>获取分页数据</el-button
>
</div>
</div>
</template>
<script setup>
import BaseTableCom from '@/components/table/BaseTableCom.vue'
import { ref } from 'vue'
const baseTableComRef = ref(null)
const tableData = [
{
// tag
// tag prop
tag: {
// tagNametagType
tagName: '成功',
tagType: 'success'
},
//
// picture prop
picture:
'https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg',
name: 'Tom1',
//
switch: false
},
{
tag: {
tagName: '信息',
tagType: 'info'
},
name: 'Tom2',
picture: 'https://placekitten.com/800/600',
switch: true
},
{
tag: {
tagName: '警告',
tagType: 'warning'
},
name: 'Tom3',
picture: 'https://placebear.com/800/600',
switch: true
},
{
tag: {
tagName: '默认',
tagType: 'default'
},
name: 'Tom4',
picture:
'https://loremflickr.com/cache/resized/65535_53040484749_6fd5663cd5_c_800_600_nofilter.jpg',
switch: false
},
{
tag: {
tagName: '危险',
tagType: 'danger'
},
name: 'Tom5',
picture:
'https://fastly.picsum.photos/id/875/800/600.jpg?hmac=NXX-SwYycWXsbCWcJJnivoEGENe8Mp4fvuHqATxgOSY',
switch: false
}
]
//
const dropdownData = [
{
command: 'command1',
handleAction: (row) => {
console.log('command1', row)
},
actionName: '删除',
// element
icon: 'Delete',
//
auth: 'delete'
},
{
command: 'command2',
handleAction: (row) => {
console.log('command2', row)
},
actionName: '查看',
icon: 'View',
auth: 'view'
},
{
command: 'conmmand3',
handleAction: (row) => {
console.log('command3', row)
},
actionName: '修改',
icon: 'Edit',
auth: 'edit'
}
]
//
const columnData = [
//
{
prop: 'picture',
label: '图片列',
// 使
pictureColumn: true
},
{
prop: 'name',
label: '普通数据列',
// px
width: '200',
// 使
sortable: true
},
// tag
{
prop: 'tag',
label: 'tag列',
// 使tag
tagColumn: true
},
//
{
prop: 'switch',
label: '开关列',
// 使
switchColumn: true
}
]
//
const updateSwitchState = (switchState) => {
console.log('改变后的switch状态', switchState)
//
baseTableComRef.value.changeSwitchLoading()
//
setTimeout(() => {
baseTableComRef.value.changeSwitchLoading()
}, 1000)
}
//
const updateTableData = (pageSize, currentPage) => {
console.log('页码', currentPage)
console.log('页面数据容量', pageSize)
}
</script>
<style lang="scss" scoped></style>

@ -2,8 +2,8 @@
* @Author: BINGWU
* @Date: 2024-02-16 18:42:11
* @LastEditors: BINGWU HuJiaCheng2003@163.com
* @LastEditTime: 2024-02-17 19:50:10
* @FilePath: \bingwu-admin\src\views\test\TestView.vue
* @LastEditTime: 2024-05-19 19:11:58
* @FilePath: \employee-information-management-system\app\src\views\test\TestView.vue
* @Describe:
* @Mark: (˶ ˶)
-->
@ -11,6 +11,26 @@
<div class="test">
<ProgressLiteCom ref="progressLiteComRef"></ProgressLiteCom>
<el-button type="primary" @click="test"></el-button>
<div class="example-pagination-block">
<div class="example-demonstration">When you have few pages</div>
<el-pagination layout="prev, pager, next" :total="50" />
</div>
<div class="demo-pagination-block">
<div class="demonstration">All combined</div>
<el-pagination
v-model:current-page="currentPage4"
v-model:page-size="pageSize4"
:page-sizes="[100, 200, 300, 400]"
:small="small"
:disabled="disabled"
:background="background"
layout="total, sizes, prev, pager, next, jumper"
:total="400"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
@change="change"
/>
</div>
</div>
</template>
@ -25,6 +45,26 @@ const test = () => {
progressLiteComRef.value.end(startWork)
}, 5000)
}
const currentPage1 = ref(5)
const currentPage2 = ref(5)
const currentPage3 = ref(5)
const currentPage4 = ref(4)
const pageSize2 = ref(100)
const pageSize3 = ref(100)
const pageSize4 = ref(100)
const small = ref(false)
const background = ref(false)
const disabled = ref(false)
const handleSizeChange = (val) => {
console.log(`${val} items per page`)
}
const handleCurrentChange = (val) => {
console.log(`current page: ${val}`)
}
const change = () => {
console.log('111')
}
onMounted(async () => {
await getUser().then((res) => {
console.log(res)

@ -58,7 +58,7 @@ def loginUser(request):
user = collection.find_one(query)
if user:
token = get_jwt_token(data['username'], data['password'])
return JsonResponse({"code": 2000, "msg": "登陆成功", "token": token})
return JsonResponse({"code": 2000, "msg": "登陆成功", "token": token, "_id": str(user['_id'])})
else:
return JsonResponse({"code": 1000, "msg": "数据不存在"})

Loading…
Cancel
Save