diff --git a/src/com/engine/hrm/cmd/emmanager/SynKqData4EMCmd.java b/src/com/engine/hrm/cmd/emmanager/SynKqData4EMCmd.java new file mode 100644 index 0000000..155b2b1 --- /dev/null +++ b/src/com/engine/hrm/cmd/emmanager/SynKqData4EMCmd.java @@ -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> { + private static SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + + public SynKqData4EMCmd(Map 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 execute(CommandContext commandContext) { + Map retmap = new HashMap(); + String sql = ""; + RecordSet rs = new RecordSet(); + BatchRecordSet bRs = new BatchRecordSet(); + List> lsParam = new ArrayList<>(); + List> lsParam_out = new ArrayList<>(); + List param = null; + List param_out = null; + + List> lsDelParams = new ArrayList<>(); + List> lsDelParams_out = new ArrayList<>(); + List delParams = null; + + List lsFormatData = new ArrayList<>(); + List lsFormatData_out = new ArrayList<>(); + List> lsFormatParams = new ArrayList<>(); + List 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> overtimeMap = Maps.newHashMap(); + List overtimeList = Lists.newArrayList(); + //刷新报表数据 + for(int i=0;lsFormatData!=null&&i(); + 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 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(); + 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 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 tasks = new ArrayList<>(); + for(Map.Entry> mme: overtimeMap.entrySet()){ + String resid = mme.getKey(); + List 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; + } + +} diff --git a/src/com/engine/kq/cmd/schedulesignimport/SynDingTalkDataCmd.java b/src/com/engine/kq/cmd/schedulesignimport/SynDingTalkDataCmd.java new file mode 100644 index 0000000..d090e5d --- /dev/null +++ b/src/com/engine/kq/cmd/schedulesignimport/SynDingTalkDataCmd.java @@ -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> { + private SimpleBizLogger logger; + public SynDingTalkDataCmd(Map params) { + this.params = params; + } + + @Override + public Map execute(CommandContext commandContext) { + Map retmap = new HashMap(); + 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 lsFormatData = new ArrayList<>(); + List> lsFormatParams = new ArrayList<>(); + List formatParams = null; + + rs.executeUpdate("delete HrmScheduleSign where isimport=1 and signdate>='"+fromDate+"' and signdate<='"+toDate+"'"); + + Map resourceIdMap = new HashMap(); + 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 resourceList = new ArrayList(); + 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(); + } catch (Exception e) { + writeLog(this.getClass().getName(),e); + } + } + } + + //刷新报表数据 + for(int i=0;lsFormatData!=null&&i(); + 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 getLogContexts() { + return logger.getBizLogContexts(); + } + +}