From bbd880d66e993f80670259882f2feca1b150d1ae Mon Sep 17 00:00:00 2001
From: yaowanxin <3588231647@qq.com>
Date: 星期五, 16 一月 2026 17:58:52 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/dev_New' into dev_New

---
 src/views/personnelManagement/employeeRecord/index.vue                       |   59 +++
 src/views/system/dept/index.vue                                              |    1 
 src/views/reportAnalysis/dataDashboard/index.vue                             |    2 
 src/views/personnelManagement/contractManagement/index.vue                   |    2 
 src/views/personnelManagement/employeeRecord/components/Show.vue             |    2 
 /dev/null                                                                    |   18 -
 src/api/personnelManagement/staffContract.js                                 |   10 
 src/views/personnelManagement/dimission/components/formDia.vue               |    2 
 src/views/personnelManagement/employeeRecord/components/NewOrEditFormDia.vue |  284 ++++++++++++++++++++
 src/views/collaborativeApproval/notificationManagement/index.vue             |    2 
 src/api/personnelManagement/staffOnJob.js                                    |   45 +++
 src/views/personnelManagement/contractManagement/components/formDia.vue      |  171 -----------
 src/views/personnelManagement/analytics/index.vue                            |    2 
 src/views/financialManagement/financialStatements/index.vue                  |  194 ++++++++++---
 14 files changed, 542 insertions(+), 252 deletions(-)

diff --git a/src/api/personnelManagement/employeeRecord.js b/src/api/personnelManagement/employeeRecord.js
deleted file mode 100644
index 378756a..0000000
--- a/src/api/personnelManagement/employeeRecord.js
+++ /dev/null
@@ -1,18 +0,0 @@
-import request from '@/utils/request'
-
-// 鏌ヨ鍦ㄨ亴鍛樺伐鍙拌处
-export function staffOnJobListPage(query) {
-    return request({
-        url: '/staff/staffOnJob/listPage',
-        method: 'get',
-        params: query,
-    })
-}
-// 鏌ヨ鍛樺伐鍏ヨ亴淇℃伅
-export function staffOnJobInfo(query) {
-    return request({
-        url: '/staff/staffOnJob/staffNo',
-        method: 'get',
-        params: query,
-    })
-}
\ No newline at end of file
diff --git a/src/api/personnelManagement/staffContract.js b/src/api/personnelManagement/staffContract.js
new file mode 100644
index 0000000..a6b71cb
--- /dev/null
+++ b/src/api/personnelManagement/staffContract.js
@@ -0,0 +1,10 @@
+import request from "@/utils/request.js";
+
+
+export function findStaffContractListPage(query) {
+    return request({
+        url: "/staff/staffContract/listPage",
+        method: "get",
+        params: query,
+    });
+}
diff --git a/src/api/personnelManagement/staffOnJob.js b/src/api/personnelManagement/staffOnJob.js
new file mode 100644
index 0000000..ba26878
--- /dev/null
+++ b/src/api/personnelManagement/staffOnJob.js
@@ -0,0 +1,45 @@
+import request from '@/utils/request'
+
+// 鏌ヨ鍦ㄨ亴鍛樺伐鍙拌处
+export function staffOnJobListPage(query) {
+    return request({
+        url: '/staff/staffOnJob/listPage',
+        method: 'get',
+        params: query,
+    })
+}
+// 鏌ヨ鍛樺伐鍏ヨ亴淇℃伅
+export function staffOnJobInfo(id, query) {
+    return request({
+        url: '/staff/staffOnJob/' + id,
+        method: 'get',
+        params: query,
+    })
+}
+
+// 鏂板鍛樺伐
+export function createStaffOnJob(params) {
+    return request({
+        url: "/staff/staffOnJob",
+        method: "post",
+        data: params,
+    });
+}
+
+// 淇敼鍛樺伐
+export function updateStaffOnJob(id, params) {
+    return request({
+        url: "/staff/staffOnJob/" + id,
+        method: "put",
+        data: params,
+    });
+}
+
+// 鍒犻櫎鍛樺伐
+export function batchDeleteStaffOnJobs(query) {
+    return request({
+        url: "/staff/staffOnJob/del",
+        method: "delete",
+        data: query,
+    });
+}
\ No newline at end of file
diff --git a/src/views/collaborativeApproval/notificationManagement/index.vue b/src/views/collaborativeApproval/notificationManagement/index.vue
index 37c13cf..fb3f7a8 100644
--- a/src/views/collaborativeApproval/notificationManagement/index.vue
+++ b/src/views/collaborativeApproval/notificationManagement/index.vue
@@ -322,7 +322,7 @@
 import { ElMessage, ElMessageBox } from "element-plus";
 import PIMTable from "@/components/PIMTable/PIMTable.vue";
 import { userListNoPageByTenantId } from "@/api/system/user.js";
-import { staffOnJobListPage } from "@/api/personnelManagement/employeeRecord.js";
+import { staffOnJobListPage } from "@/api/personnelManagement/staffOnJob.js";
 import { listNotification, addNotification, updateNotification, delNotification,addOnlineMeeting,addFileSharing } from "@/api/collaborativeApproval/notificationManagement.js";
 import { id } from "element-plus/es/locales.mjs";
 
diff --git a/src/views/financialManagement/financialStatements/index.vue b/src/views/financialManagement/financialStatements/index.vue
index e5f9b23..88aa5d2 100644
--- a/src/views/financialManagement/financialStatements/index.vue
+++ b/src/views/financialManagement/financialStatements/index.vue
@@ -1,16 +1,16 @@
  <template>
   <div style="padding: 20px;">
-    <!-- 椤甸潰鏍囬鍜屾棩鏈熺瓫閫� -->
+    <!-- 椤甸潰鏍囬鍜屾湀浠界瓫閫� -->
     <div class="w-full md:w-auto flex items-center gap-3" style="margin-bottom: 20px;">
       <el-date-picker
         v-model="dateRange"
-        type="daterange"
-        format="YYYY-MM-DD"
-        value-format="YYYY-MM-DD"
+        type="monthrange"
+        format="YYYY-MM"
+        value-format="YYYY-MM"
         range-separator="鑷�"
-        start-placeholder="寮�濮嬫棩鏈�"
-        end-placeholder="缁撴潫鏃ユ湡"
-        clearable
+        start-placeholder="寮�濮嬫湀浠�"
+        end-placeholder="缁撴潫鏈堜唤"
+        :disabled-date="disabledDate"
         @change="handleDateChange"
         class="w-full md:w-auto"
         style="margin-right: 30px;"
@@ -130,7 +130,7 @@
 </template>
 
 <script setup>
-import { ref, computed, onMounted, reactive } from 'vue';
+import { ref, computed, onMounted, reactive, nextTick, getCurrentInstance } from 'vue';
 import 'element-plus/dist/index.css';
 import Echarts from "@/components/Echarts/echarts.vue";
 import { reportForms,reportIncome,reportExpense } from "@/api/financialManagement/financialStatements";
@@ -138,6 +138,7 @@
 
 // 鏃ユ湡鑼冨洿
 const dateRange = ref(null);
+const { proxy } = getCurrentInstance();
 const chartStyle = {
 	width: '100%',
 	height: '100%', // 璁剧疆鍥捐〃瀹瑰櫒鐨勯珮搴�
@@ -172,22 +173,35 @@
     return `<div>${axisLabel}</div><div>${rows}</div>`
   }
 })
-const months = ['1鏈�','2鏈�','3鏈�','4鏈�','5鏈�','6鏈�','7鏈�','8鏈�','9鏈�','10鏈�','11鏈�','12鏈�'];
 const lineSeries0 = ref([])
 const lineSeries1 = ref([])
+
+// 鏍规嵁鏈堜唤鑼冨洿鐢熸垚 x 杞存暟鎹�
+const generateMonthLabels = (startMonth, endMonth) => {
+  const labels = [];
+  let current = dayjs(startMonth);
+  const end = dayjs(endMonth);
+  
+  while (current.isBefore(end) || current.isSame(end, 'month')) {
+    labels.push(`${current.month() + 1}鏈坄);
+    current = current.add(1, 'month');
+  }
+  
+  return labels;
+};
 
 const xAxis0 = ref([
   {
     type: 'category',
     axisTick: { show: true, alignWithLabel: true },
-    data: months,
+    data: [],
   },
 ]);
 const xAxis1 = ref([
   {
     type: 'category',
     axisTick: { show: true, alignWithLabel: true },
-    data: months,
+    data: [],
   },
 ]);
 const yAxis0 = [
@@ -232,9 +246,10 @@
   left: '60%',
   orient: 'vertical',
   icon: 'circle',
-  data: pieData0.value.map(item => item.name),
+  data: (pieData0.value || []).filter(item => item && item.name).map(item => item.name),
   formatter: function(name) {
-    const item = pieData0.value.find(i => i.name === name);
+    if (!name) return '';
+    const item = pieData0.value.find(i => i && i.name === name);
     if (!item) return name;
     return `${name} | ${item.percent} ${item.amount}`;
   },
@@ -250,9 +265,10 @@
   left: '60%',
   orient: 'vertical',
   icon: 'circle',
-  data: pieData1.value.map(item => item.name),
+  data: (pieData1.value || []).filter(item => item && item.name).map(item => item.name),
   formatter: function(name) {
-    const item = pieData1.value.find(i => i.name === name);
+    if (!name) return '';
+    const item = pieData1.value.find(i => i && i.name === name);
     if (!item) return name;
     return `${name} | ${item.percent} ${item.amount}`;
   },
@@ -276,7 +292,7 @@
     label: {
       show: false
     },
-    data: pieData0.value,
+    data: (pieData0.value || []).filter(item => item && item.name),
     color: pieColors
   }
 ]);
@@ -293,7 +309,7 @@
     label: {
       show: false
     },
-    data: pieData1.value,
+    data: (pieData1.value || []).filter(item => item && item.name),
     color: pieColors
   }
 ]);
@@ -318,53 +334,81 @@
 const pageInfo = ref({
 })
 
+// 鑾峰彇鏈�杩戝叚涓湀鐨勮寖鍥�
+const getLastSixMonths = () => {
+  const endMonth = dayjs().format('YYYY-MM');
+  const startMonth = dayjs().subtract(5, 'month').format('YYYY-MM');
+  return [startMonth, endMonth];
+};
+
 const getData = async () => {
-  if (!dateRange.value || !dateRange.value.length) {
+  if (!dateRange.value || !Array.isArray(dateRange.value) || dateRange.value.length !== 2) {
     return;
   }
+  const startDateStr = dateRange.value[0];
+  const endDateStr = dateRange.value[1];
+  if (!startDateStr || !endDateStr) {
+    return;
+  }
+  
+  // 楠岃瘉鏃ユ湡鏍煎紡骞惰浆鎹负瀹屾暣鏃ユ湡
+  const startDate = dayjs(startDateStr);
+  const endDate = dayjs(endDateStr);
+  if (!startDate.isValid() || !endDate.isValid()) {
+    console.error('鏃犳晥鐨勬棩鏈熸牸寮�');
+    return;
+  }
+  
+  // 鏇存柊 x 杞存暟鎹�
+  const monthLabels = generateMonthLabels(startDateStr, endDateStr);
+  xAxis0.value[0].data = monthLabels;
+  xAxis1.value[0].data = monthLabels;
+  
+  // 寮�濮嬫湀浠芥嫾鎺ョ涓�澶╋紝缁撴潫鏈堜唤鎷兼帴鏈�鍚庝竴澶�
+  const entryDateStart = startDate.startOf('month').format('YYYY-MM-DD');
+  const entryDateEnd = endDate.endOf('month').format('YYYY-MM-DD');
+  
   try {
-    const {code,data} = await reportForms({entryDateStart:dateRange.value[0], entryDateEnd:dateRange.value[1]});
-    if(code === 200) {
-      pageInfo.value = data
-      pieData0.value = data.incomeType.map(item=>({
-        name:item.typeName,
-        value:item.account,
-        percent:`${item.proportion*100}%`,
-        amount:`楼${item.account}`
+    const {code,data} = await reportForms({entryDateStart, entryDateEnd});
+    if(code === 200 && data) {
+      pageInfo.value = data || {};
+      // 瀹夊叏澶勭悊鏁版嵁锛岃繃婊ゆ帀 null 鎴� undefined
+      pieData0.value = (data.incomeType || []).filter(item => item && item.typeName).map(item=>({
+        name:item.typeName || '',
+        value:item.account || 0,
+        percent:`${((item.proportion || 0) * 100).toFixed(2)}%`,
+        amount:`楼${(item.account || 0).toFixed(2)}`
       }))
-      pieData1.value = data.expenseType.map(item=>({
-        name:item.typeName,
-        value:item.account,
-        percent:`${item.proportion*100}%`,
-        amount:`楼${item.account}`
+      pieData1.value = (data.expenseType || []).filter(item => item && item.typeName).map(item=>({
+        name:item.typeName || '',
+        value:item.account || 0,
+        percent:`${((item.proportion || 0) * 100).toFixed(2)}%`,
+        amount:`楼${(item.account || 0).toFixed(2)}`
       }))
-
     }
   } catch (error) {
     console.error('鑾峰彇璐㈠姟鎸囨爣鏁版嵁澶辫触锛�', error);
   }
   try{
-    const {code,data} = await reportIncome();
-    if(code==200){
-      lineSeries0.value = data.map(item=>({
-        name:item.typeName,
+    const {code,data} = await reportIncome({entryDateStart, entryDateEnd});
+    if(code==200 && data && Array.isArray(data)){
+      lineSeries0.value = data.filter(item => item && item.typeName).map(item=>({
+        name:item.typeName || '',
         type: 'line',
-        data:item.account.map(item=>Number(item))
+        data:(item.account || []).map(val => Number(val) || 0)
       }))
-
     }
   }catch (error) {
     console.error('鑾峰彇璐㈠姟鎸囨爣鏁版嵁澶辫触锛�', error);
   }
   try{
-    const {code,data} = await reportExpense();
-    if(code==200){
-      lineSeries1.value = data.map(item=>({
-        name:item.typeName,
+    const {code,data} = await reportExpense({entryDateStart, entryDateEnd});
+    if(code==200 && data && Array.isArray(data)){
+      lineSeries1.value = data.filter(item => item && item.typeName).map(item=>({
+        name:item.typeName || '',
         type: 'line',
-        data:item.account.map(item=>Number(item))
+        data:(item.account || []).map(val => Number(val) || 0)
       }))
-
     }
   }catch (error) {
     console.error('鑾峰彇璐㈠姟鎸囨爣鏁版嵁澶辫触锛�', error);
@@ -374,20 +418,66 @@
 
 // 鍒濆鍖�
 onMounted(() => {
-  // 涓嶈缃粯璁ゆ棩鏈燂紝鐢辩敤鎴锋墜鍔ㄩ�夋嫨
+  // 璁剧疆榛樿鍊间负鏈�杩戝叚涓湀
+  const defaultRange = getLastSixMonths();
+  dateRange.value = defaultRange;
+  // 浣跨敤 nextTick 纭繚缁勪欢瀹屽叏娓叉煋鍚庡啀璋冪敤
+  nextTick(() => {
+    getData();
+  });
 });
 
-// 澶勭悊鏃ユ湡鑼冨洿鍙樺寲
-const handleDateChange = (newRange) => {
-  dateRange.value = newRange;
-  if (newRange && newRange.length === 2) {
-    getData()
+// 闄愬埗鏈堜唤閫夋嫨鑼冨洿锛堟渶澶�12涓湀锛�
+const disabledDate = (time) => {
+  // 濡傛灉娌℃湁閫夋嫨寮�濮嬫湀浠斤紝涓嶇鐢ㄤ换浣曟棩鏈�
+  if (!dateRange.value || !Array.isArray(dateRange.value) || !dateRange.value[0]) {
+    return false;
   }
+  
+  const startMonth = dayjs(dateRange.value[0]);
+  const currentMonth = dayjs(time);
+  
+  // 濡傛灉褰撳墠鏈堜唤鍦ㄥ紑濮嬫湀浠戒箣鍓嶏紝绂佺敤
+  if (currentMonth.isBefore(startMonth, 'month')) {
+    return true;
+  }
+  
+  // 璁$畻鏈�澶у厑璁哥殑鏈堜唤锛堝紑濮嬫湀浠� + 11涓湀 = 12涓湀锛�
+  const maxMonth = startMonth.add(11, 'month');
+  
+  // 绂佺敤瓒呰繃12涓湀鐨勬湀浠�
+  return currentMonth.isAfter(maxMonth, 'month');
 };
 
-// 閲嶇疆鏃ユ湡鑼冨洿
+// 澶勭悊鏈堜唤鑼冨洿鍙樺寲
+const handleDateChange = (newRange) => {
+  if (!newRange || !Array.isArray(newRange) || newRange.length !== 2) {
+    return;
+  }
+  
+  // 楠岃瘉鏈堜唤鑼冨洿涓嶈秴杩�12涓湀
+  const startDate = dayjs(newRange[0]);
+  const endDate = dayjs(newRange[1]);
+  const monthDiff = endDate.diff(startDate, 'month');
+  
+  if (monthDiff > 11) {
+    proxy.$modal.msgWarning('鏈�澶氬彧鑳介�夋嫨12涓湀浠�');
+    // 鑷姩璋冩暣涓�12涓湀
+    const adjustedEnd = startDate.add(11, 'month').format('YYYY-MM');
+    dateRange.value = [newRange[0], adjustedEnd];
+    getData();
+    return;
+  }
+  
+  dateRange.value = newRange;
+  getData();
+};
+
+// 閲嶇疆鏈堜唤鑼冨洿
 const resetDateRange = () => {
-  dateRange.value = null;
+  // 閲嶇疆涓烘渶杩戝叚涓湀
+  dateRange.value = getLastSixMonths();
+  getData();
 };
 
 </script>
diff --git a/src/views/personnelManagement/analytics/index.vue b/src/views/personnelManagement/analytics/index.vue
index 2bca335..091156d 100644
--- a/src/views/personnelManagement/analytics/index.vue
+++ b/src/views/personnelManagement/analytics/index.vue
@@ -110,7 +110,7 @@
   ArrowDown
 } from '@element-plus/icons-vue'
 import * as echarts from 'echarts'
-import { staffOnJobListPage } from '@/api/personnelManagement/employeeRecord.js'
+import { staffOnJobListPage } from '@/api/personnelManagement/staffOnJob.js'
 
 // 鍝嶅簲寮忔暟鎹�
 const loading = ref(false)
diff --git a/src/views/personnelManagement/contractManagement/components/formDia.vue b/src/views/personnelManagement/contractManagement/components/formDia.vue
index 9fdb84e..224fdbb 100644
--- a/src/views/personnelManagement/contractManagement/components/formDia.vue
+++ b/src/views/personnelManagement/contractManagement/components/formDia.vue
@@ -13,39 +13,6 @@
           :tableLoading="tableLoading"
           height="600"
       ></PIMTable>
-
-      <div style="margin: 30px 0px;text-align: right">
-        <el-upload
-            v-model:file-list="fileList"
-            class="upload-demo"
-            :action="uploadUrl"
-            :on-success="handleUploadSuccess"
-            :on-error="handleUploadError"
-            name="file"
-            :show-file-list="false"
-            :headers="headers"
-            style="display: inline;margin-right: 10px"
-        >
-          <el-button type="primary">涓婁紶闄勪欢</el-button>
-        </el-upload>
-        <el-button type="danger" plain @click="handleDelete">鍒犻櫎</el-button>
-      </div>
-      <PIMTable
-          rowKey="id"
-          :column="fileTableColumn"
-          :tableData="fileTableData"
-          :tableLoading="fileTableLoading"
-          :isSelection="true"
-          @selection-change="handleSelectionChange"
-          @pagination="paginationSearch"
-          :page="{
-          current: page.current,
-          size: page.size,
-          total: total,
-        }"
-          height="500"
-      >
-      </PIMTable>
       <template #footer>
         <div class="dialog-footer">
           <el-button @click="closeDia">鍙栨秷</el-button>
@@ -57,19 +24,8 @@
 
 <script setup>
 import {ref} from "vue";
-import {staffOnJobInfo} from "@/api/personnelManagement/employeeRecord.js";
-import Pagination from "@/components/PIMTable/Pagination.vue";
-import {ElMessageBox} from "element-plus";
-import {getToken} from "@/utils/auth.js";
-import filePreview from '@/components/filePreview/index.vue'
-import {
-  fileAdd,
-  fileDel,
-  fileListPage
-} from "@/api/financialManagement/revenueManagement.js";
-import PIMTable from "@/components/PIMTable/PIMTable.vue";
-
-
+import {staffOnJobInfo} from "@/api/personnelManagement/staffOnJob.js";
+import {findStaffContractListPage} from "@/api/personnelManagement/staffContract.js";
 const { proxy } = getCurrentInstance()
 const emit = defineEmits(['close'])
 
@@ -92,132 +48,13 @@
 const tableData = ref([]);
 const tableLoading = ref(false);
 
-const currentId = ref('')
-const selectedRows = ref([]);
-const filePreviewRef = ref()
-const fileTableColumn = ref([
-  {
-    label: "鏂囦欢鍚嶇О",
-    prop: "name",
-  },
-  {
-    dataType: "action",
-    label: "鎿嶄綔",
-    align: "center",
-    operation: [
-      {
-        name: "涓嬭浇",
-        type: "text",
-        clickFun: (row) => {
-          downLoadFile(row);
-        },
-      },
-      {
-        name: "棰勮",
-        type: "text",
-        clickFun: (row) => {
-          lookFile(row);
-        },
-      }
-    ],
-  },
-]);
-const page = reactive({
-  current: 1,
-  size: 100,
-});
-const total = ref(0);
-const fileTableData = ref([]);
-const fileList = ref([]);
-const fileTableLoading = ref(false);
-const accountType = ref('')
-const headers = ref({
-  Authorization: "Bearer " + getToken(),
-});
-const uploadUrl = ref(import.meta.env.VITE_APP_BASE_API + "/file/upload"); // 涓婁紶鐨勫浘鐗囨湇鍔″櫒鍦板潃
-
-const paginationSearch = (obj) => {
-  page.current = obj.page;
-  page.size = obj.limit;
-  getList();
-};
-const getList = () => {
-  fileListPage({accountId: currentId.value,accountType:accountType.value, ...page}).then(res => {
-    fileTableData.value = res.data.records;
-    total.value = res.data.total;
-  })
-}
-// 琛ㄦ牸閫夋嫨鏁版嵁
-const handleSelectionChange = (selection) => {
-  selectedRows.value = selection;
-};
-
-
-// 涓婁紶鎴愬姛澶勭悊
-function handleUploadSuccess(res, file) {
-  // 濡傛灉涓婁紶鎴愬姛
-  if (res.code == 200) {
-    const fileRow = {}
-    fileRow.name = res.data.originalName
-    fileRow.url = res.data.tempPath
-    uploadFile(fileRow)
-  } else {
-    proxy.$modal.msgError("鏂囦欢涓婁紶澶辫触");
-  }
-}
-function uploadFile(file) {
-  file.accountId = currentId.value;
-  file.accountType = accountType.value;
-  fileAdd(file).then(res => {
-    proxy.$modal.msgSuccess("鏂囦欢涓婁紶鎴愬姛");
-    getList()
-  })
-}
-// 涓婁紶澶辫触澶勭悊
-function handleUploadError() {
-  proxy.$modal.msgError("鏂囦欢涓婁紶澶辫触");
-}
-// 涓嬭浇闄勪欢
-const downLoadFile = (row) => {
-  proxy.$download.name(row.url);
-}
-// 鍒犻櫎
-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(() => {
-    fileDel(ids).then((res) => {
-      proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
-      getList();
-    });
-  }).catch(() => {
-    proxy.$modal.msg("宸插彇娑�");
-  });
-};
-// 棰勮闄勪欢
-const lookFile = (row) => {
-  filePreviewRef.value.open(row.url)
-}
-
 // 鎵撳紑寮规
 const openDialog = (type, row) => {
   operationType.value = type;
   dialogFormVisible.value = true;
-  accountType.value = type;
-  currentId.value = row.id;
-  getList()
   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
     })
   }
 }
diff --git a/src/views/personnelManagement/contractManagement/index.vue b/src/views/personnelManagement/contractManagement/index.vue
index 3d986ee..76f1401 100644
--- a/src/views/personnelManagement/contractManagement/index.vue
+++ b/src/views/personnelManagement/contractManagement/index.vue
@@ -74,7 +74,7 @@
 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";
diff --git a/src/views/personnelManagement/dimission/components/formDia.vue b/src/views/personnelManagement/dimission/components/formDia.vue
index 9880a67..84808f8 100644
--- a/src/views/personnelManagement/dimission/components/formDia.vue
+++ b/src/views/personnelManagement/dimission/components/formDia.vue
@@ -168,7 +168,7 @@
 <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";
 const { proxy } = getCurrentInstance()
 const emit = defineEmits(['close'])
 
diff --git a/src/views/personnelManagement/employeeRecord/components/NewOrEditFormDia.vue b/src/views/personnelManagement/employeeRecord/components/NewOrEditFormDia.vue
new file mode 100644
index 0000000..00e796c
--- /dev/null
+++ b/src/views/personnelManagement/employeeRecord/components/NewOrEditFormDia.vue
@@ -0,0 +1,284 @@
+<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="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, onMounted} from "vue";
+import {getStaffJoinInfo, staffJoinAdd, staffJoinUpdate} from "@/api/personnelManagement/onboarding.js";
+import {findPostOptions} from "@/api/system/post.js";
+import {staffOnJobInfo, createStaffOnJob, updateStaffOnJob} from "@/api/personnelManagement/staffOnJob.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: "",
+    staffState: "",
+    sysPostId: 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" }],
+  },
+  postOptions: [], // 宀椾綅閫夐」
+});
+const { form, rules, postOptions } = 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
+      }
+      // 缂栬緫鏃朵篃璁$畻涓�娆″悎鍚屽勾闄�
+      calculateContractTerm();
+    })
+  } else {
+		form.value.id = ''
+	}
+
+}
+onMounted(() => {
+  fetchPostOptions()
+})
+
+const fetchPostOptions = () => {
+  findPostOptions().then(res => {
+    postOptions.value = res.data
+  })
+}
+// 鎻愪氦浜у搧琛ㄥ崟
+const submitForm = () => {
+  if (!form.value.sysPostId) {
+    form.value.sysPostId = 0;
+  }
+  proxy.$refs.formRef.validate(valid => {
+    if (valid) {
+      form.value.staffState = 1
+      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/formDia.vue b/src/views/personnelManagement/employeeRecord/components/Show.vue
similarity index 94%
rename from src/views/personnelManagement/employeeRecord/components/formDia.vue
rename to src/views/personnelManagement/employeeRecord/components/Show.vue
index 3c9674c..9220d45 100644
--- a/src/views/personnelManagement/employeeRecord/components/formDia.vue
+++ b/src/views/personnelManagement/employeeRecord/components/Show.vue
@@ -24,7 +24,7 @@
 
 <script setup>
 import {ref} from "vue";
-import {staffOnJobInfo} from "@/api/personnelManagement/employeeRecord.js";
+import {staffOnJobInfo} from "@/api/personnelManagement/staffOnJob.js";
 const { proxy } = getCurrentInstance()
 const emit = defineEmits(['close'])
 
diff --git a/src/views/personnelManagement/employeeRecord/index.vue b/src/views/personnelManagement/employeeRecord/index.vue
index 5a0d07c..b8e48eb 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,20 @@
           :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>
   </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 data = reactive({
   searchForm: {
@@ -154,14 +157,22 @@
     label: "鎿嶄綔",
     align: "center",
     fixed: 'right',
+    width: 180,
     operation: [
       {
-        name: "璇︽儏",
+        name: "缂栬緫",
         type: "text",
         clickFun: (row) => {
-          openForm("edit", row);
+          openFormNewOrEditFormDia("edit", row);
         },
       },
+      // {
+      //   name: "璇︽儏",
+      //   type: "text",
+      //   clickFun: (row) => {
+      //     openForm("edit", row);
+      //   },
+      // },
     ],
   },
 ]);
@@ -174,6 +185,7 @@
   total: 0
 });
 const formDia = ref()
+const formDiaNewOrEditFormDia = ref()
 const { proxy } = getCurrentInstance()
 
 const changeDaterange = (value) => {
@@ -219,6 +231,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 +270,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/reportAnalysis/dataDashboard/index.vue b/src/views/reportAnalysis/dataDashboard/index.vue
index ad01f4b..574c3f2 100644
--- a/src/views/reportAnalysis/dataDashboard/index.vue
+++ b/src/views/reportAnalysis/dataDashboard/index.vue
@@ -253,7 +253,7 @@
 	getProgressStatistics,
   	getWorkInProcessTurnover
 } from "@/api/viewIndex.js";
-import {staffOnJobListPage} from "@/api/personnelManagement/employeeRecord.js";
+import {staffOnJobListPage} from "@/api/personnelManagement/staffOnJob.js";
 import {listCustomer} from "@/api/basicData/customerFile.js";
 import {listSupplier} from "@/api/basicData/supplierManageFile.js";
 import {getLedgerPage} from "@/api/equipmentManagement/ledger.js";
diff --git a/src/views/system/dept/index.vue b/src/views/system/dept/index.vue
index bcc70ee..a177314 100644
--- a/src/views/system/dept/index.vue
+++ b/src/views/system/dept/index.vue
@@ -46,7 +46,6 @@
 			</el-col>
 			<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
 		</el-row>
-		
 		<el-table
 			v-if="refreshTable"
 			v-loading="loading"

--
Gitblit v1.9.3