|
@@ -43,6 +43,8 @@ import java.util.stream.Collectors;
|
|
|
@Transactional
|
|
|
public class DingDingServiceImpl implements DingDingService {
|
|
|
private final Logger bizLogger = LoggerFactory.getLogger(getClass());
|
|
|
+ public static final DateTimeFormatter timeDtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
|
|
+ public static final DateTimeFormatter mmDtf = DateTimeFormatter.ofPattern("HH:mm");
|
|
|
long appId = 71020L;
|
|
|
String token = "cf776d62c5fb3508b5d8c2cbb9f3df0c";
|
|
|
String aesKey = "ktmbamhymjsf60ndwp6n81mnu92847oynsgj9e0zr9v";
|
|
@@ -60,6 +62,8 @@ public class DingDingServiceImpl implements DingDingService {
|
|
|
@Resource
|
|
|
SysRoleModuleMapper sysRoleModuleMapper;
|
|
|
@Resource
|
|
|
+ BusinessTripMapper businessTripMapper;
|
|
|
+ @Resource
|
|
|
SysRoleFunctionMapper sysRoleFunctionMapper;
|
|
|
@Resource
|
|
|
private SysRoleMapper sysRoleMapper;
|
|
@@ -264,9 +268,11 @@ public class DingDingServiceImpl implements DingDingService {
|
|
|
//查找默认角色
|
|
|
//默认角色
|
|
|
int roleId = 0;
|
|
|
+ String roleName = null;
|
|
|
List<SysRole> droleList = sysRoleMapper.selectList(new QueryWrapper<SysRole>().eq("company_id", dingding.getCompanyId()).eq("is_default", 1));
|
|
|
if (droleList.size() > 0) {
|
|
|
roleId = droleList.get(0).getId();
|
|
|
+ roleName = droleList.get(0).getRolename();
|
|
|
}
|
|
|
|
|
|
DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/auth/scopes");
|
|
@@ -279,11 +285,11 @@ public class DingDingServiceImpl implements DingDingService {
|
|
|
JSONArray deptArray = json.getJSONObject("auth_org_scopes").getJSONArray("authed_dept");
|
|
|
//如果授权的是全部公司部门,则递归获取子部门和人员
|
|
|
if (deptArray.size() == 1 && deptArray.getLong(0) == 1L) {
|
|
|
- getDepartmentList(roleId, dingding.getCompanyId(), dingding.getCorpid(), accessToken, 1L, null);
|
|
|
+ getDepartmentList(roleId, roleName, dingding.getCompanyId(), dingding.getCorpid(), accessToken, 1L, null);
|
|
|
} else {
|
|
|
for (int i=0;i<deptArray.size(); i++) {
|
|
|
long deptId = deptArray.getLongValue(i);
|
|
|
- getDepartmentDetailAndUserList(roleId, dingding.getCompanyId(), dingding.getCorpid(), accessToken, deptId);
|
|
|
+ getDepartmentDetailAndUserList(roleId, roleName, dingding.getCompanyId(), dingding.getCorpid(), accessToken, deptId);
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -293,7 +299,7 @@ public class DingDingServiceImpl implements DingDingService {
|
|
|
for (int i=0;i<userArray.size(); i++) {
|
|
|
String userdingId = userArray.getString(i);
|
|
|
//获取人员详情
|
|
|
- getUserDetail(roleId, dingding.getCompanyId(), 0, userdingId, accessToken);
|
|
|
+ getUserDetail(roleId, roleName, dingding.getCompanyId(), 0, userdingId, accessToken);
|
|
|
}
|
|
|
} else {
|
|
|
System.err.println("获取通讯录范围出错:" + json.toJSONString());
|
|
@@ -363,15 +369,19 @@ public class DingDingServiceImpl implements DingDingService {
|
|
|
/**
|
|
|
* 获取钉钉内部企业的token
|
|
|
*/
|
|
|
- private OapiGettokenResponse getInnerCorpToken() throws ApiException {
|
|
|
- DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/gettoken");
|
|
|
- OapiGettokenRequest request = new OapiGettokenRequest();
|
|
|
- request.setAppkey(appkey);
|
|
|
- request.setAppsecret(appsecret);
|
|
|
- request.setHttpMethod("GET");
|
|
|
- OapiGettokenResponse response = client.execute(request);
|
|
|
- System.out.println(response.getBody());
|
|
|
- return response;
|
|
|
+ private String getInnerCorpToken(CompanyDingding dingding) throws ApiException {
|
|
|
+ if (dingding.getInnerToken() == null || LocalDateTime.now().isAfter(dingding.getInnerExpireTime())) {
|
|
|
+ DefaultDingTalkClient client= new DefaultDingTalkClient("https://oapi.dingtalk.com/service/get_corp_token");
|
|
|
+ OapiServiceGetCorpTokenRequest req= new OapiServiceGetCorpTokenRequest();
|
|
|
+ req.setAuthCorpid(dingding.getCorpid());
|
|
|
+ OapiServiceGetCorpTokenResponse response= client.execute(req,dingding.getCustomAppkey(),dingding.getCustomAppsecret(),"anything");
|
|
|
+ if (!response.isSuccess()) {
|
|
|
+ System.err.println("获取企业内部token:"+response.getErrorCode()+":"+response.getErrmsg());
|
|
|
+ }
|
|
|
+ dingding.setInnerToken(response.getAccessToken());
|
|
|
+ dingding.setInnerExpireTime(LocalDateTime.now().plusSeconds(response.getExpiresIn()));
|
|
|
+ }
|
|
|
+ return dingding.getInnerToken();
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -740,7 +750,7 @@ public class DingDingServiceImpl implements DingDingService {
|
|
|
}
|
|
|
|
|
|
//获取部门详情和部门下的人员
|
|
|
- public void getDepartmentDetailAndUserList(int roleId, Integer companyId, String corpid, String accessToken, long deptId) {
|
|
|
+ public void getDepartmentDetailAndUserList(int roleId, String roleName, Integer companyId, String corpid, String accessToken, long deptId) {
|
|
|
try {
|
|
|
DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/department/get");
|
|
|
OapiV2DepartmentGetRequest req = new OapiV2DepartmentGetRequest();
|
|
@@ -790,9 +800,9 @@ public class DingDingServiceImpl implements DingDingService {
|
|
|
}
|
|
|
|
|
|
//获取该部门下的人员, 如果是根部门,不会创建,人员的部门id会使用数据库默认的0
|
|
|
- getDeptUserIdList(roleId, companyId, deptId, department.getDepartmentId(), accessToken);
|
|
|
+ getDeptUserIdList(roleId, roleName, companyId, deptId, department.getDepartmentId(), accessToken);
|
|
|
//获取子部门
|
|
|
- getDepartmentList(roleId, companyId, corpid, accessToken, departmentDingding.getDdDeptid(), department.getDepartmentId());
|
|
|
+ getDepartmentList(roleId, roleName, companyId, corpid, accessToken, departmentDingding.getDdDeptid(), department.getDepartmentId());
|
|
|
}
|
|
|
} catch (ApiException e) {
|
|
|
e.printStackTrace();
|
|
@@ -800,7 +810,7 @@ public class DingDingServiceImpl implements DingDingService {
|
|
|
}
|
|
|
|
|
|
//获取该部门下的人员和子部门列表,递归下一级子部门
|
|
|
- public String getDepartmentList(int roleId, Integer companyId, String corpid, String access_token, long parentDeptId, Integer parentSysDeptId) throws ApiException {
|
|
|
+ public String getDepartmentList(int roleId, String roleName, Integer companyId, String corpid, String access_token, long parentDeptId, Integer parentSysDeptId) throws ApiException {
|
|
|
DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/department/listsub");
|
|
|
OapiV2DepartmentListsubRequest req = new OapiV2DepartmentListsubRequest();
|
|
|
req.setDeptId(parentDeptId);
|
|
@@ -835,10 +845,10 @@ public class DingDingServiceImpl implements DingDingService {
|
|
|
}
|
|
|
}
|
|
|
//获取子部门的数据
|
|
|
- getDepartmentList(roleId, companyId, corpid, access_token, departmentDingding.getDdDeptid(), department.getDepartmentId());
|
|
|
+ getDepartmentList(roleId, roleName, companyId, corpid, access_token, departmentDingding.getDdDeptid(), department.getDepartmentId());
|
|
|
}
|
|
|
//获取部门下的人员列表
|
|
|
- getDeptUserIdList(roleId, companyId, parentDeptId, parentSysDeptId, access_token);
|
|
|
+ getDeptUserIdList(roleId, roleName, companyId, parentDeptId, parentSysDeptId, access_token);
|
|
|
} else {
|
|
|
return json.toJSONString();
|
|
|
}
|
|
@@ -846,7 +856,7 @@ public class DingDingServiceImpl implements DingDingService {
|
|
|
}
|
|
|
|
|
|
//获取部门下的人员ids
|
|
|
- public void getDeptUserIdList(int roleId, int companyId, long ddDeptId,Integer sysDeptId, String access_token) throws ApiException {
|
|
|
+ public void getDeptUserIdList(int roleId, String roleName, int companyId, long ddDeptId,Integer sysDeptId, String access_token) throws ApiException {
|
|
|
DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/user/listid");
|
|
|
OapiUserListidRequest req = new OapiUserListidRequest();
|
|
|
req.setDeptId(ddDeptId);
|
|
@@ -857,13 +867,13 @@ public class DingDingServiceImpl implements DingDingService {
|
|
|
JSONArray jsonArray = resp.getJSONObject("result").getJSONArray("userid_list");
|
|
|
for (int i=0;i<jsonArray.size(); i++) {
|
|
|
String dduid = jsonArray.getString(i);
|
|
|
- getUserDetail(roleId, companyId, sysDeptId, dduid, access_token);
|
|
|
+ getUserDetail(roleId, roleName, companyId, sysDeptId, dduid, access_token);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
//获取人员详情
|
|
|
- private void getUserDetail(int roleId, Integer companyId, Integer departmentId, String dingdingUserid, String access_token) throws ApiException {
|
|
|
+ private void getUserDetail(int roleId, String roleName, Integer companyId, Integer departmentId, String dingdingUserid, String access_token) throws ApiException {
|
|
|
DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/user/get");
|
|
|
OapiV2UserGetRequest req = new OapiV2UserGetRequest();
|
|
|
req.setUserid(dingdingUserid);
|
|
@@ -876,6 +886,7 @@ public class DingDingServiceImpl implements DingDingService {
|
|
|
User user = new User();
|
|
|
user.setId(SnowFlake.nextId()+"")
|
|
|
.setRoleId(roleId)
|
|
|
+ .setRoleName(roleName)
|
|
|
.setCompanyId(companyId)
|
|
|
.setDepartmentId(departmentId)
|
|
|
.setName(userJson.getString("name"))
|
|
@@ -1078,17 +1089,22 @@ public class DingDingServiceImpl implements DingDingService {
|
|
|
//指定的某个公司
|
|
|
CompanyDingding dingding = companyDingdingMapper.selectOne(new QueryWrapper<CompanyDingding>().eq("company_id", companyId));
|
|
|
syncOneCompWorkData(dingding, workDate);
|
|
|
- } else {
|
|
|
- //全部的
|
|
|
- List<TimeType> timeTypes = timeTypeMapper.selectList(new QueryWrapper<TimeType>().eq("sync_dingding", 1));
|
|
|
- List<Integer> companyIds = timeTypes.stream().map(TimeType::getCompanyId).collect(Collectors.toList());
|
|
|
- List<CompanyDingding> dingdingList = companyDingdingMapper.selectList(new QueryWrapper<CompanyDingding>().in("company_id", companyIds));
|
|
|
- for (CompanyDingding dingding : dingdingList) {
|
|
|
- syncOneCompWorkData(dingding, workDate);
|
|
|
- }
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ @Override
|
|
|
+ public void getCorpSelfDefSmartReport(CompanyDingding dingding) {
|
|
|
+ DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/attendance/getattcolumns");
|
|
|
+ OapiAttendanceGetattcolumnsRequest req = new OapiAttendanceGetattcolumnsRequest();
|
|
|
+ OapiAttendanceGetattcolumnsResponse rsp = null;
|
|
|
+ try {
|
|
|
+ rsp = client.execute(req, getCorpAccessToken(dingding));
|
|
|
+ } catch (ApiException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ System.out.println(rsp.getBody());
|
|
|
+ }
|
|
|
+
|
|
|
|
|
|
private void syncOneCompLeave(CompanyDingding dingding, String targetUserId, String startDate, String endDate) {
|
|
|
List<User> userList = new ArrayList<>();
|
|
@@ -1206,31 +1222,128 @@ public class DingDingServiceImpl implements DingDingService {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ //获取一个公司的用户考勤数据
|
|
|
private void syncOneCompWorkData(CompanyDingding dingding, String workDate) {
|
|
|
List<User> userList = userMapper.selectList(new QueryWrapper<User>().eq("company_id", dingding.getCompanyId()));
|
|
|
String accessToken = null;
|
|
|
try {
|
|
|
- accessToken = getInnerCorpToken().getAccessToken();
|
|
|
+ accessToken = getInnerCorpToken(dingding);
|
|
|
+ for (User user : userList) {
|
|
|
+ DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/attendance/getupdatedata");
|
|
|
+ OapiAttendanceGetupdatedataRequest req = new OapiAttendanceGetupdatedataRequest();
|
|
|
+ req.setUserid(user.getDingdingUserid());
|
|
|
+ req.setWorkDate(StringUtils.parseDateTime(workDate + " 00:00:00"));
|
|
|
+ OapiAttendanceGetupdatedataResponse rsp = null;
|
|
|
+ try {
|
|
|
+ rsp = client.execute(req, accessToken);
|
|
|
+ System.out.println(user.getName());
|
|
|
+ System.out.println(rsp.getBody());
|
|
|
+ JSONObject json = JSONObject.parseObject(rsp.getBody());
|
|
|
+ JSONObject result = json.getJSONObject("result");
|
|
|
+ //考勤数据
|
|
|
+ JSONArray attendanceList = result.getJSONArray("attendance_result_list");
|
|
|
+ UserDingdingTime cardTime = new UserDingdingTime();
|
|
|
+ cardTime.setCompanyId(dingding.getCompanyId());
|
|
|
+ cardTime.setUserId(user.getId());
|
|
|
+ cardTime.setDingdingCorpid(dingding.getCorpid());
|
|
|
+ cardTime.setDingdingUserid(user.getDingdingUserid());
|
|
|
+ LocalDateTime onDutyEarleast = null;
|
|
|
+ LocalDateTime offDutyLatest = null;
|
|
|
+
|
|
|
+ for (int i=0;i<attendanceList.size(); i++) {
|
|
|
+ JSONObject attItem = attendanceList.getJSONObject(i);
|
|
|
+ String checkType = attItem.getString("check_type");
|
|
|
+ String checkTime = attItem.getString("user_check_time");
|
|
|
+ LocalDateTime dateTime = LocalDateTime.parse(checkTime, timeDtf);
|
|
|
+ cardTime.setWorkDate(dateTime.toLocalDate());
|
|
|
+ //计算周几
|
|
|
+ cardTime.setWeekDay(cardTime.getWorkDate().getDayOfWeek().getValue());
|
|
|
+ cardTime.setWeekDayTxt(DateTimeUtil.getWeekDayTxt(cardTime.getWeekDay()));
|
|
|
+ if ("OnDuty".equals(checkType)) {
|
|
|
+ //上班时间
|
|
|
+ cardTime.setStartTime(mmDtf.format(dateTime));
|
|
|
+ onDutyEarleast = dateTime;
|
|
|
+ } else {
|
|
|
+ //下班
|
|
|
+ cardTime.setEndTime(mmDtf.format(dateTime));
|
|
|
+ offDutyLatest = dateTime;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (onDutyEarleast != null && offDutyLatest != null) {
|
|
|
+ long seconds = (offDutyLatest.getSecond()- onDutyEarleast.getSecond());
|
|
|
+ float hours = (offDutyLatest.getHour() - onDutyEarleast.getHour()) + seconds*1.0f/3600;
|
|
|
+ cardTime.setWorkHours(hours);
|
|
|
+ //对比,看看之前是否已经存了
|
|
|
+ List<UserDingdingTime> old = userDingdingTimeMapper.selectList(new QueryWrapper<UserDingdingTime>().eq("user_id", user.getId())
|
|
|
+ .eq("work_date", cardTime.getWorkDate()));
|
|
|
+ if (old.size() > 0) {
|
|
|
+ cardTime.setId(old.get(0).getId());
|
|
|
+ }
|
|
|
+ userDingdingTimeService.saveOrUpdate(cardTime);
|
|
|
+ }
|
|
|
+
|
|
|
+ //请假和出差的审批单列表
|
|
|
+ JSONArray approveList = result.getJSONArray("approve_list");
|
|
|
+ for (int i=0;i<approveList.size(); i++) {
|
|
|
+ JSONObject item = approveList.getJSONObject(i);
|
|
|
+ String tagName = item.getString("tag_name");
|
|
|
+ if ("出差".equals(tagName)) {
|
|
|
+ BusinessTrip trip = new BusinessTrip();
|
|
|
+ trip.setOwnerId(user.getId());
|
|
|
+ trip.setOwnerName(user.getName());
|
|
|
+ trip.setStartDate(LocalDateTime.parse(item.getString("begin_time"), timeDtf).toLocalDate());
|
|
|
+ trip.setEndDate(LocalDateTime.parse(item.getString("end_time"), timeDtf).toLocalDate());
|
|
|
+ trip.setCompanyId(dingding.getCompanyId());
|
|
|
+ Long cha = trip.getEndDate().toEpochDay() - trip.getStartDate().toEpochDay() + 1;
|
|
|
+ trip.setDayCount(Integer.parseInt(cha.toString()));
|
|
|
+ trip.setStatus(0);
|
|
|
+ int cnt = businessTripMapper.selectCount(new QueryWrapper<BusinessTrip>().eq("owner_id", user.getId())
|
|
|
+ .eq("start_date", trip.getStartDate())
|
|
|
+ .eq("end_date", trip.getEndDate()));
|
|
|
+ if (cnt == 0) {
|
|
|
+ businessTripMapper.insert(trip);
|
|
|
+ }
|
|
|
+ } else if ("请假".equals(tagName)) {
|
|
|
+ LeaveSheet sheet = new LeaveSheet();
|
|
|
+ sheet.setOwnerId(user.getId());
|
|
|
+ sheet.setOwnerName(user.getName());
|
|
|
+ sheet.setStartDate(LocalDateTime.parse(item.getString("begin_time"), timeDtf).toLocalDate());
|
|
|
+ sheet.setEndDate(LocalDateTime.parse(item.getString("end_time"), timeDtf).toLocalDate());
|
|
|
+ Long cha = sheet.getEndDate().toEpochDay() - sheet.getStartDate().toEpochDay() + 1;
|
|
|
+ sheet.setTimeDays((float)cha);
|
|
|
+ sheet.setCompanyId(dingding.getCompanyId());
|
|
|
+ sheet.setStatus(0);
|
|
|
+ String dLeaveType = item.getString("sub_type");
|
|
|
+ if (!dLeaveType.endsWith("假")) dLeaveType = dLeaveType + "假";
|
|
|
+ int leaveTypeIndex = -1;
|
|
|
+ for (int t=0;t<Constant.LEAVE_TYPES.length; t++) {
|
|
|
+ if (Constant.LEAVE_TYPES[t].equals(dLeaveType)) {
|
|
|
+ leaveTypeIndex = t;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (leaveTypeIndex == -1) {
|
|
|
+ leaveTypeIndex = Constant.LEAVE_TYPES.length-1;
|
|
|
+ }
|
|
|
+ sheet.setLeaveType(leaveTypeIndex);
|
|
|
+ int cnt = leaveSheetMapper.selectCount(new QueryWrapper<LeaveSheet>().eq("owner_id", user.getId())
|
|
|
+ .eq("start_date", sheet.getStartDate())
|
|
|
+ .eq("end_date", sheet.getEndDate()));
|
|
|
+ if (cnt == 0) {
|
|
|
+ leaveSheetMapper.insert(sheet);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } catch (ApiException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
} catch (ApiException e) {
|
|
|
e.printStackTrace();
|
|
|
}
|
|
|
- for (User user : userList) {
|
|
|
- DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/attendance/getupdatedata");
|
|
|
- OapiAttendanceGetupdatedataRequest req = new OapiAttendanceGetupdatedataRequest();
|
|
|
- req.setUserid(user.getDingdingUserid());
|
|
|
- req.setWorkDate(StringUtils.parseDateTime(workDate + " 00:00:00"));
|
|
|
- OapiAttendanceGetupdatedataResponse rsp = null;
|
|
|
- try {
|
|
|
- rsp = client.execute(req, accessToken);
|
|
|
- System.out.println(rsp.getBody());
|
|
|
- } catch (ApiException e) {
|
|
|
- e.printStackTrace();
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
}
|
|
|
|
|
|
-
|
|
|
private void syncOneComp(CompanyDingding dingding, String targetUserId, String startDate, String endDate) {
|
|
|
List<User> userList = new ArrayList<>();
|
|
|
if (!StringUtils.isEmpty(targetUserId)) {
|
|
@@ -1264,8 +1377,8 @@ public class DingDingServiceImpl implements DingDingService {
|
|
|
OapiAttendanceListRecordResponse rsp = null;
|
|
|
try {
|
|
|
rsp = client.execute(req, accessToken);
|
|
|
- System.out.println(rsp);
|
|
|
if (rsp.getErrcode() == 0) {
|
|
|
+ System.out.println(rsp.getBody());
|
|
|
//正常
|
|
|
JSONArray array = JSONObject.parseObject(rsp.getBody()).getJSONArray("recordresult");
|
|
|
List<DdingCardTimeItem> list = new ArrayList<DdingCardTimeItem>();
|
|
@@ -1346,12 +1459,10 @@ public class DingDingServiceImpl implements DingDingService {
|
|
|
} else {
|
|
|
//报错了
|
|
|
System.err.println("同步钉钉考勤报错 "+rsp.getErrcode()+":"+rsp.getErrmsg());
|
|
|
- System.err.println("同步钉钉考勤报错 "+rsp.getErrcode()+":"+rsp.getErrmsg());
|
|
|
}
|
|
|
} catch (ApiException e) {
|
|
|
e.printStackTrace();
|
|
|
}
|
|
|
- System.out.println(rsp.getBody());
|
|
|
}
|
|
|
|
|
|
|