|
|
@@ -0,0 +1,334 @@
|
|
|
+package com.malk.dali.service.Impl;
|
|
|
+
|
|
|
+import cn.hutool.core.date.DateUtil;
|
|
|
+import cn.hutool.core.util.ObjectUtil;
|
|
|
+import com.alibaba.fastjson.JSON;
|
|
|
+import com.alibaba.fastjson.JSONObject;
|
|
|
+import com.malk.dali.entity.DocumentHeader;
|
|
|
+import com.malk.dali.server.yunjian.DDR;
|
|
|
+import com.malk.dali.service.PayService;
|
|
|
+import com.malk.service.dingtalk.DDClient;
|
|
|
+import com.malk.service.dingtalk.DDClient_Personnel;
|
|
|
+import com.malk.service.dingtalk.DDClient_Workflow;
|
|
|
+import com.malk.utils.UtilDateTime;
|
|
|
+import com.malk.utils.UtilMap;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.apache.commons.collections4.map.HashedMap;
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.beans.factory.annotation.Value;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+
|
|
|
+import java.math.BigDecimal;
|
|
|
+import java.time.LocalDateTime;
|
|
|
+import java.util.*;
|
|
|
+import java.util.concurrent.ConcurrentHashMap;
|
|
|
+import java.util.stream.Collectors;
|
|
|
+
|
|
|
+@Service
|
|
|
+@Slf4j
|
|
|
+public class PayServiceImpl implements PayService {
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private DDClient ddClient;
|
|
|
+ @Autowired
|
|
|
+ private DDClient_Workflow ddClient_workflow;
|
|
|
+ @Autowired
|
|
|
+ private DDClient_Personnel ddClientPersonnel;
|
|
|
+ @Value("${dingtalk.appKey}")
|
|
|
+ private String APP_EKY;
|
|
|
+ @Value("${dingtalk.appSecret}")
|
|
|
+ private String APP_SECRET;
|
|
|
+ @Value("${dingtalk.agentId}")
|
|
|
+ private Long agentId;
|
|
|
+ @Value("${yunjian.client_id}")
|
|
|
+ private String clientId;
|
|
|
+ @Value("${yunjian.client_secret}")
|
|
|
+ private String clientSecret;
|
|
|
+ @Value("${yunjian.url}")
|
|
|
+ private String yjHost;
|
|
|
+
|
|
|
+
|
|
|
+ private static final String API_TOKEN = "/common/unAuth/tokens/generate";
|
|
|
+ private static final String POST_DATA_URL = "/common/document";
|
|
|
+ private static final String FIND_BY_CODES = "/common/users/v2/findByCodes";
|
|
|
+ private static final String FIND_COMPANY = "/common/departments/v2/findByCode";
|
|
|
+ private ConcurrentHashMap<String, LocalDateTime> tokenStore = new ConcurrentHashMap<>();
|
|
|
+ //出差类型枚举
|
|
|
+ private static final Map<String, String> BUSINESS_TYPE = new HashMap<>();
|
|
|
+
|
|
|
+ static {
|
|
|
+ BUSINESS_TYPE.put("境内", "01");
|
|
|
+ BUSINESS_TYPE.put("境外", "02");
|
|
|
+ BUSINESS_TYPE.put("短期培训", "03");
|
|
|
+ }
|
|
|
+
|
|
|
+ //出差交通工具工具枚举
|
|
|
+ private static final Map<String, String> BUSINESS_TOOL = new HashMap<>();
|
|
|
+
|
|
|
+ static {
|
|
|
+ BUSINESS_TOOL.put("飞机", "1");
|
|
|
+ BUSINESS_TOOL.put("高铁", "2");
|
|
|
+ BUSINESS_TOOL.put("火车", "3");
|
|
|
+ BUSINESS_TOOL.put("汽车", "4");
|
|
|
+ BUSINESS_TOOL.put("其他", "5");
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void synchronousAndPush(String processInstanceId) {
|
|
|
+ Map formData = queryOAById(processInstanceId);
|
|
|
+ final String[] token = {""};
|
|
|
+ final boolean[] isHave = {false};
|
|
|
+ tokenStore.forEach((k, v) -> {
|
|
|
+ if (validateToken(k)) {
|
|
|
+ token[0] = k;
|
|
|
+ isHave[0] = true;
|
|
|
+ }
|
|
|
+ });
|
|
|
+ if (!isHave[0]) {
|
|
|
+ token[0] = getToken();
|
|
|
+ }
|
|
|
+ HashMap<String, Object> param = new HashMap<>();
|
|
|
+ param.put("access_token", token[0]);
|
|
|
+ //获取申请人数据
|
|
|
+ List<Map> userName = new ArrayList<>();
|
|
|
+ try {
|
|
|
+ List<String> userIds = Arrays.asList(formData.get("userId").toString());
|
|
|
+ List<String> workNumbers = getNumberByUserId(userIds);
|
|
|
+ log.info("获取申请人工号:{}",workNumbers.toString());
|
|
|
+ userName = getUserFormByNumber(workNumbers, token[0]);
|
|
|
+ log.info("获取申请人云简平台信息:{}",workNumbers);
|
|
|
+ } catch (NullPointerException e) {
|
|
|
+ log.info("云简平台查无此人,请检查钉钉和云简员工号是否对应");
|
|
|
+ }
|
|
|
+ //获取同行人数据
|
|
|
+ List<Object> names = new ArrayList<>();
|
|
|
+ if (ObjectUtil.isNotNull(formData.get("出行人(同行人)"))){
|
|
|
+ List<String> companionsUserIds = (List<String>)formData.get("出行人(同行人)");
|
|
|
+ List<String> companionsWorkNumbers = getNumberByUserId(companionsUserIds);
|
|
|
+ List<Map> companionsUserName = getUserFormByNumber(companionsWorkNumbers, token[0]);
|
|
|
+ names = companionsUserName.stream().map(item -> item.get("name")).collect(Collectors.toList());
|
|
|
+ }
|
|
|
+ BigDecimal defaultValue = new BigDecimal("0.0");
|
|
|
+ for (Map detail : (List<Map>) formData.get("日程")) {
|
|
|
+ if ("汽车".equals(detail.get("交通工具"))){
|
|
|
+ detail.put("出发城市",UtilMap.getString(detail,"出发城市").split("市")[0]);
|
|
|
+ detail.put("目的城市",UtilMap.getString(detail,"目的城市").split("市")[0]);
|
|
|
+ }
|
|
|
+ // 生成UUID
|
|
|
+ String uuid = UUID.randomUUID().toString();
|
|
|
+ DocumentHeader documentHeader = new DocumentHeader();
|
|
|
+// documentHeader.setExternal_id(formData.get("出差流水号").toString());
|
|
|
+ documentHeader.setExternal_id(uuid);
|
|
|
+ documentHeader.setHeader_type_code("SQ001");
|
|
|
+ documentHeader.setStatus("approved");
|
|
|
+ documentHeader.setCreated_by_code(userName.get(0).get("code").toString());//
|
|
|
+// documentHeader.setCreatedByCode(formData.get("userId").toString());
|
|
|
+// documentHeader.setSubmitUserCode(formData.get("userId").toString());
|
|
|
+ documentHeader.setSubmit_user_code(userName.get(0).get("code").toString());//
|
|
|
+ documentHeader.setSubmit_date(Long.valueOf(formData.get("createTime").toString()));
|
|
|
+ documentHeader.setBranch_code(getCompany(userName.get(0).get("depCode").toString(),token[0]));
|
|
|
+ documentHeader.setSubmit_department_code(userName.get(0).get("depCode").toString());//
|
|
|
+ documentHeader.setColumn1(formData.get("出差类型") == null ? "" : BUSINESS_TYPE.get(formData.get("出差类型").toString()));
|
|
|
+// documentHeader.setColumn1("1");
|
|
|
+ documentHeader.setStart_datetime(DateUtil.parse(detail.get("开始时间").toString(), "yyyy-MM-dd").getTime());
|
|
|
+ documentHeader.setEnd_datetime(DateUtil.parse(detail.get("结束时间").toString(), "yyyy-MM-dd").getTime());
|
|
|
+ documentHeader.setColumn2(formData.get("出差天数").toString());
|
|
|
+ documentHeader.setDestination_city_name(detail.get("出发城市").toString());
|
|
|
+ documentHeader.setDestination_city_to_name(detail.get("目的城市").toString());
|
|
|
+ documentHeader.setDestination_cities(detail.get("目的城市").toString());
|
|
|
+ documentHeader.setColumn15(BUSINESS_TOOL.get(detail.get("交通工具").toString()));
|
|
|
+ documentHeader.setColumn16(names.toString().replace("[","").replace("]",""));//同行人
|
|
|
+ documentHeader.setDescription(formData.get("备注") == null ? "" : formData.get("备注").toString());
|
|
|
+// documentHeader.setDescription("123123");
|
|
|
+ documentHeader.setTotal_amount(defaultValue);
|
|
|
+ documentHeader.setTotal_claim_amount(defaultValue);
|
|
|
+ documentHeader.setTotal_pay_amount(defaultValue);
|
|
|
+ documentHeader.setTotal_net_amount(defaultValue);
|
|
|
+ documentHeader.setTotal_tax_amount(defaultValue);
|
|
|
+ documentHeader.setTotal_pay_currency_amount(defaultValue);
|
|
|
+
|
|
|
+ log.info("documentHeader:{}",documentHeader.toString());
|
|
|
+ HashMap<String, Object> data = new HashMap<>();
|
|
|
+ data.put("header", documentHeader);
|
|
|
+ Map<String, Object> body = UtilMap.map("bizId, timestamp, data", uuid, new Date().getTime(), data);
|
|
|
+ DDR.doPost(getRequestUrl(POST_DATA_URL), null, param, body);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public String getToken() {
|
|
|
+ HashMap<String, Object> map = new HashMap<>();
|
|
|
+ map.put("client_id", clientId);
|
|
|
+ map.put("client_secret", clientSecret);
|
|
|
+ DDR ddr = DDR.doPost(getRequestUrl(API_TOKEN), null, null, map);
|
|
|
+ if (ObjectUtil.isNotNull(ddr.getData())) {
|
|
|
+ JSONObject data = JSONObject.parseObject(ddr.getData().toString());
|
|
|
+ addToken(data.get("access_token").toString(), 10);
|
|
|
+ return data.get("access_token").toString();
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void addToken(String token, int expireMinutes) {
|
|
|
+ LocalDateTime expirationTime = LocalDateTime.now().plusMinutes(expireMinutes);
|
|
|
+ tokenStore.put(token, expirationTime);
|
|
|
+ }
|
|
|
+
|
|
|
+ public boolean validateToken(String token) {
|
|
|
+ LocalDateTime expirationTime = tokenStore.get(token);
|
|
|
+ if (expirationTime == null || expirationTime.isBefore(LocalDateTime.now())) {
|
|
|
+ tokenStore.remove(token); // 清理过期 Token
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void testToken() {
|
|
|
+ getToken();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void testGet(String id) {
|
|
|
+ synchronousAndPush(id);
|
|
|
+ }
|
|
|
+
|
|
|
+ public Map queryOAById(String processInstanceId) {
|
|
|
+ String[] compsId_main = {"发票抬头", "备注", "出差天数", "出差事由", "出差备注", "出行人(同行人)", "外部人员", "出差流水号", "日程", "出差类型"};
|
|
|
+ String[] compsId_itinerary = {"交通工具", "单程往返", "出发城市", "目的城市", "开始时间", "结束时间", "时长"};
|
|
|
+// syncYD(processInstanceId, "FORM-210DA087671044F8A5CD72F0E9E89060SZ8Q", compsId_main, compsId_itinerary, "itinerary");
|
|
|
+ String token = ddClient.getAccessToken(APP_EKY, APP_SECRET);
|
|
|
+
|
|
|
+ Map processData = ddClient_workflow.getProcessInstanceId(token, processInstanceId);
|
|
|
+ List<Map> formComponentValues = (List<Map>) processData.get("formComponentValues");
|
|
|
+ log.info("开始获取OA数据:{}",formComponentValues);
|
|
|
+
|
|
|
+ String userId = String.valueOf(processData.get("originatorUserId"));
|
|
|
+ long cDate = UtilDateTime.parse(UtilMap.getString(processData, "createTime"), "yyyy-MM-dd'T'HH:mm").getTime();
|
|
|
+ Map formData = UtilMap.map("userId, depId, createTime, textField_lygnetw9", userId, processData.get("originatorDeptId"), cDate, UtilMap.getString(processData, "businessId"));
|
|
|
+
|
|
|
+ for (String name : compsId_main) {
|
|
|
+ String compId = name;
|
|
|
+ // 判定是否子表 [宜搭]
|
|
|
+ if (compId.endsWith("日程")) {
|
|
|
+ List<Map> details = new ArrayList<>();
|
|
|
+ // 兼容明细组件, 存在多条情况 [加班跨天才有有明细]
|
|
|
+ Optional optional = formComponentValues.stream().filter(item -> "itinerary".equals(item.get("bizAlias"))).findAny();
|
|
|
+ if (!optional.isPresent()) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ String schedule = UtilMap.getString((Map) optional.get(), "value");
|
|
|
+ List<Map> itineraryList = ((List<Map>) JSON.parse(schedule));
|
|
|
+ // 循环明细数据
|
|
|
+ for (Map itinerary : itineraryList) {
|
|
|
+ List<Map> rowValue = (List<Map>) itinerary.get("rowValue");
|
|
|
+ Map rowData = new HashedMap();
|
|
|
+ // 循环子表组件
|
|
|
+ for (String subName : compsId_itinerary) {
|
|
|
+ log.info("子表字段, {}", subName);
|
|
|
+ // 加班单跨天 [子表label为空]
|
|
|
+ rowData.put(subName, rowValue.stream().filter(item -> subName.equals(item.get("bizAlias")) || subName.equals(item.get("label"))).findAny().get().get("value"));
|
|
|
+ }
|
|
|
+ details.add(rowData);
|
|
|
+ }
|
|
|
+ formData.put(compId, details);
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ log.info("主表字段, {}", name);
|
|
|
+ // 请假套件: 开始时间 / 结束时间 / 时长 / 单位 / 请假类型
|
|
|
+ if ("DDHolidayField".equals(name)) {
|
|
|
+ Optional optional = formComponentValues.stream().filter(item -> "DDHolidayField".equals(item.get("componentType"))).findAny();
|
|
|
+ if (optional.isPresent()) {
|
|
|
+ String[] ids = compId.split(" / ");
|
|
|
+ List vas = (List) JSON.parse(UtilMap.getString((Map) optional.get(), "value"));
|
|
|
+ for (int i = 0; i < ids.length; i++) {
|
|
|
+ formData.put(ids[i], vas.get(i));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ try {
|
|
|
+ Map formComp = formComponentValues.stream().filter(item -> name.equals(item.get("name"))).findAny().get();
|
|
|
+ Object value = formComp.get("value");
|
|
|
+ // 成员组件, 数据处理
|
|
|
+ if ("InnerContactField".equals(formComp.get("componentType")) && formComp.containsKey("value")) {
|
|
|
+ List<Map> empInfos = (List<Map>) JSON.parse(String.valueOf(formComp.get("extValue")));
|
|
|
+ List<String> emplsId = new ArrayList<>();
|
|
|
+ for (Map empInfo : empInfos) {
|
|
|
+ emplsId.add(String.valueOf(empInfo.get("emplId")));
|
|
|
+ }
|
|
|
+ value = emplsId; // 成员多选
|
|
|
+ }
|
|
|
+ formData.put(compId, value);
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.info("缺失字段:{}", name);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return formData;
|
|
|
+ }
|
|
|
+
|
|
|
+ public List<String> getNumberByUserId(List<String> workingEmployeeIds) {
|
|
|
+ log.info("根据钉钉人员id获取员工工号:{}",workingEmployeeIds.toString());
|
|
|
+ List<String> filterList = new ArrayList<>();
|
|
|
+ filterList.add("sys00-jobNumber");
|
|
|
+ List<Map> employeeInfos = ddClientPersonnel.getEmployeeInfos(ddClient.getAccessToken(), workingEmployeeIds, agentId, filterList);
|
|
|
+ List<String> personList = new ArrayList<>();
|
|
|
+ employeeInfos.forEach(e -> {
|
|
|
+ List<Map> mapList = (List<Map>) e.get("field_data_list");
|
|
|
+ mapList.forEach(m -> {
|
|
|
+ List<Map> valueList = (List<Map>) m.get("field_value_list");
|
|
|
+ String value = valueList.get(0).get("value").toString();
|
|
|
+ personList.add(value);
|
|
|
+ });
|
|
|
+ });
|
|
|
+ return personList;
|
|
|
+ }
|
|
|
+
|
|
|
+ public List<Map> getUserFormByNumber(List<String> workNumbers, String token) {
|
|
|
+ log.info("开始获取云简平台员工信息:{}",workNumbers.toString());
|
|
|
+ String uuid = UUID.randomUUID().toString();
|
|
|
+ Map<String, Object> param = UtilMap.map("bizId, timestamp, codes, access_token", uuid, new Date().getTime(), workNumbers, token);
|
|
|
+ DDR ddr = DDR.doGet(getRequestUrl(FIND_BY_CODES), null, param);
|
|
|
+ log.info("员工信息返回:{}",ddr.toString());
|
|
|
+ List<Map> userForm = new ArrayList<>();
|
|
|
+ if (ObjectUtil.isNotNull(ddr.getData())) {
|
|
|
+ JSONObject jsonObject = JSONObject.parseObject(ddr.getData().toString());
|
|
|
+ List<Map> pageInfo = (List<Map>) jsonObject.get("page_info");
|
|
|
+ for (int i = 0; i < workNumbers.size(); i++) {
|
|
|
+ int finalI = i;
|
|
|
+ Optional optional = pageInfo.stream().filter(item -> workNumbers.get(finalI).equals(item.get("code"))).findAny();
|
|
|
+ if (optional.isPresent()) {
|
|
|
+ HashMap<String, Object> user = new HashMap<>();
|
|
|
+ user.put("code", UtilMap.getString((Map) optional.get(), "code"));
|
|
|
+ user.put("name", UtilMap.getString((Map) optional.get(), "full_name"));
|
|
|
+ Map map = (Map) optional.get();
|
|
|
+ String depCode = UtilMap.getString((Map) map.get("department_vo"), "department_code");
|
|
|
+ user.put("depCode", depCode);
|
|
|
+
|
|
|
+ userForm.add(user);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return userForm;
|
|
|
+ }
|
|
|
+
|
|
|
+ public String getCompany(String depId, String token) {
|
|
|
+ String uuid = UUID.randomUUID().toString();
|
|
|
+ Map<String, Object> param = UtilMap.map("bizId, timestamp, code, access_token", uuid, new Date().getTime(), depId, token);
|
|
|
+ DDR ddr = DDR.doGet(getRequestUrl(FIND_COMPANY), null, param);
|
|
|
+ String company = depId;
|
|
|
+ if (ObjectUtil.isNotNull(ddr.getData())) {
|
|
|
+ List<Map> data = (List<Map>) ddr.getData();
|
|
|
+ JSONObject jsonObject = JSONObject.parseObject(data.get(0).get("parent_vo").toString());
|
|
|
+ if (!"B0001".equals(depId) && !"B0001".equals(jsonObject.getString("code"))){
|
|
|
+ company = jsonObject.getString("code");
|
|
|
+ company = getCompany(company, token);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return company;
|
|
|
+ }
|
|
|
+ public String getRequestUrl(String url){
|
|
|
+ log.info("请求云简地址接口:{}",yjHost+url);
|
|
|
+ return yjHost + url;
|
|
|
+ }
|
|
|
+}
|