Commit 11bbcb58 authored by 赵啸非's avatar 赵啸非

添加钉钉对接流程代码

parent b3d46e7c
......@@ -23,6 +23,7 @@
<profiles.log.path>/home/mortals/app/logs</profiles.log.path>
<profiles.log.level>info</profiles.log.level>
<profiles.publish.path>/home/publish</profiles.publish.path>
<profiles.source.type>hik</profiles.source.type>
<profiles.hik.host></profiles.hik.host>
<profiles.hik.protocol></profiles.hik.protocol>
<profiles.hik.appKey></profiles.hik.appKey>
......@@ -38,8 +39,10 @@
<profiles.dingtalk.opUserId></profiles.dingtalk.opUserId>
<profiles.webUrl></profiles.webUrl>
<package.environment>build</package.environment>
<profiles.nacos.server-addr>127.0.0.1:8848</profiles.nacos.server-addr>
<profiles.nacos.group>DEFAULT_GROUP</profiles.nacos.group>
<profiles.nacos.namespace>smart-gov</profiles.nacos.namespace>
<skipUi>ture</skipUi>
</properties>
<profiles>
......@@ -47,10 +50,8 @@
<id>develop</id>
<properties>
<profiles.active>develop</profiles.active>
<profiles.nacos.server-addr>127.0.0.1:8848</profiles.nacos.server-addr>
<profiles.sms.smsSendUrl>http://127.0.0.1:8089/api/index/index</profiles.sms.smsSendUrl>
<profiles.sms.apiId>k6BVS1PEbyzcJAE4</profiles.sms.apiId>
<skipUi>ture</skipUi>
</properties>
</profile>
<profile>
......@@ -58,10 +59,8 @@
<properties>
<profiles.active>test</profiles.active>
<profiles.server.debug>-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=51750</profiles.server.debug>
<profiles.nacos.server-addr>192.168.0.252:8848</profiles.nacos.server-addr>
<profiles.sms.smsSendUrl>http://127.0.0.1:8089/api/index/index</profiles.sms.smsSendUrl>
<profiles.sms.apiId>k6BVS1PEbyzcJAE4</profiles.sms.apiId>
<skipUi>ture</skipUi>
</properties>
</profile>
......@@ -69,11 +68,9 @@
<id>product</id>
<properties>
<profiles.active>product</profiles.active>
<profiles.nacos.server-addr>127.0.0.1:8848</profiles.nacos.server-addr>
<profiles.sms.smsSendUrl>http://127.0.0.1:8089/api/index/index</profiles.sms.smsSendUrl>
<profiles.server.debug>-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=51750</profiles.server.debug>
<profiles.sms.apiId>k6BVS1PEbyzcJAE4</profiles.sms.apiId>
<skipUi>ture</skipUi>
</properties>
</profile>
<profile>
......@@ -99,8 +96,6 @@
<profiles.dingtalk.token>m3WeuVx5kcTY76kh22uWZOTSu0XjvcwNhd</profiles.dingtalk.token>
<profiles.dingtalk.opUserId>254868153920685466</profiles.dingtalk.opUserId>
<profiles.webUrl>https://ybswxxcx.zwfwhfgjjfzj.yibin.gov.cn/performance-h5</profiles.webUrl>
<package.environment>build</package.environment>
<skipUi>ture</skipUi>
</properties>
</profile>
......@@ -108,17 +103,12 @@
<id>reg</id>
<properties>
<profiles.active>reg</profiles.active>
<profiles.nacos.server-addr>127.0.0.1:8848</profiles.nacos.server-addr>
<profiles.nacos.group>DEFAULT_GROUP</profiles.nacos.group>
<profiles.nacos.namespace>smart-gov</profiles.nacos.namespace>
<profiles.sms.smsSendUrl>http://sms.wx3.com.cn/api/index/index</profiles.sms.smsSendUrl>
<profiles.sms.apiId>ADsUXLrS81vZDU95</profiles.sms.apiId>
<profiles.hik.host>10.207.153.105:443</profiles.hik.host>
<profiles.hik.protocol>https://</profiles.hik.protocol>
<profiles.hik.appKey>25594054</profiles.hik.appKey>
<profiles.hik.appSecret>K12IkZoSLxpsJjrUPtfV</profiles.hik.appSecret>
<package.environment>build</package.environment>
<skipUi>true</skipUi>
</properties>
</profile>
......@@ -127,16 +117,12 @@
<properties>
<profiles.active>yanyuan</profiles.active>
<profiles.nacos.server-addr>172.16.30.245:8848</profiles.nacos.server-addr>
<profiles.nacos.group>DEFAULT_GROUP</profiles.nacos.group>
<profiles.nacos.namespace>smart-gov</profiles.nacos.namespace>
<profiles.sms.smsSendUrl>http://sms.wx3.com.cn/api/index/index</profiles.sms.smsSendUrl>
<profiles.sms.apiId>ADsUXLrS81vZDU95</profiles.sms.apiId>
<profiles.hik.host>172.16.30.240:443</profiles.hik.host>
<profiles.hik.protocol>https://</profiles.hik.protocol>
<profiles.hik.appKey>25444489</profiles.hik.appKey>
<profiles.hik.appSecret>QoBF7sD2zrKHabqmeoEP</profiles.hik.appSecret>
<package.environment>build</package.environment>
<skipUi>true</skipUi>
</properties>
</profile>
......@@ -144,12 +130,10 @@
<id>pengxi</id>
<properties>
<profiles.active>pengxi</profiles.active>
<profiles.source.type>hik-device</profiles.source.type>
<profiles.nacos.server-addr>192.168.106.6:8848</profiles.nacos.server-addr>
<profiles.nacos.group>DEFAULT_GROUP</profiles.nacos.group>
<profiles.nacos.namespace>smart-gov</profiles.nacos.namespace>
<profiles.sms.smsSendUrl>http://sms.wx3.com.cn/api/index/index</profiles.sms.smsSendUrl>
<profiles.sms.apiId>ADsUXLrS81vZDU95</profiles.sms.apiId>
<skipUi>true</skipUi>
</properties>
</profile>
......@@ -157,7 +141,6 @@
<id>bzjkq</id>
<properties>
<profiles.active>bzjkq</profiles.active>
<profiles.nacos.server-addr>127.0.0.1:8848</profiles.nacos.server-addr>
<profiles.sms.smsSendUrl>http://sms.wx3.com.cn/api/index/index</profiles.sms.smsSendUrl>
<profiles.sms.apiId>ADsUXLrS81vZDU95</profiles.sms.apiId>
</properties>
......@@ -167,12 +150,31 @@
<id>qiling</id>
<properties>
<profiles.active>qiling</profiles.active>
<profiles.nacos.server-addr>127.0.0.1:8848</profiles.nacos.server-addr>
<profiles.sms.smsSendUrl>http://sms.wx3.com.cn/api/index/index</profiles.sms.smsSendUrl>
<profiles.sms.apiId>ADsUXLrS81vZDU95</profiles.sms.apiId>
</properties>
</profile>
<profile>
<id>qionglai</id>
<properties>
<profiles.active>qionglai</profiles.active>
<profiles.source.type>dingtalk</profiles.source.type>
<profiles.sms.smsSendUrl>http://sms.wx3.com.cn/api/index/index</profiles.sms.smsSendUrl>
<profiles.sms.apiId>ADsUXLrS81vZDU95</profiles.sms.apiId>
<profiles.dingtalk.domain>https://oapi.dingtalk.com</profiles.dingtalk.domain>
<profiles.dingtalk.oaScheme>http</profiles.dingtalk.oaScheme>
<profiles.dingtalk.oaUrl>https://oapi.dingtalk.com</profiles.dingtalk.oaUrl>
<profiles.dingtalk.agentId>2652674890</profiles.dingtalk.agentId>
<profiles.dingtalk.appKey>dingvbzaw1176pbzo1zx</profiles.dingtalk.appKey>
<profiles.dingtalk.appSecret>jmKqKPDLR3BxdZT_QNX4pm6zDdtbaLI3PtsFymQ6tUle-uKUgmxtr_a6ys3b8v3Y</profiles.dingtalk.appSecret>
<profiles.dingtalk.aesKey>1QcPYuSpAc98OS3qQwwx5HPH85CZDidxF95yBGad2fJ</profiles.dingtalk.aesKey>
<profiles.dingtalk.token>m3WeuVx5kcTY76kh22uWZOTSu0XjvcwNhd</profiles.dingtalk.token>
<profiles.dingtalk.opUserId>254868153920685466</profiles.dingtalk.opUserId>
</properties>
</profile>
</profiles>
<dependencies>
......
......@@ -132,7 +132,12 @@ public class TestController {
List<AttendanceRecordHikEntity> attRecords = doorEventsRest.getData().getList().stream().map(item -> {
AttendanceRecordHikEntity recordHikEntity = new AttendanceRecordHikEntity();
recordHikEntity.initAttrValue();
StaffEntity staffCache = staffService.getExtCache(StrUtil.padPre(item.getJobNo(), 8, "0"));
String workNum = item.getJobNo();
if(item.getJobNo().length()<8){
workNum = StrUtil.padPre(item.getJobNo(), 8, "0");
}
StaffEntity staffCache = staffService.getExtCache(workNum);
//StaffEntity staffCache = staffService.getExtCache(StrUtil.padPre(item.getJobNo(), 8, "0"));
if (ObjectUtils.isEmpty(staffCache)) {
log.info("staff is null !staffCode:{}", item.getJobNo());
return null;
......
package com.mortals.xhx.common.code;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* 考勤来源类型枚举
*
* @author zxfei
*/
public enum AttendSourceTypeEnum {
海康云平台("hik", "海康云平台"),
海康考勤机("hik-device", "海康考勤机"),
钉钉("dingtalk", "钉钉");
private String value;
private String desc;
AttendSourceTypeEnum(String value, String desc) {
this.value = value;
this.desc = desc;
}
public String getValue() {
return this.value;
}
public String getDesc() {
return this.desc;
}
public static AttendSourceTypeEnum getByValue(String value) {
for (AttendSourceTypeEnum typeEnum : AttendSourceTypeEnum.values()) {
if (typeEnum.getValue() == value) {
return typeEnum;
}
}
return null;
}
/**
* 获取Map集合
*
* @param eItem 不包含项
* @return
*/
public static Map<String, String> getEnumMap(String... eItem) {
Map<String, String> resultMap = new LinkedHashMap<>();
for (AttendSourceTypeEnum item : AttendSourceTypeEnum.values()) {
try {
boolean hasE = false;
for (String e : eItem) {
if (e.equals(item.getValue())) {
hasE = true;
break;
}
}
if (!hasE) {
resultMap.put(item.getValue(), item.getDesc());
}
} catch (Exception ex) {
}
}
return resultMap;
}
}
\ No newline at end of file
......@@ -12,7 +12,8 @@ public enum AttendanceTypeEnum {
地点打卡("地点打卡", "地点打卡"),
WiFi打卡("Wi-Fi打卡", "Wi-Fi打卡"),
蓝牙打卡("蓝牙打卡", "蓝牙打卡"),
考勤机打卡("考勤机打卡", "考勤机打卡");
考勤机打卡("考勤机打卡", "考勤机打卡"),
钉钉打卡("钉钉打卡", "钉钉打卡"),;
private String value;
private String desc;
......
......@@ -10,6 +10,7 @@ import java.util.Map;
*/
public enum SourceEnum {
海康(1, "海康"),
钉钉(3, "钉钉"),
自定义(2, "自定义");
private Integer value;
private String desc;
......
package com.mortals.xhx.daemon.applicationservice;
import com.alibaba.fastjson.JSON;
import com.mortals.framework.springcloud.service.IApplicationStartedService;
import com.mortals.framework.util.ThreadPool;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
@Component
@Slf4j
public class StartService implements IApplicationStartedService {
......@@ -13,8 +17,34 @@ public class StartService implements IApplicationStartedService {
@Override
public void start() {
ThreadPool.getInstance().init(10);
//测试 多个返回
int i = 0;
List<String> list = query(i);
log.info(JSON.toJSONString(list));
}
public List<String> query(int i) {
i++;
if (i > 5) {
return new ArrayList<>();
}
return query(i);
}
@Override
public void stop() {
log.info("停止服务..");
......
package com.mortals.xhx.daemon.applicationservice;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.dingtalk.api.response.*;
import com.google.common.collect.Lists;
import com.mortals.framework.common.Rest;
import com.mortals.framework.model.PageInfo;
import com.mortals.framework.springcloud.service.IApplicationStartedService;
import com.mortals.framework.util.DataUtil;
import com.mortals.xhx.base.system.user.service.UserService;
import com.mortals.xhx.common.code.AttendSourceTypeEnum;
import com.mortals.xhx.common.code.AttendanceTypeEnum;
import com.mortals.xhx.common.code.YesNoEnum;
import com.mortals.xhx.module.attendance.model.*;
import com.mortals.xhx.module.attendance.service.AttendanceClassService;
import com.mortals.xhx.module.attendance.service.AttendanceGroupService;
import com.mortals.xhx.module.attendance.service.AttendanceGroupStaffService;
import com.mortals.xhx.module.attendance.service.AttendanceRecordHikService;
import com.mortals.xhx.module.dept.model.DeptEntity;
import com.mortals.xhx.module.dept.model.DeptQuery;
import com.mortals.xhx.module.dept.service.DeptService;
import com.mortals.xhx.module.dingding.attendance.service.IDingAttenanceService;
import com.mortals.xhx.module.dingding.personal.service.IDingPersonService;
import com.mortals.xhx.module.hik.person.model.req.org.OrgListReq;
import com.mortals.xhx.module.hik.person.model.rsp.org.OrgDataInfo;
import com.mortals.xhx.module.hik.person.model.rsp.org.OrgInfo;
import com.mortals.xhx.module.staff.model.StaffEntity;
import com.mortals.xhx.module.staff.model.StaffQuery;
import com.mortals.xhx.module.staff.service.StaffService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
@Component
@Slf4j
......@@ -14,14 +48,166 @@ public class StartedService implements IApplicationStartedService {
private UserService userService;
@Autowired
private StaffService staffService;
@Autowired
private DeptService deptService;
@Autowired
private IDingPersonService dingPersonService;
@Autowired
private IDingAttenanceService dingAttenanceService;
@Autowired
private AttendanceRecordHikService hikService;
@Autowired
private AttendanceGroupService groupService;
@Autowired
private AttendanceGroupStaffService groupStaffService;
@Override
public void start() {
log.info("开始服务..[配置已加载完成,并且所有框架都已经初始化]");
//初始执行同步用户与皮肤任务
//获取排班信息
/* Rest<List<OapiAttendanceShiftListResponse.TopMinimalismShiftVo>> rest = dingAttenanceService.getShiftList(0L);
rest.getData();
for (OapiAttendanceShiftListResponse.TopMinimalismShiftVo datum : rest.getData()) {
//获取排班详细信息
dingAttenanceService.getShiftDetail(datum.getId());
}*/
/*
dingPersonService.getPersonsByDept(new PageInfo(), 123716132L);
Rest<OapiV2UserGetResponse.UserGetResponse> rest = dingAttenanceService.getPersonDetail("2850143830605086304");
*/
//保存更新考勤组
PageInfo pageInfo = new PageInfo();
Rest<List<OapiAttendanceGetsimplegroupsResponse.AtGroupForTopVo>> groupRest = dingAttenanceService.getAttendanceGroupList(pageInfo);
if (YesNoEnum.YES.getValue() == groupRest.getCode()) {
List<OapiAttendanceGetsimplegroupsResponse.AtGroupForTopVo> groupList = groupRest.getData();
for (OapiAttendanceGetsimplegroupsResponse.AtGroupForTopVo group : groupList) {
Long groupId = group.getGroupId();
String groupName = group.getGroupName();
Long memberCount = group.getMemberCount();
String type = group.getType();
AttendanceGroupQuery groupQuery = new AttendanceGroupQuery();
groupQuery.setRemark(groupId.toString());
AttendanceGroupEntity attendanceGroupEntity = groupService.selectOne(groupQuery);
if (ObjectUtils.isEmpty(attendanceGroupEntity)) {
attendanceGroupEntity = new AttendanceGroupEntity();
attendanceGroupEntity.initAttrValue();
attendanceGroupEntity.setRemark(groupId.toString());
attendanceGroupEntity.setGroupName(groupName);
attendanceGroupEntity.setPersonNum(memberCount.intValue());
attendanceGroupEntity.setAttendanceType(AttendanceTypeEnum.钉钉打卡.getValue());
attendanceGroupEntity.setCreateTime(new Date());
attendanceGroupEntity.setCreateUserId(1L);
if ("FIXED".equalsIgnoreCase(type)) {
attendanceGroupEntity.setType(1);
} else if ("TURN".equalsIgnoreCase(type)) {
attendanceGroupEntity.setType(2);
} else if ("NONE".equalsIgnoreCase(type)) {
attendanceGroupEntity.setType(3);
}
groupService.save(attendanceGroupEntity);
}
}
}
//保存考勤组人员
// pageInfo = new PageInfo();
AttendanceGroupQuery attendanceGroupQuery = new AttendanceGroupQuery();
attendanceGroupQuery.setAttendanceType(AttendanceTypeEnum.钉钉打卡.getValue());
List<AttendanceGroupEntity> groupEntityList = groupService.find(attendanceGroupQuery);
for (AttendanceGroupEntity attendanceGroupEntity : groupEntityList) {
long groupId = DataUtil.converStr2Long(attendanceGroupEntity.getRemark(), 0L);
Rest<List<String>> groupPersonRest = dingAttenanceService.getGroupPersons(0L, groupId);
if (YesNoEnum.YES.getValue() == groupPersonRest.getCode()) {
log.info("考勤组人员数量:" + groupPersonRest.getData().size());
//获取本地已有考勤人员
AttendanceGroupStaffQuery groupStaffQuery = new AttendanceGroupStaffQuery();
groupStaffQuery.setGroupId(attendanceGroupEntity.getId());
Set<Long> staffIdsSet = groupStaffService.find(groupStaffQuery).stream().map(item -> item.getStaffId()).collect(Collectors.toSet());
List<StaffEntity> staffEntityList = groupPersonRest.getData().stream().map(workNum -> {
StaffEntity extCache = staffService.getExtCache(workNum);
if (!ObjectUtils.isEmpty(extCache)) {
return extCache;
} else {
log.info("未找到员工工号:" + workNum);
return null;
}
}).collect(Collectors.toList());
/* StaffQuery staffQuery = new StaffQuery();
staffQuery.setWorkNumList(groupPersonRest.getData());
List<StaffEntity> staffEntityList = staffService.find(staffQuery);*/
for (StaffEntity staffEntity : staffEntityList) {
if (!staffIdsSet.contains(staffEntity.getId())) {
AttendanceGroupStaffEntity groupStaffEntity = new AttendanceGroupStaffEntity();
groupStaffEntity.initAttrValue();
groupStaffEntity.setGroupId(attendanceGroupEntity.getId());
groupStaffEntity.setGroupName(attendanceGroupEntity.getGroupName());
groupStaffEntity.setStaffId(staffEntity.getId());
groupStaffEntity.setStaffName(staffEntity.getName());
groupStaffEntity.setRemark("dingTalk");
groupStaffEntity.setCreateTime(new Date());
groupStaffEntity.setCreateUserId(1L);
groupStaffService.save(groupStaffEntity);
}
}
//增量添加
}
}
// //获取考勤组列表
/*
PageInfo pageInfo = new PageInfo();
dingAttenanceService.getAttendanceGroupList(pageInfo);*/
//staffService.syncPersonsByDingTalk(null);
/*
AttendanceRecordHikQuery hikQuery = new AttendanceRecordHikQuery();
hikQuery.setAttendanceDateStart("2025-03-21");
hikQuery.setAttendanceDateEnd("2025-03-21");
hikService.syncDoorEventsFromDingTalk(hikQuery);
*/
}
@Override
public void stop() {
log.info("停止服务..");
......
package com.mortals.xhx.daemon.task;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.mortals.framework.common.Rest;
import com.mortals.framework.exception.AppException;
import com.mortals.framework.service.ICacheService;
import com.mortals.framework.service.ITask;
import com.mortals.framework.service.ITaskExcuteService;
import com.mortals.framework.util.DataUtil;
import com.mortals.xhx.common.code.DwMinorEnum;
import com.mortals.xhx.common.code.YesNoEnum;
import com.mortals.xhx.module.attendance.model.AttendanceRecordHikEntity;
import com.mortals.xhx.module.attendance.service.AttendanceRecordHikService;
import com.mortals.xhx.module.door.model.DoorEntity;
import com.mortals.xhx.module.door.model.DoorQuery;
import com.mortals.xhx.module.door.service.DoorService;
import com.mortals.xhx.module.hik.door.model.req.door.HikDoorEventReq;
import com.mortals.xhx.module.hik.door.model.rsp.door.info.EventInfo;
import com.mortals.xhx.module.hik.door.model.rsp.door.info.StruTime;
import com.mortals.xhx.module.hik.door.service.IHikDoorService;
import com.mortals.xhx.module.staff.model.StaffEntity;
import com.mortals.xhx.module.staff.service.StaffService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
/**
* 同步获取当天海康门禁事件
*/
@Slf4j
//@Service("SyncDoorsEventByDevicesTask")
public class SyncDoorsEventByDevicesTaskImpl implements ITaskExcuteService {
@Autowired
private AttendanceRecordHikService recordHikService;
@Autowired
private StaffService staffService;
@Autowired
private IHikDoorService hikDoorService;
private Integer day;
@Autowired
private ICacheService cacheService;
@Autowired
private DoorService doorService;
@Override
public void excuteTask(ITask task) throws AppException {
//同步多久时间段的 偏移量为天 默认当天
String excuteParam = task.getExcuteParam();
if (!ObjectUtils.isEmpty(excuteParam)) {
day = DataUtil.converStr2Int(excuteParam, 0);
} else {
day = 0;
}
HikDoorEventReq hikDoorEventReq = new HikDoorEventReq();
//当前时间前一个小时
// Date startTime = DateUtil.offsetHour(new Date(), -1).toJdkDate();
Date startTime = DateUtil.offsetDay(new Date(), -1).toJdkDate();
Date endTime = new Date();
hikDoorEventReq.setStartTime(startTime);
hikDoorEventReq.setEndTime(endTime);
boolean in = true;
if (in) {
List<DoorEntity> doorEntities = doorService.find(new DoorQuery());
for (DoorEntity doorEntity : doorEntities) {
doorService.syncDoorDeviceEvents(doorEntity,hikDoorEventReq);
// syncDoorEvents(doorEntity);
}
}
}
@Override
public void stopTask(ITask task) throws AppException {
}
}
......@@ -14,11 +14,16 @@ import com.mortals.framework.service.ITaskExcuteService;
import com.mortals.framework.util.DataUtil;
import com.mortals.framework.util.DateUtils;
import com.mortals.xhx.base.system.user.model.UserEntity;
import com.mortals.xhx.common.code.AttendSourceTypeEnum;
import com.mortals.xhx.common.code.TypeEnum;
import com.mortals.xhx.common.code.YesNoEnum;
import com.mortals.xhx.common.key.RedisKey;
import com.mortals.xhx.module.attendance.model.AttendanceRecordHikEntity;
import com.mortals.xhx.module.attendance.model.AttendanceRecordHikQuery;
import com.mortals.xhx.module.attendance.service.AttendanceRecordHikService;
import com.mortals.xhx.module.attendance.service.work.FixWorkOtherAttendance;
import com.mortals.xhx.module.attendance.service.work.FreedomWorkAttendance;
import com.mortals.xhx.module.dingding.attendance.service.IDingAttenanceService;
import com.mortals.xhx.module.door.model.DoorEntity;
import com.mortals.xhx.module.door.model.DoorQuery;
import com.mortals.xhx.module.door.service.DoorService;
......@@ -54,8 +59,13 @@ public class SyncDoorsEventTaskImpl implements ITaskExcuteService {
@Value("${hik.host:}")
protected String hikhost;
@Value("${source.type:''}")
protected String sourceType;
@Autowired
private DoorService doorService;
@Autowired
private IDingAttenanceService dingAttenanceService;
@Override
public void excuteTask(ITask task) throws AppException {
......@@ -76,7 +86,31 @@ public class SyncDoorsEventTaskImpl implements ITaskExcuteService {
hikQuery.setAttendanceDateStart(startTime.toDateStr());
// 获取当天的结束时间
hikQuery.setAttendanceDateEnd(DateUtil.today());
if (!ObjectUtils.isEmpty(hikhost)) {
//todo 根据配置 判断是否海康门禁 钉钉考勤等
if (AttendSourceTypeEnum.海康云平台.getValue().equals(sourceType)) {
//海康云平台
log.info("同步海康云平台门禁事件!");
recordHikService.syncDoorEvents(hikQuery);
} else if (AttendSourceTypeEnum.海康考勤机.getValue().equals(sourceType)) {
//海康考勤机
log.info("同步海康设备上门禁事件!");
HikDoorEventReq hikDoorEventReq = new HikDoorEventReq();
hikDoorEventReq.setStartTime(DateUtil.parseDate(startTime.toDateStr()).toJdkDate());
hikDoorEventReq.setEndTime(DateUtil.endOfDay(new Date()));
List<DoorEntity> doorEntities = doorService.find(new DoorQuery());
for (DoorEntity doorEntity : doorEntities) {
doorService.syncDoorDeviceEvents(doorEntity, hikDoorEventReq);
}
} else if (AttendSourceTypeEnum.钉钉.getValue().equals(sourceType)) {
//钉钉
log.info("同步钉钉考勤事件!");
recordHikService.syncDoorEventsFromDingTalk(hikQuery);
}else {
log.info("未配置考勤源类型!");
}
/* if (!ObjectUtils.isEmpty(hikhost)) {
recordHikService.syncDoorEvents(hikQuery);
} else {
log.info("同步设备上门禁事件!");
......@@ -87,7 +121,7 @@ public class SyncDoorsEventTaskImpl implements ITaskExcuteService {
for (DoorEntity doorEntity : doorEntities) {
doorService.syncDoorDeviceEvents(doorEntity, hikDoorEventReq);
}
}
}*/
}
}
......
......@@ -8,6 +8,7 @@ import com.mortals.framework.service.ICacheService;
import com.mortals.framework.service.ITask;
import com.mortals.framework.service.ITaskExcuteService;
import com.mortals.framework.util.ThreadPool;
import com.mortals.xhx.common.code.AttendSourceTypeEnum;
import com.mortals.xhx.common.utils.AddAttendThread;
import com.mortals.xhx.module.attendance.model.AttendanceLeaveRecordQuery;
import com.mortals.xhx.module.attendance.model.AttendanceRecordHikQuery;
......@@ -44,8 +45,8 @@ public class SyncDoorsEventWeekTaskImpl implements ITaskExcuteService {
private DoorService doorService;
@Autowired
private ICacheService cacheService;
@Value("${source.type:''}")
protected String sourceType;
@Value("${dingtalk.domain:}")
protected String domain;
......@@ -60,12 +61,59 @@ public class SyncDoorsEventWeekTaskImpl implements ITaskExcuteService {
AttendanceRecordHikQuery hikEntity = new AttendanceRecordHikQuery();
hikEntity.setAttendanceDateStart(DateUtil.format(weekStart, "yyyy-MM-dd"));
hikEntity.setAttendanceDateEnd(DateUtil.today());
//天数区间分段计算
DateTime attendStart = DateUtil.parseDate(hikEntity.getAttendanceDateStart());
DateTime attendEnd = DateUtil.parseDate(hikEntity.getAttendanceDateEnd());
Long compare = DateUtil.between(attendEnd, attendStart, DateUnit.DAY);
if (!ObjectUtils.isEmpty(hikhost)) {
//todo 根据配置 判断是否海康门禁 钉钉考勤等
if (AttendSourceTypeEnum.海康云平台.getValue().equals(sourceType)) {
//海康云平台
log.info("同步海康云平台门禁事件!");
StopWatch stopWatch = new StopWatch("stopwatch attend1");
log.info("考勤计算天数区间:{}", compare);
for (int i = 0; i <= compare.intValue(); i++) {
DateTime curDate = DateUtil.offsetDay(attendStart, i);
log.info("考勤计算日期:{}", curDate.toDateStr());
stopWatch.start("执行本地方法");
hikEntity.setAttendanceDateStart(curDate.toDateStr());
hikEntity.setAttendanceDateEnd(curDate.toDateStr());
recordHikService.syncDoorEvents(hikEntity);
recordHikService.deletFakeRecord(hikEntity, null);
stopWatch.stop();
log.info("考勤计算日期:{} 完成,耗时:{}ms", curDate.toDateStr(), stopWatch.getLastTaskTimeMillis());
}
} else if (AttendSourceTypeEnum.海康考勤机.getValue().equals(sourceType)) {
//海康考勤机
log.info("同步海康设备上门禁事件!");
StopWatch stopWatch = new StopWatch("stopwatch attend1");
log.info("考勤计算天数区间:{}", compare);
for (int i = 0; i <= compare.intValue(); i++) {
DateTime curDate = DateUtil.offsetDay(attendStart, i);
log.info("考勤计算日期:{}", curDate.toDateStr());
stopWatch.start("执行本地方法");
HikDoorEventReq hikDoorEventReq = new HikDoorEventReq();
hikDoorEventReq.setStartTime(curDate.toJdkDate());
hikDoorEventReq.setEndTime(curDate.toJdkDate());
List<DoorEntity> doorEntities = doorService.find(new DoorQuery());
for (DoorEntity doorEntity : doorEntities) {
doorService.syncDoorDeviceEvents(doorEntity, hikDoorEventReq);
}
hikEntity.setAttendanceDateStart(curDate.toDateStr());
hikEntity.setAttendanceDateEnd(curDate.toDateStr());
recordHikService.deletFakeRecord(hikEntity, null);
stopWatch.stop();
log.info("考勤计算日期:{} 完成,耗时:{}ms", curDate.toDateStr(), stopWatch.getLastTaskTimeMillis());
}
} else if (AttendSourceTypeEnum.钉钉.getValue().equals(sourceType)) {
//钉钉
log.info("同步钉钉考勤事件!");
}else {
log.info("未配置考勤源类型!");
}
/* if (!ObjectUtils.isEmpty(hikhost)) {
log.info("同步海康云主机");
StopWatch stopWatch = new StopWatch("stopwatch attend1");
log.info("考勤计算天数区间:{}", compare);
......@@ -106,7 +154,7 @@ public class SyncDoorsEventWeekTaskImpl implements ITaskExcuteService {
log.info("考勤计算日期:{} 完成,耗时:{}ms", curDate.toDateStr(), stopWatch.getLastTaskTimeMillis());
}
}
}*/
log.info("开始计算及统计最近7天考勤!");
String expire = cacheService.get(KEY_ATTENDANCE_STAT_LOCK_CACHE);
if (ObjectUtils.isEmpty(expire)) {
......
......@@ -44,6 +44,9 @@ public class SyncRegisterUserPicTaskImpl implements ITaskExcuteService {
@Autowired
private DoorService doorService;
@Value("${source.type:''}")
protected String sourceType;
@Override
public void excuteTask(ITask task) throws AppException {
......
package com.mortals.xhx.daemon.task;
import cn.hutool.core.date.DateUtil;
import com.mortals.framework.common.Rest;
import com.mortals.framework.exception.AppException;
import com.mortals.framework.service.ITask;
......@@ -7,6 +8,7 @@ import com.mortals.framework.service.ITaskExcuteService;
import com.mortals.xhx.base.system.user.model.UserEntity;
import com.mortals.xhx.base.system.user.model.UserQuery;
import com.mortals.xhx.base.system.user.service.UserService;
import com.mortals.xhx.common.code.AttendSourceTypeEnum;
import com.mortals.xhx.common.code.YesNoEnum;
import com.mortals.xhx.module.attendance.service.AttendanceStatService;
import com.mortals.xhx.module.attendance.service.AttendanceVacationBalanceService;
......@@ -14,6 +16,9 @@ import com.mortals.xhx.module.dept.model.DeptEntity;
import com.mortals.xhx.module.dept.model.DeptQuery;
import com.mortals.xhx.module.dept.service.DeptService;
import com.mortals.xhx.module.dingding.personal.service.IDingPersonService;
import com.mortals.xhx.module.door.model.DoorEntity;
import com.mortals.xhx.module.door.model.DoorQuery;
import com.mortals.xhx.module.hik.door.model.req.door.HikDoorEventReq;
import com.mortals.xhx.module.hik.person.model.req.org.OrgListReq;
import com.mortals.xhx.module.hik.person.model.rsp.org.OrgDataInfo;
import com.mortals.xhx.module.hik.person.model.rsp.org.OrgInfo;
......@@ -32,7 +37,7 @@ import java.util.List;
import java.util.stream.Collectors;
/**
* 同步海康用户
* 同步用户
*/
@Slf4j
@Service("SyncUserTask")
......@@ -49,8 +54,72 @@ public class SyncUserTaskImpl implements ITaskExcuteService {
@Value("${hik.host:}")
protected String hikhost;
@Value("${source.type:''}")
protected String sourceType;
@Override
public void excuteTask(ITask task) throws AppException {
if (AttendSourceTypeEnum.海康云平台.getValue().equals(sourceType)) {
log.info("同步部门");
deptService.syncDept(null);
log.info("同步用户");
staffService.syncPersons(null);
log.info("同步钉钉usreId");
try {
List<UserEntity> userList = userService.getCacheList().stream()
.filter(f -> !ObjectUtils.isEmpty(f.getCustomerId()))
.filter(f -> ObjectUtils.isEmpty(f.getDingUserId())).collect(Collectors.toList());
List<UserEntity> updateUserList = userList.stream().map(item -> {
UserEntity userEntity = new UserEntity();
userEntity.setId(item.getId());
String mobile = "";
StaffEntity staffCache = staffService.getCache(item.getCustomerId().toString());
if (!ObjectUtils.isEmpty(staffCache) && !ObjectUtils.isEmpty(staffCache.getPhoneNumber())) {
mobile = staffCache.getPhoneNumber();
if (ObjectUtils.isEmpty(item.getMobile())) {
userEntity.setMobile(mobile);
}
}
if (!ObjectUtils.isEmpty(mobile)) {
Rest<String> personByMobile = dingPersonService.getPersonByMobile(mobile);
if (!ObjectUtils.isEmpty(personByMobile) &&
YesNoEnum.YES.getValue() == personByMobile.getCode()
&& !ObjectUtils.isEmpty(personByMobile.getData())) {
userEntity.setDingUserId(personByMobile.getData());
}
}
userEntity.setUpdateTime(new Date());
userEntity.setUpdateUserId(1L);
return userEntity;
}).filter(f -> !ObjectUtils.isEmpty(f.getDingUserId())).collect(Collectors.toList());
if (!ObjectUtils.isEmpty(updateUserList)) {
log.info("更新用户钉钉id信息数量:{}", updateUserList.size());
userService.getUserDao().updateBatch(updateUserList);
}
} catch (Exception e) {
log.error("同步钉钉usreId失败");
}
} else if (AttendSourceTypeEnum.海康考勤机.getValue().equals(sourceType)) {
log.info("设备直连同步人员信息");
staffService.syncPersonsByDevices(null);
} else if (AttendSourceTypeEnum.钉钉.getValue().equals(sourceType)) {
//钉钉
log.info("同步钉钉部门");
deptService.syncDeptByDingTalk(null);
//同步钉钉人员
staffService.syncPersonsByDingTalk(null);
log.info("钉钉直连同步人员信息");
} else {
log.info("未配置考勤源类型!");
}
/*
try {
if (!ObjectUtils.isEmpty(hikhost)) {
log.info("同步部门");
......@@ -102,7 +171,7 @@ public class SyncUserTaskImpl implements ITaskExcuteService {
}
} catch (Exception e) {
log.error("同步人事异常", e);
}
}*/
}
@Override
......
......@@ -169,7 +169,7 @@ public class AttendanceGroupStaffEntity extends AttendanceGroupStaffVo {
this.staffName = "";
this.partAttendance = null;
this.partAttendance = 1;
this.remark = "";
}
......
......@@ -11,4 +11,7 @@ import com.mortals.xhx.module.attendance.model.AttendanceClassEntity;
*/
public interface AttendanceClassService extends ICRUDService<AttendanceClassEntity,Long>{
}
\ No newline at end of file
......@@ -26,15 +26,12 @@ public interface AttendanceRecordHikService extends ICRUDService<AttendanceRecor
*/
void addAttendanceRecordByQuery(AttendanceRecordHikEntity attendanceRecordHikQuery, Context context) throws Exception;
/**
* 根据查询条件生成打卡记录 排除节假日
* @param attendanceRecordHikQuery
*/
void addAttendanceRecordByQueryCustom(AttendanceRecordHikEntity attendanceRecordHikQuery, Context context) throws Exception;
/**
* 根据查询条件生成打卡记录
* @param hikEntity
......@@ -65,12 +62,31 @@ public interface AttendanceRecordHikService extends ICRUDService<AttendanceRecor
*/
void buildAllCustomHikRecord(AttendanceRecordHikQuery recordHikQuery,Context context);
/**
* 根据查询条件生成打卡记录
* @param recordHikQuery
* @param context
* @return
*/
Rest<Integer> buildSourceHikRecord(AttendanceRecordHikQuery recordHikQuery, Context context);
/**
* 删除虚增考勤记录
* @param recordHikQuery
* @param context
*/
void deletFakeRecord(AttendanceRecordHikQuery recordHikQuery, Context context);
/**
* 从海康同步考勤门禁事件
* @param recordHikQuery
*/
void syncDoorEvents(AttendanceRecordHikQuery recordHikQuery);
/**
* 从钉钉同步考勤门禁事件
* @param recordHikQuery
*/
void syncDoorEventsFromDingTalk(AttendanceRecordHikQuery recordHikQuery);
}
......@@ -65,4 +65,10 @@ public class AttendanceClassServiceImpl extends AbstractCRUDServiceImpl<Attendan
attendanceClassDetailService.removeList(attendanceClassDetaillist, context);
super.removeAfter(ids, context, result);
}
}
\ No newline at end of file
package com.mortals.xhx.module.dept.service;
import com.dingtalk.api.response.OapiV2DepartmentListsubResponse;
import com.mortals.framework.common.Rest;
import com.mortals.framework.exception.AppException;
import com.mortals.framework.model.Context;
......@@ -99,4 +100,9 @@ public interface DeptService extends ICRUDService<DeptEntity, Long> {
*/
Rest<String> syncDeptByDevice(Context context);
Rest<String> syncDeptByDingTalk(Context context);
void saveSubDepts(Rest<List<OapiV2DepartmentListsubResponse.DeptBaseResponse>> depts);
}
\ No newline at end of file
package com.mortals.xhx.module.dept.service.impl;
import com.alibaba.fastjson.JSON;
import com.dingtalk.api.response.OapiV2DepartmentListsubResponse;
import com.mortals.framework.common.Rest;
import com.mortals.xhx.common.code.EnableEnum;
import com.mortals.xhx.common.code.EnabledEnum;
import com.mortals.xhx.common.code.StaffSatusEnum;
import com.mortals.xhx.common.code.YesNoEnum;
import com.mortals.xhx.module.dingding.personal.service.IDingPersonService;
import com.mortals.xhx.module.hik.person.model.req.org.OrgListReq;
import com.mortals.xhx.module.hik.person.model.rsp.org.OrgDataInfo;
import com.mortals.xhx.module.hik.person.model.rsp.org.OrgInfo;
......@@ -48,6 +50,9 @@ public class DeptServiceImpl extends AbstractCRUDServiceImpl<DeptDao, DeptEntity
@Autowired
private IHikPersonService hikPersonService;
@Autowired
private IDingPersonService dingPersonService;
@Override
protected void saveBefore(DeptEntity entity, Context context) throws AppException {
if (ObjectUtils.isEmpty(entity.getParentId())) {
......@@ -344,7 +349,7 @@ public class DeptServiceImpl extends AbstractCRUDServiceImpl<DeptDao, DeptEntity
//差额删除部门
List<DeptEntity> localDeptList = this.find(new DeptQuery());
// Map<String, DeptEntity> localDeptMap = localDeptList.stream().collect(Collectors.toMap(x -> x.getDeptCode(), y -> y, (o, n) -> n));
// Map<String, DeptEntity> localDeptMap = localDeptList.stream().collect(Collectors.toMap(x -> x.getDeptCode(), y -> y, (o, n) -> n));
//差额对
Map<String, OrgInfo> remoteDeptMap = orgInfoList.stream().collect(Collectors.toMap(x -> x.getOrgIndexCode(), y -> y, (o, n) -> n));
......@@ -373,4 +378,57 @@ public class DeptServiceImpl extends AbstractCRUDServiceImpl<DeptDao, DeptEntity
return Rest.ok();
}
@Override
public Rest<String> syncDeptByDingTalk(Context context) {
Rest<List<OapiV2DepartmentListsubResponse.DeptBaseResponse>> depts = dingPersonService.getDepts(null);
saveSubDepts(depts);
return Rest.ok();
}
@Override
public void saveSubDepts(Rest<List<OapiV2DepartmentListsubResponse.DeptBaseResponse>> depts) {
if (depts.getCode() == YesNoEnum.YES.getValue()) {
List<OapiV2DepartmentListsubResponse.DeptBaseResponse> data = depts.getData();
for (OapiV2DepartmentListsubResponse.DeptBaseResponse dept : data) {
String name = dept.getName();
Long parentId = dept.getParentId();
Long deptId = dept.getDeptId();
DeptEntity deptEntity = this.selectOne(new DeptQuery().deptCode(deptId.toString()));
DeptEntity deptEntityParent = this.selectOne(new DeptQuery().deptCode(parentId.toString()));
//新增
if (ObjectUtils.isEmpty(deptEntity)) {
deptEntity = new DeptEntity();
deptEntity.initAttrValue();
if (!ObjectUtils.isEmpty(deptEntityParent)) {
deptEntity.setParentId(deptEntityParent.getId());
}
deptEntity.setDeptName(name);
deptEntity.setDeptCode(deptId.toString());
// deptEntity.setRemark(orgInfo.getParentOrgIndexCode());
deptEntity.setCreateTime(new Date());
deptEntity.setCreateUserId(1L);
this.save(deptEntity);
} else {
//更新
deptEntity.setDeptName(name);
deptEntity.setDeptCode(deptId.toString());
// deptEntity.setAncestors(orgInfo.getOrgPath());
deptEntity.setUpdateTime(new Date());
deptEntity.setUpdateUserId(1L);
this.update(deptEntity);
}
Boolean createDeptGroup = dept.getCreateDeptGroup();//是否有子部门
if (createDeptGroup) {
//存在子部门 继续调用
Rest<List<OapiV2DepartmentListsubResponse.DeptBaseResponse>> deptSub = dingPersonService.getDepts(deptId);
saveSubDepts(deptSub);
}
}
}
}
}
......@@ -26,7 +26,7 @@ import java.util.Map;
* @date: 2023/7/14 13:49
*/
@Slf4j
public abstract class AbstractDingTalkService implements IDingPersonService {
public abstract class AbstractDingTalkService implements IDingTalkService {
/**
* AgentId
......@@ -94,13 +94,13 @@ public abstract class AbstractDingTalkService implements IDingPersonService {
if (rsp.getErrcode() == 0) {
cacheService.setnx(RedisKey.KEY_DINGTALK_ACCESSTOKEN_CACHE, rsp.getAccessToken(), 7200);
// log.info("redis dingding token:{}",cacheService.get(RedisKey.KEY_DINGTALK_ACCESSTOKEN_CACHE));
// log.info("redis dingding token:{}",cacheService.get(RedisKey.KEY_DINGTALK_ACCESSTOKEN_CACHE));
return rsp.getAccessToken();
} else {
throw new AppException(String.format("code:{},errorMsg:{}", rsp.getErrcode(), rsp.getErrmsg()));
}
} else {
// log.info("redis dingding token:{}",dingToken);
// log.info("redis dingding token:{}",dingToken);
return dingToken;
}
} catch (Exception e) {
......
package com.mortals.xhx.module.dingding.attendance.service;
import com.dingtalk.api.response.*;
import com.mortals.framework.common.Rest;
import com.mortals.framework.model.PageInfo;
import com.mortals.xhx.module.attendance.model.AttendanceRecordHikQuery;
import com.mortals.xhx.module.dingding.IDingTalkService;
import java.util.List;
public interface IDingAttenanceService extends IDingTalkService {
/**
* 获取打卡结果
*
* @return
*/
Rest<List<OapiAttendanceListResponse.Recordresult>> getAttendanceList(PageInfo pageInfo, List<String> userIdList, AttendanceRecordHikQuery hikQuery);
/**
* 获取考勤组
*
* @param pageInfo
* @return
*/
Rest<List<OapiAttendanceGetsimplegroupsResponse.AtGroupForTopVo>> getAttendanceGroupList(PageInfo pageInfo);
/**
* 获取考勤组人员
*
* @param cursor
* @param groupId
* @return
*/
Rest<List<String>> getGroupPersons(Long cursor, Long groupId);
/**
* 获取班次列表
*
* @param cursor
* @return
*/
Rest<List<OapiAttendanceShiftListResponse.TopMinimalismShiftVo>> getShiftList(Long cursor);
/**
* 获取班次详细
*
* @param shiftId
* @return
*/
Rest<OapiAttendanceShiftQueryResponse.TopShiftVo> getShiftDetail(Long shiftId);
/**
* 获取个人信息详细
* @param userId
* @return
*/
Rest<OapiV2UserGetResponse.UserGetResponse> getPersonDetail(String userId);
}
\ No newline at end of file
package com.mortals.xhx.module.dingding.attendance.service.impl;
import com.alibaba.fastjson.JSON;
import com.dingtalk.api.DefaultDingTalkClient;
import com.dingtalk.api.DingTalkClient;
import com.dingtalk.api.request.*;
import com.dingtalk.api.response.*;
import com.mortals.framework.common.Rest;
import com.mortals.framework.model.PageInfo;
import com.mortals.xhx.module.attendance.model.AttendanceRecordHikQuery;
import com.mortals.xhx.module.dingding.AbstractDingTalkService;
import com.mortals.xhx.module.dingding.attendance.service.IDingAttenanceService;
import com.taobao.api.ApiException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.util.List;
@Service("dingAttendanceService")
@Slf4j
public class DingAttendanceServiceImpl extends AbstractDingTalkService implements IDingAttenanceService {
@Override
public Rest<List<OapiAttendanceListResponse.Recordresult>> getAttendanceList(PageInfo pageInfo, List<String> userIdList, AttendanceRecordHikQuery hikQuery) {
//todo 获取考勤列表
try {
DingTalkClient client = getDingTalkClient("/attendance/list");
OapiAttendanceListRequest req = new OapiAttendanceListRequest();
String attendanceDateStart = hikQuery.getAttendanceDateStart();
String attendanceDateEnd = hikQuery.getAttendanceDateEnd();
req.setWorkDateFrom(attendanceDateStart);
req.setWorkDateTo(attendanceDateEnd);
req.setUserIdList(userIdList);
req.setOffset(Long.valueOf(pageInfo.getBeginIndex() + ""));
req.setLimit(Long.valueOf(pageInfo.getPrePageResult() + ""));
log.info("req:{}", JSON.toJSONString(req));
OapiAttendanceListResponse rsp = client.execute(req, getToken());
// log.info("OapiV2UserGetbymobileResponse:{}", rsp.getBody());
if (rsp.getErrcode() == 0) {
if (rsp.getHasMore()) {
log.info("还有更多数据,递归调用,req:{}", JSON.toJSONString(req));
pageInfo.setCurrPage(pageInfo.getCurrPage() + 1);
Rest<List<OapiAttendanceListResponse.Recordresult>> attendanceList = getAttendanceList(pageInfo, userIdList, hikQuery);
rsp.getRecordresult().addAll(attendanceList.getData());
return Rest.ok("成功", rsp.getRecordresult());
}
return Rest.ok("成功", rsp.getRecordresult());
} else {
log.info("异常数据,rsp error:{}", JSON.toJSONString(rsp));
return Rest.fail(String.format("code:%s,msg:%s", rsp.getErrcode(), rsp.getErrmsg()));
}
} catch (ApiException e) {
log.info("获取考勤列表异常", e);
return Rest.fail(e.getMessage());
}
}
@Override
public Rest<List<OapiAttendanceGetsimplegroupsResponse.AtGroupForTopVo>> getAttendanceGroupList(PageInfo pageInfo) {
//todo 获取考勤组列表
try {
DingTalkClient client = getDingTalkClient("/topapi/attendance/getsimplegroups");
OapiAttendanceGetsimplegroupsRequest req = new OapiAttendanceGetsimplegroupsRequest();
req.setOffset(Long.valueOf(pageInfo.getBeginIndex() + ""));
req.setSize(Long.valueOf(pageInfo.getPrePageResult() + ""));
log.info("req:{}", JSON.toJSONString(req));
OapiAttendanceGetsimplegroupsResponse rsp = client.execute(req, getToken());
log.info("考勤组 Response:{}", rsp.getBody());
if (rsp.getErrcode() == 0) {
if (rsp.getResult().getHasMore()) {
log.info("还有更多数据,递归调用,req:{}", JSON.toJSONString(req));
pageInfo.setCurrPage(pageInfo.getCurrPage() + 1);
Rest<List<OapiAttendanceGetsimplegroupsResponse.AtGroupForTopVo>> rest = getAttendanceGroupList(pageInfo);
rsp.getResult().getGroups().addAll(rest.getData());
return Rest.ok("成功", rsp.getResult().getGroups());
}
return Rest.ok("成功", rsp.getResult().getGroups());
} else {
log.info("异常数据,rsp error:{}", JSON.toJSONString(rsp));
return Rest.fail(String.format("code:%s,msg:%s", rsp.getErrcode(), rsp.getErrmsg()));
}
} catch (ApiException e) {
log.info("获取考勤组异常", e);
return Rest.fail(e.getMessage());
}
}
@Override
public Rest<List<String>> getGroupPersons(Long cursor, Long groupId) {
//todo 获取考勤组人员列表
try {
DingTalkClient client = getDingTalkClient("/topapi/attendance/group/memberusers/list");
OapiAttendanceGroupMemberusersListRequest req = new OapiAttendanceGroupMemberusersListRequest();
req.setCursor(cursor);
req.setOpUserId("manager");
req.setGroupId(groupId);
log.info("req:{}", JSON.toJSONString(req));
OapiAttendanceGroupMemberusersListResponse rsp = client.execute(req, getToken());
log.info("考勤组 Response:{}", rsp.getBody());
if (rsp.getErrcode() == 0) {
if (rsp.getResult().getHasMore()) {
log.info("还有更多数据,递归调用,req:{}", JSON.toJSONString(req));
Rest<List<String>> rest = getGroupPersons(rsp.getResult().getCursor(), groupId);
rsp.getResult().getResult().addAll(rest.getData());
return Rest.ok("成功", rsp.getResult().getResult());
}
return Rest.ok("成功", rsp.getResult().getResult());
} else {
log.info("异常数据,rsp error:{}", JSON.toJSONString(rsp));
return Rest.fail(String.format("code:%s,msg:%s", rsp.getErrcode(), rsp.getErrmsg()));
}
} catch (ApiException e) {
log.info("获取考勤组人员异常", e);
return Rest.fail(e.getMessage());
}
}
public Rest<List<OapiAttendanceShiftListResponse.TopMinimalismShiftVo>> getShiftList(Long cursor) {
//todo 获取班次列表
try {
DingTalkClient client = getDingTalkClient("/topapi/attendance/shift/list");
OapiAttendanceShiftListRequest req = new OapiAttendanceShiftListRequest();
req.setCursor(cursor);
req.setOpUserId("manager");
log.info("req:{}", JSON.toJSONString(req));
OapiAttendanceShiftListResponse rsp = client.execute(req, getToken());
log.info("考勤班次 Response:{}", rsp.getBody());
if (rsp.getErrcode() == 0) {
if (rsp.getResult().getHasMore()) {
log.info("还有更多数据,递归调用,req:{}", JSON.toJSONString(req));
Rest<List<OapiAttendanceShiftListResponse.TopMinimalismShiftVo>> rest = getShiftList(rsp.getResult().getCursor());
rsp.getResult().getResult().addAll(rest.getData());
return Rest.ok("成功", rsp.getResult().getResult());
}
return Rest.ok("成功", rsp.getResult().getResult());
} else {
log.info("异常数据,rsp error:{}", JSON.toJSONString(rsp));
return Rest.fail(String.format("code:%s,msg:%s", rsp.getErrcode(), rsp.getErrmsg()));
}
} catch (ApiException e) {
log.info("获取班次异常", e);
return Rest.fail(e.getMessage());
}
}
public Rest<OapiAttendanceShiftQueryResponse.TopShiftVo> getShiftDetail(Long shiftId) {
//todo 获取班次列表
try {
DingTalkClient client = getDingTalkClient("/topapi/attendance/shift/query");
OapiAttendanceShiftQueryRequest req = new OapiAttendanceShiftQueryRequest();
req.setShiftId(shiftId);
req.setOpUserId("manager");
log.info("req:{}", JSON.toJSONString(req));
OapiAttendanceShiftQueryResponse rsp = client.execute(req, getToken());
log.info("班次详细 Response:{}", rsp.getBody());
if (rsp.getErrcode() == 0) {
return Rest.ok("成功", rsp.getResult());
} else {
log.info("异常数据,rsp error:{}", JSON.toJSONString(rsp));
return Rest.fail(String.format("code:%s,msg:%s", rsp.getErrcode(), rsp.getErrmsg()));
}
} catch (ApiException e) {
log.info("获取班次异常", e);
return Rest.fail(e.getMessage());
}
}
public Rest<OapiV2UserGetResponse.UserGetResponse> getPersonDetail(String userId) {
//todo 获取班次列表
try {
DingTalkClient client = getDingTalkClient("/topapi/v2/user/get");
OapiV2UserGetRequest req = new OapiV2UserGetRequest();
req.setUserid(userId);
log.info("req:{}", JSON.toJSONString(req));
OapiV2UserGetResponse rsp = client.execute(req, getToken());
log.info("个人详细 Response:{}", rsp.getBody());
if (rsp.getErrcode() == 0) {
return Rest.ok("成功", rsp.getResult());
} else {
log.info("异常数据,rsp error:{}", JSON.toJSONString(rsp));
return Rest.fail(String.format("code:%s,msg:%s", rsp.getErrcode(), rsp.getErrmsg()));
}
} catch (ApiException e) {
log.info("获取异常", e);
return Rest.fail(e.getMessage());
}
}
}
\ No newline at end of file
package com.mortals.xhx.module.dingding.personal.service;
import com.aliyun.dingtalkattendance_1_0.models.GetLeaveRecordsResponseBody;
import com.aliyun.dingtalkworkflow_1_0.models.GetProcessInstanceResponseBody;
import com.aliyun.dingtalkworkflow_1_0.models.ListProcessInstanceIdsResponse;
import com.aliyun.dingtalkworkflow_1_0.models.ListProcessInstanceIdsResponseBody;
import com.dingtalk.api.response.OapiAttendanceVacationQuotaListResponse;
import com.dingtalk.api.response.OapiV2UserGetResponse;
import com.dingtalk.api.response.OapiV2DepartmentListsubResponse;
import com.dingtalk.api.response.OapiV2UserListResponse;
import com.mortals.framework.common.Rest;
import com.mortals.framework.model.PageInfo;
import com.mortals.xhx.module.dingding.IDingTalkService;
import com.mortals.xhx.module.dingding.personal.model.req.workmsg.WorkMsgReq;
import com.mortals.xhx.module.hik.person.model.req.org.OrgListReq;
import com.mortals.xhx.module.hik.person.model.req.person.PersonReq;
import com.mortals.xhx.module.hik.person.model.rsp.org.OrgDataInfo;
import com.mortals.xhx.module.hik.person.model.rsp.person.PersonDataInfo;
import org.apache.poi.ss.formula.functions.T;
import java.util.List;
import java.util.stream.Stream;
/**
* 钉钉人事相关服务类
......@@ -37,7 +35,7 @@ public interface IDingPersonService extends IDingTalkService {
*
* @param id
* @return
*/
*/
Rest<String> getPersonById(String id);
/**
......@@ -51,46 +49,68 @@ public interface IDingPersonService extends IDingTalkService {
/**
* 发送工作消息
*
* @param workMsgReq
* @return
*/
Rest<String> sendWorkMsg(WorkMsgReq workMsgReq);
Rest<String> sendWorkMsg(WorkMsgReq workMsgReq);
/**
* 审批详情
*
* @param processInstanceId 审批实例ID。
* @return
*/
Rest<GetProcessInstanceResponseBody.GetProcessInstanceResponseBodyResult> getOaRecordsById(String processInstanceId);
Rest<GetProcessInstanceResponseBody.GetProcessInstanceResponseBodyResult> getOaRecordsById(String processInstanceId);
/**
* 查询userid的特定假期余额
* @param user_id 被查询员工的id集合 多个用,分隔
*
* @param user_id 被查询员工的id集合 多个用,分隔
* @param leave_code 假期类型编码
* @return
*/
Rest<OapiAttendanceVacationQuotaListResponse.OapiLeaveQuotaUserListVo> getLeaveRecordByUserId(String user_id, String leave_code);
Rest<OapiAttendanceVacationQuotaListResponse.OapiLeaveQuotaUserListVo> getLeaveRecordByUserId(String user_id, String leave_code);
/**
* 根据审批详情处理审批(插入请假数据)
*
* @param processInstanceId 实例id
*/
void handleByProcessInstanceId(String processInstanceId);
/**
* 根据系统电话查询指定时间的审批表单
*
* @param processCode 审批流的唯一码(详见doc下 审批表单列表.txt)。
* 请假:PROC-2E5C0DFF-3615-4409-A614-A2011FED5D38
* 外出:PROC-56D3ADEE-45A4-47BC-931A-2A0DC067DE32
* 出差:PROC-578CBDDF-B768-496D-9918-44A3F1D9CAE7
* @param startTime 审批实例开始时间,Unix时间戳,单位毫秒
* @param endTime 审批实例结束时间,Unix时间戳,单位毫秒。
* @param nextToken 分页游标。如果是非首次调用,该参数传上次调用时返回的nextToken。
* @param maxResults 分页参数,每页大小,最多传20。
* @param userIds 发起人id列表 最大列表长度为10
* @param startTime 审批实例开始时间,Unix时间戳,单位毫秒
* @param endTime 审批实例结束时间,Unix时间戳,单位毫秒。
* @param nextToken 分页游标。如果是非首次调用,该参数传上次调用时返回的nextToken。
* @param maxResults 分页参数,每页大小,最多传20。
* @param userIds 发起人id列表 最大列表长度为10
*/
Rest<ListProcessInstanceIdsResponseBody.ListProcessInstanceIdsResponseBodyResult> getProcessInstanceIdByUserIds(String processCode, long startTime, long endTime, Long nextToken, long maxResults, String userIds) throws Exception;
/**
* 根据部门获取用户信息
*
* @param pageInfo
* @param deptId
* @return
*/
List<OapiV2UserListResponse.ListUserResponse> getPersonsByDept(PageInfo pageInfo, Long deptId);
/**
* 根据部门id获取子部门
*
* @return
*/
Rest<List<OapiV2DepartmentListsubResponse.DeptBaseResponse>> getDepts(Long deptId);
}
......@@ -32,12 +32,12 @@ import java.util.Set;
import java.util.stream.Collectors;
/**
* DoorService
* 门禁设备 service实现
*
* @author zxfei
* @date 2023-11-22
*/
* DoorService
* 门禁设备 service实现
*
* @author zxfei
* @date 2023-11-22
*/
@Service("doorService")
@Slf4j
public class DoorServiceImpl extends AbstractCRUDServiceImpl<DoorDao, DoorEntity, Long> implements DoorService {
......@@ -72,7 +72,7 @@ public class DoorServiceImpl extends AbstractCRUDServiceImpl<DoorDao, DoorEntity
} else {
jobNo = new String(byEmployeeNo).trim();
}
log.info("jobNo==>{}",jobNo);
log.info("jobNo==>{}", jobNo);
//查看考勤状态
int dwMajor = item.getDwMajor();//报警主类型
int dwMinor = item.getDwMinor();//报警次类型
......@@ -97,7 +97,12 @@ public class DoorServiceImpl extends AbstractCRUDServiceImpl<DoorDao, DoorEntity
Date attendDate = Date.from(zdt.toInstant());
StaffEntity staffCache = staffService.getExtCache(StrUtil.padPre(jobNo, 8, "0"));
String workNum = jobNo;
if (jobNo.length() < 8) {
workNum = StrUtil.padPre(jobNo, 8, "0");
}
StaffEntity staffCache = staffService.getExtCache(workNum);
// StaffEntity staffCache = staffService.getExtCache(StrUtil.padPre(jobNo, 8, "0"));
if (ObjectUtils.isEmpty(staffCache)) {
log.info("staff is null !staffCode:{}", jobNo);
return null;
......
......@@ -32,8 +32,6 @@ public interface StaffService extends ICRUDCacheService<StaffEntity,Long> {
*/
Rest<Void> syncPersons(Context context);
/**
* 同步人员信息
* @param context
......@@ -41,6 +39,15 @@ public interface StaffService extends ICRUDCacheService<StaffEntity,Long> {
*/
Rest<Void> syncPersonsByDevices(Context context);
/**
* 同步钉钉人员信息
* @param context
* @return
*/
Rest<Void> syncPersonsByDingTalk(Context context);
/**
* 绩效考核授权
* @param pdu
......
......@@ -56,6 +56,8 @@ hystrix:
sms:
smsSendUrl: @profiles.sms.smsSendUrl@
apiId: @profiles.sms.apiId@
source:
type: @profiles.source.type@ # hik:海康云 hik-device:海康考勤机 dingtalk:钉钉考勤
hik:
host: @profiles.hik.host@
appKey: @profiles.hik.appKey@
......
......@@ -50,7 +50,7 @@ Content-Type: application/json
{
"attendanceDateStart": "2025-01-01",
"attendanceDateEnd": "2025-01-02"
"attendanceDateEnd": "2025-01-31"
}
###海康考勤打卡记录计算1
......@@ -58,9 +58,9 @@ POST {{baseUrl}}/attendance/record/hik/addAttendanceRecord
Content-Type: application/json
{
"attendanceDateStart": "2025-01-20",
"attendanceDateEnd": "2025-01-21",
"staffId":317
"attendanceDateStart": "2025-02-05",
"attendanceDateEnd": "2025-02-05",
"staffId":752
}
......@@ -80,8 +80,8 @@ POST {{baseUrl}}/attendance/record/hik/addAttendanceHikRecordCustom
Content-Type: application/json
{
"attendanceDateStart": "2024-11-18",
"attendanceDateEnd": "2024-11-26"
"attendanceDateStart": "2025-02-01",
"attendanceDateEnd": "2025-03-18"
}
......@@ -90,8 +90,8 @@ POST {{baseUrl}}/attendance/stat/summary
Content-Type: application/json
{
"summaryTimeStart": "2024-10-08",
"summaryTimeEnd": "2024-10-31"
"summaryTimeStart": "2025-02-01",
"summaryTimeEnd": "2025-03-18"
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment