From c8b65690b946b28b179796fbe2f020e732043c58 Mon Sep 17 00:00:00 2001
From: 张诺 <zhang_12370@163.com>
Date: 星期四, 08 一月 2026 18:10:16 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/dev_天津军泰伟业' into dev_天津军泰伟业

---
 src/views/collaborativeApproval/attendanceManagement/index.vue | 1859 +++++++++++++++++++++++++++++++++++++++++------------------
 1 files changed, 1,283 insertions(+), 576 deletions(-)

diff --git a/src/views/collaborativeApproval/attendanceManagement/index.vue b/src/views/collaborativeApproval/attendanceManagement/index.vue
index 37b3d59..97dd549 100644
--- a/src/views/collaborativeApproval/attendanceManagement/index.vue
+++ b/src/views/collaborativeApproval/attendanceManagement/index.vue
@@ -1,254 +1,419 @@
 <template>
   <div class="app-container">
-    <el-tabs v-model="activeTab" type="border-card">
+    <el-tabs v-model="activeTab"
+             type="border-card">
       <!-- 鍋囨湡璁剧疆 -->
-      <el-tab-pane label="鍋囨湡璁剧疆" name="holiday">
+      <el-tab-pane label="鍋囨湡璁剧疆"
+                   name="holiday">
         <div class="tab-content">
-          <el-button type="primary" @click="openDialog('holiday', 'add')">鏂板鍋囨湡</el-button>
-          
-          <el-table :data="holidayData" border style="width: 100%; margin-top: 20px;">
-            <el-table-column prop="name" label="鍋囨湡鍚嶇О" />
-            <el-table-column prop="type" label="鍋囨湡绫诲瀷">
+          <el-button type="primary"
+                     @click="openDialog('holiday', 'add')">鏂板鍋囨湡</el-button>
+          <el-table :data="holidayData"
+                    border
+                    style="width: 100%; margin-top: 20px;">
+            <el-table-column prop="name"
+                             label="鍋囨湡鍚嶇О" />
+            <el-table-column prop="type"
+                             label="鍋囨湡绫诲瀷">
               <template #default="scope">
                 <el-tag :type="getTagType(scope.row.type)">{{ getTypeLabel(scope.row.type) }}</el-tag>
               </template>
             </el-table-column>
-            <el-table-column prop="startDate" label="寮�濮嬫棩鏈�"  />
-            <el-table-column prop="endDate" label="缁撴潫鏃ユ湡"  />
-            <el-table-column prop="days" label="澶╂暟"  align="center" />
-            <el-table-column prop="status" label="鐘舵��" >
+            <el-table-column prop="startDate"
+                             label="寮�濮嬫棩鏈�" />
+            <el-table-column prop="endDate"
+                             label="缁撴潫鏃ユ湡" />
+            <el-table-column prop="days"
+                             label="澶╂暟"
+                             align="center" />
+            <el-table-column prop="status"
+                             label="鐘舵��">
               <template #default="scope">
                 <el-tag :type="scope.row.status === 'active' ? 'success' : 'info'">
                   {{ scope.row.status === 'active' ? '鍚敤' : '鍋滅敤' }}
                 </el-tag>
               </template>
             </el-table-column>
-            <el-table-column label="鎿嶄綔" fixed="right">
+            <el-table-column label="鎿嶄綔"
+                             fixed="right">
               <template #default="scope">
-                <el-button type="primary" size="small" @click="openDialog('holiday', 'edit', scope.row)">缂栬緫</el-button>
-                <el-button type="danger" size="small" @click="deleteItem('holiday', scope.row)">鍒犻櫎</el-button>
+                <el-button type="primary"
+                           size="small"
+                           @click="openDialog('holiday', 'edit', scope.row)">缂栬緫</el-button>
+                <el-button type="danger"
+                           size="small"
+                           @click="deleteItem('holiday', scope.row)">鍒犻櫎</el-button>
               </template>
             </el-table-column>
           </el-table>
         </div>
       </el-tab-pane>
-
       <!-- 骞村亣璁剧疆 -->
-      <el-tab-pane label="骞村亣璁剧疆" name="annual">
+      <el-tab-pane label="骞村亣璁剧疆"
+                   name="annual">
         <div class="tab-content">
-          <el-button type="primary" @click="openDialog('annual', 'add')">鏂板骞村亣瑙勫垯</el-button>
-          
-          <el-table :data="annualData" border style="width: 100%; margin-top: 20px;">
-            <el-table-column prop="employeeType" label="鍛樺伐绫诲瀷"/>
-            <el-table-column prop="workYears" label="宸ヤ綔骞撮檺" />
-            <el-table-column prop="annualDays" label="骞村亣澶╂暟" align="center" />
-            <el-table-column prop="maxCarryOver" label="鏈�澶х粨杞ぉ鏁�" align="center" />
-            <el-table-column prop="status" label="鐘舵��">
+          <el-button type="primary"
+                     @click="openDialog('annual', 'add')">鏂板骞村亣瑙勫垯</el-button>
+          <el-table :data="annualData"
+                    border
+                    style="width: 100%; margin-top: 20px;">
+            <el-table-column prop="employeeType"
+                             label="鍛樺伐绫诲瀷">
+              <template #default="scope">
+                <el-tag :type="getTagType(scope.row.employeeType)">{{ getTypeLabel(scope.row.employeeType) }}</el-tag>
+              </template>
+            </el-table-column>
+            <el-table-column prop="workYears"
+                             label="宸ヤ綔骞撮檺" />
+            <el-table-column prop="annualDays"
+                             label="骞村亣澶╂暟"
+                             align="center" />
+            <el-table-column prop="maxCarryOver"
+                             label="鏈�澶х粨杞ぉ鏁�"
+                             align="center" />
+            <el-table-column prop="status"
+                             label="鐘舵��">
               <template #default="scope">
                 <el-tag :type="scope.row.status === 'active' ? 'success' : 'info'">
                   {{ scope.row.status === 'active' ? '鍚敤' : '鍋滅敤' }}
                 </el-tag>
               </template>
             </el-table-column>
-            <el-table-column label="鎿嶄綔" fixed="right">
+            <el-table-column label="鎿嶄綔"
+                             fixed="right">
               <template #default="scope">
-                <el-button type="primary" size="small" @click="openDialog('annual', 'edit', scope.row)">缂栬緫</el-button>
-                <el-button type="danger" size="small" @click="deleteItem('annual', scope.row)">鍒犻櫎</el-button>
+                <el-button type="primary"
+                           size="small"
+                           @click="openDialog('annual', 'edit', scope.row)">缂栬緫</el-button>
+                <el-button type="danger"
+                           size="small"
+                           @click="deleteItem('annual', scope.row)">鍒犻櫎</el-button>
               </template>
             </el-table-column>
           </el-table>
         </div>
       </el-tab-pane>
-
       <!-- 鍔犵彮璁剧疆 -->
-      <el-tab-pane label="鍔犵彮璁剧疆" name="overtime">
+      <el-tab-pane label="鍔犵彮璁剧疆"
+                   name="overtime">
         <div class="tab-content">
-          <el-button type="primary" @click="openDialog('overtime', 'add')">鏂板鍔犵彮瑙勫垯</el-button>
-          
-          <el-table :data="overtimeData" border style="width: 100%; margin-top: 20px;">
-            <el-table-column prop="name" label="瑙勫垯鍚嶇О" />
-            <el-table-column prop="type" label="鍔犵彮绫诲瀷" >
+          <el-button type="primary"
+                     @click="openDialog('overtime', 'add')">鏂板鍔犵彮瑙勫垯</el-button>
+          <el-table :data="overtimeData"
+                    border
+                    style="width: 100%; margin-top: 20px;">
+            <el-table-column prop="name"
+                             label="瑙勫垯鍚嶇О" />
+            <el-table-column prop="type"
+                             label="鍔犵彮绫诲瀷">
               <template #default="scope">
                 <el-tag :type="getTagType(scope.row.type)">{{ getTypeLabel(scope.row.type) }}</el-tag>
               </template>
             </el-table-column>
-            <el-table-column prop="startTime" label="寮�濮嬫椂闂�"  />
-            <el-table-column prop="endTime" label="缁撴潫鏃堕棿"  />
-            <el-table-column prop="rate" label="鍊嶇巼" align="center" />
-            <el-table-column prop="status" label="鐘舵��" >
+            <el-table-column prop="startTime"
+                             label="寮�濮嬫椂闂�" />
+            <el-table-column prop="endTime"
+                             label="缁撴潫鏃堕棿" />
+            <el-table-column prop="rate"
+                             label="鍊嶇巼"
+                             align="center" />
+            <el-table-column prop="status"
+                             label="鐘舵��">
               <template #default="scope">
                 <el-tag :type="scope.row.status === 'active' ? 'success' : 'info'">
                   {{ scope.row.status === 'active' ? '鍚敤' : '鍋滅敤' }}
                 </el-tag>
               </template>
             </el-table-column>
-            <el-table-column label="鎿嶄綔" fixed="right">
+            <el-table-column label="鎿嶄綔"
+                             fixed="right">
               <template #default="scope">
-                <el-button type="primary" size="small" @click="openDialog('overtime', 'edit', scope.row)">缂栬緫</el-button>
-                <el-button type="danger" size="small" @click="deleteItem('overtime', scope.row)">鍒犻櫎</el-button>
+                <el-button type="primary"
+                           size="small"
+                           @click="openDialog('overtime', 'edit', scope.row)">缂栬緫</el-button>
+                <el-button type="danger"
+                           size="small"
+                           @click="deleteItem('overtime', scope.row)">鍒犻櫎</el-button>
               </template>
             </el-table-column>
           </el-table>
         </div>
       </el-tab-pane>
-
       <!-- 涓婄彮鏃堕棿璁剧疆 -->
-      <el-tab-pane label="涓婄彮鏃堕棿璁剧疆" name="worktime">
+      <el-tab-pane label="涓婄彮鏃堕棿璁剧疆"
+                   name="worktime">
         <div class="tab-content">
-          <el-button type="primary" @click="openDialog('worktime', 'add')">鏂板鏃堕棿娈�</el-button>
-          
-          <el-table :data="worktimeData" border style="width: 100%; margin-top: 20px;">
-            <el-table-column prop="name" label="鏃堕棿娈靛悕绉�"  />
-            <el-table-column prop="startTime" label="涓婄彮鏃堕棿"/>
-            <el-table-column prop="endTime" label="涓嬬彮鏃堕棿" />
-            <el-table-column prop="flexibleStart" label="寮规�т笂鐝�">
+          <el-button type="primary"
+                     @click="openDialog('worktime', 'add')">鏂板鏃堕棿娈�</el-button>
+          <el-table :data="worktimeData"
+                    border
+                    style="width: 100%; margin-top: 20px;">
+            <el-table-column prop="name"
+                             label="鏃堕棿娈靛悕绉�" />
+            <el-table-column prop="startTime"
+                             label="涓婄彮鏃堕棿" />
+            <el-table-column prop="endTime"
+                             label="涓嬬彮鏃堕棿" />
+            <el-table-column prop="flexibleStart"
+                             label="寮规�т笂鐝�">
               <template #default="scope">
-                <el-tag :type="scope.row.flexibleStart ? 'success' : 'info'">
-                  {{ scope.row.flexibleStart ? '鏄�' : '鍚�' }}
+                <el-tag :type="scope.row.flexibleStart === 'true' ? 'success' : 'info'">
+                  {{ scope.row.flexibleStart === 'true' ? '鏄�' : '鍚�' }}
                 </el-tag>
               </template>
             </el-table-column>
-            <el-table-column prop="flexibleMinutes" label="寮规�ф椂闂�(鍒嗛挓)" width="120" align="center" />
-            <el-table-column prop="status" label="鐘舵��" >
+            <el-table-column prop="flexibleMinutes"
+                             label="寮规�ф椂闂�(鍒嗛挓)"
+                             width="120"
+                             align="center" />
+            <el-table-column prop="status"
+                             label="鐘舵��">
               <template #default="scope">
                 <el-tag :type="scope.row.status === 'active' ? 'success' : 'info'">
                   {{ scope.row.status === 'active' ? '鍚敤' : '鍋滅敤' }}
                 </el-tag>
               </template>
             </el-table-column>
-            <el-table-column label="鎿嶄綔" fixed="right">
+            <el-table-column label="鎿嶄綔"
+                             fixed="right">
               <template #default="scope">
-                <el-button type="primary" size="small" @click="openDialog('worktime', 'edit', scope.row)">缂栬緫</el-button>
-                <el-button type="danger" size="small" @click="deleteItem('worktime', scope.row)">鍒犻櫎</el-button>
+                <el-button type="primary"
+                           size="small"
+                           @click="openDialog('worktime', 'edit', scope.row)">缂栬緫</el-button>
+                <el-button type="danger"
+                           size="small"
+                           @click="deleteItem('worktime', scope.row)">鍒犻櫎</el-button>
               </template>
             </el-table-column>
+          </el-table>
+        </div>
+      </el-tab-pane>
+      <!-- 鎵撳崱璁板綍 -->
+      <el-tab-pane label="鎵撳崱璁板綍"
+                   name="attendance">
+        <div class="tab-content">
+          <div style="margin-bottom: 20px;">
+            <el-date-picker v-model="attendanceDate"
+                            type="date"
+                            placeholder="閫夋嫨鏃ユ湡"
+                            format="YYYY-MM-DD"
+                            value-format="YYYY-MM-DD"
+                            style="margin-right: 10px;"
+                            @change="filterAttendanceData" />
+            <el-select v-model="attendanceStatus"
+                       placeholder="閫夋嫨鐘舵��"
+                       style="width: 120px; margin-right: 10px;"
+                       @change="filterAttendanceData">
+              <el-option label="鍏ㄩ儴"
+                         value="" />
+              <el-option label="姝e父"
+                         value="normal" />
+              <el-option label="杩熷埌"
+                         value="late" />
+              <el-option label="鏃╅��"
+                         value="early" />
+              <el-option label="缂哄嫟"
+                         value="absent" />
+            </el-select>
+            <el-button type="primary"
+                       @click="exportAttendance">瀵煎嚭璁板綍</el-button>
+          </div>
+          <el-table :data="filteredAttendanceData"
+                    border
+                    style="width: 100%;">
+            <el-table-column prop="employeeName"
+                             label="鍛樺伐濮撳悕"
+                             width="120" />
+            <el-table-column prop="department"
+                             label="閮ㄩ棬"
+                             width="120" />
+            <el-table-column prop="date"
+                             label="鏃ユ湡"
+                             width="120" />
+            <el-table-column prop="clockInTime"
+                             label="涓婄彮鎵撳崱"
+                             width="120" />
+            <el-table-column prop="clockOutTime"
+                             label="涓嬬彮鎵撳崱"
+                             width="120" />
+            <el-table-column prop="workHours"
+                             label="宸ヤ綔鏃堕暱"
+                             width="100"
+                             align="center" />
+            <el-table-column prop="status"
+                             label="鐘舵��"
+                             width="100"
+                             align="center">
+              <template #default="scope">
+                <el-tag :type="getAttendanceTagType(scope.row.status)">{{ getAttendanceStatusLabel(scope.row.status) }}</el-tag>
+              </template>
+            </el-table-column>
+            <el-table-column prop="location"
+                             label="鎵撳崱鍦扮偣"
+                             width="150" />
+            <el-table-column prop="remark"
+                             label="澶囨敞"
+                             min-width="150" />
           </el-table>
         </div>
       </el-tab-pane>
     </el-tabs>
-
     <!-- 閫氱敤寮圭獥 -->
-    <el-dialog v-model="dialogVisible" :title="dialogTitle" width="600px">
-      <el-form ref="formRef" :model="form" :rules="rules" label-width="100px">
-        <el-form-item label="鍚嶇О" prop="name" v-if="currentType !== 'annual'">
-          <el-input v-model="form.name" placeholder="璇疯緭鍏ュ悕绉�" />
+    <el-dialog v-model="dialogVisible"
+               :title="dialogTitle"
+               width="600px">
+      <el-form ref="formRef"
+               :model="form"
+               :rules="rules"
+               label-width="100px">
+        <el-form-item label="鍚嶇О"
+                      prop="name"
+                      v-if="currentType !== 'annual'">
+          <el-input v-model="form.name"
+                    placeholder="璇疯緭鍏ュ悕绉�" />
         </el-form-item>
-        
-        <el-form-item label="绫诲瀷" prop="type" v-if="currentType === 'holiday' || currentType === 'overtime'">
-          <el-select v-model="form.type" placeholder="璇烽�夋嫨绫诲瀷" style="width: 100%">
-            <el-option 
-              v-for="option in getTypeOptions()" 
-              :key="option.value" 
-              :label="option.label" 
-              :value="option.value" 
-            />
+        <el-form-item label="绫诲瀷"
+                      prop="type"
+                      v-if="currentType === 'holiday' || currentType === 'overtime'">
+          <el-select v-model="form.type"
+                     placeholder="璇烽�夋嫨绫诲瀷"
+                     style="width: 100%">
+            <el-option v-for="option in getTypeOptions()"
+                       :key="option.value"
+                       :label="option.label"
+                       :value="option.value" />
           </el-select>
         </el-form-item>
-
-        <el-form-item label="鍛樺伐绫诲瀷" prop="employeeType" v-if="currentType === 'annual'">
-          <el-select v-model="form.employeeType" placeholder="璇烽�夋嫨鍛樺伐绫诲瀷" style="width: 100%">
-            <el-option label="姝e紡鍛樺伐" value="regular" />
+        <el-form-item label="鍛樺伐绫诲瀷"
+                      prop="employeeType"
+                      v-if="currentType === 'annual'">
+          <el-select v-model="form.employeeType"
+                     placeholder="璇烽�夋嫨鍛樺伐绫诲瀷"
+                     style="width: 100%">
+            <!-- <el-option label="姝e紡鍛樺伐" value="regular" />
             <el-option label="璇曠敤鏈熷憳宸�" value="probation" />
-            <el-option label="瀹炰範鐢�" value="intern" />
+            <el-option label="瀹炰範鐢�" value="intern" /> -->
+            <el-option v-for="option in getTypeOptions()"
+                       :key="option.value"
+                       :label="option.label"
+                       :value="option.value" />
           </el-select>
         </el-form-item>
-
-        <el-form-item label="宸ヤ綔骞撮檺" prop="workYears" v-if="currentType === 'annual'">
-          <el-input v-model="form.workYears" placeholder="濡傦細1-3骞淬��3-5骞寸瓑" />
+        <el-form-item label="宸ヤ綔骞撮檺"
+                      prop="workYears"
+                      v-if="currentType === 'annual'">
+          <el-input v-model="form.workYears"
+                    placeholder="濡傦細1-3骞淬��3-5骞寸瓑" />
         </el-form-item>
-
-        <el-form-item label="骞村亣澶╂暟" prop="annualDays" v-if="currentType === 'annual'">
-          <el-input-number v-model="form.annualDays" :min="0" :max="365" style="width: 100%" />
+        <el-form-item label="骞村亣澶╂暟"
+                      prop="annualDays"
+                      v-if="currentType === 'annual'">
+          <el-input-number v-model="form.annualDays"
+                           :min="0"
+                           :max="365"
+                           style="width: 100%" />
         </el-form-item>
-
-        <el-form-item label="鏈�澶х粨杞ぉ鏁�" prop="maxCarryOver" v-if="currentType === 'annual'">
-          <el-input-number v-model="form.maxCarryOver" :min="0" :max="30" style="width: 100%" />
+        <el-form-item label="鏈�澶х粨杞ぉ鏁�"
+                      prop="maxCarryOver"
+                      v-if="currentType === 'annual'">
+          <el-input-number v-model="form.maxCarryOver"
+                           :min="0"
+                           :max="30"
+                           style="width: 100%" />
         </el-form-item>
-
-                          <el-form-item label="鏃ユ湡鑼冨洿" prop="dateRange" v-if="currentType === 'holiday'">
-           <el-date-picker
-             v-model="form.dateRange"
-             type="daterange"
-             range-separator="鑷�"
-             start-placeholder="寮�濮嬫棩鏈�"
-             end-placeholder="缁撴潫鏃ユ湡"
-             style="width: 100%"
-             @change="calculateDays"
-           />
-         </el-form-item>
-
-        <el-form-item label="澶╂暟" prop="days" v-if="currentType === 'holiday'">
-          <el-input-number v-model="form.days" :min="0" style="width: 100%" />
+        <el-form-item label="鏃ユ湡鑼冨洿"
+                      prop="dateRange"
+                      v-if="currentType === 'holiday'">
+          <el-date-picker v-model="form.dateRange"
+                          type="daterange"
+                          range-separator="鑷�"
+                          start-placeholder="寮�濮嬫棩鏈�"
+                          end-placeholder="缁撴潫鏃ユ湡"
+                          style="width: 100%"
+                          @change="calculateDays" />
         </el-form-item>
-
-                 <el-form-item label="寮�濮嬫椂闂�" prop="startTime" v-if="currentType === 'overtime'">
-           <el-time-picker
-             v-model="form.startTime"
-             placeholder="寮�濮嬫椂闂�"
-             format="HH:mm"
-             value-format="HH:mm"
-             style="width: 100%"
-             @change="validateTimeField('startTime')"
-           />
-         </el-form-item>
-         
-         <el-form-item label="缁撴潫鏃堕棿" prop="endTime" v-if="currentType === 'overtime'">
-           <el-time-picker
-             v-model="form.endTime"
-             placeholder="缁撴潫鏃堕棿"
-             format="HH:mm"
-             value-format="HH:mm"
-             style="width: 100%"
-             @change="validateTimeField('endTime')"
-           />
-         </el-form-item>
-
-        <el-form-item label="鍊嶇巼" prop="rate" v-if="currentType === 'overtime'">
-          <el-input-number v-model="form.rate" :min="1" :max="3" :step="0.5" style="width: 100%" />
+        <el-form-item label="澶╂暟"
+                      prop="days"
+                      v-if="currentType === 'holiday'">
+          <el-input-number v-model="form.days"
+                           :min="0"
+                           style="width: 100%" />
         </el-form-item>
-
-                 <el-form-item label="涓婄彮鏃堕棿" prop="workStartTime" v-if="currentType === 'worktime'">
-           <el-time-picker
-             v-model="form.workStartTime"
-             placeholder="涓婄彮鏃堕棿"
-             format="HH:mm"
-             value-format="HH:mm"
-             style="width: 100%"
-             @change="validateTimeField('workStartTime')"
-           />
-         </el-form-item>
-
-         <el-form-item label="涓嬬彮鏃堕棿" prop="workEndTime" v-if="currentType === 'worktime'">
-           <el-time-picker
-             v-model="form.workEndTime"
-             placeholder="涓嬬彮鏃堕棿"
-             format="HH:mm"
-             value-format="HH:mm"
-             style="width: 100%"
-             @change="validateTimeField('workEndTime')"
-           />
-         </el-form-item>
-
-        <el-form-item label="寮规�т笂鐝�" prop="flexibleStart" v-if="currentType === 'worktime'">
+        <el-form-item label="寮�濮嬫椂闂�"
+                      prop="startTime"
+                      v-if="currentType === 'overtime'">
+          <el-time-picker v-model="form.startTime"
+                          placeholder="寮�濮嬫椂闂�"
+                          format="HH:mm"
+                          value-format="HH:mm"
+                          style="width: 100%"
+                          @change="validateTimeField('startTime')" />
+        </el-form-item>
+        <el-form-item label="缁撴潫鏃堕棿"
+                      prop="endTime"
+                      v-if="currentType === 'overtime'">
+          <el-time-picker v-model="form.endTime"
+                          placeholder="缁撴潫鏃堕棿"
+                          format="HH:mm"
+                          value-format="HH:mm"
+                          style="width: 100%"
+                          @change="validateTimeField('endTime')" />
+        </el-form-item>
+        <el-form-item label="鍊嶇巼"
+                      prop="rate"
+                      v-if="currentType === 'overtime'">
+          <el-input-number v-model="form.rate"
+                           :min="1"
+                           :max="3"
+                           :step="0.5"
+                           style="width: 100%" />
+        </el-form-item>
+        <el-form-item label="涓婄彮鏃堕棿"
+                      prop="workStartTime"
+                      v-if="currentType === 'worktime'">
+          <el-time-picker v-model="form.workStartTime"
+                          placeholder="涓婄彮鏃堕棿"
+                          format="HH:mm"
+                          value-format="HH:mm"
+                          style="width: 100%"
+                          @change="validateTimeField('workStartTime')" />
+        </el-form-item>
+        <el-form-item label="涓嬬彮鏃堕棿"
+                      prop="workEndTime"
+                      v-if="currentType === 'worktime'">
+          <el-time-picker v-model="form.workEndTime"
+                          placeholder="涓嬬彮鏃堕棿"
+                          format="HH:mm"
+                          value-format="HH:mm"
+                          style="width: 100%"
+                          @change="validateTimeField('workEndTime')" />
+        </el-form-item>
+        <el-form-item label="寮规�т笂鐝�"
+                      prop="flexibleStart"
+                      v-if="currentType === 'worktime'">
           <el-switch v-model="form.flexibleStart" />
         </el-form-item>
-
-        <el-form-item label="寮规�ф椂闂�(鍒嗛挓)" prop="flexibleMinutes" v-if="currentType === 'worktime' && form.flexibleStart">
-          <el-input-number v-model="form.flexibleMinutes" :min="0" :max="120" style="width: 100%" />
+        <el-form-item label="寮规�ф椂闂�(鍒嗛挓)"
+                      prop="flexibleMinutes"
+                      v-if="currentType === 'worktime' && form.flexibleStart">
+          <el-input-number v-model="form.flexibleMinutes"
+                           :min="0"
+                           :max="120"
+                           style="width: 100%" />
         </el-form-item>
-
-                 <el-form-item label="鐘舵��" prop="status">
-           <el-radio-group v-model="form.status">
-             <el-radio value="active">鍚敤</el-radio>
-             <el-radio value="inactive">鍋滅敤</el-radio>
-           </el-radio-group>
-         </el-form-item>
+        <el-form-item label="鐘舵��"
+                      prop="status">
+          <el-radio-group v-model="form.status">
+            <el-radio value="active">鍚敤</el-radio>
+            <el-radio value="inactive">鍋滅敤</el-radio>
+          </el-radio-group>
+        </el-form-item>
       </el-form>
-      
       <template #footer>
         <span class="dialog-footer">
+          <el-button type="primary"
+                     @click="submitForm">纭畾</el-button>
           <el-button @click="dialogVisible = false">鍙栨秷</el-button>
-          <el-button type="primary" @click="submitForm">纭畾</el-button>
         </span>
       </template>
     </el-dialog>
@@ -256,459 +421,1001 @@
 </template>
 
 <script setup>
-import { ref, reactive, onMounted, onUnmounted } from 'vue'
-import { ElMessage, ElMessageBox } from 'element-plus'
+  import { ref, reactive, onMounted, onUnmounted } from "vue";
+  import { ElMessage, ElMessageBox } from "element-plus";
+  import {
+    listHolidaySettings,
+    addHolidaySettings,
+    updateHolidaySettings,
+    delHolidaySettings,
+    listAnnualLeaveSettingList,
+    addAnnualLeaveSetting,
+    updateAnnualLeaveSetting,
+    delAnnualLeaveSetting,
+    listOvertimeSettingList,
+    addOvertimeSetting,
+    updateOvertimeSetting,
+    delOvertimeSetting,
+    listWorkingHoursSettingList,
+    addWorkingHoursSetting,
+    updateWorkingHoursSetting,
+    delWorkingHoursSetting,
+  } from "@/api/collaborativeApproval/attendanceManagement.js";
 
-// 褰撳墠婵�娲荤殑鏍囩椤�
-const activeTab = ref('holiday')
+  // 褰撳墠婵�娲荤殑鏍囩椤�
+  const activeTab = ref("holiday");
 
-// 寮圭獥鐩稿叧
-const dialogVisible = ref(false)
-const dialogTitle = ref('')
-const currentType = ref('')
-const currentAction = ref('')
-const currentEditId = ref('')
-const formRef = ref()
+  // 寮圭獥鐩稿叧
+  const dialogVisible = ref(false);
+  const dialogTitle = ref("");
+  const currentType = ref("");
+  const currentAction = ref("");
+  const currentEditId = ref("");
+  const formRef = ref();
+  const page = {
+    current: 1,
+    size: 20,
+    total: 0,
+  };
+  const holidayData = ref([]);
+  const annualData = ref([]);
+  const overtimeData = ref([]);
+  const worktimeData = ref([]);
 
-// 琛ㄥ崟鏁版嵁
-const form = reactive({
-  name: '',
-  type: '',
-  dateRange: [],
-  days: 0,
-  employeeType: '',
-  workYears: '',
-  annualDays: 0,
-  maxCarryOver: 0,
-  startTime: '', // 鍔犵彮寮�濮嬫椂闂�
-  endTime: '',   // 鍔犵彮缁撴潫鏃堕棿
-  workStartTime: '', // 涓婄彮鏃堕棿
-  workEndTime: '',   // 涓嬬彮鏃堕棿
-  rate: 1.5,
-  flexibleStart: false,
-  flexibleMinutes: 30,
-  status: 'active'
-})
+  // 鎵撳崱璁板綍鐩稿叧鏁版嵁
+  const attendanceData = ref([]);
+  const filteredAttendanceData = ref([]);
+  const attendanceDate = ref("");
+  const attendanceStatus = ref("");
 
-// 琛ㄥ崟楠岃瘉瑙勫垯
-const rules = {
-  name: [{ required: true, message: '璇疯緭鍏ュ悕绉�', trigger: 'blur' }],
-  type: [{ required: true, message: '璇烽�夋嫨绫诲瀷', trigger: 'change' }],
-  dateRange: [{ required: true, message: '璇烽�夋嫨鏃ユ湡鑼冨洿', trigger: 'change' }],
-  days: [{ required: true, message: '璇疯緭鍏ュぉ鏁�', trigger: 'blur' }],
-  employeeType: [{ required: true, message: '璇烽�夋嫨鍛樺伐绫诲瀷', trigger: 'change' }],
-  workYears: [{ required: true, message: '璇疯緭鍏ュ伐浣滃勾闄�', trigger: 'blur' }],
-  annualDays: [{ required: true, message: '璇疯緭鍏ュ勾鍋囧ぉ鏁�', trigger: 'blur' }],
-  maxCarryOver: [{ required: true, message: '璇疯緭鍏ユ渶澶х粨杞ぉ鏁�', trigger: 'blur' }],
-  startTime: [{ 
-    required: true, 
-    message: '璇烽�夋嫨寮�濮嬫椂闂�', 
-    trigger: 'change',
-    validator: (rule, value, callback) => {
-      if (!value) {
-        callback(new Error('璇烽�夋嫨寮�濮嬫椂闂�'))
-      } else {
-        callback()
-      }
-    }
-  }],
-  endTime: [{ 
-    required: true, 
-    message: '璇烽�夋嫨缁撴潫鏃堕棿', 
-    trigger: 'change',
-    validator: (rule, value, callback) => {
-      if (!value) {
-        callback(new Error('璇烽�夋嫨缁撴潫鏃堕棿'))
-      } else {
-        callback()
-      }
-    }
-  }],
-  workStartTime: [{ 
-    required: true, 
-    message: '璇烽�夋嫨涓婄彮鏃堕棿', 
-    trigger: 'change',
-    validator: (rule, value, callback) => {
-      if (!value) {
-        callback(new Error('璇烽�夋嫨涓婄彮鏃堕棿'))
-      } else {
-        callback()
-      }
-    }
-  }],
-  workEndTime: [{ 
-    required: true, 
-    message: '璇烽�夋嫨涓嬬彮鏃堕棿', 
-    trigger: 'change',
-    validator: (rule, value, callback) => {
-      if (!value) {
-        callback(new Error('璇烽�夋嫨涓嬬彮鏃堕棿'))
-      } else {
-        callback()
-      }
-    }
-  }],
-  rate: [{ required: true, message: '璇疯緭鍏ュ�嶇巼', trigger: 'blur' }]
-}
-
-// 妯℃嫙鏁版嵁
-const holidayData = ref([
-  { id: '1', name: '鏄ヨ妭', type: 'legal', startDate: '2024-02-10', endDate: '2024-02-17', days: 8, status: 'active' },
-  { id: '2', name: '娓呮槑鑺�', type: 'legal', startDate: '2024-04-05', endDate: '2024-04-05', days: 1, status: 'active' },
-  { id: '3', name: '鍔冲姩鑺�', type: 'legal', startDate: '2024-05-01', endDate: '2024-05-05', days: 5, status: 'active' }
-])
-
-const annualData = ref([
-  { id: '1', employeeType: 'regular', workYears: '1-3骞�', annualDays: 5, maxCarryOver: 2, status: 'active' },
-  { id: '2', employeeType: 'regular', workYears: '3-5骞�', annualDays: 10, maxCarryOver: 5, status: 'active' },
-  { id: '3', employeeType: 'regular', workYears: '5骞翠互涓�', annualDays: 15, maxCarryOver: 10, status: 'active' }
-])
-
-const overtimeData = ref([
-  { id: '1', name: '宸ヤ綔鏃ュ姞鐝�', type: 'weekday', startTime: '18:00', endTime: '22:00', rate: 1.5, status: 'active' },
-  { id: '2', name: '鍛ㄦ湯鍔犵彮', type: 'weekend', startTime: '09:00', endTime: '18:00', rate: 2.0, status: 'active' },
-  { id: '3', name: '娣卞鍔犵彮', type: 'night', startTime: '22:00', endTime: '06:00', rate: 2.5, status: 'active' }
-])
-
-const worktimeData = ref([
-  { id: '1', name: '鏍囧噯宸ヤ綔鏃堕棿', startTime: '09:00', endTime: '18:00', flexibleStart: true, flexibleMinutes: 30, status: 'active' },
-  { id: '2', name: '鏃╃彮鏃堕棿', startTime: '08:00', endTime: '17:00', flexibleStart: false, flexibleMinutes: 0, status: 'active' },
-  { id: '3', name: '鏅氱彮鏃堕棿', startTime: '14:00', endTime: '23:00', flexibleStart: false, flexibleMinutes: 0, status: 'active' }
-])
-
-// 宸ュ叿鍑芥暟
-const getTagType = (type) => {
-  const tagMap = {
-    legal: 'success', adjustment: 'warning', special: 'info', company: 'primary',
-    weekday: 'primary', weekend: 'warning', holiday: 'danger', night: 'info'
-  }
-  return tagMap[type] || 'info'
-}
-
-const getTypeLabel = (type) => {
-  const labelMap = {
-    legal: '娉曞畾鑺傚亣鏃�', adjustment: '璋冧紤鏃�', special: '鐗规畩鍋囨湡', company: '鍏徃鍋囨湡',
-    weekday: '宸ヤ綔鏃ュ姞鐝�', weekend: '鍛ㄦ湯鍔犵彮', holiday: '鑺傚亣鏃ュ姞鐝�', night: '娣卞鍔犵彮'
-  }
-  return labelMap[type] || type
-}
-
-const getTypeOptions = () => {
-  if (currentType.value === 'holiday') {
-    return [
-      { label: '娉曞畾鑺傚亣鏃�', value: 'legal' },
-      { label: '璋冧紤鏃�', value: 'adjustment' },
-      { label: '鐗规畩鍋囨湡', value: 'special' },
-      { label: '鍏徃鍋囨湡', value: 'company' }
-    ]
-  } else if (currentType.value === 'overtime') {
-    return [
-      { label: '宸ヤ綔鏃ュ姞鐝�', value: 'weekday' },
-      { label: '鍛ㄦ湯鍔犵彮', value: 'weekend' },
-      { label: '鑺傚亣鏃ュ姞鐝�', value: 'holiday' },
-      { label: '娣卞鍔犵彮', value: 'night' }
-    ]
-  }
-  return []
-}
-
-// 璁$畻鍋囨湡澶╂暟
-const calculateDays = () => {
-  try {
-    if (form.dateRange && form.dateRange.length === 2 && form.dateRange[0] && form.dateRange[1]) {
-      const start = new Date(form.dateRange[0])
-      const end = new Date(form.dateRange[1])
-      
-      if (isNaN(start.getTime()) || isNaN(end.getTime())) {
-        console.warn('鏃犳晥鐨勬棩鏈熸牸寮�')
-        return
-      }
-      
-      const diffTime = Math.abs(end - start)
-      const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24)) + 1
-      form.days = diffDays
-    }
-  } catch (error) {
-    console.error('璁$畻澶╂暟澶辫触:', error)
-  }
-}
-
-// 楠岃瘉鏃堕棿鏍煎紡
-const validateTime = (time) => {
-  if (!time) return ''
-  if (typeof time === 'string') return time
-  if (time instanceof Date) {
-    return time.toTimeString().slice(0, 5)
-  }
-  return ''
-}
-
-// 楠岃瘉鏃堕棿瀛楁
-const validateTimeField = (fieldName) => {
-  try {
-    const value = form[fieldName]
-    if (value && typeof value === 'object' && value.hour !== undefined) {
-      // 濡傛灉鏄椂闂村璞★紝杞崲涓哄瓧绗︿覆鏍煎紡
-      const hours = value.hour.toString().padStart(2, '0')
-      const minutes = value.minute.toString().padStart(2, '0')
-      form[fieldName] = `${hours}:${minutes}`
-    }
-  } catch (error) {
-    console.error(`楠岃瘉鏃堕棿瀛楁 ${fieldName} 澶辫触:`, error)
-    form[fieldName] = ''
-  }
-}
-
-// 鎵撳紑寮圭獥
-const openDialog = (type, action, row = null) => {
-  try {
-    currentType.value = type
-    currentAction.value = action
-    
-    if (action === 'add') {
-      dialogTitle.value = `鏂板${getTypeName(type)}`
-      currentEditId.value = ''
-      resetForm()
-    } else if (action === 'edit' && row) {
-      dialogTitle.value = `缂栬緫${getTypeName(type)}`
-      currentEditId.value = row.id
-      fillForm(row)
-    }
-    
-    dialogVisible.value = true
-  } catch (error) {
-    console.error('鎵撳紑寮圭獥澶辫触:', error)
-    ElMessage.error('鎵撳紑寮圭獥澶辫触锛岃閲嶈瘯')
-  }
-}
-
-const getTypeName = (type) => {
-  const nameMap = {
-    holiday: '鍋囨湡',
-    annual: '骞村亣瑙勫垯',
-    overtime: '鍔犵彮瑙勫垯',
-    worktime: '鏃堕棿娈�'
-  }
-  return nameMap[type] || ''
-}
-
-const resetForm = () => {
-  Object.assign(form, {
-    name: '',
-    type: '',
+  // 琛ㄥ崟鏁版嵁
+  const form = reactive({
+    name: "",
+    type: "",
     dateRange: [],
+    startDate: "",
+    endDate: "",
     days: 0,
-    employeeType: '',
-    workYears: '',
+    employeeType: "",
+    workYears: "",
     annualDays: 0,
     maxCarryOver: 0,
-    startTime: '',
-    endTime: '',
-    workStartTime: '',
-    workEndTime: '',
+    startTime: "", // 鍔犵彮寮�濮嬫椂闂�
+    endTime: "", // 鍔犵彮缁撴潫鏃堕棿
+    workStartTime: "", // 涓婄彮鏃堕棿
+    workEndTime: "", // 涓嬬彮鏃堕棿
     rate: 1.5,
     flexibleStart: false,
     flexibleMinutes: 30,
-    status: 'active'
-  })
-}
+    status: "active",
+  });
 
-const fillForm = (row) => {
-  if (currentType.value === 'holiday') {
-    Object.assign(form, {
-      name: row.name,
-      type: row.type,
-      dateRange: [new Date(row.startDate), new Date(row.endDate)],
-      days: row.days,
-      status: row.status
-    })
-  } else if (currentType.value === 'annual') {
-    Object.assign(form, {
-      employeeType: row.employeeType,
-      workYears: row.workYears,
-      annualDays: row.annualDays,
-      maxCarryOver: row.maxCarryOver,
-      status: row.status
-    })
-  } else if (currentType.value === 'overtime') {
-    Object.assign(form, {
-      name: row.name,
-      type: row.type,
-      startTime: row.startTime || '',
-      endTime: row.endTime || '',
-      rate: row.rate,
-      status: row.status
-    })
-  } else if (currentType.value === 'worktime') {
-    Object.assign(form, {
-      name: row.name,
-      workStartTime: row.startTime || '',
-      workEndTime: row.endTime || '',
-      flexibleStart: row.flexibleStart,
-      flexibleMinutes: row.flexibleMinutes,
-      status: row.status
-    })
-  }
-}
+  // 琛ㄥ崟楠岃瘉瑙勫垯
+  const rules = {
+    name: [{ required: true, message: "璇疯緭鍏ュ悕绉�", trigger: "blur" }],
+    type: [{ required: true, message: "璇烽�夋嫨绫诲瀷", trigger: "change" }],
+    dateRange: [{ required: true, message: "璇烽�夋嫨鏃ユ湡鑼冨洿", trigger: "change" }],
+    days: [{ required: true, message: "璇疯緭鍏ュぉ鏁�", trigger: "blur" }],
+    employeeType: [
+      { required: true, message: "璇烽�夋嫨鍛樺伐绫诲瀷", trigger: "change" },
+    ],
+    workYears: [{ required: true, message: "璇疯緭鍏ュ伐浣滃勾闄�", trigger: "blur" }],
+    annualDays: [{ required: true, message: "璇疯緭鍏ュ勾鍋囧ぉ鏁�", trigger: "blur" }],
+    maxCarryOver: [
+      { required: true, message: "璇疯緭鍏ユ渶澶х粨杞ぉ鏁�", trigger: "blur" },
+    ],
+    startTime: [
+      {
+        required: true,
+        message: "璇烽�夋嫨寮�濮嬫椂闂�",
+        trigger: "change",
+        validator: (rule, value, callback) => {
+          if (!value) {
+            callback(new Error("璇烽�夋嫨寮�濮嬫椂闂�"));
+          } else {
+            callback();
+          }
+        },
+      },
+    ],
+    endTime: [
+      {
+        required: true,
+        message: "璇烽�夋嫨缁撴潫鏃堕棿",
+        trigger: "change",
+        validator: (rule, value, callback) => {
+          if (!value) {
+            callback(new Error("璇烽�夋嫨缁撴潫鏃堕棿"));
+          } else {
+            callback();
+          }
+        },
+      },
+    ],
+    workStartTime: [
+      {
+        required: true,
+        message: "璇烽�夋嫨涓婄彮鏃堕棿",
+        trigger: "change",
+        validator: (rule, value, callback) => {
+          if (!value) {
+            callback(new Error("璇烽�夋嫨涓婄彮鏃堕棿"));
+          } else {
+            callback();
+          }
+        },
+      },
+    ],
+    workEndTime: [
+      {
+        required: true,
+        message: "璇烽�夋嫨涓嬬彮鏃堕棿",
+        trigger: "change",
+        validator: (rule, value, callback) => {
+          if (!value) {
+            callback(new Error("璇烽�夋嫨涓嬬彮鏃堕棿"));
+          } else {
+            callback();
+          }
+        },
+      },
+    ],
+    rate: [{ required: true, message: "璇疯緭鍏ュ�嶇巼", trigger: "blur" }],
+  };
+  // 宸ュ叿鍑芥暟
+  const getTagType = type => {
+    const tagMap = {
+      legal: "success",
+      adjustment: "warning",
+      special: "info",
+      company: "primary",
+      weekday: "primary",
+      weekend: "warning",
+      holiday: "danger",
+      night: "info",
+      regular: "success",
+      probation: "info",
+      intern: "danger",
+    };
+    return tagMap[type] || "info";
+  };
 
-// 鎻愪氦琛ㄥ崟
-const submitForm = async () => {
-  try {
-    if (!formRef.value) {
-      ElMessage.error('琛ㄥ崟寮曠敤涓嶅瓨鍦�')
-      return
+  const getTypeLabel = type => {
+    const labelMap = {
+      legal: "娉曞畾鑺傚亣鏃�",
+      adjustment: "璋冧紤鏃�",
+      special: "鐗规畩鍋囨湡",
+      company: "鍏徃鍋囨湡",
+      weekday: "宸ヤ綔鏃ュ姞鐝�",
+      weekend: "鍛ㄦ湯鍔犵彮",
+      holiday: "鑺傚亣鏃ュ姞鐝�",
+      night: "娣卞鍔犵彮",
+      regular: "姝e紡鍛樺伐",
+      probation: "璇曠敤鏈熷憳宸�",
+      intern: "瀹炰範鐢�",
+    };
+    return labelMap[type] || type;
+  };
+
+  // 鎵撳崱璁板綍鐩稿叧宸ュ叿鍑芥暟
+  const getAttendanceTagType = status => {
+    const tagMap = {
+      normal: "success",
+      late: "warning",
+      early: "warning",
+      absent: "danger",
+    };
+    return tagMap[status] || "info";
+  };
+
+  const getAttendanceStatusLabel = status => {
+    const labelMap = {
+      normal: "姝e父",
+      late: "杩熷埌",
+      early: "鏃╅��",
+      absent: "缂哄嫟",
+    };
+    return labelMap[status] || status;
+  };
+
+  const getTypeOptions = () => {
+    if (currentType.value === "holiday") {
+      return [
+        { label: "娉曞畾鑺傚亣鏃�", value: "legal" },
+        { label: "璋冧紤鏃�", value: "adjustment" },
+        { label: "鐗规畩鍋囨湡", value: "special" },
+        { label: "鍏徃鍋囨湡", value: "company" },
+      ];
+    } else if (currentType.value === "overtime") {
+      return [
+        { label: "宸ヤ綔鏃ュ姞鐝�", value: "weekday" },
+        { label: "鍛ㄦ湯鍔犵彮", value: "weekend" },
+        { label: "鑺傚亣鏃ュ姞鐝�", value: "holiday" },
+        { label: "娣卞鍔犵彮", value: "night" },
+      ];
+    } else if (currentType.value === "annual") {
+      return [
+        { label: "姝e紡鍛樺伐", value: "regular" },
+        { label: "璇曠敤鏈熷憳宸�", value: "probation" },
+        { label: "瀹炰範鐢�", value: "intern" },
+      ];
     }
-    
-    await formRef.value.validate()
-    
-    if (currentAction.value === 'add') {
-      addItem()
-    } else if (currentAction.value === 'edit') {
-      editItem()
+    return [];
+  };
+
+  // 璁$畻鍋囨湡澶╂暟
+  const calculateDays = () => {
+    try {
+      if (
+        form.dateRange &&
+        form.dateRange.length === 2 &&
+        form.dateRange[0] &&
+        form.dateRange[1]
+      ) {
+        const start = new Date(form.dateRange[0]);
+        const end = new Date(form.dateRange[1]);
+        form.startDate = start.toISOString().split("T")[0];
+        form.endDate = end.toISOString().split("T")[0];
+
+        if (isNaN(start.getTime()) || isNaN(end.getTime())) {
+          console.warn("鏃犳晥鐨勬棩鏈熸牸寮�");
+          return;
+        }
+
+        const diffTime = Math.abs(end - start);
+        const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24)) + 1;
+        form.days = diffDays;
+      }
+    } catch (error) {
+      console.error("璁$畻澶╂暟澶辫触:", error);
     }
-    
-    dialogVisible.value = false
-    ElMessage.success('鎿嶄綔鎴愬姛')
-  } catch (error) {
-    console.error('琛ㄥ崟楠岃瘉澶辫触:', error)
-    ElMessage.error('琛ㄥ崟楠岃瘉澶辫触锛岃妫�鏌ヨ緭鍏�')
-  }
-}
+  };
 
-const addItem = () => {
-  const newItem = { ...form, id: Date.now().toString() }
-  
-  if (currentType.value === 'holiday') {
-    newItem.startDate = form.dateRange[0].toISOString().split('T')[0]
-    newItem.endDate = form.dateRange[1].toISOString().split('T')[0]
-    holidayData.value.push(newItem)
-  } else if (currentType.value === 'annual') {
-    annualData.value.push(newItem)
-  } else if (currentType.value === 'overtime') {
-    newItem.startTime = form.startTime || ''
-    newItem.endTime = form.endTime || ''
-    overtimeData.value.push(newItem)
-  } else if (currentType.value === 'worktime') {
-    newItem.startTime = form.workStartTime || ''
-    newItem.endTime = form.workEndTime || ''
-    worktimeData.value.push(newItem)
-  }
-}
+  // 楠岃瘉鏃堕棿鏍煎紡
+  // const validateTime = (time) => {
+  //   if (!time) return ''
+  //   if (typeof time === 'string') return time
+  //   if (time instanceof Date) {
+  //     return time.toTimeString().slice(0, 5)
+  //   }
+  //   return ''
+  // }
 
-const editItem = () => {
-  let dataArray
-  let index
-  
-  if (currentType.value === 'holiday') {
-    dataArray = holidayData.value
-    index = dataArray.findIndex(item => item.id === currentEditId.value)
-    if (index > -1) {
-      dataArray[index] = { 
-        ...dataArray[index],
+  // 楠岃瘉鏃堕棿瀛楁
+  const validateTimeField = fieldName => {
+    try {
+      const value = form[fieldName];
+      if (value && typeof value === "object" && value.hour !== undefined) {
+        // 濡傛灉鏄椂闂村璞★紝杞崲涓哄瓧绗︿覆鏍煎紡
+        const hours = value.hour.toString().padStart(2, "0");
+        const minutes = value.minute.toString().padStart(2, "0");
+        form[fieldName] = `${hours}:${minutes}`;
+      }
+    } catch (error) {
+      console.error(`楠岃瘉鏃堕棿瀛楁 ${fieldName} 澶辫触:`, error);
+      form[fieldName] = "";
+    }
+  };
+
+  // 鎵撳紑寮圭獥
+  const openDialog = (type, action, row = null) => {
+    try {
+      currentType.value = type;
+      currentAction.value = action;
+
+      if (action === "add") {
+        dialogTitle.value = `鏂板${getTypeName(type)}`;
+        currentEditId.value = "";
+        resetForm();
+      } else if (action === "edit" && row) {
+        dialogTitle.value = `缂栬緫${getTypeName(type)}`;
+        currentEditId.value = row.id;
+        fillForm(row);
+      }
+
+      dialogVisible.value = true;
+    } catch (error) {
+      console.error("鎵撳紑寮圭獥澶辫触:", error);
+      ElMessage.error("鎵撳紑寮圭獥澶辫触锛岃閲嶈瘯");
+    }
+  };
+
+  const getTypeName = type => {
+    const nameMap = {
+      holiday: "鍋囨湡",
+      annual: "骞村亣瑙勫垯",
+      overtime: "鍔犵彮瑙勫垯",
+      worktime: "鏃堕棿娈�",
+    };
+    return nameMap[type] || "";
+  };
+
+  const resetForm = () => {
+    Object.assign(form, {
+      name: "",
+      type: "",
+      dateRange: [],
+      startDate: "",
+      endDate: "",
+      days: 0,
+      employeeType: "",
+      workYears: "",
+      annualDays: 0,
+      maxCarryOver: 0,
+      startTime: "",
+      endTime: "",
+      workStartTime: "",
+      workEndTime: "",
+      rate: 1.5,
+      flexibleStart: false,
+      flexibleMinutes: 30,
+      status: "active",
+    });
+  };
+
+  const fillForm = row => {
+    if (currentType.value === "holiday") {
+      Object.assign(form, {
+        name: row.name,
+        type: row.type,
+        dateRange: [new Date(row.startDate), new Date(row.endDate)],
+        startDate: row.startDate,
+        endDate: row.endDate,
+        days: row.days,
+        status: row.status,
+      });
+    } else if (currentType.value === "annual") {
+      Object.assign(form, {
+        employeeType: row.employeeType,
+        workYears: row.workYears,
+        annualDays: row.annualDays,
+        maxCarryOver: row.maxCarryOver,
+        status: row.status,
+      });
+    } else if (currentType.value === "overtime") {
+      Object.assign(form, {
+        name: row.name,
+        type: row.type,
+        startTime: row.startTime || "",
+        endTime: row.endTime || "",
+        rate: row.rate,
+        status: row.status,
+      });
+    } else if (currentType.value === "worktime") {
+      Object.assign(form, {
+        name: row.name,
+        workStartTime: row.startTime || "",
+        workEndTime: row.endTime || "",
+        flexibleStart: row.flexibleStart,
+        flexibleMinutes: row.flexibleMinutes,
+        status: row.status,
+      });
+    }
+  };
+
+  // 鎻愪氦琛ㄥ崟
+  const submitForm = async () => {
+    try {
+      if (!formRef.value) {
+        ElMessage.error("琛ㄥ崟寮曠敤涓嶅瓨鍦�");
+        return;
+      }
+
+      await formRef.value.validate();
+
+      if (currentAction.value === "add") {
+        addItem();
+      } else if (currentAction.value === "edit") {
+        editItem();
+      }
+
+      dialogVisible.value = false;
+      ElMessage.success("鎿嶄綔鎴愬姛");
+    } catch (error) {
+      console.error("琛ㄥ崟楠岃瘉澶辫触:", error);
+      ElMessage.error("琛ㄥ崟楠岃瘉澶辫触锛岃妫�鏌ヨ緭鍏�");
+    }
+  };
+
+  const addItem = () => {
+    if (currentType.value === "holiday") {
+      const params = {
         name: form.name,
         type: form.type,
-        startDate: form.dateRange[0].toISOString().split('T')[0],
-        endDate: form.dateRange[1].toISOString().split('T')[0],
+        startDate: form.startDate,
+        endDate: form.endDate,
         days: form.days,
-        status: form.status
-      }
-    }
-  } else if (currentType.value === 'annual') {
-    dataArray = annualData.value
-    index = dataArray.findIndex(item => item.id === currentEditId.value)
-    if (index > -1) {
-      dataArray[index] = { 
-        ...dataArray[index],
+        status: form.status,
+      };
+      addHolidaySettings(params)
+        .then(res => {
+          if (res.code == 200) {
+            ElMessage.success("娣诲姞鎴愬姛");
+            // dialogVisible.value = false;
+            getHolidaySettingsList();
+          }
+        })
+        .catch(err => {
+          ElMessage.error(err.msg);
+        });
+    } else if (currentType.value === "annual") {
+      // annualData.value.push(newItem)
+      const params = {
         employeeType: form.employeeType,
         workYears: form.workYears,
         annualDays: form.annualDays,
         maxCarryOver: form.maxCarryOver,
-        status: form.status
-      }
-    }
-  } else if (currentType.value === 'overtime') {
-    dataArray = overtimeData.value
-    index = dataArray.findIndex(item => item.id === currentEditId.value)
-    if (index > -1) {
-      dataArray[index] = { 
-        ...dataArray[index],
+        status: form.status,
+      };
+      addAnnualLeaveSetting(params)
+        .then(res => {
+          if (res.code == 200) {
+            ElMessage.success("娣诲姞鎴愬姛");
+            // dialogVisible.value = false;
+            getAnnualLeaveSettingList();
+          }
+        })
+        .catch(err => {
+          ElMessage.error(err.msg);
+        });
+    } else if (currentType.value === "overtime") {
+      const params = {
         name: form.name,
         type: form.type,
-        startTime: form.startTime || '',
-        endTime: form.endTime || '',
+        startTime: form.startTime || "",
+        endTime: form.endTime || "",
         rate: form.rate,
-        status: form.status
-      }
-    }
-  } else if (currentType.value === 'worktime') {
-    dataArray = worktimeData.value
-    index = dataArray.findIndex(item => item.id === currentEditId.value)
-    if (index > -1) {
-      dataArray[index] = { 
-        ...dataArray[index],
+        status: form.status,
+      };
+      addOvertimeSetting(params)
+        .then(res => {
+          if (res.code == 200) {
+            ElMessage.success("娣诲姞鎴愬姛");
+            // dialogVisible.value = false;
+            getOvertimeSettingList();
+          }
+        })
+        .catch(err => {
+          ElMessage.error(err.msg);
+        });
+      // newItem.startTime = form.startTime || ''
+      // newItem.endTime = form.endTime || ''
+      // overtimeData.value.push(newItem)
+    } else if (currentType.value === "worktime") {
+      const params = {
         name: form.name,
-        startTime: form.workStartTime || '',
-        endTime: form.workEndTime || '',
+        startTime: form.workStartTime || "",
+        endTime: form.workEndTime || "",
         flexibleStart: form.flexibleStart,
         flexibleMinutes: form.flexibleMinutes,
-        status: form.status
+        status: form.status,
+      };
+      addWorkingHoursSetting(params)
+        .then(res => {
+          if (res.code == 200) {
+            ElMessage.success("娣诲姞鎴愬姛");
+            getWorkingHoursSettingList();
+          }
+        })
+        .catch(err => {
+          ElMessage.error(err.msg);
+        });
+      // newItem.startTime = form.workStartTime || ''
+      // newItem.endTime = form.workEndTime || ''
+      // worktimeData.value.push(newItem)
+    }
+  };
+
+  const editItem = () => {
+    let dataArray;
+    let index;
+
+    if (currentType.value === "holiday") {
+      const params = {
+        id: currentEditId.value,
+        name: form.name,
+        type: form.type,
+        startDate: form.dateRange[0].toISOString().split("T")[0],
+        endDate: form.dateRange[1].toISOString().split("T")[0],
+        days: form.days,
+        status: form.status,
+      };
+      updateHolidaySettings(params)
+        .then(res => {
+          if (res.code == 200) {
+            ElMessage.success("鏇存柊鎴愬姛");
+            // dialogVisible.value = false;
+            getHolidaySettingsList();
+          }
+        })
+        .catch(err => {
+          ElMessage.error(err.msg);
+        });
+    } else if (currentType.value === "annual") {
+      const params = {
+        id: currentEditId.value,
+        employeeType: form.employeeType,
+        workYears: form.workYears,
+        annualDays: form.annualDays,
+        maxCarryOver: form.maxCarryOver,
+        status: form.status,
+      };
+      updateAnnualLeaveSetting(params)
+        .then(res => {
+          if (res.code == 200) {
+            ElMessage.success("鏇存柊鎴愬姛");
+            getAnnualLeaveSettingList();
+          }
+        })
+        .catch(err => {
+          ElMessage.error(err.msg);
+        });
+    } else if (currentType.value === "overtime") {
+      const params = {
+        id: currentEditId.value,
+        name: form.name,
+        type: form.type,
+        startTime: form.startTime || "",
+        endTime: form.endTime || "",
+        rate: form.rate,
+        status: form.status,
+      };
+      updateOvertimeSetting(params)
+        .then(res => {
+          if (res.code == 200) {
+            ElMessage.success("鏇存柊鎴愬姛");
+            getOvertimeSettingList();
+          }
+        })
+        .catch(err => {
+          ElMessage.error(err.msg);
+        });
+
+      // dataArray = overtimeData.value
+      // index = dataArray.findIndex(item => item.id === currentEditId.value)
+      // if (index > -1) {
+      //   dataArray[index] = {
+      //     ...dataArray[index],
+      //     name: form.name,
+      //     type: form.type,
+      //     startTime: form.startTime || '',
+      //     endTime: form.endTime || '',
+      //     rate: form.rate,
+      //     status: form.status
+      //   }
+      // }
+    } else if (currentType.value === "worktime") {
+      const params = {
+        id: currentEditId.value,
+        name: form.name,
+        startTime: form.workStartTime || "",
+        endTime: form.workEndTime || "",
+        flexibleStart: form.flexibleStart,
+        flexibleMinutes: form.flexibleMinutes,
+        status: form.status,
+      };
+      updateWorkingHoursSetting(params)
+        .then(res => {
+          if (res.code == 200) {
+            ElMessage.success("鏇存柊鎴愬姛");
+            getWorkingHoursSettingList();
+          }
+        })
+        .catch(err => {
+          ElMessage.error(err.msg);
+        });
+      // dataArray = worktimeData.value
+      // index = dataArray.findIndex(item => item.id === currentEditId.value)
+      // if (index > -1) {
+      //   dataArray[index] = {
+      //     ...dataArray[index],
+      //     name: form.name,
+      //     startTime: form.workStartTime || '',
+      //     endTime: form.workEndTime || '',
+      //     flexibleStart: form.flexibleStart,
+      //     flexibleMinutes: form.flexibleMinutes,
+      //     status: form.status
+      //   }
+      // }
+    }
+  };
+
+  // 鎵撳崱璁板綍杩囨护鍔熻兘
+  const filterAttendanceData = () => {
+    let filtered = attendanceData.value;
+
+    // 鎸夋棩鏈熻繃婊�
+    if (attendanceDate.value) {
+      filtered = filtered.filter(item => item.date === attendanceDate.value);
+    }
+
+    // 鎸夌姸鎬佽繃婊�
+    if (attendanceStatus.value) {
+      filtered = filtered.filter(item => item.status === attendanceStatus.value);
+    }
+
+    filteredAttendanceData.value = filtered;
+  };
+
+  // 瀵煎嚭鎵撳崱璁板綍
+  const exportAttendance = () => {
+    ElMessage.success("瀵煎嚭鍔熻兘寮�鍙戜腑...");
+  };
+
+  // 鍒濆鍖栨墦鍗¤褰曞亣鏁版嵁
+  const initAttendanceData = () => {
+    const mockData = [
+      {
+        id: 1,
+        employeeName: "闄堝織寮�",
+        department: "鎶�鏈儴",
+        date: "2025-08-15",
+        clockInTime: "09:00:00",
+        clockOutTime: "18:00:00",
+        workHours: "8.0h",
+        status: "normal",
+        location: "鍏徃鎬婚儴",
+        remark: "",
+      },
+      {
+        id: 2,
+        employeeName: "鏉庨洩姊�",
+        department: "甯傚満閮�",
+        date: "2025-08-16",
+        clockInTime: "08:58:00",
+        clockOutTime: "18:05:00",
+        workHours: "8.12h",
+        status: "normal",
+        location: "鍏徃鎬婚儴",
+        remark: "",
+      },
+      {
+        id: 3,
+        employeeName: "鐜嬪缓鍗�",
+        department: "浜轰簨閮�",
+        date: "2025-08-16",
+        clockInTime: "09:02:00",
+        clockOutTime: "18:00:00",
+        workHours: "7.97h",
+        status: "normal",
+        location: "鍏徃鎬婚儴",
+        remark: "",
+      },
+      {
+        id: 4,
+        employeeName: "璧垫檽涓�",
+        department: "璐㈠姟閮�",
+        date: "2025-09-02",
+        clockInTime: "08:55:00",
+        clockOutTime: "18:10:00",
+        workHours: "8.25h",
+        status: "normal",
+        location: "鍏徃鎬婚儴",
+        remark: "",
+      },
+      {
+        id: 5,
+        employeeName: "寮犲浗搴�",
+        department: "鎶�鏈儴",
+        date: "2025-09-02",
+        clockInTime: "09:00:00",
+        clockOutTime: "18:30:00",
+        workHours: "8.5h",
+        status: "normal",
+        location: "鍏徃鎬婚儴",
+        remark: "鍔犵彮",
+      },
+      {
+        id: 6,
+        employeeName: "鍒樻槑杈�",
+        department: "杩愯惀閮�",
+        date: "2025-09-03",
+        clockInTime: "09:05:00",
+        clockOutTime: "18:00:00",
+        workHours: "7.92h",
+        status: "normal",
+        location: "鍏徃鎬婚儴",
+        remark: "",
+      },
+      {
+        id: 7,
+        employeeName: "瀛欎附鍗�",
+        department: "璁捐閮�",
+        date: "2025-09-03",
+        clockInTime: "08:59:00",
+        clockOutTime: "18:02:00",
+        workHours: "8.05h",
+        status: "normal",
+        location: "鍏徃鎬婚儴",
+        remark: "",
+      },
+      {
+        id: 8,
+        employeeName: "鍛ㄥ缓鍐�",
+        department: "閿�鍞儴",
+        date: "2025-09-04",
+        clockInTime: "09:15:00",
+        clockOutTime: "18:00:00",
+        workHours: "7.75h",
+        status: "late",
+        location: "鍏徃鎬婚儴",
+        remark: "浜ら�氬牭濉�",
+      },
+      {
+        id: 9,
+        employeeName: "鍚村皬鑺�",
+        department: "瀹㈡湇閮�",
+        date: "2025-09-04",
+        clockInTime: "09:01:00",
+        clockOutTime: "18:00:00",
+        workHours: "7.98h",
+        status: "normal",
+        location: "鍏徃鎬婚儴",
+        remark: "",
+      },
+      {
+        id: 10,
+        employeeName: "椹枃鏉�",
+        department: "鎶�鏈儴",
+        date: "2025-09-05",
+        clockInTime: "08:57:00",
+        clockOutTime: "17:30:00",
+        workHours: "7.55h",
+        status: "early",
+        location: "鍏徃鎬婚儴",
+        remark: "鏈夋�ヤ簨鎻愬墠绂诲紑",
+      },
+      {
+        id: 11,
+        employeeName: "鏋楁檽涓�",
+        department: "琛屾斂閮�",
+        date: "2025-09-05",
+        clockInTime: "09:03:00",
+        clockOutTime: "18:08:00",
+        workHours: "8.08h",
+        status: "normal",
+        location: "鍏徃鎬婚儴",
+        remark: "",
+      },
+      {
+        id: 12,
+        employeeName: "榛勭編鐜�",
+        department: "璐㈠姟閮�",
+        date: "2025-09-06",
+        clockInTime: "",
+        clockOutTime: "",
+        workHours: "0h",
+        status: "absent",
+        location: "",
+        remark: "璇风梾鍋�",
+      },
+      {
+        id: 13,
+        employeeName: "閮戞捣娑�",
+        department: "甯傚満閮�",
+        date: "2025-08-14",
+        clockInTime: "09:00:00",
+        clockOutTime: "18:00:00",
+        workHours: "8.0h",
+        status: "normal",
+        location: "鍏徃鎬婚儴",
+        remark: "",
+      },
+      {
+        id: 14,
+        employeeName: "璋附濞�",
+        department: "浜轰簨閮�",
+        date: "2025-08-20",
+        clockInTime: "08:58:00",
+        clockOutTime: "18:03:00",
+        workHours: "8.08h",
+        status: "normal",
+        location: "鍏徃鎬婚儴",
+        remark: "",
+      },
+      {
+        id: 15,
+        employeeName: "浣曞織浼�",
+        department: "鎶�鏈儴",
+        date: "2025-08-21",
+        clockInTime: "09:10:00",
+        clockOutTime: "18:00:00",
+        workHours: "7.83h",
+        status: "late",
+        location: "鍏徃鎬婚儴",
+        remark: "",
+      },
+      {
+        id: 16,
+        employeeName: "璁搁泤鑺�",
+        department: "璁捐閮�",
+        date: "2025-08-22",
+        clockInTime: "09:01:00",
+        clockOutTime: "18:00:00",
+        workHours: "7.98h",
+        status: "normal",
+        location: "鍏徃鎬婚儴",
+        remark: "",
+      },
+      {
+        id: 17,
+        employeeName: "閭撳缓骞�",
+        department: "杩愯惀閮�",
+        date: "2025-09-10",
+        clockInTime: "08:59:00",
+        clockOutTime: "18:05:00",
+        workHours: "8.1h",
+        status: "normal",
+        location: "鍏徃鎬婚儴",
+        remark: "",
+      },
+      {
+        id: 18,
+        employeeName: "鏇惧皬绾�",
+        department: "瀹㈡湇閮�",
+        date: "2025-09-11",
+        clockInTime: "09:02:00",
+        clockOutTime: "18:00:00",
+        workHours: "7.97h",
+        status: "normal",
+        location: "鍏徃鎬婚儴",
+        remark: "",
+      },
+    ];
+
+    attendanceData.value = mockData;
+    filteredAttendanceData.value = mockData;
+  };
+
+  // 鍒犻櫎椤圭洰
+  const deleteItem = (type, row) => {
+    ElMessageBox.confirm("纭畾瑕佸垹闄よ繖涓」鐩悧锛�", "鎻愮ず", {
+      confirmButtonText: "纭畾",
+      cancelButtonText: "鍙栨秷",
+      type: "warning",
+    }).then(() => {
+      let ids = [];
+      let dataArray;
+      if (type === "holiday") {
+        ids.push(row.id);
+        delHolidaySettings(ids)
+          .then(res => {
+            if (res.code == 200) {
+              ElMessage.success("鍒犻櫎鎴愬姛");
+              ids = [];
+              getHolidaySettingsList();
+            }
+          })
+          .catch(err => {
+            ElMessage.error(err.msg);
+          });
+      } else if (type === "annual") {
+        ids.push(row.id);
+        delAnnualLeaveSetting(ids)
+          .then(res => {
+            if (res.code == 200) {
+              ElMessage.success("鍒犻櫎鎴愬姛");
+              ids = [];
+              getAnnualLeaveSettingList();
+            }
+          })
+          .catch(err => {
+            ElMessage.error(err.msg);
+          });
+      } else if (type === "overtime") {
+        ids.push(row.id);
+        delOvertimeSetting(ids)
+          .then(res => {
+            if (res.code == 200) {
+              ElMessage.success("鍒犻櫎鎴愬姛");
+              ids = [];
+              getOvertimeSettingList();
+            }
+          })
+          .catch(err => {
+            ElMessage.error(err.msg);
+          });
+      } else if (type === "worktime") {
+        ids.push(row.id);
+        delWorkingHoursSetting(ids)
+          .then(res => {
+            if (res.code == 200) {
+              ElMessage.success("鍒犻櫎鎴愬姛");
+              ids = [];
+              getWorkingHoursSettingList();
+            }
+          })
+          .catch(err => {
+            ElMessage.error(err.msg);
+          });
       }
-    }
-  }
-}
 
-// 鍒犻櫎椤圭洰
-const deleteItem = (type, row) => {
-  ElMessageBox.confirm('纭畾瑕佸垹闄よ繖涓」鐩悧锛�', '鎻愮ず', {
-    confirmButtonText: '纭畾',
-    cancelButtonText: '鍙栨秷',
-    type: 'warning'
-  }).then(() => {
-    let dataArray
-    if (type === 'holiday') dataArray = holidayData.value
-    else if (type === 'annual') dataArray = annualData.value
-    else if (type === 'overtime') dataArray = overtimeData.value
-    else if (type === 'worktime') dataArray = worktimeData.value
-    
-    const index = dataArray.findIndex(item => item.id === row.id)
-    if (index > -1) {
-      dataArray.splice(index, 1)
-      ElMessage.success('鍒犻櫎鎴愬姛')
-    }
-  })
-}
+      // const index = dataArray.findIndex(item => item.id === row.id)
+      // if (index > -1) {
+      //   dataArray.splice(index, 1)
+      //   ElMessage.success('鍒犻櫎鎴愬姛')
+      // }
+    });
+  };
+  // 鑾峰彇鍋囨湡璁剧疆鍒楄〃
+  const getHolidaySettingsList = () => {
+    // tableLoading.value = true;
+    listHolidaySettings({ ...page.value })
+      .then(res => {
+        // tableLoading.value = false;
+        holidayData.value = res.data.records;
+        page.total = res.data.total;
+      })
+      .catch(err => {
+        // tableLoading.value = false;
+      });
+  };
+  // 鑾峰彇骞村亣瑙勫垯鍒楄〃
+  const getAnnualLeaveSettingList = () => {
+    listAnnualLeaveSettingList({ ...page.value })
+      .then(res => {
+        // console.log(res.data)
+        annualData.value = res.data.records;
+        page.total = res.data.total;
+      })
+      .catch(err => {});
+  };
+  // 鑾峰彇鍔犵彮瑙勫垯鍒楄〃
+  const getOvertimeSettingList = () => {
+    listOvertimeSettingList({ ...page.value })
+      .then(res => {
+        // console.log(res.data)
+        overtimeData.value = res.data.records;
+        page.total = res.data.total;
+      })
+      .catch(err => {});
+  };
+  // 鑾峰彇宸ヤ綔鏃堕棿瑙勫垯鍒楄〃
+  const getWorkingHoursSettingList = () => {
+    listWorkingHoursSettingList({ ...page.value })
+      .then(res => {
+        // console.log(res.data)
+        worktimeData.value = res.data.records;
+        page.total = res.data.total;
+      })
+      .catch(err => {});
+  };
+  onMounted(() => {
+    getHolidaySettingsList();
+    getAnnualLeaveSettingList();
+    getOvertimeSettingList();
+    getWorkingHoursSettingList();
+    initAttendanceData();
+    console.log("鑰冨嫟绠$悊椤甸潰鍔犺浇瀹屾垚");
+  });
 
-onMounted(() => {
-  console.log('鑰冨嫟绠$悊椤甸潰鍔犺浇瀹屾垚')
-})
-
-onUnmounted(() => {
-  // 娓呯悊宸ヤ綔
-  dialogVisible.value = false
-  currentType.value = ''
-  currentAction.value = ''
-  currentEditId.value = ''
-})
+  onUnmounted(() => {
+    // 娓呯悊宸ヤ綔
+    dialogVisible.value = false;
+    currentType.value = "";
+    currentAction.value = "";
+    currentEditId.value = "";
+  });
 </script>
 
 <style scoped>
-.app-container {
-  padding: 20px;
-}
+  .app-container {
+    padding: 20px;
+  }
 
-.tab-content {
-  padding: 20px 0;
-}
+  .tab-content {
+    padding: 20px 0;
+  }
 
-.dialog-footer {
-  text-align: right;
-}
+  .dialog-footer {
+    text-align: right;
+  }
 
-:deep(.el-tabs__content) {
-  padding: 20px;
-}
+  :deep(.el-tabs__content) {
+    padding: 20px;
+  }
 
-:deep(.el-form-item) {
-  margin-bottom: 20px;
-}
+  :deep(.el-form-item) {
+    margin-bottom: 20px;
+  }
 </style>

--
Gitblit v1.9.3