diff --git a/yanzhu-bigscreen/public/index.html b/yanzhu-bigscreen/public/index.html
index 081a3048..7007aee0 100644
--- a/yanzhu-bigscreen/public/index.html
+++ b/yanzhu-bigscreen/public/index.html
@@ -16,7 +16,7 @@
diff --git a/yanzhu-bigscreen/src/views/bim/briefingTools.js b/yanzhu-bigscreen/src/views/bim/briefingTools.js
index 907e3d99..1966768b 100644
--- a/yanzhu-bigscreen/src/views/bim/briefingTools.js
+++ b/yanzhu-bigscreen/src/views/bim/briefingTools.js
@@ -293,13 +293,13 @@ function initClientClipping(that) {
}
//剖切 -- 服务端渲染
function initClipping(that) {
+ let api = bimBriefingApi;
api.Public.clearHandler();
api.Measurement.clearAllTrace();
if(that.isClient){
initClientClipping(that);
return;
}
- let api = bimBriefingApi;
api.Model.clipByBox(getModels(that));
}
diff --git a/yanzhu-bigscreen/src/views/bimBriefing.vue b/yanzhu-bigscreen/src/views/bimBriefing.vue
index 98a1fda6..dd575c9d 100644
--- a/yanzhu-bigscreen/src/views/bimBriefing.vue
+++ b/yanzhu-bigscreen/src/views/bimBriefing.vue
@@ -370,7 +370,7 @@ export default {
},
doSelectMenu(index) {
this.selectMenu = index;
- if (index == 0) {
+ if (index == this.selectMenu) {
briefingTools.clearEvent(this);
this.showClipping = false;
briefingTools.clearSelectFeature(this);
diff --git a/yanzhu-common/yanzhu-common-mapper/src/main/java/com/yanzhu/manage/domain/ProMobileAttendanceData.java b/yanzhu-common/yanzhu-common-mapper/src/main/java/com/yanzhu/manage/domain/ProMobileAttendanceData.java
new file mode 100644
index 00000000..5f139c68
--- /dev/null
+++ b/yanzhu-common/yanzhu-common-mapper/src/main/java/com/yanzhu/manage/domain/ProMobileAttendanceData.java
@@ -0,0 +1,187 @@
+package com.yanzhu.manage.domain;
+
+import java.math.BigDecimal;
+import java.util.Date;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.yanzhu.common.core.annotation.Excel;
+import com.yanzhu.common.core.web.domain.BaseEntity;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+
+
+/**
+ * 移动考勤记录对象 pro_mobile_attendance_data
+ *
+ * @author yanzhu
+ * @date 2025-09-03
+ */
+public class ProMobileAttendanceData extends BaseEntity
+{
+ private static final long serialVersionUID = 1L;
+
+ /** $column.columnComment */
+ private Long id;
+
+ /** 用户ID */
+ @Excel(name = "用户ID")
+ private Long userId;
+
+ /** 项目ID */
+ @Excel(name = "项目ID")
+ private Long projectId;
+
+ /** 配置ID */
+ @Excel(name = "配置ID")
+ private Long cfgId;
+
+ /** 进还是出 */
+ @Excel(name = "进还是出")
+ private String inOut;
+
+ /** 经度 */
+ @Excel(name = "经度")
+ private BigDecimal longitude;
+
+ /** 纬度 */
+ @Excel(name = "纬度")
+ private BigDecimal latitude;
+
+ /** 考勤时间 */
+ @JsonFormat(pattern = "yyyy-MM-dd")
+ @Excel(name = "考勤时间", width = 30, dateFormat = "yyyy-MM-dd")
+ private Date attDate;
+
+ /** 考勤照片 */
+ @Excel(name = "考勤照片")
+ private String attImg;
+
+ /** $column.columnComment */
+ @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()")
+ private Long isDel;
+
+ /** $column.columnComment */
+ @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()")
+ private Long state;
+
+ public void setId(Long id)
+ {
+ this.id = id;
+ }
+
+ public Long getId()
+ {
+ return id;
+ }
+ public void setUserId(Long userId)
+ {
+ this.userId = userId;
+ }
+
+ public Long getUserId()
+ {
+ return userId;
+ }
+ public void setProjectId(Long projectId)
+ {
+ this.projectId = projectId;
+ }
+
+ public Long getProjectId()
+ {
+ return projectId;
+ }
+ public void setCfgId(Long cfgId)
+ {
+ this.cfgId = cfgId;
+ }
+
+ public Long getCfgId()
+ {
+ return cfgId;
+ }
+ public void setInOut(String inOut)
+ {
+ this.inOut = inOut;
+ }
+
+ public String getInOut()
+ {
+ return inOut;
+ }
+ public void setLongitude(BigDecimal longitude)
+ {
+ this.longitude = longitude;
+ }
+
+ public BigDecimal getLongitude()
+ {
+ return longitude;
+ }
+ public void setLatitude(BigDecimal latitude)
+ {
+ this.latitude = latitude;
+ }
+
+ public BigDecimal getLatitude()
+ {
+ return latitude;
+ }
+ public void setAttDate(Date attDate)
+ {
+ this.attDate = attDate;
+ }
+
+ public Date getAttDate()
+ {
+ return attDate;
+ }
+ public void setAttImg(String attImg)
+ {
+ this.attImg = attImg;
+ }
+
+ public String getAttImg()
+ {
+ return attImg;
+ }
+ public void setIsDel(Long isDel)
+ {
+ this.isDel = isDel;
+ }
+
+ public Long getIsDel()
+ {
+ return isDel;
+ }
+ public void setState(Long state)
+ {
+ this.state = state;
+ }
+
+ public Long getState()
+ {
+ return state;
+ }
+
+ @Override
+ public String toString() {
+ return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
+ .append("id", getId())
+ .append("userId", getUserId())
+ .append("projectId", getProjectId())
+ .append("cfgId", getCfgId())
+ .append("inOut", getInOut())
+ .append("longitude", getLongitude())
+ .append("latitude", getLatitude())
+ .append("attDate", getAttDate())
+ .append("attImg", getAttImg())
+ .append("isDel", getIsDel())
+ .append("remark", getRemark())
+ .append("state", getState())
+ .append("createBy", getCreateBy())
+ .append("createTime", getCreateTime())
+ .append("updateBy", getUpdateBy())
+ .append("updateTime", getUpdateTime())
+ .toString();
+ }
+}
diff --git a/yanzhu-common/yanzhu-common-mapper/src/main/java/com/yanzhu/manage/mapper/ProMobileAttendanceDataMapper.java b/yanzhu-common/yanzhu-common-mapper/src/main/java/com/yanzhu/manage/mapper/ProMobileAttendanceDataMapper.java
new file mode 100644
index 00000000..90eb71b3
--- /dev/null
+++ b/yanzhu-common/yanzhu-common-mapper/src/main/java/com/yanzhu/manage/mapper/ProMobileAttendanceDataMapper.java
@@ -0,0 +1,61 @@
+package com.yanzhu.manage.mapper;
+
+import java.util.List;
+import com.yanzhu.manage.domain.ProMobileAttendanceData;
+
+/**
+ * 移动考勤记录Mapper接口
+ *
+ * @author yanzhu
+ * @date 2025-09-03
+ */
+public interface ProMobileAttendanceDataMapper
+{
+ /**
+ * 查询移动考勤记录
+ *
+ * @param id 移动考勤记录主键
+ * @return 移动考勤记录
+ */
+ public ProMobileAttendanceData selectProMobileAttendanceDataById(Long id);
+
+ /**
+ * 查询移动考勤记录列表
+ *
+ * @param proMobileAttendanceData 移动考勤记录
+ * @return 移动考勤记录集合
+ */
+ public List selectProMobileAttendanceDataList(ProMobileAttendanceData proMobileAttendanceData);
+
+ /**
+ * 新增移动考勤记录
+ *
+ * @param proMobileAttendanceData 移动考勤记录
+ * @return 结果
+ */
+ public int insertProMobileAttendanceData(ProMobileAttendanceData proMobileAttendanceData);
+
+ /**
+ * 修改移动考勤记录
+ *
+ * @param proMobileAttendanceData 移动考勤记录
+ * @return 结果
+ */
+ public int updateProMobileAttendanceData(ProMobileAttendanceData proMobileAttendanceData);
+
+ /**
+ * 删除移动考勤记录
+ *
+ * @param id 移动考勤记录主键
+ * @return 结果
+ */
+ public int deleteProMobileAttendanceDataById(Long id);
+
+ /**
+ * 批量删除移动考勤记录
+ *
+ * @param ids 需要删除的数据主键集合
+ * @return 结果
+ */
+ public int deleteProMobileAttendanceDataByIds(Long[] ids);
+}
diff --git a/yanzhu-common/yanzhu-common-mapper/src/main/resources/mapper/manage/ProMobileAttendanceDataMapper.xml b/yanzhu-common/yanzhu-common-mapper/src/main/resources/mapper/manage/ProMobileAttendanceDataMapper.xml
new file mode 100644
index 00000000..bc10dd24
--- /dev/null
+++ b/yanzhu-common/yanzhu-common-mapper/src/main/resources/mapper/manage/ProMobileAttendanceDataMapper.xml
@@ -0,0 +1,121 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ select id, user_id, project_id, cfg_id, in_out, longitude, latitude, att_date, att_img, is_del, remark, state, create_by, create_time, update_by, update_time from pro_mobile_attendance_data
+
+
+
+
+
+
+
+ insert into pro_mobile_attendance_data
+
+ user_id,
+ project_id,
+ cfg_id,
+ in_out,
+ longitude,
+ latitude,
+ att_date,
+ att_img,
+ is_del,
+ remark,
+ state,
+ create_by,
+ create_time,
+ update_by,
+ update_time,
+
+
+ #{userId},
+ #{projectId},
+ #{cfgId},
+ #{inOut},
+ #{longitude},
+ #{latitude},
+ #{attDate},
+ #{attImg},
+ #{isDel},
+ #{remark},
+ #{state},
+ #{createBy},
+ #{createTime},
+ #{updateBy},
+ #{updateTime},
+
+
+
+
+ update pro_mobile_attendance_data
+
+ user_id = #{userId},
+ project_id = #{projectId},
+ cfg_id = #{cfgId},
+ in_out = #{inOut},
+ longitude = #{longitude},
+ latitude = #{latitude},
+ att_date = #{attDate},
+ att_img = #{attImg},
+ is_del = #{isDel},
+ remark = #{remark},
+ state = #{state},
+ create_by = #{createBy},
+ create_time = #{createTime},
+ update_by = #{updateBy},
+ update_time = #{updateTime},
+
+ where id = #{id}
+
+
+
+ delete from pro_mobile_attendance_data where id = #{id}
+
+
+
+ delete from pro_mobile_attendance_data where id in
+
+ #{id}
+
+
+
\ No newline at end of file
diff --git a/yanzhu-modules/yanzhu-manage/src/main/java/com/yanzhu/manage/controller/remoteAttendance/ProMobileAttendanceConfigController.java b/yanzhu-modules/yanzhu-manage/src/main/java/com/yanzhu/manage/controller/remoteAttendance/ProMobileAttendanceConfigController.java
index 04d4e2d6..8f326348 100644
--- a/yanzhu-modules/yanzhu-manage/src/main/java/com/yanzhu/manage/controller/remoteAttendance/ProMobileAttendanceConfigController.java
+++ b/yanzhu-modules/yanzhu-manage/src/main/java/com/yanzhu/manage/controller/remoteAttendance/ProMobileAttendanceConfigController.java
@@ -113,4 +113,16 @@ public class ProMobileAttendanceConfigController extends BaseController
{
return toAjax(proMobileAttendanceConfigService.deleteProMobileAttendanceConfigByIds(ids));
}
+
+ /**
+ * 移动考勤
+ */
+ @RequiresPermissions("manage:mobileAttendConfig:add")
+ @PostMapping("/attendance")
+ public AjaxResult attendance(@RequestBody ProMobileAttendanceConfig cfg){
+ //根据用户上传的照片与用户信息的照片计算相似度
+ //增加考勤数据
+ //增加考勤历史记录
+ return AjaxResult.success("OK");
+ }
}
diff --git a/yanzhu-modules/yanzhu-manage/src/main/java/com/yanzhu/manage/service/IProMobileAttendanceDataService.java b/yanzhu-modules/yanzhu-manage/src/main/java/com/yanzhu/manage/service/IProMobileAttendanceDataService.java
new file mode 100644
index 00000000..cc06bfaa
--- /dev/null
+++ b/yanzhu-modules/yanzhu-manage/src/main/java/com/yanzhu/manage/service/IProMobileAttendanceDataService.java
@@ -0,0 +1,61 @@
+package com.yanzhu.manage.service;
+
+import java.util.List;
+import com.yanzhu.manage.domain.ProMobileAttendanceData;
+
+/**
+ * 移动考勤记录Service接口
+ *
+ * @author yanzhu
+ * @date 2025-09-03
+ */
+public interface IProMobileAttendanceDataService
+{
+ /**
+ * 查询移动考勤记录
+ *
+ * @param id 移动考勤记录主键
+ * @return 移动考勤记录
+ */
+ public ProMobileAttendanceData selectProMobileAttendanceDataById(Long id);
+
+ /**
+ * 查询移动考勤记录列表
+ *
+ * @param proMobileAttendanceData 移动考勤记录
+ * @return 移动考勤记录集合
+ */
+ public List selectProMobileAttendanceDataList(ProMobileAttendanceData proMobileAttendanceData);
+
+ /**
+ * 新增移动考勤记录
+ *
+ * @param proMobileAttendanceData 移动考勤记录
+ * @return 结果
+ */
+ public int insertProMobileAttendanceData(ProMobileAttendanceData proMobileAttendanceData);
+
+ /**
+ * 修改移动考勤记录
+ *
+ * @param proMobileAttendanceData 移动考勤记录
+ * @return 结果
+ */
+ public int updateProMobileAttendanceData(ProMobileAttendanceData proMobileAttendanceData);
+
+ /**
+ * 批量删除移动考勤记录
+ *
+ * @param ids 需要删除的移动考勤记录主键集合
+ * @return 结果
+ */
+ public int deleteProMobileAttendanceDataByIds(Long[] ids);
+
+ /**
+ * 删除移动考勤记录信息
+ *
+ * @param id 移动考勤记录主键
+ * @return 结果
+ */
+ public int deleteProMobileAttendanceDataById(Long id);
+}
diff --git a/yanzhu-modules/yanzhu-manage/src/main/java/com/yanzhu/manage/service/impl/ProMobileAttendanceDataServiceImpl.java b/yanzhu-modules/yanzhu-manage/src/main/java/com/yanzhu/manage/service/impl/ProMobileAttendanceDataServiceImpl.java
new file mode 100644
index 00000000..3b4afd49
--- /dev/null
+++ b/yanzhu-modules/yanzhu-manage/src/main/java/com/yanzhu/manage/service/impl/ProMobileAttendanceDataServiceImpl.java
@@ -0,0 +1,100 @@
+package com.yanzhu.manage.service.impl;
+
+import java.util.List;
+
+import com.yanzhu.common.core.context.SecurityContextHolder;
+import com.yanzhu.common.core.utils.DateUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import com.yanzhu.manage.mapper.ProMobileAttendanceDataMapper;
+import com.yanzhu.manage.domain.ProMobileAttendanceData;
+import com.yanzhu.manage.service.IProMobileAttendanceDataService;
+
+/**
+ * 移动考勤记录Service业务层处理
+ *
+ * @author yanzhu
+ * @date 2025-09-03
+ */
+@Service
+public class ProMobileAttendanceDataServiceImpl implements IProMobileAttendanceDataService
+{
+ @Autowired
+ private ProMobileAttendanceDataMapper proMobileAttendanceDataMapper;
+
+ /**
+ * 查询移动考勤记录
+ *
+ * @param id 移动考勤记录主键
+ * @return 移动考勤记录
+ */
+ @Override
+ public ProMobileAttendanceData selectProMobileAttendanceDataById(Long id)
+ {
+ return proMobileAttendanceDataMapper.selectProMobileAttendanceDataById(id);
+ }
+
+ /**
+ * 查询移动考勤记录列表
+ *
+ * @param proMobileAttendanceData 移动考勤记录
+ * @return 移动考勤记录
+ */
+ @Override
+ public List selectProMobileAttendanceDataList(ProMobileAttendanceData proMobileAttendanceData)
+ {
+ return proMobileAttendanceDataMapper.selectProMobileAttendanceDataList(proMobileAttendanceData);
+ }
+
+ /**
+ * 新增移动考勤记录
+ *
+ * @param proMobileAttendanceData 移动考勤记录
+ * @return 结果
+ */
+ @Override
+ public int insertProMobileAttendanceData(ProMobileAttendanceData proMobileAttendanceData)
+ {
+ proMobileAttendanceData.setCreateBy(SecurityContextHolder.getUserName());
+ proMobileAttendanceData.setCreateTime(DateUtils.getNowDate());
+ return proMobileAttendanceDataMapper.insertProMobileAttendanceData(proMobileAttendanceData);
+ }
+
+ /**
+ * 修改移动考勤记录
+ *
+ * @param proMobileAttendanceData 移动考勤记录
+ * @return 结果
+ */
+ @Override
+ public int updateProMobileAttendanceData(ProMobileAttendanceData proMobileAttendanceData)
+ {
+ proMobileAttendanceData.setUpdateBy(SecurityContextHolder.getUserName());
+ proMobileAttendanceData.setUpdateTime(DateUtils.getNowDate());
+ return proMobileAttendanceDataMapper.updateProMobileAttendanceData(proMobileAttendanceData);
+ }
+
+ /**
+ * 批量删除移动考勤记录
+ *
+ * @param ids 需要删除的移动考勤记录主键
+ * @return 结果
+ */
+ @Override
+ public int deleteProMobileAttendanceDataByIds(Long[] ids)
+ {
+ return proMobileAttendanceDataMapper.deleteProMobileAttendanceDataByIds(ids);
+ }
+
+ /**
+ * 删除移动考勤记录信息
+ *
+ * @param id 移动考勤记录主键
+ * @return 结果
+ */
+ @Override
+ public int deleteProMobileAttendanceDataById(Long id)
+ {
+ return proMobileAttendanceDataMapper.deleteProMobileAttendanceDataById(id);
+ }
+}
diff --git a/yanzhu-ui-app/miniprogram/images/svg/signal.svg b/yanzhu-ui-app/miniprogram/images/svg/signal.svg
new file mode 100644
index 00000000..d0602752
--- /dev/null
+++ b/yanzhu-ui-app/miniprogram/images/svg/signal.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/yanzhu-ui-app/miniprogram/pageage/mobile_attendance/attendance/add/index.js b/yanzhu-ui-app/miniprogram/pageage/mobile_attendance/attendance/add/index.js
index 8156faf5..cca700c6 100644
--- a/yanzhu-ui-app/miniprogram/pageage/mobile_attendance/attendance/add/index.js
+++ b/yanzhu-ui-app/miniprogram/pageage/mobile_attendance/attendance/add/index.js
@@ -1,6 +1,9 @@
+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({
/**
@@ -15,6 +18,10 @@ Page({
type: "",
cfgData: null,
arrSel: "in",
+ mapMarkers: [], // 地图标记
+ mapCircles: [], // 地图圆圈(用于显示考勤范围)
+ faceImage: "", // 人脸识别图片
+ faceImageUrl: "", // 上传后的人脸图片URL
},
/**
@@ -54,10 +61,14 @@ Page({
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();
@@ -67,7 +78,284 @@ Page({
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;
@@ -80,4 +368,10 @@ Page({
url: "../list/index",
});
},
+ doSelectArr(e) {
+ this.setData({
+ arrSel: e.currentTarget.dataset.set,
+ "cfgData.attDate": fmt(new Date()).format("YYYY-MM-DD HH:mm:ss"),
+ });
+ },
});
diff --git a/yanzhu-ui-app/miniprogram/pageage/mobile_attendance/attendance/add/index.wxml b/yanzhu-ui-app/miniprogram/pageage/mobile_attendance/attendance/add/index.wxml
index d0f32eec..a6e058da 100644
--- a/yanzhu-ui-app/miniprogram/pageage/mobile_attendance/attendance/add/index.wxml
+++ b/yanzhu-ui-app/miniprogram/pageage/mobile_attendance/attendance/add/index.wxml
@@ -17,20 +17,65 @@
-
-
-
- 请选择考勤方向
+
+
+
+ 请选择考勤方向
+
+
+
+
+ 上班考勤打卡
-
-
-
- 上班考勤打卡
-
-
-
- 下班考勤打卡
-
+
+
+ 下班考勤打卡
+
+
+
+
+
+ 考勤信息
+
+
+
+ 考勤标题:
+ {{cfgData.title}}
+
+
+ 考勤时间:
+ {{cfgData.attDate}}
+
+
+ 考勤位置:
+ {{cfgData.attAddress}}
+
+
+
+
+
+
+
+
+
+
+ 考勤人像刷脸
+
+
+
+ 拍照后显示图片
+
+
+
+
+
+ 打卡
+
+ 返回
+
+
\ No newline at end of file
diff --git a/yanzhu-ui-app/miniprogram/pageage/mobile_attendance/attendance/add/index.wxss b/yanzhu-ui-app/miniprogram/pageage/mobile_attendance/attendance/add/index.wxss
index 90c858bf..b6165d4c 100644
--- a/yanzhu-ui-app/miniprogram/pageage/mobile_attendance/attendance/add/index.wxss
+++ b/yanzhu-ui-app/miniprogram/pageage/mobile_attendance/attendance/add/index.wxss
@@ -4,19 +4,26 @@
.content_box_title{
display: flex;
align-items: center;
+ margin-bottom: 20rpx;
+}
+.content_box_title text{
+ margin-left:10rpx;
}
-
.arrow_content{
display: flex;
}
.arrow_box{
- background-color: #ccc;
+ background-color: #626262;
width:45%;
margin:0 5%;
position: relative;
- display: flex;
- align-items: center;
+ border-radius: 10rpx;
+ color: #aaa;
+}
+.arrow_box.is-active{
+ background-color: #37BBDE;
+ color:#000;
}
.arrow_box .img-sel{
position: absolute;
@@ -26,6 +33,65 @@
}
.arrow_box view{
- height: 120rpx;
- line-height: 120rpx;
+ height: 160rpx;
+ line-height: 160rpx;
+ width:100% ;
+ text-align: center;
+}
+
+/* 地图样式 */
+#attendanceMap {
+ width: 100%;
+ height: 300rpx;
+ border-radius: 10rpx;
+}
+.box_row{
+ display: flex;
+ line-height: 50rpx;
+}
+.att-info{
+ padding-left:40rpx;
+}
+.att-info .row-content{
+ padding-left:10rpx;
+}
+.box_map{
+ margin-top: 20rpx;
+}
+/* 人脸识别区域样式 */
+.att-img {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ padding: 20rpx 0;
+}
+
+.att-img image {
+ width: 400rpx;
+ height: 400rpx;
+ margin-bottom: 20rpx;
+ border-radius: 10rpx;
+ background-color: #1E2737;
+}
+
+.att-img .placeholder-text {
+ width: 400rpx;
+ height: 400rpx;
+ margin-bottom: 20rpx;
+ border-radius: 10rpx;
+ background-color: #1E2737;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ color: #999;
+ font-size: 24rpx;
+}
+
+.att-img button {
+ background-color: #07C160;
+ color: white;
+ border: none;
+ padding: 20rpx 20rpx;
+ border-radius: 10rpx;
+ font-size: 28rpx;
}
\ No newline at end of file
diff --git a/yanzhu-ui-app/miniprogram/pageage/mobile_attendance/attendance/list/index.js b/yanzhu-ui-app/miniprogram/pageage/mobile_attendance/attendance/list/index.js
index 646fb50a..a307dff4 100644
--- a/yanzhu-ui-app/miniprogram/pageage/mobile_attendance/attendance/list/index.js
+++ b/yanzhu-ui-app/miniprogram/pageage/mobile_attendance/attendance/list/index.js
@@ -17,6 +17,7 @@ Page({
listData: [],
userLongitude: undefined,
userLatitude: undefined,
+ currentAddress: "", // 当前位置地址
pageNum: 1,
pageSize: 10,
},
@@ -48,6 +49,7 @@ Page({
* 获取用户当前位置
*/
getUserLocation() {
+ debugger;
wx.getLocation({
type: "gcj02", // 使用国测局坐标
success: (res) => {
@@ -55,7 +57,21 @@ Page({
userLongitude: res.longitude,
userLatitude: res.latitude,
});
- this.getListData();
+ // 获取当前位置的地址信息
+ this.getCurrentAddress(res.longitude, res.latitude)
+ .then((address) => {
+ this.setData({
+ currentAddress: address,
+ });
+ this.getListData();
+ })
+ .catch((err) => {
+ console.error("获取当前位置地址失败", err);
+ this.setData({
+ currentAddress: "地址获取失败",
+ });
+ this.getListData();
+ });
},
fail: (err) => {
console.error("获取位置失败", err);
@@ -86,6 +102,9 @@ Page({
it.longitude,
it.latitude
);
+ it.attLongitude = this.data.userLongitude;
+ it.attLatitude = this.data.userLatitude;
+ it.attAddress = this.data.currentAddress;
} else {
it.distance = -1; // 无法计算距离
}
@@ -98,6 +117,32 @@ Page({
}
});
},
+ getCurrentAddress(longitude, latitude) {
+ // 使用腾讯地图API获取地址信息
+ const apiKey = "NUQBZ-UIYCW-H7GRI-YXOXA-WNZB7-IGFLY"; // 使用项目中已有的API密钥
+ const url = `https://apis.map.qq.com/ws/geocoder/v1/?location=${latitude},${longitude}&key=${apiKey}&get_poi=1`;
+
+ return new Promise((resolve, reject) => {
+ wx.request({
+ url: url,
+ method: "GET",
+ success: (res) => {
+ if (res.statusCode === 200 && res.data.status === 0) {
+ // 成功获取地址信息
+ const address = res.data.result.address || "未知地址";
+ resolve(address);
+ } else {
+ // API调用失败
+ reject(new Error(res.data.message || "获取地址失败"));
+ }
+ },
+ fail: (err) => {
+ // 网络请求失败
+ reject(new Error("网络请求失败"));
+ },
+ });
+ });
+ },
getInfo(e) {
let cfgData = e.currentTarget.dataset.set;
wx.setStorageSync("editAttCfg", cfgData);
diff --git a/yanzhu-ui-app/miniprogram/pageage/mobile_attendance/attendance/list/index.wxml b/yanzhu-ui-app/miniprogram/pageage/mobile_attendance/attendance/list/index.wxml
index 11f12876..d5cd6c3e 100644
--- a/yanzhu-ui-app/miniprogram/pageage/mobile_attendance/attendance/list/index.wxml
+++ b/yanzhu-ui-app/miniprogram/pageage/mobile_attendance/attendance/list/index.wxml
@@ -19,11 +19,11 @@
+
生效中的考勤点({{total}})
-
@@ -72,6 +72,11 @@
+
+
+ 当前位置:
+ {{item.attAddress}}
+
diff --git a/yanzhu-ui-app/miniprogram/pageage/mobile_attendance/attendance/list/index.wxss b/yanzhu-ui-app/miniprogram/pageage/mobile_attendance/attendance/list/index.wxss
index c1842a31..696a4ef8 100644
--- a/yanzhu-ui-app/miniprogram/pageage/mobile_attendance/attendance/list/index.wxss
+++ b/yanzhu-ui-app/miniprogram/pageage/mobile_attendance/attendance/list/index.wxss
@@ -29,4 +29,25 @@
.module_title{
flex-grow: 1;
text-align: right;
+}
+
+/* 用户位置信息样式 */
+.user-location-info {
+ background-color: #f0f8ff;
+ padding: 20rpx 30rpx;
+ margin: 20rpx 30rpx;
+ border-radius: 10rpx;
+ border: 1px solid #45affb;
+}
+
+.location-title {
+ font-weight: bold;
+ color: #45affb;
+ margin-bottom: 10rpx;
+}
+
+.location-address {
+ font-size: 26rpx;
+ color: #333;
+ word-wrap: break-word;
}
\ No newline at end of file
diff --git a/yanzhu-ui-vue3/index.html b/yanzhu-ui-vue3/index.html
index 12dbfe52..a9cb0a38 100644
--- a/yanzhu-ui-vue3/index.html
+++ b/yanzhu-ui-vue3/index.html
@@ -15,7 +15,7 @@
数字建安施工