移动端考勤配置开发-配置详情页面

dev_xd
lj7788@126.com 2025-09-01 16:45:24 +08:00
parent 282bdf98d5
commit 4823d75b28
24 changed files with 828 additions and 350 deletions

View File

@ -98,8 +98,18 @@ export default {
this.$bus.$on('projectChange', debounce(res => {
this.prjInfo = res;
//this.getMonitAndWarning();
debugger
this.$api.safety.selectCountForBGByProjectId(res.id).then(d => {
this.loadData();
}));
this.prjInfo = this.$store.getters.selProject;
this.loadData();
},
methods: {
loadData(){
if(!this.prjInfo){
return
}
this.$api.safety.selectCountForBGByProjectId(this.prjInfo.id).then(d => {
this.baseData = d.data || [];
this.warningType[0].total = this.getBaseData("a");
this.warningType[1].total = this.getBaseData("c");
@ -109,9 +119,7 @@ export default {
this.todayCnt = this.getBaseData("g");
this.weekCnt = this.getBaseData("h");
});
}));
},
methods: {
getBaseData(type) {
let tmp = this.baseData.find(item => item.projectName == type);
return tmp ? tmp.id || 0 : 0;

View File

@ -38,7 +38,7 @@ public class ProMobileAttendanceConfig extends BaseEntity
/** 开始时间 */
@JsonFormat(pattern = "yyyy-MM-dd")
@Excel(name = "开始时间", width = 30, dateFormat = "yyyy-MM-dd")
private Date starteDate;
private Date startDate;
/** 结束时间 */
@JsonFormat(pattern = "yyyy-MM-dd")
@ -47,6 +47,24 @@ public class ProMobileAttendanceConfig extends BaseEntity
private List<ProMobileAttendanceConfigGroup> groupList;
private Integer isDel;
public Date getStartDate() {
return startDate;
}
public void setStartDate(Date startDate) {
this.startDate = startDate;
}
public Integer getIsDel() {
return isDel;
}
public void setIsDel(Integer isDel) {
this.isDel = isDel;
}
public List<ProMobileAttendanceConfigGroup> getGroupList() {
return groupList;
}
@ -115,15 +133,7 @@ public class ProMobileAttendanceConfig extends BaseEntity
{
return title;
}
public void setStarteDate(Date starteDate)
{
this.starteDate = starteDate;
}
public Date getStarteDate()
{
return starteDate;
}
public void setEndDate(Date endDate)
{
this.endDate = endDate;
@ -195,7 +205,7 @@ public class ProMobileAttendanceConfig extends BaseEntity
.append("comId", getComId())
.append("projectId", getProjectId())
.append("title", getTitle())
.append("starteDate", getStarteDate())
.append("startDate", getStartDate())
.append("endDate", getEndDate())
.append("address", getAddress())
.append("longitude", getLongitude())

View File

@ -55,6 +55,25 @@ public class ProMobileAttendanceConfigGroup extends BaseEntity
return groupId;
}
private String groupName;
private String deptName;
public String getGroupName() {
return groupName;
}
public void setGroupName(String groupName) {
this.groupName = groupName;
}
public String getDeptName() {
return deptName;
}
public void setDeptName(String deptName) {
this.deptName = deptName;
}
@Override
public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)

View File

@ -2,6 +2,7 @@ package com.yanzhu.manage.mapper;
import java.util.List;
import com.yanzhu.manage.domain.ProMobileAttendanceConfigGroup;
import org.apache.ibatis.annotations.Param;
/**
* Mapper
@ -67,5 +68,5 @@ public interface ProMobileAttendanceConfigGroupMapper
*/
public int deleteProMobileAttendanceConfigGroupByCfgId(Long cfgId);
public int insertProMobileAttendanceConfigGroupBatch(List<ProMobileAttendanceConfigGroup> groupList);
public int insertProMobileAttendanceConfigGroupBatch(@Param("groupList") List<ProMobileAttendanceConfigGroup> groupList);
}

View File

@ -2,6 +2,7 @@ package com.yanzhu.manage.mapper;
import java.util.List;
import com.yanzhu.manage.domain.ProMobileAttendanceConfig;
import org.apache.ibatis.annotations.Param;
/**
* Mapper
@ -58,4 +59,8 @@ public interface ProMobileAttendanceConfigMapper
* @return
*/
public int deleteProMobileAttendanceConfigByIds(Long[] ids);
/**
*
*/
List<Long> selectCountByValid(@Param("projectId") Long projectId);
}

View File

@ -41,7 +41,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<insert id="insertProMobileAttendanceConfigGroupBatch">
insert into pro_mobile_attendance_config_group (cfg_id, group_id)
values
<foreach collection="groupList" item="item" index="index" separator=";">
<foreach collection="groupList" item="item" index="index" separator=",">
(#{item.cfgId}, #{item.groupId})
</foreach>
</insert>

View File

@ -9,7 +9,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="comId" column="com_id" />
<result property="projectId" column="project_id" />
<result property="title" column="title" />
<result property="starteDate" column="starte_date" />
<result property="startDate" column="start_date" />
<result property="endDate" column="end_date" />
<result property="address" column="address" />
<result property="longitude" column="longitude" />
@ -17,37 +17,57 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="valid" column="valid" />
<result property="rang" column="rang" />
<result property="state" column="state" />
<result property="isDel" column="is_del" />
<result property="remark" column="remark" />
<result property="createBy" column="create_by" />
<result property="createTime" column="create_time" />
<result property="updateBy" column="update_by" />
<result property="updateTime" column="update_time" />
<collection property="groupList" ofType="ProMobileAttendanceConfigGroup">
<result property="id" column="group_id"/>
<result property="cfgId" column="cfg_id"/>
<result property="groupId" column="group_id"/>
<result property="groupName" column="group_name"/>
<result property="deptName" column="dept_name"/>
</collection>
</resultMap>
<sql id="selectProMobileAttendanceConfigVo">
select id, com_id, project_id, title, starte_date, end_date, address, longitude, latitude, valid, rang, state, remark, create_by, create_time, update_by, update_time from pro_mobile_attendance_config
select c.id, c.com_id, c.project_id, c.title, c.start_date, c.end_date, c.address, c.longitude, c.latitude, c.valid, c.rang, c.state, c.is_del, c.remark, c.create_by, c.create_time, c.update_by, c.update_time, g.id as group_id, g.cfg_id, g.group_id as group_id, pg.group_name, pg.sub_dept_name as dept_name
from pro_mobile_attendance_config c
left join pro_mobile_attendance_config_group g on c.id=g.cfg_id
left join pro_project_info_subdepts_group pg on g.group_id=pg.id
</sql>
<select id="selectProMobileAttendanceConfigList" parameterType="ProMobileAttendanceConfig" resultMap="ProMobileAttendanceConfigResult">
<include refid="selectProMobileAttendanceConfigVo"/>
<where>
<if test="comId != null "> and com_id = #{comId}</if>
<if test="projectId != null "> and project_id = #{projectId}</if>
<if test="title != null and title != ''"> and title = #{title}</if>
<if test="starteDate != null "> and starte_date = #{starteDate}</if>
<if test="endDate != null "> and end_date = #{endDate}</if>
<if test="address != null and address != ''"> and address = #{address}</if>
<if test="longitude != null "> and longitude = #{longitude}</if>
<if test="latitude != null "> and latitude = #{latitude}</if>
<if test="valid != null "> and valid = #{valid}</if>
<if test="rang != null "> and rang = #{rang}</if>
<if test="state != null "> and state = #{state}</if>
c.is_del = 0
<if test="comId != null "> and c.com_id = #{comId}</if>
<if test="projectId != null "> and c.project_id = #{projectId}</if>
<if test="title != null and title != ''"> and c.title = #{title}</if>
<if test="startDate != null "> and c.start_date = #{startDate}</if>
<if test="endDate != null "> and c.end_date = #{endDate}</if>
<if test="address != null and address != ''"> and c.address = #{address}</if>
<if test="longitude != null "> and c.longitude = #{longitude}</if>
<if test="latitude != null "> and c.latitude = #{latitude}</if>
<choose>
<when test="valid==null or valid==0">and c.valid=0 and date(c.end_date) &gt;=CURRENT_DATE()</when>
<otherwise>and ( c.valid!=0 or date(c.end_date) &lt; CURRENT_DATE() )</otherwise>
</choose>
<if test="rang != null "> and c.rang = #{rang}</if>
<if test="state != null "> and c.state = #{state}</if>
</where>
</select>
<select id="selectCountByValid" resultType="java.lang.Long" parameterType="Long">
select count(1) cnt from pro_mobile_attendance_config where is_del=0 and valid=0 and date(end_date) &gt;=CURRENT_DATE() and project_id = #{projectId}
union
select count(1) cnt from pro_mobile_attendance_config where is_del=0 and ( valid!=0 or date(end_date) &lt; CURRENT_DATE() ) and project_id = #{projectId}
</select>
<select id="selectProMobileAttendanceConfigById" parameterType="Long" resultMap="ProMobileAttendanceConfigResult">
<include refid="selectProMobileAttendanceConfigVo"/>
where id = #{id}
where c.id = #{id}
</select>
<insert id="insertProMobileAttendanceConfig" parameterType="ProMobileAttendanceConfig" useGeneratedKeys="true" keyProperty="id">
@ -56,7 +76,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="comId != null">com_id,</if>
<if test="projectId != null">project_id,</if>
<if test="title != null and title != ''">title,</if>
<if test="starteDate != null">starte_date,</if>
<if test="startDate != null">start_date,</if>
<if test="endDate != null">end_date,</if>
<if test="address != null">address,</if>
<if test="longitude != null">longitude,</if>
@ -64,6 +84,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="valid != null">valid,</if>
<if test="rang != null">rang,</if>
<if test="state != null">state,</if>
<if test="isDel != null">is_del,</if>
<if test="remark != null">remark,</if>
<if test="createBy != null">create_by,</if>
<if test="createTime != null">create_time,</if>
@ -74,7 +95,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="comId != null">#{comId},</if>
<if test="projectId != null">#{projectId},</if>
<if test="title != null and title != ''">#{title},</if>
<if test="starteDate != null">#{starteDate},</if>
<if test="startDate != null">#{startDate},</if>
<if test="endDate != null">#{endDate},</if>
<if test="address != null">#{address},</if>
<if test="longitude != null">#{longitude},</if>
@ -82,6 +103,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="valid != null">#{valid},</if>
<if test="rang != null">#{rang},</if>
<if test="state != null">#{state},</if>
<if test="isDel != null">#{isDel},</if>
<if test="remark != null">#{remark},</if>
<if test="createBy != null">#{createBy},</if>
<if test="createTime != null">#{createTime},</if>
@ -96,7 +118,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="comId != null">com_id = #{comId},</if>
<if test="projectId != null">project_id = #{projectId},</if>
<if test="title != null and title != ''">title = #{title},</if>
<if test="starteDate != null">starte_date = #{starteDate},</if>
<if test="startDate != null">start_date = #{startDate},</if>
<if test="endDate != null">end_date = #{endDate},</if>
<if test="address != null">address = #{address},</if>
<if test="longitude != null">longitude = #{longitude},</if>
@ -104,6 +126,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="valid != null">valid = #{valid},</if>
<if test="rang != null">rang = #{rang},</if>
<if test="state != null">state = #{state},</if>
<if test="isDel != null">is_del = #{isDel},</if>
<if test="remark != null">remark = #{remark},</if>
<if test="createBy != null">create_by = #{createBy},</if>
<if test="createTime != null">create_time = #{createTime},</if>

View File

@ -528,9 +528,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="infoType != null "> and dic.remark = #{infoType}</if>
</select>
<select id="selectCountForBGByProjectId" parameterType="Long" resultMap="SmzSspProblemmodifyResult">
SELECT 'a' projectName, count(1) id,'全部' remark from smz_ssp_problemmodify where projectId=#{projectId} and isDel=0
union
SELECT 'b' projectName, count(1) id,'全部已完成' remark from smz_ssp_problemmodify where projectId=#{projectId} and isDel=0 and checkState not in (4)
SELECT 'a' projectName, count(1) id,'AI全部' remark from dev_ai_project_data where project_id=#{projectId} and is_del!=2
UNION
SELECT 'c' projectName, count(1) id,'安全全部' remark from smz_ssp_problemmodify where projectId=#{projectId} and isDel=0 and infoType=0
UNION

View File

@ -49,6 +49,15 @@ public class ProMobileAttendanceConfigController extends BaseController
return getDataTable(list);
}
/**
*
*/
@RequiresPermissions("manage:mobileAttendConfig:list")
@GetMapping("/selectCountByValid")
public AjaxResult selectCountByValid(Long projectId){
List<Long> list=proMobileAttendanceConfigService.selectCountByValid(projectId);
return AjaxResult.success(list);
}
/**
*
*/

View File

@ -58,4 +58,9 @@ public interface IProMobileAttendanceConfigService
* @return
*/
public int deleteProMobileAttendanceConfigById(Long id);
/**
*
*/
List<Long> selectCountByValid(Long projectId);
}

View File

@ -124,4 +124,11 @@ public class ProMobileAttendanceConfigServiceImpl implements IProMobileAttendanc
{
return proMobileAttendanceConfigMapper.deleteProMobileAttendanceConfigById(id);
}
/**
*
*/
@Override
public List<Long> selectCountByValid(Long projectId) {
return proMobileAttendanceConfigMapper.selectCountByValid(projectId);
}
}

View File

@ -429,3 +429,56 @@ export function countTechByStatus(query) {
method: "get",
});
}
/**
* 增加移动考勤配置
*/
export function addMobileAttendanceConfig(data) {
return request({
url: "/manage/mobileAttendConfig",
method: "post",
data: data,
});
}
/**
* 修改移动考勤配置
*/
export function updateMobileAttendanceConfig(data) {
return request({
url: "/manage/mobileAttendConfig",
method: "put",
data: data,
});
}
/**
* 获取移动考勤配置
*/
export function getMobileAttendanceConfig(data) {
return request({
url: "/manage/mobileAttendConfig/list",
method: "get",
params: data,
});
}
/**
* 获取有效和无效数据量
*/
export function selectMobileAttendanceCountByValid(data) {
return request({
url: "/manage/mobileAttendConfig/selectCountByValid",
method: "get",
params: data,
});
}
/**
* 获取移动考勤配置详情
*/
export function getMobileAttendanceConfigById(id) {
return request({
url: "/manage/mobileAttendConfig/" + id,
method: "get",
});
}

View File

@ -47,7 +47,8 @@
"project_checked/info/index",
"mobile_attendance/attendance/index",
"mobile_attendance/attendance_config/list/index",
"mobile_attendance/attendance_config/add/index"
"mobile_attendance/attendance_config/add/index",
"mobile_attendance/attendance_config/info/index"
],
"independent": false
}

View File

@ -0,0 +1,7 @@
<svg class="icon"
style="width: 1em;height: 1em;vertical-align: middle;fill: currentColor;overflow: hidden;"
viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
p-id="6196">
<path d="M864 192H704v-64h-64v64H384v-64h-64v64H160c-17.6 0-32 14.4-32 32v640c0 17.6 14.4 32 32 32h704c17.6 0 32-14.4 32-32V224c0-17.6-14.4-32-32-32z m-32 640H192V384h640v448zM403.2 707.2L320.8 624.8l45.6-45.6L448 661.6l210.4-210.4 45.6 45.6-210.4 210.4L448 752l-44.8-44.8z"
fill="#ccc" p-id="6197"></path>
</svg>

After

Width:  |  Height:  |  Size: 516 B

View File

@ -2,11 +2,13 @@
import { getToken, getUserInfo } from "../../../../utils/auth";
import { uploadFiles } from "../../../utils/upload.js";
import { tryToJson } from '../../../utils/tools'
import { findSubGroupsList, subdeptsList } from '../../../../api/project'
import { tryToJson } from "../../../utils/tools";
import {
findDictCache
} from '../../../../api/publics'
findSubGroupsList,
subdeptsList,
addMobileAttendanceConfig,
} from "../../../../api/project";
import { findDictCache } from "../../../../api/publics";
const app = getApp();
// 添加防抖变量避免频繁请求API
@ -25,15 +27,15 @@ Page({
projectName: "",
initData: {},
form: {
title: '',
startDate: '',
endDate: '',
title: "",
startDate: "",
endDate: "",
longitude: 0,
latitude: 0,
range: 50,
address: '',
address: "",
subGroup: [],
groupIds: '',
groupIds: "",
groupNames: [],
},
markers: [],
@ -42,13 +44,15 @@ Page({
mapLongitude: 0,
mapLatitude: 0,
fullScreenMarkers: [],
selectedAddress: '',
selectedAddress: "",
// 搜索相关数据
searchKeyword: '',
searchKeyword: "",
searchResults: [],
subGroupList: [],
groupList: [],
subDeptTypeList: [],
// 添加成功标识
isAddSuccess: false,
},
/**
@ -75,23 +79,23 @@ Page({
this.getSubGroupList();
},
getSubGroupList() {
findDictCache("sub_dept_type").then(dict => {
findDictCache("sub_dept_type").then((dict) => {
this.setData({
subDeptTypeList: dict.data
})
subDeptTypeList: dict.data,
});
findSubGroupsList({
projectId: app.globalData.useProjectId,
pageNum: 1,
pageSize: 1000,
}).then(res => {
}).then((res) => {
if (res.code == 200) {
let tmps = res.rows || [];
this.setData({
groupList: tmps
})
groupList: tmps,
});
let obj = {};
tmps.forEach(it => {
let name = it.subDeptType == 1 ? '施工单位' : it.subDeptName;
tmps.forEach((it) => {
let name = it.subDeptType == 1 ? "施工单位" : it.subDeptName;
if (!obj[name]) {
obj[name] = [it];
} else {
@ -100,19 +104,21 @@ Page({
});
let subGroupList = [];
for (let key in obj) {
let val = obj[key][0]
let deptType = this.data.subDeptTypeList.find(dict => dict.dictValue == val.subDeptType)
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 => {
subDeptTypeName: deptType?.dictLabel || "",
userList: obj[key].map((it) => {
it.status = false;
it.userId = it.id;
it.userName = it.groupName;
return it;
})
}),
});
}
this.setData({
@ -125,37 +131,37 @@ Page({
// 获取用户当前位置
getUserLocation() {
wx.getLocation({
type: 'gcj02', // 腾讯地图坐标系
type: "gcj02", // 腾讯地图坐标系
success: (res) => {
const { latitude, longitude } = res;
// 设置地图初始位置
this.setData({
mapLatitude: latitude,
mapLongitude: longitude,
'form.latitude': latitude,
'form.longitude': longitude
"form.latitude": latitude,
"form.longitude": longitude,
});
// 获取地址信息
this.getAddressInfo(latitude, longitude);
},
fail: (err) => {
console.error('获取位置失败', err);
console.error("获取位置失败", err);
wx.showToast({
title: '请允许位置权限',
icon: 'none'
title: "请允许位置权限",
icon: "none",
});
// 引导用户开启权限
setTimeout(() => {
wx.openSetting({
success: (setting) => {
if (setting.authSetting['scope.userLocation']) {
if (setting.authSetting["scope.userLocation"]) {
this.getUserLocation();
}
}
},
});
}, 1500);
}
},
});
},
// 获取地址信息(逆地理编码)- 带重试机制
@ -163,46 +169,46 @@ Page({
const now = Date.now();
// 检查请求间隔,避免频繁请求
if (now - lastRequestTime < REQUEST_INTERVAL) {
console.log('请求过于频繁,跳过本次请求');
console.log("请求过于频繁,跳过本次请求");
return;
}
lastRequestTime = now;
// 使用腾讯地图API进行逆地理编码
// 注意需要替换为你自己的腾讯地图API密钥
const apiKey = 'NUQBZ-UIYCW-H7GRI-YXOXA-WNZB7-IGFLY';
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 || '获取地址失败';
const address = data.result.address || "获取地址失败";
if (isFullScreen) {
// 全屏地图模式下更新选中地址
this.setData({
selectedAddress: address
selectedAddress: address,
});
} else {
// 普通模式下更新表单地址
this.setData({
"form.address": address
"form.address": address,
});
}
} else {
console.error('逆地理编码失败', data);
const errorMsg = '获取地址失败';
console.error("逆地理编码失败", data);
const errorMsg = "获取地址失败";
if (isFullScreen) {
this.setData({
selectedAddress: errorMsg
selectedAddress: errorMsg,
});
} else {
this.setData({
"form.address": errorMsg
"form.address": errorMsg,
});
}
wx.showToast({
title: '地址获取失败,请手动输入',
icon: 'none'
title: "地址获取失败,请手动输入",
icon: "none",
});
}
});
@ -216,8 +222,16 @@ Page({
callback(true, res.data);
} else {
// 如果是因为请求频率限制导致的失败,进行重试
if (res.data.message && res.data.message.includes('请求量') && retryCount < maxRetries) {
console.log(`请求失败,${(retryCount + 1) * 1000}ms后进行第${retryCount + 1}次重试`);
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); // 递增延迟重试
@ -229,14 +243,18 @@ Page({
fail: (err) => {
// 网络错误时进行重试
if (retryCount < maxRetries) {
console.log(`网络请求失败,${(retryCount + 1) * 1000}ms后进行第${retryCount + 1}次重试`);
console.log(
`网络请求失败,${(retryCount + 1) * 1000}ms后进行第${
retryCount + 1
}次重试`
);
setTimeout(() => {
this.requestWithRetry(url, maxRetries, callback, retryCount + 1);
}, (retryCount + 1) * 1000); // 递增延迟重试
} else {
callback(false, err);
}
}
},
});
},
// 显示全屏地图
@ -245,28 +263,37 @@ Page({
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 ? [{
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',
title: "考勤点",
iconPath: "/images/location-marker.png",
width: 30,
height: 30
}] : []
height: 30,
},
]
: [],
});
// 如果已有坐标,获取地址信息
if (this.data.form.latitude && this.data.form.longitude) {
this.getAddressInfo(this.data.form.latitude, this.data.form.longitude, true);
this.getAddressInfo(
this.data.form.latitude,
this.data.form.longitude,
true
);
}
},
// 隐藏全屏地图
hideFullScreenMap() {
this.setData({
showFullScreenMap: false,
searchKeyword: '',
searchResults: []
searchKeyword: "",
searchResults: [],
});
},
// 全屏地图点击事件
@ -275,15 +302,17 @@ Page({
this.setData({
mapLatitude: latitude,
mapLongitude: longitude,
fullScreenMarkers: [{
fullScreenMarkers: [
{
id: 1,
latitude: latitude,
longitude: longitude,
title: '考勤点',
iconPath: '/images/location-marker.png',
title: "考勤点",
iconPath: "/images/location-marker.png",
width: 30,
height: 30
}]
height: 30,
},
],
});
// 获取点击位置的地址信息
@ -292,27 +321,29 @@ Page({
// 确认选择的位置
confirmLocation() {
this.setData({
'form.latitude': this.data.mapLatitude,
'form.longitude': this.data.mapLongitude,
'form.address': this.data.selectedAddress,
"form.latitude": this.data.mapLatitude,
"form.longitude": this.data.mapLongitude,
"form.address": this.data.selectedAddress,
showFullScreenMap: false,
markers: [{
markers: [
{
id: 1,
latitude: this.data.mapLatitude,
longitude: this.data.mapLongitude,
title: '考勤点',
iconPath: '/images/location-marker.png',
title: "考勤点",
iconPath: "/images/location-marker.png",
width: 30,
height: 30
}],
searchKeyword: '',
searchResults: []
height: 30,
},
],
searchKeyword: "",
searchResults: [],
});
},
// 搜索输入事件
onSearchInput(e) {
this.setData({
searchKeyword: e.detail.value
searchKeyword: e.detail.value,
});
},
// 搜索确认事件
@ -320,38 +351,44 @@ Page({
const keyword = this.data.searchKeyword.trim();
if (!keyword) {
wx.showToast({
title: '请输入搜索关键词',
icon: 'none'
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}&region=全国`;
const apiKey = "NUQBZ-UIYCW-H7GRI-YXOXA-WNZB7-IGFLY";
const url = `https://apis.map.qq.com/ws/place/v1/suggestion/?keyword=${encodeURIComponent(
keyword
)}&key=${apiKey}&region=全国`;
wx.request({
url: url,
success: (res) => {
if (res.data.status === 0 && res.data.data && res.data.data.length > 0) {
if (
res.data.status === 0 &&
res.data.data &&
res.data.data.length > 0
) {
// 更新搜索结果
this.setData({
searchResults: res.data.data
searchResults: res.data.data,
});
} else {
wx.showToast({
title: '未找到相关地址',
icon: 'none'
title: "未找到相关地址",
icon: "none",
});
}
},
fail: (err) => {
console.error('搜索地址失败', err);
console.error("搜索地址失败", err);
wx.showToast({
title: '搜索失败,请重试',
icon: 'none'
title: "搜索失败,请重试",
icon: "none",
});
}
},
});
},
// 选择搜索结果
@ -363,17 +400,19 @@ Page({
this.setData({
mapLatitude: lat,
mapLongitude: lng,
fullScreenMarkers: [{
fullScreenMarkers: [
{
id: 1,
latitude: lat,
longitude: lng,
title: item.title,
iconPath: '/images/location-marker.png',
iconPath: "/images/location-marker.png",
width: 30,
height: 30
}],
height: 30,
},
],
searchResults: [], // 清空搜索结果
searchKeyword: item.title // 更新搜索框内容
searchKeyword: item.title, // 更新搜索框内容
});
// 获取地址信息
@ -381,49 +420,49 @@ Page({
},
onTitleInput(e) {
this.setData({
'form.title': e.detail.value
})
"form.title": e.detail.value,
});
},
onStartDateInput(e) {
this.setData({
'form.startDate': e.detail.value
})
"form.startDate": e.detail,
});
},
onEndDateInput(e) {
this.setData({
'form.endDate': e.detail.value
})
"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);
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}]`;
_userNames += "," + item.userName; //+ `[${item.subDeptName}]`;
});
this.setData({
"form.subGroup": groups,
"form.groupIds": _userIds.substring(1),
"form.groupNames": _userNames.substring(1)
})
"form.groupNames": _userNames.substring(1),
});
} else {
this.setData({
"form.subGroup": [],
"form.groupIds": "",
"form.groupNames": ""
})
"form.groupNames": "",
});
}
},
onRangeChange(e) {
// 正确处理步进器的值变化
this.setData({
'form.range': e.detail.value
})
"form.range": e.detail.value,
});
},
//项目切换 返回值
@ -437,19 +476,109 @@ Page({
doBack(isRefresh) {
/*返回列表页面并刷新*/
if (isRefresh) {
wx.navigateBack({
delta: 1
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;
},
});

View File

@ -31,7 +31,7 @@
<view class="markers inspect_info_title">开始时间</view>
<view class="inspect_info_content">
<voucher-date counts="5" placeholder="请选择开始时间" time="{{form.startDate}}" minDate="{{ minDate }}"
maxDate="{{ maxDate||form.endDate }}" bindchange="onStartDateInput"></voucher-date>
maxDate="{{ maxDate }}" bindchange="onStartDateInput"></voucher-date>
</view>
</view>
@ -39,7 +39,7 @@
<view class="markers inspect_info_title">结束时间</view>
<view class="inspect_info_content">
<voucher-date counts="5" wx:key="form.startDate" placeholder="请选择结束时间" time="{{form.endDate}}"
minDate="{{ form.startDate||minDate }}" maxDate="{{ maxDate }}" bindchange="onEndDateInput"></voucher-date>
minDate="{{ minDate }}" maxDate="{{ maxDate }}" bindchange="onEndDateInput"></voucher-date>
</view>
</view>
@ -61,14 +61,14 @@
</view>
<view class=" inspect_info_list">
<view class="markers inspect_info_title">指定考勤班组</view>
<view class="inspect_info_title">指定考勤班组</view>
<view class="inspect_info_content">
<select-group-person rectifierData="{{subGroupList}}" multiple="{{true}}" bindselected="onAddGroupList"
index="3" :title="{{form.groupNames?form.groupNames:'请选择考勤班组'}}" choose="{{form.groupNames}}">
</select-group-person>
</view>
<view wx:if="{{form.subGroup && form.subGroup.length>0}}">
<view wx:for="{{form.subGroup}}" wx:key="item.id">
<view wx:for="{{form.subGroup}}" wx:key="id">
{{item.groupName}} <view class="dept-name"> [{{item.subDeptName}}]</view>
</view>
</view>

View File

@ -0,0 +1,104 @@
import { getToken, getUserInfo } from "../../../../utils/auth.js";
const app = getApp();
import { getMobileAttendanceConfigById } from "../../../../api/project.js";
Page({
/**
* 页面的初始数据
*/
data: {
projectUserInfo: {},
projectUserInfo: {},
projectId: "",
projectName: "",
initData: {},
type: "",
cfgData: null,
},
/**
* 生命周期函数--监听页面加载
*/
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,
},
type: options.type,
});
if (options.id) {
this.loadData(options.id);
} else {
app.toast("参数错误!");
this.returnToPage();
}
},
loadData(id) {
getMobileAttendanceConfigById(id).then((res) => {
if (res.code == 200) {
this.setData({
cfgData: res.data,
});
} else {
app.toast("参数错误!");
this.returnToPage();
}
});
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady() {},
/**
* 生命周期函数--监听页面显示
*/
onShow() {},
/**
* 生命周期函数--监听页面隐藏
*/
onHide() {},
/**
* 生命周期函数--监听页面卸载
*/
onUnload() {},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh() {},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom() {},
/**
* 用户点击右上角分享
*/
onShareAppMessage() {},
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",
});
},
});

View File

@ -0,0 +1,6 @@
{
"usingComponents": {},
"navigationStyle": "custom",
"styleIsolation": "apply-shared",
"backgroundColor": "#191d28"
}

View File

@ -0,0 +1,19 @@
<wxs module="format" src="/utils/format.wxs"></wxs>
<view class="header_title">
<view class="header_title_row">
<van-row>
<van-col span="4">
<view class="header_img" bindtap="returnToPage">
<image src="/images/left.png"></image>
</view>
</van-col>
<van-col span="15">
<view class="header_name">移动考勤配置详情</view>
</van-col>
</van-row>
</view>
</view>
<scroll-view class="max_content_scroll" type="list" scroll-y bindscrolltolower="onScrollToLower">
<project-select init="{{ initData }}" bindchange="onProjectSelect" id="projectSel"></project-select>
</scroll-view>

View File

@ -0,0 +1 @@
/* pageage/mobile_attendance/attendance_config/info/index.wxss */

View File

@ -3,13 +3,10 @@ import config from "../../../../config.js";
import fmt from "../../../utils/date.js";
import { getToken, getUserInfo } from "../../../../utils/auth.js";
import { uploadFiles } from "../../../utils/upload.js";
import { tryToJson } from '../../../utils/tools.js'
import { tryToJson } from "../../../utils/tools.js";
import {
getProjectChecked,
findPlanDatas,
listProProjectInfoSubdeptsUsers,
updateProjectChecked,
addProjectChecked,
getMobileAttendanceConfig,
selectMobileAttendanceCountByValid,
} from "../../../../api/project.js";
const app = getApp();
@ -26,9 +23,10 @@ Page({
initData: {},
listData: [],
counts: [0, 0],
activeState: 'vaild',
activeState: "vaild",
pageNum: 1,
pageSize: 10,
total: 0,
},
/**
@ -50,14 +48,28 @@ Page({
text: app.globalData.useProjectName,
},
});
this.getCount();
this.getListData();
},
getCount() {
selectMobileAttendanceCountByValid({
projectId: app.globalData.useProjectId,
}).then((res) => {
let tmps = res.data || [];
if (tmps.length == 2) {
this.setData({
counts: tmps,
});
}
});
},
switchTabJump(e) {
let index = e.currentTarget.dataset.index;
let nav = "";
if (index == 1) {
nav = 'vaild';
nav = "vaild";
} else {
nav = 'invalid';
nav = "invalid";
}
if (nav != this.data.activeState) {
this.setData({
@ -66,48 +78,41 @@ Page({
pageSize: 10,
listData: [],
});
//this.getListData();
this.getListData();
}
},
getListData() {
//TODO 获取列表数据
console.log("===>获取列表数据");
let data = {
projectId: app.globalData.useProjectId,
pageNum: this.data.pageNum,
pageSize: this.data.pageSize,
valid: this.data.activeState == "vaild" ? 0 : 1,
};
getMobileAttendanceConfig(data).then((res) => {
if (res.code == 200) {
this.setData({
total: res.total,
listData: this.data.listData.concat(res.rows),
});
}
});
},
/**
* 增加
*/
doAddCfg() {
wx.redirectTo({
url: '../add/index',
wx.navigateTo({
url: "../add/index",
});
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady() { },
/**
* 生命周期函数--监听页面显示
*/
onShow() { },
/**
* 生命周期函数--监听页面隐藏
*/
onHide() { },
/**
* 生命周期函数--监听页面卸载
*/
onUnload() { },
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh() { },
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom() { },
getInfo(e) {
wx.redirectTo({
url: `../info/index?type=cfg&id=${e.currentTarget.dataset.set.id}`,
});
},
/**
* 用户点击右上角分享
*/
@ -122,14 +127,25 @@ Page({
},
returnToPage() {
/*关闭当前页面,跳转到其它页面。*/
if (wx.getStorageSync('nav-menu') == "xmgl") {
if (wx.getStorageSync("nav-menu") == "xmgl") {
wx.redirectTo({
url: '../../../project_more/index',
})
url: "../../../project_more/index",
});
} else {
wx.redirectTo({
url: '../../../project_quality/index',
})
url: "../../../project_quality/index",
});
}
},
onScrollToLower() {
let nal = Math.ceil(this.data.total / this.data.pageSize);
if (this.data.pageNum < nal) {
this.setData({
pageNum: this.data.pageNum + 1,
});
this.getListData(this.data.activeState);
} else {
console.log("已经到底了,没有数据可加载!!!");
}
},
});

View File

@ -1,5 +1,7 @@
{
"usingComponents": {},
"usingComponents": {
"svg-icon": "/pageage/components/svg-icon/index"
},
"navigationStyle": "custom",
"styleIsolation": "apply-shared",
"backgroundColor": "#191d28"

View File

@ -15,7 +15,7 @@
</view>
</view>
<scroll-view class="max_content_scroll" type="list" scroll-y>
<scroll-view class="max_content_scroll" type="list" scroll-y bindscrolltolower="onScrollToLower">
<project-select init="{{ initData }}" bindchange="onProjectSelect" id="projectSel"></project-select>
@ -28,13 +28,49 @@
</view>
</view>
<view wx:if="{{listData.length==0}}">
<view style="padding-top: 70px;text-align: -webkit-center;">
<image src="https://szgcwx.jhncidg.com/staticFiles/nodata.png" style="width: 130px;height: 105px;"></image>
<view style="color: #a5abbb;">暂无数据</view>
</view>
</view>
<view class="inspect_max_scroll" wx:else>
<view class="inspect_for_scroll" wx:for="{{ listData }}" wx:key="index" data-set="{{ item }}" bindtap="getInfo">
<view class="inspect_for_bgd">
<view class="inspect_list_title">
<view class="inspect_list_title_number">{{
index < 10 ? "0" + (index + 1) : index + 1 }}</view>
<view class="module_title">
</view>
</view>
<view class="inspect_list_content">
<svg-icon src="attendance" color="#45affb" size="140" />
<view class="content-right">
<view class="content-row first">
考勤标题:
{{item.title}}
</view>
<view class="content-row">
开始时间:
{{item.startDate}}
</view>
<view class="content-row">
结束时间:
{{item.endDate}}
</view>
<view class="content-row">
考勤位置:
{{item.address}}
</view>
</view>
</view>
</view>
</view>
</view>
<view class="inspect_add_to" bindtap="doAddCfg">

View File

@ -1 +1,20 @@
/* pageage/mobile_attendance/attendance_config/index.wxss */
.inspect_list_title{
justify-content: left;
}
.inspect_list_content{
display: flex;
padding-top: 20rpx;
}
.content-right{
padding-left: 20rpx;
line-height: 40rpx;
}
.content-row{
font-size:24rpx;
}
.content-row.first{
color: #03a9f4;
}