Explorar o código

feat: ✨ 完成项目以及表单,完成风格主题

@sun-chaoqun %!s(int64=2) %!d(string=hai) anos
pai
achega
8110e9d67e

+ 1 - 0
components.d.ts

@@ -52,6 +52,7 @@ declare module '@vue/runtime-core' {
     ElScrollbar: typeof import('element-plus/es')['ElScrollbar']
     ElSelect: typeof import('element-plus/es')['ElSelect']
     ElSubMenu: typeof import('element-plus/es')['ElSubMenu']
+    ElSwitch: typeof import('element-plus/es')['ElSwitch']
     ElTable: typeof import('element-plus/es')['ElTable']
     ElTableColumn: typeof import('element-plus/es')['ElTableColumn']
     ElTabPane: typeof import('element-plus/es')['ElTabPane']

+ 9 - 7
src/api/project/index.ts

@@ -3,16 +3,18 @@ import $http from '../index'
 // 项目列表(财务)
 export const Project_Finance_List = (params: any) => $http.post('/testapi/project/Project/Finance_List', params)
 // 项目列表
-export const User_Power_List = (params: any) => $http.post('/testapi/project/Project/List', params)
+export const Project_List = (params: any) => $http.post('/testapi/project/Project/List', params)
 // 审批
-export const User_Power_Approval = (params: any) => $http.post('/testapi/project/Project/Approval', params)
+export const Project_Approval = (params: any) => $http.post('/testapi/project/Project/Approval', params)
 // 我的项目
-export const User_Power_User_list = (params: any) => $http.post('/testapi/project/Project/User_list', params)
+export const Project_Project_User_list = (params: any) => $http.post('/testapi/project/Project/User_list', params)
 // 详情
-export const User_Power_Get = (params: any) => $http.post('/testapi/project/Project/Get', params)
+export const Project_Get = (params: any) => $http.post('/testapi/project/Project/Get', params)
 // 立项申请
-export const User_Power_Add = (params: any) => $http.post('/testapi/project/Project/Add', params)
+export const Project_Add = (params: any) => $http.post('/testapi/project/Project/Add', params)
 // 编辑
-export const User_Power_Edit = (params: any) => $http.post('/testapi/project/Project/Edit', params)
+export const Project_Edit = (params: any) => $http.post('/testapi/project/Project/Edit', params)
 // 删除
-export const User_Power_Del = (params: any) => $http.post('/testapi/project/Project/Del', params)
+export const Project_Del = (params: any) => $http.post('/testapi/project/Project/Del', params)
+// 左侧用户列表
+export const Project_User_List = (params: any) => $http.post('/testapi/project/User/List', params)

+ 2 - 2
src/components/TableBase/index.scss

@@ -3,7 +3,7 @@
   // height: 5rem;
   margin-bottom: 0.75rem;
   border: 1px solid var(--el-border-color-light);
-  border-radius: 4px;
+  border-radius: 8px;
   padding: 20px;
 
   display: flex;
@@ -24,7 +24,7 @@
   overflow-x: hidden;
   background-color: var(--el-fill-color-blank);
   border: 1px solid var(--el-border-color-light);
-  border-radius: 4px;
+  border-radius: 8px;
   // box-shadow: 0 0 12px rgb(0 0 0 / 5%);
 
   display: flex;

+ 47 - 0
src/hooks/useTablePublic.ts

@@ -0,0 +1,47 @@
+export interface LeaveUserInfoIn {
+  T_user_name: string
+  T_dept: string
+  T_post: string
+  T_type_name: string
+  T_start_time: string
+  T_end_time: string
+  T_text: string
+  Id: string
+  T_duration: number
+}
+
+export interface OvertimeUserInfoIn {
+  T_uid: string
+  T_user_name: string
+  T_dept: string
+  T_post: string
+  T_type_name: string
+  T_start_time: string
+  T_end_time: string
+  T_text: string
+  Id: string
+  T_duration: string
+  T_prove_img: string
+}
+
+export function useTablePublic() {
+  //判断是否相等,相同时改变背景颜色
+  const tableRowClassName = (T_uuid: string, T_uuid2: string): any => {
+    let user: any = undefined
+    if (T_uuid === T_uuid2) {
+      user = T_uuid2
+    }
+    if (user !== undefined) {
+      let rowBackground = {
+        background: '#e3eefd',
+        color: '#0d7bff'
+      }
+      return rowBackground
+    } else {
+      return ''
+    }
+  }
+  return {
+    tableRowClassName
+  }
+}

+ 17 - 1
src/layouts/Header/index.vue

@@ -1,11 +1,13 @@
 <script setup lang="ts">
+import Notice from './Notice.vue'
 import { ref, computed } from 'vue'
 import { useRouter } from 'vue-router'
 import { GlobalStore } from '@/stores/index'
 import Breadcrumb from './Breadcrumb.vue'
-import Notice from './Notice.vue'
+import { Sunny, Moon } from '@element-plus/icons-vue'
 import { Expand, Fold, List, SwitchButton, UserFilled } from '@element-plus/icons-vue'
 import 'element-plus/theme-chalk/src/dropdown.scss'
+import { toggleDark, isDark } from '@/composables/dark'
 
 const noticeRef = ref<InstanceType<typeof Notice> | null>(null)
 const globalStore = GlobalStore()
@@ -89,6 +91,17 @@ const computedNotice = computed(() => {
         </template>
       </el-dropdown>
       <span>{{ time }}</span>
+
+      <el-popover placement="bottom" :width="200" trigger="hover">
+        <div style="display: flex; justify-content: center; align-items: center">
+          <el-icon v-if="isDark" color="#e9780e" :size="20"><Sunny /></el-icon>
+          <el-icon v-else color="#a80000" :size="20"><Moon /></el-icon>
+          <span style="padding: 0 10px">正在切换主题</span>
+        </div>
+        <template #reference>
+          <el-button class="toggle" :icon="isDark ? Moon : Sunny" circle @click="toggleDark()" />
+        </template>
+      </el-popover>
     </div>
   </div>
 </template>
@@ -109,6 +122,9 @@ const computedNotice = computed(() => {
     .mr-2 {
       margin-right: 8px;
     }
+    .toggle {
+      margin: 0 20px 0 10px;
+    }
   }
   .notice {
     cursor: pointer;

+ 67 - 11
src/styles/element/dark.scss

@@ -1,11 +1,67 @@
-// only scss variables
-
-$--colors: (
-  'primary': (
-    'base': #589ef8
-  )
-);
-
-@forward 'element-plus/theme-chalk/src/dark/var.scss' with (
-  $colors: $--colors
-);
+html.dark {
+  /* 自定义深色背景颜色 */
+  --el-bg-color: #262727;
+  --font-color: #fff;
+  --el-menu-text-color: #fff;
+  --el-menu-hover-text-color: #fff;
+  --el-menu-bg-color: var(--el-bg-color);
+  --el-menu-hover-bg-color: var(--el-bg-color);
+  --el-menu-active-color: #ffd04b;
+  --el-menu-level: 0;
+  .el-header {
+    background-color: var(--el-bg-color);
+  }
+  .home-container .el-header {
+    box-shadow: 0px 0px 5px rgba(255, 255, 255, 1);
+  }
+  .el-main {
+    color: var(--font-color);
+    background-color: var(--el-bg-color);
+    .table-header {
+      background-color: var(--el-bg-color);
+    }
+    .el-table__body tr.el-table__row {
+      background-color: var(--el-bg-color) !important;
+    }
+    .el-table__body tr.el-table__row:hover {
+      // box-shadow: 0 0 6px #fff;
+      // background-color: var(--el-bg-color) !important;
+      box-shadow: 0px 0px 10px rgba(255, 255, 255, 1) inset, 0px 0px 5px rgba(200, 200, 200, 1);
+    }
+    .el-table .el-table__row {
+      color: var(--font-color);
+      font-weight: 600;
+    }
+    .records {
+      .info-content,
+      .content {
+        color: var(--font-color) !important;
+      }
+      .content {
+        background-color: var(--el-bg-color);
+      }
+    }
+    .RecordsFinance .RecordsFinance-container .info-content,
+    .Leave .Leave-container .info-content,
+    .salary .info-content {
+      color: var(--font-color) !important;
+    }
+  }
+  .home-container .el-aside {
+    background-color: var(--el-bg-color);
+    .menu .el-menu {
+      color: var(--font-color);
+      background-color: var(--el-bg-color);
+      .el-sub-menu .el-sub-menu__title {
+        color: var(--font-color) !important;
+        background-color: var(--el-bg-color) !important;
+      }
+      .el-menu-item:hover {
+        background-color: rgba(14, 17, 31, 0.5);
+      }
+    }
+  }
+  .el-button {
+    background-color: var(--el-bg-color);
+  }
+}

+ 0 - 42
src/styles/element/index.scss

@@ -1,42 +0,0 @@
-$--colors: (
-  'primary': (
-    'base': green
-  ),
-  'success': (
-    'base': #21ba45
-  ),
-  'warning': (
-    'base': #f2711c
-  ),
-  'danger': (
-    'base': #db2828
-  ),
-  'error': (
-    'base': #db2828
-  ),
-  'info': (
-    'base': #42b8dd
-  )
-);
-
-// we can add this to custom namespace, default is 'el'
-@forward 'element-plus/theme-chalk/src/mixins/config.scss' with (
-  $namespace: 'ep'
-);
-
-// You should use them in scss, because we calculate it by sass.
-// comment next lines to use default color
-@forward 'element-plus/theme-chalk/src/common/var.scss' with (
-  // do not use same name, it will override.
-  $colors: $--colors,
-  $button-padding-horizontal: ('default': 50px)
-);
-
-// if you want to import all
-// @use "element-plus/theme-chalk/src/index.scss" as *;
-
-// You can comment it to hide debug info.
-// @debug $--colors;
-
-// custom dark variables
-@use './dark.scss';

+ 2 - 8
src/styles/index.scss

@@ -1,12 +1,6 @@
-// @use 'element-plus/theme-chalk/src/index.scss' as *;
+@use 'element-plus/theme-chalk/src/dark/css-vars.scss' as *;
 
-// @forward 'element-plus/theme-chalk/src/common/var.scss' with (
-//   $colors: (
-//     'primary': (
-//       'base': green
-//     )
-//   )
-// );
+@import './element/dark.scss';
 
 $--color-primary: #0078d7;
 $--color-success: #107c10;

+ 8 - 0
src/styles/var.scss

@@ -3,3 +3,11 @@
   flex-direction: column;
   height: 100%;
 }
+
+:deep(.el-table__body tr.el-table__row) {
+  transition: all 0.5s ease-in-out;
+}
+:deep(.el-table__body tr.el-table__row:hover) {
+  box-shadow: 0 0 6px #dfdfdf;
+  transform: translateX(-2px);
+}

+ 10 - 21
src/views/account/roles/Roles.vue

@@ -31,15 +31,13 @@ const isNew = ref(true)
 let currentVal: any = {}
 const SysList = ref<InSys[]>([])
 const globalStore = GlobalStore()
+const User_tokey = globalStore.GET_User_tokey
 const formLabelWidth = ref('100px')
 const ruleFormRef = ref<FormInstance>()
 const dialog = ref<InstanceType<typeof Dialog> | null>(null)
 const drawerRef = ref<InstanceType<typeof Drawer> | null>(null)
 const TableRef = ref<InstanceType<typeof TableBase> | null>(null)
-const initParam = {
-  User_tokey: globalStore.GET_User_tokey,
-  T_name: ''
-}
+const initParam = { User_tokey, T_name: '' }
 
 const DialogOpen = async (row: any) => {
   currentVal = row
@@ -55,7 +53,7 @@ const columns: ColumnProps[] = [
 ]
 
 const getSysList = async () => {
-  const { Data } = await User_Sys_List({ User_tokey: globalStore.GET_User_tokey })
+  const { Data } = await User_Sys_List({ User_tokey })
   SysList.value = Data as InSys[]
   const promises = []
   for (let item of SysList.value) {
@@ -78,11 +76,10 @@ const getSysList = async () => {
     })
     menuList.value = menuListTemporary
     setCheckedTreeKeys(permissionArr.value)
-    console.log(permissionArr.value)
   })
 }
 const getMenuList = async (code: string) => {
-  const res: any = await User_Power_Get({ User_tokey: globalStore.GET_User_tokey, T_code: code, T_id: currentVal.T_id })
+  const res: any = await User_Power_Get({ User_tokey, T_code: code, T_id: currentVal.T_id })
   return {
     code,
     ...res
@@ -113,7 +110,6 @@ const getCurrentFlatMenu = (children: any[], arr: number[], permission: string)
 const setCheckedTreeKeys = (arr: string[]) => treeRef.value?.setCheckedKeys(arr, true)
 
 // 添加角色
-type Fn = () => void
 const form = reactive({
   name: '',
   id: ''
@@ -123,7 +119,7 @@ const rules = reactive<FormRules>({
   name: [{ required: true, message: '请输入角色名称', trigger: 'blur' }]
 })
 
-const callbackDrawer = (done: Fn) => {
+const callbackDrawer = (done: () => void) => {
   resetForm(ruleFormRef.value)
   done()
 }
@@ -147,9 +143,9 @@ const AddUserName = (formEl: FormInstance | undefined) => {
     if (valid) {
       let res: any = {}
       if (isNew.value) {
-        res = await User_Power_Add({ User_tokey: globalStore.GET_User_tokey, T_name: form.name })
+        res = await User_Power_Add({ 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 })
+        res = await User_Power_Edit({ User_tokey, T_name: form.name, T_id: form.id })
       }
       if (res.Code === 200) {
         ElNotification.success({
@@ -178,7 +174,7 @@ const UserDelete = (row: any) => {
     type: 'warning'
   })
     .then(async () => {
-      const res: any = await User_Power_Del({ User_tokey: globalStore.GET_User_tokey, T_id: row.T_id })
+      const res: any = await User_Power_Del({ User_tokey, T_id: row.T_id })
       if (res.Code === 200) {
         ElMessage.success('删除成功!')
         nextTick(() => {
@@ -229,15 +225,10 @@ const getMontageRole = (children: any[]) => {
  */
 const append = async (data: any) => {
   const currentMenu = menuMap.get(data.T_permission)
-  console.log(menuMap)
-
   const { code, children } = currentMenu
-
   let T_menu = getMontageRole(children)
-  console.log(children)
-
   const params = {
-    User_tokey: globalStore.GET_User_tokey,
+    User_tokey,
     T_id: currentVal.T_id,
     T_code: code,
     T_menu
@@ -252,7 +243,6 @@ let fatherDataCopy: any = {}
 const getMenuChildren = (menuchildren: any, T_permission: string) => {
   let fatherData = getFatherData(T_permission)
   const { children } = fatherData
-  console.log(menuchildren, fatherData)
 
   if (!menuchildren?.length) {
     const index = children.findIndex((child: any) => child.T_permission === menuchildren.T_permission)
@@ -283,7 +273,6 @@ const checkChange = (data: any, check: boolean) => {
   if (check && fatherDataCopy) {
     const { children } = fatherDataCopy
     if (!data.Children) {
-      console.log('1', data)
       const index = children.findIndex((child: any) => data.T_permission === child.T_permission)
       if (index === -1) children.push({ ...data })
     } else {
@@ -341,7 +330,7 @@ const dialogCloseCallback = () => {
           <el-row :gutter="20" style="margin-bottom: 0">
             <el-col :span="12">
               <span class="inline-flex items-center">角色名:</span>
-              <el-input v-model="search" type="text" class="w-50 m-2" />
+              <el-input v-model="search" type="text" class="w-50 m-2" placeholder="输入角色名称查询" />
               <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>

+ 3 - 5
src/views/account/users/Users.vue

@@ -90,7 +90,7 @@ const SearchInfo = () => {
           <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" v-model="search" />
+              <el-input type="text" class="w-50 m-2" v-model="search" placeholder="输入账户名称查询" />
               <el-button type="primary" @click="SearchInfo">搜索</el-button>
             </el-col>
             <el-col :span="6" :offset="6"><el-button type="primary" @click="openDrawerFrom">添加</el-button></el-col>
@@ -126,16 +126,14 @@ const SearchInfo = () => {
 
 <style scoped lang="scss">
 @import '@/styles/var.scss';
+
 .users {
   @include f-direction;
   .input-suffix {
     width: 100%;
     .w-50 {
-      width: 12.5rem;
+      width: 33.33%;
     }
   }
-  .form {
-    margin-top: 3rem;
-  }
 }
 </style>

+ 2 - 7
src/views/account/users/components/DrawerFrom.vue

@@ -9,11 +9,6 @@ import { ref, reactive, onMounted, nextTick } from 'vue'
 import type { FormInstance, FormRules } from 'element-plus'
 import { User_Post_List, User_Add, User_Edit } from '@/api/user/index'
 
-type Fn = () => void
-interface PropsType {
-  action: boolean
-}
-
 const validate_checkPass = (rule: any, value: any, callback: any) => {
   if (checkPass.value === '') {
     callback(new Error('请再输入一次密码'))
@@ -85,7 +80,7 @@ const resetForm = (formEl: FormInstance | undefined) => {
   checkPass.value = ''
 }
 
-const callbackDrawer = (done: Fn) => {
+const callbackDrawer = (done: () => void) => {
   done()
   nextTick(() => {
     resetForm(formRef.value)
@@ -141,7 +136,7 @@ onMounted(() => {
 })
 
 const emit = defineEmits<{ (event: 'onTableList'): void; (event: 'onaction', val: boolean): void }>()
-const props = defineProps<PropsType>()
+const props = defineProps<{ action: boolean }>()
 defineExpose({
   openDrawer,
   callbackDrawer,

+ 1 - 1
src/views/home/Home.vue

@@ -84,7 +84,7 @@ onUnmounted(() => {
       <el-tabs v-model="activeName" @tab-click="handleClick" id="home">
         <transition-group
           appear
-          leave-active-class="animate__animated animate__fadeOutLeft"
+          leave-active-class="animate__animated animate__fadeOutRight"
           enter-active-class="animate__animated animate__fadeInLeft"
         >
           <el-tab-pane label="未读" name="first" key="first">

+ 20 - 27
src/views/project/MyProject.vue

@@ -1,24 +1,15 @@
 <script setup lang="ts">
 import { ElMessage, ElMessageBox } from 'element-plus'
 import { GlobalStore } from '@/stores/index'
-import { ref, reactive, nextTick, computed } from 'vue'
-import { getFormatDuration } from '@/utils/common'
-import { UserFilled } from '@element-plus/icons-vue'
+import { ref, reactive, nextTick } from 'vue'
 import TableBase from '@/components/TableBase/index.vue'
 import { ColumnProps } from '@/components/TableBase/interface/index'
-import { User_List } from '@/api/user/index'
 import Drawer from '@/components/Drawer/index.vue'
-import {
-  User_Power_User_list,
-  User_Power_Add,
-  User_Power_Edit,
-  User_Power_Del,
-  User_Power_Get
-} from '@/api/project/index'
 import type { FormInstance, FormRules } from 'element-plus'
 import ProjectDetail from './ProjectDetail.vue'
 import receiveUser from '@/views/storehouse/outStock/receiveUser.vue'
 import { Edit, Delete, View } from '@element-plus/icons-vue'
+import { Project_Add, Project_Edit, Project_Del, Project_Get, Project_Project_User_list } from '@/api/project/index'
 
 const isNew = ref(true)
 const TableRef = ref()
@@ -36,10 +27,10 @@ const columns: ColumnProps[] = [
   { prop: 'Id', label: 'ID' },
   { prop: 'T_name', label: '项目名称' },
   { prop: 'T_user_name', label: '项目负责人' },
-  { prop: 'T_start_date', label: '立项日期' },
+  { prop: 'T_set_up_date', label: '立项日期' },
   { prop: 'T_end_date', label: '结束时间' },
-  { prop: 'T_planning_cycle', label: '计划完成周期(工作日)' },
-  { prop: 'T_name', label: '绩效总金额' },
+  { prop: 'T_planning_cycle', label: '计划完成周期(工作日)', width: 125 },
+  { prop: 'T_Perf', label: '绩效总金额' },
   { prop: 'T_State', label: '状态' },
   { prop: 'operation', label: '操作', width: 200, fixed: 'right' }
 ]
@@ -67,7 +58,7 @@ const openProjectDrawer = (type: string, row?: any) => {
       form.value = { ...row }
       form.value.T_approver = row.T_approver_name
       form.value.T_uuid = row.T_approver
-      const res: any = await User_Power_Get({ T_id: row.Id })
+      const res: any = await Project_Get({ T_id: row.Id })
       if (res.Code === 200) {
         projectDetailRef.value?.setDetailData(res.Data.T_Detail)
       }
@@ -116,9 +107,9 @@ const addProject = (formEl: FormInstance | undefined) => {
         T_approver: form.value.T_uuid
       }
       if (isNew.value) {
-        res = await User_Power_Add(params)
+        res = await Project_Add(params)
       } else {
-        res = await User_Power_Edit({ ...params, T_id: form.value.Id })
+        res = await Project_Edit({ ...params, T_id: form.value.Id })
       }
 
       if (res.Code === 200) {
@@ -141,7 +132,7 @@ const DeleteProject = (Id: number) => {
     type: 'warning'
   })
     .then(async () => {
-      const res: any = await User_Power_Del({ User_tokey, T_id: Id })
+      const res: any = await Project_Del({ User_tokey, T_id: Id })
       if (res.Code === 200) {
         ElMessage.success('删除成功!')
         nextTick(() => {
@@ -156,10 +147,11 @@ const DeleteProject = (Id: number) => {
 </script>
 <template>
   <div class="my-project">
-    <TableBase ref="TableRef" :columns="columns" :requestApi="User_Power_User_list" :initParam="initParam">
+    <TableBase ref="TableRef" :columns="columns" :requestApi="Project_Project_User_list" :initParam="initParam">
       <template #table-header>
         <el-row :gutter="20" class="w-100">
-          <el-col :span="4" :offset="20"
+          <el-col :span="4"><h3 class="title">我的项目</h3></el-col>
+          <el-col :span="4" :offset="16"
             ><el-button type="primary" @click="openProjectDrawer('new')">立项申请</el-button></el-col
           >
         </el-row>
@@ -182,6 +174,7 @@ const DeleteProject = (Id: number) => {
         <el-form-item label="项目名称:" :label-width="formLabelWidth" prop="T_name">
           <el-input
             v-model="form.T_name"
+            class="w-50"
             :disabled="disabled"
             type="text"
             autocomplete="off"
@@ -204,6 +197,7 @@ const DeleteProject = (Id: number) => {
           <div style="display: flex; white-space: nowrap; flex: 1">
             <el-input
               v-model="form.T_planning_cycle"
+              style="flex: 0 0 33.33%"
               :disabled="disabled"
               type="text"
               autocomplete="off"
@@ -245,13 +239,6 @@ const DeleteProject = (Id: number) => {
 
 <style scoped lang="scss">
 @import '@/styles/var.scss';
-:deep(.el-table--enable-row-hover .el-table__body tr) {
-  transition: all 0.5s ease-in-out;
-}
-:deep(.el-table--enable-row-hover .el-table__body tr:hover) {
-  box-shadow: 0 0 6px #dfdfdf;
-  transform: translateX(-2px);
-}
 .my-project {
   height: 100%;
   display: flex;
@@ -263,8 +250,14 @@ const DeleteProject = (Id: number) => {
     margin: 0;
     border-radius: 8px;
   }
+  :deep(.el-table .cell) {
+    white-space: normal !important;
+  }
   .btn {
     padding: 0 25px;
   }
+  .w-50 {
+    flex: 0 0 50%;
+  }
 }
 </style>

+ 377 - 3
src/views/project/Project.vue

@@ -1,6 +1,380 @@
-<script setup lang="ts"></script>
+<script setup lang="ts">
+import { ElMessage } from 'element-plus'
+import { GlobalStore } from '@/stores/index'
+import { ref, reactive, nextTick } from 'vue'
+import { UserFilled } from '@element-plus/icons-vue'
+import TableBase from '@/components/TableBase/index.vue'
+import { ColumnProps } from '@/components/TableBase/interface/index'
+import { Project_List, Project_Get, Project_Edit, Project_User_List } from '@/api/project/index'
+import { Edit, View } from '@element-plus/icons-vue'
+import Drawer from '@/components/Drawer/index.vue'
+import ProjectDetail from './ProjectDetail.vue'
+import type { FormInstance, FormRules } from 'element-plus'
+import { useTablePublic } from '@/hooks/useTablePublic'
+
+interface UserInfoIn {
+  T_name: string
+  T_type_name: string
+  T_text: string
+  T_uuid: string
+  T_dept_name: string
+  T_post_name: string
+}
+const userInfo = ref<UserInfoIn>({
+  T_name: '',
+  T_type_name: '',
+  T_text: '',
+  T_uuid: '',
+  T_dept_name: '',
+  T_post_name: ''
+})
+const isNew = ref(true)
+const disabled = ref(false)
+const TableRef = ref()
+const formLabelWidth = ref('120px')
+const globalStore = GlobalStore()
+const User_tokey = globalStore.GET_User_tokey
+const ruleFormRef = ref<FormInstance>()
+const drawerRef = ref<InstanceType<typeof Drawer> | null>(null)
+const projectDetailRef = ref<InstanceType<typeof ProjectDetail> | null>(null)
+const { tableRowClassName } = useTablePublic()
+const tableRowClassNameHandle = (data: any): any => tableRowClassName(data.row.T_uuid, userInfo.value.T_uuid)
+
+const columns: ColumnProps[] = [{ prop: 'T_name', label: '姓名' }]
+const columnsProject: ColumnProps[] = [
+  { prop: 'Id', label: 'ID' },
+  { prop: 'T_name', label: '项目名称' },
+  { prop: 'T_user_name', label: '项目负责人' },
+  { prop: 'T_set_up_date', label: '立项日期' },
+  { prop: 'T_end_date', label: '结束时间' },
+  { prop: 'T_planning_cycle', label: '计划完成周期(工作日)', width: 125 },
+  { prop: 'T_bonus', label: '绩效总金额' },
+  { prop: 'T_Perf', label: '状态' },
+  { prop: 'operation', label: '操作', width: 200, fixed: 'right' }
+]
+const initParam = { User_tokey: globalStore.GET_User_tokey }
+const initParamProject = reactive({ User_tokey: globalStore.GET_User_tokey, T_uuid: userInfo.value.T_uuid, page_z: 99 })
+
+const form = ref({
+  Id: '',
+  T_name: '',
+  T_end_date: '',
+  T_set_up_date: '',
+  T_description: '',
+  T_detail: '',
+  T_planning_cycle: '',
+  T_reality_cycle: '',
+  T_bonus: '',
+  T_Perf: '',
+  T_remark: '',
+  T_approver: '',
+  T_advance_day: '',
+  T_uuid: ''
+})
+const rules = reactive<FormRules>({
+  T_name: [{ required: true, message: '请输入项目名称', trigger: 'blur' }]
+})
+
+const openProjectDrawer = (type: string, row?: any) => {
+  isNew.value = type === 'view' ? true : false
+  nextTick(async () => {
+    if (type === 'view') disabled.value = true
+    form.value = { ...row }
+    form.value.T_approver = row.T_approver_name
+    form.value.T_uuid = row.T_approver
+    const res: any = await Project_Get({ T_id: row.Id })
+    if (res.Code === 200) {
+      projectDetailRef.value?.setDetailData(res.Data.T_Detail)
+    }
+  })
+  drawerRef.value?.openDrawer()
+}
+
+const getSalaryParams = (row: any) => {
+  userInfo.value.T_uuid = ''
+  setTimeout(() => {
+    userInfo.value = { ...row }
+    initParamProject.T_uuid = userInfo.value.T_uuid
+  }, 100)
+}
+
+const callbackDrawer = (done: () => void) => {
+  resetForm(ruleFormRef.value)
+  projectDetailRef.value?.clearDetail()
+  isNew.value = true
+  disabled.value = false
+  done()
+}
+
+const resetForm = (formEl: FormInstance | undefined) => {
+  if (!formEl) return
+  formEl.resetFields()
+}
+const addProject = (formEl: FormInstance | undefined) => {
+  if (!formEl) return
+  formEl.validate(async valid => {
+    if (valid) {
+      let detail = ''
+      projectDetailRef.value?.getDetailInfo().forEach((item: any) => {
+        detail += `${item.T_function},${item.T_planned_time},${item.T_finish}|`
+      })
+      const params = {
+        User_tokey,
+        ...form.value,
+        T_detail: detail,
+        T_approver: form.value.T_uuid
+      }
+      console.log(params)
+
+      const res: any = await Project_Edit({ ...params, T_id: form.value.Id })
+
+      if (res.Code === 200) {
+        ElMessage.success('项目修改成功!')
+        nextTick(() => {
+          isNew.value = true
+          TableRef.value?.getTableList()
+          drawerRef.value?.closeDrawer()
+          resetForm(ruleFormRef.value)
+        })
+      }
+    } else return false
+  })
+}
+</script>
 <template>
-  <div></div>
+  <div class="project">
+    <div style="width: 290px" class="project-table">
+      <TableBase
+        ref="TableRef"
+        :columns="columns"
+        :requestApi="Project_User_List"
+        :initParam="initParam"
+        layout="prev, pager, next"
+        :rowClick="getSalaryParams"
+        :tableRowClassName="tableRowClassNameHandle"
+      >
+        <template #table-header>
+          <h3 class="title">员工列表</h3>
+        </template>
+      </TableBase>
+    </div>
+    <transition
+      leave-active-class="animate__animated animate__fadeOutRight"
+      enter-active-class="animate__animated animate__fadeInLeft"
+    >
+      <div class="project-container" v-if="userInfo.T_uuid">
+        <el-card class="box-card">
+          <h3 class="text title m-b-5">员工基本信息</h3>
+          <div class="info-content">
+            <el-avatar shape="square" size="large" :icon="UserFilled" />
+            <div class="info-name">
+              <h4>名字:{{ userInfo.T_name }}</h4>
+              <h4>部门: {{ userInfo.T_dept_name }}</h4>
+              <h4>岗位: {{ userInfo.T_post_name }}</h4>
+            </div>
+          </div>
+        </el-card>
+        <TableBase
+          :columns="columnsProject"
+          :requestApi="Project_List"
+          :initParam="initParamProject"
+          :displayHeader="true"
+          :pagination="false"
+        >
+          <template #right="{ row }">
+            <el-button link type="success" size="small" :icon="View" @click="openProjectDrawer('view', row)"
+              >详情</el-button
+            >
+            <el-button link type="primary" size="small" :icon="Edit" @click="openProjectDrawer('edit', row)"
+              >编辑</el-button
+            >
+          </template>
+        </TableBase>
+      </div>
+    </transition>
+    <Drawer ref="drawerRef" :handleClose="callbackDrawer" size="50%">
+      <template #header="{ params }">
+        <h4 :id="params.titleId" :class="params.titleClass">项目 - {{ isNew ? '详情' : '编辑' }}</h4>
+      </template>
+      <el-form ref="ruleFormRef" :model="form" :rules="rules">
+        <el-form-item label="项目名称:" :label-width="formLabelWidth" prop="T_name">
+          <el-input
+            v-model="form.T_name"
+            class="w-50"
+            :disabled="disabled"
+            type="text"
+            autocomplete="off"
+            placeholder="请输入项目名称"
+          />
+        </el-form-item>
+        <el-form-item label="项目结束日期:" :label-width="formLabelWidth" prop="T_end_date">
+          <el-date-picker
+            style="flex: 0 0 50%"
+            class="my-date-picker"
+            v-model="form.T_end_date"
+            :disabled="disabled"
+            type="date"
+            placeholder="项目结束日期"
+            format="YYYY-MM-DD"
+            value-format="YYYY-MM-DD"
+          />
+        </el-form-item>
+        <el-form-item label="项目立项日期:" :label-width="formLabelWidth" prop="T_set_up_date">
+          <el-date-picker
+            style="flex: 0 0 50%"
+            class="my-date-picker"
+            v-model="form.T_set_up_date"
+            :disabled="disabled"
+            type="date"
+            placeholder="项目立项日期"
+            format="YYYY-MM-DD"
+            value-format="YYYY-MM-DD"
+          />
+        </el-form-item>
+        <el-form-item label="项目简介:" :label-width="formLabelWidth" prop="T_description">
+          <el-input
+            v-model="form.T_description"
+            :disabled="disabled"
+            :autosize="{ minRows: 6, maxRows: 8 }"
+            type="textarea"
+            placeholder="请输入项目简介"
+          />
+        </el-form-item>
+        <el-form-item label="项目明细:" :label-width="formLabelWidth" prop="T_detail">
+          <ProjectDetail ref="projectDetailRef" :disabled="disabled" :isShow="false"></ProjectDetail>
+        </el-form-item>
+        <el-form-item label="计划完成周期:" :label-width="formLabelWidth" prop="T_planning_cycle">
+          <div style="display: flex; white-space: nowrap; flex: 1">
+            <el-input
+              v-model="form.T_planning_cycle"
+              style="flex: 0 0 33.33%"
+              :disabled="true"
+              type="text"
+              autocomplete="off"
+              placeholder="请输入计划完成周期"
+            />
+            <span style="margin: 0 10px">工作日</span>
+            <span style="color: #bbb"
+              ><el-icon><QuestionFilled /></el-icon>备注;根据项目明细计划时间自动计算</span
+            >
+          </div>
+        </el-form-item>
+        <el-form-item label="实际完成周期:" :label-width="formLabelWidth" prop="T_reality_cycle">
+          <div style="display: flex; white-space: nowrap; flex: 1">
+            <el-input
+              v-model="form.T_reality_cycle"
+              class="w-50"
+              :disabled="disabled"
+              type="text"
+              autocomplete="off"
+              placeholder="请输入实际完成周期"
+            />
+            <span style="margin: 0 10px">工作日</span>
+          </div>
+        </el-form-item>
+        <el-form-item label="提前完成天数:" :label-width="formLabelWidth" prop="T_advance_day">
+          <div style="display: flex; white-space: nowrap; flex: 1">
+            <el-input
+              v-model="form.T_advance_day"
+              class="w-50"
+              :disabled="disabled"
+              type="text"
+              autocomplete="off"
+              placeholder="请输入提前完成天数"
+            />
+            <span style="margin: 0 10px">工作日</span>
+          </div>
+        </el-form-item>
+        <el-form-item label="奖励金额:" :label-width="formLabelWidth" prop="T_bonus">
+          <div style="display: flex; white-space: nowrap; flex: 1">
+            <el-input
+              v-model="form.T_bonus"
+              class="w-50"
+              :disabled="disabled"
+              type="text"
+              autocomplete="off"
+              placeholder="请输入奖励金额"
+            />
+            <span style="margin: 0 10px">元</span>
+          </div>
+        </el-form-item>
+        <el-form-item label="绩效总金额:" :label-width="formLabelWidth" prop="T_Perf">
+          <div style="display: flex; white-space: nowrap; flex: 1">
+            <el-input
+              v-model="form.T_Perf"
+              class="w-50"
+              :disabled="disabled"
+              type="text"
+              autocomplete="off"
+              placeholder="请输入绩效总金额"
+            />
+            <span style="margin: 0 10px">元</span>
+          </div>
+        </el-form-item>
+        <el-form-item :label-width="formLabelWidth" v-if="!disabled">
+          <el-button class="btn" color="#626aef" @click="addProject(ruleFormRef)">提交</el-button>
+        </el-form-item>
+      </el-form>
+    </Drawer>
+  </div>
 </template>
 
-<style scoped></style>
+<style scoped lang="scss">
+@import '@/styles/var.scss';
+.project {
+  width: 100%;
+  height: 100%;
+  display: flex;
+  overflow: hidden;
+  .project-table {
+    z-index: 1;
+    @include f-direction;
+  }
+  .project-container {
+    @include f-direction;
+    width: calc(100% - 290px);
+    z-index: 0;
+    margin-left: 12px;
+    .box-card {
+      border-radius: 8px;
+    }
+    :deep(.el-table tr) {
+      &:hover {
+        transition: all 5s ease-in-out;
+      }
+    }
+    :deep(.el-table .cell) {
+      white-space: normal !important;
+    }
+    .text {
+      text-align: left;
+    }
+    .info-content {
+      display: flex;
+      color: #606266;
+      .info-name {
+        flex: 1;
+        display: flex;
+        justify-content: space-around;
+        align-items: center;
+        padding-left: 0.75rem;
+      }
+    }
+  }
+  :deep(.table-header),
+  :deep(.card) {
+    margin: 0;
+    border-radius: 8px;
+  }
+  .title {
+    width: 100%;
+    text-align: center;
+    line-height: 1.7em;
+    font-size: 20px;
+    color: #707b84;
+  }
+  .w-50 {
+    flex: 0 0 50%;
+  }
+}
+</style>

+ 4 - 3
src/views/project/ProjectDetail.vue

@@ -89,8 +89,9 @@ defineExpose({
   setDetailData
 })
 
-const props = defineProps<{ disabled: boolean }>()
+const props = defineProps<{ disabled: boolean; isShow?: boolean }>()
 const disabled = computed(() => props.disabled)
+const isShow = ref(props.isShow)
 </script>
 
 <template>
@@ -106,7 +107,7 @@ const disabled = computed(() => props.disabled)
     <template v-for="item in columns" :key="item.prop">
       <el-table-column v-bind="item" v-if="item.type === 'index'"></el-table-column>
       <el-table-column v-bind="item" v-if="item.fixed !== 'right' && item.type !== 'index'"> </el-table-column>
-      <el-table-column v-bind="item" v-if="item.fixed === 'right'">
+      <el-table-column v-bind="item" v-if="item.fixed === 'right' && isShow">
         <template #default="{ row }">
           <el-button size="small" :disabled="disabled" type="primary" @click="openProductionDetailed('edit', row)"
             >编辑</el-button
@@ -117,7 +118,7 @@ const disabled = computed(() => props.disabled)
         </template>
       </el-table-column>
     </template>
-    <template #append>
+    <template #append v-if="isShow">
       <el-button type="primary" :disabled="disabled" @click="openProductionDetailed('new')">
         <el-icon><Plus /></el-icon><span style="margin-left: 6px">添加</span>
       </el-button>

+ 0 - 3
src/views/salary/SalaryMy.vue

@@ -68,16 +68,13 @@ const salarDateYearChange = (val: string) => {
   if (!val) return
   getMySalary()
 }
-
 const salarDateMonthChange = (val: string) => {
   if (!val) return
   getMySalary()
 }
-
 const searchSalary = () => {
   getMySalary()
 }
-
 getMySalary()
 </script>
 

+ 4 - 25
src/views/salary/salary/Salary.vue

@@ -7,6 +7,7 @@ import { GlobalStore } from '@/stores/index'
 import { Salary_Get } from '@/api/salary/index'
 import TableBase from '@/components/TableBase/index.vue'
 import { ColumnProps } from '@/components/TableBase/interface/index'
+import { useTablePublic } from '@/hooks/useTablePublic'
 
 let date = new Date()
 const year = date.getFullYear()
@@ -19,6 +20,8 @@ const salaryFromData = reactive({
 const globalStore = GlobalStore()
 const TableRef = ref<InstanceType<typeof TableBase> | null>(null)
 const salaryFromRef = ref<InstanceType<typeof SalaryFrom> | null>(null)
+const { tableRowClassName } = useTablePublic()
+const tableRowClassNameHandle = (data: any): any => tableRowClassName(data.row.T_uuid, salaryFromData.T_uuid)
 
 // 搜索以及参数
 const columns: ColumnProps[] = [
@@ -75,23 +78,6 @@ const userInfo = reactive({
   T_dept: '',
   T_post: ''
 })
-
-const tableRowClassName = (data: any): any => {
-  //判断是否相等,相同时改变背景颜色
-  let user: any = undefined
-  if (data.row.T_uuid === salaryFromData.T_uuid) {
-    user = data.row
-  }
-  if (user !== undefined) {
-    let rowBackground = {
-      background: '#f0f9eb',
-      color: '#67c23a'
-    }
-    return rowBackground
-  } else {
-    return ''
-  }
-}
 </script>
 
 <template>
@@ -104,7 +90,7 @@ const tableRowClassName = (data: any): any => {
         :initParam="initParam"
         layout="prev, pager, next"
         :rowClick="getSalaryParams"
-        :tableRowClassName="tableRowClassName"
+        :tableRowClassName="tableRowClassNameHandle"
       >
         <template #table-header>
           <el-row :gutter="24" class="input-suffix margin-left-0 margin-right-0">
@@ -175,11 +161,4 @@ const tableRowClassName = (data: any): any => {
 
 <style scoped lang="scss">
 @import './index.scss';
-:deep(.el-table--enable-row-hover .el-table__body tr) {
-  transition: all 0.5s ease-in-out;
-}
-:deep(.el-table--enable-row-hover .el-table__body tr:hover) {
-  box-shadow: 0 0 6px #dfdfdf;
-  transform: translateX(-2px);
-}
 </style>

+ 1 - 2
src/views/storehouse/IoTNetworkCard.vue

@@ -31,7 +31,6 @@ const columns: ColumnProps[] = [
 ]
 
 // 添加仓库名称
-type Fn = () => void
 const form = reactive({
   T_id: '',
   T_sn: '',
@@ -55,7 +54,7 @@ const rules = reactive<FormRules>({
   T_sn: [{ validator: validate_T_sn, trigger: 'blur' }]
 })
 
-const callbackDrawer = (done: Fn) => {
+const callbackDrawer = (done: () => void) => {
   resetForm(ruleFormRef.value)
   done()
 }

+ 2 - 4
src/views/storehouse/List.vue

@@ -24,7 +24,6 @@ const initParam = {
   User_tokey: globalStore.GET_User_tokey,
   T_name: ''
 }
-
 const columns: ColumnProps[] = [
   { type: 'index', label: '序号', width: 80 },
   { prop: 'T_name', label: '仓库名称' },
@@ -32,7 +31,6 @@ const columns: ColumnProps[] = [
 ]
 
 // 添加仓库名称
-type Fn = () => void
 const form = reactive({
   name: '',
   id: ''
@@ -42,7 +40,7 @@ const rules = reactive<FormRules>({
   name: [{ required: true, message: '请输入仓库名称', trigger: 'blur' }]
 })
 
-const callbackDrawer = (done: Fn) => {
+const callbackDrawer = (done: () => void) => {
   resetForm(ruleFormRef.value)
   done()
 }
@@ -166,7 +164,7 @@ const searchHandle = () => {
 .input-suffix {
   width: 100%;
   .w-50 {
-    width: 12.5rem;
+    width: 33.33%;
   }
 }
 </style>

+ 2 - 5
src/views/storehouse/ProductionList.vue

@@ -120,8 +120,7 @@ const ProductDelete = (row: any) => {
     })
 }
 
-type Fn = () => void
-const callbackDrawer = (done: Fn) => {
+const callbackDrawer = (done: () => void) => {
   resetForm(ruleFormRef.value)
   done()
 }
@@ -138,9 +137,7 @@ const initParam = reactive({
   T_class: ''
 })
 
-const searchHandle = () => {
-  TableRef.value?.searchTable()
-}
+const searchHandle = () => TableRef.value?.searchTable()
 
 // 获取产品分类
 const options = ref<any[]>([])

+ 47 - 60
src/views/workAttendance/Leave.vue

@@ -4,6 +4,7 @@ import { GlobalStore } from '@/stores/index'
 import { ref } from 'vue'
 import { getFormatDuration } from '@/utils/common'
 import { UserFilled } from '@element-plus/icons-vue'
+import { useTablePublic, LeaveUserInfoIn } from '@/hooks/useTablePublic'
 import TableBase from '@/components/TableBase/index.vue'
 import { ColumnProps } from '@/components/TableBase/interface/index'
 import { Leave_List, Leave_Approval } from '@/api/workAttendance/index'
@@ -11,19 +12,10 @@ import { Leave_List, Leave_Approval } from '@/api/workAttendance/index'
 const TableRef = ref()
 const globalStore = GlobalStore()
 const columns: ColumnProps[] = [{ prop: 'T_user_name', label: '姓名' }]
+const { tableRowClassName } = useTablePublic()
+const tableRowClassNameHandle = (data: any): any => tableRowClassName(data.row.Id, userInfo.value.Id)
 
-interface UserInfoIn {
-  T_user_name: string
-  T_dept: string
-  T_post: string
-  T_type_name: string
-  T_start_time: string
-  T_end_time: string
-  T_text: string
-  Id: string
-  T_duration: number
-}
-const userInfo = ref<UserInfoIn>({
+const userInfo = ref<LeaveUserInfoIn>({
   T_user_name: '',
   T_dept: '',
   T_post: '',
@@ -35,11 +27,12 @@ const userInfo = ref<UserInfoIn>({
   T_duration: 0
 })
 
-const initParam = {
-  User_tokey: globalStore.GET_User_tokey
-}
+const initParam = { User_tokey: globalStore.GET_User_tokey }
 const getSalaryParams = (row: any) => {
-  userInfo.value = { ...row }
+  userInfo.value.Id = ''
+  setTimeout(() => {
+    userInfo.value = { ...row }
+  }, 100)
 }
 
 const LeaveUser = async (T_State: number) => {
@@ -57,24 +50,7 @@ const LeaveUser = async (T_State: number) => {
       ElMessage.warning('审核不通过!')
     }
     TableRef.value.getTableList()
-    userInfo.value = {} as UserInfoIn
-  }
-}
-
-const tableRowClassName = (data: any): any => {
-  //判断是否相等,相同时改变背景颜色
-  let user: any = undefined
-  if (data.row.Id === userInfo.value.Id) {
-    user = data.row
-  }
-  if (user !== undefined) {
-    let rowBackground = {
-      background: '#f0f9eb',
-      color: '#67c23a'
-    }
-    return rowBackground
-  } else {
-    return ''
+    userInfo.value = {} as LeaveUserInfoIn
   }
 }
 </script>
@@ -89,7 +65,7 @@ const tableRowClassName = (data: any): any => {
         :initParam="initParam"
         layout="prev, pager, next"
         :rowClick="getSalaryParams"
-        :tableRowClassName="tableRowClassName"
+        :tableRowClassName="tableRowClassNameHandle"
       >
         <template #table-header>
           <h3 class="title">待处理</h3>
@@ -97,17 +73,19 @@ const tableRowClassName = (data: any): any => {
       </TableBase>
     </div>
     <transition
-      leave-active-class="animate__animated animate__bounceOutRight"
-      enter-active-class="animate__animated animate__bounceInDown"
+      leave-active-class="animate__animated animate__fadeOutRight"
+      enter-active-class="animate__animated animate__fadeInLeft"
     >
-      <el-row class="h-100 f-1 margin-left-3" v-if="userInfo.Id">
+      <el-row class="h-100 f-1 margin-left-3 Leave-container" v-if="userInfo.Id">
         <el-col :span="24" class="h-100" style="overflow: hidden; display: flex; flex-direction: column">
           <el-card class="m-b-3 b-show-0">
             <h3 class="title-user m-b-5">员工基本信息</h3>
             <div class="info-content">
               <el-avatar shape="square" size="large" :icon="UserFilled" />
               <div class="info-name">
-                <h4 class="m-b-3">名字:{{ userInfo.T_user_name }}</h4>
+                <h4>名字:{{ userInfo.T_user_name }}</h4>
+                <h4>部门: {{ userInfo.T_dept }}</h4>
+                <h4>岗位: {{ userInfo.T_post }}</h4>
               </div>
             </div>
           </el-card>
@@ -157,29 +135,38 @@ const tableRowClassName = (data: any): any => {
   overflow: hidden;
   .Leave-table {
     @include f-direction;
+    z-index: 1;
+    :deep(.table-header) {
+      margin-bottom: 0;
+    }
+    .title {
+      width: 100%;
+      text-align: center;
+    }
   }
-  .b-show-0 {
-    box-shadow: none;
-  }
-  .title {
-    width: 100%;
-    text-align: center;
-  }
-  .title-user {
-    text-align: left;
-  }
-  .btn {
-    margin-top: 2rem;
-    display: flex;
-    justify-content: end;
-  }
-  .info-content {
-    display: flex;
-    color: #606266;
-    .info-name {
+  .Leave-container {
+    z-index: 0;
+    .title-user {
+      text-align: left;
+    }
+    .b-show-0 {
+      box-shadow: none;
+    }
+    .btn {
+      margin-top: 2rem;
+      display: flex;
+      justify-content: end;
+    }
+    .info-content {
       display: flex;
-      align-items: center;
-      padding-left: 0.75rem;
+      color: #606266;
+      .info-name {
+        flex: 1;
+        display: flex;
+        justify-content: space-around;
+        align-items: center;
+        padding-left: 0.75rem;
+      }
     }
   }
 }

+ 1 - 2
src/views/workAttendance/MyLeave.vue

@@ -42,8 +42,7 @@ const columns: ColumnProps[] = [
 ]
 
 //drawer
-type Fn = () => void
-const callbackDrawer = (done: Fn) => {
+const callbackDrawer = (done: () => void) => {
   resetForm(ruleFormRef.value)
   done()
 }

+ 1 - 2
src/views/workAttendance/MyOvertime.vue

@@ -148,8 +148,7 @@ const AddOvertime = (formEl: FormInstance | undefined) => {
 }
 
 // Drawer
-type Fn = () => void
-const callbackDrawer = (done: Fn) => {
+const callbackDrawer = (done: () => void) => {
   disabled.value = false
   isNew.value = true
   nextTick(() => {

+ 20 - 43
src/views/workAttendance/Overtime.vue

@@ -1,30 +1,22 @@
 <script setup lang="ts">
+import { ref, nextTick } from 'vue'
 import { ElMessage } from 'element-plus'
 import { GlobalStore } from '@/stores/index'
 import { getFormatDuration } from '@/utils/common'
 import { UserFilled } from '@element-plus/icons-vue'
 import TableBase from '@/components/TableBase/index.vue'
-import { ref, nextTick } from 'vue'
 import { ColumnProps } from '@/components/TableBase/interface/index'
 import { Overtime_List, Overtime_Approval } from '@/api/workAttendance/index'
+import { useTablePublic, OvertimeUserInfoIn } from '@/hooks/useTablePublic'
 
 const TableRef = ref()
 const globalStore = GlobalStore()
+const initParam = { User_tokey: globalStore.GET_User_tokey }
 const columns: ColumnProps[] = [{ prop: 'T_user_name', label: '姓名' }]
-interface UserInfoIn {
-  T_uid: string
-  T_user_name: string
-  T_dept: string
-  T_post: string
-  T_type_name: string
-  T_start_time: string
-  T_end_time: string
-  T_text: string
-  Id: string
-  T_duration: string
-  T_prove_img: string
-}
-const userInfo = ref<UserInfoIn>({
+const { tableRowClassName } = useTablePublic()
+const tableRowClassNameHandle = (data: any): any => tableRowClassName(data.row.Id, userInfo.value.Id)
+
+const userInfo = ref<OvertimeUserInfoIn>({
   T_uid: '',
   T_user_name: '',
   T_dept: '',
@@ -38,11 +30,11 @@ const userInfo = ref<UserInfoIn>({
   T_duration: ''
 })
 
-const initParam = {
-  User_tokey: globalStore.GET_User_tokey
-}
 const getSalaryParams = (row: any) => {
-  userInfo.value = { ...row }
+  userInfo.value.Id = ''
+  setTimeout(() => {
+    userInfo.value = { ...row }
+  }, 100)
 }
 
 const LeaveUser = async (T_State: number) => {
@@ -61,27 +53,10 @@ const LeaveUser = async (T_State: number) => {
     }
     nextTick(() => {
       TableRef.value.getTableList()
-      userInfo.value = {} as UserInfoIn
+      userInfo.value = {} as OvertimeUserInfoIn
     })
   }
 }
-
-const tableRowClassName = (data: any): any => {
-  //判断是否相等,相同时改变背景颜色
-  let user: any = undefined
-  if (data.row.Id === userInfo.value.Id) {
-    user = data.row
-  }
-  if (user !== undefined) {
-    let rowBackground = {
-      background: '#f0f9eb',
-      color: '#67c23a'
-    }
-    return rowBackground
-  } else {
-    return ''
-  }
-}
 </script>
 
 <template>
@@ -94,7 +69,7 @@ const tableRowClassName = (data: any): any => {
         :initParam="initParam"
         layout="prev, pager, next"
         :rowClick="getSalaryParams"
-        :tableRowClassName="tableRowClassName"
+        :tableRowClassName="tableRowClassNameHandle"
       >
         <template #table-header>
           <h3 class="title">待处理</h3>
@@ -102,8 +77,8 @@ const tableRowClassName = (data: any): any => {
       </TableBase>
     </div>
     <transition
-      leave-active-class="animate__animated animate__bounceOutRight"
-      enter-active-class="animate__animated animate__bounceInDown"
+      leave-active-class="animate__animated animate__fadeOutRight"
+      enter-active-class="animate__animated animate__fadeInLeft"
     >
       <div class="Overtime-container" v-if="userInfo.Id">
         <el-card class="m-b-3 b-show-0">
@@ -218,6 +193,7 @@ const tableRowClassName = (data: any): any => {
 @import '@/styles/var.scss';
 
 .Overtime-container {
+  z-index: 0;
   width: 100%;
   height: 100%;
   display: flex;
@@ -256,6 +232,10 @@ const tableRowClassName = (data: any): any => {
   height: 100%;
   .Overtime-table {
     @include f-direction;
+    z-index: 1;
+    :deep(.table-header) {
+      margin-bottom: 0;
+    }
   }
   overflow: hidden;
   .img {
@@ -283,9 +263,6 @@ const tableRowClassName = (data: any): any => {
     width: 100%;
     text-align: center;
   }
-  .title-user {
-    // text-align: left;
-  }
   .btn {
     margin-top: 1rem;
     display: flex;

+ 52 - 69
src/views/workAttendance/RecordsFinance.vue

@@ -9,6 +9,7 @@ import { ElMessage, ElMessageBox } from 'element-plus'
 import { ColumnProps } from '@/components/TableBase/interface/index'
 import { ref, reactive, computed, nextTick } from 'vue'
 import { Leave_Finance_List, Leave_Deduct, LeaveType_List } from '@/api/workAttendance/index'
+import { useTablePublic } from '@/hooks/useTablePublic'
 
 const LeaveType = ref<any[]>([])
 const globalStore = GlobalStore()
@@ -17,6 +18,8 @@ const TableRef = ref<InstanceType<typeof TableBase> | null>(null)
 const initParam = reactive({ User_tokey: globalStore.GET_User_tokey, T_name: '' })
 const drawerRef = ref<InstanceType<typeof Drawer> | null>(null)
 const LeaveTableRef = ref<InstanceType<typeof TableBase> | null>(null)
+const { tableRowClassName } = useTablePublic()
+const tableRowClassNameHandle = (data: any): any => tableRowClassName(data.row.T_uuid, LeaveinitParam.T_uuid)
 
 let date = new Date()
 const month = date.getMonth()
@@ -51,12 +54,14 @@ const LeaveinitParam = reactive({
 })
 
 const getSalaryParams = (row: any) => {
-  userInfo.name = row.T_name
-  userInfo.T_dept = row.T_dept_name
-  userInfo.T_post = row.T_post_name
-  LeaveinitParam.T_uuid = row.T_uuid
-
-  LeaveTableRef.value && LeaveTableRef.value.searchTable()
+  LeaveinitParam.T_uuid = ''
+  setTimeout(() => {
+    userInfo.name = row.T_name
+    userInfo.T_dept = row.T_dept_name
+    userInfo.T_post = row.T_post_name
+    LeaveinitParam.T_uuid = row.T_uuid
+    LeaveTableRef.value && LeaveTableRef.value.searchTable()
+  }, 100)
 }
 
 const salarDateMonthChange = (val: string) => {
@@ -82,26 +87,7 @@ const userInfo = reactive({
   T_post: ''
 })
 
-const tableRowClassName = (data: any): any => {
-  //判断是否相等,相同时改变背景颜色
-  let user: any = undefined
-  if (data.row.T_uuid === LeaveinitParam.T_uuid) {
-    user = data.row
-  }
-  if (user !== undefined) {
-    let rowBackground = {
-      background: '#f0f9eb',
-      color: '#67c23a'
-    }
-    return rowBackground
-  } else {
-    return ''
-  }
-}
-
-const dataCallback = (res: any): any => {
-  return res.Data.Data && res.Data.Data.filter((item: any) => item.T_approver)
-}
+const dataCallback = (res: any): any => res.Data.Data && res.Data.Data.filter((item: any) => item.T_approver)
 
 // drawer
 const form = reactive({
@@ -122,7 +108,6 @@ const rules = reactive<FormRules>({
   T_text: [{ required: true, message: '请输入扣除理由', trigger: 'blur' }]
 })
 
-type Fn = () => void
 const Deductduraton = async () => {
   !LeaveType.value.length && getLeaveTypeList()
   drawerRef.value?.openDrawer()
@@ -133,7 +118,7 @@ const getLeaveTypeList = async () => {
     LeaveType.value = res.Data
   }
 }
-const callbackDrawer = (done: Fn) => {
+const callbackDrawer = (done: () => void) => {
   nextTick(() => {
     resetForm(ruleFormRef.value)
     done()
@@ -197,7 +182,7 @@ const searchHandle = () => TableRef.value?.searchTable()
         :initParam="initParam"
         layout="prev, pager, next"
         :rowClick="getSalaryParams"
-        :tableRowClassName="tableRowClassName"
+        :tableRowClassName="tableRowClassNameHandle"
       >
         <template #table-header>
           <el-row :gutter="24" class="input-suffix margin-left-0 margin-right-0">
@@ -211,21 +196,19 @@ const searchHandle = () => TableRef.value?.searchTable()
       </TableBase>
     </div>
     <transition
-      leave-active-class="animate__animated animate__bounceOutRight"
-      enter-active-class="animate__animated animate__bounceInDown"
+      leave-active-class="animate__animated animate__fadeOutRight"
+      enter-active-class="animate__animated animate__fadeInLeft"
     >
-      <el-row class="h-100 f-1 margin-left-3" v-if="LeaveinitParam.T_uuid">
+      <el-row class="h-100 f-1 margin-left-3 RecordsFinance-container" v-if="LeaveinitParam.T_uuid">
         <el-col :span="24" class="h-100" style="overflow: hidden; display: flex; flex-direction: column">
           <el-card class="m-b-3">
             <h3 class="title m-b-5">员工基本信息</h3>
             <div class="info-content">
               <el-avatar shape="square" size="large"><img src="@/assets/images/avatar.jpg" /> </el-avatar>
               <div class="info-name">
-                <h4 class="m-b-3">名字:{{ userInfo.name }}</h4>
-                <h4>
-                  <span>部门:{{ userInfo.T_dept }}</span>
-                  <span>岗位:{{ userInfo.T_post }}</span>
-                </h4>
+                <h4>名字:{{ userInfo.name }}</h4>
+                <h4>部门: {{ userInfo.T_dept }}</h4>
+                <h4>岗位: {{ userInfo.T_post }}</h4>
               </div>
             </div>
           </el-card>
@@ -316,14 +299,41 @@ const searchHandle = () => TableRef.value?.searchTable()
 <style scoped lang="scss">
 @import '@/styles/var.scss';
 .RecordsFinance {
-  .RecordsFinance-table {
-    @include f-direction;
-  }
   display: flex;
   height: 100%;
   overflow: hidden;
-  .w-100 {
-    width: 100%;
+  .RecordsFinance-table {
+    @include f-direction;
+    z-index: 1;
+    :deep(.table-header) {
+      margin-bottom: 0;
+    }
+    .input-suffix {
+      width: 100%;
+      flex-direction: column;
+
+      .inline-flex {
+        white-space: nowrap;
+        display: inline-flex;
+      }
+    }
+  }
+  .RecordsFinance-container {
+    z-index: 0;
+    .title {
+      text-align: left;
+    }
+    .info-content {
+      display: flex;
+      color: #606266;
+      .info-name {
+        flex: 1;
+        display: flex;
+        justify-content: space-around;
+        align-items: center;
+        padding-left: 0.75rem;
+      }
+    }
   }
 }
 .d-flex {
@@ -338,31 +348,4 @@ const searchHandle = () => TableRef.value?.searchTable()
 .justify-end {
   justify-content: end;
 }
-.input-suffix {
-  width: 100%;
-  flex-direction: column;
-  .w-50 {
-    width: 12.5rem;
-  }
-
-  .inline-flex {
-    white-space: nowrap;
-    display: inline-flex;
-  }
-}
-.title {
-  text-align: left;
-}
-.info-content {
-  display: flex;
-  color: #606266;
-  .info-name {
-    display: flex;
-    flex-direction: column;
-    padding-left: 0.75rem;
-    span:first-child {
-      margin-right: 2rem;
-    }
-  }
-}
 </style>

+ 19 - 37
src/views/workAttendance/records/Records.vue

@@ -7,6 +7,7 @@ import Drawer from '@/components/Drawer/index.vue'
 import TableBase from '@/components/TableBase/index.vue'
 import { ref, reactive, onMounted, onUnmounted, nextTick } from 'vue'
 import { ColumnProps } from '@/components/TableBase/interface/index'
+import { useTablePublic } from '@/hooks/useTablePublic'
 import { Leave_User_list, Overtime_User_list, Overtime_Stat } from '@/api/workAttendance/index'
 
 let clientHeight = ref(0)
@@ -17,6 +18,8 @@ const overtimeRef = ref<InstanceType<typeof TableBase> | null>(null)
 const remainingTimeRef = ref<InstanceType<typeof TableBase> | null>(null)
 const drawerLeaveRef = ref<InstanceType<typeof Drawer> | null>(null)
 const drawerOvertimeRef = ref<InstanceType<typeof Drawer> | null>(null)
+const { tableRowClassName } = useTablePublic()
+const tableRowClassNameHandle = (data: any): any => tableRowClassName(data.row.T_uuid, userInitParam.T_uuid)
 
 const columns: ColumnProps[] = [{ prop: 'T_name', label: '姓名' }]
 const overtimeColums: ColumnProps[] = [
@@ -98,10 +101,13 @@ onUnmounted(() => (window.onresize = null))
 // 点击行
 const getSalaryParams = (row: any) => {
   if (row.T_uuid === userInitParam.T_uuid) return
-  userInfoAssign(row)
-  leaveRef.value && leaveRef.value.searchTable()
-  overtimeRef.value && overtimeRef.value.searchTable()
-  remainingTimeRef.value && remainingTimeRef.value.searchTable()
+  userInitParam.T_uuid = ''
+  setTimeout(() => {
+    userInfoAssign(row)
+    leaveRef.value && leaveRef.value.searchTable()
+    overtimeRef.value && overtimeRef.value.searchTable()
+    remainingTimeRef.value && remainingTimeRef.value.searchTable()
+  }, 100)
 }
 // 查看加班记录
 const viewOvertime = (row: any) => {
@@ -126,28 +132,7 @@ const viewoLeave = (row: any) => {
   LeaveInfo.value.T_duration = getFormatDuration(row.T_duration)
   drawerLeaveRef.value && drawerLeaveRef.value.openDrawer()
 }
-type Fn = () => void
-const callbackDrawer = (done: Fn) => {
-  done()
-}
-
-const tableRowClassName = (data: any): any => {
-  //判断是否相等,相同时改变背景颜色
-  let user: any = undefined
-  if (data.row.T_uuid === userInitParam.T_uuid) {
-    user = data.row
-  }
-  if (user !== undefined) {
-    let rowBackground = {
-      background: '#f0f9eb',
-      color: '#67c23a'
-    }
-    return rowBackground
-  } else {
-    return ''
-  }
-}
-
+const callbackDrawer = (done: () => void) => done()
 const searchHandle = () => TableRef.value?.searchTable()
 </script>
 
@@ -161,11 +146,10 @@ const searchHandle = () => TableRef.value?.searchTable()
         :initParam="initParam"
         layout="prev, pager, next"
         :rowClick="getSalaryParams"
-        :tableRowClassName="tableRowClassName"
+        :tableRowClassName="tableRowClassNameHandle"
       >
         <template #table-header>
-          <!-- <h3 class="title">待处理</h3> -->
-          <el-row :gutter="24" class="input-suffix margin-left-0 margin-right-0">
+          <el-row :gutter="24" class="margin-left-0 margin-right-0">
             <el-col :span="24" class="d-flex padding-right-0 padding-left-0">
               <span class="inline-flex">姓名:</span>
               <el-input type="text" v-model="initParam.T_name" @change="searchHandle" />
@@ -176,21 +160,19 @@ const searchHandle = () => TableRef.value?.searchTable()
       </TableBase>
     </div>
     <transition
-      leave-active-class="animate__animated animate__bounceOutRight"
-      enter-active-class="animate__animated animate__bounceInDown"
+      leave-active-class="animate__animated animate__fadeOutRight"
+      enter-active-class="animate__animated animate__fadeInLeft"
     >
-      <el-row class="h-100 f-1 margin-left-3" v-if="userInitParam.T_uuid">
+      <el-row class="h-100 f-1 margin-left-3 records-container" v-if="userInitParam.T_uuid">
         <el-col :span="24" class="h-100" style="overflow: hidden">
           <el-card class="m-b-3">
             <h3 class="title m-b-5">员工基本信息</h3>
             <div class="info-content">
               <el-avatar shape="square" size="large"><img src="@/assets/images/avatar.jpg" /> </el-avatar>
               <div class="info-name">
-                <h4 class="m-b-3">名字:{{ userInfo.name }}</h4>
-                <h4>
-                  <span>部门:{{ userInfo.T_dept }}</span>
-                  <span>岗位:{{ userInfo.T_post }}</span>
-                </h4>
+                <h4>名字:{{ userInfo.name }}</h4>
+                <h4>部门: {{ userInfo.T_dept }}</h4>
+                <h4>岗位: {{ userInfo.T_post }}</h4>
               </div>
             </div>
           </el-card>

+ 16 - 4
src/views/workAttendance/records/index.scss

@@ -2,6 +2,19 @@
   display: flex;
   height: 100%;
   overflow: hidden;
+  .records-table {
+    z-index: 1;
+    :deep(.table-header) {
+      margin-bottom: 0;
+    }
+  }
+  .records-container {
+    z-index: 0;
+  }
+  .el-card,
+  .content {
+    border-radius: 8px;
+  }
   .inline-flex {
     white-space: nowrap;
     display: inline-flex;
@@ -50,12 +63,11 @@
     display: flex;
     color: #606266;
     .info-name {
+      flex: 1;
       display: flex;
-      flex-direction: column;
+      justify-content: space-around;
+      align-items: center;
       padding-left: 0.75rem;
-      span:first-child {
-        margin-right: 2rem;
-      }
     }
   }
 }

+ 1 - 1
vite.config.ts

@@ -23,7 +23,7 @@ export default defineConfig(({ mode }: ConfigEnv): UserConfig => {
     css: {
       preprocessorOptions: {
         scss: {
-          additionalData: '@use "@/styles/index.scss";'
+          additionalData: '@use "@/styles/index.scss" as *;'
         }
       }
     },