Преглед изворни кода

优化考勤新增弹窗的自动带出逻辑

zhonghuizhen пре 6 часа
родитељ
комит
d1200d6f65
1 измењених фајлова са 233 додато и 101 уклоњено
  1. 233 101
      src/views/business/attendance/attendanceDetails.vue

+ 233 - 101
src/views/business/attendance/attendanceDetails.vue

@@ -90,13 +90,6 @@
             label="排班类型"
             width="140"
           />
-          <!--
-          <el-table-column
-            key="banCiBieMing"
-            prop="banCiBieMing"
-            label="班次别名"
-            width="100"
-          />-->
         </el-table-column>
         <el-table-column key="riQi" prop="riQi" label="日期" width="90" />
         <!-- 上班分组 -->
@@ -249,7 +242,7 @@
             style="width: 100%"
           />
         </el-form-item>
-        <!-- 排班类型改为下拉选择,选项从接口动态加载 -->
+        <!-- 排班类型下拉(编辑弹窗使用,全局加载) -->
         <el-form-item label="排班类型" prop="banCiMing">
           <el-select
             v-model="editForm.banCiMing"
@@ -308,7 +301,13 @@
           />
         </el-form-item>
         <el-form-item label="部门" prop="buMen">
-          <el-select v-model="addForm.buMen" placeholder="请选择部门" clearable style="width: 100%">
+          <el-select
+            v-model="addForm.buMen"
+            placeholder="请选择部门"
+            clearable
+            style="width: 100%"
+            @change="handleDeptChange"
+          >
             <el-option
               v-for="item in deptOption"
               :key="item.value"
@@ -317,16 +316,45 @@
             />
           </el-select>
         </el-form-item>
+        <!-- 配置名称下拉(根据部门过滤) -->
         <el-form-item label="配置名称" prop="paiBanMingChen">
-          <el-input v-model="addForm.paiBanMingChen" placeholder="请输入排班配置名称" />
+          <el-select
+            v-model="addForm.paiBanMingChen"
+            placeholder="请选择配置名称"
+            clearable
+            filterable
+            style="width: 100%"
+            :loading="configLoading"
+            @change="handleConfigChange"
+          >
+            <el-option
+              v-for="item in configNameOptions"
+              :key="item.value"
+              :label="item.label"
+              :value="item.value"
+            />
+          </el-select>
         </el-form-item>
+        <!-- 排班类型下拉(根据部门过滤) -->
         <el-form-item label="排班类型" prop="banCiMing">
-          <el-input v-model="addForm.banCiMing" placeholder="请输入班次名称" />
+          <el-select
+            v-model="addForm.banCiMing"
+            placeholder="请选择排班类型"
+            clearable
+            filterable
+            style="width: 100%"
+            :loading="configLoading"
+          >
+            <el-option
+              v-for="item in scheduleTypeOptions"
+              :key="item.value"
+              :label="item.label"
+              :value="item.value"
+            />
+          </el-select>
         </el-form-item>
         <el-form-item label="补卡类型" prop="clockType">
-          <el-select v-model="addForm.clockType" placeholder="请选择补卡类型" clearable style="width: 100%">
-            <el-option label="上班卡" value="1" />
-            <el-option label="下班卡" value="2" />
+          <el-select disabled v-model="addForm.clockType" placeholder="请选择补卡类型" clearable style="width: 100%">
             <el-option label="补卡" value="3" />
           </el-select>
         </el-form-item>
@@ -338,10 +366,10 @@
             value-format="yyyy-MM-dd"
             style="width: 100%"
             :picker-options="pickerOptions"
+            @change="handleDateChange"
           />
         </el-form-item>
-        <!-- 动态显示打卡时间字段 -->
-        <el-form-item v-if="addForm.clockType === '1' || addForm.clockType === '3'" label="上班打卡时间" prop="daKaShiJian1">
+        <el-form-item label="上班打卡时间" prop="daKaShiJian1">
           <el-date-picker
             v-model="addForm.daKaShiJian1"
             type="datetime"
@@ -350,7 +378,7 @@
             style="width: 100%"
           />
         </el-form-item>
-        <el-form-item v-if="addForm.clockType === '2' || addForm.clockType === '3'" label="下班打卡时间" prop="daKaShiJian2">
+        <el-form-item label="下班打卡时间" prop="daKaShiJian2">
           <el-date-picker
             v-model="addForm.daKaShiJian2"
             type="datetime"
@@ -372,7 +400,6 @@
 
 <script>
 import { queryAttendanceDetail, gdUpdateAttendce, removeAttendanceDetail, gdClockIn } from '@/api/business/attendance'
-// 引入班次配置查询接口
 import { queryScheduleConfigItem } from '@/api/business/schedule'
 import ibpsUserSelector from '@/business/platform/org/selector'
 import FixHeight from '@/mixins/height'
@@ -398,7 +425,7 @@ export default {
       userOption,
       deptOption,
       title: '考勤明细',
-      pkKey: 'id', // 主键对应数据库字段
+      pkKey: 'id',
       loading: true,
       height: document.clientHeight,
       listData: [],
@@ -419,13 +446,12 @@ export default {
           userType: 'position'
         }
       ],
-      sorts:{
-            "ri_qi_": "DESC"
-        },
+      sorts: {
+        'ri_qi_': 'DESC'
+      },
       editFormRules: {
         beiZhu: [
           { required: true, message: '请输入备注信息', trigger: 'blur' }
-          // 可选:还可以增加其他规则,如最小长度等
         ]
       },
       daterRange: [],
@@ -434,7 +460,6 @@ export default {
         disabledDate(time) {
           const today = new Date()
           today.setHours(0, 0, 0, 0)
-          // 禁用今天及未来的日期
           return time.getTime() > today.getTime()
         }
       },
@@ -487,7 +512,6 @@ export default {
             },
             { prop: 'Q^pai_ban_ming_chen^SL', label: '配置名称' },
             { prop: 'Q^ban_ci_ming_^SL', label: '排班类型' },
-            //{ prop: 'Q^ban_ci_bie_ming_^SL', label: '班次别名' },
             {
               prop: '',
               label: '日期范围',
@@ -500,17 +524,15 @@ export default {
       },
       // 编辑弹窗相关
       editDialogVisible: false,
-      currentEditRow: null,      // 当前正在编辑的行数据
+      currentEditRow: null,
       editForm: {
         id: '',
         daKaShiJian1: '',
         daKaShiJian2: '',
         beiZhu: '',
-        banCiMing: ''          // 排班类型
-        // 注意:kaoQinZhuangTa 不存储在表单中,提交时固定为 '正常'
+        banCiMing: ''
       },
       saveLoading: false,
-      // 排班类型下拉选项
       banCiOptions: [],
       banCiOptionsLoading: false,
       // 新增弹窗相关
@@ -521,22 +543,22 @@ export default {
         paiBanMingChen: '',
         banCiMing: '',
         buMen: '',
-        clockType: '',
+        clockType: '3',
         daKaShiJian1: '',
         daKaShiJian2: '',
         riQi: ''
       },
       addFormRules: {
         yongHuId: [{ required: true, message: '请选择用户', trigger: 'change' }],
-        paiBanMingChen: [{ required: true, message: '请输入配置名称', trigger: 'blur' }],
-        banCiMing: [{ required: true, message: '请输入排班类型', trigger: 'blur' }],
+        paiBanMingChen: [{ required: true, message: '请选择配置名称', trigger: 'change' }],
+        banCiMing: [{ required: true, message: '请选择排班类型', trigger: 'change' }],
         buMen: [{ required: true, message: '请选择部门', trigger: 'change' }],
         clockType: [{ required: true, message: '请选择补卡类型', trigger: 'change' }],
         riQi: [{ required: true, message: '请选择日期', trigger: 'change' }],
         daKaShiJian1: [
           {
             validator: (rule, value, callback) => {
-              if ((this.addForm.clockType === '1' || this.addForm.clockType === '3') && !value) {
+              if (this.addForm.clockType === '3' && !value) {
                 callback(new Error('上班打卡时间不能为空'))
               } else {
                 callback()
@@ -548,7 +570,7 @@ export default {
         daKaShiJian2: [
           {
             validator: (rule, value, callback) => {
-              if ((this.addForm.clockType === '2' || this.addForm.clockType === '3') && !value) {
+              if (this.addForm.clockType === '3' && !value) {
                 callback(new Error('下班打卡时间不能为空'))
               } else {
                 callback()
@@ -557,35 +579,37 @@ export default {
             trigger: 'blur'
           }
         ]
-      }
+      },
+      // 配置相关(新增弹窗)
+      configList: [],
+      selectedConfig: null,
+      configNameOptions: [],
+      scheduleTypeOptions: [],
+      configLoading: false
     }
   },
   computed: {
     computedDateRange: {
       get() {
-        return this.daterRange;
+        return this.daterRange
       },
       set(newValue) {
-        this.daterRange = newValue || [];
+        this.daterRange = newValue || []
       }
     },
-    // 判断当前用户是否为质量负责人
-    isQualityManager() {      
+    isQualityManager() {
       const userInfo = this.$store.getters.userInfo
       return userInfo.role.some(role => role.alias === 'zlfzr') || userInfo.role.some(role => role.alias === 'xtgljs')
     },
-    // 动态工具栏(根据权限添加新增按钮)
     finalToolbars() {
       const toolbars = [...this.listConfig.toolbars]
       if (this.isQualityManager) {
-        // 在查询按钮之后,导出之前插入新增按钮(可根据需求调整顺序)
         const addBtn = {
           key: 'add',
           icon: 'ibps-icon-add',
           label: '新增',
           type: 'success'
         }
-        // 插入到第二个位置(查询之后,导出之前)
         toolbars.splice(1, 0, addBtn)
       }
       return toolbars
@@ -606,9 +630,9 @@ export default {
               item.userName = this.getUserLabel(item.yongHuId)
               item.deptName = this.getDeptLabel(item.buMen)
               if (item.kaoQinZhuangTa === '') {
-                if(item.banCiMing == '休息'){
+                if (item.banCiMing == '休息') {
                   item.kaoQinZhuangTa = '无需打卡'
-                }else{
+                } else {
                   item.kaoQinZhuangTa = '异常'
                 }
               }
@@ -628,9 +652,6 @@ export default {
       const dept = this.deptOption.find((item) => item.value === positionId)
       return dept ? dept.label : ''
     },
-    /**
-     * 获取格式化参数
-     */
     getSearchFormData() {
       const { first, second } = this.$store.getters.level || {}
       const searchParam = this.$refs['crud']
@@ -647,7 +668,6 @@ export default {
       }
       return ActionUtils.formatParams(searchParam, this.pagination, this.sorts)
     },
-    // 分页/排序处理
     handlePaginationChange(page) {
       ActionUtils.setPagination(this.pagination, page)
       this.loadData()
@@ -656,8 +676,6 @@ export default {
       ActionUtils.setSorts(this.sorts, sort)
       this.loadData()
     },
-
-    // 操作处理
     handleAction(command, _, selection) {
       switch (command) {
         case 'search':
@@ -675,13 +693,11 @@ export default {
           break
       }
     },
-     // 删除记录
-     handleRemove(selection) {
+    handleRemove(selection) {
       if (!selection || selection.length === 0) {
         ActionUtils.warning('请至少选择一条记录')
         return
       }
-      //const ids = selection.map(item => item[this.pkKey])
       const ids = selection
       this.$confirm(`确定要删除选中的 ${selection.length} 条考勤明细吗?`, '提示', {
         confirmButtonText: '确定',
@@ -689,13 +705,9 @@ export default {
         type: 'warning'
       }).then(() => {
         this.loading = true
-        console.log('删除传参数据:',ids)
-        
-        removeAttendanceDetail( { ids: ids }).then(() => {
+        removeAttendanceDetail({ ids: ids }).then(() => {
           ActionUtils.success('删除成功')
-          // 刷新列表
           this.loadData()
-          // 清空选中
           if (this.$refs.crud && this.$refs.crud.clearSelection) {
             this.$refs.crud.clearSelection()
           }
@@ -706,19 +718,13 @@ export default {
         })
       }).catch(() => {})
     },
-    // 导出数据
     exportData() {
       const exportColumns = [
         { field_name: 'userName', label: '姓名', name: 'userName' },
         { field_name: 'deptName', label: '部门', name: 'deptName' },
         { field_name: 'gongHao', label: '工号', name: 'gongHao' },
-        {
-          field_name: 'paiBanMingChen',
-          label: '配置名称',
-          name: 'paiBanMingChen'
-        },
+        { field_name: 'paiBanMingChen', label: '配置名称', name: 'paiBanMingChen' },
         { field_name: 'banCiMing', label: '排班类型', name: 'banCiMing' },
-        //{ field_name: 'banCiBieMing', label: '班次别名', name: 'banCiBieMing' },
         { field_name: 'riQi', label: '日期', name: 'riQi' },
         { field_name: 'daKaShiJian1', label: '上班打卡时间', name: 'daKaShiJian1' },
         { field_name: 'zhuangTai1', label: '上班打卡状态', name: 'zhuangTai1' },
@@ -728,24 +734,25 @@ export default {
         { field_name: 'daKaCiShu', label: '打卡次数', name: 'daKaCiShu' },
         { field_name: 'kaoQinZhuangTa', label: '考勤状态', name: 'kaoQinZhuangTa' }
       ]
-      this.handleExport(exportColumns, this.listData, `考勤明细统计数据`)
+      this.handleExport(exportColumns, this.listData, '考勤明细统计数据')
     },
-    getToday(){
+    getToday() {
       const date = new Date(this.$common.getDateNow())
       date.setDate(date.getDate())
       return date.toISOString().split('T')[0]
     },
     getPrevDateString(riqi) {
       const previousDay = new Date(riqi)
-      previousDay.setDate(previousDay.getDate() - 1);
-      return [previousDay.getFullYear(),
-                String(previousDay.getMonth() + 1).padStart(2, '0'),
-                String(previousDay.getDate()).padStart(2, '0')
-            ].join('-')
+      previousDay.setDate(previousDay.getDate() - 1)
+      return [
+        previousDay.getFullYear(),
+        String(previousDay.getMonth() + 1).padStart(2, '0'),
+        String(previousDay.getDate()).padStart(2, '0')
+      ].join('-')
     },
     formatDateTime(row, column, cellValue) {
-      if (!cellValue) return '';
-      return cellValue.substring(0, 16);
+      if (!cellValue) return ''
+      return cellValue.substring(0, 16)
     },
     handleExport(columns, data, title, message, nameKey = 'name') {
       IbpsExport.excel({
@@ -759,19 +766,18 @@ export default {
       })
     },
 
-    // ========= 加载排班类型下拉选项 =========
+    // ========= 加载排班类型下拉选项(编辑弹窗使用) =========
     async loadBanCiOptions() {
       this.banCiOptionsLoading = true
       try {
         const res = await queryScheduleConfigItem({
           pageNo: 1,
-          limit: 999, // 获取全部生效配置
+          limit: 999,
           param: {
-            shengXiaoBiaoZhi: 'Y'  // 只查询生效的
+            shengXiaoBiaoZhi: 'Y'
           }
         })
         const list = res.data.dataResult || []
-        // 提取所有排班类型(去重)
         const typeSet = new Set()
         list.forEach(item => {
           if (item.paiBanLeiXing) {
@@ -790,9 +796,139 @@ export default {
       }
     },
 
-    // ========= 编辑上下班时间相关方法 =========
+    // ========= 新增:根据部门加载配置列表(按编制部门过滤) =========
+    async loadConfigsByDept(deptId) {
+      if (!deptId) {
+        this.configList = []
+        this.configNameOptions = []
+        this.scheduleTypeOptions = []
+        this.selectedConfig = null
+        return
+      }
+      this.configLoading = true
+      try {
+        const res = await queryScheduleConfigItem({
+          pageNo: 1,
+          limit: 999,
+          param: {
+            bianZhiBuMeng: deptId,    // 使用编制部门字段过滤
+            shengXiaoBiaoZhi: 'Y'
+          }
+        })
+        const list = res.data.dataResult || []
+        this.configList = list
+
+        this.configNameOptions = list.map(item => ({
+          label: item.peiZhiMingChen,
+          value: item.id
+        }))
+
+        const typeSet = new Set()
+        list.forEach(item => {
+          if (item.paiBanLeiXing) {
+            typeSet.add(item.paiBanLeiXing)
+          }
+        })
+        this.scheduleTypeOptions = Array.from(typeSet).map(type => ({
+          label: type,
+          value: type
+        }))
+
+        // 如果当前已有选中配置且编制部门匹配,则保留;否则清空
+        if (this.selectedConfig && this.selectedConfig.bianZhiBuMen === deptId) {
+          // 保持选中
+        } else {
+          this.selectedConfig = null
+          this.addForm.paiBanMingChen = ''
+          this.addForm.banCiMing = ''
+          this.addForm.daKaShiJian1 = ''
+          this.addForm.daKaShiJian2 = ''
+        }
+      } catch (error) {
+        console.error('加载配置列表失败', error)
+        this.configList = []
+        this.configNameOptions = []
+        this.scheduleTypeOptions = []
+      } finally {
+        this.configLoading = false
+      }
+    },
+
+    // ========= 部门变更处理 =========
+    handleDeptChange(deptId) {
+      this.addForm.paiBanMingChen = ''
+      this.addForm.banCiMing = ''
+      this.addForm.daKaShiJian1 = ''
+      this.addForm.daKaShiJian2 = ''
+      this.selectedConfig = null
+      this.loadConfigsByDept(deptId)
+    },
+
+    // ========= 配置名称变更处理 =========
+    handleConfigChange(configId) {
+      if (!configId) {
+        this.selectedConfig = null
+        this.addForm.banCiMing = ''
+        this.addForm.daKaShiJian1 = ''
+        this.addForm.daKaShiJian2 = ''
+        return
+      }
+      const config = this.configList.find(item => item.id === configId)
+      if (config) {
+        this.selectedConfig = config
+        this.addForm.banCiMing = config.paiBanLeiXing || ''
+        if (this.addForm.riQi) {
+          this.fillClockTime()
+        } else {
+          this.addForm.daKaShiJian1 = ''
+          this.addForm.daKaShiJian2 = ''
+        }
+      } else {
+        this.selectedConfig = null
+        this.addForm.banCiMing = ''
+        this.addForm.daKaShiJian1 = ''
+        this.addForm.daKaShiJian2 = ''
+      }
+    },
+
+    // ========= 日期变更处理 =========
+    handleDateChange(date) {
+      if (date && this.selectedConfig) {
+        this.fillClockTime()
+      } else {
+        this.addForm.daKaShiJian1 = ''
+        this.addForm.daKaShiJian2 = ''
+      }
+    },
+
+    // ========= 根据日期和配置自动填充上下班打卡时间 =========
+    fillClockTime() {
+      if (!this.selectedConfig || !this.addForm.riQi) {
+        return
+      }
+      const config = this.selectedConfig
+      const dateStr = this.addForm.riQi
+      if (config.shangBanShiJian) {
+        this.addForm.daKaShiJian1 = `${dateStr} ${config.shangBanShiJian}:00`
+      } else {
+        this.addForm.daKaShiJian1 = ''
+      }
+      if (config.xiaBanShiJian) {
+        let dateObj = new Date(dateStr)
+        if (config.shiFouKuaRi === 'Y') {
+          dateObj.setDate(dateObj.getDate() + 1)
+        }
+        const year = dateObj.getFullYear()
+        const month = String(dateObj.getMonth() + 1).padStart(2, '0')
+        const day = String(dateObj.getDate()).padStart(2, '0')
+        this.addForm.daKaShiJian2 = `${year}-${month}-${day} ${config.xiaBanShiJian}:00`
+      } else {
+        this.addForm.daKaShiJian2 = ''
+      }
+    },
+
+    // ========= 编辑上下班时间 =========
     async openEditDialog(row) {
-      // 先加载选项,再打开弹窗
       await this.loadBanCiOptions()
       this.currentEditRow = row
       this.editForm = {
@@ -800,10 +936,9 @@ export default {
         daKaShiJian1: row.daKaShiJian1 || '',
         daKaShiJian2: row.daKaShiJian2 || '',
         beiZhu: row.beiZhu || '',
-        banCiMing: row.banCiMing || ''   // 回填当前排班类型
+        banCiMing: row.banCiMing || ''
       }
       this.editDialogVisible = true
-      // 清除残留的校验样式和提示
       this.$nextTick(() => {
         if (this.$refs.editFormRef) {
           this.$refs.editFormRef.clearValidate()
@@ -820,25 +955,23 @@ export default {
         if (!valid) return
         if (!this.currentEditRow) return
         this.saveLoading = true
-        // 调用 gdUpdateAttendce 接口,传递需要更新的字段
         const postData = {
           id: this.editForm.id,
           daKaShiJian1: this.editForm.daKaShiJian1,
           daKaShiJian2: this.editForm.daKaShiJian2,
           beiZhu: this.editForm.beiZhu,
           banCiMing: this.editForm.banCiMing,
-          kaoQinZhuangTa: '正常'   // 强制设置为正常
+          kaoQinZhuangTa: '正常'
         }
         gdUpdateAttendce(postData)
           .then(() => {
             this.$message.success('修改成功')
             this.editDialogVisible = false
-            // 刷新列表以显示最新数据
             this.loadData()
           })
           .catch((err) => {
             console.error(err)
-            if(!err.cause){
+            if (!err.cause) {
               this.$message.error('修改异常')
             }
           })
@@ -848,18 +981,22 @@ export default {
       })
     },
 
-    // ========= 新增考勤记录相关方法 =========
+    // ========= 新增考勤记录 =========
     openAddDialog() {
       this.addForm = {
         yongHuId: '',
         paiBanMingChen: '',
         banCiMing: '',
         buMen: '',
-        clockType: '',
+        clockType: '3',
         daKaShiJian1: '',
         daKaShiJian2: '',
         riQi: ''
       }
+      this.configList = []
+      this.configNameOptions = []
+      this.scheduleTypeOptions = []
+      this.selectedConfig = null
       this.addDialogVisible = true
       this.$nextTick(() => {
         if (this.$refs.addFormRef) {
@@ -874,18 +1011,21 @@ export default {
         paiBanMingChen: '',
         banCiMing: '',
         buMen: '',
-        clockType: '',
+        clockType: '3',
         daKaShiJian1: '',
         daKaShiJian2: '',
         riQi: ''
       }
+      this.configList = []
+      this.configNameOptions = []
+      this.scheduleTypeOptions = []
+      this.selectedConfig = null
     },
     saveAddRecord() {
       this.$refs.addFormRef.validate((valid) => {
         if (!valid) return
         this.addLoading = true
 
-        // 构建请求参数,只根据 clockType 传递必要字段
         const postData = {
           yongHuId: this.addForm.yongHuId,
           paiBanMingChen: this.addForm.paiBanMingChen,
@@ -894,20 +1034,13 @@ export default {
           clockType: this.addForm.clockType,
           riQi: this.addForm.riQi
         }
-
-        // 根据补卡类型添加对应时间字段
-        if (this.addForm.clockType === '1' || this.addForm.clockType === '3') {
-          postData.daKaShiJian1 = this.addForm.daKaShiJian1
-        }
-        if (this.addForm.clockType === '2' || this.addForm.clockType === '3') {
-          postData.daKaShiJian2 = this.addForm.daKaShiJian2
-        }
+        postData.daKaShiJian1 = this.addForm.daKaShiJian1
+        postData.daKaShiJian2 = this.addForm.daKaShiJian2
 
         gdClockIn(postData)
           .then(() => {
             this.$message.success('新增考勤记录成功')
             this.addDialogVisible = false
-            // 刷新列表
             this.loadData()
           })
           .catch((err) => {
@@ -925,7 +1058,7 @@ export default {
 
 <style scoped>
 .el-dialog__wrapper .el-dialog__body {
-    padding: 15px !important;
+  padding: 15px !important;
 }
 .main-container {
   padding: 20px;
@@ -933,7 +1066,6 @@ export default {
   border-radius: 4px;
   box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
 }
-
 ::v-deep .el-table {
   .el-table__column[prop='bu_men_'] {
     min-width: 200px;