Selaa lähdekoodia

feat: ✨ 薪资扣除功能

@sun-chaoqun 2 vuotta sitten
vanhempi
commit
91b8bf22d4

+ 1 - 0
package.json

@@ -5,6 +5,7 @@
   "type": "module",
   "scripts": {
     "dev": "vite",
+    "server":"vite",
     "build": "vue-tsc && vite build --mode production",
     "preview": "vite preview"
   },

+ 1 - 1
src/api/index.ts

@@ -12,7 +12,7 @@ let loadingInstance: LoadingType = {}
 
 const config = {
   // 默认地址请求地址,可在 .env.*** 文件中修改
-  // baseURL: import.meta.env.VITE_BZD_ERP_APP_API as string,
+  baseURL: import.meta.env.VITE_BZD_ERP_APP_API as string,
   // 设置超时时间(10s)
   timeout: ResultEnum.TIMEOUT as number,
   // 跨域时候允许携带凭证

+ 2 - 0
src/api/workAttendance/index.ts

@@ -22,6 +22,8 @@ export const Leave_Del = (params: any) => $http.post('/api/ams/Leave/Del', param
 export const Leave_DaysOff = (params: any) => $http.post('/api/ams/Leave/DaysOff', params)
 // 财务管理
 export const Leave_Finance_List = (params: any) => $http.post('/api/ams/Leave/Finance_List', params)
+// 计算请假时长
+export const Leave_Duration = (params: any) => $http.post('/api/ams/Leave/Duration', params)
 
 /**
  * 加班

+ 1 - 1
src/hooks/useTable.ts

@@ -59,8 +59,8 @@ export const useTable = (
       page_z: state.pageable.pageSize
     }
     const res = await requestApi(params)
-    dataCallback && dataCallback(res)
     state.tableData = res.Data.Data
+    dataCallback && (state.tableData = dataCallback(res))
     state.pageable.total = res.Data.Num
     if (res.Data.RemainingTime) {
       state.pageable.RemainingTime = res.Data.RemainingTime

+ 2 - 2
src/layouts/Header/index.vue

@@ -37,7 +37,7 @@ setInterval(() => {
 <template>
   <div class="header">
     <el-row>
-      <el-col :xl="15" :lg="13" :sm="13" class="d-flex">
+      <el-col :xl="15" :lg="13" :sm="12" class="d-flex">
         <el-button
           class="isCollapse"
           type="primary"
@@ -47,7 +47,7 @@ setInterval(() => {
         ></el-button>
         <Breadcrumb></Breadcrumb>
       </el-col>
-      <el-col :xl="2" :lg="2" :sm="2" class="notice">
+      <el-col :xl="2" :lg="2" :sm="3" class="notice">
         <el-link type="primary" @click="goTask"
           ><el-icon> <List /> </el-icon>任务管理</el-link
         >

+ 0 - 1
src/router/index.ts

@@ -19,7 +19,6 @@ router.beforeEach(async (to, from, next) => {
   title && (document.title = title as string)
 
   if (store.GET_User_tokey && to.path !== '/login') {
-    // console.log(to.path)
     if (!store.GET_Flat_Menu.length) {
       await initDynamicRouter()
       return next({ ...to, replace: true })

+ 0 - 8
src/router/modules/asyncRouter.ts

@@ -34,15 +34,7 @@ export const initDynamicRouter = async () => {
     globalStore.GET_Flat_Menu.forEach((item: any) => {
       item.children && delete item.children
       if (item.component && typeof item.component == 'string') {
-        // console.log(item.component);
-
         item.component = modules['/src/views' + item.component + '.vue']
-        // console.log(modules['/src/views' + item.component + '.vue'], modules)
-
-        // console.log(item)
-        // /src/views/home/Home.vue
-        // /src/views' + item.component + '.vue
-        // "/home/Home"
       }
       if (item.meta.isFull) {
         router.addRoute(item)

+ 96 - 96
src/router/modules/staticRouter.ts

@@ -13,102 +13,102 @@ export const staticRouter: RouteRecordRaw[] = [
       title: '起始页'
     },
     children: [
-      {
-        path: '/list',
-        name: 'List',
-        component: () => import('@/views/storehouse/List.vue'),
-        meta: {
-          title: '仓库列表'
-        }
-      },
-      {
-        path: '/classify',
-        name: 'Classify',
-        component: () => import('@/views/storehouse/Classify.vue'),
-        meta: {
-          title: '产品分类'
-        }
-      },
-      {
-        path: '/productionList',
-        name: 'ProductionList',
-        component: () => import('@/views/storehouse/ProductionList.vue'),
-        meta: {
-          title: '产品列表'
-        }
-      },
-      {
-        path: '/ioTNetworkCard',
-        name: 'IoTNetworkCard',
-        component: () => import('@/views/storehouse/IoTNetworkCard.vue'),
-        meta: {
-          title: '物联网卡'
-        }
-      },
-      {
-        path: '/saleMange',
-        name: 'SaleMange',
-        component: () => import('@/views/storehouse/sales/index.vue'),
-        // redirect: '/contract',
-        meta: {
-          routerView: true,
-          title: '销售管理'
-        },
-        children: [
-          {
-            path: '/contract',
-            name: 'Contract',
-            component: () => import('@/views/storehouse/sales/Contract.vue'),
-            meta: {
-              title: '合同管理'
-            }
-          },
-          {
-            path: '/contractDetail/:id',
-            name: 'ContractDetail',
-            component: () => import('@/views/storehouse/sales/ContractDetail.vue'),
-            meta: {
-              title: '合同详情'
-            }
-          },
-          {
-            path: '/contractSale',
-            name: 'ContractSale',
-            component: () => import('@/views/storehouse/sales/ContractSale.vue'),
-            meta: {
-              title: '合同详情(销售)'
-            }
-          }
-        ]
-      },
-      {
-        path: '/inventoryMange',
-        name: 'InventoryMange',
-        component: () => import('@/views/storehouse/inventory/index.vue'),
-        // redirect: '/contract',
-        meta: {
-          routerView: true,
-          title: '库存管理'
-        },
-        children: [
-          {
-            path: '/device',
-            name: 'Device',
-            component: () => import('@/views/storehouse/inventory/Device.vue'),
-            meta: {
-              title: '设备列表'
-            }
-          },
-          {
-            path: '/inStorage',
-            name: 'InStorage',
-            component: () => import('@/views/storehouse/inventory/InStorage.vue'),
-            meta: {
-              title: '入库管理'
-            }
-          }
-        ]
-      },
+      // {
+      //   path: '/list',
+      //   name: 'List',
+      //   component: () => import('@/views/storehouse/List.vue'),
+      //   meta: {
+      //     title: '仓库列表'
+      //   }
+      // },
+      // {
+      //   path: '/classify',
+      //   name: 'Classify',
+      //   component: () => import('@/views/storehouse/Classify.vue'),
+      //   meta: {
+      //     title: '产品分类'
+      //   }
+      // },
+      // {
+      //   path: '/productionList',
+      //   name: 'ProductionList',
+      //   component: () => import('@/views/storehouse/ProductionList.vue'),
+      //   meta: {
+      //     title: '产品列表'
+      //   }
+      // },
+      // {
+      //   path: '/ioTNetworkCard',
+      //   name: 'IoTNetworkCard',
+      //   component: () => import('@/views/storehouse/IoTNetworkCard.vue'),
+      //   meta: {
+      //     title: '物联网卡'
+      //   }
+      // },
+      // {
+      //   path: '/saleMange',
+      //   name: 'SaleMange',
+      //   component: () => import('@/views/storehouse/sales/index.vue'),
+      //   // redirect: '/contract',
+      //   meta: {
+      //     routerView: true,
+      //     title: '销售管理'
+      //   },
+      //   children: [
+      //     {
+      //       path: '/contract',
+      //       name: 'Contract',
+      //       component: () => import('@/views/storehouse/sales/Contract.vue'),
+      //       meta: {
+      //         title: '合同管理'
+      //       }
+      //     },
+      //     {
+      //       path: '/contractDetail/:id',
+      //       name: 'ContractDetail',
+      //       component: () => import('@/views/storehouse/sales/ContractDetail.vue'),
+      //       meta: {
+      //         title: '合同详情'
+      //       }
+      //     },
+      //     {
+      //       path: '/contractSale',
+      //       name: 'ContractSale',
+      //       component: () => import('@/views/storehouse/sales/ContractSale.vue'),
+      //       meta: {
+      //         title: '合同详情(销售)'
+      //       }
+      //     }
+      //   ]
+      // },
+      // {
+      //   path: '/inventoryMange',
+      //   name: 'InventoryMange',
+      //   component: () => import('@/views/storehouse/inventory/index.vue'),
+      //   // redirect: '/contract',
+      //   meta: {
+      //     routerView: true,
+      //     title: '库存管理'
+      //   },
+      //   children: [
+      //     {
+      //       path: '/device',
+      //       name: 'Device',
+      //       component: () => import('@/views/storehouse/inventory/Device.vue'),
+      //       meta: {
+      //         title: '设备列表'
+      //       }
+      //     },
+      //     {
+      //       path: '/inStorage',
+      //       name: 'InStorage',
+      //       component: () => import('@/views/storehouse/inventory/InStorage.vue'),
+      //       meta: {
+      //         title: '入库管理'
+      //       }
+      //     }
+      //   ]
+      // },
       // {
       //   path: '/contract',
       //   name: 'Contract',

+ 0 - 62
src/utils/common.ts

@@ -135,56 +135,6 @@ export const getFormatDuration = (time: number) => {
   return result
 }
 
-/**
- *
- * @param {*} file 上传的文件
- * @param {*} token 上传需要的token
- */
-// export const qiniuUpLoadFun = (file: any, token: any) => {
-//   //七牛上传方法
-//   return new Promise(function (resolve) {
-//     let timestamp = new Date().valueOf()
-//     let params = {
-//       file: file, //要上传的文件
-//       key: 'paper_file/' + timestamp + file.name, //自定义文件地址
-//       token: token,
-//       config: {
-//         useCdnDomain: false,
-//         // region: undefined,
-//         region: qiniu.region.z2,
-//         domin: 'https://qiniu.region.z2',
-//         chunkSize: 1000
-//       },
-//       putExtra: {
-//         fname: file.name,
-//         params: {},
-//         mimeType: [] || null
-//       }
-//     }
-//     console.log('domin')
-//     resolve(params)
-//   })
-// }
-// export function upLoadQiniu(params: any) {
-//   let observable = qiniu.upload(params.file, params.key, params.token, params.putExtra, params.config)
-//   let observer = {
-//     next(res: any) {
-//       // console.log(res);
-//       console.log('上传中', res)
-//     },
-//     error(err: any) {
-//       console.log(err)
-//     },
-//     complete(res: any) {
-//       // let url = 'http://xxxxxx.cn/' + res.key
-//       // layer.close(loading) //关闭loading效果
-//       console.log(res)
-//       // resolve(url)
-//     }
-//   }
-//   observable.subscribe(observer)
-// }
-
 interface iconsType {
   [propName: string]: string | number
 }
@@ -207,18 +157,6 @@ export const icons: iconsType = {
   ue7cd: '\ue7cd',
   ue831: '\ue831'
 }
-
-// export const debounce = (fn: () => void, duration: number) => {
-//   let time: NodeJS.Timeout = 0
-//   return () => {
-//     // let arg =
-//     clearTimeout(time)
-//     time = setTimeout(() => {
-//       fn && fn()
-//     }, duration)
-//   }
-// }
-
 export function debounce<T extends (...args: any[]) => any>(fn: T, delay: number): (...args: Parameters<T>) => void {
   let timerId: number | undefined
 

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

@@ -126,6 +126,7 @@ const AddUser = (formEl: FormInstance | undefined) => {
 const DataEcho = async (row: any) => {
   row.T_entry_type = +row.T_entry_type
   row.T_pass = _PASS
+  checkPass.value = _PASS
   const res: any = await User_Post_List({ T_dept: row.T_dept })
   userPostList.value = res.Data
   nextTick(() => {

+ 0 - 1
src/views/home/User.vue

@@ -83,7 +83,6 @@ const submitForm = (formEl: FormInstance | undefined) => {
   formEl.validate(async valid => {
     if (valid) {
       const res: any = await User_Post({ User_tokey: globalStore.GET_User_tokey, T_pass: fnMd5(ruleForm.pass) })
-      console.log(res)
       if (res.Code === 200) {
         ElMessage.success('修改成功!!')
         nextTick(() => resetForm(ruleFormRef.value))

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

@@ -69,7 +69,6 @@ const openDrawer = (type: string, row?: any) => {
       form.T_remark = row.T_remark
       form.T_relation_sn = row.T_relation_sn
     }
-    console.log(form)
   })
   drawerRef.value?.openDrawer()
 }
@@ -160,7 +159,6 @@ const getProductClassList = async () => {
 const specList = ref<any[]>([])
 const getSpecList = async () => {
   const res: any = await Storehouse_Product_Spec_List({ User_tokey: globalStore.GET_User_tokey })
-  console.log(res)
   specList.value = res.Data
 }
 

+ 21 - 9
src/views/storehouse/inventory/InStorage.vue

@@ -1,5 +1,5 @@
 <script setup lang="ts">
-import { ref, reactive, onMounted } from 'vue'
+import { ref, reactive, onMounted, computed } from 'vue'
 import { GlobalStore } from '@/stores/index'
 import Dialog from '@/components/dialog/Dialog.vue'
 import TableBase from '@/components/TableBase/index.vue'
@@ -32,12 +32,23 @@ const previewImg = (str: string) => {
 }
 
 // 搜索
+const T_date = ref('')
+
 const initParam = reactive({
   User_tokey: globalStore.GET_User_tokey,
-  T_date: '',
-  T_state: ''
+  T_end_date: '',
+  T_start_date: '',
+  T_depot_id: ''
 })
+
+// const date = computed(()=>{
+//   return { T_end_date: T_date[1] }
+// })
+
 const searchHandle = () => {
+  console.log(initParam)
+  // initParam.T_end_date = initParam.T_date[1]
+  // initParam.T_start_date = initParam.T_date[0]
   TableRef.value?.searchTable()
 }
 
@@ -66,27 +77,26 @@ onMounted(() => {
       <template #table-header>
         <div class="input-suffix">
           <el-row :gutter="20" style="margin-bottom: 0">
-            <el-col :xl="7" :lg="9" :md="11">
+            <el-col :xl="6" :lg="9" :md="11" style="display: flex">
               <span class="inline-flex items-center">入库日期:</span>
               <el-date-picker
-                v-model="initParam.T_date"
+                v-model="T_date"
                 type="daterange"
                 range-separator="~"
                 start-placeholder="开始时间"
                 end-placeholder="结束时间"
                 format="YYYY-MM-DD"
                 value-format="YYYY-MM-DD"
-                class="w-50 m-2"
               />
             </el-col>
-            <el-col :xl="14" :lg="12" :md="11">
+            <el-col :xl="6" :lg="7" :md="9" style="display: flex">
               <span class="inline-flex items-center">仓库:</span>
-              <el-select v-model="initParam.T_state" class="w-50" clearable placeholder="请选择仓库~">
+              <el-select v-model="initParam.T_depot_id" clearable placeholder="请选择仓库~">
                 <el-option v-for="item in options" :key="item.T_State" :label="item.T_name" :value="item.T_State" />
               </el-select>
               <el-button type="primary" @click="searchHandle">搜索</el-button>
             </el-col>
-            <el-col :xl="3" :lg="3" :md="4" class="btn"
+            <el-col :xl="12" :lg="8" :md="4" class="btn"
               ><el-button type="primary" @click="openInStorageFormDrawer('new')">入库</el-button></el-col
             >
           </el-row>
@@ -127,6 +137,8 @@ onMounted(() => {
       width: 12.5rem;
     }
     .btn {
+      display: flex;
+      justify-content: end;
       .el-button {
         padding: 0 20px;
       }

+ 45 - 8
src/views/storehouse/inventory/InStorageForm.vue

@@ -98,7 +98,7 @@ const deleteProduct = (row: any) => {
   tableData.value = tableData.value.filter(item => item.Id !== row.Id)
 
   // 设置产品的选中
-  // selectTable.value?.toggleRowSelection(row, false)
+  selectTable.value?.toggleRowSelection(row, false)
 }
 
 const callbackDrawer = (done: Fn) => {
@@ -220,7 +220,15 @@ const getProductList = async () => {
 }
 const ProductselectionChange = (row: any[]) => {
   const newProduct = row.find((product: any) => tableData.value.findIndex((item: any) => item.Id === product.Id) === -1)
-  newProduct && tableData.value.push({ ...newProduct })
+  newProduct && tableData.value.push(newProduct)
+  // if (!isNew.value) {
+  //   const newProduct = row.find(
+  //     (product: any) => tableData.value.findIndex((item: any) => item.Id === product.Id) === -1
+  //   )
+  //   newProduct && tableData.value.push({ ...newProduct })
+  // } else {
+  //   tableData.value = row
+  // }
 }
 
 // 搜索模型
@@ -240,13 +248,36 @@ const addDeviceSn = () => {
   //
   drawerSnRef.value?.openDrawer()
 }
-const tableSnData: any[] = []
+const tableSnData: any[] = reactive([{ sn: 12131423 }])
 const snColumns = [
   { type: 'index', label: '序号', width: 80, align: 'center ' },
   { label: 'SN', prop: 'sn', align: 'center ' },
   { prop: 'operation', label: '操作', width: 80, fixed: 'right' }
 ]
 
+const ruleSnFormRef = ref()
+const formSn = reactive({
+  T_sn: ''
+})
+const rulesSn = reactive<FormRules>({
+  T_sn: [{ required: true, message: '请输入SN号', trigger: 'blur' }]
+})
+
+const addSn = (formEl: FormInstance | undefined) => {
+  if (!formEl) return
+  formEl.validate(async valid => {
+    if (valid) {
+      console.log('push')
+
+      tableSnData.push({ sn: formSn.T_sn })
+    }
+  })
+}
+const deleteSn = (row: any) => {
+  const index = tableSnData.findIndex((item: any) => row.sn === item.sn)
+  tableSnData.splice(index, 1)
+}
+
 // 接受props
 interface ItemType {
   T_name: string
@@ -450,12 +481,12 @@ defineExpose({
           <el-card class="box-card" shadow="never">
             <template #header>
               <div class="sn-header">
-                <el-form ref="ruleFormRef" :model="form" :rules="rules">
-                  <el-form-item label="SN:" :label-width="formLabelWidth" prop="T_number">
-                    <el-input v-model="form.T_number" type="text" placeholder="请输入SN" class="w-50" />
+                <el-form ref="ruleSnFormRef" :model="formSn" :rules="rulesSn">
+                  <el-form-item label="SN:" :label-width="formLabelWidth" prop="T_sn">
+                    <el-input v-model="formSn.T_sn" type="text" placeholder="请输入SN" class="w-50" />
                   </el-form-item>
                 </el-form>
-                <el-button type="primary">添加</el-button>
+                <el-button type="primary" @click="addSn(ruleSnFormRef)">添加</el-button>
               </div>
             </template>
             <el-table
@@ -471,7 +502,13 @@ defineExpose({
                 <el-table-column v-if="item.type === 'index'" v-bind="item" />
                 <el-table-column v-if="item.prop" align="center" v-bind="item">
                   <template #default="{ row }">
-                    <el-button v-if="item.prop === 'operation'" link type="danger" size="small" :icon="Delete"
+                    <el-button
+                      v-if="item.prop === 'operation'"
+                      link
+                      type="danger"
+                      size="small"
+                      :icon="Delete"
+                      @click="deleteSn(row)"
                       >删除</el-button
                     >
                   </template>

+ 266 - 3
src/views/storehouse/inventory/InStorageProduct.vue

@@ -1,7 +1,270 @@
-<script setup lang="ts"></script>
+<script setup lang="ts">
+import { ref, reactive, onMounted, computed, nextTick } from 'vue'
+import { GlobalStore } from '@/stores/index'
+import Drawer from '@/components/Drawer/index.vue'
+import {
+  Storehouse_Product_List,
+  Storehouse_ProductClass_List,
+  Storehouse_Product_Model_List,
+  Storehouse_Product_Name_List,
+  Storehouse_Contract_Product_List
+} from '@/api/storehouse/index'
+import { ElMessage } from 'element-plus'
+import { default as vElTableInfiniteScroll } from 'el-table-infinite-scroll'
+
+type Fn = () => void
+
+let total = 0
+const selectTable = ref()
+let selectProductData: any[] = []
+const globalStore = GlobalStore()
+const classOptions = ref<any[]>([])
+const modelOptions = ref<any[]>([])
+const tableProductData = ref<any[]>([])
+const drawerProductRef = ref<InstanceType<typeof Drawer> | null>(null)
+
+const initParam = reactive({
+  User_tokey: globalStore.GET_User_tokey,
+  T_name: '',
+  T_model: '',
+  T_class: '',
+  page: 0,
+  page_z: 20
+})
+const callbackProductDrawer = (done: Fn) => done()
+const autoSelect = ref('')
+let timeout: NodeJS.Timeout
+const querySearchAsync = async (queryString: string, cb: (arg: any) => void) => {
+  clearTimeout(timeout)
+  timeout = setTimeout(async () => {
+    const results = await getNameAsync(queryString)
+    console.log(autoSelect, queryString)
+    cb(results)
+  }, 2000)
+}
+
+const getProductModelList = async () => {
+  const res: any = await Storehouse_Product_Model_List({ T_name: autoSelect.value })
+  modelOptions.value = res.Data.map((item: any, index: number) => {
+    return {
+      value: item,
+      index: index
+    }
+  })
+}
+const handleSelect = (item: any) => {
+  // initParam.T_name = item.value
+  getProductModelList()
+}
+// 搜索模型
+const searchModelHandle = () => {
+  total = 0
+  initParam.page = 1
+  tableProductData.value = []
+  getProductList()
+}
+
+// 保存选中的数据id,row-key就是要指定一个key标识这一行的数据
+const getRowKey = (row: any) => {
+  return row.Id
+}
+
+// 加载第二个抽屉数据
+const load = () => {
+  if (initParam.page && total === tableProductData.value.length) {
+    ElMessage.warning('没有更多数据了!!')
+    return
+  }
+  initParam.page++
+  getProductList()
+}
+// 勾选产品
+const ProductselectionChange = (row: any[]) => {
+  console.log(row, tableData.value)
+  const newProduct = row.find((product: any) => tableData.value.findIndex((item: any) => item.Id === product.Id) === -1)
+  newProduct && emit('ontableData', newProduct)
+}
+
+const getNameAsync = async (str: string): Promise<any> => {
+  const res: any = await Storehouse_Product_Name_List({ T_name: str, T_class: initParam.T_class })
+  if (!res.Data) return
+  return res.Data.map((item: any, index: number) => {
+    return {
+      value: item,
+      index: index
+    }
+  })
+}
+
+const getProductList = async () => {
+  const res: any = await Storehouse_Product_List({ ...initParam, T_name: autoSelect.value })
+  tableProductData.value.push(...res.Data.Data)
+  total = res.Data.Num
+  if (!props.isNew) {
+    // 设置产品的选中
+    tableProductData.value.forEach((row: any) => {
+      const matchedIndex = selectProductData.findIndex((item: any) => item.Id == row.Id)
+
+      selectTable.value?.toggleRowSelection(row, matchedIndex != -1)
+    })
+  }
+}
+
+// 获取产品分类
+const getProductClassList = async () => {
+  const res: any = await Storehouse_ProductClass_List({ page: 1, page_z: 999 })
+  classOptions.value = res.Data.Data
+}
+
+onMounted(() => {
+  !classOptions.value.length && getProductClassList()
+})
+
+const productColumns = [
+  { type: 'selection', width: 80 },
+  { prop: 'T_img', label: '产品图片', name: 'T_img' },
+  { prop: 'T_name', label: '产品名称' },
+  { prop: 'T_class_name', label: '产品分类' },
+  { prop: 'T_model', label: '产品型号', ellipsis: true },
+  { prop: 'T_spec', label: '产品规格' },
+  { prop: 'T_relation_sn', label: '关联SN', name: 'T_relation_sn' },
+  { prop: 'T_remark', label: '备注', ellipsis: true }
+]
+
+const openDrawer = () => {
+  drawerProductRef.value?.openDrawer()
+}
+
+const selectTableChange = (row: any) => {
+  console.log(row, tableData)
+  selectTable.value?.clearSelection()
+  nextTick(() => {
+    // selectTable.value?.toggleRowSelection(row, false)
+  })
+}
+
+interface PropsType {
+  isNew: boolean
+  tableData: any[]
+}
+
+const emit = defineEmits<{ (event: 'ontableData', value: any): void }>()
+
+const props = defineProps<PropsType>()
+
+const tableData = computed(() => props.tableData)
+
+defineExpose({
+  openDrawer,
+  selectTableChange
+})
+</script>
 
 <template>
-  <div></div>
+  <Drawer ref="drawerProductRef" :handleClose="callbackProductDrawer" size="70%">
+    <template #header="{ params }">
+      <h4 :id="params.titleId" :class="params.titleClass">选择产品</h4>
+    </template>
+    <el-card class="box-card" shadow="never">
+      <template #header>
+        <div class="input-suffix">
+          <el-row :gutter="20" style="margin-bottom: 0">
+            <el-col :xl="5" :lg="8" :md="10" class="d-flex">
+              <span class="inline-flex items-center">产品分类:</span>
+              <el-select v-model="initParam.T_class" clearable placeholder="请选择分类~">
+                <el-option v-for="item in classOptions" :key="item.Id" :label="item.T_name" :value="item.Id" />
+              </el-select>
+            </el-col>
+            <el-col :xl="7" :lg="8" :md="10" class="d-flex">
+              <span class="inline-flex items-center">产品名称:</span>
+              <el-autocomplete
+                v-model="autoSelect"
+                clearable
+                :fetch-suggestions="querySearchAsync"
+                placeholder="按产品名称搜索"
+                :debounce="2000"
+                :trigger-on-focus="false"
+                @select="handleSelect"
+              />
+            </el-col>
+            <el-col :xl="7" :lg="8" :md="12" class="d-flex">
+              <span class="inline-flex items-center">产品型号:</span>
+              <el-select v-model="initParam.T_model" clearable placeholder="请选择型号~">
+                <el-option v-for="item in modelOptions" :key="item.index" :label="item.value" :value="item.value" />
+              </el-select>
+              <el-button type="primary" @click="searchModelHandle">搜索</el-button>
+            </el-col>
+          </el-row>
+        </div>
+      </template>
+      <el-table
+        ref="selectTable"
+        :row-key="getRowKey"
+        :data="tableProductData"
+        style="width: 100%; height: 99%"
+        :header-cell-style="{
+          background: '#dedfe0',
+          height: '50px'
+        }"
+        v-el-table-infinite-scroll="load"
+        @selection-change="ProductselectionChange"
+      >
+        <template v-for="item in productColumns" :key="item">
+          <el-table-column v-if="item.type === 'index' || item.type === 'selection'" align="center" v-bind="item" />
+          <el-table-column v-if="!item.ellipsis && item.prop" v-bind="item">
+            <template #default="{ row }">
+              <span v-if="item.prop === 'T_relation_sn'">
+                <el-tag v-if="row.T_relation_sn === 1" effect="dark">是</el-tag>
+                <el-tag v-else type="success" effect="dark">否</el-tag>
+              </span>
+              <el-image v-if="item.prop === 'T_img'" style="height: 50px" :src="row.T_img" fit="cover" />
+            </template>
+          </el-table-column>
+          <el-table-column v-if="item.ellipsis && item.prop === 'T_model'" align="center" v-bind="item">
+            <template #default="{ row }">
+              <el-tooltip effect="dark" :content="row.T_model" placement="bottom">
+                {{ row.T_model }}
+              </el-tooltip>
+            </template>
+          </el-table-column>
+          <el-table-column v-if="item.ellipsis && item.prop === 'T_remark'" align="center" v-bind="item">
+            <template #default="{ row }">
+              <el-tooltip effect="customized" placement="left">
+                <template #content>
+                  <div class="tooltip-content">{{ row.T_remark }}</div>
+                </template>
+                {{ row.T_remark }}
+              </el-tooltip>
+            </template>
+          </el-table-column>
+        </template>
+      </el-table>
+    </el-card>
+  </Drawer>
 </template>
 
-<style scoped></style>
+<style scoped lang="scss">
+.tooltip-content {
+  max-width: 500px;
+  overflow-y: auto;
+}
+.box-card {
+  height: 100%;
+  :deep(.el-card__body) {
+    height: calc(100% - 70px);
+  }
+  .sn-header {
+    display: flex;
+    justify-content: end;
+  }
+  .input-suffix {
+    width: 100%;
+    .inline-flex {
+      white-space: nowrap;
+    }
+    .d-flex {
+      display: flex;
+    }
+  }
+}
+</style>

+ 7 - 0
src/views/storehouse/inventory/InStorageSn.vue

@@ -0,0 +1,7 @@
+<script setup lang="ts"></script>
+
+<template>
+  <div></div>
+</template>
+
+<style scoped></style>

+ 0 - 2
src/views/storehouse/sales/ContractForm.vue

@@ -287,7 +287,6 @@ const querySearchAsync = async (queryString: string, cb: (arg: any) => void) =>
   clearTimeout(timeout)
   timeout = setTimeout(async () => {
     const results = await getNameAsync(queryString)
-    console.log(autoSelect, queryString)
     cb(results)
   }, 2000)
 }
@@ -304,7 +303,6 @@ const getNameAsync = async (str: string): Promise<any> => {
 }
 
 const handleSelect = (item: any) => {
-  console.log(item, autoSelect.value)
   // initParam.T_name = item.value
   getProductModelList()
 }

+ 1 - 1
src/views/workAttendance/Leave.vue

@@ -181,7 +181,7 @@ const tableRowClassName = (data: any): any => {
   }
   .info-content {
     display: flex;
-    color: #303133;
+    color: #606266;
     .info-name {
       display: flex;
       align-items: center;

+ 39 - 8
src/views/workAttendance/MyLeave.vue

@@ -5,7 +5,8 @@ import {
   Leave_Add,
   Leave_Edit,
   Leave_Del,
-  Leave_DaysOff
+  Leave_DaysOff,
+  Leave_Duration
 } from '@/api/workAttendance/index'
 import { GlobalStore } from '@/stores/index'
 import { User_List } from '@/api/user/index'
@@ -177,6 +178,17 @@ const getLeaveDaysOff = async () => {
   const res: any = await Leave_DaysOff({ User_tokey: globalStore.GET_User_tokey })
   RemainingTime.value = res.Data
 }
+// 计算请假时长
+const computedDuration = async () => {
+  if (!form.value.T_end_time) return
+  const parasm = {
+    User_tokey: globalStore.GET_User_tokey,
+    T_start_time: form.value.T_start_time,
+    T_end_time: form.value.T_end_time
+  }
+  const res: any = await Leave_Duration(parasm)
+  res.Data && (form.value.T_duration = res.Data / 60)
+}
 
 const onResize = () => {
   const height = document.documentElement.clientHeight
@@ -207,8 +219,24 @@ onMounted(() => {
         <el-tag effect="dark"> {{ getFormatDuration(row.T_duration) }} </el-tag>
       </template>
       <template #right="{ row }">
-        <el-button link type="primary" size="small" :icon="Edit" @click="openDrawerLeave('edit', row)">编辑</el-button>
-        <el-button link type="danger" size="small" :icon="Delete" @click="LeaveDelete(row)">删除</el-button>
+        <el-button
+          link
+          type="primary"
+          size="small"
+          :disabled="row.T_State === 1"
+          :icon="Edit"
+          @click="openDrawerLeave('edit', row)"
+          >编辑</el-button
+        >
+        <el-button
+          link
+          type="danger"
+          size="small"
+          :disabled="row.T_State === 1"
+          :icon="Delete"
+          @click="LeaveDelete(row)"
+          >删除</el-button
+        >
       </template>
     </TableBase>
     <Drawer ref="drawerRef" :handleClose="callbackDrawer">
@@ -231,7 +259,7 @@ onMounted(() => {
             v-model="form.T_start_time"
             type="datetime"
             placeholder="选择开始时间"
-            format="YYYY-MM-DD HH:mm:ss"
+            format="YYYY-MM-DD HH:mm"
             value-format="YYYY-MM-DD HH:mm:ss"
           />
         </el-form-item>
@@ -242,12 +270,15 @@ onMounted(() => {
             v-model="form.T_end_time"
             type="datetime"
             placeholder="选择结束时间"
-            format="YYYY-MM-DD HH:mm:ss"
+            format="YYYY-MM-DD HH:mm"
             value-format="YYYY-MM-DD HH:mm:ss"
+            @change="computedDuration"
           />
         </el-form-item>
         <el-form-item label="请假时长:" :label-width="formLabelWidth" prop="T_duration">
-          <el-input v-model="form.T_duration" autocomplete="off" placeholder="请假时长" />
+          <el-input v-model="form.T_duration" disabled placeholder="请假时长"
+            ><template #suffix> 小时 </template></el-input
+          >
         </el-form-item>
         <el-form-item label="内容:" :label-width="formLabelWidth">
           <el-input
@@ -281,9 +312,9 @@ onMounted(() => {
       >
         <template #table-header>
           <el-row :gutter="20">
-            <el-col :span="20" class="d-flex">
+            <el-col :span="24" class="d-flex">
               <span class="inline-flex">账户查询:</span>
-              <el-input v-model="search" type="text" class="w-50 m-2" />
+              <el-input v-model="search" type="text" />
               <el-button type="primary" @click="searchHandle">搜索</el-button>
             </el-col>
           </el-row>

+ 71 - 56
src/views/workAttendance/MyOvertime.vue

@@ -11,9 +11,9 @@ import { GlobalStore } from '@/stores/index'
 import Drawer from '@/components/Drawer/index.vue'
 import Dialog from '@/components/dialog/Dialog.vue'
 import { floatReg } from '@/views/salary/salary/relus'
-import { reactive, ref, nextTick } from 'vue'
+import { reactive, ref, nextTick, computed } from 'vue'
 import TableBase from '@/components/TableBase/index.vue'
-import { getFormatDuration } from '@/utils/common'
+import { getFormatDuration, dayJs } from '@/utils/common'
 import { Edit, Delete, View, Plus } from '@element-plus/icons-vue'
 import { ElMessageBox, ElMessage } from 'element-plus'
 import { ColumnProps } from '@/components/TableBase/interface/index'
@@ -21,7 +21,7 @@ import type { FormInstance, FormRules } from 'element-plus'
 import Upload from '@/components/Upload/index.vue'
 
 let uuid = ''
-let isNew = true
+let isNew = ref(true)
 const search = ref('')
 const TableStatRef = ref()
 const disabled = ref(false)
@@ -50,18 +50,48 @@ const columns_Stat: ColumnProps[] = [
   { prop: 'UpdateTime', label: '时间', ellipsis: true }
 ]
 
-const openDrawerOvertime = (str: string, row: any) => {
-  drawerRef.value && drawerRef.value.openDrawer()
-  if (str === 'edit') {
-    isNew = false
+const form = ref({
+  T_id: '',
+  T_text: '',
+  T_duration: 0,
+  T_end_time: '',
+  T_approver: '',
+  T_prove_img: '',
+  T_start_time: ''
+})
+const validate_float = (rule: any, value: any, callback: any) => {
+  if (value === '') {
+    callback(new Error('请输入加班时长'))
+  } else {
+    if (floatReg.test(value) || /\d+/.test(value)) {
+      callback()
+    } else {
+      callback(new Error('时间必须是数字或小数'))
+    }
+  }
+}
+const rules = reactive<FormRules>({
+  T_type: [{ required: true, message: '请选择请假类型', trigger: 'blur' }],
+  T_start_time: [{ required: true, message: '请选择开始时间', trigger: 'blur' }],
+  T_end_time: [{ required: true, message: '请选择结束时间', trigger: 'blur' }],
+  T_duration: [{ required: true, validator: validate_float, trigger: 'blur' }],
+  T_approver: [{ required: true, message: '请选择审批人', trigger: 'blur' }]
+})
+
+const openDrawerOvertime = (str: string, row?: any) => {
+  isNew.value = str === 'new' ? true : false
+
+  if (!isNew.value) {
     nextTick(() => {
       form.value = { ...row }
       uuid = row.T_approver
-      form.value.T_approver = row.T_user_name
+      form.value.T_approver = row.T_approver_name
       form.value.T_id = row.Id
       form.value.T_duration = row.T_duration / 60
     })
   }
+
+  drawerRef.value && drawerRef.value.openDrawer()
 }
 
 const OvertimeView = (row: any) => {
@@ -69,7 +99,7 @@ const OvertimeView = (row: any) => {
   drawerRef.value && drawerRef.value.openDrawer()
   nextTick(() => {
     form.value = { ...row }
-    form.value.T_approver = row.T_user_name
+    form.value.T_approver = row.T_approver_name
   })
 }
 const OvertimeDelete = (row: any) => {
@@ -96,19 +126,19 @@ const AddOvertime = (formEl: FormInstance | undefined) => {
   formEl.validate(async valid => {
     if (valid) {
       let res: any = {}
-      let time = form.value.T_duration * 60
-      if (isNew) {
+      let time = duration.value * 60
+      if (isNew.value) {
         res = await Overtime_Add({ ...form.value, T_approver: uuid, T_duration: time })
       } else {
         res = await Overtime_Edit({ ...form.value, T_approver: uuid, T_duration: time })
       }
       if (res.Code === 200) {
-        ElMessage.success(`${isNew ? '申请' : '修改'}成功!`)
+        ElMessage.success(`${isNew.value ? '申请' : '修改'}成功!`)
         nextTick(() => {
           drawerRef.value?.closeDrawer()
           TableRef.value?.getTableList()
           resetForm(ruleFormRef.value)
-          isNew = true
+          isNew.value = true
         })
       }
     } else {
@@ -121,7 +151,7 @@ const AddOvertime = (formEl: FormInstance | undefined) => {
 type Fn = () => void
 const callbackDrawer = (done: Fn) => {
   disabled.value = false
-  isNew = false
+  isNew.value = true
   nextTick(() => {
     resetForm(ruleFormRef.value)
     done()
@@ -129,35 +159,9 @@ const callbackDrawer = (done: Fn) => {
 }
 const resetForm = (formEl: FormInstance | undefined) => {
   if (!formEl) return
+  uploadRef.value?.clearfileList()
   formEl.resetFields()
 }
-const validate_float = (rule: any, value: any, callback: any) => {
-  if (value === '') {
-    callback(new Error('请输入加班时长'))
-  } else {
-    if (floatReg.test(value) || /\d+/.test(value)) {
-      callback()
-    } else {
-      callback(new Error('时间必须是数字或小数'))
-    }
-  }
-}
-const form = ref({
-  T_id: '',
-  T_text: '',
-  T_duration: 0,
-  T_end_time: '',
-  T_approver: '',
-  T_prove_img: '',
-  T_start_time: ''
-})
-const rules = reactive<FormRules>({
-  T_type: [{ required: true, message: '请选择请假类型', trigger: 'blur' }],
-  T_start_time: [{ required: true, message: '请选择开始时间', trigger: 'blur' }],
-  T_end_time: [{ required: true, message: '请选择结束时间', trigger: 'blur' }],
-  T_duration: [{ required: true, validator: validate_float, trigger: 'blur' }],
-  T_approver: [{ required: true, message: '请选择审批人', trigger: 'blur' }]
-})
 
 // dialog
 const Dialogcolumns: ColumnProps[] = [{ prop: 'T_name', label: '名字', name: 'T_name' }]
@@ -179,6 +183,16 @@ const getApproverInfo = (row: any) => {
   dialog.value?.DialogClose()
 }
 
+const duration = computed(() => {
+  const end_time = dayJs(form.value.T_end_time)
+  if (!form.value.T_end_time) {
+    return 0
+  }
+  let count: number = end_time.diff(form.value.T_start_time, 'hour', true)
+  let num: number = Number(count.toFixed(2))
+  return Math.round(num * 10) / 10
+})
+
 const onResize = () => {
   const height = document.documentElement.clientHeight
   return height / 2
@@ -198,7 +212,7 @@ const onResize = () => {
         <template #table-header>
           <div class="table-header">
             <h4>我的加班</h4>
-            <el-button type="primary" @click="openDrawerOvertime">申请加班</el-button>
+            <el-button type="primary" @click="openDrawerOvertime('new')">申请加班</el-button>
           </div>
         </template>
         <template #T_duration="{ row }"> {{ getFormatDuration(row.T_duration) }} </template>
@@ -226,15 +240,7 @@ const onResize = () => {
             @click="OvertimeDelete(row)"
             >删除</el-button
           >
-          <el-button
-            :disabled="row.T_State !== 1"
-            link
-            type="success"
-            size="small"
-            :icon="View"
-            @click="OvertimeView(row)"
-            >查看</el-button
-          >
+          <el-button link type="success" size="small" :icon="View" @click="OvertimeView(row)">查看</el-button>
         </template>
       </TableBase></el-col
     >
@@ -272,7 +278,7 @@ const onResize = () => {
             type="datetime"
             :disabled="disabled"
             placeholder="选择开始时间"
-            format="YYYY-MM-DD HH:mm:ss"
+            format="YYYY-MM-DD HH:mm"
             value-format="YYYY-MM-DD HH:mm:ss"
           />
         </el-form-item>
@@ -284,15 +290,24 @@ const onResize = () => {
             type="datetime"
             :disabled="disabled"
             placeholder="选择结束时间"
-            format="YYYY-MM-DD HH:mm:ss"
+            format="YYYY-MM-DD HH:mm"
             value-format="YYYY-MM-DD HH:mm:ss"
           />
         </el-form-item>
         <el-form-item label="加班时长:" :label-width="formLabelWidth" prop="T_duration">
-          <el-input v-model.number="form.T_duration" autocomplete="off" placeholder="请假时长" />
+          <el-input v-model="duration" autocomplete="off" placeholder="请假时长">
+            <template #suffix> 小时 </template>
+          </el-input>
         </el-form-item>
-        <el-form-item label="取证:" :label-width="formLabelWidth">
-          <Upload ref="uploadRef" :isImg="true" :limit="1" v-model="form.T_prove_img" accept="image/*">
+        <el-form-item label="取证:" :label-width="formLabelWidth" prop="T_prove_img">
+          <Upload
+            ref="uploadRef"
+            :isImg="true"
+            :limit="1"
+            v-model="form.T_prove_img"
+            :disabled="disabled"
+            accept="image/*"
+          >
             <el-icon><Plus /></el-icon>
           </Upload>
         </el-form-item>

+ 1 - 1
src/views/workAttendance/Overtime.vue

@@ -216,7 +216,7 @@ const tableRowClassName = (data: any): any => {
   }
   .info-content {
     display: flex;
-    color: #303133;
+    color: #606266;
     .info-name {
       display: flex;
       // flex-direction: column;

+ 135 - 9
src/views/workAttendance/RecordsFinance.vue

@@ -1,18 +1,24 @@
 <script setup lang="ts">
-import { ElMessage } from 'element-plus'
 import { User_List } from '@/api/user/index'
 import { GlobalStore } from '@/stores/index'
 import { getFormatDuration } from '@/utils/common'
+import Drawer from '@/components/Drawer/index.vue'
 import TableBase from '@/components/TableBase/index.vue'
-import { Leave_Finance_List } from '@/api/workAttendance/index'
-import { ref, reactive, onMounted, computed, onUnmounted } from 'vue'
+import type { FormInstance, FormRules } from 'element-plus'
+import { ElMessage, ElMessageBox } from 'element-plus'
 import { ColumnProps } from '@/components/TableBase/interface/index'
 import Pagination from '@/components/TableBase/components/Pagination.vue'
+import { ref, reactive, onMounted, computed, onUnmounted, nextTick } from 'vue'
+import { Leave_Finance_List, Leave_Deduct, LeaveType_List } from '@/api/workAttendance/index'
 
 const TableData = ref()
+const LeaveType = ref<any[]>([])
 const globalStore = GlobalStore()
+const ruleFormRef = ref<FormInstance>()
 const initParam = { User_tokey: globalStore.GET_User_tokey }
+const drawerRef = ref<InstanceType<typeof Drawer> | null>(null)
 const LeaveTableRef = ref<InstanceType<typeof TableBase> | null>(null)
+
 let date = new Date()
 const month = date.getMonth()
 const year = date.getFullYear()
@@ -88,11 +94,6 @@ const getTableData = async () => {
 }
 onMounted(async () => {
   await getTableData()
-  // let userInfoFirst = TableData.value[0]
-  // LeaveinitParam.T_uuid = userInfoFirst.T_uuid
-  // userInfo.name = userInfoFirst.T_name
-  // userInfo.T_dept = userInfoFirst.T_dept_name
-  // userInfo.T_post = userInfoFirst.T_post_name
 })
 const pageable = reactive({
   pageNum: 1,
@@ -137,6 +138,92 @@ const tableRowClassName = (data: any): any => {
     return ''
   }
 }
+
+const dataCallback = (res: any): any => {
+  return res.Data.Data.filter((item: any) => item.T_approver)
+}
+
+// drawer
+const form = reactive({
+  T_type: '',
+  T_duration: 0,
+  hover: 0,
+  minute: 0,
+  T_text: ''
+})
+
+const duration = computed(() => {
+  return form.hover * 60 + form.minute
+})
+
+const rules = reactive<FormRules>({
+  T_type: [{ required: true, message: '请选择扣除类型', trigger: 'blur' }],
+  T_duration: [{ required: true, message: '请输入扣除时长', trigger: 'blur' }],
+  T_text: [{ required: true, message: '请输入扣除理由', trigger: 'blur' }]
+})
+
+type Fn = () => void
+const Deductduraton = async () => {
+  !LeaveType.value.length && getLeaveTypeList()
+  drawerRef.value?.openDrawer()
+}
+const getLeaveTypeList = async () => {
+  const res: any = await LeaveType_List({ User_tokey: globalStore.GET_User_tokey, T_deduct: 1 })
+  if (res.Code === 200) {
+    LeaveType.value = res.Data
+  }
+}
+const callbackDrawer = (done: Fn) => {
+  nextTick(() => {
+    resetForm(ruleFormRef.value)
+    done()
+  })
+}
+const resetForm = (formEl: FormInstance | undefined) => {
+  if (!formEl) return
+  form.hover = 0
+  form.minute = 0
+  formEl.resetFields()
+}
+
+const AddLeave = (formEl: FormInstance | undefined) => {
+  if (!formEl) return
+  form.T_duration = duration.value
+  formEl.validate(async valid => {
+    if (valid) {
+      open()
+    }
+  })
+}
+
+const open = () => {
+  ElMessageBox.confirm('确定扣除?扣除后无法修改?', '警告', {
+    confirmButtonText: '确定',
+    cancelButtonText: '取消',
+    type: 'warning'
+  })
+    .then(async () => {
+      const params = {
+        User_tokey: globalStore.GET_User_tokey,
+        T_type: form.T_type,
+        T_duration: form.T_duration,
+        T_text: form.T_text,
+        T_uuid: LeaveinitParam.T_uuid,
+        T_month: dateCom.value
+      }
+      const res: any = await Leave_Deduct(params)
+      if (res.Code === 200) {
+        ElMessage.success('扣除成功!')
+        nextTick(() => {
+          drawerRef.value?.closeDrawer()
+          resetForm(ruleFormRef.value)
+        })
+      }
+    })
+    .catch(() => {
+      ElMessage.info('取消成功!')
+    })
+}
 </script>
 
 <template>
@@ -205,6 +292,9 @@ const tableRowClassName = (data: any): any => {
                   @change="salarDateMonthChange"
                 />
               </el-col>
+              <el-col :span="12" class="d-flex justify-end">
+                <el-button type="primary" @click="Deductduraton">扣除时长</el-button>
+              </el-col>
             </el-row>
           </el-card>
           <div :style="{ height: clientHeight + 'px' }">
@@ -217,6 +307,7 @@ const tableRowClassName = (data: any): any => {
               layout="total,prev, pager, next"
               :onResize="onResize"
               :displayHeader="true"
+              :dataCallback="dataCallback"
             >
               <template #T_duration="{ row }">{{ getFormatDuration(row.T_duration) }}</template>
               <template #T_State="{ row }">
@@ -229,6 +320,38 @@ const tableRowClassName = (data: any): any => {
         </el-col>
       </el-row>
     </transition>
+    <Drawer ref="drawerRef" :handleClose="callbackDrawer">
+      <template #header="{ params }">
+        <h4 :id="params.titleId" :class="params.titleClass">扣除时长</h4>
+      </template>
+      <el-form ref="ruleFormRef" :model="form" :rules="rules">
+        <el-form-item label="扣除类型:" label-width="100px" prop="T_type">
+          <el-select v-model="form.T_type" placeholder="请选择扣除类型">
+            <el-option v-for="item in LeaveType" :key="item.Id" :label="item.T_name" :value="item.Id" />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="扣除时长:" label-width="100px" prop="T_duration">
+          <div class="d-flex">
+            <el-input type="text" v-model.number="form.hover"><template #suffix> 小时 </template></el-input
+            ><el-input type="text" v-model.number="form.minute">
+              <template #suffix> 分钟 </template>
+            </el-input>
+          </div>
+        </el-form-item>
+        <el-form-item label="扣除理由:" label-width="100px" prop="T_text">
+          <el-input
+            v-model="form.T_text"
+            autocomplete="off"
+            type="textarea"
+            :autosize="{ minRows: 4, maxRows: 6 }"
+            placeholder="请输入扣除理由"
+          />
+        </el-form-item>
+        <div class="d-flex">
+          <el-button type="primary" @click="AddLeave(ruleFormRef)">提交</el-button>
+        </div>
+      </el-form>
+    </Drawer>
   </div>
 </template>
 
@@ -250,6 +373,9 @@ const tableRowClassName = (data: any): any => {
 .justify-start {
   justify-content: start;
 }
+.justify-end {
+  justify-content: end;
+}
 .input-suffix {
   width: 100%;
   flex-direction: column;
@@ -267,7 +393,7 @@ const tableRowClassName = (data: any): any => {
 }
 .info-content {
   display: flex;
-  color: #303133;
+  color: #606266;
   .info-name {
     display: flex;
     flex-direction: column;

+ 1 - 1
src/views/workAttendance/records/index.scss

@@ -38,7 +38,7 @@
   }
   .info-content {
     display: flex;
-    color: #303133;
+    color: #606266;
     .info-name {
       display: flex;
       flex-direction: column;

+ 16 - 16
vite.config.ts

@@ -22,22 +22,22 @@ export default defineConfig(({ mode }: ConfigEnv): UserConfig => {
     },
     server: {
       open: true,
-      host: '0.0.0.0',
-      proxy: {
-        '/api': {
-          target: 'https://erp.baozhida.cn',
-          changeOrigin: true,
-          rewrite: path => path.replace(/^\/api/, '/testapi')
-        },
-        '/testapi': {
-          target: 'https://erp.baozhida.cn',
-          changeOrigin: true
-        },
-        '/ams': {
-          target: 'http://erp.baozhida.cn',
-          changeOrigin: true
-        }
-      }
+      host: '0.0.0.0'
+      // proxy: {
+      //   '/api': {
+      //     target: 'https://erp.baozhida.cn',
+      //     changeOrigin: true,
+      //     rewrite: path => path.replace(/^\/api/, '/testapi')
+      //   },
+      //   '/testapi': {
+      //     target: 'https://erp.baozhida.cn',
+      //     changeOrigin: true
+      //   },
+      //   '/ams': {
+      //     target: 'http://erp.baozhida.cn',
+      //     changeOrigin: true
+      //   }
+      // }
     },
     plugins: [
       vue(),