Commit 5889223c authored by hongguangwu's avatar hongguangwu

MVP1.6.3-HCM HCM的出差接口

parent 58dd59d5
......@@ -170,6 +170,8 @@ public interface CacheConstants {
// 项目报销token的key
String WX_REIMBURSEMENT_TOKEN = "WX_REIMBURSEMENT_TOKEN";
// HCM出差的sign
String HCM_CHU_CHAI_SIGN = "HCM_CHU_CHAI_SIGN";
public static final String WX_ACCOSS_TOKEN = "WX_ACCOSS_TOKEN";
......
......@@ -52,4 +52,19 @@ public class EkpPermissionTask {
log.info("-------------获取企业微信出差数据-定时任务结束------------");
}
/**
* @return
* @Author hgw
* @Description 每天1点,定时同步HCM审批出差数据
* @Date 2024-4-29 15:59:31
* @Param
**/
public void doSaveHcmChuChai() throws Exception {
log.info("-------------获取HCM出差数据-定时任务开始------------");
HttpDaprUtil.invokeMethodPost(daprEkpPermissionProperties.getAppUrl(), daprEkpPermissionProperties.getAppId(),
"/qiWei/inner/everyDaySaveHcmChuChai", "", Object.class,
SecurityConstants.FROM_IN);
log.info("-------------获取HCM出差数据-定时任务结束------------");
}
}
\ No newline at end of file
......@@ -78,4 +78,8 @@ public class EkpQiwiChuchai {
@Schema(description = "创建时间")
private LocalDateTime createTime;
// 企微、HCM
@Schema(description = "数据源")
private String fdDataSource;
}
\ No newline at end of file
......@@ -10,6 +10,7 @@ import com.yifu.cloud.plus.v1.yifu.common.core.exception.CheckedException;
import com.yifu.cloud.plus.v1.yifu.common.core.util.Common;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Hex;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
......@@ -21,6 +22,8 @@ import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.web.client.RestTemplate;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.util.Map;
import java.util.concurrent.TimeUnit;
......@@ -47,12 +50,54 @@ public class WxConfig {
@Value("${wx.authUrl}")
private String authUrl;
// 获取HCM相关信息
@Value("${hcm.appId}")
private String hcmAppId;
@Value("${hcm.appSecret}")
private String hcmAppSecret;
@Value("${hcm.appUrl}")
private String hcmAppUrl;
@Autowired
private RedisTemplate redisTemplate;
//未授权
private String accossTokenInvliad = "40014";
/**
* @Description: 获取HCM出差的sign
* @Author: hgw
* @Date: 2024-4-29 15:34:54
* @return: java.lang.String
**/
public String getHcmSign() {
String sign = null;
Object wxToken = redisTemplate.opsForValue().get(CacheConstants.HCM_CHU_CHAI_SIGN);
if (null != wxToken) {
return String.valueOf(wxToken);
}
try {
byte[] a = (hcmAppId + hcmAppSecret).getBytes(StandardCharsets.UTF_8);
sign = Hex.encodeHexString(MessageDigest.getInstance("SHA-256").digest(a));
} catch (Exception e) {
e.printStackTrace();
log.error("2拉取HCM出差数据sign出错=" + e.getMessage());
}
redisTemplate.opsForValue().set(CacheConstants.HCM_CHU_CHAI_SIGN, sign);
redisTemplate.expire(CacheConstants.HCM_CHU_CHAI_SIGN, 3600, TimeUnit.SECONDS);
return sign;
}
/**
* @Description: 获取HCM出差的url
* @Author: hgw
* @Date: 2024-4-29 15:34:54
* @return: java.lang.String
**/
public String getHcmChuChaiUrl() {
return hcmAppUrl;
}
/**
* @param restTemplate
* @Description: 获取项目报销的token
......
......@@ -38,7 +38,7 @@ public class QiWeiController {
public R<List<EkpQiwiChuchai>> everyDaySaveQiWeiChuChai() {
String startDay = DateUtil.addDay(-29);
String endDay = DateUtil.addDay(0);
return wxSalaryService.getQiWeiChuChaiAndSave(startDay, endDay);
return wxSalaryService.getQiWeiChuChaiAndSave(startDay, endDay, 1);
}
/**
......@@ -53,7 +53,36 @@ public class QiWeiController {
@PostMapping("/getQiWeiChuCHaiInfoAndSave")
//@PreAuthorize("@pms.hasPermission('wxhr:wxsalaryauth')")
public R<List<EkpQiwiChuchai>> getQiWeiChuCHaiInfoAndSave(@RequestParam String startTime, @RequestParam String endTime) {
return wxSalaryService.getQiWeiChuChaiAndSave(startTime, endTime);
return wxSalaryService.getQiWeiChuChaiAndSave(startTime, endTime, 1);
}
/**
* @Description: 每日获取当日HCM的E人事审批里的出差
* @Author: hgw
* @Date: 2024-4-28 16:51:16
* @return: com.yifu.cloud.v1.common.core.util.R<java.util.List < com.yifu.cloud.v1.hrms.api.entity.TEventFeeDetail>>
**/
@PostMapping("/inner/everyDaySaveHcmChuChai")
@Inner
public R<List<EkpQiwiChuchai>> everyDaySaveHcmChuChai() {
String startDay = DateUtil.addDay(-1);
String endDay = DateUtil.addDay(0);
return wxSalaryService.getQiWeiChuChaiAndSave(startDay, endDay, 2);
}
/**
* @param startTime
* @param endTime
* @Description: 获取HCM的E人事审批里的出差
* @Author: hgw
* @Date: 2024-4-28 16:51:39
* @return: com.yifu.cloud.v1.common.core.util.R<java.util.List < com.yifu.cloud.v1.hrms.api.entity.TStatisticsProjectReimburse>>
**/
@Operation(description = "获取HCM的E人事审批里的出差:startTime格式:2024-04-10")
@PostMapping("/getHcmChuChaiInfoAndSave")
//@PreAuthorize("@pms.hasPermission('wxhr:wxsalaryauth')")
public R<List<EkpQiwiChuchai>> getHcmChuChaiInfoAndSave(@RequestParam String startTime, @RequestParam String endTime) {
return wxSalaryService.getQiWeiChuChaiAndSave(startTime, endTime, 2);
}
}
......@@ -17,11 +17,12 @@ public interface QiWeiService extends IService<EkpQiwiChuchai> {
/**
* @param startTime
* @param endTime
* @param type 1:企业微信;2:HCM的E人事
* @Description: 获取微信信息
* @Author: hgw
* @Date: 2021-7-28 17:46:01
* @return: com.yifu.cloud.v1.common.core.util.R<java.util.List < com.yifu.cloud.v1.hrms.api.entity.TStatisticsProjectReimburse>>
**/
R<List<EkpQiwiChuchai>> getQiWeiChuChaiAndSave(String startTime, String endTime);
R<List<EkpQiwiChuchai>> getQiWeiChuChaiAndSave(String startTime, String endTime, int type);
}
......@@ -10,10 +10,16 @@ import com.yifu.cloud.plus.v1.permission.service.QiWeiService;
import com.yifu.cloud.plus.v1.yifu.common.core.constant.CommonConstants;
import com.yifu.cloud.plus.v1.yifu.common.core.constant.SecurityConstants;
import com.yifu.cloud.plus.v1.yifu.common.core.util.Common;
import com.yifu.cloud.plus.v1.yifu.common.core.util.LocalDateTimeUtils;
import com.yifu.cloud.plus.v1.yifu.common.core.util.R;
import com.yifu.cloud.plus.v1.yifu.insurances.util.LocalDateUtil;
import com.yifu.cloud.plus.v1.yifu.permission.entity.EkpQiwiChuchai;
import com.yifu.cloud.plus.v1.yifu.permission.vo.QiWeiUserVo;
import lombok.AllArgsConstructor;
import lombok.Data;
import org.apache.commons.codec.binary.Hex;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
......@@ -21,6 +27,9 @@ import org.springframework.security.authentication.AuthenticationServiceExceptio
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.time.*;
import java.time.format.DateTimeFormatter;
......@@ -46,13 +55,14 @@ public class QiWeiServiceImpl extends ServiceImpl<EkpQiweiChuchaiMapper, EkpQiwi
/**
* @param startTime
* @param endTime
* @param type 1:企业微信;2:HCM的E人事
* @Description: 获取所有的出差
* @Author: hgw
* @Date: 2021/3/24 15:41
* @return: com.yifu.cloud.v1.common.core.util.R<java.util.List < com.yifu.cloud.v1.hrms.api.entity.TStatisticsProjectReimburse>>
**/
@Override
public synchronized R<List<EkpQiwiChuchai>> getQiWeiChuChaiAndSave(String startTime, String endTime) {
public synchronized R<List<EkpQiwiChuchai>> getQiWeiChuChaiAndSave(String startTime, String endTime, int type) {
try {
// 起止时间
DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
......@@ -64,6 +74,8 @@ public class QiWeiServiceImpl extends ServiceImpl<EkpQiweiChuchaiMapper, EkpQiwi
if (days > 30) {
return R.failed("时间范围超过30天了:起:" + startTime + ";止:" + endTime);
}
String startTimes = startTime + " 00:00:00";
String endTimes = endTime + " 23:59:59";
// 获取起月份的起止时间
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date startTimeDate = sdf.parse(startTime + " 00:00:00");
......@@ -75,28 +87,49 @@ public class QiWeiServiceImpl extends ServiceImpl<EkpQiweiChuchaiMapper, EkpQiwi
endTime = String.valueOf(rightNow.getTime().getTime() / 1000);
// 已被拉取的Map
Map<String, String> cpMap = this.getAllMap();
Map<String, String> cpMap = new HashMap<>();
// 企微姓名Map
Map<String, String> userMap = this.getUserMap();
Map<String, String> userMap = new HashMap<>();
// 一个月的全量数据
List<EkpQiwiChuchai> cpAllList = new ArrayList<>();
List<EkpQiwiChuchai> returnCpList = new ArrayList<>();
this.getCostPaymentListByMonth(startTime, endTime, cpAllList);
log.error("1拉取企业微信出差数据cpAllList.size()=" + cpAllList.size());
if (!cpAllList.isEmpty()) {
for (EkpQiwiChuchai cp : cpAllList) {
if (cpMap.get(cp.getFdSpNo()) == null) {
returnCpList.add(cp);
// type 1:企业微信;2:HCM的E人事
if (type == 1) {
// 已被拉取的Map
cpMap = this.getAllMap();
// 企微姓名Map
userMap = this.getUserMap();
this.getCostPaymentListByMonth(startTime, endTime, cpAllList);
log.error("1拉取企业微信出差数据cpAllList.size()=" + cpAllList.size());
if (!cpAllList.isEmpty()) {
for (EkpQiwiChuchai cp : cpAllList) {
if (cpMap.get(cp.getFdSpNo()) == null) {
returnCpList.add(cp);
}
}
}
}
log.error("1拉取企业微信出差数据returnCpList.size()=" + returnCpList.size());
// 填充详情
if (!returnCpList.isEmpty()) {
log.error("拉取企业微信出差数据:"+returnCpList.size()+" 条,开始循环拉取明细!");
this.getTStatisticsProjectReimburseDetail(returnCpList, userMap);
log.error("拉取企业微信出差数据结束");
log.error("1拉取企业微信出差数据returnCpList.size()=" + returnCpList.size());
// 填充详情
if (!returnCpList.isEmpty()) {
log.error("拉取企业微信出差数据:"+returnCpList.size()+" 条,开始循环拉取明细!");
this.getTStatisticsProjectReimburseDetail(returnCpList, userMap);
log.error("拉取企业微信出差数据结束");
}
} else {
// type 2:HCM的E人事
// 已被拉取的Map
cpMap = this.getAllMap();
this.getChuChaiListByHcm(startTimes, endTimes, cpAllList);
log.error("2拉取HCM的E人事出差数据cpAllList.size()=" + cpAllList.size());
if (!cpAllList.isEmpty()) {
for (EkpQiwiChuchai cp : cpAllList) {
if (cpMap.get(cp.getFdSpNo()) == null) {
returnCpList.add(cp);
}
}
}
log.error("2拉取HCM的E人事出差数据returnCpList.size()=" + returnCpList.size());
}
// 填充基础数据并保存:
if (!returnCpList.isEmpty()) {
......@@ -190,6 +223,121 @@ public class QiWeiServiceImpl extends ServiceImpl<EkpQiweiChuchaiMapper, EkpQiwi
return new R<>(cpList);
}
/**
* @Description: 从HCM-获取所有的出差信息
* @Author: hgw
* @Date: 2024-4-28 17:02:01
* @return: java.util.List<com.yifu.cloud.v1.hrms.api.entity.TStatisticsProjectReimburse>
**/
private R<String> getChuChaiListByHcm(String startTime, String endTime, List<EkpQiwiChuchai> cpList) {
//测试环境:
// String appId = "627673F79C6BAB92"
//String appSecret = "EA2641EF627673F79C6BAB9280137F00"
//线上环境:
// String appId = "627673F79C6BAB92"
//String appSecret = "EA2641EF627673F79C6BAB9280137F00"
// HCM的签名 0501be43d7249b4b82a916be67ee88b08f721b02dd590812deec0ba03361afda
String sign = wxConfig.getHcmSign();
if (Common.isEmpty(sign)) {
return R.failed("获取HCM的sign失败!");
}
String appUrl = wxConfig.getHcmAppUrl();
if (Common.isEmpty(appUrl)) {
return R.failed("获取HCM的appUrl失败!");
}
log.error("1拉取HCM出差数据sign=" + sign);
HttpHeaders headers = new HttpHeaders();
MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8");
headers.setContentType(type);
headers.add("Accept", MediaType.APPLICATION_JSON.toString());
headers.add("sign", sign);
HttpEntity<String> formEntity = new HttpEntity<>(headers);
// 线上地址 appUrl = "http://119.96.166.49:28950/api/v1/instance/business/list?startTime={startTime}&endTime={endTime}"
// 测试地址 appUrl = "https://qas-hcm.yfzxtech.com:28950/api/v1/instance/business/list?startTime={startTime}&endTime={endTime}"
String dataResultList = restTemplate.postForEntity(appUrl, formEntity, String.class, startTime, endTime).getBody();
log.error("1拉取HCM出差数据dataResultList=" + dataResultList);
if (Common.isEmpty(dataResultList)) {
throw new AuthenticationServiceException("获取HCM出差数据失败");
}
JSONObject jsonObject = JSON.parseObject(dataResultList);
String code = jsonObject.getString("code");
String msg = jsonObject.getString("msg");
if (!"200".equals(code)) {
return R.failed(msg);
}
// 时间段内的总审批单个数
EkpQiwiChuchai reimburse;
String data = jsonObject.getString("data");
if (Common.isNotNull(data)) {
List<JSONObject> dataList = JSON.parseArray(data, JSONObject.class);
String formatterTime = LocalDateTimeUtils.DATE_TIME_PATTERN;
JSONObject formData;
String person;
int renShu;
int renShu1;
int renShu2;
String dataSource = "HCM";
for (JSONObject datas : dataList) {
reimburse = new EkpQiwiChuchai();
reimburse.setFdDataSource(dataSource);
if (Common.isNotNull(datas.getString("applyTimeFormat"))) {
reimburse.setFdApplyDate(LocalDateTimeUtils.formatTime(datas.getString("applyTimeFormat"), formatterTime));
}
reimburse.setFdApplyUserName(datas.getString("applyName"));
reimburse.setFdSpNo(datas.getString("flowId"));
reimburse.setFdStatus(CommonConstants.ZERO_STRING);
reimburse.setCreateTime(LocalDateTime.now());
reimburse.setFdApplyUserDept(datas.getString("applyDeptName"));
if (Common.isNotNull(datas.getString("startTimeFormat"))) {
reimburse.setFdNewBegin(LocalDateUtil.parseLocalDate(datas.getString("startTimeFormat")));
}
if (Common.isNotNull(datas.getString("endTimeFormat"))) {
reimburse.setFdNewEnd(LocalDateUtil.parseLocalDate(datas.getString("endTimeFormat")));
}
reimburse.setFdReason(datas.getString("initiationReason"));
if (Common.isNotNull(datas.getString("formData"))) {
formData = JSON.parseObject(datas.getString("formData"));
person = formData.getString("随行人员");
renShu = 1;
if (Common.isNotNull(person)) {
renShu1 = person.split(",").length;
renShu2 = person.split(",").length;
if (renShu1 > renShu2) {
renShu +=renShu1;
} else {
renShu +=renShu2;
}
}
List<JSONObject> toolList = JSON.parseArray(formData.getString("出行工具"), JSONObject.class);
String tools = null;
int i=0;
if (toolList != null && !toolList.isEmpty()) {
for (JSONObject tool : toolList) {
if (i++ == 0) {
tools = tool.getString("label");
} else {
tools += "," + tool.getString("label");
}
}
}
reimburse.setFdRenShu(renShu);
reimburse.setFdPerson(person);
reimburse.setFdAddress(formData.getString("出差地点"));
reimburse.setFdOldAddress(formData.getString("出发地点"));
reimburse.setFdTools(tools);
reimburse.setFdAddressLevel(formData.getString("出差地点级别"));
reimburse.setFdJiaoTong(formData.getString("交通补助"));
reimburse.setFdCanYin(formData.getString("餐饮补助"));
}
cpList.add(reimburse);
}
}
return R.ok();
}
/**
* @Description: 从企业微信-获取详情
* @Author: hgw
......@@ -298,6 +446,7 @@ public class QiWeiServiceImpl extends ServiceImpl<EkpQiweiChuchaiMapper, EkpQiwi
private void setTStatisticsProjectReimburseDetail(String info, EkpQiwiChuchai reimburse, Map<String, String> userMap) {
JSONObject jsonObject = JSON.parseObject(info);
if (Common.isNotNull(info)) {
reimburse.setFdDataSource("企微");
reimburse.setCreateTime(LocalDateTime.now());
String userId = ((JSONObject) jsonObject.get("applyer")).getString("userid");
if (Common.isNotNull(userId) && userMap.get(userId) != null) {
......
......@@ -26,3 +26,7 @@ spring:
maximum-pool-size: 12 # 连接池最大连接数,默认是10
auto-commit: true #此属性控制从池返回的连接的默认自动提交行为,默认值:true
max-lifetime: 0 #此属性控制池中连接的最长生命周期,值0表示无限生命周期,默认1800000即30分钟
hcm:
appId: 627673F79C6BAB92
appSecret: EA2641EF627673F79C6BAB9280137F00
appUrl: https://qas-hcm.yfzxtech.com:28950/api/v1/instance/business/list?startTime={startTime}&endTime={endTime}
\ No newline at end of file
......@@ -26,3 +26,7 @@ spring:
maximum-pool-size: 12 # 连接池最大连接数,默认是10
auto-commit: true #此属性控制从池返回的连接的默认自动提交行为,默认值:true
max-lifetime: 0 #此属性控制池中连接的最长生命周期,值0表示无限生命周期,默认1800000即30分钟
hcm:
appId: b2475bbd0a7ef3f3
appSecret: C800A676B2475BBD0A7EF3F3C4265582
appUrl: https://119.96.166.49:28950/api/v1/instance/business/list?startTime={startTime}&endTime={endTime}
\ No newline at end of file
......@@ -26,3 +26,7 @@ spring:
maximum-pool-size: 12 # 连接池最大连接数,默认是10
auto-commit: true #此属性控制从池返回的连接的默认自动提交行为,默认值:true
max-lifetime: 0 #此属性控制池中连接的最长生命周期,值0表示无限生命周期,默认1800000即30分钟
hcm:
appId: 627673F79C6BAB92
appSecret: EA2641EF627673F79C6BAB9280137F00
appUrl: https://qas-hcm.yfzxtech.com:28950/api/v1/instance/business/list?startTime={startTime}&endTime={endTime}
\ No newline at end of file
......@@ -24,6 +24,7 @@
<result property="fdStatus" column="FD_STATUS"/>
<result property="fdSettleFormId" column="FD_SETTLE_FORM_ID"/>
<result property="createTime" column="create_time"/>
<result property="fdDataSource" column="FD_DATA_SOURCE"/>
</resultMap>
<sql id="Base_Column_List">
......@@ -45,7 +46,8 @@
a.FD_REN_SHU,
a.FD_STATUS,
a.FD_SETTLE_FORM_ID,
a.create_time
a.create_time,
a.FD_DATA_SOURCE
</sql>
<!--获取全部的,用来: 拉取企业微信时,不覆盖数据 -->
<select id="getAllInfo" resultMap="BaseResultMap">
......
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