钉钉考勤时间格式处理

dev_dxf
dxfeng 1 year ago
parent 57a78725a6
commit 2cfbf1683c

@ -0,0 +1,324 @@
package com.engine.hrm.cmd.emmanager;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.engine.common.biz.AbstractCommonCommand;
import com.engine.common.entity.BizLogContext;
import com.engine.core.interceptor.CommandContext;
import com.engine.kq.biz.KQGroupMemberComInfo;
import com.engine.kq.entity.KQGroupEntity;
import com.engine.kq.timer.KQQueue;
import com.engine.kq.timer.KQTaskBean;
import com.engine.kq.wfset.util.SplitActionUtil;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import weaver.common.DateUtil;
import weaver.conn.BatchRecordSet;
import weaver.conn.RecordSet;
import weaver.general.Util;
import com.engine.kq.biz.KQFormatData;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;
/**
* EM
*
* @author lvyi
*/
public class SynKqData4EMCmd extends AbstractCommonCommand<Map<String, Object>> {
private static SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
public SynKqData4EMCmd(Map<String, Object> params) {
this.params = params;
}
// "checkindata": [{
// "userid" : "100",
// "checkin_type" : 1,
// "checkin_time" : "1492617610",
// "location" : "四川省成都市武侯区益州大道中段784号附近",
// "longitude" : "116.486888",
// "latitude" : "39.999946",
// "wifiname" : "办公一区",
// "wifimac" : "3c:46:d8:0c:7a:70",
// "notes" : "路上堵车迟到了5分钟"
// },{
// "userid" : "101",
// "checkin_type" : 3,
// "checkin_time" : "1492617620",
// "location" : "重庆市渝北区金渝大道101号金渝大道",
// "longitude" : "116.486888",
// "latitude" : "39.999946",
// "wifiname" : "办公室二区",
// "wifimac" : "3c:46:d8:0c:7a:71",
// "notes" : ""
// }]
@Override
public Map<String, Object> execute(CommandContext commandContext) {
Map<String, Object> retmap = new HashMap<String, Object>();
String sql = "";
RecordSet rs = new RecordSet();
BatchRecordSet bRs = new BatchRecordSet();
List<List<Object>> lsParam = new ArrayList<>();
List<List<Object>> lsParam_out = new ArrayList<>();
List<Object> param = null;
List<Object> param_out = null;
List<List<Object>> lsDelParams = new ArrayList<>();
List<List<Object>> lsDelParams_out = new ArrayList<>();
List<Object> delParams = null;
List<String> lsFormatData = new ArrayList<>();
List<String> lsFormatData_out = new ArrayList<>();
List<List<Object>> lsFormatParams = new ArrayList<>();
List<Object> formatParams = null;
try {
String checkindata = Util.null2String(params.get("checkindata"));
String cptype = Util.null2String(params.get("cptype"));
writeLog("执行考勤数据同步=="+JSONObject.toJSONString(params));
JSONArray datas = JSONArray.parseArray(checkindata);
for (int i = 0; datas != null && i < datas.size(); i++) {
JSONObject data = datas.getJSONObject(i);
String userid = Util.null2String(data.getString("userid"));
String signtype = Util.null2String(data.getString("checkin_type"));
boolean isOutSide = false; //是否是外勤打卡数据
String outsidesign = ""; //人员所在考勤组是否开启外勤签到转考勤
KQGroupMemberComInfo kqGroupMemberComInfo = new KQGroupMemberComInfo();
KQGroupEntity kqGroupEntity = kqGroupMemberComInfo.getUserKQGroupInfo(userid);
if (kqGroupEntity != null) {
outsidesign = kqGroupEntity.getOutsidesign();
}
String checkin_time = Util.null2String(data.getString("checkin_time"));
if(checkin_time.length()==0)continue;
String[] tmpDateTime = Util.splitString(DateUtil.getFullDate(new Date(new Long(checkin_time)* 1000L))," ");
String signdate = tmpDateTime[0].trim();
String signtime = tmpDateTime[1].trim();
// 将钉钉上同步过来的打卡数据去掉后面的秒数显示解决统计迟到时长
signtime = DateUtil.formatTime(signtime)+":00";
writeLog("处理钉钉考勤时间格式化完成userid==" + userid + ",signdate==" + signdate + ",signtime==" + signtime);
String addr = Util.null2String(data.getString("location"));
String longitude = Util.null2String(data.getString("longitude"));
String latitude = Util.null2String(data.getString("latitude"));
String wifiname = Util.null2String(data.getString("wifiname"));
String wifimac = Util.null2String(data.getString("wifimac"));
String notes = Util.null2String(data.getString("notes"));
String exception_type = Util.null2String(data.getString("exception_type"));
String timeResult = Util.null2String(data.getString("timeResult"));
String locationResult = Util.null2String(data.getString("locationResult"));
String memo = "";//最近一直有云桥的同步报错的问题,先干掉;"wifiname:"+wifiname+"#wifimac:"+wifimac+"#notes:"+notes;
if("1".equals(cptype)){
//企业微信打卡
if(signtype.equalsIgnoreCase("3")) isOutSide = true;
//过滤异常数据
if(exception_type.length()>0&&(exception_type.indexOf("未打卡")>=0 || exception_type.indexOf("地点异常")>=0 || exception_type.indexOf("wifi异常")>=0)){
continue;
}
}else if("2".equals(cptype)){
//钉钉打卡
// 有一个isLegal 字段是否合法如果timeResult和locationResult都是空则不合法无效打卡数据。
// 如果是不合法打卡数据不传给OA
boolean notLegal = "".equalsIgnoreCase(timeResult) && "".equals(locationResult);
if(notLegal) {
continue;
}
if("Outside".equals(locationResult)) isOutSide = true;
//过滤异常数据
if("NotSigned".equals(timeResult)) continue;
}
//允许外勤签到转考勤
if("1".equalsIgnoreCase(outsidesign)){
param = new ArrayList<>();
param_out = new ArrayList<>();
param.add(userid);
param.add("1");
param.add(signtype);
param.add(signdate);
param.add(signtime);
if(isOutSide){
param.add("EMSyn_out");
}else{
param.add("EMSyn");
}
param.add("1");
param.add(addr);
param.add(longitude);
param.add(latitude);
param.add(memo);
lsParam.add(param);
String formatData = userid+"|"+signdate;
if(!lsFormatData.contains(formatData)){
lsFormatData.add(formatData);
}
//外勤数据
if(isOutSide) {
param_out.add(userid);
param_out.add("e9_mobile_out");
param_out.add(signdate);
param_out.add(signtime);
param_out.add(longitude);
param_out.add(latitude);
param_out.add(addr);
param_out.add(notes);
param_out.add("1");
lsParam_out.add(param_out);
String formatData_out = userid+"|"+signdate;
if(!lsFormatData_out.contains(formatData_out)){
lsFormatData_out.add(formatData_out);
}
}
}else{
//不允许外勤数据转考勤
param = new ArrayList<>();
param_out = new ArrayList<>();
//外勤打卡数据
if(isOutSide){
param_out.add(userid);
param_out.add("e9_mobile_out");
param_out.add(signdate);
param_out.add(signtime);
param_out.add(longitude);
param_out.add(latitude);
param_out.add(addr);
param_out.add(notes);
param_out.add("1");
lsParam_out.add(param_out);
String formatData_out = userid+"|"+signdate;
if(!lsFormatData_out.contains(formatData_out)){
lsFormatData_out.add(formatData_out);
}
}else{
//人事打卡数据
param.add(userid);
param.add("1");
param.add(signtype);
param.add(signdate);
param.add(signtime);
param.add("EMSyn");
param.add("1");
param.add(addr);
param.add(longitude);
param.add(latitude);
param.add(memo);
lsParam.add(param);
String formatData = userid+"|"+signdate;
if(!lsFormatData.contains(formatData)){
lsFormatData.add(formatData);
}
}
}
}
Map<String,List<String>> overtimeMap = Maps.newHashMap();
List<String> overtimeList = Lists.newArrayList();
//刷新报表数据
for(int i=0;lsFormatData!=null&&i<lsFormatData.size();i++){
formatParams = new ArrayList<>();
String[] formatData = Util.splitString(lsFormatData.get(i),"|");
String date_1 = DateUtil.addDate(formatData[1], -1);
formatParams.add(formatData[0]);
formatParams.add(date_1);
lsFormatParams.add(formatParams);
formatParams = new ArrayList<>();
formatParams.add(formatData[0]);
formatParams.add(formatData[1]);
lsFormatParams.add(formatParams);
delParams = new ArrayList<>();
delParams.add(formatData[0]);
delParams.add(formatData[1]);
lsDelParams.add(delParams);
String resourceId = formatData[0];
String kqdate = formatData[1];
if(overtimeMap.containsKey(resourceId)){
List<String> tmp_overtimeList = overtimeMap.get(resourceId);
if(!tmp_overtimeList.contains(kqdate)){
tmp_overtimeList.add(kqdate);
}
}else{
if(!overtimeList.contains(kqdate)){
overtimeList.add(kqdate);
}
overtimeMap.put(resourceId, overtimeList);
}
}
for(int i=0;lsFormatData_out!=null&&i<lsFormatData_out.size();i++){
String[] formatData = Util.splitString(lsFormatData_out.get(i),"|");
delParams = new ArrayList<>();
delParams.add(formatData[0]);
delParams.add(formatData[1]);
lsDelParams_out.add(delParams);
//使用executeBatchSql删除不了暂时用这种方法
sql = " delete from mobile_sign where isImport='1' and operater ='"+formatData[0]+"' and operate_date = '"+formatData[1]+"'";
rs.executeUpdate(sql);
}
//删除本次同步数据
sql = " delete from hrmschedulesign where (signfrom='EMSyn' or signfrom = 'EMSyn_out') and userid =? and signdate = ? ";
bRs.executeBatchSql(sql, lsDelParams);
//插入同步数据
sql = " insert into hrmschedulesign (userid,userType,signtype,signdate,signtime,signfrom,isincom,addr,longitude,latitude,memo) " +
" values(?,?,?,?,?,?,?,?,?,?,?)";
bRs.executeBatchSql(sql, lsParam);
//插入外勤同步数据
sql = " insert into mobile_sign (operater,operate_type,operate_date,operate_time,longitude,latitude,address,remark,isImport) " +
" values(?,?,?,?,?,?,?,?,?)";
bRs.executeBatchSql(sql, lsParam_out);
//格式化报表数据
String resourceid = "";
String kqdate = "";
List<Object> params = null;
for (int i = 0; lsFormatParams != null && i < lsFormatParams.size(); i++) {
params = lsFormatParams.get(i);
resourceid = Util.null2String(params.get(0));
kqdate = Util.null2String(params.get(1));
new KQFormatData().formatKqDate(resourceid, kqdate);
}
//处理加班生成
List<KQTaskBean> tasks = new ArrayList<>();
for(Map.Entry<String, List<String>> mme: overtimeMap.entrySet()){
String resid = mme.getKey();
List<String> overList = mme.getValue();
for(String date : overList){
SplitActionUtil.pushOverTimeTasks(date,date,resid,tasks);
}
}
if(!tasks.isEmpty()){
KQQueue.writeTasks(tasks);
}
retmap.put("errcode", 0);
retmap.put("errmsg", ""+weaver.systeminfo.SystemEnv.getHtmlLabelName(387135,weaver.general.ThreadVarLanguage.getLang())+"");
} catch (Exception e) {
retmap.put("status", 1);
retmap.put("error", ""+weaver.systeminfo.SystemEnv.getHtmlLabelName(10005249,weaver.general.ThreadVarLanguage.getLang())+"" + e.getMessage());
writeLog(e);
}
return retmap;
}
@Override
public BizLogContext getLogContext() {
return null;
}
}

@ -0,0 +1,173 @@
package com.engine.kq.cmd.schedulesignimport;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.engine.common.biz.AbstractCommonCommand;
import com.engine.common.biz.SimpleBizLogger;
import com.engine.common.entity.BizLogContext;
import com.engine.core.interceptor.CommandContext;
import com.engine.kq.biz.KQFormatBiz;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import weaver.common.StringUtil;
import weaver.conn.BatchRecordSet;
import weaver.conn.RecordSet;
import weaver.file.Prop;
import com.dingtalk.api.DefaultDingTalkClient;
import com.dingtalk.api.DingTalkClient;
import com.dingtalk.api.request.OapiAttendanceListRequest;
import com.dingtalk.api.request.OapiGettokenRequest;
import com.dingtalk.api.response.OapiAttendanceListResponse;
import com.dingtalk.api.response.OapiGettokenResponse;
import weaver.general.Util;
public class SynDingTalkDataCmd extends AbstractCommonCommand<Map<String, Object>> {
private SimpleBizLogger logger;
public SynDingTalkDataCmd(Map<String, Object> params) {
this.params = params;
}
@Override
public Map<String, Object> execute(CommandContext commandContext) {
Map<String, Object> retmap = new HashMap<String, Object>();
try{
String fromDate = Util.null2String(params.get("fromDate"));
String toDate = Util.null2String(params.get("toDate"));
String sql = "";
RecordSet rs = new RecordSet();
BatchRecordSet bRs = new BatchRecordSet();
RecordSet rs1 = new RecordSet();
List<String> lsFormatData = new ArrayList<>();
List<List<Object>> lsFormatParams = new ArrayList<>();
List<Object> formatParams = null;
rs.executeUpdate("delete HrmScheduleSign where isimport=1 and signdate>='"+fromDate+"' and signdate<='"+toDate+"'");
Map<String, String> resourceIdMap = new HashMap<String, String>();
rs.executeQuery("select id,workcode from hrmresource where workcode is not null and workcode<>''");
while(rs.next()){
resourceIdMap.put(Util.formatMultiLang(rs.getString("workcode")), StringUtil.vString(rs.getString("id")));
}
String corpId = StringUtil.vString(Prop.getInstance().getPropValue("HrmSynDDInfo", "corpId"));
String corpSecret = StringUtil.vString(Prop.getInstance().getPropValue("HrmSynDDInfo", "corpSecret"));
if(corpId.length()==0||corpSecret.length()==0){
writeLog("获取钉钉考勤数据失败corpId=="+corpId+" corpSecret=="+corpSecret);
retmap.put("status", "-1");
retmap.put("message", ""+weaver.systeminfo.SystemEnv.getHtmlLabelName(10005341,weaver.general.ThreadVarLanguage.getLang())+"corpId=="+corpId+" corpSecret=="+corpSecret);
return retmap;
}
DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/gettoken");
OapiGettokenRequest request1 = new OapiGettokenRequest();
request1.setAppkey(corpId);
request1.setAppsecret(corpSecret);
request1.setHttpMethod("GET");
OapiGettokenResponse response1 = client.execute(request1);
String accessToken = response1.getAccessToken();
client = new DefaultDingTalkClient("https://oapi.dingtalk.com/attendance/list");
OapiAttendanceListRequest request = new OapiAttendanceListRequest();
request.setWorkDateFrom(fromDate+" 00:00:00");
request.setWorkDateTo(toDate+" 23:59:59");
request.setOffset(0L);
request.setLimit(50L);
List<String> resourceList = new ArrayList<String>();
int ni = 0;
rs.executeQuery("select workcode from hrmresource where workcode is not null and workcode<>''");
while(rs.next()){
ni++;
resourceList.add(Util.formatMultiLang(rs.getString("workcode")));
if(ni%10==0 || ni==rs.getCounts()){
try {
request.setUserIdList(resourceList);
OapiAttendanceListResponse response = client.execute(request, accessToken);
JSONObject jsonData = JSONObject.fromObject(response);
if(!"0".equals(StringUtil.vString(jsonData.get("errcode")))){
writeLog("获取钉钉考勤数据失败:"+jsonData.get("errmsg"));
retmap.put("status", "-1");
retmap.put("message", ""+weaver.systeminfo.SystemEnv.getHtmlLabelName(10005341,weaver.general.ThreadVarLanguage.getLang())+""+jsonData.get("errmsg"));
return retmap;
}
Calendar calendar = Calendar.getInstance();
DateFormat formatterDate = new SimpleDateFormat("yyyy-MM-dd");
// 将钉钉上同步过来的打卡数据去掉后面的秒数显示解决统计迟到时长
DateFormat formatterTime = new SimpleDateFormat("HH:mm:00");
JSONArray jsonList = JSONArray.fromObject(jsonData.get("recordresult"));
for(int i=0;i<jsonList.size();i++){
JSONObject data = jsonList.getJSONObject(i);
String locationResult = StringUtil.vString(data.get("locationResult"));
if("NotSigned".equals(locationResult)){
continue;
}
String userId = StringUtil.vString(data.get("userId"));
String oaUserId = StringUtil.vString(resourceIdMap.get(userId));
if("".equals(oaUserId)){
writeLog("通过工号("+userId+"无法在OA找到对应人员请维护人员信息");
continue;
}
JSONObject jsonCheckTime = JSONObject.fromObject(data.get("userCheckTime"));
if("".equals(StringUtil.vString(jsonCheckTime.get("time")))){
writeLog("获取实际打卡时间失败userId="+userId);
continue;
}
long userCheckTime = StringUtil.parseToLong(jsonCheckTime.get("time"));
calendar.setTimeInMillis(userCheckTime);
String signDate = formatterDate.format(calendar.getTime());
String signTime = formatterTime.format(calendar.getTime());
writeLog("处理钉钉考勤时间格式化完成userId==" + oaUserId + ",signDate==" + signDate + ",signTime==" + signTime);
String checkType = StringUtil.vString(data.get("checkType"));
String signType = "";
if("OnDuty".equals(checkType)){
signType = "1";
}else if("OffDuty".equals(checkType)){
signType = "2";
}else{
writeLog("获取考勤类型失败userId="+userId);
continue;
}
writeLog("获取考勤数据oaUserId="+oaUserId+",userId="+userId+",userCheckTime="+userCheckTime+",locationResult="+locationResult+",checkType="+checkType+",signDate="+signDate+",signTime="+signTime);
rs1.executeUpdate("insert into hrmScheduleSign(userid,userType,signType,signDate,signTime,isInCom,isImport,signFrom) values("+oaUserId+",'1','"+signType+"','"+signDate+"','"+signTime+"','1',1,'DingTalk')");
String formatData = oaUserId+"|"+signDate;
if(!lsFormatData.contains(formatData)){
lsFormatData.add(formatData);
}
}
resourceList = new ArrayList<String>();
} catch (Exception e) {
writeLog(this.getClass().getName(),e);
}
}
}
//刷新报表数据
for(int i=0;lsFormatData!=null&&i<lsFormatData.size();i++){
formatParams = new ArrayList<>();
String[] formatData = Util.splitString(lsFormatData.get(i),"|");
formatParams.add(formatData[0]);
formatParams.add(formatData[1]);
lsFormatParams.add(formatParams);
}
new KQFormatBiz().format(lsFormatParams);
} catch (Exception e) {
writeLog("同步钉钉考勤数据:" + e);
retmap.put("status", "-1");
}
return retmap;
}
@Override
public BizLogContext getLogContext() {
return null;
}
@Override
public List<BizLogContext> getLogContexts() {
return logger.getBizLogContexts();
}
}
Loading…
Cancel
Save