Jelajahi Sumber

完成角色权限,账户管理,薪资管理

@sun-chaoqun 2 tahun lalu
induk
melakukan
33e382e143

+ 7 - 1
README.md

@@ -1,5 +1,11 @@
-# ERP 
+# ERP
 
 > Vue 3 + TypeScript + Vite
 
+### 接口
 
+用户管理 http://erp.baozhida.cn/user
+
+薪资管理 http://erp.baozhida.cn/salary
+
+考勤管理 http://erp.baozhida.cn/ams

+ 3 - 3
src/api/index.ts

@@ -2,10 +2,10 @@ import axios from 'axios'
 import type { AxiosInstance, AxiosError, AxiosRequestConfig, InternalAxiosRequestConfig, AxiosResponse } from 'axios'
 import { ElMessage, ElLoading } from 'element-plus'
 import { ResultEnum, ResultData, ContentType } from './interface/index'
-import { GlobalStore } from '@/stores/index'
+// import { GlobalStore } from '@/stores/index'
 import { useRouter } from 'vue-router'
 const router = useRouter()
-const globalStore = GlobalStore()
+// const globalStore = GlobalStore()
 type LoadingType = {
   close?: () => void
 }
@@ -64,7 +64,7 @@ class RequestHttp {
         // * 登陆失效(code == 401)
         if (data.code == ResultEnum.OVERDUE) {
           ElMessage.error(data.msg)
-          globalStore.SET_User_Tokey('')
+          // globalStore.SET_User_Tokey('')
           router.replace('/login')
           return Promise.reject(data)
         }

+ 4 - 0
src/api/role/index.ts

@@ -14,3 +14,7 @@ export const User_Power_Add = (params: any): any => $http.post('/api/user/Power/
 export const User_Power_Edit = (params: any): any => $http.post('/api/user/Power/Edit', params)
 // 删除角色名
 export const User_Power_Del = (params: any): any => $http.post('/api/user/Power/Del', params)
+// 编辑菜单
+export const User_Power_Edit_Menu = (params: any): any => $http.post('/api/user/Power/Edit_Menu', params)
+// 获取用户权限
+export const User_Power_Get = (params: any): any => $http.post('/api/user/Power/Get', params)

+ 15 - 0
src/api/salary/index.ts

@@ -0,0 +1,15 @@
+import $http from '../index'
+// 用户列表
+export const Salary_List = (params: any) => $http.post('/api/salary/Salary/List', params)
+// 员工列表
+export const Salary_User_List = (params: any) => $http.post('/api/salary/Salary/User_List', params)
+// 获取最新的数据
+export const Salary_Get = (params: any) => $http.post('/api/salary/Salary/Get', params)
+// 员工薪资
+export const Salary_User_Get = (params: any) => $http.post('/api/salary/Salary/User_Get', params)
+// 发布
+export const Salary_Send = (params: any) => $http.post('/api/salary/Salary/Send', params)
+// 添加
+export const Salary_Post = (params: any) => $http.post('/api/salary/Salary/Post', params)
+// 导出Excel
+export const Salary_Excel = (params: any) => $http.post('/api/salary/Salary/Excel', params)

+ 8 - 10
src/assets/iconfont.css

@@ -1,12 +1,11 @@
 @font-face {
-  font-family: "iconfont"; /* Project id 3967191 */
-  src: url('iconfont.woff2?t=1679391620275') format('woff2'),
-       url('iconfont.woff?t=1679391620275') format('woff'),
-       url('iconfont.ttf?t=1679391620275') format('truetype');
+  font-family: 'iconfont'; /* Project id 3967191 */
+  src: url('./iconfont.woff2?t=1679447680399') format('woff2'), url('./iconfont.woff?t=1679447680399') format('woff'),
+    url('./iconfont.ttf?t=1679447680399') format('truetype');
 }
 
 .iconfont {
-  font-family: "iconfont" !important;
+  font-family: 'iconfont' !important;
   font-size: 16px;
   font-style: normal;
   -webkit-font-smoothing: antialiased;
@@ -14,18 +13,17 @@
 }
 
 .icon-money:before {
-  content: "\e663";
+  content: '\ue663';
 }
 
 .icon-moneybag:before {
-  content: "\e7d1";
+  content: '\ue7d1';
 }
 
 .icon-moneycollect:before {
-  content: "\e7cd";
+  content: '\ue7cd';
 }
 
 .icon-money-funds:before {
-  content: "\e831";
+  content: '\ue831';
 }
-

TEMPAT SAMPAH
src/assets/iconfont.ttf


TEMPAT SAMPAH
src/assets/iconfont.woff


TEMPAT SAMPAH
src/assets/iconfont.woff2


+ 0 - 1
src/assets/vue.svg

@@ -1 +0,0 @@
-<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="37.07" height="36" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 198"><path fill="#41B883" d="M204.8 0H256L128 220.8L0 0h97.92L128 51.2L157.44 0h47.36Z"></path><path fill="#41B883" d="m0 0l128 220.8L256 0h-51.2L128 132.48L50.56 0H0Z"></path><path fill="#35495E" d="M50.56 0L128 133.12L204.8 0h-47.36L128 51.2L97.92 0H50.56Z"></path></svg>

+ 8 - 3
src/components/Drawer/index.vue

@@ -6,17 +6,21 @@ const drawerRef = ref(null)
 type Fn = () => void
 interface drawerProps {
   title?: string
+  size?: string
   handleClose?: (params: Fn) => void
+  openDrawer?: (params: Fn) => void
   direction?: string
 }
 
 withDefaults(defineProps<drawerProps>(), {
   title: '',
+  size: '30%',
   direction: 'rtl' // rtl / ltr / ttb / btt
 })
 
-const closeDrawer = () => (visible.value = true)
-defineExpose({ closeDrawer })
+const openDrawer = () => (visible.value = true)
+const closeDrawer = () => (visible.value = false)
+defineExpose({ closeDrawer, openDrawer })
 </script>
 
 <template>
@@ -24,10 +28,11 @@ defineExpose({ closeDrawer })
     <el-drawer
       ref="drawerRef"
       v-model="visible"
+      lock-scroll
       :title="title"
       :before-close="handleClose"
       :direction="direction"
-      class="demo-drawer"
+      :size="size"
     >
       <template #header="{ close, titleId, titleClass }">
         <slot name="header" :params="{ close, titleId, titleClass }"></slot>

+ 13 - 6
src/hooks/useTable.ts

@@ -51,21 +51,28 @@ export const useTable = (
   })
 
   const getTableList = async () => {
-    const res = await requestApi(initParam)
+    const params: any = {
+      ...initParam,
+      page: state.pageable.pageNum,
+      page_z: state.pageable.pageSize
+    }
+    const res = await requestApi(params)
     dataCallback && dataCallback(res)
-    console.log(res)
     state.tableData = res.Data.Data
+    state.pageable.total = res.Data.Num
   }
 
   if (isPagination) {
   }
 
-  const handleSizeChange = () => {
-    return false
+  const handleSizeChange = (val: number) => {
+    state.pageable.pageSize = val
+    getTableList()
   }
 
-  const handleCurrentChange = () => {
-    return false
+  const handleCurrentChange = (val: number) => {
+    state.pageable.pageNum = val
+    getTableList()
   }
 
   return {

+ 13 - 3
src/layouts/Menu/SubMenu.vue

@@ -11,17 +11,19 @@ const handleClickMenu = (route: Menu.MenuOptions) => {
   <div v-for="subItem in menuList" :key="subItem.path">
     <el-sub-menu v-if="subItem.children && subItem.children.length > 0" :index="subItem.path">
       <template #title>
-        <el-icon>
+        <el-icon v-if="subItem.meta.icon">
           <component :is="subItem.meta.icon"></component>
         </el-icon>
+        <i v-else class="iconfont">{{ subItem.meta.unicode }}</i>
         <span>{{ subItem.meta.title }}</span>
       </template>
       <SubMenu :menuList="subItem.children" />
     </el-sub-menu>
     <el-menu-item v-else :index="subItem.path" @click="handleClickMenu(subItem)">
-      <el-icon>
+      <el-icon v-if="subItem.meta.icon">
         <component :is="subItem.meta.icon"></component>
       </el-icon>
+      <i v-else class="iconfont">{{ subItem.meta.unicode }}</i>
       <template #title>
         <span>{{ subItem.meta.title }}</span>
       </template>
@@ -29,4 +31,12 @@ const handleClickMenu = (route: Menu.MenuOptions) => {
   </div>
 </template>
 
-<style></style>
+<style scoped>
+.iconfont {
+  margin-right: 5px;
+  width: var(--el-menu-icon-width);
+  text-align: center;
+  font-size: 18px;
+  vertical-align: middle;
+}
+</style>

+ 13 - 1
src/stores/index.ts

@@ -1,19 +1,31 @@
 import { defineStore, createPinia } from 'pinia'
 import { GlobalState } from './interface/index'
+import { User_Dept_List, User_Post_List } from '@/api/user/index'
 export const GlobalStore = defineStore({
   id: 'GlobalState',
   state: (): GlobalState => ({
     loading: false,
+    UserDeptList: [],
+    UserPostList: [],
     User_tokey: localStorage.getItem('User_tokey') || ''
   }),
   getters: {
-    GET_User_tokey: state => state.User_tokey
+    GET_User_tokey: state => state.User_tokey,
+    GET_Dept_List: state => state.UserDeptList
   },
   actions: {
     SET_User_Tokey(payload: string) {
       if (typeof payload === 'string') {
         this.User_tokey = payload
       }
+    },
+    async SET_User_Dept_List() {
+      const res: any = await User_Dept_List()
+      this.UserDeptList = res.Data
+    },
+    async SET_User_Post_List() {
+      const res = await User_Post_List()
+      console.log(res)
     }
   }
 })

+ 8 - 0
src/stores/interface/index.ts

@@ -4,6 +4,14 @@ export interface GlobalState {
   User_tokey: string
   userInfo?: any
   language?: string
+  UserPostList: string[]
+  UserDeptList: UserDeptType[]
+}
+
+export interface UserDeptType {
+  Id: number
+  T_State: number
+  T_name: string
 }
 
 /* tabsMenuProps */

+ 32 - 11
src/style.scss

@@ -26,6 +26,37 @@ body,
   width: 100%;
 }
 
+.margin-left-0 {
+  margin-left: 0;
+}
+.margin-right-0 {
+  margin-right: 0;
+}
+.margin-top-0 {
+  margin-top: 0;
+}
+.margin-bottom-0 {
+  margin-bottom: 0;
+}
+.padding-left-0 {
+  padding-left: 0 !important;
+}
+.padding-right-0 {
+  padding-right: 0 !important;
+}
+.padding-top-0 {
+  padding-top: 0 !important;
+}
+.padding-bottom-0 {
+  padding-bottom: 0 !important;
+}
+.w-100 {
+  width: 100%;
+}
+.h-100 {
+  height: 100%;
+}
+
 ::-webkit-scrollbar {
   width: 3px;
   height: 3px;
@@ -38,14 +69,4 @@ body,
   background-color: #999;
 }
 
-// ::-webkit-scrollbar {
-//   width: 2px;
-// }
-// ::-webkit-scrollbar-thumb {
-//   border-radius: 2px;
-//   background: rgba(0, 0, 0, 0.2);
-// }
-// ::-webkit-scrollbar-track {
-//   border-radius: 0;
-//   background: rgba(0, 0, 0, 0.1);
-// }
+@import '@/assets/iconfont.css';

+ 2 - 1
src/typings/global.d.ts

@@ -9,7 +9,8 @@ declare namespace Menu {
     children?: MenuOptions[]
   }
   interface MetaProps {
-    icon: string
+    icon?: string
+    unicode?: string
     title: string
     activeMenu?: string
     isKeepAlive: boolean

+ 16 - 4
src/views/Index.vue

@@ -1,9 +1,12 @@
 <script setup lang="ts">
+import { ref, onMounted } from 'vue'
 import SubMenu from '@/layouts/Menu/SubMenu.vue'
 import Main from '@/layouts/Main/index.vue'
 import Header from '@/layouts/Header/index.vue'
 import { Menu_User_List } from '@/api/role/index'
 import { GlobalStore } from '@/stores/index'
+
+import { useRoute } from 'vue-router'
 // import md5 from 'js-md5'
 // console.log(md5('123456'))
 const globalStore = GlobalStore()
@@ -64,7 +67,7 @@ const routerList = [
     path: '/salary',
     name: '薪资管理',
     meta: {
-      icon: 'HomeFilled',
+      unicode: '\ue663',
       title: '薪资管理',
       isKeepAlive: true
     },
@@ -73,7 +76,7 @@ const routerList = [
         path: '/salary',
         name: '薪资管理',
         meta: {
-          icon: 'HomeFilled',
+          unicode: '\ue7cd',
           title: '薪资管理',
           isKeepAlive: true
         }
@@ -82,7 +85,7 @@ const routerList = [
         path: '/salaryCount',
         name: '薪资统计',
         meta: {
-          icon: 'HomeFilled',
+          unicode: '\ue831',
           title: '薪资统计',
           isKeepAlive: true
         }
@@ -91,7 +94,7 @@ const routerList = [
         path: '/salaryMy',
         name: '我的薪资',
         meta: {
-          icon: 'HomeFilled',
+          unicode: '\ue7d1',
           title: '我的薪资',
           isKeepAlive: true
         }
@@ -133,6 +136,14 @@ const routerList = [
     ]
   }
 ]
+onMounted(() => {
+  // store
+  globalStore.SET_User_Dept_List()
+  // globalStore.SET_User_Post_List()
+})
+
+const route = useRoute()
+const defaultActive = ref<string>(route.path)
 </script>
 
 <template>
@@ -142,6 +153,7 @@ const routerList = [
       <el-scrollbar class="scrollbar">
         <!-- text-color="#303133" -->
         <el-menu
+          :default-active="defaultActive"
           :unique-opened="true"
           :collapse-transition="false"
           active-text-color="#ffd04b"

+ 91 - 24
src/views/account/roles/Roles.vue

@@ -2,7 +2,16 @@
 import { ref, reactive, nextTick } from 'vue'
 import TableBase from '@/components/TableBase/index.vue'
 import type { ColumnProps } from '@/components/TableBase/interface/index'
-import { User_Power_List, User_Sys_List, Menu_List, User_Power_Add, User_Power_Del } from '@/api/role/index'
+import {
+  User_Power_List,
+  User_Sys_List,
+  Menu_List,
+  User_Power_Get,
+  User_Power_Add,
+  User_Power_Del,
+  User_Power_Edit,
+  User_Power_Edit_Menu
+} from '@/api/role/index'
 import { Edit, Delete, Operation } from '@element-plus/icons-vue'
 import Dialog from '@/components/dialog/Dialog.vue'
 import Drawer from '@/components/Drawer/index.vue'
@@ -11,14 +20,17 @@ import type { FormInstance, FormRules } from 'element-plus'
 import { ElNotification, ElMessageBox, ElMessage } from 'element-plus'
 
 const globalStore = GlobalStore()
+// 权限
 const dialog = ref()
 const TableRef = ref()
+let currentVal: any = {}
 const DialogOpen = async (row: any) => {
-  console.log(row)
+  currentVal = row
   await getSysList()
   dialog.value.DialogOpen()
 }
-const checkList = ref()
+
+const checkList = ref<string[]>([])
 const columns: ColumnProps[] = [
   { type: 'index', label: '#', width: 80 },
   { prop: 'T_name', label: '姓名' },
@@ -30,6 +42,7 @@ interface InSys {
   T_sys: string
   T_name: string
   children: any
+  checkList: string[]
 }
 
 let SysList = ref<InSys[]>([])
@@ -37,20 +50,56 @@ const getSysList = async () => {
   const { Data } = await User_Sys_List({ User_tokey: globalStore.GET_User_tokey })
   SysList.value = Data as InSys[]
 }
-// let MenuList = reactive([])
 const getMenuList = async (code: string) => {
-  const res = await Menu_List({ User_tokey: globalStore.GET_User_tokey, T_code: code })
+  // User_Power_Get
+  const res: any = await User_Power_Get({ User_tokey: globalStore.GET_User_tokey, T_code: code, T_id: currentVal.T_id })
   const sys = SysList.value.find(item => item.T_sys === code) as InSys
-  console.log(SysList, sys, res)
-  sys.children = res.Data.Data[0].Children
+  console.log(res)
+  sys.children = res.Data.Menu[0].Children
+  if (res.Data.Menu_checked) {
+    sys.checkList = sys.children.map((m: any) => {
+      if (res.Data.Menu_checked.includes(m.Id)) return m.T_name
+    })
+  } else {
+    sys.checkList = []
+  }
 }
-const submitUserRole = () => {
-  console.log(checkList)
+const submitUserRole = async (item: InSys) => {
+  console.log(checkList.value, currentVal, item, SysList)
+
+  let Sys: any = SysList.value.find(sys => item.T_sys === sys.T_sys)
+  let childs = Sys?.children.filter((child: InSys) => Sys.checkList.includes(child.T_name))
+  let T_menu = ''
+  if (childs.length > 1) {
+    childs.forEach((f: any) => {
+      let str = 'M' + f.Id + '|'
+      T_menu += str
+    })
+  } else {
+    T_menu = 'M' + childs[0].Id
+  }
+  const params = {
+    User_tokey: globalStore.GET_User_tokey,
+    T_id: currentVal.T_id,
+    T_code: item.T_sys,
+    T_menu
+  }
+  console.log(params)
+
+  // const res = await User_Power_Edit_Menu(params)
+  // if (res.Code === 200) {
+  //   ElMessage({
+  //     type: 'success',
+  //     message: '修改成功!'
+  //   })
+  //   dialog.value.DialogClose()
+  //   checkList.value = []
+  // }
 }
+
 const initParam = {
   User_tokey: globalStore.GET_User_tokey,
-  page: 1,
-  page_z: 10
+  T_name: ''
 }
 
 // 添加角色
@@ -69,12 +118,13 @@ const callbackDrawer = (done: Fn) => {
 const openDrawer = (type: string, row?: any) => {
   isNew.value = type === 'new' ? true : false
   nextTick(() => {
-    !isNew.value && (form.name = row.T_name)
+    !isNew.value && ((form.name = row.T_name), (form.id = row.T_id))
   })
-  drawerRef.value.closeDrawer()
+  drawerRef.value.openDrawer()
 }
 const form = reactive({
-  name: ''
+  name: '',
+  id: ''
 })
 const resetForm = (formEl: FormInstance | undefined) => {
   if (!formEl) return
@@ -84,15 +134,24 @@ const AddUserName = (formEl: FormInstance | undefined) => {
   if (!formEl) return
   formEl.validate(async valid => {
     if (valid) {
-      let res = await User_Power_Add({ User_tokey: globalStore.GET_User_tokey, T_name: form.name })
+      let res: any = {}
+      if (isNew.value) {
+        res = await User_Power_Add({ User_tokey: globalStore.GET_User_tokey, T_name: form.name })
+      } else {
+        res = await User_Power_Edit({ User_tokey: globalStore.GET_User_tokey, T_name: form.name, T_id: form.id })
+      }
       if (res.Code === 200) {
         ElNotification.success({
           title: '添加角色',
           message: '添加成功!',
           position: 'bottom-right'
         })
-        drawerRef.value.closeDrawer()
-        TableRef.value.getTableList()
+        nextTick(() => {
+          drawerRef.value.closeDrawer()
+          TableRef.value.getTableList()
+          resetForm(ruleFormRef.value)
+          isNew.value = false
+        })
       }
     } else {
       console.log('error submit!')
@@ -119,6 +178,13 @@ const UserDelete = (row: any) => {
       })
     })
 }
+
+// 搜索
+const search = ref('')
+const searchHandle = () => {
+  initParam.T_name = search.value
+  TableRef.value.getTableList()
+}
 </script>
 
 <template>
@@ -128,8 +194,8 @@ const UserDelete = (row: any) => {
         <el-row :gutter="20">
           <el-col :span="12">
             <span class="ml-3 w-35 text-gray-600 inline-flex items-center">角色名:</span>
-            <el-input type="text" class="w-50 m-2" />
-            <el-button type="primary">搜索</el-button>
+            <el-input v-model="search" type="text" class="w-50 m-2" />
+            <el-button type="primary" @click="searchHandle">搜索</el-button>
           </el-col>
           <el-col :span="6" :offset="6"><el-button type="primary" @click="openDrawer('new')">添加</el-button></el-col>
         </el-row>
@@ -158,16 +224,16 @@ const UserDelete = (row: any) => {
       >
       <el-col :span="18"
         ><div class="grid-content grid-active">
-          <el-checkbox-group v-model="checkList" v-if="item.children">
+          <el-checkbox-group v-model="item.checkList" v-if="item.children">
             <el-checkbox :label="child.T_name" v-for="child in item.children" :key="'rr' + child.Id">{{
               child.T_name
             }}</el-checkbox>
           </el-checkbox-group>
-        </div></el-col
-      >
+        </div>
+      </el-col>
       <el-col :span="3"
         ><div class="grid-content">
-          <el-button type="primary" @click="submitUserRole">提交</el-button>
+          <el-button type="primary" @click="submitUserRole(item)">提交</el-button>
         </div></el-col
       >
     </el-row>
@@ -181,7 +247,8 @@ const UserDelete = (row: any) => {
         <el-input v-model="form.name" type="text" autocomplete="off" placeholder="请输入角色名称" />
       </el-form-item>
       <el-form-item :label-width="formLabelWidth">
-        <el-button color="#626aef" @click="AddUserName(ruleFormRef)">添加</el-button>
+        <el-button v-if="isNew" color="#626aef" @click="AddUserName(ruleFormRef)">添加</el-button>
+        <el-button v-else color="#626aef" @click="AddUserName(ruleFormRef)">修改</el-button>
       </el-form-item>
     </el-form>
   </Drawer>

+ 5 - 0
src/views/account/roles/index.scss

@@ -13,6 +13,11 @@
   justify-content: start;
   align-items: center;
   flex-wrap: nowrap;
+  position: relative;
+}
+.grid-submit {
+  position: absolute;
+  right: 0.625rem;
 }
 .el-checkbox-group {
   display: flex;

+ 20 - 69
src/views/account/users/Users.vue

@@ -2,55 +2,39 @@
 import TableBase from '@/components/TableBase/index.vue'
 import { ColumnProps } from '@/components/TableBase/interface/index'
 import { Edit, Delete } from '@element-plus/icons-vue'
-import Drawer from '@/components/Drawer/index.vue'
 import { ref, reactive, onMounted } from 'vue'
 import { GlobalStore } from '@/stores/index'
 import { User_List, User_Add, User_Edit, User_Del, User_Post_List, User_Dept_List } from '@/api/user/index'
+import DrawerFrom from './components/DrawerFrom.vue'
 const globalStore = GlobalStore()
-const drawerRef = ref()
 const action = ref(true)
-const formLabelWidth = ref('80px')
-const form = reactive({
-  username: '',
-  password: '',
-  user: '',
-  department: '',
-  post: ''
-})
+const drawerFromRef = ref()
 const columns: ColumnProps[] = [
   { type: 'index', label: '#', width: 80 },
   { prop: 'T_name', label: '姓名', search: { el: 'input' } },
   { prop: 'T_post_name', label: '职位' },
   { prop: 'T_dept_name', label: '部门' },
+  { prop: 'T_phone', label: '联系电话' },
+  { prop: 'T_nation', label: '民族' },
+  { prop: 'T_school', label: '毕业院校' },
+  { prop: 'T_major', label: '专业' },
+  { prop: 'T_education', label: '学历' },
+  { prop: 'T_entry_time', label: '入职时间' },
+  { prop: 'T_positive_time', label: '转正时间' },
+  { prop: 'T_entry_type', label: '入职类型' },
+  { prop: 'T_contract_start_time', label: '劳动合同开始时间' },
+  { prop: 'T_contract_end_time', label: '劳动合同结束时间' },
+  { prop: 'T_remark', label: '备注' },
   { prop: 'operation', label: '操作', width: 200, fixed: 'right' }
 ]
-const openDrawer = () => {
-  drawerRef.value.closeDrawer()
-  console.log(drawerRef.value)
-}
 
-type Fn = () => void
-const callbackDrawer = (done: Fn) => {
-  console.log('触发回调')
-  done()
+// const callbackDrawerFrom = () => {
+//   drawerFromRef.value.callbackDrawer()
+// }
+const openDrawerFrom = () => {
+  drawerFromRef.value.openDrawer()
 }
 
-const AddUser = () => {}
-
-const Posts = []
-const getPosts = async () => {
-  const res = await User_Post_List()
-  console.log(res)
-}
-const Depts = []
-const getDept = async () => {
-  const res = await User_Dept_List()
-  console.log(res)
-}
-onMounted(() => {
-  getPosts()
-  getDept()
-})
 const initParam = {
   User_tokey: globalStore.GET_User_tokey,
   page: 1,
@@ -68,7 +52,7 @@ const initParam = {
             <el-input type="text" class="w-50 m-2" />
             <el-button type="primary">搜索</el-button>
           </el-col>
-          <el-col :span="6" :offset="6"><el-button type="primary" @click="openDrawer">添加</el-button></el-col>
+          <el-col :span="6" :offset="6"><el-button type="primary" @click="openDrawerFrom">添加</el-button></el-col>
         </el-row>
       </div>
     </template>
@@ -77,40 +61,7 @@ const initParam = {
       <el-button link type="danger" size="small" :icon="Delete">删除</el-button>
     </template>
   </TableBase>
-  <Drawer ref="drawerRef" :handleClose="callbackDrawer">
-    <template #header="{ params }">
-      <h4 :id="params.titleId" :class="params.titleClass">{{ action ? '添加' : '编辑' }} - 账户管理</h4>
-    </template>
-    <el-form :model="form" class="form">
-      <el-form-item label="用户名:" :label-width="formLabelWidth">
-        <el-input v-model="form.username" autocomplete="off" />
-      </el-form-item>
-      <el-form-item label="密码:" :label-width="formLabelWidth">
-        <el-input v-model="form.username" autocomplete="off" />
-      </el-form-item>
-      <el-form-item label="角色名:" :label-width="formLabelWidth">
-        <el-select v-model="form.password" placeholder="请选择角色">
-          <el-option label="Area1" value="shanghai" />
-          <el-option label="Area2" value="beijing" />
-        </el-select>
-      </el-form-item>
-      <el-form-item label="部门:" :label-width="formLabelWidth">
-        <el-select v-model="form.password" placeholder="请选择部门">
-          <el-option label="Area1" value="shanghai" />
-          <el-option label="Area2" value="beijing" />
-        </el-select>
-      </el-form-item>
-      <el-form-item label="岗位:" :label-width="formLabelWidth">
-        <el-select v-model="form.password" placeholder="请选择岗位">
-          <el-option label="Area1" value="shanghai" />
-          <el-option label="Area2" value="beijing" />
-        </el-select>
-      </el-form-item>
-      <el-form-item :label-width="formLabelWidth">
-        <el-button color="#626aef" @click="AddUser">添加</el-button>
-      </el-form-item>
-    </el-form>
-  </Drawer>
+  <DrawerFrom ref="drawerFromRef" :action="action" />
 </template>
 
 <style scoped lang="scss">

+ 182 - 0
src/views/account/users/components/DrawerFrom.vue

@@ -0,0 +1,182 @@
+<script setup lang="ts">
+import { ref, reactive, onMounted } from 'vue'
+import Drawer from '../../../../components/Drawer/index.vue'
+import { User_Power_List } from '@/api/role/index'
+import { User_Post_List, User_Add, User_Edit } from '@/api/user/index'
+import { GlobalStore } from '@/stores/index'
+const globalStore = GlobalStore()
+let userPowerList: any = []
+const getUserPowerList = async () => {
+  const res: any = await User_Power_List({ User_tokey: globalStore.GET_User_tokey, page: 1, page_z: 9999 })
+  userPowerList = res.Data.Data
+}
+let userPostList = ref<any>([])
+const changeDept = async (val: number) => {
+  const res = await User_Post_List({ T_dept: val })
+  userPostList.value = res.Data
+}
+const drawerRef = ref()
+const formLabelWidth = ref('90px')
+const form = reactive({
+  T_power: '',
+  T_name: '',
+  T_user: '',
+  T_pass: '',
+  T_dept: '',
+  T_post: '',
+  T_sex: '',
+  T_id_card: '',
+  T_nation: '',
+  T_school: '',
+  T_major: '',
+  T_education: '',
+  T_marry: '',
+  T_phone: '',
+  T_entry_time: '',
+  T_spouse_name: '',
+  T_entry_type: '',
+  T_contract_start_time: '',
+  T_contract_end_time: '',
+  T_remark: '',
+  T_positive_time: '',
+  T_spouse_phone: '',
+  T_expire: ''
+})
+type Fn = () => void
+const callbackDrawer = (done: Fn) => {
+  console.log('触发回调')
+  done()
+}
+const openDrawer = () => {
+  drawerRef.value.openDrawer()
+}
+const AddUser = () => {}
+
+onMounted(() => {
+  if (userPowerList.length <= 0) {
+    getUserPowerList()
+  }
+})
+
+interface PropsType {
+  action: boolean
+}
+defineProps<PropsType>()
+defineExpose({
+  openDrawer,
+  callbackDrawer
+})
+</script>
+<template>
+  <Drawer ref="drawerRef" :handleClose="callbackDrawer">
+    <template #header="{ params }">
+      <h4 :id="params.titleId" :class="params.titleClass">{{ action ? '添加' : '编辑' }} - 账户管理</h4>
+    </template>
+    <el-form :model="form" class="form">
+      <el-form-item label="角色权限:" :label-width="formLabelWidth">
+        <el-select v-model="form.T_power" placeholder="请选择角色">
+          <el-option v-for="item in userPowerList" :key="item.T_id" :label="item.T_name" :value="item.T_id" />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="名称:" :label-width="formLabelWidth">
+        <el-input v-model="form.T_name" autocomplete="off" />
+      </el-form-item>
+      <el-form-item label="账号:" :label-width="formLabelWidth">
+        <el-input v-model="form.T_user" autocomplete="off" />
+      </el-form-item>
+      <el-form-item label="密码:" :label-width="formLabelWidth">
+        <el-input v-model="form.T_pass" autocomplete="off" />
+      </el-form-item>
+      <el-form-item label="部门:" :label-width="formLabelWidth">
+        <el-select v-model="form.T_dept" placeholder="请选择部门" @change="changeDept">
+          <el-option v-for="item in globalStore.GET_Dept_List" :key="item.Id" :label="item.T_name" :value="item.Id" />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="岗位:" :label-width="formLabelWidth">
+        <el-select v-model="form.T_post" placeholder="请选择岗位">
+          <el-option v-for="item in userPostList" :key="item.Id" :label="item.T_name" :value="item.Id" />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="性别:" :label-width="formLabelWidth">
+        <el-radio-group v-model="form.T_sex" class="ml-4">
+          <el-radio label="1">男</el-radio>
+          <el-radio label="2">女</el-radio>
+        </el-radio-group>
+      </el-form-item>
+      <el-form-item label="身份证号:" :label-width="formLabelWidth">
+        <el-input v-model="form.T_id_card" autocomplete="off" />
+      </el-form-item>
+      <el-form-item label="民族:" :label-width="formLabelWidth">
+        <el-input v-model="form.T_nation" autocomplete="off" />
+      </el-form-item>
+      <el-form-item label="毕业院校:" :label-width="formLabelWidth">
+        <el-input v-model="form.T_school" autocomplete="off" />
+      </el-form-item>
+      <el-form-item label="专业:" :label-width="formLabelWidth">
+        <el-input v-model="form.T_major" autocomplete="off" />
+      </el-form-item>
+      <el-form-item label="学历:" :label-width="formLabelWidth">
+        <el-input v-model="form.T_education" autocomplete="off" />
+      </el-form-item>
+      <el-form-item label="联系电话:" :label-width="formLabelWidth">
+        <el-input v-model="form.T_phone" autocomplete="off" />
+      </el-form-item>
+      <el-form-item label="婚否:" :label-width="formLabelWidth">
+        <el-input v-model="form.T_marry" autocomplete="off" />
+      </el-form-item>
+      <el-form-item label="入职时间:" :label-width="formLabelWidth">
+        <el-input v-model="form.T_entry_time" autocomplete="off" />
+      </el-form-item>
+      <el-form-item label="转正时间:" :label-width="formLabelWidth">
+        <el-input v-model="form.T_positive_time" autocomplete="off" />
+      </el-form-item>
+      <el-form-item label="配偶姓名:" :label-width="formLabelWidth">
+        <el-input v-model="form.T_spouse_name" autocomplete="off" />
+      </el-form-item>
+      <el-form-item label="配偶联系电话:" label-width="110px">
+        <el-input v-model="form.T_spouse_phone" autocomplete="off" />
+      </el-form-item>
+      <el-form-item label="入职类型:" :label-width="formLabelWidth">
+        <el-input v-model="form.T_entry_type" autocomplete="off" />
+      </el-form-item>
+      <el-form-item label="劳动合同开始时间:" label-width="140px">
+        <el-input v-model="form.T_contract_start_time" autocomplete="off" />
+      </el-form-item>
+      <el-form-item label="劳动合同结束时间:" label-width="140px">
+        <el-input v-model="form.T_contract_end_time" autocomplete="off" />
+      </el-form-item>
+      <el-form-item label="是否到期:" :label-width="formLabelWidth">
+        <el-input v-model="form.T_expire" autocomplete="off" />
+      </el-form-item>
+
+      <el-form-item label="备注:" :label-width="formLabelWidth">
+        <el-input v-model="form.T_remark" autocomplete="off" />
+      </el-form-item>
+      <el-form-item :label-width="formLabelWidth">
+        <el-button color="#626aef" @click="AddUser">添加</el-button>
+      </el-form-item>
+      <!-- <el-form-item label="角色名:" :label-width="formLabelWidth">
+        <el-select v-model="form.password" placeholder="请选择角色">
+          <el-option label="Area1" value="shanghai" />
+          <el-option label="Area2" value="beijing" />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="部门:" :label-width="formLabelWidth">
+        <el-select v-model="form.password" placeholder="请选择部门">
+          <el-option label="Area1" value="shanghai" />
+          <el-option label="Area2" value="beijing" />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="岗位:" :label-width="formLabelWidth">
+        <el-select v-model="form.password" placeholder="请选择岗位">
+          <el-option label="Area1" value="shanghai" />
+          <el-option label="Area2" value="beijing" />
+        </el-select>
+      </el-form-item>
+      <el-form-item :label-width="formLabelWidth">
+        <el-button color="#626aef" @click="AddUser">添加</el-button>
+      </el-form-item> -->
+    </el-form>
+  </Drawer>
+</template>
+<style scoped></style>

+ 80 - 6
src/views/salary/Salary.vue

@@ -1,13 +1,87 @@
 <script setup lang="ts">
+import { ref, onMounted, reactive } from 'vue'
+import TableBase from '@/components/TableBase/index.vue'
+import { Salary_List, Salary_User_List } from '@/api/salary/index'
+import { User_List } from '@/api/user/index'
+import { ColumnProps } from '@/components/TableBase/interface/index'
+import { GlobalStore } from '@/stores/index'
+const globalStore = GlobalStore()
 
+const getSalary_List = async () => {
+  const res = await Salary_User_List({ page: 1, page_z: 10 })
+  console.log(res)
+}
+
+onMounted(() => {
+  getSalary_List()
+})
+
+// 搜索以及参数
+const columns: ColumnProps = []
+const searchHandle = () => {
+  console.log(searchs)
+}
+const searchs = reactive({
+  T_name: '',
+  T_dept: ''
+})
+const initParam = {
+  User_tokey: globalStore.GET_User_tokey,
+  T_name: '',
+  T_dept: ''
+}
 </script>
 
 <template>
-  <div class="role">
-    Salary manag
-  </div>
+  <el-row :gutter="20" class="h-100">
+    <el-col :span="8" class="padding-right-0">
+      <TableBase :columns="columns" :requestApi="User_List" :initParam="initParam">
+        <template #table-header>
+          <div class="input-suffix">
+            <el-row :gutter="24">
+              <el-col :span="10" class="d-flex padding-left-0 padding-right-0">
+                <span class="inline-flex">部门:</span>
+                <el-select v-model="searchs.T_dept" class="m-2" placeholder="请选择部门">
+                  <el-option
+                    v-for="item in globalStore.GET_Dept_List"
+                    :key="item.Id"
+                    :label="item.T_name"
+                    :value="item.Id"
+                  />
+                </el-select>
+              </el-col>
+              <el-col :span="14" class="d-flex padding-right-0">
+                <span class="inline-flex">姓名:</span>
+                <el-input v-model="searchs.T_name" type="text" class="w-50 m-2" />
+                <el-button type="primary" @click="searchHandle">搜索</el-button>
+              </el-col>
+            </el-row>
+          </div>
+        </template>
+      </TableBase></el-col
+    >
+    <el-col :span="16">
+      <el-card class="">
+        <div v-for="o in 4" :key="o" class="text item">{{ 'List item ' + o }}</div>
+      </el-card>
+    </el-col>
+  </el-row>
 </template>
 
-<style scoped>
-
-</style>
+<style scoped lang="scss">
+.input-suffix {
+  width: 100%;
+  .w-50 {
+    width: 12.5rem;
+  }
+  .d-flex {
+    display: flex;
+    justify-content: center;
+    align-items: center;
+  }
+  .inline-flex {
+    white-space: nowrap;
+    display: inline-flex;
+  }
+}
+</style>

+ 3 - 3
tsconfig.json

@@ -14,9 +14,9 @@
     "noEmit": true,
     "baseUrl": "./",
     "paths": {
-			"@": ["src"],
-			"@/*": ["src/*"]
-		}
+      "@": ["src"],
+      "@/*": ["./src/*"]
+    }
   },
   "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"],
   "references": [{ "path": "./tsconfig.node.json" }]