From 2cf4225d7748322520d5374c92796a23d9517fe1 Mon Sep 17 00:00:00 2001
From: gaoluyang <2820782392@qq.com>
Date: 星期四, 26 二月 2026 10:29:03 +0800
Subject: [PATCH] 湟水峡 1.人员模块代码迁移

---
 src/api/personnelManagement/attendanceRules.js                                   |   45 
 src/views/personnelManagement/payrollManagement/components/formDia.vue           |   14 
 src/views/personnelManagement/payrollManagement/index.vue                        |    1 
 src/views/personnelManagement/scheduling/index.vue                               |   10 
 src/views/personnelManagement/attendanceCheckin/index.vue                        |  507 +++++++
 src/views/personnelManagement/contractManagement/index.vue                       |   20 
 src/views/personnelManagement/attendanceCheckin/checkinRules/components/form.vue |  496 +++++++
 src/views/personnelManagement/selfService/index.vue                              |   12 
 src/api/personnelManagement/staffAnalytics.js                                    |   26 
 src/views/personnelManagement/contractManagement/components/formDia.vue          |   40 
 src/views/personnelManagement/employeeRecord/components/RenewContract.vue        |  141 ++
 src/views/personnelManagement/analytics/index.vue                                |  228 +-
 src/views/personnelManagement/employeeRecord/index.vue                           |   82 +
 src/views/personnelManagement/monthlyStatistics/components/formDia.vue           |  318 ++++
 src/api/personnelManagement/monthlyStatistics.js                                 |   65 +
 src/views/personnelManagement/employeeRecord/components/Show.vue                 |   73 +
 /dev/null                                                                        |  280 ----
 src/views/personnelManagement/dimission/components/formDia.vue                   |  425 ++---
 src/views/personnelManagement/employeeRecord/components/NewOrEditFormDia.vue     |  373 +++++
 src/api/personnelManagement/staffOnJob.js                                        |    9 
 src/views/personnelManagement/attendanceCheckin/checkinRules/index.vue           |  293 ++++
 src/api/personnelManagement/personalAttendanceRecords.js                         |   25 
 src/views/personnelManagement/contractManagement/filesDia.vue                    |   13 
 src/views/personnelManagement/dimission/index.vue                                |   60 
 src/views/personnelManagement/monthlyStatistics/index.vue                        |  303 ++++
 25 files changed, 3,121 insertions(+), 738 deletions(-)

diff --git a/src/api/personnelManagement/attendanceRules.js b/src/api/personnelManagement/attendanceRules.js
new file mode 100644
index 0000000..021442e
--- /dev/null
+++ b/src/api/personnelManagement/attendanceRules.js
@@ -0,0 +1,45 @@
+import request from "@/utils/request";
+
+// 鑾峰彇鎵撳崱瑙勫垯鍒楄〃
+export function getAttendanceRules(query) {
+  return request({
+    url: "/personalAttendanceLocationConfig/listPage",
+    method: "get",
+    params: query,
+  });
+}
+
+// 鏂板鎵撳崱瑙勫垯
+export function addAttendanceRule(data) {
+  return request({
+    url: "/personalAttendanceLocationConfig/add",
+    method: "post",
+    data,
+  });
+}
+
+// 鏇存柊鎵撳崱瑙勫垯
+export function updateAttendanceRule(data) {
+  return request({
+    url: "/attendanceRules/update",
+    method: "put",
+    data,
+  });
+}
+
+// 鍒犻櫎鎵撳崱瑙勫垯
+export function deleteAttendanceRule(ids) {
+  return request({
+    url: `/personalAttendanceLocationConfig/del`,
+    method: "delete",
+    data: ids,
+  });
+}
+
+// 鑾峰彇鍗曚釜鎵撳崱瑙勫垯璇︽儏
+export function getAttendanceRuleDetail(id) {
+  return request({
+    url: `/attendanceRules/detail/${id}`,
+    method: "get",
+  });
+}
diff --git a/src/api/personnelManagement/monthlyStatistics.js b/src/api/personnelManagement/monthlyStatistics.js
new file mode 100644
index 0000000..a070d0f
--- /dev/null
+++ b/src/api/personnelManagement/monthlyStatistics.js
@@ -0,0 +1,65 @@
+import request from "@/utils/request";
+
+// 浜哄憳钖祫鍙拌处鍒楄〃
+export function monthlyStatisticsListPage(query) {
+  return request({
+    url: "/compensationPerformance/listPage",
+    method: "get",
+    params: query,
+  });
+}
+
+// 浜哄憳钖祫鍙拌处璇︽儏
+export function monthlyStatisticsGet(id) {
+  return request({
+    url: "/monthlyStatistics/get",
+    method: "get",
+    params: { id },
+  });
+}
+
+// 鏂板浜哄憳钖祫鍙拌处
+export function monthlyStatisticsAdd(data) {
+  return request({
+    url: "/compensationPerformance/add",
+    method: "post",
+    data,
+  });
+}
+
+// 缂栬緫浜哄憳钖祫鍙拌处
+export function monthlyStatisticsUpdate(data) {
+  return request({
+    url: "/compensationPerformance/update",
+    method: "post",
+    data,
+  });
+}
+
+// 鍒犻櫎浜哄憳钖祫鍙拌处
+export function monthlyStatisticsDelete(ids) {
+  return request({
+    url: "/compensationPerformance/delete",
+    method: "delete",
+    data: ids,
+  });
+}
+
+// 瀵煎嚭浜哄憳钖祫鍙拌处
+export function monthlyStatisticsExport(query) {
+  return request({
+    url: "/compensationPerformance/export",
+    method: "get",
+    params: query,
+    responseType: "blob",
+  });
+}
+
+// 浜哄憳鍒楄〃
+export function staffOnJobList(query) {
+  return request({
+    url: "/staff/staffOnJob/list",
+    method: "get",
+    params: query,
+  });
+}
diff --git a/src/api/personnelManagement/onboarding.js b/src/api/personnelManagement/onboarding.js
deleted file mode 100644
index 39dbf22..0000000
--- a/src/api/personnelManagement/onboarding.js
+++ /dev/null
@@ -1,49 +0,0 @@
-import request from "@/utils/request";
-
-// 鏌ヨ浜哄憳鍏ヨ亴鍒楄〃
-export function staffJoinListPage(query) {
-  return request({
-    url: "/staff/staffJoinLeaveRecord/listPage",
-    method: "get",
-    params: query,
-  });
-}
-// 鏂板浜哄憳鍏ヨ亴
-export function staffJoinAdd(query) {
-  return request({
-    url: "/staff/staffJoinLeaveRecord/add",
-    method: "post",
-    data: query,
-  });
-}
-// 淇敼浜哄憳鍏ヨ亴
-export function staffJoinUpdate(query) {
-  return request({
-    url: "/staff/staffJoinLeaveRecord/update",
-    method: "post",
-    data: query,
-  });
-}
-// 鏌ヨ鍛樺伐鍏ヨ亴淇℃伅
-export function getStaffJoinInfo(query) {
-  return request({
-    url: "/staff/staffJoinLeaveRecord/" + query,
-    method: "get",
-    data: query,
-  });
-}
-// 鍒犻櫎鍛樺伐
-export function staffJoinDel(query) {
-  return request({
-    url: "/staff/staffJoinLeaveRecord/del",
-    method: "delete",
-    data: query,
-  });
-}
-
-export function getStaffOnJob() {
-  return request({
-    url: "/staff/staffOnJob/list",
-    method: "get",
-  });
-}
diff --git a/src/api/personnelManagement/personalAttendanceRecords.js b/src/api/personnelManagement/personalAttendanceRecords.js
new file mode 100644
index 0000000..bdd9e1c
--- /dev/null
+++ b/src/api/personnelManagement/personalAttendanceRecords.js
@@ -0,0 +1,25 @@
+import request from "@/utils/request.js";
+
+export function createPersonalAttendanceRecord(params) {
+    return request({
+        url: "/personalAttendanceRecords",
+        method: "post",
+        data: params,
+    });
+}
+
+export function findPersonalAttendanceRecords(query) {
+    return request({
+        url: "/personalAttendanceRecords/listPage",
+        method: "get",
+        params: query,
+    });
+}
+
+export function findTodayPersonalAttendanceRecord(query) {
+    return request({
+        url: "/personalAttendanceRecords/today",
+        method: "get",
+        params: query,
+    });
+}
\ No newline at end of file
diff --git a/src/api/personnelManagement/staffAnalytics.js b/src/api/personnelManagement/staffAnalytics.js
new file mode 100644
index 0000000..83eb375
--- /dev/null
+++ b/src/api/personnelManagement/staffAnalytics.js
@@ -0,0 +1,26 @@
+import request from "@/utils/request.js";
+
+// 绂昏亴鍘熷洜鍒嗘瀽
+export function findStaffLeaveReasonAnalysis() {
+    return request({
+        url: "/staff/analytics/reason",
+        method: "get"
+    });
+}
+
+// 12涓湀鍛樺伐娴佸姩娴佸け鐜囧垎鏋�
+export function findStaffAnalysisMonthlyTurnoverRateFor12Months() {
+    return request({
+        url: "/staff/analytics/monthly_turnover_rate",
+        method: "get"
+    });
+}
+
+export function findStaffAnalysisTotalStatistic() {
+    return request({
+        url: "/staff/analytics/total_statistic",
+        method: "get"
+    });
+}
+
+
diff --git a/src/api/personnelManagement/staffOnJob.js b/src/api/personnelManagement/staffOnJob.js
index 7da5469..7a14391 100644
--- a/src/api/personnelManagement/staffOnJob.js
+++ b/src/api/personnelManagement/staffOnJob.js
@@ -17,6 +17,15 @@
     })
 }
 
+// 鏌ヨ鍛樺伐鍏ヨ亴淇℃伅
+export function getStaffOnJobInfoByUserName(query) {
+    return request({
+        url: '/staff/staffOnJob/byUserName',
+        method: 'get',
+        params: query,
+    })
+}
+
 // 鏂板鍛樺伐
 export function createStaffOnJob(params) {
     return request({
diff --git a/src/views/personnelManagement/analytics/index.vue b/src/views/personnelManagement/analytics/index.vue
index 2bca335..9e6e449 100644
--- a/src/views/personnelManagement/analytics/index.vue
+++ b/src/views/personnelManagement/analytics/index.vue
@@ -1,5 +1,5 @@
 <template>
-  <div class="app-container analytics-container">
+  <div class="app-container analytics-container" v-loading="loading">
 
     <!-- 鍏抽敭鎸囨爣鍗$墖 -->
     <el-row :gutter="20" class="metrics-cards">
@@ -11,18 +11,18 @@
                 <component :is="item.icon" />
               </el-icon>
             </div>
-              <div class="card-info">
+            <div class="card-info">
               <div class="card-number">
                 <el-skeleton-item v-if="loading" variant="text" style="width: 60px; height: 32px;" />
                 <span v-else>{{ item.value }}{{ item.unit }}</span>
               </div>
               <div class="card-label">{{ item.label }}</div>
-              <div class="card-trend" :class="item.trend > 0 ? 'positive' : 'negative'" v-if="item.showTrend !== false">
-                <el-icon>
-                  <component :is="item.trend > 0 ? 'ArrowUp' : 'ArrowDown'" />
-                </el-icon>
-                {{ Math.abs(item.trend) }}%
-              </div>
+<!--              <div class="card-trend" :class="item.trend > 0 ? 'positive' : 'negative'" v-if="item.showTrend !== false">-->
+<!--                <el-icon>-->
+<!--                  <component :is="item.trend > 0 ? 'ArrowUp' : 'ArrowDown'" />-->
+<!--                </el-icon>-->
+<!--                {{ Math.abs(item.trend) }}%-->
+<!--              </div>-->
             </div>
           </div>
         </el-card>
@@ -64,21 +64,6 @@
 
     <!-- 绗簩琛屽浘琛� -->
     <el-row :gutter="20" class="charts-section">
-      <!-- 缂栧埗杈炬垚鐜� -->
-      <el-col :span="12">
-        <el-card class="chart-card">
-          <template #header>
-            <div class="card-header">
-              <span>缂栧埗杈炬垚鐜�</span>
-              <el-tag type="warning">鍚勯儴闂ㄥ姣�</el-tag>
-            </div>
-          </template>
-          <div class="chart-container">
-            <div ref="staffingChartRef" class="chart"></div>
-          </div>
-        </el-card>
-      </el-col>
-
       <!-- 鍛樺伐娴佸け鍘熷洜鍒嗘瀽 -->
       <el-col :span="12">
         <el-card class="chart-card">
@@ -98,19 +83,15 @@
 </template>
 
 <script setup>
-import { ref, reactive, onMounted, onUnmounted } from 'vue'
+import { ref, onMounted, onUnmounted, nextTick } from 'vue'
 import { ElMessage } from 'element-plus'
-import { 
-  Refresh, 
-  User, 
-  TrendCharts, 
-  DataAnalysis, 
-  PieChart,
-  ArrowUp,
-  ArrowDown
-} from '@element-plus/icons-vue'
 import * as echarts from 'echarts'
-import { staffOnJobListPage } from '@/api/personnelManagement/employeeRecord.js'
+import {listDept} from "@/api/system/dept.js";
+import {
+  findStaffAnalysisMonthlyTurnoverRateFor12Months,
+  findStaffLeaveReasonAnalysis,
+  findStaffAnalysisTotalStatistic
+} from "@/api/personnelManagement/staffAnalytics.js";
 
 // 鍝嶅簲寮忔暟鎹�
 const loading = ref(false)
@@ -151,14 +132,6 @@
     trend: 0
   },
   {
-    label: '缂栧埗杈炬垚鐜�',
-    value: 0,
-    unit: '%',
-    icon: 'DataAnalysis',
-    type: 'success',
-    trend: 0
-  },
-  {
     label: '鍦ㄨ亴鍛樺伐鏁�',
     value: 0,
     unit: '浜�',
@@ -171,16 +144,56 @@
 
 // 閮ㄩ棬鏁版嵁
 const departmentData = ref([])
+// 鍛樺伐娴佸け鍘熷洜鍒嗘瀽鏁版嵁
+const staffLeaveReasons = ref([])
+// 12涓湀鍛樺伐娴佸姩娴佸け鐜囧垎鏋愭暟鎹�
+const turnoverRateStatistics = ref([])
 
-// 鑾峰彇鍦ㄨ亴鍛樺伐鏁�
-const getStaffCount = async () => {
+// 鑾峰彇閮ㄩ棬鏁版嵁
+const getDepartmentData = async () => {
   try {
-    const res = await staffOnJobListPage({ staffState: 1, current: 1, size: 1 })
+    const res = await listDept()
     if (res && res.data) {
-      keyMetrics.value[3].value = res.data.total || 0
+      departmentData.value = res.data
     }
   } catch (error) {
-    console.error('鑾峰彇鍦ㄨ亴鍛樺伐鏁板け璐�:', error)
+    console.error('鑾峰彇閮ㄩ棬鏁版嵁澶辫触:', error)
+  }
+}
+
+const getStaffLeaveReasonAnalysis = async () => {
+  try {
+    const res = await findStaffLeaveReasonAnalysis()
+    if (res && res.data) {
+      staffLeaveReasons.value = res.data || []
+    }
+  } catch (error) {
+    console.error('鑾峰彇鍛樺伐娴佸け鍘熷洜鍒嗘瀽澶辫触:', error)
+  }
+}
+
+// 淇敼涓鸿繑鍥濸romise鐨勫紓姝ュ嚱鏁�
+const getMonthlyTurnoverRateFor12Months = async () => {
+  try {
+    const res = await findStaffAnalysisMonthlyTurnoverRateFor12Months()
+    if (res && res.data) {
+      turnoverRateStatistics.value = res.data || []
+    }
+  } catch (error) {
+    console.error('鑾峰彇12涓湀鍛樺伐娴佸姩娴佸け鐜囧垎鏋愭暟鎹け璐�:', error)
+  }
+}
+
+const getStaffAnalysisTotalStatistic = async () => {
+  try {
+    const res = await findStaffAnalysisTotalStatistic()
+    if (res && res.data) {
+      keyMetrics.value[0].value = res.data.totalFlowRate || 0
+      keyMetrics.value[1].value = res.data.totalTurnoverRate || 0
+      keyMetrics.value[2].value = res.data.currentOnJobCount || 0
+    }
+  } catch (error) {
+    console.error('鑾峰彇鍛樺伐鍒嗘瀽鎬荤粺璁℃暟鎹け璐�:', error)
   }
 }
 
@@ -213,49 +226,28 @@
   }
 }
 
-// 鐢熸垚妯℃嫙鏁版嵁
-const generateMockData = () => {
-  // 鐢熸垚鍏抽敭鎸囨爣鏁版嵁
-  keyMetrics.value[0].value = (Math.random() * 5 + 2).toFixed(1)
-  keyMetrics.value[0].trend = (Math.random() * 3 - 1.5).toFixed(1)
-  
-  keyMetrics.value[1].value = (Math.random() * 3 + 1).toFixed(1)
-  keyMetrics.value[1].trend = (Math.random() * 2 - 1).toFixed(1)
-  
-  keyMetrics.value[2].value = (Math.random() * 15 + 85).toFixed(1)
-  keyMetrics.value[2].trend = (Math.random() * 3 - 1.5).toFixed(1)
-
-  // 鐢熸垚閮ㄩ棬鏁版嵁
-  const departments = ['鎶�鏈儴', '閿�鍞儴', '浜轰簨閮�', '璐㈠姟閮�', '鐢熶骇閮�', '甯傚満閮�']
-  departmentData.value = departments.map(dept => ({
-    department: dept,
-    currentStaff: Math.floor(Math.random() * 30 + 20),
-    plannedStaff: Math.floor(Math.random() * 10 + 35),
-    staffingRate: Math.floor(Math.random() * 20 + 80),
-    turnoverRate: (Math.random() * 4 + 1).toFixed(1),
-    attritionRate: (Math.random() * 2 + 0.5).toFixed(1),
-    newHires: Math.floor(Math.random() * 5 + 1),
-    resignations: Math.floor(Math.random() * 3 + 1),
-    status: Math.random() > 0.7 ? '寮傚父' : '姝e父'
-  }))
-}
-
-// 鍒锋柊鏁版嵁
+// 淇敼涓哄紓姝ュ嚱鏁帮紝纭繚鏁版嵁鍔犺浇瀹屾垚鍚庡啀娓叉煋鍥捐〃
 const refreshData = async () => {
-  loading.value = true
   try {
-    // 妯℃嫙API璋冪敤寤惰繜
-    await new Promise(resolve => setTimeout(resolve, 500))
-    
-    generateMockData()
+    loading.value = true
+
+    // 绛夊緟鎵�鏈夋暟鎹姞杞藉畬鎴�
+    await Promise.all([
+      getDepartmentData(),
+      getStaffLeaveReasonAnalysis(),
+      getMonthlyTurnoverRateFor12Months(),
+      getStaffAnalysisTotalStatistic()
+    ])
+
+    await nextTick()
     renderAllCharts()
-    
+
     if (!autoRefreshEnabled.value) {
       ElMessage.success('鏁版嵁鍒锋柊鎴愬姛')
     }
   } catch (error) {
-    console.error('鍒锋柊鏁版嵁澶辫触:', error)
-    ElMessage.error('鍒锋柊鏁版嵁澶辫触')
+    console.error('鏁版嵁鍒锋柊澶辫触:', error)
+    ElMessage.error('鏁版嵁鍒锋柊澶辫触')
   } finally {
     loading.value = false
   }
@@ -276,8 +268,9 @@
     if (attritionChartRef.value) {
       attritionChart = echarts.init(attritionChartRef.value)
     }
-    
-    renderAllCharts()
+
+    // 鍒濆鍖栨椂涔熷厛鍔犺浇鏁版嵁鍐嶆覆鏌撳浘琛�
+    refreshData()
   }, 300)
 }
 
@@ -289,14 +282,15 @@
   renderAttritionChart()
 }
 
-// 娓叉煋鍛樺伐娴佸姩鐜囪秼鍔垮浘
+// 淇敼涓轰娇鐢ˋPI杩斿洖鐨勫疄闄呮暟鎹�
 const renderTurnoverChart = () => {
   if (!turnoverChart) return
-  
-  const months = ['1鏈�', '2鏈�', '3鏈�', '4鏈�', '5鏈�', '6鏈�', '7鏈�', '8鏈�', '9鏈�', '10鏈�', '11鏈�', '12鏈�']
-  const turnoverData = months.map(() => (Math.random() * 5 + 2).toFixed(1))
-  const attritionData = months.map(() => (Math.random() * 3 + 1).toFixed(1))
-  
+
+  // 浣跨敤API杩斿洖鐨勫疄闄呮暟鎹�
+  const months = turnoverRateStatistics.value.map(item => item.month)
+  const turnoverData = turnoverRateStatistics.value.map(item => item.flowRate || 0)
+  const attritionData = turnoverRateStatistics.value.map(item => item.turnoverRate || 0)
+
   const option = {
     title: {
       text: '鍛樺伐娴佸姩鐜囪秼鍔�',
@@ -346,19 +340,19 @@
       }
     ]
   }
-  
+
   turnoverChart.setOption(option)
 }
 
 // 娓叉煋閮ㄩ棬浜哄憳鍒嗗竷鍥�
 const renderDepartmentChart = () => {
   if (!departmentChart) return
-  
+
   const data = departmentData.value.map(item => ({
-    name: item.department,
-    value: item.currentStaff
+    name: item.deptName,
+    value: item.staffCount
   }))
-  
+
   const option = {
     title: {
       text: '閮ㄩ棬浜哄憳鍒嗗竷',
@@ -391,17 +385,17 @@
       }
     ]
   }
-  
+
   departmentChart.setOption(option)
 }
 
 // 娓叉煋缂栧埗杈炬垚鐜囧浘
 const renderStaffingChart = () => {
   if (!staffingChart) return
-  
-  const departments = departmentData.value.map(item => item.department)
+
+  const departments = departmentData.value.map(item => item.deptName)
   const rates = departmentData.value.map(item => item.staffingRate)
-  
+
   const option = {
     title: {
       text: '缂栧埗杈炬垚鐜�',
@@ -445,17 +439,17 @@
       }
     ]
   }
-  
+
   staffingChart.setOption(option)
 }
 
 // 娓叉煋鍛樺伐娴佸け鍘熷洜鍒嗘瀽鍥�
 const renderAttritionChart = () => {
   if (!attritionChart) return
-  
-  const reasons = ['钖祫寰呴亣', '鑱屼笟鍙戝睍', '宸ヤ綔鐜', '涓汉鍘熷洜', '鍏朵粬']
-  const data = reasons.map(() => Math.floor(Math.random() * 20 + 5))
-  
+
+  const reasons = staffLeaveReasons.value.map(item => item.reasonText)
+  const data = staffLeaveReasons.value.map(item => item.count)
+
   const option = {
     title: {
       text: '鍛樺伐娴佸け鍘熷洜鍒嗘瀽',
@@ -491,14 +485,12 @@
       }
     ]
   }
-  
+
   attritionChart.setOption(option)
 }
- 
+
 // 鐢熷懡鍛ㄦ湡
 onMounted(() => {
-  generateMockData()
-  getStaffCount()
   initCharts()
   startAutoRefresh()
 })
@@ -663,32 +655,32 @@
   .analytics-container {
     padding: 10px;
   }
-  
+
   .page-header {
     padding: 15px;
   }
-  
+
   .page-header h2 {
     font-size: 24px;
   }
-  
+
   .header-controls {
     flex-direction: column;
     gap: 15px;
   }
-  
+
   .refresh-btn {
     margin-left: 0;
   }
-  
+
   .metrics-cards .el-col {
     margin-bottom: 15px;
   }
-  
+
   .charts-section .el-col {
     margin-bottom: 20px;
   }
-  
+
   .chart-container {
     height: 300px;
   }
@@ -698,11 +690,11 @@
   .page-header h2 {
     font-size: 20px;
   }
-  
+
   .card-number {
     font-size: 24px;
   }
-  
+
   .chart-container {
     height: 250px;
   }
diff --git a/src/views/personnelManagement/attendanceCheckin/checkinRules/components/form.vue b/src/views/personnelManagement/attendanceCheckin/checkinRules/components/form.vue
new file mode 100644
index 0000000..11e21bc
--- /dev/null
+++ b/src/views/personnelManagement/attendanceCheckin/checkinRules/components/form.vue
@@ -0,0 +1,496 @@
+<template>
+  <el-dialog v-model="dialogVisible"
+             :title="dialogTitle"
+             width="700px"
+             :close-on-click-modal="false">
+    <el-form ref="formRef"
+             :model="form"
+             :rules="rules"
+             label-width="120px"
+             class="mt8">
+      <!-- 閮ㄩ棬閫夋嫨 -->
+      <el-form-item label="閮ㄩ棬"
+                    prop="sysDeptId">
+        <el-tree-select v-model="form.sysDeptId"
+                        :data="deptOptions"
+                        :props="{ value: 'id', label: 'label', children: 'children' }"
+                        value-key="id"
+                        placeholder="璇烽�夋嫨閮ㄩ棬"
+                        check-strictly
+                        style="width: 100%"
+                        :disabled="['edit', 'view'].includes(operationType)" />
+      </el-form-item>
+      <!-- 鍦扮偣淇℃伅 -->
+      <!-- <el-form-item label="鍦扮偣鍚嶇О"
+                    prop="locationName">
+        <el-input v-model="form.locationName"
+                  placeholder="璇疯緭鍏ュ湴鐐瑰悕绉�"
+                  :disabled="operationType === 'view'" />
+      </el-form-item> -->
+      <!-- 鎵撳崱鑼冨洿 -->
+      <el-form-item label="鎵撳崱鑼冨洿(m)"
+                    prop="radius">
+        <el-input-number v-model="form.radius"
+                         :min="10"
+                         :max="1000"
+                         :step="10"
+                         placeholder="璇疯緭鍏ユ墦鍗¤寖鍥�"
+                         :disabled="operationType === 'view'" />
+      </el-form-item>
+      <!-- 楂樺痉鍦板浘閫夋嫨 -->
+      <el-form-item label="鎵撳崱浣嶇疆"
+                    prop="longitude">
+        <div class="map-container">
+          <div class="map-header"
+               style="margin-bottom: 10px">
+            <!-- <el-button @click="getCurrentLocation">
+              <el-icon>
+                <Position />
+              </el-icon>
+              褰撳墠浣嶇疆
+            </el-button> -->
+            <!-- <span style="margin-left: 10px; color: #909399;font-size: 12px;">鐐瑰嚮鍦板浘閫夋嫨浣嶇疆</span> -->
+          </div>
+          <div id="map-container"
+               class="map"
+               ref="mapContainer"></div>
+          <div class="coordinates-info mt10">
+            <el-input v-model="form.longitude"
+                      readonly
+                      placeholder="缁忓害"
+                      style="width: 140px; margin-right: 10px" />
+            <el-input v-model="form.latitude"
+                      readonly
+                      placeholder="绾害"
+                      style="width: 140px; margin-right: 10px" />
+            <!-- <el-input v-model="form.locationName"
+                      placeholder="鍦扮偣鍚嶇О"
+                      style="width: calc(100% - 290px)" /> -->
+          </div>
+        </div>
+      </el-form-item>
+      <el-form-item label="鍦扮偣鍚嶇О"
+                    prop="locationName">
+        <el-input v-model="form.locationName"
+                  :disabled="operationType === 'view'"
+                  placeholder="璇疯緭鍏ュ湴鐐瑰悕绉�" />
+      </el-form-item>
+      <!-- 涓婁笅鐝椂闂� -->
+      <el-form-item label="涓婄彮鏃堕棿"
+                    prop="startAt">
+        <el-time-picker v-model="form.startAt"
+                        format="HH:mm"
+                        value-format="HH:mm"
+                        placeholder="璇烽�夋嫨涓婄彮鏃堕棿"
+                        :disabled="operationType === 'view'" />
+      </el-form-item>
+      <el-form-item label="涓嬬彮鏃堕棿"
+                    prop="endAt">
+        <el-time-picker v-model="form.endAt"
+                        format="HH:mm"
+                        value-format="HH:mm"
+                        :picker-options="{
+      minTime: form.startAt
+    }"
+                        placeholder="璇烽�夋嫨涓嬬彮鏃堕棿"
+                        :disabled="operationType === 'view'" />
+      </el-form-item>
+    </el-form>
+    <template #footer>
+      <span class="dialog-footer">
+        <el-button @click="dialogVisible = false">鍙栨秷</el-button>
+        <el-button type="primary"
+                   @click="submitForm"
+                   v-if="operationType !== 'view'">
+          纭畾
+        </el-button>
+      </span>
+    </template>
+  </el-dialog>
+</template>
+
+<script setup>
+  import { ref, reactive, computed, watch, onMounted, nextTick } from "vue";
+  import { ElMessage } from "element-plus";
+  import { Position } from "@element-plus/icons-vue";
+  import { deptTreeSelect } from "@/api/system/user.js";
+  import { addAttendanceRule } from "@/api/personnelManagement/attendanceRules.js";
+
+  const props = defineProps({
+    modelValue: {
+      type: Boolean,
+      default: false,
+    },
+    operationType: {
+      type: String,
+      default: "add",
+    },
+    row: {
+      type: Object,
+      default: () => ({}),
+    },
+  });
+  // const pickerOptions = ref({ minTime: form.value.startAt });
+
+  const emit = defineEmits(["update:modelValue", "close"]);
+
+  const dialogVisible = computed({
+    get: () => props.modelValue,
+    set: val => emit("update:modelValue", val),
+  });
+
+  const dialogTitle = computed(() => {
+    if (props.operationType === "add") return "鏂板鎵撳崱瑙勫垯";
+    if (props.operationType === "edit") return "缂栬緫鎵撳崱瑙勫垯";
+    return "鏌ョ湅鎵撳崱瑙勫垯";
+  });
+
+  // 琛ㄥ崟鏁版嵁
+  const formRef = ref();
+  const form = reactive({
+    id: "",
+    sysDeptId: "",
+    locationName: "",
+    longitude: "",
+    latitude: "",
+    radius: 100,
+    startAt: "09:00",
+    endAt: "18:00",
+  });
+
+  // 琛ㄥ崟楠岃瘉瑙勫垯
+  const rules = {
+    sysDeptId: [{ required: true, message: "璇烽�夋嫨閮ㄩ棬", trigger: "change" }],
+    locationName: [
+      { required: true, message: "璇疯緭鍏ュ湴鐐瑰悕绉�", trigger: "blur" },
+    ],
+    longitude: [{ required: true, message: "璇烽�夋嫨鎵撳崱浣嶇疆", trigger: "blur" }],
+    latitude: [{ required: true, message: "璇烽�夋嫨鎵撳崱浣嶇疆", trigger: "blur" }],
+    radius: [{ required: true, message: "璇疯緭鍏ユ墦鍗¤寖鍥�", trigger: "blur" }],
+    startAt: [{ required: true, message: "璇烽�夋嫨涓婄彮鏃堕棿", trigger: "change" }],
+    endAt: [
+      { required: true, message: "璇烽�夋嫨涓嬬彮鏃堕棿", trigger: "change" },
+      {
+        validator: (rule, value, callback) => {
+          if (form.startAt && value) {
+            const startParts = form.startAt.split(":");
+            const endParts = value.split(":");
+            const startTime =
+              parseInt(startParts[0]) * 60 + parseInt(startParts[1]);
+            const endTime = parseInt(endParts[0]) * 60 + parseInt(endParts[1]);
+            if (endTime <= startTime) {
+              callback(new Error("涓嬬彮鏃堕棿涓嶈兘鏃╀簬涓婄彮鏃堕棿"));
+            } else {
+              callback();
+            }
+          } else {
+            callback();
+          }
+        },
+        trigger: "change",
+      },
+    ],
+  };
+
+  // 閮ㄩ棬閫夐」
+  const deptOptions = ref([]);
+
+  // 鍦板浘鐩稿叧
+  const mapContainer = ref(null);
+  let map = null;
+  let marker = null;
+  let circle = null;
+
+  // 鑾峰彇閮ㄩ棬鍒楄〃
+  const fetchDeptOptions = () => {
+    deptTreeSelect().then(response => {
+      deptOptions.value = filterDisabledDept(
+        JSON.parse(JSON.stringify(response.data))
+      );
+    });
+  };
+
+  // 杩囨护绂佺敤鐨勯儴闂�
+  const filterDisabledDept = deptList => {
+    return deptList.filter(dept => {
+      if (dept.disabled) {
+        return false;
+      }
+      if (dept.children && dept.children.length) {
+        dept.children = filterDisabledDept(dept.children);
+      }
+      return true;
+    });
+  };
+
+  // 鍒濆鍖栧湴鍥�
+  const initMap = () => {
+    nextTick(() => {
+      if (window.AMap && mapContainer.value) {
+        // 鍒濆鍖栧湴鍥�
+        map = new window.AMap.Map(mapContainer.value, {
+          zoom: 16,
+          center: [116.397428, 39.90923], // 榛樿鍖椾含
+        });
+
+        // 娣诲姞鎺т欢
+        window.AMap.plugin(["AMap.ToolBar", "AMap.Scale"], function () {
+          map.addControl(new window.AMap.ToolBar());
+          map.addControl(new window.AMap.Scale());
+        });
+
+        // 娣诲姞鏍囪
+        marker = new window.AMap.Marker({
+          position: [116.397428, 39.90923],
+          draggable: true,
+          cursor: "move",
+          title: "鎷栨嫿瀹氫綅",
+        });
+        map.add(marker);
+
+        // 娣诲姞鍦嗗舰鑼冨洿
+        circle = new window.AMap.Circle({
+          center: [116.397428, 39.90923],
+          radius: form.radius,
+          strokeColor: "#3366FF",
+          strokeOpacity: 0.8,
+          strokeWeight: 2,
+          fillColor: "#3366FF",
+          fillOpacity: 0.2,
+        });
+        map.add(circle);
+
+        // 鐩戝惉鏍囪鎷栨嫿
+        marker.on("dragend", e => {
+          const position = e.lnglat;
+          const lng = position.getLng();
+          const lat = position.getLat();
+          form.longitude = lng;
+          form.latitude = lat;
+          updateCircle(position);
+        });
+
+        // 鐩戝惉鏍囪鎷栨嫿寮�濮�
+        marker.on("dragstart", () => {
+          map.setDefaultCursor("move");
+        });
+
+        // 鐩戝惉鏍囪鎷栨嫿缁撴潫
+        marker.on("dragend", () => {
+          map.setDefaultCursor("default");
+        });
+
+        // 鐩戝惉鍦板浘鐐瑰嚮
+        map.on("click", e => {
+          const position = e.lnglat;
+          const lng = position.getLng();
+          const lat = position.getLat();
+          form.longitude = lng;
+          form.latitude = lat;
+          updateMarker(position);
+          updateCircle(position);
+        });
+
+        // 灏濊瘯鑾峰彇褰撳墠浣嶇疆骞惰缃负鍦板浘涓績
+        if (navigator.geolocation && !form.longitude && !form.latitude) {
+          navigator.geolocation.getCurrentPosition(
+            position => {
+              console.log("鑾峰彇鍒板綋鍓嶄綅缃�:", position);
+              const { longitude, latitude } = position.coords;
+              const currentPosition = [longitude, latitude];
+              map.setCenter(currentPosition);
+              updateMarker(currentPosition);
+              updateCircle(currentPosition);
+              form.longitude = longitude;
+              form.latitude = latitude;
+            },
+            error => {
+              console.log("鑾峰彇浣嶇疆澶辫触锛屼娇鐢ㄩ粯璁や綅缃�");
+            }
+          );
+        } else if (form.longitude && form.latitude) {
+          // 濡傛灉鏈夋暟鎹紝璁剧疆鍒板湴鍥�
+          const position = [form.longitude, form.latitude];
+          map.setCenter(position);
+          updateMarker(position);
+          updateCircle(position);
+        }
+      }
+    });
+  };
+
+  // 鏇存柊鏍囪浣嶇疆
+  const updateMarker = position => {
+    if (marker) {
+      marker.setPosition(position);
+    }
+  };
+
+  // 鏇存柊鍦嗗舰鑼冨洿
+  const updateCircle = position => {
+    if (circle) {
+      circle.setCenter(position);
+      circle.setRadius(form.radius);
+    }
+  };
+
+  // 鑾峰彇褰撳墠浣嶇疆
+  const getCurrentLocation = () => {
+    if (navigator.geolocation) {
+      navigator.geolocation.getCurrentPosition(
+        position => {
+          const { longitude, latitude } = position.coords;
+          form.longitude = longitude;
+          form.latitude = latitude;
+          if (map) {
+            map.setCenter([longitude, latitude]);
+            updateMarker([longitude, latitude]);
+            updateCircle([longitude, latitude]);
+          }
+
+          // 閫嗗湴鐞嗙紪鐮佽幏鍙栧湴鍧�
+          if (window.AMap) {
+            // 鍔犺浇Geocoder鎻掍欢
+            window.AMap.plugin("AMap.Geocoder", function () {
+              const geocoder = new window.AMap.Geocoder();
+              geocoder.getAddress([longitude, latitude], (status, result) => {
+                if (status === "complete" && result.regeocode) {
+                  form.locationName = result.regeocode.formattedAddress;
+                }
+              });
+            });
+          }
+        },
+        error => {
+          ElMessage.error("鑾峰彇浣嶇疆澶辫触锛岃鎵嬪姩閫夋嫨");
+        }
+      );
+    } else {
+      ElMessage.error("娴忚鍣ㄤ笉鏀寔鍦扮悊瀹氫綅");
+    }
+  };
+
+  // 鐩戝惉鍗婂緞鍙樺寲
+  watch(
+    () => form.radius,
+    newValue => {
+      if (circle) {
+        circle.setRadius(newValue);
+      }
+    }
+  );
+
+  // 鐩戝惉涓婄彮鏃堕棿鍙樺寲锛岃Е鍙戜笅鐝椂闂存牎楠�
+  watch(
+    () => form.startAt,
+    () => {
+      if (formRef.value && form.endAt) {
+        formRef.value.validateField("endAt");
+      }
+    }
+  );
+
+  // 鐩戝惉寮圭獥鏄剧ず
+  watch(
+    () => dialogVisible.value,
+    newValue => {
+      if (newValue) {
+        // 閲嶇疆琛ㄥ崟
+        Object.assign(form, {
+          id: "",
+          sysDeptId: "",
+          locationName: "",
+          longitude: "",
+          latitude: "",
+          radius: 100,
+          startAt: "09:00",
+          endAt: "18:00",
+        });
+
+        // 濡傛灉鏄紪杈戞垨鏌ョ湅锛屽~鍏呮暟鎹�
+        if (props.operationType !== "add" && props.row.id) {
+          // 澶勭悊鏃堕棿鏍煎紡锛岀‘淇濇槸HH:mm鏍煎紡
+          const rowData = { ...props.row };
+          if (rowData.startAt && rowData.startAt.includes(":")) {
+            rowData.startAt = rowData.startAt.split(":").slice(0, 2).join(":");
+          }
+          if (rowData.endAt && rowData.endAt.includes(":")) {
+            rowData.endAt = rowData.endAt.split(":").slice(0, 2).join(":");
+          }
+          Object.assign(form, rowData);
+        }
+
+        // 鍒濆鍖栧湴鍥�
+        setTimeout(() => {
+          initMap();
+        }, 100);
+      }
+    }
+  );
+
+  // 鎻愪氦琛ㄥ崟
+  const submitForm = () => {
+    formRef.value.validate(valid => {
+      if (valid) {
+        const submitData = {
+          ...form,
+          // 杞崲鏃堕棿鏍煎紡锛岀‘淇濆彧淇濈暀鏃跺垎閮ㄥ垎
+          startAt: form.startAt
+            ? `${form.startAt.split(":").slice(0, 2).join(":")}`
+            : null,
+          endAt: form.endAt
+            ? `${form.endAt.split(":").slice(0, 2).join(":")}`
+            : null,
+        };
+
+        if (props.operationType === "add") {
+          addAttendanceRule(submitData).then(() => {
+            ElMessage.success("鏂板鎴愬姛");
+            emit("close");
+          });
+        } else if (props.operationType === "edit") {
+          addAttendanceRule(submitData).then(() => {
+            ElMessage.success("鏇存柊鎴愬姛");
+            emit("close");
+          });
+        }
+      }
+    });
+  };
+
+  // 鍒濆鍖�
+  onMounted(() => {
+    fetchDeptOptions();
+  });
+</script>
+
+<style scoped lang="scss">
+  .map-container {
+    width: 100%;
+  }
+
+  .map {
+    width: 100%;
+    height: 400px;
+    border: 1px solid #e4e7ed;
+  }
+
+  .coordinates-info {
+    display: flex;
+    gap: 10px;
+  }
+
+  .coordinates-display {
+    padding: 10px;
+    background-color: #f5f7fa;
+    border-radius: 4px;
+  }
+
+  .mt10 {
+    margin-top: 10px;
+  }
+
+  .mt8 {
+    margin-top: 8px;
+  }
+</style>
\ No newline at end of file
diff --git a/src/views/personnelManagement/attendanceCheckin/checkinRules/index.vue b/src/views/personnelManagement/attendanceCheckin/checkinRules/index.vue
new file mode 100644
index 0000000..1fd19f3
--- /dev/null
+++ b/src/views/personnelManagement/attendanceCheckin/checkinRules/index.vue
@@ -0,0 +1,293 @@
+<template>
+  <div class="app-container">
+    <!-- 椤甸潰鏍囬鍜屾搷浣滄寜閽� -->
+    <div class="page-header">
+      <div class="title">鎵撳崱瑙勫垯閰嶇疆</div>
+      <div class="actions">
+        <el-button type="primary"
+                   @click="openForm('add')">
+          <el-icon>
+            <Plus />
+          </el-icon>
+          鏂板瑙勫垯
+        </el-button>
+      </div>
+    </div>
+    <!-- 鏌ヨ鏉′欢 -->
+    <!-- <el-form :model="searchForm"
+             :inline="true"
+             class="search-form mb16">
+      <el-form-item label="閮ㄩ棬锛�"
+                    prop="countId">
+        <el-tree-select v-model="searchForm.countId"
+                        :data="deptOptions"
+                        :props="{ value: 'id', label: 'label', children: 'children' }"
+                        value-key="id"
+                        placeholder="璇烽�夋嫨閮ㄩ棬"
+                        check-strictly
+                        style="width: 200px" />
+      </el-form-item>
+      <el-form-item label="鍦扮偣锛�"
+                    prop="locationName">
+        <el-input v-model="searchForm.locationName"
+                  placeholder="璇疯緭鍏ュ湴鐐瑰悕绉�"
+                  clearable
+                  style="width: 200px" />
+      </el-form-item>
+      <el-form-item>
+        <el-button type="primary"
+                   @click="fetchData">
+          <el-icon>
+            <Search />
+          </el-icon>
+          鎼滅储
+        </el-button>
+        <el-button @click="resetSearch">
+          <el-icon>
+            <Refresh />
+          </el-icon>
+          閲嶇疆
+        </el-button>
+      </el-form-item>
+    </el-form> -->
+    <!-- 瑙勫垯鍒楄〃 -->
+    <el-card shadow="never"
+             class="mb16">
+      <el-table :data="tableData"
+                border
+                v-loading="tableLoading"
+                style="width: 100%"
+                row-key="id">
+        <el-table-column type="index"
+                         label="搴忓彿"
+                         width="60"
+                         align="center" />
+        <el-table-column label="閮ㄩ棬">
+          <template #default="scope">
+            {{ getDeptNameById(scope.row.sysDeptId) }}
+          </template>
+        </el-table-column>
+        <el-table-column prop="locationName"
+                         label="鍦扮偣鍚嶇О" />
+        <el-table-column prop="longitude"
+                         label="缁忓害" />
+        <el-table-column prop="latitude"
+                         label="绾害" />
+        <el-table-column prop="radius"
+                         label="鎵撳崱鑼冨洿(m)" />
+        <el-table-column prop="startAt"
+                         label="涓婄彮鏃堕棿">
+          <template #default="scope">
+            {{ scope.row.startAt }}
+          </template>
+        </el-table-column>
+        <el-table-column prop="endAt"
+                         label="涓嬬彮鏃堕棿">
+          <template #default="scope">
+            {{ scope.row.endAt }}
+          </template>
+        </el-table-column>
+        <el-table-column label="鎿嶄綔"
+                         width="180"
+                         fixed="right"
+                         align="center">
+          <template #default="scope">
+            <el-button type="primary"
+                       size="small"
+                       link
+                       @click="openForm('edit', scope.row)">缂栬緫</el-button>
+            <el-button type="danger"
+                       size="small"
+                       link
+                       @click="handleDelete(scope.row.id)">鍒犻櫎</el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+      <pagination :total="page.total"
+                  layout="total, sizes, prev, pager, next, jumper"
+                  :page="page.current"
+                  :limit="page.size"
+                  @pagination="paginationChange"
+                  class="mt10" />
+    </el-card>
+    <!-- 鏂板/缂栬緫瑙勫垯寮圭獥 -->
+    <rule-form ref="ruleFormRef"
+               v-model="dialogVisible"
+               :operation-type="operationType"
+               :row="currentRow"
+               @close="dialogVisible = false; fetchData()" />
+  </div>
+</template>
+
+<script setup>
+  import { ref, reactive, onMounted } from "vue";
+  import { ElMessage, ElMessageBox } from "element-plus";
+  import { Plus, Edit, Delete, Search, Refresh } from "@element-plus/icons-vue";
+  import Pagination from "@/components/Pagination/index.vue";
+  import RuleForm from "./components/form.vue";
+  import { deptTreeSelect } from "@/api/system/user.js";
+  import {
+    getAttendanceRules,
+    deleteAttendanceRule,
+  } from "@/api/personnelManagement/attendanceRules.js";
+
+  const { proxy } = getCurrentInstance();
+
+  // 琛ㄦ牸鏁版嵁
+  const tableData = ref([]);
+  const tableLoading = ref(false);
+
+  // 鍒嗛〉鍙傛暟
+  const page = reactive({
+    current: 1,
+    size: 10,
+    total: 0,
+  });
+
+  // 鏌ヨ琛ㄥ崟
+  const searchForm = reactive({
+    countId: "",
+    locationName: "",
+  });
+
+  // 閮ㄩ棬閫夐」
+  const deptOptions = ref([]);
+
+  // 寮圭獥鎺у埗
+  const dialogVisible = ref(false);
+  const operationType = ref("add");
+  const currentRow = ref({});
+  const ruleFormRef = ref();
+
+  // 鏍煎紡鍖栨椂闂�
+  const formatTime = timestamp => {
+    if (!timestamp) return "";
+    const date = new Date(timestamp);
+    return `${String(date.getHours()).padStart(2, "0")}:${String(
+      date.getMinutes()
+    ).padStart(2, "0")}`;
+  };
+
+  // 鑾峰彇閮ㄩ棬鍒楄〃
+  const fetchDeptOptions = () => {
+    deptTreeSelect().then(response => {
+      deptOptions.value = filterDisabledDept(
+        JSON.parse(JSON.stringify(response.data))
+      );
+    });
+  };
+
+  // 杩囨护绂佺敤鐨勯儴闂�
+  const filterDisabledDept = deptList => {
+    return deptList.filter(dept => {
+      if (dept.disabled) {
+        return false;
+      }
+      if (dept.children && dept.children.length) {
+        dept.children = filterDisabledDept(dept.children);
+      }
+      return true;
+    });
+  };
+
+  // 鏍规嵁閮ㄩ棬ID鏌ユ壘閮ㄩ棬鍚嶇О
+  const getDeptNameById = (deptId, deptList = deptOptions.value) => {
+    for (const dept of deptList) {
+      if (dept.id === deptId) {
+        return dept.label;
+      }
+      if (dept.children && dept.children.length) {
+        const name = getDeptNameById(deptId, dept.children);
+        if (name) {
+          return name;
+        }
+      }
+    }
+    return "";
+  };
+
+  // 鏌ヨ瑙勫垯鍒楄〃
+  const fetchData = () => {
+    tableLoading.value = true;
+    getAttendanceRules({ ...page, ...searchForm })
+      .then(res => {
+        tableData.value = res.data.records;
+        page.total = res.data.total;
+      })
+      .finally(() => {
+        tableLoading.value = false;
+      });
+  };
+
+  // 鍒嗛〉鍙樻洿
+  const paginationChange = pagination => {
+    page.current = pagination.page;
+    page.size = pagination.limit;
+    fetchData();
+  };
+
+  // 閲嶇疆鎼滅储
+  const resetSearch = () => {
+    searchForm.countId = "";
+    searchForm.locationName = "";
+    fetchData();
+  };
+
+  // 鎵撳紑琛ㄥ崟
+  const openForm = (type, row = {}) => {
+    operationType.value = type;
+    currentRow.value = row;
+    dialogVisible.value = true;
+  };
+
+  // 鍒犻櫎瑙勫垯
+  const handleDelete = id => {
+    ElMessageBox.confirm("纭畾瑕佸垹闄よ繖鏉¤鍒欏悧锛�", "鍒犻櫎纭", {
+      confirmButtonText: "纭畾",
+      cancelButtonText: "鍙栨秷",
+      type: "warning",
+    })
+      .then(() => {
+        deleteAttendanceRule([id]).then(() => {
+          ElMessage.success("鍒犻櫎鎴愬姛");
+          fetchData();
+        });
+      })
+      .catch(() => {
+        // 鍙栨秷鍒犻櫎
+      });
+  };
+
+  // 鍒濆鍖�
+  onMounted(() => {
+    fetchDeptOptions();
+    fetchData();
+  });
+</script>
+
+<style scoped lang="scss">
+  .page-header {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    margin-bottom: 20px;
+
+    .title {
+      font-size: 18px;
+      font-weight: 600;
+    }
+
+    .actions {
+      display: flex;
+      gap: 10px;
+    }
+  }
+
+  .mb16 {
+    margin-bottom: 16px;
+  }
+
+  .mt10 {
+    margin-top: 10px;
+  }
+</style>
\ No newline at end of file
diff --git a/src/views/personnelManagement/attendanceCheckin/index.vue b/src/views/personnelManagement/attendanceCheckin/index.vue
new file mode 100644
index 0000000..f2d8776
--- /dev/null
+++ b/src/views/personnelManagement/attendanceCheckin/index.vue
@@ -0,0 +1,507 @@
+<template>
+  <div class="app-container">
+    <!-- 鍛樺伐鎵撳崱鍖� -->
+    <!-- <el-card shadow="never"
+             class="mb16">
+      <div class="attendance-header">
+        <div>
+          <div class="title">鎵撳崱绛惧埌
+          </div>
+          <div class="sub-title">鏀寔涓�閿墦鍗★紝鑷姩璁板綍涓婁笅鐝椂闂�</div>
+        </div>
+        <div class="attendance-actions">
+          <div class="time-block">
+            <div class="label">褰撳墠鏃堕棿</div>
+            <div class="value">{{ nowTime }}</div>
+          </div>
+          <el-button type="primary"
+                     size="large"
+                     @click="handleCheckInOut"
+                     :disabled="todayRecord.workEndAt">
+            {{ checkInOutText }}
+          </el-button>
+        </div>
+      </div>
+      <el-descriptions border
+                       :column="4"
+                       class="mt10">
+        <el-descriptions-item label="鍛樺伐濮撳悕">
+          {{ todayRecord.staffName }}
+        </el-descriptions-item>
+        <el-descriptions-item label="宸ュ彿">
+          {{ todayRecord.staffNo }}
+        </el-descriptions-item>
+        <el-descriptions-item label="鎵�灞為儴闂�">
+          {{ todayRecord.deptName }}
+        </el-descriptions-item>
+        <el-descriptions-item label="浠婃棩鐘舵��">
+          <el-tag :type="todayStatusTag"
+                  size="small">
+            {{ todayStatusText }}
+          </el-tag>
+        </el-descriptions-item>
+        <el-descriptions-item label="涓婄彮鏃堕棿">
+          {{ todayRecord?.workStartAt || '-' }}
+        </el-descriptions-item>
+        <el-descriptions-item label="涓嬬彮鏃堕棿">
+          {{ todayRecord?.workEndAt || '-' }}
+        </el-descriptions-item>
+        <el-descriptions-item label="宸ユ椂(灏忔椂)">
+          {{ todayRecord?.workHours ?? '-' }}
+        </el-descriptions-item>
+        <el-descriptions-item label="寮傚父鏍囪">
+          <span v-if="!todayRecord.id || todayRecord?.status === 0">-</span>
+          <el-tag v-else
+                  type="danger"
+                  size="small">
+            {{ todayRecord?.status ? getStatusText(todayRecord.status) : '-' }}
+          </el-tag>
+        </el-descriptions-item>
+      </el-descriptions>
+    </el-card> -->
+    <div class="attendance-operation">
+      <!-- 鏌ヨ鏉′欢锛堢鐞嗗憳鑰冨嫟鏃ユ姤锛� -->
+      <el-form :model="searchForm"
+               :inline="true"
+               class="search-form">
+        <el-form-item label="閮ㄩ棬锛�"
+                      prop="deptId">
+          <el-tree-select v-model="searchForm.deptId"
+                          :data="deptOptions"
+                          :props="{ value: 'id', label: 'label', children: 'children' }"
+                          value-key="id"
+                          placeholder="璇烽�夋嫨閮ㄩ棬"
+                          check-strictly
+                          style="width: 200px" />
+        </el-form-item>
+        <el-form-item label="鏃ユ湡锛�"
+                      prop="date">
+          <el-date-picker v-model="searchForm.date"
+                          type="date"
+                          value-format="YYYY-MM-DD"
+                          format="YYYY-MM-DD"
+                          placeholder="璇烽�夋嫨鏃ユ湡"
+                          clearable />
+        </el-form-item>
+        <el-form-item>
+          <el-button type="primary"
+                     @click="fetchData">
+            <el-icon>
+              <Search />
+            </el-icon>
+            鎼滅储
+          </el-button>
+          <el-button @click="resetSearch">
+            <el-icon>
+              <Refresh />
+            </el-icon>
+            閲嶇疆
+          </el-button>
+        </el-form-item>
+      </el-form>
+      <el-button icon="Download"
+                 @click="handleExport">
+        瀵煎嚭鑰冨嫟鏃ユ姤
+      </el-button>
+    </div>
+    <!-- 鑰冨嫟鏃ユ姤琛ㄦ牸 -->
+    <div class="table_list">
+      <el-table :data="tableData"
+                border
+                v-loading="tableLoading"
+                style="width: 100%"
+                height="calc(100vh - 24em)"
+                :header-cell-style="{ background: '#F0F1F5', color: '#333333' }"
+                :row-class-name="rowClassName">
+        <el-table-column type="index"
+                         label="搴忓彿"
+                         width="60"
+                         align="center" />
+        <el-table-column prop="date"
+                         label="鏃ユ湡"
+                         width="120" />
+        <el-table-column prop="deptName"
+                         label="閮ㄩ棬"
+                         width="140" />
+        <el-table-column prop="staffName"
+                         label="濮撳悕"
+                         width="120" />
+        <el-table-column prop="staffNo"
+                         label="宸ュ彿"
+                         width="120" />
+        <el-table-column prop="workStartAt"
+                         label="涓婄彮鏃堕棿"
+                         width="140" />
+        <el-table-column prop="workEndAt"
+                         label="涓嬬彮鏃堕棿"
+                         width="140" />
+        <el-table-column prop="workHours"
+                         label="宸ユ椂(灏忔椂)"
+                         align="center" />
+        <el-table-column prop="status"
+                         label="鑰冨嫟鐘舵��"
+                         align="center">
+          <template #default="scope">
+            <el-tag v-if="scope.row.status === 0"
+                    type="success"
+                    size="small">
+              姝e父
+            </el-tag>
+            <el-tag v-else
+                    type="danger"
+                    size="small">
+              <!-- {{ scope.row.status === 1 ? '杩熷埌' : scope.row.status === 2 ? '鏃╅��' : '杩熷埌銆佹棭閫�' }} -->
+              {{ getStatusText(scope.row.status) }}
+            </el-tag>
+          </template>
+        </el-table-column>
+        <el-table-column prop="remark"
+                         label="澶囨敞"
+                         show-overflow-tooltip />
+      </el-table>
+      <pagination :total="page.total"
+                  layout="total, sizes, prev, pager, next, jumper"
+                  :page="page.current"
+                  :limit="page.size"
+                  @pagination="paginationChange" />
+    </div>
+  </div>
+</template>
+
+<script setup>
+  import { ref, reactive, computed, onMounted, onBeforeUnmount } from "vue";
+  import { ElMessage, ElMessageBox } from "element-plus";
+  import {
+    createPersonalAttendanceRecord,
+    findPersonalAttendanceRecords,
+    findTodayPersonalAttendanceRecord,
+  } from "@/api/personnelManagement/personalAttendanceRecords.js";
+  import Pagination from "@/components/Pagination/index.vue";
+  import { deptTreeSelect } from "@/api/system/user.js";
+  import { Refresh, Search } from "@element-plus/icons-vue";
+
+  const { proxy } = getCurrentInstance();
+  const tableLoading = ref(false);
+  // 鍒嗛〉鍙傛暟
+  const page = reactive({
+    current: 1,
+    size: 10,
+    total: 0,
+  });
+  // 浠婃棩鏁版嵁
+  const todayRecord = ref({});
+
+  // 閮ㄩ棬閫夐」
+  const deptOptions = ref([]);
+
+  // 鏌ヨ琛ㄥ崟
+  const searchForm = reactive({
+    deptId: "",
+    date: "",
+  });
+
+  // 琛ㄦ牸鏁版嵁
+  const tableData = ref([]);
+
+  // 褰撳墠鏃堕棿灞曠ず
+  const nowTime = ref("");
+  let timer = null;
+
+  const updateNowTime = () => {
+    const now = new Date();
+    const Y = now.getFullYear();
+    const M = String(now.getMonth() + 1).padStart(2, "0");
+    const D = String(now.getDate()).padStart(2, "0");
+    const h = String(now.getHours()).padStart(2, "0");
+    const m = String(now.getMinutes()).padStart(2, "0");
+    const s = String(now.getSeconds()).padStart(2, "0");
+    nowTime.value = `${Y}-${M}-${D} ${h}:${m}:${s}`;
+  };
+
+  // 鎵撳崱鎸夐挳鏂囨湰
+  const checkInOutText = computed(() => {
+    if (!todayRecord.value || !todayRecord.value.workStartAt) {
+      return "涓婄彮鎵撳崱";
+    }
+    if (!todayRecord.value.workEndAt) {
+      return "涓嬬彮鎵撳崱";
+    }
+    return "浠婃棩宸叉墦鍗″畬鎴�";
+  });
+
+  // 浠婃棩鐘舵�佸睍绀�
+  const todayStatusTag = computed(() => {
+    if (!todayRecord.value.id) return "info";
+    if (todayRecord.value.status === 0) return "success";
+    return "danger";
+  });
+  const getStatusText = status => {
+    switch (status) {
+      case 0:
+        return "姝e父";
+      case 1:
+        return "杩熷埌";
+      case 2:
+        return "鏃╅��";
+      case 3:
+        return "杩熷埌銆佹棭閫�";
+      case 4:
+        return "缂哄嫟";
+    }
+  };
+
+  const todayStatusText = computed(() => {
+    if (!todayRecord.value.id) return "鏈墦鍗�";
+    switch (todayRecord.value.status) {
+      case 0:
+        return "姝e父";
+      case 1:
+        return "杩熷埌";
+      case 2:
+        return "鏃╅��";
+      case 3:
+        return "杩熷埌銆佹棭閫�";
+      case 4:
+        return "缂哄嫟";
+    }
+  });
+
+  // 琛屾牱寮忥細寮傚父楂樹寒
+  const rowClassName = ({ row }) => {
+    if (row.status === 1 || row.status === 2) {
+      return "row-abnormal";
+    }
+    return "";
+  };
+
+  // 鏌ヨ閮ㄩ棬鍒楄〃
+  const fetchDeptOptions = () => {
+    deptTreeSelect().then(response => {
+      deptOptions.value = filterDisabledDept(
+        JSON.parse(JSON.stringify(response.data))
+      );
+    });
+  };
+
+  /** 杩囨护绂佺敤鐨勯儴闂� */
+  function filterDisabledDept(deptList) {
+    return deptList.filter(dept => {
+      if (dept.disabled) {
+        return false;
+      }
+      if (dept.children && dept.children.length) {
+        dept.children = filterDisabledDept(dept.children);
+      }
+      return true;
+    });
+  }
+
+  // 鏌ヨ
+  const fetchData = () => {
+    tableLoading.value = true;
+    findPersonalAttendanceRecords({ ...page, ...searchForm })
+      .then(res => {
+        tableData.value = res.data.records;
+        page.total = res.data.total;
+      })
+      .finally(() => {
+        tableLoading.value = false;
+      });
+  };
+
+  // 鏌ヨ浠婃棩鎵撳崱淇℃伅
+  const fetchTodayData = () => {
+    // findTodayPersonalAttendanceRecord({}).then(res => {
+    //   todayRecord.value = res.data;
+    // });
+  };
+
+  const paginationChange = pagination => {
+    page.current = pagination.page;
+    page.size = pagination.limit;
+    fetchData();
+  };
+
+  const resetSearch = () => {
+    searchForm.deptId = "";
+    searchForm.date = "";
+    fetchData();
+  };
+
+  const handleExport = () => {
+    ElMessageBox.confirm("鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
+      confirmButtonText: "纭",
+      cancelButtonText: "鍙栨秷",
+      type: "warning",
+    })
+      .then(() => {
+        proxy.download("/personalAttendanceRecords/export", {}, "鑰冨嫟璁板綍.xlsx");
+      })
+      .catch(() => {
+        proxy.$modal.msg("宸插彇娑�");
+      });
+  };
+
+  // 鑾峰彇褰撳墠浣嶇疆
+  const getCurrentLocation = () => {
+    return new Promise((resolve, reject) => {
+      if (!navigator.geolocation) {
+        reject(new Error("娴忚鍣ㄤ笉鏀寔鍦扮悊瀹氫綅"));
+        return;
+      }
+
+      // 妫�鏌ユ槸鍚︿娇鐢℉TTPS
+      const isSecureContext =
+        window.isSecureContext || window.location.protocol === "https:";
+      console.log(
+        "褰撳墠鍗忚:",
+        window.location.protocol,
+        "鏄惁瀹夊叏涓婁笅鏂�:",
+        isSecureContext
+      );
+
+      if (!isSecureContext) {
+        console.warn("褰撳墠涓嶆槸HTTPS鍗忚锛屽湴鐞嗕綅缃瓵PI鍙兘鍙楅檺");
+      }
+
+      navigator.geolocation.getCurrentPosition(
+        position => {
+          const { longitude, latitude } = position.coords;
+          console.log("鑾峰彇浣嶇疆鎴愬姛:", longitude, latitude);
+          resolve({ longitude, latitude });
+        },
+        error => {
+          console.log("鑾峰彇浣嶇疆澶辫触:", error);
+          let errorMessage = "鑾峰彇浣嶇疆澶辫触";
+
+          // 鏍规嵁閿欒绫诲瀷鎻愪緵鏇村叿浣撶殑鎻愮ず
+          switch (error.code) {
+            case error.PERMISSION_DENIED:
+              errorMessage =
+                "鐢ㄦ埛鎷掔粷浜嗕綅缃潈闄愯姹傦紝璇峰湪娴忚鍣ㄨ缃腑鍏佽浣嶇疆璁块棶";
+              break;
+            case error.POSITION_UNAVAILABLE:
+              errorMessage = "浣嶇疆淇℃伅涓嶅彲鐢紝璇锋鏌ヨ澶囧畾浣嶅姛鑳�";
+              break;
+            case error.TIMEOUT:
+              errorMessage = "鑾峰彇浣嶇疆瓒呮椂锛岃閲嶈瘯";
+              break;
+            case error.UNKNOWN_ERROR:
+              errorMessage = "鑾峰彇浣嶇疆鏃跺彂鐢熸湭鐭ラ敊璇�";
+              break;
+            default:
+              errorMessage = `鑾峰彇浣嶇疆澶辫触: ${error.message}`;
+          }
+
+          // 妫�鏌ユ槸鍚︽槸HTTPS闂
+          if (error.code === error.PERMISSION_DENIED && !isSecureContext) {
+            errorMessage += "锛堟敞鎰忥細鐢熶骇鐜闇�瑕佷娇鐢℉TTPS鍗忚鎵嶈兘鑾峰彇浣嶇疆锛�";
+          }
+
+          reject(new Error(errorMessage));
+        },
+        {
+          enableHighAccuracy: true,
+          timeout: 10000,
+          maximumAge: 0,
+        }
+      );
+    });
+  };
+
+  // 鎵撳崱
+  const handleCheckInOut = () => {
+    getCurrentLocation()
+      .then(location => {
+        console.log("浣嶇疆鎴愬姛");
+        createPersonalAttendanceRecord(location).then(res => {
+          fetchData();
+          fetchTodayData();
+          ElMessage.success("鎵撳崱鎴愬姛锛�");
+        });
+      })
+      .catch(error => {
+        // 鑾峰彇浣嶇疆澶辫触鏃讹紝浠嶅厑璁告墦鍗�
+        ElMessage.warning("鑾峰彇浣嶇疆澶辫触锛屽皢浣跨敤榛樿浣嶇疆鎵撳崱");
+        createPersonalAttendanceRecord({}).then(res => {
+          fetchData();
+          fetchTodayData();
+          ElMessage.success("鎵撳崱鎴愬姛锛�");
+        });
+      });
+  };
+
+  onMounted(() => {
+    updateNowTime();
+    timer = setInterval(updateNowTime, 1000);
+    // 榛樿灞曠ず褰撳ぉ鏁版嵁
+    const today = new Date();
+    const Y = today.getFullYear();
+    const M = String(today.getMonth() + 1).padStart(2, "0");
+    const D = String(today.getDate()).padStart(2, "0");
+    searchForm.date = `${Y}-${M}-${D}`;
+    fetchData();
+    fetchTodayData();
+    fetchDeptOptions();
+  });
+
+  onBeforeUnmount(() => {
+    if (timer) {
+      clearInterval(timer);
+    }
+  });
+</script>
+
+<style scoped lang="scss">
+  .mb16 {
+    margin-bottom: 16px;
+  }
+
+  .attendance-header {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+  }
+
+  .attendance-header .title {
+    font-size: 18px;
+    font-weight: 600;
+    margin-bottom: 4px;
+  }
+
+  .attendance-header .sub-title {
+    font-size: 13px;
+    color: #909399;
+  }
+
+  .attendance-actions {
+    display: flex;
+    align-items: center;
+    gap: 16px;
+  }
+
+  .time-block {
+    text-align: right;
+  }
+
+  .time-block .label {
+    font-size: 12px;
+    color: #909399;
+  }
+
+  .time-block .value {
+    font-size: 18px;
+    font-weight: 600;
+    color: #333;
+  }
+
+  ::v-deep(.row-abnormal) {
+    background-color: #fff5f5;
+  }
+
+  .attendance-operation {
+    display: flex;
+    justify-content: space-between;
+  }
+</style>
+
diff --git a/src/views/personnelManagement/contractManagement/components/formDia.vue b/src/views/personnelManagement/contractManagement/components/formDia.vue
index a124c1b..54b2ef9 100644
--- a/src/views/personnelManagement/contractManagement/components/formDia.vue
+++ b/src/views/personnelManagement/contractManagement/components/formDia.vue
@@ -11,7 +11,6 @@
           :column="tableColumn"
           :tableData="tableData"
           :tableLoading="tableLoading"
-          :showPagination="false"
           height="600"
       ></PIMTable>
       <template #footer>
@@ -20,22 +19,24 @@
         </div>
       </template>
     </el-dialog>
+    <Files ref="filesDia"></Files>
   </div>
 </template>
 
 <script setup>
 import {ref} from "vue";
-import {staffOnJobInfo} from "@/api/personnelManagement/employeeRecord.js";
+import {findStaffContractListPage} from "@/api/personnelManagement/staffContract.js";
+const Files = defineAsyncComponent(() => import( "@/views/personnelManagement/contractManagement/filesDia.vue"));
 const { proxy } = getCurrentInstance()
 const emit = defineEmits(['close'])
-
+const filesDia = ref()
 const dialogFormVisible = ref(false);
 const operationType = ref('')
 const tableColumn = ref([
-  // {
-  //   label: "鍚堝悓骞撮檺",
-  //   prop: "contractTerm",
-  // },
+  {
+    label: "鍚堝悓骞撮檺",
+    prop: "contractTerm",
+  },
   {
     label: "鍚堝悓寮�濮嬫棩鏈�",
     prop: "contractStartTime",
@@ -43,6 +44,22 @@
   {
     label: "鍚堝悓缁撴潫鏃ユ湡",
     prop: "contractEndTime",
+  },
+  {
+    dataType: "action",
+    label: "鎿嶄綔",
+    align: "center",
+    fixed: 'right',
+    width: 120,
+    operation: [
+      {
+        name: "涓婁紶闄勪欢",
+        type: "text",
+        clickFun: (row) => {
+          filesDia.value.openDialog( row,'鍚堝悓')
+        },
+      }
+    ],
   },
 ]);
 const tableData = ref([]);
@@ -53,12 +70,17 @@
   operationType.value = type;
   dialogFormVisible.value = true;
   if (operationType.value === 'edit') {
-    staffOnJobInfo({staffNo: row.staffNo}).then(res => {
-      tableData.value = res.data
+    findStaffContractListPage({staffOnJobId: row.id}).then(res => {
+      tableData.value = res.data.records
     })
   }
 }
 
+const openUploadFile = (row) => {
+  filesDia.value.open = true
+  filesDia.value.row = row
+}
+
 // 鍏抽棴寮规
 const closeDia = () => {
   dialogFormVisible.value = false;
diff --git a/src/views/personnelManagement/contractManagement/filesDia.vue b/src/views/personnelManagement/contractManagement/filesDia.vue
index f752496..4bcd812 100644
--- a/src/views/personnelManagement/contractManagement/filesDia.vue
+++ b/src/views/personnelManagement/contractManagement/filesDia.vue
@@ -28,18 +28,13 @@
           :tableData="tableData"
           :tableLoading="tableLoading"
           :isSelection="true"
+          :page="page"
           @selection-change="handleSelectionChange"
           height="500"
+          @pagination="paginationSearch"
+          :total="page.total"
       >
       </PIMTable>
-			<pagination
-				style="margin: 10px 0"
-				v-show="total > 0"
-				@pagination="paginationSearch"
-				:total="total"
-				:page="page.current"
-				:limit="page.size"
-			/>
       <template #footer>
         <div class="dialog-footer">
           <el-button @click="closeDia">鍙栨秷</el-button>
@@ -124,7 +119,7 @@
 const getList = () => {
   fileListPage({accountId: currentId.value,accountType:accountType.value, ...page}).then(res => {
     tableData.value = res.data.records;
-		total.value = res.data.total;
+    page.total = res.data.total;
   })
 }
 // 琛ㄦ牸閫夋嫨鏁版嵁
diff --git a/src/views/personnelManagement/contractManagement/index.vue b/src/views/personnelManagement/contractManagement/index.vue
index 30aefb9..1d2aab7 100644
--- a/src/views/personnelManagement/contractManagement/index.vue
+++ b/src/views/personnelManagement/contractManagement/index.vue
@@ -70,11 +70,11 @@
 </template>
 
 <script setup>
-import { Search, UploadFilled } from "@element-plus/icons-vue";
-import { onMounted, ref, reactive, toRefs, getCurrentInstance, nextTick } from "vue";
+import { Search } from "@element-plus/icons-vue";
+import { onMounted, ref } from "vue";
 import FormDia from "@/views/personnelManagement/contractManagement/components/formDia.vue";
 import { ElMessageBox } from "element-plus";
-import { staffOnJobListPage } from "@/api/personnelManagement/employeeRecord.js";
+import { staffOnJobListPage } from "@/api/personnelManagement/staffOnJob.js";
 import dayjs from "dayjs";
 import { getToken } from "@/utils/auth.js";
 import FilesDia from "./filesDia.vue";
@@ -183,7 +183,7 @@
     label: "鎿嶄綔",
     align: "center",
     fixed: 'right',
-    width: 130,
+    width: 120,
     operation: [
       {
         name: "璇︽儏",
@@ -191,14 +191,7 @@
         clickFun: (row) => {
           openForm("edit", row);
         },
-      },
-      {
-        name: "闄勪欢",
-        type: "text",
-        clickFun: (row) => {
-          openFilesFormDia(row);
-        },
-      },
+      }
     ],
   },
 ]);
@@ -245,6 +238,7 @@
   tableLoading.value = true;
   const params = { ...searchForm.value, ...page };
   params.entryDate = undefined
+  params.staffState = 1
   staffOnJobListPage(params).then(res => {
     tableLoading.value = false;
     tableData.value = res.data.records
@@ -272,7 +266,7 @@
     type: "warning",
   })
     .then(() => {
-      proxy.download("/staff/staffOnJob/export", {}, "鍚堝悓绠$悊.xlsx");
+      proxy.download("/staff/staffOnJob/export", {staffState: 1}, "鍚堝悓绠$悊.xlsx");
     })
     .catch(() => {
       proxy.$modal.msg("宸插彇娑�");
diff --git a/src/views/personnelManagement/dimission/components/formDia.vue b/src/views/personnelManagement/dimission/components/formDia.vue
index 01bd35f..2b8a7fd 100644
--- a/src/views/personnelManagement/dimission/components/formDia.vue
+++ b/src/views/personnelManagement/dimission/components/formDia.vue
@@ -9,145 +9,143 @@
       <!-- 鍛樺伐淇℃伅灞曠ず鍖哄煙 -->
       <div class="info-section">
         <div class="info-title">鍛樺伐淇℃伅</div>
-        <el-row :gutter="30">
-          <el-col :span="12">
-            <div class="info-item">
-              <span class="info-label">濮撳悕锛�</span>
-              <el-select v-model="form.staffName" placeholder="璇烽�夋嫨浜哄憳" style="width: 100%" @change="handleSelect" filterable>
-                <el-option
-                  v-for="item in personList"
-                  :key="item.id"
-                  :label="item.staffName"
-                  :value="item.staffName"
+        <el-form :model="form" label-width="200px" label-position="left" :rules="rules" ref="formRef" style="margin-top: 20px">
+          <el-row :gutter="30">
+            <el-col :span="12">
+              <el-form-item label="濮撳悕锛�" prop="staffOnJobId">
+                <el-select v-model="form.staffOnJobId"
+                           placeholder="璇烽�夋嫨浜哄憳"
+                           style="width: 100%"
+                           :disabled="operationType === 'edit'"
+                           @change="handleSelect">
+                  <el-option
+                      v-for="item in personList"
+                      :key="item.id"
+                      :label="item.staffName"
+                      :value="item.id"
+                  />
+                </el-select>
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="鍛樺伐缂栧彿锛�">
+                {{ currentStaffRecord.staffNo || '-' }}
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row :gutter="30">
+            <el-col :span="12">
+              <el-form-item label="鎬у埆锛�">
+                {{ currentStaffRecord.sex || '-' }}
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="鎴风睄浣忓潃锛�">
+                {{ currentStaffRecord.nativePlace || '-' }}
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row :gutter="30">
+            <el-col :span="12">
+              <el-form-item label="宀椾綅锛�">
+                {{ currentStaffRecord.postName || '-' }}
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="鐜颁綇鍧�锛�">
+                {{ currentStaffRecord.adress || '-' }}
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row :gutter="30">
+            <el-col :span="12">
+              <el-form-item label="绗竴瀛﹀巻锛�">
+                {{ currentStaffRecord.firstStudy || '-' }}
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="涓撲笟锛�">
+                {{ currentStaffRecord.profession || '-' }}
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row :gutter="30">
+            <el-col :span="12">
+              <el-form-item label="骞撮緞锛�">
+                {{ currentStaffRecord.age || '-' }}
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row :gutter="30">
+            <el-col :span="12">
+              <el-form-item label="鑱旂郴鐢佃瘽锛�">
+                {{ currentStaffRecord.phone || '-' }}
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="绱ф�ヨ仈绯讳汉锛�">
+                {{ currentStaffRecord.emergencyContact || '-' }}
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row :gutter="30">
+            <el-col :span="12">
+              <el-form-item label="绱ф�ヨ仈绯讳汉鑱旂郴鐢佃瘽锛�">
+                {{ currentStaffRecord.emergencyContactPhone || '-' }}
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row :gutter="30">
+            <el-col :span="12">
+              <el-form-item label="绂昏亴鍘熷洜锛�" prop="reason">
+                <el-select v-model="form.reason" placeholder="璇烽�夋嫨绂昏亴鍘熷洜" style="width: 100%" @change="handleSelectDimissionReason">
+                  <el-option
+                      v-for="(item, index) in dimissionReasonOptions"
+                      :key="index"
+                      :label="item.label"
+                      :value="item.value"
+                  />
+                </el-select>
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="澶囨敞锛�" prop="remark" v-if="form.reason === 'other'">
+                <el-input
+                    v-model="form.remark"
+                    type="textarea"
+                    :rows="3"
+                    placeholder="澶囨敞"
+                    maxlength="500"
+                    show-word-limit
                 />
-              </el-select>
-            </div>
-          </el-col>
-          <el-col :span="12">
-            <div class="info-item">
-              <span class="info-label">鍛樺伐缂栧彿锛�</span>
-              <span class="info-value">{{ form.staffNo || '-' }}</span>
-            </div>
-          </el-col>
-        </el-row>
-        <el-row :gutter="30">
-          <el-col :span="12">
-            <div class="info-item">
-              <span class="info-label">鎬у埆锛�</span>
-              <span class="info-value">{{ form.sex || '-' }}</span>
-            </div>
-          </el-col>
-          <el-col :span="12">
-            <div class="info-item">
-              <span class="info-label">鎴风睄浣忓潃锛�</span>
-              <span class="info-value">{{ form.nativePlace || '-' }}</span>
-            </div>
-          </el-col>
-        </el-row>
-        <el-row :gutter="30">
-          <el-col :span="12">
-            <div class="info-item">
-              <span class="info-label">宀椾綅锛�</span>
-              <span class="info-value">{{ form.postJob || '-' }}</span>
-            </div>
-          </el-col>
-          <el-col :span="12">
-            <div class="info-item">
-              <span class="info-label">鐜颁綇鍧�锛�</span>
-              <span class="info-value">{{ form.adress || '-' }}</span>
-            </div>
-          </el-col>
-        </el-row>
-        <el-row :gutter="30">
-          <el-col :span="12">
-            <div class="info-item">
-              <span class="info-label">绗竴瀛﹀巻锛�</span>
-              <span class="info-value">{{ form.firstStudy || '-' }}</span>
-            </div>
-          </el-col>
-          <el-col :span="12">
-            <div class="info-item">
-              <span class="info-label">涓撲笟锛�</span>
-              <span class="info-value">{{ form.profession || '-' }}</span>
-            </div>
-          </el-col>
-        </el-row>
-        <el-row :gutter="30">
-          <el-col :span="12">
-            <div class="info-item">
-              <span class="info-label">骞撮緞锛�</span>
-              <span class="info-value">{{ form.age || '-' }}</span>
-            </div>
-          </el-col>
-        </el-row>
-        <el-row :gutter="30">
-          <el-col :span="12">
-            <div class="info-item">
-              <span class="info-label">鑱旂郴鐢佃瘽锛�</span>
-              <span class="info-value">{{ form.phone || '-' }}</span>
-            </div>
-          </el-col>
-          <el-col :span="12">
-            <div class="info-item">
-              <span class="info-label">绱ф�ヨ仈绯讳汉锛�</span>
-              <span class="info-value">{{ form.emergencyContact || '-' }}</span>
-            </div>
-          </el-col>
-        </el-row>
-        <el-row :gutter="30">
-          <el-col :span="12">
-            <div class="info-item">
-              <span class="info-label">绱ф�ヨ仈绯讳汉鑱旂郴鐢佃瘽锛�</span>
-              <span class="info-value">{{ form.emergencyContactPhone || '-' }}</span>
-            </div>
-          </el-col>
-        </el-row>
-        <el-row :gutter="30">
-          <el-col :span="12">
-            <div class="info-item">
-              <span class="info-label">鍚堝悓寮�濮嬫棩鏈燂細</span>
-              <span class="info-value">{{ form.contractStartTime || '-' }}</span>
-            </div>
-          </el-col>
-          <el-col :span="12">
-            <div class="info-item">
-              <span class="info-label">鍚堝悓缁撴潫鏃ユ湡锛�</span>
-              <span class="info-value">{{ form.contractExpireTime || '-' }}</span>
-            </div>
-          </el-col>
-        </el-row>
+              </el-form-item>
+            </el-col>
+          </el-row>
+        </el-form>
+
+<!--        <el-row :gutter="30">-->
+<!--          <el-col :span="12">-->
+<!--            <div class="info-item">-->
+<!--              <span class="info-label">绂昏亴鍘熷洜锛�</span>-->
+<!--              <el-select v-model="form.reason" placeholder="璇烽�夋嫨浜哄憳" style="width: 100%" @change="handleSelect">-->
+<!--                <el-option-->
+<!--                    v-for="(item, index) in dimissionReasonOptions"-->
+<!--                    :key="index"-->
+<!--                    :label="item.label"-->
+<!--                    :value="item.value"-->
+<!--                />-->
+<!--              </el-select>-->
+<!--            </div>-->
+<!--          </el-col>-->
+<!--          <el-col :span="12">-->
+<!--            <div class="info-item">-->
+<!--              <span class="info-label">鍛樺伐缂栧彿锛�</span>-->
+<!--              <span class="info-value">{{ form.staffNo || '-' }}</span>-->
+<!--            </div>-->
+<!--          </el-col>-->
+<!--        </el-row>-->
       </div>
 
-      <!-- 绂昏亴淇℃伅濉啓鍖哄煙 -->
-      <!-- <el-form :model="form" label-width="140px" label-position="top" :rules="rules" ref="formRef" style="margin-top: 20px">
-        <el-row :gutter="30">
-          <el-col :span="12">
-            <el-form-item label="绂昏亴鏃ユ湡锛�" prop="dimissionDate">
-              <el-date-picker
-                v-model="form.dimissionDate"
-                type="date"
-                placeholder="璇烽�夋嫨绂昏亴鏃ユ湡"
-                value-format="YYYY-MM-DD"
-                format="YYYY-MM-DD"
-                clearable
-                style="width: 100%"
-              />
-            </el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item label="绂昏亴鍘熷洜锛�" prop="dimissionReason">
-              <el-input
-                v-model="form.dimissionReason"
-                type="textarea"
-                :rows="3"
-                placeholder="璇疯緭鍏ョ鑱屽師鍥�"
-                maxlength="500"
-                show-word-limit
-              />
-            </el-form-item>
-          </el-col>
-        </el-row>
-      </el-form> -->
       <template #footer>
         <div class="dialog-footer">
           <el-button type="primary" @click="submitForm">纭</el-button>
@@ -160,8 +158,8 @@
 
 <script setup>
 import {ref, reactive, toRefs, getCurrentInstance} from "vue";
-import {getStaffJoinInfo, staffJoinAdd, staffJoinUpdate} from "@/api/personnelManagement/onboarding.js";
-import { staffOnJobListPage } from "@/api/personnelManagement/employeeRecord.js";
+import {staffOnJobListPage} from "@/api/personnelManagement/staffOnJob.js";
+import {createStaffLeave, updateStaffLeave} from "@/api/personnelManagement/staffLeave.js";
 const { proxy } = getCurrentInstance()
 const emit = defineEmits(['close'])
 
@@ -169,86 +167,80 @@
 const operationType = ref('')
 const data = reactive({
   form: {
-    staffNo: "",
-    staffName: "",
-    sex: "",
-    nativePlace: "",
-    postJob: "",
-    adress: "",
-    firstStudy: "",
-    profession: "",
-    age: 0,
-    phone: "",
-    emergencyContact: "",
-    emergencyContactPhone: "",
-    contractTerm: 0,
-    contractStartTime: "",
-    contractExpireTime: "",
-    dimissionDate: "",
-    dimissionReason: "",
-    staffState: "",
+    staffOnJobId: undefined,
+    reason: "",
+    remark: "",
   },
   rules: {
-    staffName: [{ required: true, message: "璇烽�夋嫨浜哄憳", trigger: "change" }],
-    dimissionDate: [{ required: true, message: "璇烽�夋嫨绂昏亴鏃ユ湡", trigger: "change" }],
-    dimissionReason: [{ required: true, message: "璇疯緭鍏ョ鑱屽師鍥�", trigger: "blur" }],
+    staffName: [{ required: true, message: "璇烽�夋嫨浜哄憳" }],
+    reason: [{ required: true, message: "璇烽�夋嫨绂昏亴鍘熷洜"}],
   },
+  dimissionReasonOptions: [
+      {label: '钖祫寰呴亣', value: 'salary'},
+      {label: '鑱屼笟鍙戝睍', value: 'career_development'},
+      {label: '宸ヤ綔鐜', value: 'work_environment'},
+      {label: '涓汉鍘熷洜', value: 'personal_reason'},
+      {label: '鍏朵粬', value: 'other'},
+  ],
+  currentStaffRecord: {},
 });
-const { form, rules } = toRefs(data);
+const { form, rules, dimissionReasonOptions, currentStaffRecord } = toRefs(data);
 
 // 鎵撳紑寮规
 const openDialog = (type, row) => {
-  getList()
   operationType.value = type;
   dialogFormVisible.value = true;
   if (operationType.value === 'edit') {
-    getStaffJoinInfo(row.id).then(res => {
-      form.value = {...res.data}
-    })
+    currentStaffRecord.value = row
+    form.value.staffOnJobId = row.staffOnJobId
+    form.value.reason = row.reason
+    form.value.remark = row.remark
+    personList.value = [
+      {
+        staffName: row.staffName,
+        id: row.staffOnJobId,
+      }
+    ]
+  } else {
+    getList()
+  }
+}
+
+const handleSelectDimissionReason = (val) => {
+  if (val === 'other') {
+    form.value.remark = ''
   }
 }
 // 鎻愪氦浜у搧琛ㄥ崟
 const submitForm = () => {
-  // 琛ㄥ崟宸叉敞閲婏紝鐩存帴鎻愪氦锛屼笉杩涜楠岃瘉
-  if (!form.value.staffName) {
-    proxy.$modal.msgError("璇烽�夋嫨浜哄憳");
-    return;
-  }
   form.value.staffState = 0
-  if (operationType.value === "add") {
-    staffJoinAdd(form.value).then(res => {
-      proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
-      closeDia();
-    })
-  } else {
-    staffJoinUpdate(form.value).then(res => {
-      proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
-      closeDia();
-    })
+  if (form.value.reason !== 'other') {
+    form.value.remark = ''
   }
+  proxy.$refs["formRef"].validate(valid => {
+    if (valid) {
+      if (operationType.value === "add") {
+        createStaffLeave(form.value).then(res => {
+          proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
+          closeDia();
+        })
+      } else {
+        updateStaffLeave(currentStaffRecord.value.id, form.value).then(res => {
+          proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
+          closeDia();
+        })
+      }
+    }
+  })
+
 }
 // 鍏抽棴寮规
 const closeDia = () => {
   // 琛ㄥ崟宸叉敞閲婏紝鎵嬪姩閲嶇疆琛ㄥ崟鏁版嵁
   form.value = {
-    staffNo: "",
-    staffName: "",
-    sex: "",
-    nativePlace: "",
-    postJob: "",
-    adress: "",
-    firstStudy: "",
-    profession: "",
-    age: 0,
-    phone: "",
-    emergencyContact: "",
-    emergencyContactPhone: "",
-    contractTerm: 0,
-    contractStartTime: "",
-    contractExpireTime: "",
-    dimissionDate: "",
-    dimissionReason: "",
-    staffState: "",
+    staffOnJobId: undefined,
+    reason: "",
+    remark: "",
   };
   dialogFormVisible.value = false;
   emit('close')
@@ -270,44 +262,11 @@
 };
 
 const handleSelect = (val) => {
-  let obj = personList.value.find(item => item.staffName === val)
+  let obj = personList.value.find(item => item.id === val)
+  currentStaffRecord.value = {}
   if (obj) {
-    let {
-      sex,
-      phone,
-      staffNo,
-      nativePlace,
-      postJob,
-      adress,
-      firstStudy,
-      profession,
-      age,
-      emergencyContact,
-      emergencyContactPhone,
-      contractTerm,
-      contractStartTime,
-      contractExpireTime,
-      staffName
-    } = obj
     // 淇濈暀绂昏亴鏃ユ湡鍜岀鑱屽師鍥狅紝鍙洿鏂板憳宸ヤ俊鎭�
-    form.value = {
-      ...form.value,
-      sex,
-      phone,
-      staffNo,
-      nativePlace,
-      postJob,
-      adress,
-      firstStudy,
-      profession,
-      age,
-      emergencyContact,
-      emergencyContactPhone,
-      contractTerm,
-      contractStartTime,
-      contractExpireTime,
-      staffName
-    }
+    currentStaffRecord.value = obj
   }
 }
 defineExpose({
diff --git a/src/views/personnelManagement/dimission/index.vue b/src/views/personnelManagement/dimission/index.vue
index ae90d99..c6ed705 100644
--- a/src/views/personnelManagement/dimission/index.vue
+++ b/src/views/personnelManagement/dimission/index.vue
@@ -11,22 +11,6 @@
             clearable
             :prefix-icon="Search"
         />
-        <span style="margin-left: 10px;"  class="search_title">鍚堝悓寮�濮嬫棩鏈燂細</span>
-        <el-date-picker
-            v-model="searchForm.entryDateStart"
-            type="date"
-            placeholder="璇烽�夋嫨鍚堝悓寮�濮嬫棩鏈�"
-            size="default"
-            @change="(date) => handleDateChange(date,1)"
-        />
-        <span style="margin-left: 10px;" class="search_title">鍚堝悓缁撴潫鏃ユ湡锛�</span>
-        <el-date-picker
-            v-model="searchForm.entryDateEnd"
-            type="date"
-            placeholder="璇烽�夋嫨鍚堝悓缁撴潫鏃ユ湡"
-            size="default"
-            @change="(date) => handleDateChange(date,2)"
-        />
         <el-button type="primary" @click="handleQuery" style="margin-left: 10px"
         >鎼滅储</el-button
         >
@@ -58,9 +42,8 @@
 import { Search } from "@element-plus/icons-vue";
 import {onMounted, ref} from "vue";
 import FormDia from "@/views/personnelManagement/dimission/components/formDia.vue";
-import {staffJoinDel, staffJoinListPage} from "@/api/personnelManagement/onboarding.js";
+import {findStaffLeaveListPage, batchDeleteStaffLeaves} from "@/api/personnelManagement/staffLeave.js";
 import {ElMessageBox} from "element-plus";
-import dayjs from "dayjs";
 
 const data = reactive({
   searchForm: {
@@ -109,8 +92,12 @@
     prop: "nativePlace",
   },
   {
+    label: "閮ㄩ棬",
+    prop: "deptName",
+  },
+  {
     label: "宀椾綅",
-    prop: "postJob",
+    prop: "postName",
   },
   {
     label: "鐜颁綇鍧�",
@@ -145,24 +132,11 @@
     prop: "emergencyContactPhone",
     width:150
   },
-  // {
-  //   label: "鍚堝悓骞撮檺",
-  //   prop: "contractTerm",
-  // },
-  {
-    label: "鍚堝悓寮�濮嬫棩鏈�",
-    prop: "contractStartTime",
-    width: 120
-  },
-  {
-    label: "鍚堝悓缁撴潫鏃ユ湡",
-    prop: "contractEndTime",
-    width: 120
-  },
   {
     dataType: "action",
     label: "鎿嶄綔",
     align: "center",
+    fixed: 'right',
     operation: [
       {
         name: "缂栬緫",
@@ -186,20 +160,6 @@
 const { proxy } = getCurrentInstance()
 
 
-const handleDateChange = (value,type) => {
-  searchForm.value.entryDateEnd = null
-  searchForm.value.entryDateStart = null
-  if(type === 1){
-    if (value) {
-      searchForm.value.entryDateStart = dayjs(value).format("YYYY-MM-DD");
-    }
-  }else{
-    if (value) {
-      searchForm.value.entryDateEnd = dayjs(value).format("YYYY-MM-DD");
-    }
-  }
-  getList();
-};
 // 鏌ヨ鍒楄〃
 /** 鎼滅储鎸夐挳鎿嶄綔 */
 const handleQuery = () => {
@@ -213,7 +173,7 @@
 };
 const getList = () => {
   tableLoading.value = true;
-  staffJoinListPage({...page, ...searchForm.value, staffState: 0}).then(res => {
+  findStaffLeaveListPage({...page, ...searchForm.value}).then(res => {
     tableLoading.value = false;
     tableData.value = res.data.records
     page.total = res.data.total;
@@ -248,7 +208,7 @@
     type: "warning",
   })
       .then(() => {
-        staffJoinDel(ids).then((res) => {
+        batchDeleteStaffLeaves(ids).then((res) => {
           proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
           getList();
         });
@@ -265,7 +225,7 @@
     type: "warning",
   })
       .then(() => {
-        proxy.download("/staff/staffJoinLeaveRecord/export", {staffState: 0}, "浜哄憳绂昏亴.xlsx");
+        proxy.download("/staff/staffLeave/export", {}, "浜哄憳绂昏亴.xlsx");
       })
       .catch(() => {
         proxy.$modal.msg("宸插彇娑�");
diff --git a/src/views/personnelManagement/employeeRecord/components/NewOrEditFormDia.vue b/src/views/personnelManagement/employeeRecord/components/NewOrEditFormDia.vue
new file mode 100644
index 0000000..1c06a98
--- /dev/null
+++ b/src/views/personnelManagement/employeeRecord/components/NewOrEditFormDia.vue
@@ -0,0 +1,373 @@
+<template>
+  <div>
+    <el-dialog v-model="dialogFormVisible"
+               :title="operationType === 'add' ? '鏂板鍏ヨ亴' : '缂栬緫浜哄憳'"
+               width="70%"
+               @close="closeDia">
+      <el-form :model="form"
+               label-width="140px"
+               label-position="top"
+               :rules="rules"
+               ref="formRef">
+        <el-row :gutter="30">
+          <el-col :span="12">
+            <el-form-item label="鍛樺伐缂栧彿锛�"
+                          prop="staffNo">
+              <el-input v-model="form.staffNo"
+                        placeholder="璇疯緭鍏�"
+                        clearable
+                        :disabled="operationType !== 'add'" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="濮撳悕锛�"
+                          prop="staffName">
+              <el-input v-model="form.staffName"
+                        placeholder="璇疯緭鍏�"
+                        clearable />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="30">
+          <el-col :span="12">
+            <el-form-item label="鎬у埆锛�"
+                          prop="sex">
+              <el-select v-model="form.sex">
+                <el-option label="鐢�"
+                           value="鐢�" />
+                <el-option label="濂�"
+                           value="濂�" />
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="鎴风睄浣忓潃锛�"
+                          prop="nativePlace">
+              <el-input v-model="form.nativePlace"
+                        placeholder="璇疯緭鍏�"
+                        clearable />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="30">
+          <el-col :span="12">
+            <el-form-item label="宀椾綅锛�"
+                          prop="sysPostId">
+              <el-select v-model="form.sysPostId"
+                         placeholder="璇烽�夋嫨宀椾綅"
+                         clearable>
+                <el-option v-for="item in postOptions"
+                           :key="item.postId"
+                           :label="item.postName"
+                           :value="item.postId"
+                           :disabled="item.status === '1'" />
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="鐜颁綇鍧�锛�"
+                          prop="adress">
+              <el-input v-model="form.adress"
+                        placeholder="璇疯緭鍏�"
+                        clearable />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="30">
+          <el-col :span="12">
+            <el-form-item label="閮ㄩ棬锛�"
+                          prop="sysDeptId">
+              <el-tree-select v-model="form.sysDeptId"
+                              :data="deptOptions"
+                              :props="{ value: 'id', label: 'label', children: 'children' }"
+                              value-key="id"
+                              placeholder="璇烽�夋嫨閮ㄩ棬"
+                              check-strictly />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="骞撮緞锛�"
+                          prop="age">
+              <el-input-number v-model="form.age"
+                               :precision="0"
+                               :step="1"
+                               style="width: 100%" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="30">
+          <el-col :span="12">
+            <el-form-item label="绗竴瀛﹀巻锛�"
+                          prop="firstStudy">
+              <el-input v-model="form.firstStudy"
+                        placeholder="璇疯緭鍏�"
+                        clearable />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="涓撲笟锛�"
+                          prop="profession">
+              <el-input v-model="form.profession"
+                        placeholder="璇疯緭鍏�"
+                        clearable />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="30">
+          <el-col :span="12">
+            <el-form-item label="鑱旂郴鐢佃瘽锛�"
+                          prop="phone">
+              <el-input v-model="form.phone"
+                        placeholder="璇疯緭鍏�"
+                        clearable />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="绱ф�ヨ仈绯讳汉锛�"
+                          prop="emergencyContact">
+              <el-input v-model="form.emergencyContact"
+                        placeholder="璇疯緭鍏�"
+                        clearable />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="30">
+          <el-col :span="12">
+            <el-form-item label="绱ф�ヨ仈绯讳汉鑱旂郴鐢佃瘽锛�"
+                          prop="emergencyContactPhone">
+              <el-input v-model="form.emergencyContactPhone"
+                        placeholder="璇疯緭鍏�"
+                        clearable />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="鍚堝悓骞撮檺锛�"
+                          prop="contractTerm">
+              <el-input-number v-model="form.contractTerm"
+                               :precision="0"
+                               :step="1"
+                               style="width: 100%"
+                               :disabled="true" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="30">
+          <el-col :span="12">
+            <el-form-item label="鍚堝悓寮�濮嬫棩鏈燂細"
+                          prop="contractStartTime">
+              <el-date-picker v-model="form.contractStartTime"
+                              type="date"
+                              placeholder="璇烽�夋嫨鏃ユ湡"
+                              value-format="YYYY-MM-DD"
+                              format="YYYY-MM-DD"
+                              clearable
+                              style="width: 100%"
+                              @change="calculateContractTerm" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="鍚堝悓缁撴潫鏃ユ湡锛�"
+                          prop="contractEndTime">
+              <el-date-picker v-model="form.contractEndTime"
+                              type="date"
+                              placeholder="璇烽�夋嫨鏃ユ湡"
+                              value-format="YYYY-MM-DD"
+                              format="YYYY-MM-DD"
+                              clearable
+                              style="width: 100%"
+                              @change="calculateContractTerm" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </el-form>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button type="primary"
+                     @click="submitForm">纭</el-button>
+          <el-button @click="closeDia">鍙栨秷</el-button>
+        </div>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup>
+  import { ref, onMounted } from "vue";
+  import { findPostOptions } from "@/api/system/post.js";
+  import { listDept } from "@/api/system/dept.js";
+  import {
+    staffOnJobInfo,
+    createStaffOnJob,
+    updateStaffOnJob,
+  } from "@/api/personnelManagement/staffOnJob.js";
+  import { deptTreeSelect } from "@/api/system/user.js";
+  const { proxy } = getCurrentInstance();
+  const emit = defineEmits(["close"]);
+
+  const dialogFormVisible = ref(false);
+  const operationType = ref("");
+  const id = ref(0);
+  const data = reactive({
+    form: {
+      staffNo: "",
+      staffName: "",
+      sex: "",
+      nativePlace: "",
+      postJob: "",
+      adress: "",
+      firstStudy: "",
+      profession: "",
+      age: 0,
+      phone: "",
+      emergencyContact: "",
+      emergencyContactPhone: "",
+      contractTerm: 0,
+      contractStartTime: "",
+      contractEndTime: "",
+      sysPostId: undefined,
+      sysDeptId: undefined,
+    },
+    rules: {
+      staffNo: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+      staffName: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+      sex: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+      nativePlace: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+      postJob: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+      adress: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+      firstStudy: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+      profession: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+      age: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+      phone: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+      emergencyContact: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+      emergencyContactPhone: [
+        { required: true, message: "璇疯緭鍏�", trigger: "blur" },
+      ],
+      contractTerm: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+      contractStartTime: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+      contractEndTime: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+      sysDeptId: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
+    },
+    postOptions: [], // 宀椾綅閫夐」
+    deptOptions: [], // 閮ㄩ棬閫夐」
+  });
+  const { form, rules, postOptions, deptOptions } = toRefs(data);
+
+  // 鎵撳紑寮规
+  const openDialog = (type, row) => {
+    operationType.value = type;
+    dialogFormVisible.value = true;
+    if (operationType.value === "edit") {
+      id.value = row.id;
+      staffOnJobInfo(id.value, {}).then(res => {
+        form.value = { ...res.data };
+        if (form.value.sysPostId === 0) {
+          form.value.sysPostId = undefined;
+        }
+        if (form.value.sysDeptId === 0) {
+          form.value.sysDeptId = undefined;
+        }
+        // 缂栬緫鏃朵篃璁$畻涓�娆″悎鍚屽勾闄�
+        calculateContractTerm();
+      });
+    } else {
+      form.value.id = "";
+    }
+  };
+  onMounted(() => {
+    fetchPostOptions();
+    fetchDeptOptions();
+  });
+
+  const fetchPostOptions = () => {
+    findPostOptions().then(res => {
+      postOptions.value = res.data;
+    });
+  };
+
+  // 鏌ヨ閮ㄩ棬鍒楄〃
+  const fetchDeptOptions = () => {
+    deptTreeSelect().then(response => {
+      deptOptions.value = filterDisabledDept(
+        JSON.parse(JSON.stringify(response.data))
+      );
+    });
+  };
+
+  /** 杩囨护绂佺敤鐨勯儴闂� */
+  function filterDisabledDept(deptList) {
+    return deptList.filter(dept => {
+      if (dept.disabled) {
+        return false;
+      }
+      if (dept.children && dept.children.length) {
+        dept.children = filterDisabledDept(dept.children);
+      }
+      return true;
+    });
+  }
+
+  // 鎻愪氦浜у搧琛ㄥ崟
+  const submitForm = () => {
+    if (!form.value.sysPostId) {
+      form.value.sysPostId = undefined;
+    }
+    if (!form.value.sysDeptId) {
+      form.value.sysDeptId = undefined;
+    }
+    proxy.$refs.formRef.validate(valid => {
+      if (valid) {
+        if (operationType.value === "add") {
+          createStaffOnJob(form.value).then(res => {
+            proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
+            closeDia();
+          });
+        } else {
+          updateStaffOnJob(id.value, form.value).then(res => {
+            proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
+            closeDia();
+          });
+        }
+      }
+    });
+  };
+  // 璁$畻鍚堝悓骞撮檺
+  const calculateContractTerm = () => {
+    if (form.value.contractStartTime && form.value.contractEndTime) {
+      const startDate = new Date(form.value.contractStartTime);
+      const endDate = new Date(form.value.contractEndTime);
+
+      if (endDate > startDate) {
+        // 璁$畻骞翠唤宸�
+        const yearDiff = endDate.getFullYear() - startDate.getFullYear();
+        const monthDiff = endDate.getMonth() - startDate.getMonth();
+        const dayDiff = endDate.getDate() - startDate.getDate();
+
+        let years = yearDiff;
+
+        // 濡傛灉缁撴潫鏃ユ湡鐨勬湀鏃ュ皬浜庡紑濮嬫棩鏈熺殑鏈堟棩锛屽垯鍑忓幓1骞�
+        if (monthDiff < 0 || (monthDiff === 0 && dayDiff < 0)) {
+          years = yearDiff - 1;
+        }
+
+        form.value.contractTerm = Math.max(0, years);
+      } else {
+        form.value.contractTerm = 0;
+      }
+    } else {
+      form.value.contractTerm = 0;
+    }
+  };
+
+  // 鍏抽棴寮规
+  const closeDia = () => {
+    proxy.resetForm("formRef");
+    dialogFormVisible.value = false;
+    emit("close");
+  };
+  defineExpose({
+    openDialog,
+  });
+</script>
+
+<style scoped>
+</style>
\ No newline at end of file
diff --git a/src/views/personnelManagement/employeeRecord/components/RenewContract.vue b/src/views/personnelManagement/employeeRecord/components/RenewContract.vue
new file mode 100644
index 0000000..9c2acfc
--- /dev/null
+++ b/src/views/personnelManagement/employeeRecord/components/RenewContract.vue
@@ -0,0 +1,141 @@
+<template>
+  <el-dialog
+      v-model="isShow"
+      title="缁鍚堝悓"
+      width="800px"
+      @close="closeModal"
+  >
+    <el-form :model="form" label-width="140px" label-position="top" :rules="rules" ref="formRef">
+      <el-form-item label="鍚堝悓寮�濮嬫棩鏈燂細" prop="contractStartTime">
+        <el-date-picker
+            v-model="form.contractStartTime"
+            type="date"
+            placeholder="璇烽�夋嫨鏃ユ湡"
+            value-format="YYYY-MM-DD"
+            format="YYYY-MM-DD"
+            clearable
+            style="width: 100%"
+            @change="calculateContractTerm"
+        />
+      </el-form-item>
+      <el-form-item label="鍚堝悓缁撴潫鏃ユ湡锛�" prop="contractEndTime">
+        <el-date-picker
+            v-model="form.contractEndTime"
+            type="date"
+            placeholder="璇烽�夋嫨鏃ユ湡"
+            value-format="YYYY-MM-DD"
+            format="YYYY-MM-DD"
+            clearable
+            style="width: 100%"
+            @change="calculateContractTerm"
+        />
+      </el-form-item>
+      <el-form-item label="鍚堝悓骞撮檺锛�" prop="contractTerm">
+        <el-input-number v-model="form.contractTerm" :precision="0" :step="1" style="width: 100%" :disabled="true"/>
+      </el-form-item>
+    </el-form>
+    <template #footer>
+      <div class="dialog-footer">
+        <el-button type="primary" @click="submitForm">纭</el-button>
+        <el-button @click="closeModal">鍙栨秷</el-button>
+      </div>
+    </template>
+  </el-dialog>
+</template>
+
+<script setup>
+// 缁鍚堝悓
+import { renewContract } from "@/api/personnelManagement/staffOnJob.js";
+import {computed, getCurrentInstance,} from "vue";
+
+const emit = defineEmits(['update:visible', 'completed']);
+
+const data = reactive({
+  form: {
+    contractTerm: 0,
+    contractStartTime: "",
+    contractEndTime: "",
+  },
+  rules: {
+    contractTerm: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+    contractStartTime: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+    contractEndTime: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+  }
+});
+const { form, rules } = toRefs(data);
+let { proxy } = getCurrentInstance()
+
+const props = defineProps({
+  id: {
+    type: Number,
+    default: 0,
+  },
+
+  visible: {
+    type: Boolean,
+    required: true,
+  },
+})
+
+const isShow = computed({
+  get() {
+    return props.visible;
+  },
+  set(val) {
+    emit('update:visible', val);
+  },
+});
+
+// 璁$畻鍚堝悓骞撮檺
+const calculateContractTerm = () => {
+  if (form.value.contractStartTime && form.value.contractEndTime) {
+    const startDate = new Date(form.value.contractStartTime);
+    const endDate = new Date(form.value.contractEndTime);
+
+    if (endDate > startDate) {
+      // 璁$畻骞翠唤宸�
+      const yearDiff = endDate.getFullYear() - startDate.getFullYear();
+      const monthDiff = endDate.getMonth() - startDate.getMonth();
+      const dayDiff = endDate.getDate() - startDate.getDate();
+
+      let years = yearDiff;
+
+      // 濡傛灉缁撴潫鏃ユ湡鐨勬湀鏃ュ皬浜庡紑濮嬫棩鏈熺殑鏈堟棩锛屽垯鍑忓幓1骞�
+      if (monthDiff < 0 || (monthDiff === 0 && dayDiff < 0)) {
+        years = yearDiff - 1;
+      }
+
+      form.value.contractTerm = Math.max(0, years);
+    } else {
+      form.value.contractTerm = 0;
+    }
+  } else {
+    form.value.contractTerm = 0;
+  }
+};
+
+const submitForm = () => {
+  proxy.$refs["formRef"].validate(valid => {
+    if (valid) {
+      renewContract(props.id, form.value).then(res => {
+        if (res.code === 200) {
+          proxy.$modal.msgSuccess("缁鍚堝悓鎴愬姛");
+          emit('completed');
+          closeModal();
+        }
+      })
+    }
+  })
+}
+
+// 鍏抽棴寮规
+const closeModal = () => {
+  // 閲嶇疆琛ㄥ崟鏁版嵁
+  form.value = {
+    contractTerm: 0,
+    contractStartTime: "",
+    contractEndTime: "",
+  };
+  isShow.value = false;
+};
+</script>
diff --git a/src/views/personnelManagement/employeeRecord/components/Show.vue b/src/views/personnelManagement/employeeRecord/components/Show.vue
new file mode 100644
index 0000000..9220d45
--- /dev/null
+++ b/src/views/personnelManagement/employeeRecord/components/Show.vue
@@ -0,0 +1,73 @@
+<template>
+  <div>
+    <el-dialog
+        v-model="dialogFormVisible"
+        title="璇︽儏"
+        width="70%"
+        @close="closeDia"
+    >
+      <PIMTable
+          rowKey="id"
+          :column="tableColumn"
+          :tableData="tableData"
+          :tableLoading="tableLoading"
+          height="600"
+      ></PIMTable>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button @click="closeDia">鍙栨秷</el-button>
+        </div>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup>
+import {ref} from "vue";
+import {staffOnJobInfo} from "@/api/personnelManagement/staffOnJob.js";
+const { proxy } = getCurrentInstance()
+const emit = defineEmits(['close'])
+
+const dialogFormVisible = ref(false);
+const operationType = ref('')
+const tableColumn = ref([
+  // {
+  //   label: "鍚堝悓骞撮檺",
+  //   prop: "contractTerm",
+  // },
+  {
+    label: "鍚堝悓寮�濮嬫棩鏈�",
+    prop: "contractStartTime",
+  },
+  {
+    label: "鍚堝悓缁撴潫鏃ユ湡",
+    prop: "contractEndTime",
+  },
+]);
+const tableData = ref([]);
+const tableLoading = ref(false);
+
+// 鎵撳紑寮规
+const openDialog = (type, row) => {
+  operationType.value = type;
+  dialogFormVisible.value = true;
+  if (operationType.value === 'edit') {
+    staffOnJobInfo({staffNo: row.staffNo}).then(res => {
+      tableData.value = res.data
+    })
+  }
+}
+
+// 鍏抽棴寮规
+const closeDia = () => {
+  dialogFormVisible.value = false;
+  emit('close')
+};
+defineExpose({
+  openDialog,
+});
+</script>
+
+<style scoped>
+
+</style>
\ No newline at end of file
diff --git a/src/views/personnelManagement/employeeRecord/components/formDia.vue b/src/views/personnelManagement/employeeRecord/components/formDia.vue
deleted file mode 100644
index c20877d..0000000
--- a/src/views/personnelManagement/employeeRecord/components/formDia.vue
+++ /dev/null
@@ -1,178 +0,0 @@
-<template>
-  <div>
-    <el-dialog
-        v-model="dialogFormVisible"
-        title="璇︽儏"
-        width="70%"
-        @close="closeDia"
-    >
-      <!-- 鎸夌収鍏ヨ亴鏂板寮圭獥瀛楁灞曠ず鍩虹淇℃伅鍜屽悎鍚屼俊鎭� -->
-      <el-descriptions class="detail-descriptions" :column="2" border size="small">
-        <el-descriptions-item label="鍛樺伐缂栧彿">
-          {{ formData.staffNo || '-' }}
-        </el-descriptions-item>
-        <el-descriptions-item label="濮撳悕">
-          {{ formData.staffName || '-' }}
-        </el-descriptions-item>
-        <el-descriptions-item label="鎬у埆">
-          {{ formData.sex || '-' }}
-        </el-descriptions-item>
-        <el-descriptions-item label="骞撮緞">
-          {{ formData.age || '-' }}
-        </el-descriptions-item>
-        <el-descriptions-item label="鎴风睄浣忓潃" :span="2">
-          {{ formData.nativePlace || '-' }}
-        </el-descriptions-item>
-        <el-descriptions-item label="鐜颁綇鍧�" :span="2">
-          {{ formData.adress || '-' }}
-        </el-descriptions-item>
-        <el-descriptions-item label="宀椾綅">
-          {{ formData.postJob || '-' }}
-        </el-descriptions-item>
-        <el-descriptions-item label="绗竴瀛﹀巻">
-          {{ formData.firstStudy || '-' }}
-        </el-descriptions-item>
-        <el-descriptions-item label="涓撲笟">
-          {{ formData.profession || '-' }}
-        </el-descriptions-item>
-        <el-descriptions-item label="鑱旂郴鐢佃瘽">
-          {{ formData.phone || '-' }}
-        </el-descriptions-item>
-        <el-descriptions-item label="绱ф�ヨ仈绯讳汉">
-          {{ formData.emergencyContact || '-' }}
-        </el-descriptions-item>
-        <el-descriptions-item label="绱ф�ヨ仈绯讳汉鐢佃瘽">
-          {{ formData.emergencyContactPhone || '-' }}
-        </el-descriptions-item>
-        <el-descriptions-item label="鍚堝悓寮�濮嬫棩鏈�">
-          {{ formData.contractStartTime || '-' }}
-        </el-descriptions-item>
-        <el-descriptions-item label="鍚堝悓缁撴潫鏃ユ湡">
-          {{ formData.contractExpireTime || '-' }}
-        </el-descriptions-item>
-        <el-descriptions-item label="鍚堝悓骞撮檺">
-          {{ formattedContractTerm }}
-        </el-descriptions-item>
-      </el-descriptions>
-      <template #footer>
-        <div class="dialog-footer">
-          <el-button @click="closeDia">鍏抽棴</el-button>
-        </div>
-      </template>
-    </el-dialog>
-  </div>
-</template>
-
-<script setup>
-import {ref, reactive, computed} from "vue";
-import dayjs from "dayjs";
-const emit = defineEmits(['close'])
-
-const dialogFormVisible = ref(false);
-const operationType = ref('')
-const formData = reactive({
-  staffNo: "",
-  staffName: "",
-  sex: "",
-  identityCard: "",
-  nativePlace: "",
-  postJob: "",
-  adress: "",
-  firstStudy: "",
-  profession: "",
-  age: 0,
-  phone: "",
-  emergencyContact: "",
-  emergencyContactPhone: "",
-  dateSelect: "",
-  trialStartDate: "",
-  trialEndDate: "",
-  proSalary: null,
-  signDate: "",
-  salarySelect: "",
-  contractStartTime: "",
-  contractExpireTime: "",
-  contractTerm: null,
-  remark: "",
-});
-
-const formattedContractTerm = computed(() => {
-  const value = formData.contractTerm;
-  if (value === null || value === undefined || value === "") {
-    return "-";
-  }
-  const numberValue = Number(value);
-  if (!isNaN(numberValue)) {
-    return `${numberValue}骞碻;
-  }
-  return value;
-});
-
-const calculatedContractStart = computed(() => {
-  const endDate = formData.contractExpireTime;
-  const termValue = formData.contractTerm;
-  const numberValue = Number(termValue);
-  if (!endDate || isNaN(numberValue)) {
-    return formData.contractStartTime || "-";
-  }
-  const start = dayjs(endDate).subtract(numberValue, "year");
-  if (!start.isValid()) {
-    return formData.contractStartTime || "-";
-  }
-  return start.format("YYYY-MM-DD");
-});
-
-// 鎵撳紑寮规
-const openDialog = (type, row) => {
-  operationType.value = type;
-  dialogFormVisible.value = true;
-  // 閲嶇疆琛ㄥ崟鏁版嵁
-  Object.keys(formData).forEach(key => {
-    if (key === 'age') {
-      formData[key] = 0;
-    } else if (["proSalary", "contractTerm"].includes(key)) {
-      formData[key] = null;
-    } else {
-      formData[key] = "";
-    }
-  });
-  
-  if (operationType.value === 'edit' && row) {
-    // 鐩存帴浣跨敤 row 鏁版嵁璧嬪��
-    Object.assign(formData, row);
-  }
-}
-
-// 鍏抽棴寮规
-const closeDia = () => {
-  dialogFormVisible.value = false;
-  emit('close')
-};
-defineExpose({
-  openDialog,
-});
-</script>
-
-<style scoped>
-.detail-descriptions {
-  margin-bottom: 16px;
-  border-radius: 6px;
-  overflow: hidden;
-}
-
-.detail-descriptions :deep(.el-descriptions__cell) {
-  padding: 12px 16px !important;
-}
-
-.detail-descriptions :deep(.el-descriptions__label) {
-  width: 140px;
-  color: #606266;
-  background-color: #f7f9fc;
-  font-weight: 500;
-}
-
-.detail-descriptions :deep(.el-descriptions__content) {
-  color: #303133;
-  line-height: 20px;
-}
-</style>
\ No newline at end of file
diff --git a/src/views/personnelManagement/employeeRecord/index.vue b/src/views/personnelManagement/employeeRecord/index.vue
index 5a0d07c..19addfa 100644
--- a/src/views/personnelManagement/employeeRecord/index.vue
+++ b/src/views/personnelManagement/employeeRecord/index.vue
@@ -19,9 +19,9 @@
         >
       </div>
       <div>
-<!--        <el-button type="primary" @click="openForm('add')">鏂板鍏ヨ亴</el-button>-->
+        <el-button type="primary" @click="openFormNewOrEditFormDia('add')">鏂板鍏ヨ亴</el-button>
         <el-button @click="handleOut">瀵煎嚭</el-button>
-<!--        <el-button type="danger" plain @click="handleDelete">鍒犻櫎</el-button>-->
+        <el-button type="danger" plain @click="handleDelete">鍒犻櫎</el-button>
       </div>
     </div>
     <div class="table_list">
@@ -37,17 +37,26 @@
           :total="page.total"
       ></PIMTable>
     </div>
-    <form-dia ref="formDia" @close="handleQuery"></form-dia>
+    <show-form-dia ref="formDia" @close="handleQuery"></show-form-dia>
+    <new-or-edit-form-dia ref="formDiaNewOrEditFormDia" @close="handleQuery"></new-or-edit-form-dia>
+    <renew-contract
+        v-if="isShowRenewContractModal"
+        v-model:visible="isShowRenewContractModal"
+        :id="id"
+        @completed="handleQuery"
+    />
   </div>
 </template>
 
 <script setup>
 import { Search } from "@element-plus/icons-vue";
 import {onMounted, ref} from "vue";
-import FormDia from "@/views/personnelManagement/employeeRecord/components/formDia.vue";
 import {ElMessageBox} from "element-plus";
-import {staffOnJobListPage} from "@/api/personnelManagement/employeeRecord.js";
+import {batchDeleteStaffOnJobs, staffOnJobListPage} from "@/api/personnelManagement/staffOnJob.js";
 import dayjs from "dayjs";
+const NewOrEditFormDia = defineAsyncComponent(() => import("@/views/personnelManagement/employeeRecord/components/NewOrEditFormDia.vue"));
+const ShowFormDia = defineAsyncComponent(() => import( "@/views/personnelManagement/employeeRecord/components/Show.vue"));
+const RenewContract = defineAsyncComponent(() => import( "@/views/personnelManagement/employeeRecord/components/RenewContract.vue"));
 
 const data = reactive({
   searchForm: {
@@ -58,6 +67,8 @@
   },
 });
 const { searchForm } = toRefs(data);
+const isShowRenewContractModal = ref(false);
+const id = ref(0);
 const tableColumn = ref([
   {
     label: "鐘舵��",
@@ -97,6 +108,10 @@
   {
     label: "鎴风睄浣忓潃",
     prop: "nativePlace",
+  },
+  {
+    label: "閮ㄩ棬",
+    prop: "deptName",
   },
   {
     label: "宀椾綅",
@@ -154,14 +169,31 @@
     label: "鎿嶄綔",
     align: "center",
     fixed: 'right',
+    width: 180,
     operation: [
       {
-        name: "璇︽儏",
+        name: "缂栬緫",
         type: "text",
         clickFun: (row) => {
-          openForm("edit", row);
+          openFormNewOrEditFormDia("edit", row);
         },
       },
+      {
+        name: "缁鍚堝悓",
+        type: "text",
+        showHide: row => row.staffState === 1,
+        clickFun: (row) => {
+          isShowRenewContractModal.value = true;
+          id.value = row.id;
+        },
+      },
+      // {
+      //   name: "璇︽儏",
+      //   type: "text",
+      //   clickFun: (row) => {
+      //     openForm("edit", row);
+      //   },
+      // },
     ],
   },
 ]);
@@ -174,6 +206,7 @@
   total: 0
 });
 const formDia = ref()
+const formDiaNewOrEditFormDia = ref()
 const { proxy } = getCurrentInstance()
 
 const changeDaterange = (value) => {
@@ -200,7 +233,7 @@
   tableLoading.value = true;
   const params = { ...searchForm.value, ...page };
   params.entryDate = undefined
-  staffOnJobListPage({...params, staffState: 1}).then(res => {
+  staffOnJobListPage({...params}).then(res => {
     tableLoading.value = false;
     tableData.value = res.data.records
     page.total = res.data.total;
@@ -219,6 +252,37 @@
     formDia.value?.openDialog(type, row)
   })
 };
+const openFormNewOrEditFormDia = (type, row) => {
+  nextTick(() => {
+    formDiaNewOrEditFormDia.value?.openDialog(type, row)
+  })
+};
+
+// 鍒犻櫎
+const handleDelete = () => {
+  let ids = [];
+  if (selectedRows.value.length > 0) {
+    ids = selectedRows.value.map((item) => item.id);
+  } else {
+    proxy.$modal.msgWarning("璇烽�夋嫨鏁版嵁");
+    return;
+  }
+  ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�", "瀵煎嚭", {
+    confirmButtonText: "纭",
+    cancelButtonText: "鍙栨秷",
+    type: "warning",
+  })
+      .then(() => {
+        batchDeleteStaffOnJobs(ids).then((res) => {
+          proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
+          getList();
+        });
+      })
+      .catch(() => {
+        proxy.$modal.msg("宸插彇娑�");
+      });
+};
+
 // 瀵煎嚭
 const handleOut = () => {
   ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
@@ -227,7 +291,7 @@
     type: "warning",
   })
       .then(() => {
-        proxy.download("/staff/staffOnJob/export", {staffState: 1}, "鍦ㄨ亴鍛樺伐鍙拌处.xlsx");
+        proxy.download("/staff/staffOnJob/export", {staffState: 1}, "鍛樺伐鍙拌处.xlsx");
       })
       .catch(() => {
         proxy.$modal.msg("宸插彇娑�");
diff --git a/src/views/personnelManagement/monthlyStatistics/components/formDia.vue b/src/views/personnelManagement/monthlyStatistics/components/formDia.vue
new file mode 100644
index 0000000..c67fdd6
--- /dev/null
+++ b/src/views/personnelManagement/monthlyStatistics/components/formDia.vue
@@ -0,0 +1,318 @@
+<template>
+  <el-dialog v-model="dialogVisible"
+             :title="title"
+             width="700px"
+             :close-on-click-modal="false">
+    <el-form ref="formRef"
+             :model="form"
+             :rules="rules"
+             label-width="140px"
+             label-position="top">
+      <el-row :gutter="20">
+        <el-col :span="12">
+          <el-form-item label="缁熻鏈堜唤"
+                        prop="payDate">
+            <el-date-picker v-model="form.payDate"
+                            type="month"
+                            value-format="YYYY-MM"
+                            format="YYYY-MM"
+                            placeholder="璇烽�夋嫨鏈堜唤"
+                            style="width: 100%"
+                            :disabled="operationType === 'view'" />
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="濮撳悕"
+                        prop="staffId">
+            <el-select v-model="form.staffId"
+                       placeholder="璇烽�夋嫨鍛樺伐"
+                       style="width: 100%"
+                       :disabled="operationType === 'view'">
+              <el-option v-for="item in userList"
+                         :key="item.id"
+                         :label="item.staffName"
+                         :value="item.id" />
+            </el-select>
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <el-row :gutter="20">
+        <el-col :span="12">
+          <el-form-item label="鍩烘湰宸ヨ祫"
+                        prop="basicSalary">
+            <el-input v-model="form.basicSalary"
+                      type="number"
+                      placeholder="璇疯緭鍏ュ熀鏈伐璧�"
+                      :disabled="operationType === 'view'" />
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="璁′欢宸ヨ祫"
+                        prop="pieceworkSalary">
+            <el-input v-model="form.pieceworkSalary"
+                      type="number"
+                      placeholder="璇疯緭鍏ヨ浠跺伐璧�"
+                      :disabled="operationType === 'view'" />
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <el-row :gutter="20">
+        <el-col :span="12">
+          <el-form-item label="璁℃椂宸ヨ祫"
+                        prop="hourlySalary">
+            <el-input v-model="form.hourlySalary"
+                      type="number"
+                      placeholder="璇疯緭鍏ヨ鏃跺伐璧�"
+                      :disabled="operationType === 'view'" />
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="鍏朵粬鏀跺叆"
+                        prop="otherIncome">
+            <el-input v-model="form.otherIncome"
+                      type="number"
+                      placeholder="璇疯緭鍏ュ叾浠栨敹鍏�"
+                      :disabled="operationType === 'view'" />
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <el-row :gutter="20">
+        <el-col :span="12">
+          <el-form-item label="绀句繚涓汉"
+                        prop="socialSecurityIndividuals">
+            <el-input v-model="form.socialSecurityIndividuals"
+                      type="number"
+                      placeholder="璇疯緭鍏ョぞ淇濅釜浜�"
+                      :disabled="operationType === 'view'" />
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="鍏Н閲戜釜浜�"
+                        prop="providentFundIndividuals">
+            <el-input v-model="form.providentFundIndividuals"
+                      type="number"
+                      placeholder="璇疯緭鍏ュ叕绉噾涓汉"
+                      :disabled="operationType === 'view'" />
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <el-row :gutter="20">
+        <el-col :span="12">
+          <el-form-item label="涓汉鎵�寰楃◣"
+                        prop="personalIncomeTax">
+            <el-input v-model="form.personalIncomeTax"
+                      type="number"
+                      placeholder="璇疯緭鍏ヤ釜浜烘墍寰楃◣"
+                      :disabled="operationType === 'view'" />
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="鍏朵粬鎵f"
+                        prop="otherDeductions">
+            <el-input v-model="form.otherDeductions"
+                      type="number"
+                      placeholder="璇疯緭鍏ュ叾浠栨墸娆�"
+                      :disabled="operationType === 'view'" />
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <el-row :gutter="20">
+        <el-col :span="24">
+          <el-form-item label="澶囨敞"
+                        prop="remark">
+            <el-input v-model="form.remark"
+                      type="textarea"
+                      placeholder="璇疯緭鍏ュ娉�"
+                      :rows="3"
+                      :disabled="operationType === 'view'" />
+          </el-form-item>
+        </el-col>
+      </el-row>
+    </el-form>
+    <template #footer>
+      <span class="dialog-footer">
+        <el-button @click="dialogVisible = false">鍙栨秷</el-button>
+        <el-button type="primary"
+                   @click="submitForm"
+                   v-if="operationType !== 'view'">
+          纭畾
+        </el-button>
+      </span>
+    </template>
+  </el-dialog>
+</template>
+
+<script setup>
+  import { ref, reactive, computed, onMounted } from "vue";
+  import { ElMessage } from "element-plus";
+  import {
+    monthlyStatisticsAdd,
+    monthlyStatisticsUpdate,
+    staffOnJobList,
+  } from "@/api/personnelManagement/monthlyStatistics.js";
+
+  const props = defineProps({
+    modelValue: {
+      type: Boolean,
+      default: false,
+    },
+    operationType: {
+      type: String,
+      default: "add",
+    },
+    row: {
+      type: Object,
+      default: () => ({}),
+    },
+  });
+
+  const emit = defineEmits(["update:modelValue", "close"]);
+
+  const dialogVisible = computed({
+    get: () => props.modelValue,
+    set: val => emit("update:modelValue", val),
+  });
+
+  const title = computed(() => {
+    if (props.operationType === "add") return "鏂板钖祫鍙拌处";
+    if (props.operationType === "edit") return "缂栬緫钖祫鍙拌处";
+    return "鏌ョ湅钖祫鍙拌处";
+  });
+
+  const formRef = ref();
+  const form = reactive({
+    id: "",
+    payDate: "",
+    staffId: "",
+    basicSalary: 0,
+    pieceworkSalary: 0,
+    hourlySalary: 0,
+    otherIncome: 0,
+    socialSecurityIndividuals: 0,
+    providentFundIndividuals: 0,
+    personalIncomeTax: 0,
+    otherDeductions: 0,
+    payableWages: 0,
+    deductibleWages: 0,
+    actualWages: 0,
+    remark: "",
+  });
+
+  const rules = {
+    payDate: [{ required: true, message: "璇烽�夋嫨缁熻鏈堜唤", trigger: "change" }],
+    staffId: [{ required: true, message: "璇烽�夋嫨鍛樺伐", trigger: "change" }],
+    basicSalary: [{ required: true, message: "璇疯緭鍏ュ熀鏈伐璧�", trigger: "blur" }],
+  };
+
+  const userList = ref([]);
+
+  const loadUserList = () => {
+    // userListNoPage().then(res => {
+    //   userList.value = res.data || [];
+    // });
+    staffOnJobList().then(res => {
+      userList.value = res.data || [];
+    });
+  };
+
+  const openDialog = (type, row) => {
+    // 閲嶇疆琛ㄥ崟
+    Object.assign(form, {
+      id: "",
+      payDate: "",
+      staffId: "",
+      basicSalary: 0,
+      pieceworkSalary: 0,
+      hourlySalary: 0,
+      otherIncome: 0,
+      socialSecurityIndividuals: 0,
+      providentFundIndividuals: 0,
+      personalIncomeTax: 0,
+      otherDeductions: 0,
+      payableWages: 0,
+      deductibleWages: 0,
+      actualWages: 0,
+      remark: "",
+    });
+
+    if (type === "add") {
+      dialogVisible.value = true;
+    } else if (type === "edit" || type === "view") {
+      if (row && row.id) {
+        Object.assign(form, row);
+        dialogVisible.value = true;
+      }
+    }
+  };
+
+  const submitForm = () => {
+    formRef.value.validate(valid => {
+      if (valid) {
+        form.basicSalary = Number(form.basicSalary);
+        form.pieceworkSalary = Number(form.pieceworkSalary);
+        form.hourlySalary = Number(form.hourlySalary);
+        form.otherIncome = Number(form.otherIncome);
+        form.socialSecurityIndividuals = Number(form.socialSecurityIndividuals);
+        form.providentFundIndividuals = Number(form.providentFundIndividuals);
+        form.personalIncomeTax = Number(form.personalIncomeTax);
+        form.otherDeductions = Number(form.otherDeductions);
+
+        // 璁$畻搴斿彂宸ヨ祫銆佸簲鎵e伐璧勫拰瀹炲彂宸ヨ祫
+        const payableWages =
+          form.basicSalary +
+          form.pieceworkSalary +
+          form.hourlySalary +
+          form.otherIncome;
+        const deductibleWages =
+          form.socialSecurityIndividuals +
+          form.providentFundIndividuals +
+          form.personalIncomeTax +
+          form.otherDeductions;
+        const actualWages = payableWages - deductibleWages;
+
+        const submitData = {
+          ...form,
+          payableWages,
+          deductibleWages,
+          actualWages,
+        };
+
+        if (props.operationType === "add") {
+          monthlyStatisticsAdd(submitData).then(res => {
+            if (res.code === 200) {
+              ElMessage.success("鏂板鎴愬姛");
+              dialogVisible.value = false;
+              emit("close");
+            } else {
+              ElMessage.error(res.msg || "鏂板澶辫触");
+            }
+          });
+        } else if (props.operationType === "edit") {
+          monthlyStatisticsUpdate(submitData).then(res => {
+            if (res.code === 200) {
+              ElMessage.success("鏇存柊鎴愬姛");
+              dialogVisible.value = false;
+              emit("close");
+            } else {
+              ElMessage.error(res.msg || "鏇存柊澶辫触");
+            }
+          });
+        }
+      }
+    });
+  };
+
+  onMounted(() => {
+    loadUserList();
+  });
+
+  defineExpose({
+    openDialog,
+  });
+</script>
+
+<style scoped>
+  .dialog-footer {
+    text-align: right;
+  }
+</style>
\ No newline at end of file
diff --git a/src/views/personnelManagement/monthlyStatistics/index.vue b/src/views/personnelManagement/monthlyStatistics/index.vue
new file mode 100644
index 0000000..741a4b7
--- /dev/null
+++ b/src/views/personnelManagement/monthlyStatistics/index.vue
@@ -0,0 +1,303 @@
+<template>
+  <div class="app-container">
+    <div class="search_form">
+      <div>
+        <span class="search_title">濮撳悕锛�</span>
+        <el-input v-model="searchForm.staffName"
+                  style="width: 240px"
+                  placeholder="璇疯緭鍏ュ鍚嶆悳绱�"
+                  @change="handleQuery"
+                  clearable
+                  :prefix-icon="Search" />
+        <span class="search_title ml10">鏈堜唤锛�</span>
+        <el-date-picker v-model="searchForm.payDateStr"
+                        type="month"
+                        @change="handleQuery"
+                        value-format="YYYY-MM"
+                        format="YYYY-MM"
+                        placeholder="璇烽�夋嫨鏈堜唤"
+                        style="width: 240px"
+                        clearable />
+        <el-button type="primary"
+                   @click="handleQuery"
+                   style="margin-left: 10px">
+          鎼滅储
+        </el-button>
+      </div>
+      <div>
+        <el-button @click="handleExport"
+                   style="margin-right: 10px">瀵煎嚭</el-button>
+        <el-button type="primary"
+                   @click="openForm('add')">鏂板鍙拌处</el-button>
+        <el-button type="danger"
+                   plain
+                   @click="handleDelete">鍒犻櫎</el-button>
+      </div>
+    </div>
+    <div class="table_list">
+      <PIMTable rowKey="id"
+                :column="tableColumn"
+                :tableData="tableData"
+                :page="page"
+                :isSelection="true"
+                @selection-change="handleSelectionChange"
+                :tableLoading="tableLoading"
+                @pagination="pagination"
+                :total="page.total"></PIMTable>
+    </div>
+    <form-dia v-model="dialogVisible"
+              :operation-type="operationType"
+              :row="currentRow"
+              ref="formDia"
+              @close="handleQuery"></form-dia>
+  </div>
+</template>
+
+<script setup>
+  import { Search } from "@element-plus/icons-vue";
+  import {
+    onMounted,
+    ref,
+    reactive,
+    toRefs,
+    getCurrentInstance,
+    nextTick,
+  } from "vue";
+  import { ElMessageBox } from "element-plus";
+  import dayjs from "dayjs";
+  import FormDia from "./components/formDia.vue";
+  import {
+    monthlyStatisticsListPage,
+    monthlyStatisticsDelete,
+  } from "@/api/personnelManagement/monthlyStatistics.js";
+
+  const data = reactive({
+    searchForm: {
+      staffName: "",
+      payDateStr: "",
+    },
+  });
+
+  const { searchForm } = toRefs(data);
+
+  const tableColumn = ref([
+    {
+      label: "鍛樺伐濮撳悕",
+      prop: "staffName",
+    },
+    {
+      label: "閮ㄩ棬",
+      prop: "deptName",
+      width: 140,
+    },
+    {
+      label: "鏈堜唤",
+      prop: "payDate",
+    },
+    {
+      label: "鍩烘湰宸ヨ祫",
+      prop: "basicSalary",
+    },
+    {
+      label: "璁′欢宸ヨ祫",
+      prop: "pieceworkSalary",
+    },
+    {
+      label: "璁℃椂宸ヨ祫",
+      prop: "hourlySalary",
+    },
+    {
+      label: "鍏朵粬鏀跺叆",
+      prop: "otherIncome",
+    },
+    {
+      label: "绀句繚涓汉",
+      prop: "socialSecurityIndividuals",
+    },
+    {
+      label: "鍏Н閲戜釜浜�",
+      prop: "providentFundIndividuals",
+      width: 140,
+    },
+    {
+      label: "宸ヨ祫涓◣",
+      prop: "personalIncomeTax",
+    },
+    {
+      label: "鍏朵粬鏀嚭",
+      prop: "otherDeductions",
+    },
+    {
+      label: "搴斿彂宸ヨ祫",
+      prop: "payableWages",
+    },
+    {
+      label: "搴旀墸宸ヨ祫",
+      prop: "deductibleWages",
+    },
+    {
+      label: "瀹炲彂宸ヨ祫",
+      prop: "actualWages",
+    },
+    {
+      label: "澶囨敞",
+      prop: "remark",
+      width: 150,
+    },
+    {
+      dataType: "action",
+      label: "鎿嶄綔",
+      align: "center",
+      fixed: "right",
+      width: 220,
+      operation: [
+        {
+          name: "缂栬緫",
+          type: "text",
+          clickFun: row => {
+            openForm("edit", row);
+          },
+        },
+        // {
+        //   name: "鏌ョ湅",
+        //   type: "text",
+        //   clickFun: row => {
+        //     openForm("view", row);
+        //   },
+        // },
+      ],
+    },
+  ]);
+
+  const tableData = ref([]);
+  const selectedRows = ref([]);
+  const tableLoading = ref(false);
+  const page = reactive({
+    current: 1,
+    size: 100,
+    total: 0,
+  });
+
+  const formDia = ref();
+  const dialogVisible = ref(false);
+  const operationType = ref("add");
+  const currentRow = ref({});
+  const { proxy } = getCurrentInstance();
+
+  // 鏌ヨ鍒楄〃
+  /** 鎼滅储鎸夐挳鎿嶄綔 */
+  const handleQuery = () => {
+    page.current = 1;
+    getList();
+  };
+
+  const pagination = obj => {
+    page.current = obj.page;
+    page.size = obj.limit;
+    getList();
+  };
+
+  const getList = () => {
+    tableLoading.value = true;
+    monthlyStatisticsListPage({ ...page, ...searchForm.value })
+      .then(res => {
+        tableLoading.value = false;
+        tableData.value = res.data.records;
+        page.total = res.data.total;
+      })
+      .catch(err => {
+        tableLoading.value = false;
+      });
+  };
+
+  // 琛ㄦ牸閫夋嫨鏁版嵁
+  const handleSelectionChange = selection => {
+    selectedRows.value = selection;
+  };
+
+  // 鎵撳紑寮规
+  const openForm = (type, row) => {
+    operationType.value = type;
+    currentRow.value = row || {};
+    dialogVisible.value = true;
+    nextTick(() => {
+      formDia.value?.openDialog(type, row);
+    });
+  };
+
+  // 鍒犻櫎
+  const handleDelete = () => {
+    let ids = [];
+    if (selectedRows.value.length > 0) {
+      ids = selectedRows.value.map(item => item.id);
+    } else {
+      proxy.$modal.msgWarning("璇烽�夋嫨鏁版嵁");
+      return;
+    }
+    ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�", "鍒犻櫎", {
+      confirmButtonText: "纭",
+      cancelButtonText: "鍙栨秷",
+      type: "warning",
+    })
+      .then(() => {
+        monthlyStatisticsDelete(ids).then(res => {
+          proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
+          getList();
+        });
+      })
+      .catch(() => {
+        proxy.$modal.msg("宸插彇娑�");
+      });
+  };
+
+  // 瀵煎嚭
+  const handleExport = () => {
+    ElMessageBox.confirm("鏄惁纭瀵煎嚭浜哄憳钖祫鍙拌处锛�", "瀵煎嚭", {
+      confirmButtonText: "纭",
+      cancelButtonText: "鍙栨秷",
+      type: "warning",
+    })
+      .then(() => {
+        proxy.download(
+          "/compensationPerformance/export",
+          { ...searchForm.value, ...page },
+          "浜哄憳钖祫鍙拌处.xlsx"
+        );
+      })
+      .catch(() => {
+        proxy.$modal.msg("宸插彇娑�");
+      });
+  };
+
+  onMounted(() => {
+    getList();
+  });
+</script>
+
+<style scoped>
+  .search_form {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    margin-bottom: 20px;
+    flex-wrap: wrap;
+    gap: 10px;
+  }
+
+  .search_title {
+    font-weight: 500;
+    margin-right: 5px;
+  }
+
+  .ml10 {
+    margin-left: 10px;
+  }
+
+  .table_list {
+    margin-top: 20px;
+  }
+
+  .dialog-footer {
+    text-align: right;
+  }
+</style>
\ No newline at end of file
diff --git a/src/views/personnelManagement/onboarding/components/formDia.vue b/src/views/personnelManagement/onboarding/components/formDia.vue
deleted file mode 100644
index d775e6b..0000000
--- a/src/views/personnelManagement/onboarding/components/formDia.vue
+++ /dev/null
@@ -1,272 +0,0 @@
-<template>
-  <div>
-    <el-dialog
-        v-model="dialogFormVisible"
-        :title="operationType === 'add' ? '鏂板鍏ヨ亴' : '缂栬緫浜哄憳'"
-        width="70%"
-        @close="closeDia"
-    >
-      <el-form :model="form" label-width="140px" label-position="top" :rules="rules" ref="formRef">
-        <el-row :gutter="30">
-          <el-col :span="12">
-            <el-form-item label="鍛樺伐缂栧彿锛�" prop="staffNo">
-              <el-input v-model="form.staffNo" placeholder="璇疯緭鍏�" clearable :disabled="operationType !== 'add'"/>
-            </el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item label="濮撳悕锛�" prop="staffName">
-              <el-input v-model="form.staffName" placeholder="璇疯緭鍏�" clearable/>
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row :gutter="30">
-          <el-col :span="12">
-            <el-form-item label="鎬у埆锛�" prop="sex">
-              <el-select v-model="form.sex">
-                <el-option label="鐢�" value="鐢�" />
-                <el-option label="濂�" value="濂�" />
-              </el-select>
-            </el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item label="鎴风睄浣忓潃锛�" prop="nativePlace">
-              <el-input v-model="form.nativePlace" placeholder="璇疯緭鍏�" clearable/>
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row :gutter="30">
-          <el-col :span="12">
-            <el-form-item label="宀椾綅锛�" prop="postJob">
-              <el-input v-model="form.postJob" placeholder="璇疯緭鍏�" clearable/>
-            </el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item label="鐜颁綇鍧�锛�" prop="adress">
-              <el-input v-model="form.adress" placeholder="璇疯緭鍏�" clearable/>
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row :gutter="30">
-          <el-col :span="12">
-            <el-form-item label="绗竴瀛﹀巻锛�" prop="firstStudy">
-              <el-input v-model="form.firstStudy" placeholder="璇疯緭鍏�" clearable/>
-            </el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item label="涓撲笟锛�" prop="profession">
-              <el-input v-model="form.profession" placeholder="璇疯緭鍏�" clearable/>
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row :gutter="30">
-          <el-col :span="12">
-            <el-form-item label="骞撮緞锛�" prop="age">
-              <el-input-number v-model="form.age" :precision="0" :step="1" style="width: 100%"/>
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row :gutter="30">
-          <el-col :span="12">
-            <el-form-item label="鑱旂郴鐢佃瘽锛�" prop="phone">
-              <el-input v-model="form.phone" placeholder="璇疯緭鍏�" clearable/>
-            </el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item label="绱ф�ヨ仈绯讳汉锛�" prop="emergencyContact">
-              <el-input v-model="form.emergencyContact" placeholder="璇疯緭鍏�" clearable/>
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row :gutter="30">
-          <el-col :span="12">
-            <el-form-item label="绱ф�ヨ仈绯讳汉鑱旂郴鐢佃瘽锛�" prop="emergencyContactPhone">
-              <el-input v-model="form.emergencyContactPhone" placeholder="璇疯緭鍏�" clearable/>
-            </el-form-item>
-          </el-col>
-         <el-col :span="12">
-           <el-form-item label="鍚堝悓骞撮檺锛�" prop="contractTerm">
-             <el-input-number v-model="form.contractTerm" :precision="0" :step="1" style="width: 100%" :disabled="true"/>
-           </el-form-item>
-         </el-col>
-        </el-row>
-        <el-row :gutter="30">
-          <el-col :span="12">
-            <el-form-item label="鍚堝悓寮�濮嬫棩鏈燂細" prop="contractStartTime">
-              <el-date-picker
-                  v-model="form.contractStartTime"
-                  type="date"
-                  placeholder="璇烽�夋嫨鏃ユ湡"
-                  value-format="YYYY-MM-DD"
-                  format="YYYY-MM-DD"
-                  clearable
-                  style="width: 100%"
-                  @change="calculateContractTerm"
-              />
-            </el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item label="鍚堝悓缁撴潫鏃ユ湡锛�" prop="contractEndTime">
-              <el-date-picker
-                  v-model="form.contractEndTime"
-                  type="date"
-                  placeholder="璇烽�夋嫨鏃ユ湡"
-                  value-format="YYYY-MM-DD"
-                  format="YYYY-MM-DD"
-                  clearable
-                  style="width: 100%"
-                  @change="calculateContractTerm"
-              />
-            </el-form-item>
-          </el-col>
-        </el-row>
-      </el-form>
-      <template #footer>
-        <div class="dialog-footer">
-          <el-button type="primary" @click="submitForm">纭</el-button>
-          <el-button @click="closeDia">鍙栨秷</el-button>
-        </div>
-      </template>
-    </el-dialog>
-  </div>
-</template>
-
-<script setup>
-import {ref, reactive, toRefs, getCurrentInstance} from "vue";
-import {getStaffJoinInfo, staffJoinAdd, staffJoinUpdate} from "@/api/personnelManagement/onboarding.js";
-const { proxy } = getCurrentInstance()
-const emit = defineEmits(['close'])
-
-const dialogFormVisible = ref(false);
-const operationType = ref('')
-const data = reactive({
-  form: {
-    staffNo: "",
-    staffName: "",
-    sex: "",
-    nativePlace: "",
-    postJob: "",
-    adress: "",
-    firstStudy: "",
-    profession: "",
-    age: 0,
-    phone: "",
-    emergencyContact: "",
-    emergencyContactPhone: "",
-    contractTerm: 0,
-    contractStartTime: "",
-    contractEndTime: "",
-    staffState: "",
-  },
-  rules: {
-    staffNo: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" },],
-    staffName: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
-    sex: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
-    nativePlace: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
-    postJob: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
-    adress: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
-    firstStudy: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
-    profession: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
-    age: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
-    phone: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
-    emergencyContact: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
-    emergencyContactPhone: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
-    contractTerm: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
-    contractStartTime: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
-    contractEndTime: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
-  },
-});
-const { form, rules } = toRefs(data);
-
-// 鎵撳紑寮规
-const openDialog = (type, row) => {
-  operationType.value = type;
-  dialogFormVisible.value = true;
-  if (operationType.value === 'edit') {
-    getStaffJoinInfo(row.id).then(res => {
-      form.value = {...res.data}
-      // 缂栬緫鏃朵篃璁$畻涓�娆″悎鍚屽勾闄�
-      calculateContractTerm();
-    })
-  } else {
-    // 鏂板鏃堕噸缃〃鍗�
-    form.value = {
-      staffNo: "",
-      staffName: "",
-      sex: "",
-      nativePlace: "",
-      postJob: "",
-      adress: "",
-      firstStudy: "",
-      profession: "",
-      age: 0,
-      phone: "",
-      emergencyContact: "",
-      emergencyContactPhone: "",
-      contractTerm: 0,
-      contractStartTime: "",
-      contractEndTime: "",
-      staffState: "",
-    };
-  }
-}
-// 鎻愪氦浜у搧琛ㄥ崟
-const submitForm = () => {
-  proxy.$refs.formRef.validate(valid => {
-    if (valid) {
-      form.value.staffState = 1
-      if (operationType.value === "add") {
-        staffJoinAdd(form.value).then(res => {
-          proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
-          closeDia();
-        })
-      } else {
-        staffJoinUpdate(form.value).then(res => {
-          proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
-          closeDia();
-        })
-      }
-    }
-  })
-}
-// 璁$畻鍚堝悓骞撮檺
-const calculateContractTerm = () => {
-  if (form.value.contractStartTime && form.value.contractEndTime) {
-    const startDate = new Date(form.value.contractStartTime);
-    const endDate = new Date(form.value.contractEndTime);
-    
-    if (endDate >= startDate) {
-      // 璁$畻骞翠唤宸�
-      const yearDiff = endDate.getFullYear() - startDate.getFullYear();
-      const monthDiff = endDate.getMonth() - startDate.getMonth();
-      const dayDiff = endDate.getDate() - startDate.getDate();
-      
-      let years = yearDiff;
-      
-      // 濡傛灉缁撴潫鏃ユ湡鐨勬湀鏃ュ皬浜庡紑濮嬫棩鏈熺殑鏈堟棩锛屽垯鍑忓幓1骞�
-      if (monthDiff < 0 || (monthDiff === 0 && dayDiff < 0)) {
-        years = yearDiff - 1;
-      }
-      
-      form.value.contractTerm = Math.max(0, years);
-    } else {
-      form.value.contractTerm = 0;
-    }
-  } else {
-    form.value.contractTerm = 0;
-  }
-};
-
-// 鍏抽棴寮规
-const closeDia = () => {
-  proxy.resetForm("formRef");
-  dialogFormVisible.value = false;
-  emit('close')
-};
-defineExpose({
-  openDialog,
-});
-</script>
-
-<style scoped>
-
-</style>
\ No newline at end of file
diff --git a/src/views/personnelManagement/onboarding/components/formDiaXJHT.vue b/src/views/personnelManagement/onboarding/components/formDiaXJHT.vue
deleted file mode 100644
index 6b70aef..0000000
--- a/src/views/personnelManagement/onboarding/components/formDiaXJHT.vue
+++ /dev/null
@@ -1,427 +0,0 @@
-<template>
-  <div>
-    <el-dialog
-        v-model="dialogFormVisible"
-        :title="operationType === 'add' ? '鏂板鍏ヨ亴' : '缂栬緫浜哄憳'"
-        width="70%"
-        @close="closeDia"
-    >
-      <el-form :model="form" label-width="140px" label-position="top" :rules="rules" ref="formRef">
-        <el-row :gutter="30">
-          <el-col :span="12">
-            <el-form-item label="鍛樺伐缂栧彿锛�" prop="staffNo">
-              <el-input v-model="form.staffNo" placeholder="璇疯緭鍏�" clearable :disabled="operationType !== 'add'"/>
-            </el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item label="濮撳悕锛�" prop="staffName">
-              <el-input v-model="form.staffName" placeholder="璇疯緭鍏�" clearable/>
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row :gutter="30">
-          <el-col :span="12">
-            <el-form-item label="鎬у埆锛�" prop="sex">
-              <el-select v-model="form.sex">
-                <el-option label="鐢�" value="鐢�" />
-                <el-option label="濂�" value="濂�" />
-              </el-select>
-            </el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item label="鎴风睄浣忓潃锛�" prop="nativePlace">
-              <el-input v-model="form.nativePlace" placeholder="璇疯緭鍏�" clearable/>
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row :gutter="30">
-          <el-col :span="12">
-            <el-form-item label="宀椾綅锛�" prop="postJob">
-              <el-input v-model="form.postJob" placeholder="璇疯緭鍏�" clearable/>
-            </el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item label="鐜颁綇鍧�锛�" prop="adress">
-              <el-input v-model="form.adress" placeholder="璇疯緭鍏�" clearable/>
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row :gutter="30">
-          <el-col :span="12">
-            <el-form-item label="绗竴瀛﹀巻锛�" prop="firstStudy">
-              <el-input v-model="form.firstStudy" placeholder="璇疯緭鍏�" clearable/>
-            </el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item label="涓撲笟锛�" prop="profession">
-              <el-input v-model="form.profession" placeholder="璇疯緭鍏�" clearable/>
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row :gutter="30">
-					<el-col :span="12">
-						<el-form-item label="韬唤璇佸彿锛�" prop="identityCard">
-							<el-input v-model="form.identityCard" placeholder="璇疯緭鍏ヨ韩浠借瘉鍙风爜" clearable maxlength="18" />
-						</el-form-item>
-					</el-col>
-          <el-col :span="12">
-            <el-form-item label="骞撮緞锛�" prop="age">
-              <el-input-number v-model="form.age" :precision="0" :step="1" style="width: 100%"/>
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row :gutter="30">
-          <el-col :span="12">
-            <el-form-item label="鑱旂郴鐢佃瘽锛�" prop="phone">
-              <el-input v-model="form.phone" placeholder="璇疯緭鍏�" clearable/>
-            </el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item label="绱ф�ヨ仈绯讳汉锛�" prop="emergencyContact">
-              <el-input v-model="form.emergencyContact" placeholder="璇疯緭鍏�" clearable/>
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row :gutter="30">
-          <el-col :span="12">
-            <el-form-item label="绱ф�ヨ仈绯讳汉鑱旂郴鐢佃瘽锛�" prop="emergencyContactPhone">
-              <el-input v-model="form.emergencyContactPhone" placeholder="璇疯緭鍏�" clearable/>
-            </el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item label="鍚堝悓绛捐鏃ユ湡锛�" prop="signDate">
-              <el-date-picker
-                  v-model="form.signDate"
-                  type="date"
-                  placeholder="璇烽�夋嫨鏃ユ湡"
-                  value-format="YYYY-MM-DD"
-                  format="YYYY-MM-DD"
-                  clearable
-                  style="width: 100%"
-              />
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row :gutter="30">
-          <el-col :span="24">
-            <el-form-item label="鍔冲姩鍚堝悓鏈熼檺閫夋嫨锛�" prop="dateSelect">
-              <el-radio-group v-model="form.dateSelect">
-                <el-radio :value="'A'">
-                  A銆佹湁鍥哄畾鏈熼檺
-                </el-radio>
-                <el-radio :value="'B'">
-                  B銆佹棤鍥哄畾鏈熼檺
-                </el-radio>
-                <el-radio :value="'C'">
-                  C銆佷互瀹屾垚涓�瀹氬伐浣滀换鍔′负鏈熼檺
-                </el-radio>
-              </el-radio-group>
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row :gutter="30" v-if="showProbationDates">
-          <el-col :span="12">
-            <el-form-item label="璇曠敤鏈熷紑濮嬫棩鏈燂細" prop="trialStartDate">
-              <el-date-picker
-                  v-model="form.trialStartDate"
-                  type="date"
-                  placeholder="璇烽�夋嫨鏃ユ湡"
-                  value-format="YYYY-MM-DD"
-                  format="YYYY-MM-DD"
-                  clearable
-                  style="width: 100%"
-              />
-            </el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item label="璇曠敤鏈熺粨鏉熸棩鏈燂細" prop="trialEndDate">
-              <el-date-picker
-                  v-model="form.trialEndDate"
-                  type="date"
-                  placeholder="璇烽�夋嫨鏃ユ湡"
-                  value-format="YYYY-MM-DD"
-                  format="YYYY-MM-DD"
-                  clearable
-                  style="width: 100%"
-              />
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row :gutter="30">
-          <el-col :span="12">
-            <el-form-item label="鍚堝悓骞撮檺锛�" prop="contractTerm">
-              <el-input-number v-model="form.contractTerm" :precision="0" :step="1" style="width: 100%" :disabled="true"/>
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row :gutter="30">
-          <el-col :span="12">
-            <el-form-item label="鍚堝悓寮�濮嬫棩鏈燂細" prop="contractStartTime">
-              <el-date-picker
-                  v-model="form.contractStartTime"
-                  type="date"
-                  placeholder="璇烽�夋嫨鏃ユ湡"
-                  value-format="YYYY-MM-DD"
-                  format="YYYY-MM-DD"
-                  clearable
-                  style="width: 100%"
-									@change="calculateContractTerm"
-              />
-            </el-form-item>
-          </el-col>
-          <el-col :span="12" v-if="showContractEnd">
-            <el-form-item label="鍚堝悓缁撴潫鏃ユ湡锛�" prop="contractEndTime">
-              <el-date-picker
-                  v-model="form.contractEndTime"
-                  type="date"
-                  placeholder="璇烽�夋嫨鏃ユ湡"
-                  value-format="YYYY-MM-DD"
-                  format="YYYY-MM-DD"
-                  clearable
-                  style="width: 100%"
-									@change="calculateContractTerm"
-              />
-            </el-form-item>
-          </el-col>
-        </el-row>
-				<el-row :gutter="30">
-					<el-col :span="12">
-						<el-form-item label="璇曠敤鏈熷伐璧勶細" prop="proSalary">
-							<el-input-number placeholder="璇疯緭鍏ヨ瘯鐢ㄦ湡宸ヨ祫" :precision="2"
-															 :step="100"
-															 :min="0" v-model="form.proSalary" style="width: 100%"/>
-						</el-form-item>
-					</el-col>
-				</el-row>
-        <el-row :gutter="30">
-          <el-col :span="24">
-            <el-form-item label="宸ヨ祫鎶ラ叕锛�" prop="salarySelect">
-              <el-radio-group v-model="form.salarySelect" class="salary-radio-group">
-                <el-radio :value="'A'" class="salary-radio-item">
-                  A銆佷箼鏂圭殑宸ヨ祫鎶ラ叕鎸夌収鐢叉柟渚濇硶鍒跺畾鐨勮绔犲埗搴︿腑鐨勫唴閮ㄥ伐璧勫垎閰嶅姙娉曠‘瀹氾紝鏍规嵁涔欐柟鐨勫伐浣滃矖浣嶇‘瀹氬叾姣忔湀宸ヨ祫銆�
-                </el-radio>
-                <el-radio :value="'B'" class="salary-radio-item">
-                  B銆佺敳鏂瑰涔欐柟瀹炶鍩烘湰宸ヨ祫鍜岀哗鏁堝伐璧勭浉缁撳悎鐨勫唴閮ㄥ伐璧勫垎閰嶅姙娉曪紝涔欐柟鐨勬敹鍏ュ寘鎷熀鏈伐璧勩�佽椁愩�佷氦閫氥�佺敓娲讳綇瀹跨瓑鍚勯」琛ュ姪锛屽鏈夊彉鍔ㄦ牴鎹唴閮ㄥ伐璧勫垎閰嶅姙娉曡皟鏁村叾宸ヨ祫锛涚哗鏁堝伐璧勬牴鎹箼鏂圭殑宸ヤ綔涓氱哗銆佸姵鍔ㄦ垚鏋滃拰瀹為檯璐$尞鎸夌収鍐呴儴鍒嗛厤鍔炴硶鑰冩牳纭畾銆�
-                </el-radio>
-                <el-radio :value="'C'" class="salary-radio-item">
-                  C銆佺敳鏂瑰疄琛岃浠跺伐璧勫埗锛屼互鐢叉柟鎺ュ埌璁㈠崟鍙婂叕鍙哥敓浜ц鍒掞紝鎸夌収瀹氶鍜岃浠跺崟浠凤紝鏍规嵁涔欐柟瀹屾垚鐨勪笟缁╋紝鎸夋椂瓒抽鏀粯涔欐柟鐨勫伐璧勬姤閰��
-                </el-radio>
-              </el-radio-group>
-            </el-form-item>
-          </el-col>
-        </el-row>
-				<el-row :gutter="30">
-					<el-col :span="12">
-						<el-form-item label="绂忓埄寰呴亣锛�" prop="remark">
-							<el-input v-model="form.remark" placeholder="璇疯緭鍏�" clearable/>
-						</el-form-item>
-					</el-col>
-				</el-row>
-      </el-form>
-      <template #footer>
-        <div class="dialog-footer">
-          <el-button type="primary" @click="submitForm">纭</el-button>
-          <el-button @click="closeDia">鍙栨秷</el-button>
-        </div>
-      </template>
-    </el-dialog>
-  </div>
-</template>
-
-<script setup>
-import {ref, reactive, toRefs, getCurrentInstance, computed, watch} from "vue";
-import {getStaffJoinInfo, staffJoinAdd, staffJoinUpdate} from "@/api/personnelManagement/onboarding.js";
-const { proxy } = getCurrentInstance()
-const emit = defineEmits(['close'])
-
-const dialogFormVisible = ref(false);
-const operationType = ref('')
-const data = reactive({
-  form: {
-    staffNo: "",
-    staffName: "",
-    sex: "",
-    identityCard: "",
-    nativePlace: "",
-    postJob: "",
-    adress: "",
-    firstStudy: "",
-    profession: "",
-    age: 0,
-    phone: "",
-    emergencyContact: "",
-    emergencyContactPhone: "",
-    dateSelect: "",
-		trialStartDate: "",
-    trialEndDate: "",
-    proSalary: null,
-    signDate: "",
-    salarySelect: "",
-    contractTerm: 0,
-    contractStartTime: "",
-    contractEndTime: "",
-    staffState: "",
-  },
-  rules: {
-    staffNo: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" },],
-    staffName: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
-    sex: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
-    identityCard: [{ required: true, message: "璇疯緭鍏ヨ韩浠借瘉鍙风爜", trigger: "blur" }],
-    nativePlace: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
-    postJob: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
-    adress: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
-    firstStudy: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
-    profession: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
-    age: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
-    phone: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
-    emergencyContact: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
-		remark: [{ required: false, message: "璇疯緭鍏�", trigger: "blur" }],
-    dateSelect: [{ required: true, message: "璇烽�夋嫨鍔冲姩鍚堝悓鏈熼檺", trigger: "change" }],
-		trialStartDate: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
-    trialEndDate: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
-    signDate: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
-    salarySelect: [{ required: true, message: "璇烽�夋嫨宸ヨ祫鎶ラ叕鏂瑰紡", trigger: "change" }],
-    contractTerm: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
-    contractStartTime: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
-    contractEndTime: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
-  },
-});
-const { form, rules } = toRefs(data);
-
-const showContractEnd = computed(() => form.value.dateSelect === "A");
-const showProbationDates = computed(() => form.value.dateSelect === "A" || form.value.dateSelect === "B");
-
-watch(() => form.value.dateSelect, (type) => {
-  if (type !== "A") {
-    form.value.contractEndTime = "";
-  }
-
-  if (type === "C") {
-    form.value.signDate = "";
-    form.value.trialEndDate = "";
-    form.value.proSalary = null;
-  }
-}, { immediate: true });
-
-// 鎵撳紑寮规
-const openDialog = (type, row) => {
-  operationType.value = type;
-  dialogFormVisible.value = true;
-  if (operationType.value === 'edit') {
-    getStaffJoinInfo(row.id).then(res => {
-      form.value = {...res.data}
-      // 缂栬緫鏃朵篃璁$畻涓�娆″悎鍚屽勾闄�
-      calculateContractTerm();
-    })
-  } else if (operationType.value === 'add') {
-    // 鏂板鏃堕噸缃〃鍗曪紝娓呴櫎 id
-    proxy.resetForm("formRef");
-    form.value = {
-      staffNo: "",
-      staffName: "",
-      sex: "",
-      identityCard: "",
-      nativePlace: "",
-      postJob: "",
-      adress: "",
-      firstStudy: "",
-      profession: "",
-      age: 0,
-      phone: "",
-      emergencyContact: "",
-      emergencyContactPhone: "",
-      dateSelect: "",
-      trialStartDate: "",
-      trialEndDate: "",
-      proSalary: null,
-      signDate: "",
-      salarySelect: "",
-      contractTerm: 0,
-      contractStartTime: "",
-      contractEndTime: "",
-      staffState: "",
-    };
-    // 纭繚娓呴櫎 id
-    if (form.value.id !== undefined) {
-      delete form.value.id;
-    }
-  }
-}
-// 鎻愪氦浜у搧琛ㄥ崟
-const submitForm = () => {
-  proxy.$refs.formRef.validate(valid => {
-    if (valid) {
-      form.value.staffState = 1
-      if (operationType.value === "add") {
-        staffJoinAdd(form.value).then(res => {
-          proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
-          closeDia();
-        })
-      } else {
-        staffJoinUpdate(form.value).then(res => {
-          proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
-          closeDia();
-        })
-      }
-    }
-  })
-}
-// 璁$畻鍚堝悓骞撮檺
-const calculateContractTerm = () => {
-  if (form.value.contractStartTime && form.value.contractEndTime) {
-    const startDate = new Date(form.value.contractStartTime);
-    const endDate = new Date(form.value.contractEndTime);
-
-    if (endDate > startDate) {
-      // 璁$畻骞翠唤宸�
-      const yearDiff = endDate.getFullYear() - startDate.getFullYear();
-      const monthDiff = endDate.getMonth() - startDate.getMonth();
-      const dayDiff = endDate.getDate() - startDate.getDate();
-
-      let years = yearDiff;
-
-      // 濡傛灉缁撴潫鏃ユ湡鐨勬湀鏃ュ皬浜庡紑濮嬫棩鏈熺殑鏈堟棩锛屽垯鍑忓幓1骞�
-      if (monthDiff < 0 || (monthDiff === 0 && dayDiff < 0)) {
-        years = yearDiff - 1;
-      }
-
-      form.value.contractTerm = Math.max(0, years);
-    } else {
-      form.value.contractTerm = 0;
-    }
-  } else {
-    form.value.contractTerm = 0;
-  }
-};
-
-// 鍏抽棴寮规
-const closeDia = () => {
-  proxy.resetForm("formRef");
-  dialogFormVisible.value = false;
-  emit('close')
-};
-defineExpose({
-  openDialog,
-});
-</script>
-
-<style scoped>
-.salary-radio-group {
-  display: flex;
-  gap: 12px;
-}
-
-.salary-radio-item {
-  white-space: normal;
-  word-wrap: break-word;
-  line-height: 1.6;
-  align-items: flex-start;
-}
-
-.salary-radio-item :deep(.el-radio__label) {
-  white-space: normal;
-  word-wrap: break-word;
-  line-height: 1.6;
-  padding-left: 8px;
-}
-</style>
\ No newline at end of file
diff --git a/src/views/personnelManagement/onboarding/index.vue b/src/views/personnelManagement/onboarding/index.vue
deleted file mode 100644
index 9151a6c..0000000
--- a/src/views/personnelManagement/onboarding/index.vue
+++ /dev/null
@@ -1,280 +0,0 @@
-<template>
-  <div class="app-container">
-    <div class="search_form">
-      <div>
-        <span class="search_title">濮撳悕锛�</span>
-        <el-input
-          v-model="searchForm.staffName"
-          style="width: 240px"
-          placeholder="璇疯緭鍏ュ鍚嶆悳绱�"
-          @change="handleQuery"
-          clearable
-          :prefix-icon="Search"
-        />
-        <span style="margin-left: 10px;"  class="search_title">鍚堝悓寮�濮嬫棩鏈燂細</span>
-        <el-date-picker
-            v-model="searchForm.entryDateStart"
-            type="date"
-            placeholder="璇烽�夋嫨鍚堝悓寮�濮嬫棩鏈�"
-            size="default"
-            @change="(date) => handleDateChange(date,1)"
-        />
-        <span style="margin-left: 10px;" class="search_title">鍚堝悓缁撴潫鏃ユ湡锛�</span>
-        <el-date-picker
-            v-model="searchForm.entryDateEnd"
-            type="date"
-            placeholder="璇烽�夋嫨鍚堝悓缁撴潫鏃ユ湡"
-            size="default"
-            @change="(date) => handleDateChange(date,2)"
-        />
-        <el-button type="primary" @click="handleQuery" style="margin-left: 10px"
-          >鎼滅储</el-button
-        >
-      </div>
-      <div>
-        <el-button type="primary" @click="openForm('add')">鏂板鍏ヨ亴</el-button>
-        <el-button @click="handleOut">瀵煎嚭</el-button>
-        <el-button type="danger" plain @click="handleDelete">鍒犻櫎</el-button>
-      </div>
-    </div>
-    <div class="table_list">
-      <PIMTable
-        rowKey="id"
-        :column="tableColumn"
-        :tableData="tableData"
-        :page="page"
-        :isSelection="true"
-        @selection-change="handleSelectionChange"
-        :tableLoading="tableLoading"
-        @pagination="pagination"
-        :total="page.total"
-      ></PIMTable>
-    </div>
-    <form-dia ref="formDia" @close="handleQuery"></form-dia>
-  </div>
-</template>
-
-<script setup>
-import { Search } from "@element-plus/icons-vue";
-import {onMounted, ref} from "vue";
-import FormDia from "@/views/personnelManagement/onboarding/components/formDia.vue";
-// import FormDia from "@/views/personnelManagement/onboarding/components/formDiaXJHT.vue"; // 鏂扮枂椋熷搧鍏徃鐢ㄧ殑琛ㄥ崟
-import {staffJoinDel, staffJoinListPage} from "@/api/personnelManagement/onboarding.js";
-import {ElMessageBox} from "element-plus";
-import dayjs from "dayjs";
-
-const data = reactive({
-  searchForm: {
-    staffName: "",
-  },
-});
-const { searchForm } = toRefs(data);
-const tableColumn = ref([
-  {
-    label: "鐘舵��",
-    prop: "staffState",
-    dataType: "tag",
-    formatData: (params) => {
-      if (params == 0) {
-        return "绂昏亴";
-      } else if (params == 1) {
-        return "鍏ヨ亴";
-      } else {
-        return null;
-      }
-    },
-    formatType: (params) => {
-      if (params == 0) {
-        return "danger";
-      } else if (params == 1) {
-        return "primary";
-      } else {
-        return null;
-      }
-    },
-  },
-  {
-    label: "鍛樺伐缂栧彿",
-    prop: "staffNo",
-  },
-  {
-    label: "濮撳悕",
-    prop: "staffName",
-  },
-  {
-    label: "鎬у埆",
-    prop: "sex",
-  },
-  {
-    label: "鎴风睄浣忓潃",
-    prop: "nativePlace",
-  },
-  {
-    label: "宀椾綅",
-    prop: "postJob",
-  },
-  {
-    label: "鐜颁綇鍧�",
-    prop: "adress",
-    width:200
-  },
-  {
-    label: "绗竴瀛﹀巻",
-    prop: "firstStudy",
-  },
-  {
-    label: "涓撲笟",
-    prop: "profession",
-    width:100
-  },
-  {
-    label: "骞撮緞",
-    prop: "age",
-  },
-  {
-    label: "鑱旂郴鐢佃瘽",
-    prop: "phone",
-    width:150
-  },
-  {
-    label: "绱ф�ヨ仈绯讳汉",
-    prop: "emergencyContact",
-    width: 120
-  },
-  {
-    label: "鑱旂郴鐢佃瘽",
-    prop: "emergencyContactPhone",
-    width:150
-  },
-  // {
-  //   label: "鍚堝悓骞撮檺",
-  //   prop: "contractTerm",
-  // },
-  {
-    label: "鍚堝悓寮�濮嬫棩鏈�",
-    prop: "contractStartTime",
-    width: 120
-  },
-  {
-    label: "鍚堝悓缁撴潫鏃ユ湡",
-    prop: "contractEndTime",
-    width: 120
-  },
-  {
-    dataType: "action",
-    label: "鎿嶄綔",
-    align: "center",
-    fixed: 'right',
-    operation: [
-      {
-        name: "缂栬緫",
-        type: "text",
-        clickFun: (row) => {
-          openForm("edit", row);
-        },
-      },
-    ],
-  },
-]);
-const tableData = ref([]);
-const selectedRows = ref([]);
-const tableLoading = ref(false);
-const page = reactive({
-  current: 1,
-  size: 100,
-  total: 0,
-});
-const formDia = ref()
-const { proxy } = getCurrentInstance()
-
-const handleDateChange = (value,type) => {
-  searchForm.value.entryDateEnd = null
-  searchForm.value.entryDateStart = null
-  if(type === 1){
-    if (value) {
-      searchForm.value.entryDateStart = dayjs(value).format("YYYY-MM-DD");
-    }
-  }else{
-    if (value) {
-      searchForm.value.entryDateEnd = dayjs(value).format("YYYY-MM-DD");
-    }
-  }
-  getList();
-};
-// 鏌ヨ鍒楄〃
-/** 鎼滅储鎸夐挳鎿嶄綔 */
-const handleQuery = () => {
-  page.current = 1;
-  getList();
-};
-const pagination = (obj) => {
-  page.current = obj.page;
-  page.size = obj.limit;
-  getList();
-};
-const getList = () => {
-  tableLoading.value = true;
-  staffJoinListPage({...page, ...searchForm.value, staffState: 1}).then(res => {
-    tableLoading.value = false;
-    tableData.value = res.data.records
-    page.total = res.data.total;
-  }).catch(err => {
-    tableLoading.value = false;
-  })
-};
-// 琛ㄦ牸閫夋嫨鏁版嵁
-const handleSelectionChange = (selection) => {
-  selectedRows.value = selection;
-};
-
-// 鎵撳紑寮规
-const openForm = (type, row) => {
-  nextTick(() => {
-    formDia.value?.openDialog(type, row)
-  })
-};
-
-// 鍒犻櫎
-const handleDelete = () => {
-  let ids = [];
-  if (selectedRows.value.length > 0) {
-    ids = selectedRows.value.map((item) => item.id);
-  } else {
-    proxy.$modal.msgWarning("璇烽�夋嫨鏁版嵁");
-    return;
-  }
-  ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�", "瀵煎嚭", {
-    confirmButtonText: "纭",
-    cancelButtonText: "鍙栨秷",
-    type: "warning",
-  })
-      .then(() => {
-        staffJoinDel(ids).then((res) => {
-          proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
-          getList();
-        });
-      })
-      .catch(() => {
-        proxy.$modal.msg("宸插彇娑�");
-      });
-};
-// 瀵煎嚭
-const handleOut = () => {
-  ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
-    confirmButtonText: "纭",
-    cancelButtonText: "鍙栨秷",
-    type: "warning",
-  })
-      .then(() => {
-        proxy.download("/staff/staffJoinLeaveRecord/export", {staffState: 1}, "浜哄憳鍏ヨ亴.xlsx");
-      })
-      .catch(() => {
-        proxy.$modal.msg("宸插彇娑�");
-      });
-};
-onMounted(() => {
-  getList();
-});
-</script>
-
-<style scoped></style>
diff --git a/src/views/personnelManagement/payrollManagement/components/formDia.vue b/src/views/personnelManagement/payrollManagement/components/formDia.vue
index e4cf0b3..cf93559 100644
--- a/src/views/personnelManagement/payrollManagement/components/formDia.vue
+++ b/src/views/personnelManagement/payrollManagement/components/formDia.vue
@@ -168,8 +168,8 @@
 
 <script setup>
 import {ref} from "vue";
-import {getStaffJoinInfo, getStaffOnJob, staffJoinAdd, staffJoinUpdate} from "@/api/personnelManagement/onboarding.js";
 import {compensationAdd, compensationUpdate} from "@/api/personnelManagement/payrollManagement.js";
+import {staffOnJobInfo, staffOnJobListPage} from "@/api/personnelManagement/staffOnJob.js";
 const { proxy } = getCurrentInstance()
 const emit = defineEmits(['close'])
 
@@ -234,12 +234,16 @@
 const openDialog = (type, row) => {
   operationType.value = type;
   dialogFormVisible.value = true;
-	getStaffOnJob().then(res => {
-		personList.value = res.data
-	})
+  staffOnJobListPage({
+    current: -1,
+    size: -1,
+    staffState: 1
+  }).then(res => {
+    personList.value = res.data.records || []
+  })
 	form.value = {}
   if (operationType.value === 'edit') {
-    getStaffJoinInfo(row.id).then(res => {
+    staffOnJobInfo(row.staffId).then(res => {
 			form.value = {...row}
 			form.value.payDate = form.value.payDate + '-01'
     })
diff --git a/src/views/personnelManagement/payrollManagement/index.vue b/src/views/personnelManagement/payrollManagement/index.vue
index 24e3dd8..f17f42e 100644
--- a/src/views/personnelManagement/payrollManagement/index.vue
+++ b/src/views/personnelManagement/payrollManagement/index.vue
@@ -53,7 +53,6 @@
 import { Search } from "@element-plus/icons-vue";
 import {onMounted, ref, reactive, toRefs, getCurrentInstance, nextTick} from "vue";
 import FormDia from "@/views/personnelManagement/payrollManagement/components/formDia.vue";
-import {staffJoinDel} from "@/api/personnelManagement/onboarding.js";
 import {ElMessageBox} from "element-plus";
 import dayjs from "dayjs";
 import {compensationDelete, compensationListPage} from "@/api/personnelManagement/payrollManagement.js";
diff --git a/src/views/personnelManagement/scheduling/index.vue b/src/views/personnelManagement/scheduling/index.vue
index 251dbe9..19d2062 100644
--- a/src/views/personnelManagement/scheduling/index.vue
+++ b/src/views/personnelManagement/scheduling/index.vue
@@ -253,9 +253,9 @@
 import {useDict} from "@/utils/dict.js"
 import {Plus, Download, Search, Refresh} from '@element-plus/icons-vue'
 import {save, del, delByIds, listPage} from "@/api/personnelManagement/scheduling.js"
-import {getStaffOnJob} from "@/api/personnelManagement/onboarding.js";
 import dayjs from "dayjs";
 import pagination from "@/components/PIMTable/Pagination.vue";
+import {staffOnJobListPage} from "@/api/personnelManagement/staffOnJob.js";
 
 const { proxy } = getCurrentInstance();
 
@@ -317,8 +317,12 @@
  * 鑾峰彇褰撳墠鍦ㄨ亴浜哄憳鍒楄〃
  */
 const getPersonList = () => {
-  getStaffOnJob().then(res => {
-    personList.value = res.data
+  staffOnJobListPage({
+    current: -1,
+    size: -1,
+    staffState: 1
+  }).then(res => {
+    personList.value = res.data.records || []
   })
 };
 const paginationChange = (obj) => {
diff --git a/src/views/personnelManagement/selfService/index.vue b/src/views/personnelManagement/selfService/index.vue
index ca683c0..647f149 100644
--- a/src/views/personnelManagement/selfService/index.vue
+++ b/src/views/personnelManagement/selfService/index.vue
@@ -221,8 +221,7 @@
 
 const { proxy } = getCurrentInstance()
 import { getUserProfile } from '@/api/system/user.js'
-import {staffJoinUpdate, staffJoinListPage} from "@/api/personnelManagement/onboarding.js";
-import { fa, id } from 'element-plus/es/locales.mjs'
+import {staffOnJobListPage, updateStaffOnJob} from "@/api/personnelManagement/staffOnJob.js";
 
 const tableLoading = ref(false)
 // 鍒嗛〉鍙傛暟
@@ -572,7 +571,7 @@
       currentUser.value = res.data
       // console.log("----",currentUser.value)
         //寰楀埌浜哄憳鍒楄〃
-        staffJoinListPage({staffState: 1}).then(res => {
+      staffOnJobListPage({staffState: 1}).then(res => {
           //绛涢�夊嚭鍜宑urrentUser鍚屽悕鐨勪汉鍛�
           // let tableData = res.data.records
           user.value = res.data.records.find(item => item.staffName === currentUser.value.userName)
@@ -604,18 +603,15 @@
     const userRes = await getUserProfile();
     if (userRes.code === 200) {
       currentUser.value = userRes.data;
-      const staffListRes = await staffJoinListPage({ staffState: 1 });
+      const staffListRes = await staffOnJobListPage({ staffState: 1 });
       user.value = staffListRes.data.records.find(item => item.staffName === currentUser.value.userName);
-      // console.log("++++", user.value);
-
       Object.assign(joinForm, user.value);
       joinForm.staffName = profileForm.name;
       joinForm.phone = profileForm.phone;
       joinForm.email = profileForm.email;
       joinForm.adress = profileForm.adress; 
-      console.log(joinForm)
       // 璋冪敤鏇存柊涓汉淇℃伅鐨勬帴鍙�
-      staffJoinUpdate(joinForm).then(res => {
+      updateStaffOnJob(user.value.id, joinForm).then(res => {
         if (res.code === 200) {
           ElMessage.success('涓汉淇℃伅淇濆瓨鎴愬姛');
           getProfile();

--
Gitblit v1.9.3