gaoluyang
昨天 fcf6e5286e72d2df817ac077b47acd2bfc1e0649
src/pages/humanResources/attendance/checkin.vue
@@ -14,14 +14,14 @@
          <u-icon name="calendar"
                  color="#348fe2"
                  size="16"></u-icon>
          <text class="shift-text">白班: {{ workTimeDict.startAt }}-{{ workTimeDict.endAt }}</text>
          <text class="shift-text">白班: {{ todayRecord.startAt }}-{{ todayRecord.endAt }}</text>
        </view>
      </view>
      <!-- 打卡按钮 -->
      <view class="checkin-button-container">
        <view class="checkin-button-wrapper">
          <view class="checkin-button"
                :class="{ 'disabled': todayRecord.workEndAt }"
                :class="{ 'disabled': todayRecord.workEndAt || noNeedCheckIn }"
                @click="handleCheckInOut">
            <text class="checkin-button-text">{{ checkInOutText }}</text>
            <text class="checkin-time">{{ nowTime.split(' ')[1] }}</text>
@@ -114,6 +114,12 @@
  // 当前时间展示
  const nowTime = ref("");
  let timer = null;
  // 上次打卡时间
  const lastCheckInTime = ref(null);
  // 打卡冷却时间(毫秒)
  const CHECKIN_COOLDOWN = 5000;
  // 返回上一页
  const goBack = () => {
    uni.navigateBack();
@@ -121,12 +127,27 @@
  // 查询今日打卡信息
  const fetchTodayData = () => {
    findTodayPersonalAttendanceRecord({}).then(res => {
      todayRecord.value = res.data;
      if (res.data) {
        todayRecord.value = res.data;
        // 检查startAt和endAt是否为空,为空则无需打卡
        if (!todayRecord.value.startAt || !todayRecord.value.endAt) {
          noNeedCheckIn.value = true;
        } else {
          noNeedCheckIn.value = false;
        }
      } else {
        // 页面显示“无需打卡”
        todayRecord.value = {};
        noNeedCheckIn.value = true;
      }
    });
  };
  // 打卡范围状态
  const inCheckRange = ref(true);
  // 是否无需打卡
  const noNeedCheckIn = ref(false);
  // 当前位置
  const currentLocation = ref(null);
@@ -147,6 +168,9 @@
  // 打卡按钮文本
  const checkInOutText = computed(() => {
    if (noNeedCheckIn.value) {
      return "无需打卡";
    }
    if (!todayRecord.value || !todayRecord.value.workStartAt) {
      return "上班打卡";
    }
@@ -217,26 +241,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 = "位置获取失败";
      },
    });
  };
@@ -259,6 +309,14 @@
  // 打卡逻辑
  const handleCheckInOut = async () => {
    if (noNeedCheckIn.value) {
      uni.showToast({
        title: "今日无需打卡",
        icon: "none",
      });
      return;
    }
    if (todayRecord.value.workEndAt) {
      uni.showToast({
        title: "您已经打过卡了,无需重复打卡!!!",
@@ -266,6 +324,21 @@
      });
      return;
    }
    // 检查是否在打卡冷却时间内
    if (lastCheckInTime.value) {
      const currentTime = Date.now();
      const timeDiff = currentTime - lastCheckInTime.value;
      if (timeDiff < CHECKIN_COOLDOWN) {
        const remainingTime = Math.ceil((CHECKIN_COOLDOWN - timeDiff) / 1000);
        uni.showToast({
          title: `请${remainingTime}秒后再试`,
          icon: "none",
        });
        return;
      }
    }
    // 检查是否在打卡范围内
    if (!inCheckRange.value) {
      uni.showToast({
@@ -276,8 +349,13 @@
    }
    // 调用打卡API
    createPersonalAttendanceRecord({})
    createPersonalAttendanceRecord({
      ...form.value,
    })
      .then(res => {
        // 记录打卡时间
        lastCheckInTime.value = Date.now();
        uni.showToast({
          title: "打卡成功!",
          icon: "success",
@@ -286,7 +364,6 @@
        fetchTodayData();
      })
      .catch(error => {
        console.error("打卡失败:", error);
        uni.showToast({
          title: error.msg || "打卡失败,请重试",
          icon: "none",
@@ -302,7 +379,7 @@
    // 获取位置权限并检查位置
    try {
      await getLocationPermission();
      // await getLocationPermission();
      await getCurrentLocation();
    } catch (error) {
      console.error("位置权限获取失败:", error);