zhangwencui
4 小时以前 244c42d87ed2ee45f339101a377f7d897124aea4
打卡规则变动
已修改1个文件
155 ■■■■■ 文件已修改
src/pages/humanResources/attendance/checkin.vue 155 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/humanResources/attendance/checkin.vue
@@ -21,9 +21,9 @@
      <view class="checkin-button-container">
        <view class="checkin-button-wrapper">
          <view class="checkin-button"
                :class="{ 'disabled': todayRecord.workEndAt || noNeedCheckIn }"
                :class="{ 'disabled': todayRecord.workEndAt || noNeedCheckIn || locating || submitting }"
                @click="handleCheckInOut">
            <text class="checkin-button-text">{{ checkInOutText }}</text>
            <text class="checkin-button-text">{{ locating ? '定位中...' : (submitting ? '提交中...' : checkInOutText) }}</text>
            <text class="checkin-time">{{ nowTime.split(' ')[1] }}</text>
          </view>
        </view>
@@ -117,6 +117,8 @@
  // 打卡冷却时间(毫秒)
  const CHECKIN_COOLDOWN = 5000;
  const locating = ref(false);
  const submitting = ref(false);
  // 返回上一页
  const goBack = () => {
    uni.navigateBack();
@@ -208,82 +210,68 @@
    });
  };
  // 获取位置权限
  const getLocationPermission = () => {
    return new Promise((resolve, reject) => {
      // #ifdef APP-PLUS
      uni.getAppAuthorizeSetting({
        success: res => {
          if (res.authSetting["scope.userLocation"]) {
            resolve(true);
          } else {
            uni.requestAppAuthorize({
              scope: "scope.userLocation",
              success: res => {
                resolve(res.authSetting["scope.userLocation"]);
              },
              fail: err => {
                reject(err);
              },
            });
          }
        },
        fail: err => {
          reject(err);
        },
      });
      // #else
      // 非APP环境直接返回成功
      resolve(true);
      // #endif
    });
  };
  const form = ref({
    longitude: "",
    latitude: "",
  });
  const getCurrentLocation = () => {
    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();
  const showLocationError = err => {
    const errorMessage = err?.errMsg || err?.message || "未知错误";
        console.error("获取位置失败:", err);
        // 显示错误提示并引导用户检查权限
        showToast("获取位置失败,请检查定位权限");
        // 引导用户检查权限设置
        uni.showModal({
          title: "位置权限提示",
          content:
            "获取位置失败,可能是因为位置权限未开启,请在设备设置中检查并开启位置权限。",
          confirmText: "知道了",
      title: "无法获取位置",
      content: `请开启手机定位服务,并允许应用使用精确位置后重试。\n\n${errorMessage}`,
      confirmText: "去设置",
          cancelText: "取消",
          success: res => {
            if (res.confirm) {
              // 可以尝试打开设置页面(如果支持)
              if (uni.openSetting) {
                uni.openSetting({
                  success: settingRes => {
                    console.log("设置结果:", settingRes);
        if (!res.confirm) return;
        // #ifdef APP-PLUS
        uni.openAppAuthorizeSetting({
          fail: settingError => {
            console.error("打开应用权限设置失败:", settingError);
                  },
                });
              }
            }
        // #endif
        // #ifndef APP-PLUS
        if (uni.openSetting) uni.openSetting({});
        // #endif
          },
        });
  };
        // 失败时显示错误信息
        form.value.visitAddress = "位置获取失败";
  const getCurrentLocation = (showError = true) => {
    if (locating.value) {
      return Promise.reject(new Error("正在获取位置,请稍候"));
    }
    locating.value = true;
    form.value.latitude = "";
    form.value.longitude = "";
    return new Promise((resolve, reject) => {
      uni.getLocation({
        // 使用系统 WGS84 定位,正式包不依赖高德 Android Key、包名和签名 SHA1。
        type: "wgs84",
        isHighAccuracy: true,
        highAccuracyExpireTime: 10000,
        success: res => {
          const latitude = Number(res.latitude);
          const longitude = Number(res.longitude);
          if (!Number.isFinite(latitude) || !Number.isFinite(longitude)) {
            reject(new Error("定位结果中的经纬度无效"));
            return;
          }
          form.value.latitude = latitude;
          form.value.longitude = longitude;
          resolve({ latitude, longitude });
      },
        fail: reject,
        complete: () => {
          locating.value = false;
        },
      });
    }).catch(err => {
      if (showError) showLocationError(err);
      throw err;
    });
  };
@@ -306,6 +294,8 @@
  // 打卡逻辑
  const handleCheckInOut = async () => {
    if (locating.value || submitting.value) return;
    if (noNeedCheckIn.value) {
      uni.showToast({
        title: "今日无需打卡",
@@ -345,27 +335,31 @@
      return;
    }
    // 调用打卡API
    createPersonalAttendanceRecord({
      ...form.value,
    })
      .then(res => {
        // 记录打卡时间
    try {
      // 每次打卡都重新定位,避免提交进入页面时缓存的旧位置。
      await getCurrentLocation();
      if (form.value.latitude === "" || form.value.longitude === "") {
        throw new Error("未获取到有效位置");
      }
      submitting.value = true;
      await createPersonalAttendanceRecord({ ...form.value });
        lastCheckInTime.value = Date.now();
        uni.showToast({
          title: "打卡成功!",
          icon: "success",
        });
        // 重新获取今日打卡信息
        fetchTodayData();
      })
      .catch(error => {
    } catch (error) {
      // 定位失败已由 getCurrentLocation 给出权限引导,这里只提示接口错误。
      if (form.value.latitude !== "" && form.value.longitude !== "") {
        uni.showToast({
          title: error.msg || "打卡失败,请重试",
          title: error.msg || error.message || "打卡失败,请重试",
          icon: "none",
        });
      });
      }
    } finally {
      submitting.value = false;
    }
  };
  onMounted(async () => {
@@ -374,13 +368,10 @@
    timer = setInterval(updateNowTime, 1000);
    getWorkTimeDict();
    // 获取位置权限并检查位置
    try {
      // await getLocationPermission();
      await getCurrentLocation();
    } catch (error) {
      console.error("位置权限获取失败:", error);
    }
    // 进入页面时预定位;真正打卡前还会再次获取,预定位失败不打扰用户。
    getCurrentLocation(false).catch(error => {
      console.error("页面预定位失败:", error);
    });
  });
  onBeforeUnmount(() => {