123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556 |
- package com.malk.shantai.service.impl;
- import cn.hutool.http.HttpUtil;
- import com.alibaba.fastjson.JSONArray;
- import com.alibaba.fastjson.JSONObject;
- import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
- import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
- import com.malk.server.common.McR;
- import com.malk.server.dingtalk.DDR_New;
- import com.malk.shantai.config.StEkbConfig;
- import com.malk.shantai.entity.Shantai;
- import com.malk.shantai.mapper.ShantaiMapper;
- import com.malk.shantai.service.StDingProcService;
- import com.malk.service.dingtalk.DDClient;
- import com.malk.service.dingtalk.DDClient_Workflow;
- import com.malk.utils.UtilHttp;
- import com.malk.utils.UtilMap;
- import com.malk.utils.UtilToken;
- import lombok.extern.slf4j.Slf4j;
- import org.apache.commons.lang3.StringUtils;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.beans.factory.annotation.Value;
- import org.springframework.stereotype.Service;
- import java.io.*;
- import java.net.HttpURLConnection;
- import java.net.MalformedURLException;
- import java.net.URL;
- import java.net.URLConnection;
- import java.util.*;
- @Service
- @Slf4j
- public class StDingProcServiceImpl extends ServiceImpl<ShantaiMapper, Shantai> implements StDingProcService {
- @Autowired
- private DDClient_Workflow ddClient_workflow;
- @Autowired
- private DDClient ddClient;
- @Autowired
- private StEkbConfig stEkbConfig;
- @Autowired
- private ShantaiMapper shantaiMapper;
- @Value("${download.path}")
- private String filePath;
- @Value("${dingtalk.operatorUserId}")
- private String operatorUserId;
- @Value("${dingtalk.operatorUnionId}")
- private String operatorUnionId;
- @Value("${ekb.operatorStaffId}")
- private String operatorStaffId;
- //法人实体
- private static Map<String,String> CORPORATION = new HashMap<>();
- //任务状态
- private static Map<String,String> STATUS = new HashMap<>();
- static{
- CORPORATION.put("杉泰健康管理(上海)有限公司","ID01tX0xhMwgbR");
- CORPORATION.put("上海广慈太保互联网医院有限公司","LY4cw6EvcNZQ00");
- CORPORATION.put("苏州杉泰大药房有限公司","ID_3IzESoE1lxM");
- CORPORATION.put("成都杉泰互联网医院有限公司","zsIcw6E-tcIM00");
- CORPORATION.put("海南杉泰健康科技有限公司","kcwcw6F3esco00");
- CORPORATION.put("上海杉泰健康科技有限公司","SdEcw6EvcN9U00");
- STATUS.put("APPROVING","待审批");
- STATUS.put("PAYING","待支付");
- STATUS.put("PROCESSING","处理中(支付中)");
- STATUS.put("PROCESSED","已处理(审批完成、已支付)");
- STATUS.put("CANCELED","待办被取消");
- STATUS.put("SENDING","待寄送");
- STATUS.put("RECEIVING","待收单");
- STATUS.put("RECEIVING_EXCEP","收单异常");
- STATUS.put("REQUISITION_PAID","临时状态(申请单支付时消息发送)");
- STATUS.put("DRAFT","草稿");
- STATUS.put("PENDING","提交中");
- STATUS.put("REJECTED","已驳回");
- STATUS.put("PAID","已支付/审批完成");
- STATUS.put("ARCHIVED","归档");
- }
- @Override
- public void fkdSync(String procInstId) {
- Map map=ddClient_workflow.getProcessInstanceId(ddClient.getAccessToken(),procInstId);
- log.info("map:{}",map);
- List<Map> tasks = (List<Map>) map.get("tasks");
- boolean hasRunning = false;
- for (Map task : tasks) {
- if ("RUNNING".equals(task.get("status").toString())){
- hasRunning = true;
- //判断是否为审批流程第一个出纳节点是否完成(第二个出纳节点进行中)
- if (!"55d3_4702".equals(task.get("activityId").toString())){
- log.info("当前节点为:activityId:{},activityName:{},不进行同步",task.get("activityId"),task.get("activityName"));
- return;
- }else {
- log.info("当前节点为:activityId:{},activityName:{},进行同步",task.get("activityId"),task.get("activityName"));
- break;
- }
- }
- }
- //若没有正在运行的审批流程,则不进行同步
- if (!hasRunning){
- log.info("没有正在运行的审批流程,不进行同步");
- return;
- }
- Map rule=new HashMap();
- rule.put("DDSelectField_8UJMKRMLWYK0","是否推送到易快报");// 是否推送到易快报
- // rule.put("TextField-K11U6U5Q","付款事由");// 标题/付款事由
- rule.put("TextField_18XU5XCGC4RK0","付款摘要");// 标题/付款摘要
- rule.put("RecipientAccountField-K11U6U5P","收款信息");// 收款信息
- rule.put("MoneyField_FMP7OAX3TZ40","付款金额");// 付款金额
- rule.put("TextareaField_15PEUHBWFDDS0","备注");// 备注
- rule.put("DDMultiSelectField_17IA7RJQYGWW0","付款公司");// 付款公司
- Map data=getData(map,rule);
- if( Objects.isNull(data.get("是否推送到易快报")) || data.get("是否推送到易快报").toString().equals("否")){
- return;
- }
- data.put("户名", UtilMap.getMap(data,"收款信息").get("name"));// 户名
- data.put("银行",UtilMap.getMap(data,"收款信息").get("instName"));// 银行
- data.put("支行信息",UtilMap.getMap(data,"收款信息").get("instBranchName"));// 支行信息
- data.put("账号",UtilMap.getMap(data,"收款信息").get("cardNo"));// 账号
- data.put("省份",UtilMap.getMap(data,"收款信息").get("instProvince"));// 省份
- data.put("城市",UtilMap.getMap(data,"收款信息").get("instCity"));// 城市
- log.info("data:{}",JSONObject.toJSONString(data));
- //获取发起人userId
- String userId = map.get("originatorUserId").toString();
- String staffId = operatorStaffId;// 曹艳杰
- //查询易快报中发起人是否存在
- /*Map<String,Object> param3 = new HashMap<>();
- param3.put("accessToken",getToken());
- Map body3 = new HashMap<>();
- body3.put("type","USERID");
- body3.put("conditionIds",Arrays.asList(userId));
- Map user = (Map) JSONObject.parseObject(UtilHttp.doPost(stEkbConfig.getPreUrl() + "/api/openapi/v1/staffs/getStaffIds", null, param3, body3)).getJSONArray("items").get(0);
- if (Objects.isNull(user)){
- log.error("易快报中发起人不存在");
- staffId = "pQccdcNGsM3U00:16278700718435315";// 李溯
- }else {
- staffId = "pQccdcNGsM3U00:16278700718435315";// 李溯
- staffId = user.get("id").toString();
- }*/
- //查询易快报中收款账户是否存在
- Map result = (Map) JSONObject.parseObject(UtilHttp.doGet(stEkbConfig.getPreUrl() + "/api/openapi/v2/payeeInfos",
- null, UtilMap.map("accessToken, start, count, names, cardNos, ids, active, orderBy, orderByType", getToken(), 0, 100, data.get("户名"), data.get("账号"), null, true, "updateTime", "desc"))) ;
- System.out.println(result);
- String payeeId = "";
- List<Map> items = (List<Map>) result.get("items");
- //若不存在则新增收款账户
- if (Objects.isNull(items) || items.isEmpty()){
- Map<String, Object> body = new HashMap<>();
- Map visibility = new HashMap();
- visibility.put("fullVisible",true);
- body.put("sort","BANK");
- body.put("type","PUBLIC");
- body.put("owner","CORPORATION");
- body.put("name",data.get("户名"));
- body.put("cardNo",data.get("账号"));
- body.put("bank",data.get("银行"));
- body.put("branch",data.get("支行信息"));
- body.put("province",data.get("省份"));
- body.put("city",data.get("城市"));
- body.put("visibility",visibility);
- Map<String,Object> param = new HashMap<>();
- param.put("accessToken",getToken());
- payeeId = JSONObject.parseObject(UtilHttp.doPost(stEkbConfig.getPreUrl() + "/api/openapi/v2.1/payeeInfos", null, param, body)).getString("id");
- //再次获取新增后的收款账户
- /* account = JSONObject.parseObject(UtilHttp.doGet(stEkbConfig.getPreUrl() + "/api/openapi/v2/payeeInfos",
- null, UtilMap.map("accessToken, start, count, names, cardNos, ids, active", getToken(), 0, 100, null, null, id, true))) ;*/
- }else {
- payeeId = items.get(0).get("id").toString();
- }
- //根据模板ID获取模板信息
- String id="ID01yVMv53gDSL";// "对外付款单"模板id
- Map template = (Map) JSONObject.parseObject(HttpUtil.get(stEkbConfig.getPreUrl().concat("/api/openapi/v2/specifications/byIds/[").concat(id).concat("]"), UtilMap.map("accessToken, type, start, count", getToken(), "payment", 0, 10))).getJSONArray("items").get(0);
- String specificationId = template.get("id").toString();
- //新增单据
- Map<String, Object> param = new HashMap<>();
- param.put("accessToken",getToken());
- param.put("isCommit",true);
- param.put("isUpdate",true);
- Map<String, Object> body = new HashMap<>();
- Map<String, Object> form = new HashMap<>();
- //金额
- Map<String, Object> payMoney = new HashMap<>();
- payMoney.put("standard",data.get("付款金额"));
- payMoney.put("standardStrCode","CNY");
- payMoney.put("standardNumCode","156");
- payMoney.put("standardSymbol","¥");
- payMoney.put("standardUnit","元");
- payMoney.put("standardScale",2);
- form.put("title",data.get("付款摘要")); //单据标题
- form.put("submitterId",staffId); //提交人ID
- form.put("description",data.get("备注")); //描述
- form.put("specificationId",specificationId); //单据模板id
- form.put("payMoney",payMoney); //付款金额
- form.put("payeeId",payeeId);
- form.put("u_订单信息",procInstId);
- if (CORPORATION.keySet().contains(data.get("付款公司"))){
- form.put("法人实体",CORPORATION.get(data.get("付款公司"))); //法人实体
- }
- body.put("form",form);
- Map document = JSONObject.parseObject(UtilHttp.doPost(stEkbConfig.getPreUrl() + ("/api/openapi/v2.2/flow/data"), null, param, body));
- Map flow = (Map) document.get("flow");
- String flowId = flow.get("id").toString();
- Shantai shantai = new Shantai();
- shantai.setProcInstId(procInstId);
- shantai.setState("3");
- shantai.setUserId(userId);
- shantai.setFlowId(flowId);
- shantaiMapper.insert(shantai);
- log.info("新增单据成功:{}",document);
- }
- @Override
- public McR commentSync(Map map,String flowId){
- try{
- String procInstId = map.get("procInstId").toString();
- //查询表中是否存在同步评论记录
- LambdaQueryWrapper<Shantai> shantaiLambdaQueryWrapper = new LambdaQueryWrapper<>();
- shantaiLambdaQueryWrapper.eq(Shantai::getProcInstId,procInstId)
- .eq(Shantai::getValidFlag,"1");
- Shantai shantai = shantaiMapper.selectOne(shantaiLambdaQueryWrapper);
- //获取提交人
- String userId = "";
- if (Objects.nonNull(shantai)){
- if (shantai.getState().equals("1")){
- log.info("该单据Id:{}已同步过水单,本次不进行同步",flowId);
- return McR.success();
- }
- userId = shantai.getUserId();
- }
- if (Objects.isNull(userId)){
- userId = map.get("userId").toString();
- }
- //上传钉盘目前设置为管理员
- String unionId = operatorUnionId;
- /*DDR_New ddrNew = (DDR_New) UtilHttp.doPost("https://oapi.dingtalk.com/topapi/v2/user/get", null, ddClient.initTokenParams(), UtilMap.map("userid", userId), DDR_New.class);
- Map result = (Map) ddrNew.getResult();
- if (Objects.nonNull(result)){
- unionId = result.get("unionid").toString();
- }else {
- unionId = operatorUnionId;//曹艳杰
- userId = operatorUserId;//曹艳杰
- }*/
- //获取附件上传到钉盘
- List<String> paths = (List<String>) map.get("paths");
- List<Map> dentries = new ArrayList<>();
- if (Objects.nonNull(paths) && !paths.isEmpty()){
- for (String path : paths) {
- File file = new File(path);
- try{
- //上传文件至钉盘
- Map dentry = upload(file,unionId);
- dentries.add(dentry);
- }catch (IOException e){
- e.printStackTrace();
- log.info("上传文件至钉盘失败:{}",e.getMessage());
- return McR.errorUnknown("上传文件至钉盘失败");
- }
- }
- }
- String state = map.get("state").toString();
- if (Objects.nonNull(shantai) && shantai.getState().equals("2") && dentries.isEmpty()){
- log.info("该单据Id:{}本次无水单上传,不进行同步",flowId);
- return McR.success();
- }
- //新增评论
- // comment(dentries,state,userId,procInstId);
- //20241018 评论人统一改为曹艳杰
- comment(dentries,state,operatorUserId,procInstId);
- if (Objects.isNull(shantai)){
- //更新表中同步状态
- shantai = new Shantai();
- if (dentries.isEmpty()){
- shantai.setState("2");
- }else {
- shantai.setState("1");
- }
- shantai.setFlowId(flowId);
- shantai.setProcInstId(procInstId);
- shantai.setUserId(userId);
- shantaiMapper.insert(shantai);
- }else {
- //更新表中同步状态
- if (dentries.isEmpty()){
- shantai.setState("2");
- shantai.setFlowId(flowId);
- }else {
- shantai.setState("1");
- shantai.setFlowId(flowId);
- }
- //更新评论状态
- shantaiMapper.updateById(shantai);
- }
- }catch (Exception e){
- log.info("单据Id:{}同步失败,原因:{}",flowId,e.getMessage());
- return McR.errorUnknown("同步评论失败");
- }
- return McR.success();
- }
- @Override
- public Map getFlowInfo(String flowId) {
- //根据单据id获取单据信息
- Map param = new HashMap<>();
- param.put("accessToken",getToken());
- param.put("flowId",flowId);
- Map flow = JSONObject.parseObject(UtilHttp.doGet("https://dd2.hosecloud.com/api/openapi/v1.1/flowDetails", null, param)).getJSONObject("value");
- Map form = (Map) flow.get("form");
- String procInstId = form.get("u_订单信息").toString();
- String submitterId = form.get("submitterId").toString();
- String userId = submitterId.substring(submitterId.indexOf(':') + 1);
- String state = flow.get("state").toString();
- log.info("流程状态:{}",state.toUpperCase());
- if (STATUS.keySet().contains(state.toUpperCase())){
- state = STATUS.get(state.toUpperCase());
- }
- //根据单据id获取单据附件信息
- Map param2 = new HashMap<>();
- param2.put("accessToken",getToken());
- Map body2 = new HashMap<>();
- String[] flowIds = {flowId};
- body2.put("flowIds",flowIds);
- JSONArray items = JSONObject.parseObject(UtilHttp.doPost("https://dd2.hosecloud.com/api/openapi/v1/flowDetails/attachment", null, param2, body2)).getJSONArray("items");
- Map item = (Map) items.get(0);
- List<Map> attachmentList = (List<Map>) item.get("attachmentList");
- List<String> paths = new ArrayList<>();
- if (!attachmentList.isEmpty()){
- for (Map attachment : attachmentList) {
- if (attachment.get("type").toString().equals("flow.receipt")){
- List<Map> receiptUrls = (List<Map>) attachment.get("receiptUrls");
- for (Map receiptUrl : receiptUrls) {
- //附件下载到本地
- String url = receiptUrl.get("url").toString();
- String fileName = receiptUrl.get("key").toString();
- String path = filePath + fileName;
- downloadNet(url, path);
- //添加到路径列表
- paths.add(path);
- }
- }
- }
- }
- Map result = new HashMap();
- result.put("state",state);
- result.put("procInstId",procInstId);
- result.put("paths",paths);
- result.put("userId",userId);
- return result;
- }
- // 下载网络文件
- public void downloadNet(String netUrl, String path){
- int bytesum = 0;
- int byteread = 0;
- try{
- URL url = new URL(netUrl);
- URLConnection conn = url.openConnection();
- InputStream inStream = conn.getInputStream();
- FileOutputStream fs = new FileOutputStream(path);
- byte[] buffer = new byte[1204];
- while ((byteread = inStream.read(buffer)) != -1) {
- bytesum += byteread;
- fs.write(buffer, 0, byteread);
- }
- } catch (MalformedURLException e){
- e.printStackTrace();
- } catch (FileNotFoundException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- @Override
- public void commentSyncAll() {
- //获取所有评论未同步水单的单据列表
- LambdaQueryWrapper<Shantai> shantaiLambdaQueryWrapper = new LambdaQueryWrapper<>();
- shantaiLambdaQueryWrapper.ne(Shantai::getState,"1")
- .eq(Shantai::getValidFlag,"1");
- List<Shantai> shantaiList = shantaiMapper.selectList(shantaiLambdaQueryWrapper);
- for (Shantai shantai : shantaiList) {
- String flowId = shantai.getFlowId();
- log.info("开始定时同步评论水单:{}",flowId);
- Map flowInfo = getFlowInfo(flowId);
- commentSync(flowInfo,flowId);
- }
- }
- private void comment(List<Map> dentries, String state, String userId, String procInstId) {
- Map body = new HashMap<>();
- Map fileMap = new HashMap<>();
- List<Map> attachments= new ArrayList<>();
- for (Map dentry : dentries) {
- Map attachment = new HashMap<>();
- attachment.put("spaceId",dentry.get("spaceId").toString());
- attachment.put("fileSize",dentry.get("size").toString());
- attachment.put("fileId",dentry.get("id").toString());
- attachment.put("fileName",dentry.get("name").toString());
- attachment.put("fileType",dentry.get("type").toString());
- attachments.add(attachment);
- }
- fileMap.put("photos",null);
- fileMap.put("attachments",attachments);
- body.put("processInstanceId",procInstId);
- body.put("text","付款状态:" + state);
- body.put("commentUserId",userId);
- body.put("file",fileMap);
- UtilHttp.doPost("https://api.dingtalk.com/v1.0/workflow/processInstances/comments",ddClient.initTokenHeader(),null,body);
- }
- private Map upload(File file,String unionId) throws IOException {
- //获取文件上传信息
- // String parentDentryUuid = "ZQYprEoWonmdnzdOFpklzk1a81waOeDk";// poc目录 api测试上传/附件
- String parentDentryUuid = "YQBnd5ExVEowejBQtZ1v6wO28yeZqMmz";// 杉泰目录 /技术文档/易快报银企直连
- Map<String,Object> param1 = new HashMap<>();
- param1.put("unionId",unionId);
- Map body1 = new HashMap<>();
- body1.put("protocol","HEADER_SIGNATURE");
- DDR_New ddrNew = (DDR_New) UtilHttp.doPost("https://api.dingtalk.com/v2.0/storage/spaces/files/" + parentDentryUuid + "/uploadInfos/query", ddClient.initTokenHeader(), param1, body1, DDR_New.class);
- String uploadKey = ddrNew.getUploadKey();
- Map headerSignatureInfo = ddrNew.getHeaderSignatureInfo();
- Map<String,String> headers = (Map<String,String>) headerSignatureInfo.get("headers");
- String resourceUrl = ((List<String>) headerSignatureInfo.get("resourceUrls")).get(0);
- //使用OSS的header加签方式上传文件
- URL url = new URL(resourceUrl);
- HttpURLConnection connection = (HttpURLConnection)url.openConnection();
- if (headers != null) {
- for (Map.Entry<String, String> entry : headers.entrySet()) {
- connection.setRequestProperty(entry.getKey(), entry.getValue());
- }
- }
- connection.setDoOutput(true);
- connection.setRequestMethod("PUT");
- connection.setUseCaches(false);
- connection.setReadTimeout(10000);
- connection.setConnectTimeout(10000);
- connection.connect();
- OutputStream out = connection.getOutputStream();
- InputStream is = new FileInputStream(file);
- byte[] b =new byte[1024];
- int temp;
- while ((temp=is.read(b))!=-1){
- out.write(b,0,temp);
- }
- out.flush();
- out.close();
- int responseCode = connection.getResponseCode();
- connection.disconnect();
- if (responseCode == 200) {
- System.out.println("上传成功");
- } else {
- System.out.println("上传失败");
- }
- //提交文件
- Map<String,Object> param2 = new HashMap<>();
- param2.put("unionId",unionId);
- Map body2 = new HashMap<>();
- body2.put("uploadKey",uploadKey);
- body2.put("name",file.getName());
- Map option = new HashMap<>();
- option.put("conflictStrategy","OVERWRITE");//文件名称冲突策略:覆盖
- body2.put("option",option);
- DDR_New ddrNew2 = (DDR_New) UtilHttp.doPost("https://api.dingtalk.com/v2.0/storage/spaces/files/" + parentDentryUuid + "/commit", ddClient.initTokenHeader(), param2, body2, DDR_New.class);
- return ddrNew2.getDentry();
- }
- public Map getData(Map instance,Map rule){
- Map resultMap=new HashMap();
- List<Map> list=(List<Map>) instance.get("formComponentValues");
- for (Map map:list) {
- if(rule.containsKey(String.valueOf(map.get("id")))){
- String componentType=String.valueOf(map.get("componentType"));
- if(componentType.equals("RecipientAccountField")){
- resultMap.put(rule.get(String.valueOf(map.get("id"))),JSONObject.parseObject(String.valueOf(map.get("extValue"))));
- }else if (componentType.equals("DDMultiSelectField")){
- resultMap.put(rule.get(String.valueOf(map.get("id"))),JSONObject.parseArray(String.valueOf(map.get("value"))).get(0).toString());
- }else{
- resultMap.put(rule.get(String.valueOf(map.get("id"))),map.get("value"));
- }
- }
- }
- return resultMap;
- }
- private String getToken(){
- String accessToken = UtilToken.get("invalid-token-ykb");
- if (StringUtils.isNotBlank(accessToken)) return accessToken;
- Map result = JSONObject.parseObject(HttpUtil.post(stEkbConfig.getPreUrl().concat("/api/openapi/v1/auth/getAccessToken"),JSONObject.toJSONString(UtilMap.map("appKey, appSecurity",stEkbConfig.getAppKey(),stEkbConfig.getAppSecurity()))));
- String token = ((Map) result.get("value")).get("accessToken").toString();
- long expireTime = (long) ((Map) result.get("value")).get("expireTime");
- log.info("响应token, {}", token);
- // token失效自动重置: 重新调用会重置过期时间
- UtilToken.put("invalid-token-ykb", token, 2 * 3600 * 1000L);
- return token;
- }
- }
|