585 lines
15 KiB
JavaScript
585 lines
15 KiB
JavaScript
// pageage/mobile_attendance/attendance_config/add/index.js
|
||
|
||
import { getToken, getUserInfo } from "../../../../utils/auth";
|
||
import { uploadFiles } from "../../../utils/upload.js";
|
||
import { tryToJson } from "../../../utils/tools";
|
||
import {
|
||
findSubGroupsList,
|
||
subdeptsList,
|
||
addMobileAttendanceConfig,
|
||
} from "../../../../api/project";
|
||
import { findDictCache } from "../../../../api/publics";
|
||
const app = getApp();
|
||
|
||
// 添加防抖变量,避免频繁请求API
|
||
let lastRequestTime = 0;
|
||
const REQUEST_INTERVAL = 1000; // 1秒间隔
|
||
|
||
Page({
|
||
/**
|
||
* 页面的初始数据
|
||
*/
|
||
data: {
|
||
maxDate: new Date(2088, 1, 1).getTime(),
|
||
minDate: new Date().getTime(),
|
||
projectUserInfo: {},
|
||
projectId: "",
|
||
projectName: "",
|
||
initData: {},
|
||
form: {
|
||
title: "",
|
||
startDate: "",
|
||
endDate: "",
|
||
longitude: 0,
|
||
latitude: 0,
|
||
range: 50,
|
||
address: "",
|
||
subGroup: [],
|
||
groupIds: "",
|
||
groupNames: [],
|
||
},
|
||
markers: [],
|
||
// 全屏地图相关数据
|
||
showFullScreenMap: false,
|
||
mapLongitude: 0,
|
||
mapLatitude: 0,
|
||
fullScreenMarkers: [],
|
||
selectedAddress: "",
|
||
// 搜索相关数据
|
||
searchKeyword: "",
|
||
searchResults: [],
|
||
subGroupList: [],
|
||
groupList: [],
|
||
subDeptTypeList: [],
|
||
// 添加成功标识
|
||
isAddSuccess: false,
|
||
},
|
||
|
||
/**
|
||
* 生命周期函数--监听页面加载
|
||
*/
|
||
onLoad(options) {
|
||
if (!getToken()) {
|
||
wx.redirectTo({
|
||
url: "../../../pages/login/login",
|
||
});
|
||
}
|
||
const proUserInfo = getUserInfo();
|
||
this.setData({
|
||
projectUserInfo: proUserInfo.projectUserInfo,
|
||
projectId: app.globalData.useProjectId,
|
||
projectName: app.globalData.useProjectName,
|
||
initData: {
|
||
id: app.globalData.useProjectId,
|
||
text: app.globalData.useProjectName,
|
||
},
|
||
});
|
||
// 获取当前位置作为初始位置
|
||
this.getUserLocation();
|
||
this.getSubGroupList();
|
||
},
|
||
getSubGroupList() {
|
||
findDictCache("sub_dept_type").then((dict) => {
|
||
this.setData({
|
||
subDeptTypeList: dict.data,
|
||
});
|
||
findSubGroupsList({
|
||
projectId: app.globalData.useProjectId,
|
||
pageNum: 1,
|
||
pageSize: 1000,
|
||
}).then((res) => {
|
||
if (res.code == 200) {
|
||
let tmps = res.rows || [];
|
||
this.setData({
|
||
groupList: tmps,
|
||
});
|
||
let obj = {};
|
||
tmps.forEach((it) => {
|
||
let name = it.subDeptType == 1 ? "施工单位" : it.subDeptName;
|
||
if (!obj[name]) {
|
||
obj[name] = [it];
|
||
} else {
|
||
obj[name].push(it);
|
||
}
|
||
});
|
||
let subGroupList = [];
|
||
for (let key in obj) {
|
||
let val = obj[key][0];
|
||
let deptType = this.data.subDeptTypeList.find(
|
||
(dict) => dict.dictValue == val.subDeptType
|
||
);
|
||
subGroupList.push({
|
||
subDeptId: val.subDeptId,
|
||
subDeptName: val.subDeptName,
|
||
subDeptType: val.subDeptType,
|
||
subDeptTypeName: deptType?.dictLabel || "",
|
||
userList: obj[key].map((it) => {
|
||
it.status = false;
|
||
it.userId = it.id;
|
||
it.userName = it.groupName;
|
||
return it;
|
||
}),
|
||
});
|
||
}
|
||
this.setData({
|
||
subGroupList: subGroupList,
|
||
});
|
||
}
|
||
});
|
||
});
|
||
},
|
||
// 获取用户当前位置
|
||
getUserLocation() {
|
||
wx.getLocation({
|
||
type: "gcj02", // 腾讯地图坐标系
|
||
success: (res) => {
|
||
const { latitude, longitude } = res;
|
||
// 设置地图初始位置
|
||
this.setData({
|
||
mapLatitude: latitude,
|
||
mapLongitude: longitude,
|
||
"form.latitude": latitude,
|
||
"form.longitude": longitude,
|
||
});
|
||
|
||
// 获取地址信息
|
||
this.getAddressInfo(latitude, longitude);
|
||
},
|
||
fail: (err) => {
|
||
console.error("获取位置失败", err);
|
||
wx.showToast({
|
||
title: "请允许位置权限",
|
||
icon: "none",
|
||
});
|
||
// 引导用户开启权限
|
||
setTimeout(() => {
|
||
wx.openSetting({
|
||
success: (setting) => {
|
||
if (setting.authSetting["scope.userLocation"]) {
|
||
this.getUserLocation();
|
||
}
|
||
},
|
||
});
|
||
}, 1500);
|
||
},
|
||
});
|
||
},
|
||
// 获取地址信息(逆地理编码)- 带重试机制
|
||
getAddressInfo(latitude, longitude, isFullScreen = false) {
|
||
const now = Date.now();
|
||
// 检查请求间隔,避免频繁请求
|
||
if (now - lastRequestTime < REQUEST_INTERVAL) {
|
||
console.log("请求过于频繁,跳过本次请求");
|
||
return;
|
||
}
|
||
lastRequestTime = now;
|
||
|
||
// 使用腾讯地图API进行逆地理编码
|
||
// 注意:需要替换为你自己的腾讯地图API密钥
|
||
const apiKey = "NUQBZ-UIYCW-H7GRI-YXOXA-WNZB7-IGFLY";
|
||
const url = `https://apis.map.qq.com/ws/geocoder/v1/?location=${latitude},${longitude}&key=${apiKey}&get_poi=0`;
|
||
|
||
// 添加重试机制
|
||
this.requestWithRetry(url, 3, (success, data) => {
|
||
if (success) {
|
||
const address = data.result.address || "获取地址失败";
|
||
if (isFullScreen) {
|
||
// 全屏地图模式下更新选中地址
|
||
this.setData({
|
||
selectedAddress: address,
|
||
});
|
||
} else {
|
||
// 普通模式下更新表单地址
|
||
this.setData({
|
||
"form.address": address,
|
||
});
|
||
}
|
||
} else {
|
||
console.error("逆地理编码失败", data);
|
||
const errorMsg = "获取地址失败";
|
||
if (isFullScreen) {
|
||
this.setData({
|
||
selectedAddress: errorMsg,
|
||
});
|
||
} else {
|
||
this.setData({
|
||
"form.address": errorMsg,
|
||
});
|
||
}
|
||
wx.showToast({
|
||
title: "地址获取失败,请手动输入",
|
||
icon: "none",
|
||
});
|
||
}
|
||
});
|
||
},
|
||
// 带重试机制的请求方法
|
||
requestWithRetry(url, maxRetries, callback, retryCount = 0) {
|
||
wx.request({
|
||
url: url,
|
||
success: (res) => {
|
||
if (res.data.status === 0) {
|
||
callback(true, res.data);
|
||
} else {
|
||
// 如果是因为请求频率限制导致的失败,进行重试
|
||
if (
|
||
res.data.message &&
|
||
res.data.message.includes("请求量") &&
|
||
retryCount < maxRetries
|
||
) {
|
||
console.log(
|
||
`请求失败,${(retryCount + 1) * 1000}ms后进行第${
|
||
retryCount + 1
|
||
}次重试`
|
||
);
|
||
setTimeout(() => {
|
||
this.requestWithRetry(url, maxRetries, callback, retryCount + 1);
|
||
}, (retryCount + 1) * 1000); // 递增延迟重试
|
||
} else {
|
||
callback(false, res.data);
|
||
}
|
||
}
|
||
},
|
||
fail: (err) => {
|
||
// 网络错误时进行重试
|
||
if (retryCount < maxRetries) {
|
||
console.log(
|
||
`网络请求失败,${(retryCount + 1) * 1000}ms后进行第${
|
||
retryCount + 1
|
||
}次重试`
|
||
);
|
||
setTimeout(() => {
|
||
this.requestWithRetry(url, maxRetries, callback, retryCount + 1);
|
||
}, (retryCount + 1) * 1000); // 递增延迟重试
|
||
} else {
|
||
callback(false, err);
|
||
}
|
||
},
|
||
});
|
||
},
|
||
// 显示全屏地图
|
||
showFullScreenMap() {
|
||
this.setData({
|
||
showFullScreenMap: true,
|
||
mapLatitude: this.data.form.latitude || this.data.mapLatitude,
|
||
mapLongitude: this.data.form.longitude || this.data.mapLongitude,
|
||
fullScreenMarkers:
|
||
this.data.form.latitude && this.data.form.longitude
|
||
? [
|
||
{
|
||
id: 1,
|
||
latitude: this.data.form.latitude,
|
||
longitude: this.data.form.longitude,
|
||
title: "考勤点",
|
||
iconPath: "/images/location-marker.png",
|
||
width: 30,
|
||
height: 30,
|
||
},
|
||
]
|
||
: [],
|
||
});
|
||
|
||
// 如果已有坐标,获取地址信息
|
||
if (this.data.form.latitude && this.data.form.longitude) {
|
||
this.getAddressInfo(
|
||
this.data.form.latitude,
|
||
this.data.form.longitude,
|
||
true
|
||
);
|
||
}
|
||
},
|
||
// 隐藏全屏地图
|
||
hideFullScreenMap() {
|
||
this.setData({
|
||
showFullScreenMap: false,
|
||
searchKeyword: "",
|
||
searchResults: [],
|
||
});
|
||
},
|
||
// 全屏地图点击事件
|
||
onFullScreenMapTap(e) {
|
||
const { latitude, longitude } = e.detail;
|
||
this.setData({
|
||
mapLatitude: latitude,
|
||
mapLongitude: longitude,
|
||
fullScreenMarkers: [
|
||
{
|
||
id: 1,
|
||
latitude: latitude,
|
||
longitude: longitude,
|
||
title: "考勤点",
|
||
iconPath: "/images/location-marker.png",
|
||
width: 30,
|
||
height: 30,
|
||
},
|
||
],
|
||
});
|
||
|
||
// 获取点击位置的地址信息
|
||
this.getAddressInfo(latitude, longitude, true);
|
||
},
|
||
// 确认选择的位置
|
||
confirmLocation() {
|
||
this.setData({
|
||
"form.latitude": this.data.mapLatitude,
|
||
"form.longitude": this.data.mapLongitude,
|
||
"form.address": this.data.selectedAddress,
|
||
showFullScreenMap: false,
|
||
markers: [
|
||
{
|
||
id: 1,
|
||
latitude: this.data.mapLatitude,
|
||
longitude: this.data.mapLongitude,
|
||
title: "考勤点",
|
||
iconPath: "/images/location-marker.png",
|
||
width: 30,
|
||
height: 30,
|
||
},
|
||
],
|
||
searchKeyword: "",
|
||
searchResults: [],
|
||
});
|
||
},
|
||
// 搜索输入事件
|
||
onSearchInput(e) {
|
||
this.setData({
|
||
searchKeyword: e.detail.value,
|
||
});
|
||
},
|
||
// 搜索确认事件
|
||
onSearchConfirm() {
|
||
const keyword = this.data.searchKeyword.trim();
|
||
if (!keyword) {
|
||
wx.showToast({
|
||
title: "请输入搜索关键词",
|
||
icon: "none",
|
||
});
|
||
return;
|
||
}
|
||
|
||
// 使用腾讯地图API进行地址搜索
|
||
const apiKey = "NUQBZ-UIYCW-H7GRI-YXOXA-WNZB7-IGFLY";
|
||
const url = `https://apis.map.qq.com/ws/place/v1/suggestion/?keyword=${encodeURIComponent(
|
||
keyword
|
||
)}&key=${apiKey}®ion=全国`;
|
||
|
||
wx.request({
|
||
url: url,
|
||
success: (res) => {
|
||
if (
|
||
res.data.status === 0 &&
|
||
res.data.data &&
|
||
res.data.data.length > 0
|
||
) {
|
||
// 更新搜索结果
|
||
this.setData({
|
||
searchResults: res.data.data,
|
||
});
|
||
} else {
|
||
wx.showToast({
|
||
title: "未找到相关地址",
|
||
icon: "none",
|
||
});
|
||
}
|
||
},
|
||
fail: (err) => {
|
||
console.error("搜索地址失败", err);
|
||
wx.showToast({
|
||
title: "搜索失败,请重试",
|
||
icon: "none",
|
||
});
|
||
},
|
||
});
|
||
},
|
||
// 选择搜索结果
|
||
onSelectSearchResult(e) {
|
||
const item = e.currentTarget.dataset.item;
|
||
const { lat, lng } = item.location;
|
||
|
||
// 更新地图位置
|
||
this.setData({
|
||
mapLatitude: lat,
|
||
mapLongitude: lng,
|
||
fullScreenMarkers: [
|
||
{
|
||
id: 1,
|
||
latitude: lat,
|
||
longitude: lng,
|
||
title: item.title,
|
||
iconPath: "/images/location-marker.png",
|
||
width: 30,
|
||
height: 30,
|
||
},
|
||
],
|
||
searchResults: [], // 清空搜索结果
|
||
searchKeyword: item.title, // 更新搜索框内容
|
||
});
|
||
|
||
// 获取地址信息
|
||
this.getAddressInfo(lat, lng, true);
|
||
},
|
||
onTitleInput(e) {
|
||
this.setData({
|
||
"form.title": e.detail.value,
|
||
});
|
||
},
|
||
onStartDateInput(e) {
|
||
this.setData({
|
||
"form.startDate": e.detail,
|
||
});
|
||
},
|
||
onEndDateInput(e) {
|
||
this.setData({
|
||
"form.endDate": e.detail,
|
||
});
|
||
},
|
||
onAddGroupList(e) {
|
||
if (e.detail.length > 0) {
|
||
let _userIds = "";
|
||
let _userNames = "";
|
||
let groups = [];
|
||
e.detail.forEach((it) => {
|
||
let item = this.data.groupList.find((item) => item.id == it.userId);
|
||
groups.push(item);
|
||
_userIds += "," + item.id;
|
||
_userNames += "," + item.userName; //+ `[${item.subDeptName}]`;
|
||
});
|
||
|
||
this.setData({
|
||
"form.subGroup": groups,
|
||
"form.groupIds": _userIds.substring(1),
|
||
"form.groupNames": _userNames.substring(1),
|
||
});
|
||
} else {
|
||
this.setData({
|
||
"form.subGroup": [],
|
||
"form.groupIds": "",
|
||
"form.groupNames": "",
|
||
});
|
||
}
|
||
},
|
||
onRangeChange(e) {
|
||
// 正确处理步进器的值变化
|
||
this.setData({
|
||
"form.range": e.detail.value,
|
||
});
|
||
},
|
||
|
||
//项目切换 返回值
|
||
onProjectSelect(e) {
|
||
let projectId = e.detail.id;
|
||
let projectName = e.detail.text;
|
||
app.globalData.useProjectId = projectId;
|
||
app.globalData.useProjectName = projectName;
|
||
this.onLoad();
|
||
},
|
||
doBack(isRefresh) {
|
||
/*返回列表页面并刷新*/
|
||
if (isRefresh) {
|
||
wx.redirectTo({
|
||
url: "../list/index",
|
||
});
|
||
} else {
|
||
wx.redirectTo({
|
||
url: "../list/index",
|
||
});
|
||
}
|
||
},
|
||
returnToPage: function () {
|
||
this.doBack(false);
|
||
},
|
||
submitSave() {
|
||
// 数据验证
|
||
if (!this.validateForm()) {
|
||
return;
|
||
}
|
||
let postData = {
|
||
projectId: app.globalData.useProjectId,
|
||
comId: app.globalData.userData.activeComId,
|
||
title: this.data.form.title,
|
||
startDate: this.data.form.startDate,
|
||
endDate: this.data.form.endDate,
|
||
address: this.data.form.address,
|
||
longitude: this.data.form.longitude,
|
||
latitude: this.data.form.latitude,
|
||
valid: 0,
|
||
range: this.data.form.range,
|
||
state: 0,
|
||
remark: "",
|
||
groupList: this.data.form.subGroup.map((it) => {
|
||
return {
|
||
groupId: it.id,
|
||
groupName: it.userName,
|
||
cfgId: -1,
|
||
};
|
||
}),
|
||
};
|
||
addMobileAttendanceConfig(postData).then((res) => {
|
||
if (res.code == 200) {
|
||
app.toast("保存成功!");
|
||
this.doBack(true);
|
||
} else {
|
||
app.toast("保存失败,请重试");
|
||
}
|
||
});
|
||
},
|
||
|
||
/**
|
||
* 表单数据验证
|
||
*/
|
||
validateForm() {
|
||
const form = this.data.form;
|
||
|
||
// 验证考勤标题
|
||
if (!form.title || form.title.trim() === "") {
|
||
wx.showToast({
|
||
title: "请输入考勤标题",
|
||
icon: "none",
|
||
duration: 2000,
|
||
});
|
||
return false;
|
||
}
|
||
|
||
// 验证开始时间
|
||
if (!form.startDate) {
|
||
wx.showToast({
|
||
title: "请选择开始时间",
|
||
icon: "none",
|
||
duration: 2000,
|
||
});
|
||
return false;
|
||
}
|
||
|
||
// 验证结束时间
|
||
if (!form.endDate) {
|
||
wx.showToast({
|
||
title: "请选择结束时间",
|
||
icon: "none",
|
||
duration: 2000,
|
||
});
|
||
return false;
|
||
}
|
||
|
||
// 验证结束时间是否晚于开始时间
|
||
if (form.startDate && form.endDate && form.startDate > form.endDate) {
|
||
wx.showToast({
|
||
title: "结束时间必须晚于开始时间",
|
||
icon: "none",
|
||
duration: 2000,
|
||
});
|
||
return false;
|
||
}
|
||
|
||
// 验证考勤地点
|
||
if (!form.address || form.address.trim() === "") {
|
||
wx.showToast({
|
||
title: "请选择考勤地点",
|
||
icon: "none",
|
||
duration: 2000,
|
||
});
|
||
return false;
|
||
}
|
||
return true;
|
||
},
|
||
});
|