From c4d25912d11ab9059f8165c25a161634bb9b5e97 Mon Sep 17 00:00:00 2001
From: gaoluyang <2820782392@qq.com>
Date: 星期二, 16 六月 2026 09:45:33 +0800
Subject: [PATCH] proapp 1.工作台分类修改

---
 src/pages/humanResources/attendance/checkin.vue |  178 ++++++++++++++++++++++++++++++++++++++++++++++++----------
 1 files changed, 146 insertions(+), 32 deletions(-)

diff --git a/src/pages/humanResources/attendance/checkin.vue b/src/pages/humanResources/attendance/checkin.vue
index e5f4e6e..ab93ed9 100644
--- a/src/pages/humanResources/attendance/checkin.vue
+++ b/src/pages/humanResources/attendance/checkin.vue
@@ -14,7 +14,7 @@
           <u-icon name="calendar"
                   color="#348fe2"
                   size="16"></u-icon>
-          <text class="shift-text">鐧界彮: {{ todayRecord.startAt }}-{{ todayRecord.endAt }}</text>
+          <text class="shift-text">{{ todayRecord.shift || '-' }}: {{ todayRecord.startAt }}-{{ todayRecord.endAt }}</text>
         </view>
       </view>
       <!-- 鎵撳崱鎸夐挳 -->
@@ -106,10 +106,7 @@
   const todayRecord = ref({});
 
   // 鐝淇℃伅
-  const workTimeDict = ref({
-    startAt: "09:00",
-    endAt: "18:00",
-  });
+  const workTimeDict = ref();
 
   // 褰撳墠鏃堕棿灞曠ず
   const nowTime = ref("");
@@ -129,11 +126,18 @@
     findTodayPersonalAttendanceRecord({}).then(res => {
       if (res.data) {
         todayRecord.value = res.data;
-        noNeedCheckIn.value = false;
+        // 妫�鏌tartAt鍜宔ndAt鏄惁涓虹┖锛屼负绌哄垯鏃犻渶鎵撳崱
+        if (!todayRecord.value.startAt || !todayRecord.value.endAt) {
+          noNeedCheckIn.value = true;
+        } else {
+          noNeedCheckIn.value = false;
+        }
+        updateInCheckRange();
       } else {
         // 椤甸潰鏄剧ず鈥滄棤闇�鎵撳崱鈥�
         todayRecord.value = {};
         noNeedCheckIn.value = true;
+        updateInCheckRange();
       }
     });
   };
@@ -156,21 +160,104 @@
     const m = String(now.getMinutes()).padStart(2, "0");
     const s = String(now.getSeconds()).padStart(2, "0");
     nowTime.value = `${Y}-${M}-${D} ${h}:${m}:${s}`;
+    updateInCheckRange();
   };
 
   // 浠婃棩鏃ユ湡
   const todayStr = computed(() => nowTime.value.slice(0, 10));
+
+  const parseHmToMinutes = hm => {
+    if (!hm || typeof hm !== "string") return null;
+    const [hStr, mStr] = hm.split(":");
+    const h = Number(hStr);
+    const m = Number(mStr);
+    if (!Number.isFinite(h) || !Number.isFinite(m)) return null;
+    if (h < 0 || h > 23 || m < 0 || m > 59) return null;
+    return h * 60 + m;
+  };
+
+  const parseYmdToDate = ymd => {
+    if (!ymd || typeof ymd !== "string") return null;
+    const [yStr, mStr, dStr] = ymd.slice(0, 10).split("-");
+    const y = Number(yStr);
+    const m = Number(mStr);
+    const d = Number(dStr);
+    if (!Number.isFinite(y) || !Number.isFinite(m) || !Number.isFinite(d)) {
+      return null;
+    }
+    return new Date(y, m - 1, d, 0, 0, 0, 0);
+  };
+
+  const addMinutes = (date, minutes) => {
+    return new Date(date.getTime() + minutes * 60 * 1000);
+  };
+
+  const buildShiftWindow = () => {
+    const startAtMinutes = parseHmToMinutes(todayRecord.value?.startAt);
+    const endAtMinutes = parseHmToMinutes(todayRecord.value?.endAt);
+    if (startAtMinutes === null || endAtMinutes === null) return null;
+
+    const baseYmd = todayRecord.value?.date
+      ? String(todayRecord.value.date).slice(0, 10)
+      : todayStr.value;
+    const baseDate = parseYmdToDate(baseYmd);
+    if (!baseDate) return null;
+
+    const startDateTime = addMinutes(baseDate, startAtMinutes);
+    const crossDay = startAtMinutes > endAtMinutes;
+    const endBase = crossDay ? addMinutes(baseDate, 24 * 60) : baseDate;
+    const endDateTime = addMinutes(endBase, endAtMinutes);
+
+    return { startDateTime, endDateTime };
+  };
+
+  const updateInCheckRange = () => {
+    if (noNeedCheckIn.value) {
+      inCheckRange.value = true;
+      return;
+    }
+    const window = buildShiftWindow();
+    if (!window) {
+      inCheckRange.value = true;
+      return;
+    }
+    const now = new Date();
+    const checkInEarlyMinutes = 120;
+    const checkOutLateMinutes = 720;
+    const needAction = (() => {
+      if (todayRecord.value?.workEndAt) return "done";
+      if (todayRecord.value?.workStartAt) return "checkOut";
+      const distToStart = Math.abs(
+        now.getTime() - window.startDateTime.getTime()
+      );
+      const distToEnd = Math.abs(now.getTime() - window.endDateTime.getTime());
+      return distToEnd < distToStart ? "checkOut" : "checkIn";
+    })();
+    const start = addMinutes(window.startDateTime, -checkInEarlyMinutes);
+    const end = addMinutes(
+      window.endDateTime,
+      needAction === "checkOut" ? checkOutLateMinutes : 0
+    );
+    inCheckRange.value = now >= start && now <= end;
+  };
 
   // 鎵撳崱鎸夐挳鏂囨湰
   const checkInOutText = computed(() => {
     if (noNeedCheckIn.value) {
       return "鏃犻渶鎵撳崱";
     }
-    if (!todayRecord.value || !todayRecord.value.workStartAt) {
-      return "涓婄彮鎵撳崱";
-    }
     if (!todayRecord.value.workEndAt) {
-      return "涓嬬彮鎵撳崱";
+      if (todayRecord.value.workStartAt) {
+        return "涓嬬彮鎵撳崱";
+      }
+      const window = buildShiftWindow();
+      if (!window) return "涓婄彮鎵撳崱";
+      const now = new Date();
+      const distToStart = Math.abs(
+        now.getTime() - window.startDateTime.getTime()
+      );
+      const distToEnd = Math.abs(now.getTime() - window.endDateTime.getTime());
+      return distToEnd < distToStart ? "涓嬬彮鎵撳崱" : "涓婄彮鎵撳崱";
     }
     return "宸叉墦鍗�";
   });
@@ -236,26 +323,52 @@
       // #endif
     });
   };
+  const form = ref({
+    longitude: "",
+    latitude: "",
+  });
 
-  // 鑾峰彇褰撳墠浣嶇疆
   const getCurrentLocation = () => {
-    return new Promise((resolve, reject) => {
-      uni.getLocation({
-        type: "wgs84",
-        success: res => {
-          currentLocation.value = res;
-          // 妯℃嫙妫�鏌ユ槸鍚﹀湪鎵撳崱鑼冨洿鍐咃紙瀹為檯椤圭洰涓簲鏍规嵁鍏徃浣嶇疆鍜屽厑璁哥殑鍗婂緞杩涜璁$畻锛�
-          // 杩欓噷绠�鍗曟ā鎷熶负濮嬬粓鍦ㄨ寖鍥村唴
-          inCheckRange.value = true;
-          resolve(res);
-        },
-        fail: err => {
-          console.error("鑾峰彇浣嶇疆澶辫触:", err);
-          // 澶辫触鏃堕粯璁ゅ厑璁告墦鍗★紙瀹為檯椤圭洰涓簲鏍规嵁涓氬姟闇�姹傚鐞嗭級
-          inCheckRange.value = true;
-          reject(err);
-        },
-      });
+    uni.showLoading({ title: "鑾峰彇浣嶇疆涓�..." });
+
+    uni.getLocation({
+      type: "gcj02",
+      success: res => {
+        uni.hideLoading();
+        form.value.latitude = res.latitude;
+        form.value.longitude = res.longitude;
+      },
+      fail: err => {
+        uni.hideLoading();
+        console.error("鑾峰彇浣嶇疆澶辫触:", err);
+
+        // 鏄剧ず閿欒鎻愮ず骞跺紩瀵肩敤鎴锋鏌ユ潈闄�
+        showToast("鑾峰彇浣嶇疆澶辫触锛岃妫�鏌ュ畾浣嶆潈闄�");
+
+        // 寮曞鐢ㄦ埛妫�鏌ユ潈闄愯缃�
+        uni.showModal({
+          title: "浣嶇疆鏉冮檺鎻愮ず",
+          content:
+            "鑾峰彇浣嶇疆澶辫触锛屽彲鑳芥槸鍥犱负浣嶇疆鏉冮檺鏈紑鍚紝璇峰湪璁惧璁剧疆涓鏌ュ苟寮�鍚綅缃潈闄愩��",
+          confirmText: "鐭ラ亾浜�",
+          cancelText: "鍙栨秷",
+          success: res => {
+            if (res.confirm) {
+              // 鍙互灏濊瘯鎵撳紑璁剧疆椤甸潰锛堝鏋滄敮鎸侊級
+              if (uni.openSetting) {
+                uni.openSetting({
+                  success: settingRes => {
+                    console.log("璁剧疆缁撴灉:", settingRes);
+                  },
+                });
+              }
+            }
+          },
+        });
+
+        // 澶辫触鏃舵樉绀洪敊璇俊鎭�
+        form.value.visitAddress = "浣嶇疆鑾峰彇澶辫触";
+      },
     });
   };
 
@@ -318,7 +431,9 @@
     }
 
     // 璋冪敤鎵撳崱API
-    createPersonalAttendanceRecord({})
+    createPersonalAttendanceRecord({
+      ...form.value,
+    })
       .then(res => {
         // 璁板綍鎵撳崱鏃堕棿
         lastCheckInTime.value = Date.now();
@@ -331,7 +446,6 @@
         fetchTodayData();
       })
       .catch(error => {
-        console.error("鎵撳崱澶辫触:", error);
         uni.showToast({
           title: error.msg || "鎵撳崱澶辫触锛岃閲嶈瘯",
           icon: "none",
@@ -347,7 +461,7 @@
 
     // 鑾峰彇浣嶇疆鏉冮檺骞舵鏌ヤ綅缃�
     try {
-      await getLocationPermission();
+      // await getLocationPermission();
       await getCurrentLocation();
     } catch (error) {
       console.error("浣嶇疆鏉冮檺鑾峰彇澶辫触:", error);
@@ -770,4 +884,4 @@
   .attendance-records {
     animation-delay: 0.2s;
   }
-</style>
\ No newline at end of file
+</style>

--
Gitblit v1.9.3