YZProjectCloud/yanzhu-ui-app/miniprogram/pageage/mobile_attendance/attendance/add/index.js

378 lines
10 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

import fmt from "../../../utils/date.js";
import { getToken, getUserInfo } from "../../../../utils/auth.js";
import { securityFileUpload } from "../../../../utils/request.js"; // 导入文件上传工具
const app = getApp();
import { getMobileAttendanceConfigById } from "../../../../api/project.js";
import { calculateDistance } from "../../../../utils/location.js"; // 导入计算距离的工具函数
Page({
/**
* 页面的初始数据
*/
data: {
projectUserInfo: {},
projectUserInfo: {},
projectId: "",
projectName: "",
initData: {},
type: "",
cfgData: null,
arrSel: "in",
mapMarkers: [], // 地图标记
mapCircles: [], // 地图圆圈(用于显示考勤范围)
faceImage: "", // 人脸识别图片
faceImageUrl: "", // 上传后的人脸图片URL
},
/**
* 生命周期函数--监听页面加载
*/
onLoad(options) {
if (!getToken()) {
wx.redirectTo({
url: "../../../pages/login/login",
});
}
const proUserInfo = getUserInfo();
// 根据当前时间设置arrSel的值14点前为in14点后为out
const now = new Date();
const arrSel = now.getHours() < 14 ? "in" : "out";
this.setData({
projectUserInfo: proUserInfo.projectUserInfo,
projectId: app.globalData.useProjectId,
projectName: app.globalData.useProjectName,
initData: {
id: app.globalData.useProjectId,
text: app.globalData.useProjectName,
},
type: options.type,
arrSel: arrSel,
});
if (options.id) {
this.loadData(options.id);
} else {
app.toast("参数错误!");
this.returnToPage();
}
//todo 14点前 arrSel=in,之后arrSel=out
},
loadData(id) {
try {
let cfgData = wx.getStorageSync("editAttCfg");
cfgData.attDate = fmt(new Date()).format("YYYY-MM-DD HH:mm:ss");
if (cfgData) {
this.setData({
cfgData: cfgData,
});
// 初始化地图标记
this.initMapMarkers(cfgData);
} else {
app.toast("参数错误!");
this.returnToPage();
}
} catch (e) {
app.toast("参数错误!");
this.returnToPage();
}
},
// 初始化地图标记
initMapMarkers(cfgData) {
// 考勤地点标记
const markers = [];
const circles = [];
// 用户当前位置标记(如果有的话)
if (cfgData.attLongitude && cfgData.attLatitude) {
markers.push({
id: 1,
longitude: cfgData.attLongitude,
latitude: cfgData.attLatitude,
title: cfgData.attAddress || "当前位置",
iconPath: "/images/location-marker.png", // 使用项目中已有的图标文件
width: 30,
height: 30,
callout: {
content: cfgData.attAddress || "当前位置",
display: "ALWAYS",
fontSize: 12,
borderRadius: 5,
padding: 5,
},
});
}
// 考勤地点标记和范围圆圈
if (cfgData.longitude && cfgData.latitude) {
// 考勤地点标记
markers.push({
id: 2,
longitude: cfgData.longitude,
latitude: cfgData.latitude,
title: cfgData.address || "考勤地点",
iconPath: "/images/location-marker.png", // 使用项目中已有的图标文件
width: 30,
height: 30,
callout: {
content: cfgData.address || "考勤地点",
display: "ALWAYS",
fontSize: 12,
borderRadius: 5,
padding: 5,
},
});
// 考勤范围圆圈(如果设置了范围)
if (cfgData.range) {
circles.push({
id: 1,
longitude: cfgData.longitude,
latitude: cfgData.latitude,
radius: cfgData.range, // 范围半径(米)
strokeWidth: 2,
color: "#FF0000", // 红色边框,符合规范
fillColor: "#FF000033", // 带透明度的红色填充,符合规范
});
}
}
this.setData({
mapMarkers: markers,
mapCircles: circles,
});
},
// 打开摄像头进行人脸识别
openCamera() {
const that = this;
wx.chooseMedia({
count: 1,
mediaType: ["image"],
sourceType: ["camera"],
camera: "front", // 前置摄像头
success(res) {
console.log("chooseMedia success", res);
// 获取到图片临时路径
const tempImagePath = res.tempFiles[0].tempFilePath;
console.log("tempImagePath", tempImagePath);
// 在iPhone上可能需要特殊处理图片路径
that.setData(
{
faceImage: tempImagePath,
},
() => {
// setData完成后的回调
console.log("faceImage set successfully");
}
);
// 这里可以添加人脸识别的逻辑
// 由于项目中没有现成的人脸识别API这里只是演示如何获取图片
// 实际项目中可能需要调用后端的人脸识别接口
//that.performFaceRecognition(tempImagePath);
},
fail(err) {
console.error("打开摄像头失败", err);
app.toast("打开摄像头失败,请重试");
},
});
},
// 执行人脸识别(模拟)
performFaceRecognition() {
let imagePath = this.data.faceImage;
// 这里应该调用实际的人脸识别API
// 由于项目中没有现成的人脸识别功能,这里只是模拟
app.toast("正在识别中...");
// 上传图片到服务器
this.uploadFaceImage();
// 模拟识别过程
setTimeout(() => {
// 模拟识别成功
app.toast("人脸识别成功");
// 可以在这里设置识别成功的状态
this.setData({
isFaceRecognized: true,
});
}, 2000);
},
// 上传人脸图片到服务器
uploadFaceImage(cb) {
let imagePath = this.data.faceImage;
app.toast("正在上传图片...");
securityFileUpload(imagePath)
.then((res) => {
console.log("图片上传成功", res);
if (res.code == 200) {
app.toast("图片上传成功");
// 保存上传后的图片URL
this.setData({
faceImageUrl: res.data.url,
});
cb && cb();
} else {
app.toast("图片上传失败: " + res.msg);
}
})
.catch((err) => {
console.error("图片上传失败", err);
app.toast("图片上传失败");
});
},
doSave() {
debugger;
if (!this.data.faceImage) {
app.toast("未获取到照片!");
return;
}
// 获取当前位置并计算距离
this.getCurrentLocationAndCalculateDistance();
},
// 获取当前位置并计算距离
getCurrentLocationAndCalculateDistance() {
wx.getLocation({
type: "gcj02", // 使用国测局坐标系
success: (res) => {
const { longitude, latitude } = res;
const cfgData = this.data.cfgData;
// 使用现有的工具函数计算距离
const distance = calculateDistance(
longitude,
latitude,
cfgData.longitude,
cfgData.latitude
);
// 检查是否超出考勤范围
if (distance > cfgData.range) {
app.toast("超出考勤范围!");
return;
}
// 更新考勤数据的位置信息
this.setData(
{
"cfgData.attLongitude": longitude,
"cfgData.attLatitude": latitude,
},
() => {
// 在数据更新完成后,更新地图上的用户位置标记
this.updateUserLocationMarker(longitude, latitude);
}
);
// 继续执行打卡操作
this.uploadFaceImage(() => {
console.log(this.data.faceImageUrl);
debugger;
});
},
fail: (err) => {
console.error("获取位置失败", err);
// 检查是否是权限问题
if (err.errMsg && err.errMsg.includes("auth deny")) {
app.toast("请开启位置权限后再试");
// 引导用户开启权限
wx.showModal({
title: "提示",
content:
"需要获取您的位置信息才能进行考勤打卡,请在设置中开启位置权限",
showCancel: true,
confirmText: "去设置",
success: (res) => {
if (res.confirm) {
wx.openSetting({
success: (setting) => {
if (setting.authSetting["scope.userLocation"]) {
// 用户开启了权限,重新获取位置
this.getCurrentLocationAndCalculateDistance();
}
},
});
}
},
});
} else {
app.toast("获取位置失败,请检查定位权限");
}
},
});
},
// 更新用户位置标记
updateUserLocationMarker(longitude, latitude) {
// 创建新的标记数组
let markers = [...this.data.mapMarkers];
// 查找是否已存在用户位置标记id为1
let userMarkerIndex = markers.findIndex((marker) => marker.id === 1);
const userMarker = {
id: 1,
longitude: longitude,
latitude: latitude,
title: "当前位置",
iconPath: "/images/location-marker.png",
width: 30,
height: 30,
callout: {
content: "当前位置",
display: "ALWAYS",
fontSize: 12,
borderRadius: 5,
padding: 5,
},
};
if (userMarkerIndex !== -1) {
// 如果已存在用户位置标记,则更新它
markers[userMarkerIndex] = userMarker;
} else {
// 如果不存在用户位置标记,则添加它
markers.push(userMarker);
}
// 更新地图标记
this.setData({
mapMarkers: markers,
});
},
getDistance(longitude, latitude) {
// 获取当前位置计算距离
// 这里直接计算给定坐标与考勤地点的距离
const cfgData = this.data.cfgData;
if (!cfgData) return 0;
return calculateDistance(
longitude,
latitude,
cfgData.longitude,
cfgData.latitude
);
},
onProjectSelect(e) {
let projectId = e.detail.id;
let projectName = e.detail.text;
app.globalData.useProjectId = projectId;
app.globalData.useProjectName = projectName;
this.onLoad();
},
returnToPage() {
wx.redirectTo({
url: "../list/index",
});
},
doSelectArr(e) {
this.setData({
arrSel: e.currentTarget.dataset.set,
"cfgData.attDate": fmt(new Date()).format("YYYY-MM-DD HH:mm:ss"),
});
},
});