JinlunServiceImpl.java 39 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939
  1. package com.malk.jinlun.service.impl;
  2. import com.alibaba.fastjson.JSON;
  3. import com.alibaba.fastjson.JSONObject;
  4. import com.auth0.jwt.JWT;
  5. import com.auth0.jwt.algorithms.Algorithm;
  6. import com.google.gson.Gson;
  7. import com.kingdee.bos.webapi.entity.IdentifyInfo;
  8. import com.kingdee.bos.webapi.entity.RepoRet;
  9. import com.kingdee.bos.webapi.sdk.K3CloudApi;
  10. import com.malk.jinlun.config.KDWebApiConf;
  11. import com.malk.jinlun.entity.*;
  12. import com.malk.jinlun.service.CpClient;
  13. import com.malk.jinlun.service.JinlunService;
  14. import com.malk.server.common.McR;
  15. import com.malk.server.teambition.TBConf;
  16. import com.malk.server.teambition.TBR;
  17. import com.malk.utils.UtilHttp;
  18. import com.malk.utils.UtilMap;
  19. import com.malk.utils.UtilToken;
  20. import lombok.extern.slf4j.Slf4j;
  21. import org.apache.commons.lang3.StringUtils;
  22. import org.apache.logging.log4j.util.Strings;
  23. import org.springframework.beans.factory.annotation.Autowired;
  24. import org.springframework.scheduling.annotation.Async;
  25. import org.springframework.stereotype.Service;
  26. import org.springframework.web.bind.annotation.RequestBody;
  27. import java.net.CookieManager;
  28. import java.nio.charset.StandardCharsets;
  29. import java.nio.file.Files;
  30. import java.nio.file.Paths;
  31. import java.security.MessageDigest;
  32. import java.util.*;
  33. import static org.junit.Assert.fail;
  34. @Slf4j
  35. @Service
  36. public class JinlunServiceImpl implements JinlunService {
  37. @Autowired
  38. private KDWebApiConf kdWebApiConf;
  39. @Autowired
  40. private CpClient cpClient;
  41. @Autowired
  42. private TBConf tbConf;
  43. private final Object $lock = new Object[0];
  44. private static final Long EXPIRES_IN = 7200000L;
  45. @Override
  46. public McR addCustomer(@RequestBody Map map) {
  47. //查询云枢客户单据详情
  48. String objectId = UtilMap.getString(map, "objectId");
  49. Map customer = cpClient.getCpBo("ZLKHLC", objectId, null);
  50. Map data = UtilMap.getMap(customer, "data");
  51. Map bizObject = UtilMap.getMap(data, "bizObject");
  52. Map customerData = UtilMap.getMap(bizObject, "data");
  53. //请求参数,要求为json字符串
  54. Save save = new Save();
  55. CustomerModel customerModel = new CustomerModel();
  56. //基本信息
  57. String FName = UtilMap.getString(customerData,"ShortText1758195928433");//客户名称
  58. String FShortName = UtilMap.getString(customerData,"ShortText1758195937324");//客户简称
  59. FNumber FCOUNTRY = new FNumber(UtilMap.getString(customerData,"ShortText1760000048047"));//国家
  60. FNumber FGroup = new FNumber(UtilMap.getString(customerData,"Dropdown1758198564777_key"));//客户分组
  61. String F_VMKV_Combo = UtilMap.getString(customerData,"Dropdown1758198576644_key");//客户等级
  62. FNumber FCustTypeId = new FNumber(UtilMap.getString(customerData,"Dropdown1758196678786_key"));//客户类别
  63. String FDescription = UtilMap.getString(customerData,"LongText1758198621716");//备注
  64. //商务信息
  65. FNumber FSELLER = new FNumber(UtilMap.getString(customerData,"ShortText1759997501370"));//销售员
  66. FSTAFFNUMBER F_VMKV_Base1 = new FSTAFFNUMBER(UtilMap.getString(customerData,"Text1762059270203"));//跟单员
  67. FNumber FRECCONDITIONID = new FNumber(UtilMap.getString(customerData,"Dropdown1758199217950_key"));//收款条件
  68. FNumber FTRADINGCURRID = new FNumber(UtilMap.getString(customerData,"Dropdown1758199184443_key"));//结算币别
  69. FNumber FSETTLETYPEID = new FNumber(UtilMap.getString(customerData,"Dropdown1758199160962_key"));//结算方式
  70. FNumber FTaxRate = new FNumber(UtilMap.getString(customerData,"Dropdown1758199231927_key"));//税率
  71. FNumber FTaxType = new FNumber(UtilMap.getString(customerData,"Dropdown1758199263660_key"));//税分类
  72. String FInvoiceType = UtilMap.getString(customerData,"Dropdown1758199247249_key");//发票类型
  73. Boolean FISCREDITCHECK = UtilMap.getBoolean(customerData,"Logic1758199516570");//启用信用管理
  74. String F_VMKV_Combo1 = UtilMap.getString(customerData,"Dropdown1762058555728_key");//订单要求
  75. //开票信息
  76. String FINVOICEBANKACCOUNT = UtilMap.getString(customerData,"ShortText1758199605057");//银行账号
  77. String FINVOICETITLE = UtilMap.getString(customerData,"ShortText1758199610851");//发票抬头
  78. String FTAXREGISTERCODE = UtilMap.getString(customerData,"ShortText1758199617057");//纳税登记号
  79. String FINVOICEBANKNAME = UtilMap.getString(customerData,"Text1758199624533");//开户银行
  80. String FSOCIALCRECODE = UtilMap.getString(customerData,"Text1758199630373");//统一社会信用代码
  81. String FINVOICETEL = UtilMap.getString(customerData,"Text1758199637444");//开票联系电话
  82. String FINVOICEADDRESS = UtilMap.getString(customerData,"LongText1758199679685");//开票通讯地址
  83. //地址信息
  84. List<Map> addressList = UtilMap.getList(customerData, "Sheet1758199794948");
  85. List<CustomerContactEntry> FT_BD_CUSTCONTACT = new ArrayList<>();
  86. for (Map address : addressList) {
  87. CustomerContactEntry customerContactEntry = new CustomerContactEntry();
  88. String addressCode = UtilMap.getString(address, "ShortText1758199808715");
  89. String addressName = UtilMap.getString(address, "ShortText1758199824395");
  90. if (Strings.isNotBlank(addressCode) && Strings.isNotBlank(addressName)){
  91. customerContactEntry.setFNUMBER1(addressCode);//地点编码
  92. customerContactEntry.setFNAME1(addressName);//地点名称
  93. FT_BD_CUSTCONTACT.add(customerContactEntry);
  94. }
  95. }
  96. customerModel.setFName(FName);
  97. customerModel.setFShortName(FShortName);
  98. customerModel.setFCOUNTRY(FCOUNTRY);
  99. customerModel.setFGroup(FGroup);
  100. customerModel.setF_VMKV_Combo(F_VMKV_Combo);
  101. customerModel.setFCustTypeId(FCustTypeId);
  102. customerModel.setFDescription(FDescription);
  103. customerModel.setFSELLER(FSELLER);
  104. customerModel.setF_VMKV_Base1(F_VMKV_Base1);
  105. customerModel.setFRECCONDITIONID(FRECCONDITIONID);
  106. customerModel.setFTRADINGCURRID(FTRADINGCURRID);
  107. customerModel.setFSETTLETYPEID(FSETTLETYPEID);
  108. customerModel.setFTaxRate(FTaxRate);
  109. customerModel.setFTaxType(FTaxType);
  110. customerModel.setFInvoiceType(FInvoiceType);
  111. customerModel.setFISCREDITCHECK(FISCREDITCHECK);
  112. customerModel.setF_VMKV_Combo1(F_VMKV_Combo1);
  113. customerModel.setFINVOICEBANKACCOUNT(FINVOICEBANKACCOUNT);
  114. customerModel.setFINVOICETITLE(FINVOICETITLE);
  115. customerModel.setFTAXREGISTERCODE(FTAXREGISTERCODE);
  116. customerModel.setFINVOICEBANKNAME(FINVOICEBANKNAME);
  117. customerModel.setFSOCIALCRECODE(FSOCIALCRECODE);
  118. customerModel.setFINVOICETEL(FINVOICETEL);
  119. customerModel.setFINVOICEADDRESS(FINVOICEADDRESS);
  120. if (!FT_BD_CUSTCONTACT.isEmpty()){
  121. customerModel.setFT_BD_CUSTCONTACT(FT_BD_CUSTCONTACT);
  122. }
  123. save.setModel(customerModel);
  124. Gson gson2 = new Gson();
  125. String jsonData = gson2.toJson(save);
  126. log.info(jsonData);
  127. K3CloudApi client = new K3CloudApi(initIden());
  128. //业务对象标识
  129. String formId = "BD_Customer";
  130. //调用接口
  131. String resultJson = "";
  132. try {
  133. resultJson = client.save(formId,jsonData);
  134. }catch (Exception e){
  135. throw new RuntimeException(e);
  136. }
  137. //用于记录结果
  138. Gson gson = new Gson();
  139. //对返回结果进行解析和校验
  140. RepoRet repoRet = gson.fromJson(resultJson, RepoRet.class);
  141. String customerCode = "";
  142. if (isTrue(repoRet)){
  143. String id = repoRet.getResult().getId();
  144. Submit submit = new Submit();
  145. submit.setIds(id);
  146. //提交客户
  147. String resultJson2 = "";
  148. try {
  149. resultJson2 = client.submit(formId, JSONObject.toJSONString(submit));
  150. }catch (Exception e){
  151. throw new RuntimeException(e);
  152. }
  153. RepoRet repoRet2 = gson.fromJson(resultJson2, RepoRet.class);
  154. isTrue(repoRet2);
  155. customerCode = repoRet2.getResult().getResponseStatus().getSuccessEntitys().get(0).getNumber();
  156. //回写云枢客户编号
  157. // cpClient.updateCpBo("ZLKHLC",UtilMap.map("id, ShortText1758195840127",objectId,customerCode),null);
  158. if (isTrue(repoRet2)){
  159. Audit audit = new Audit();
  160. audit.setNumbers(Arrays.asList(customerCode));
  161. //审核客户
  162. String resultJson3 = "";
  163. try {
  164. resultJson3 = client.audit(formId,JSONObject.toJSONString(audit));
  165. }catch (Exception e){
  166. throw new RuntimeException(e);
  167. }
  168. RepoRet repoRet3 = gson.fromJson(resultJson3, RepoRet.class);
  169. isTrue(repoRet3);
  170. }
  171. }
  172. return McR.success(customerCode);
  173. }
  174. @Async
  175. @Override
  176. public void addCustomerContact(Map map) {
  177. try {
  178. Thread.sleep(3000);
  179. } catch (InterruptedException e) {
  180. throw new RuntimeException(e);
  181. }
  182. //请求参数,要求为json字符串
  183. Save save = new Save();
  184. ContactModel contactModel = new ContactModel();
  185. String objectId = UtilMap.getString(map, "objectId");
  186. Map contact = cpClient.getCpBo("JL002", objectId, null);
  187. Map cpBoResultData = cpClient.getCpBoResultData(contact);
  188. String FName = UtilMap.getString(cpBoResultData, "ShortText1757918028530");//联系人姓名
  189. String FMobile = UtilMap.getString(cpBoResultData, "ShortText1760076219303");//移动电话
  190. FNumber Fex = new FNumber(UtilMap.getString(cpBoResultData, "Radio1757922932185_key"));//性别
  191. String FPost = UtilMap.getString(cpBoResultData, "ShortText1757918203180");//职务
  192. String FCompanyType = "BD_Customer";//类型:客户
  193. String FTel = UtilMap.getString(cpBoResultData, "ShortText1757922962403");//固定电话
  194. String FFax = UtilMap.getString(cpBoResultData, "ShortText1757918148867");//传真
  195. String FEmail = UtilMap.getString(cpBoResultData, "ShortText1757918154124");//邮箱
  196. FNumber FCustId = new FNumber(UtilMap.getString(cpBoResultData, "ShortText1758159321906"));//客户编码
  197. contactModel.setFName(FName);
  198. contactModel.setFMobile(FMobile);
  199. contactModel.setFex(Fex);
  200. contactModel.setFPost(FPost);
  201. contactModel.setFCompanyType(FCompanyType);
  202. contactModel.setFTel(FTel);
  203. contactModel.setFFax(FFax);
  204. contactModel.setFEmail(FEmail);
  205. contactModel.setFCustId(FCustId);
  206. save.setModel(contactModel);
  207. Gson gson2 = new Gson();
  208. String jsonData = gson2.toJson(save);
  209. log.info(jsonData);
  210. K3CloudApi client = new K3CloudApi(initIden());
  211. //业务对象标识
  212. String formId = "BD_CommonContact";
  213. //调用接口
  214. String resultJson = "";
  215. try {
  216. resultJson = client.save(formId,jsonData);
  217. }catch (Exception e){
  218. throw new RuntimeException(e);
  219. }
  220. //用于记录结果
  221. Gson gson = new Gson();
  222. //对返回结果进行解析和校验
  223. RepoRet repoRet = gson.fromJson(resultJson, RepoRet.class);
  224. isTrue(repoRet);
  225. String contactCode = repoRet.getResult().getResponseStatus().getSuccessEntitys().get(0).getNumber();
  226. cpClient.updateCpBo("JL002",UtilMap.map("id, ShortText1760075793733",objectId,contactCode),null);
  227. }
  228. @Async
  229. @Override
  230. public void updateCustomer(Map map) {
  231. K3CloudApi client = new K3CloudApi(initIden());
  232. //业务对象标识
  233. String formId = "BD_Customer";
  234. //查询云枢客户详情
  235. String objectId = UtilMap.getString(map, "objectId");
  236. Map customer = cpClient.getCpBo("KHDA", objectId, null);
  237. Map customerData = cpClient.getCpBoResultData(customer);
  238. String custFNumber = UtilMap.getString(customerData, "ShortText1758195840127");//客户编码
  239. FNumber FSELLER = new FNumber(UtilMap.getString(customerData, "ShortText1759998244839"));//销售负责人
  240. //反审核
  241. UnAudit unAudit = new UnAudit();
  242. unAudit.setNumbers(Arrays.asList(custFNumber));//客户编码
  243. RepoRet repoRet = new RepoRet();
  244. try {
  245. String resultJson = client.unAudit(formId,new Gson().toJson(unAudit));
  246. repoRet = new Gson().fromJson(resultJson, RepoRet.class);
  247. } catch (Exception e) {
  248. throw new RuntimeException(e);
  249. }
  250. isTrue(repoRet);
  251. //查询客户内码
  252. View view = new View();
  253. view.setNumber(custFNumber);//客户编码
  254. RepoRet repoRet2 = new RepoRet();
  255. try {
  256. String resultJson = client.view(formId,new Gson().toJson(view));
  257. repoRet2 = new Gson().fromJson(resultJson, RepoRet.class);
  258. } catch (Exception e) {
  259. throw new RuntimeException(e);
  260. }
  261. isTrue(repoRet2);
  262. int FCUSTID = UtilMap.getDouble((Map) repoRet2.getResult().getResult(), "Id").intValue();
  263. //保存
  264. Save save = new Save();
  265. CustomerModel customerModel = new CustomerModel();
  266. customerModel.setFCUSTID(FCUSTID);//客户内码
  267. customerModel.setFSELLER(FSELLER);//销售员
  268. save.setModel(customerModel);
  269. save.setNeedUpDateFields(Arrays.asList("FSELLER"));
  270. RepoRet repoRet3 = new RepoRet();
  271. try {
  272. String resultJson = client.save(formId,new Gson().toJson(save));
  273. repoRet3 = new Gson().fromJson(resultJson, RepoRet.class);
  274. } catch (Exception e) {
  275. throw new RuntimeException(e);
  276. }
  277. isTrue(repoRet3);
  278. //提交
  279. Submit submit = new Submit();
  280. submit.setNumbers(Arrays.asList(custFNumber));//客户编码
  281. RepoRet repoRet4 = new RepoRet();
  282. try {
  283. String resultJson = client.submit(formId, JSONObject.toJSONString(submit));
  284. repoRet4 = new Gson().fromJson(resultJson, RepoRet.class);
  285. }catch (Exception e){
  286. throw new RuntimeException(e);
  287. }
  288. isTrue(repoRet4);
  289. //审核
  290. Audit audit = new Audit();
  291. audit.setNumbers(Arrays.asList(custFNumber));
  292. RepoRet repoRet5 = new RepoRet();
  293. try {
  294. String resultJson = client.audit(formId,JSONObject.toJSONString(audit));
  295. repoRet5 = new Gson().fromJson(resultJson, RepoRet.class);
  296. }catch (Exception e){
  297. throw new RuntimeException(e);
  298. }
  299. isTrue(repoRet5);
  300. }
  301. @Override
  302. public McR addSaleOrder(Map map) {
  303. //查询云枢客户单据详情
  304. String objectId = UtilMap.getString(map, "objectId");
  305. Map saleOrder = cpClient.getCpBo("XSDD", objectId, null);
  306. Map saleOrderData = cpClient.getCpBoResultData(saleOrder);
  307. //请求参数,要求为json字符串
  308. Save save = new Save();
  309. SaleOrderModel saleOrderModel = new SaleOrderModel();
  310. //基本信息
  311. FNumber FBillTypeID = new FNumber(UtilMap.getString(saleOrderData, "Dropdown1758339062589_key"));//单据类型
  312. String FDate = UtilMap.getString(saleOrderData, "Date1758339215935");//日期
  313. FNumber FCustId = new FNumber(UtilMap.getString(saleOrderData, "ShortText1760426148831"));//客户
  314. String F_NLD_DDTYPE = UtilMap.getString(saleOrderData, "Dropdown1758340059699_key");//订单类型
  315. FNumber FSalerId = new FNumber(UtilMap.getString(saleOrderData, "ShortText1760421121913"));//销售员
  316. FSTAFFNUMBER F_Sl_gendanyuan = new FSTAFFNUMBER(UtilMap.getString(saleOrderData, "Text1760421147555"));//跟单员
  317. String FBusinessType = UtilMap.getString(saleOrderData,"Dropdown1758339265813_key");//业务类型
  318. String F_WGR_Combo_re5 = UtilMap.getString(saleOrderData,"Dropdown1758340112723_key");//订单要求
  319. FNumber FHEADLOCID = new FNumber(UtilMap.getString(saleOrderData, "ShortText1760507577966"));//交货地点
  320. String FNote = UtilMap.getString(saleOrderData,"LongText1758339516625");//备注
  321. String F_Sl_customerbillno = UtilMap.getString(saleOrderData,"ShortText1758340044946");//客户订单号
  322. saleOrderModel.setFBillTypeID(FBillTypeID);
  323. saleOrderModel.setFDate(FDate);
  324. saleOrderModel.setFCustId(FCustId);
  325. saleOrderModel.setF_NLD_DDTYPE(F_NLD_DDTYPE);
  326. saleOrderModel.setFSalerId(FSalerId);
  327. saleOrderModel.setF_Sl_gendanyuan(F_Sl_gendanyuan);
  328. saleOrderModel.setFBusinessType(FBusinessType);
  329. saleOrderModel.setF_WGR_Combo_re5(F_WGR_Combo_re5);
  330. saleOrderModel.setFHEADLOCID(FHEADLOCID);
  331. saleOrderModel.setFNote(FNote);
  332. saleOrderModel.setF_Sl_customerbillno(F_Sl_customerbillno);
  333. //财务信息
  334. SaleOrderFinance saleOrderFinance = new SaleOrderFinance();
  335. FNumber FSettleCurrId = new FNumber(UtilMap.getString(saleOrderData, "Dropdown1758339227503_key"));//结算币别
  336. FNumber FRecConditionId = new FNumber(UtilMap.getString(saleOrderData, "Dropdown1758339314401_key"));//收款条件
  337. FNumber FSettleModeId = new FNumber(UtilMap.getString(saleOrderData, "Dropdown1758340854092_key"));//结算方式
  338. boolean FIsIncludedTax = UtilMap.getBoolean(saleOrderData,"Logic1758340099868");//是否含税
  339. boolean FIsPriceExcludeTax = UtilMap.getBoolean(saleOrderData,"Logic1758340955492");//价外税
  340. saleOrderFinance.setFSettleCurrId(FSettleCurrId);
  341. saleOrderFinance.setFRecConditionId(FRecConditionId);
  342. saleOrderFinance.setFSettleModeId(FSettleModeId);
  343. saleOrderFinance.setFIsIncludedTax(FIsIncludedTax);
  344. saleOrderFinance.setFIsPriceExcludeTax(FIsPriceExcludeTax);
  345. saleOrderModel.setFSaleOrderFinance(saleOrderFinance);
  346. //明细信息
  347. List<Map> saleDetailList = UtilMap.getList(saleOrderData, "Sheet1758341252878");
  348. List<SaleOrderEntry> saleOrderEntryList = new ArrayList<>();
  349. for (Map saleDetail : saleDetailList) {
  350. FNumber FMaterialId = new FNumber(UtilMap.getString(saleDetail, "ShortText1758341332222"));//物料编码
  351. FNumber FUnitID = new FNumber(UtilMap.getString(saleDetail, "Text1758341368975"));//销售单位
  352. Double FQty = UtilMap.getDouble(saleDetail, "Number1758341381523");//销售数量
  353. FNumber FPriceUnitId = new FNumber(UtilMap.getString(saleDetail, "Text1763091074956"));//计价单位
  354. Double FPriceUnitQty = UtilMap.getDouble(saleDetail, "Number1763091134020");//计价数量
  355. String F_Sl_XSTYPE = UtilMap.getString(saleDetail, "Dropdown1758341293022_key");//产品类别
  356. Double FTaxPrice = UtilMap.getDouble(saleDetail, "Number1758341424993");//含税单价
  357. boolean FIsFree = UtilMap.getBoolean(saleDetail,"Logic1758341430353");//是否赠品
  358. Double FEntryTaxRate = UtilMap.getDouble(saleDetail, "Number1758349078527");//税率
  359. String FDeliveryDate = UtilMap.getString(saleDetail,"Date1758341499356");//客户交期
  360. String FEntryNote = UtilMap.getString(saleDetail,"Date1758341499356");//备注
  361. Double F_VMKV_MPPRICE = UtilMap.getDouble(saleDetail, "Number1758341576099");//报价价格
  362. String F_VMKV_SCCQ1 = UtilMap.getString(saleDetail,"Dropdown1760425152219_key");//生产厂区
  363. String F_VMKV_JSYQ = UtilMap.getString(saleDetail,"ShortText1762135907570");//技术要求
  364. String F_NLD_BR = UtilMap.getString(saleDetail,"ShortText1762135907570");//剩磁(Br)
  365. String F_NLD_Hcj = UtilMap.getString(saleDetail,"ShortText1762135907570");//内禀矫顽力(Hcj)
  366. String F_NLD_Hcb = UtilMap.getString(saleDetail,"ShortText1762135907570");//磁感矫顽力(Hcb)
  367. String F_NLD_BH = UtilMap.getString(saleDetail,"ShortText1762135907570");//最大磁能积(BH)max
  368. String F_NLD_Hk = UtilMap.getString(saleDetail,"ShortText1762135907570");//方形度Hk/Hcj
  369. String F_VMKV_GXYQ = UtilMap.getString(saleDetail,"ShortText1762135907570");//公差要求
  370. boolean FDeliveryControl = UtilMap.getBoolean(saleDetail,"Logic1763091193161");//控制发货数量
  371. Double FDeliveryMaxQty = UtilMap.getDouble(saleDetail, "Number1763091294543");//发货上限
  372. Double FDeliveryMinQty = UtilMap.getDouble(saleDetail, "Number1763091312359");//发货下限
  373. SaleOrderEntry saleOrderEntry = new SaleOrderEntry();
  374. saleOrderEntry.setFMaterialId(FMaterialId);
  375. saleOrderEntry.setFUnitID(FUnitID);
  376. saleOrderEntry.setFPriceUnitId(FPriceUnitId);
  377. saleOrderEntry.setFPriceUnitQty(FPriceUnitQty);
  378. saleOrderEntry.setF_Sl_XSTYPE(F_Sl_XSTYPE);
  379. saleOrderEntry.setFQty(FQty);
  380. saleOrderEntry.setFTaxPrice(FTaxPrice);
  381. saleOrderEntry.setFIsFree(FIsFree);
  382. saleOrderEntry.setFEntryTaxRate(FEntryTaxRate);
  383. saleOrderEntry.setFDeliveryDate(FDeliveryDate);
  384. saleOrderEntry.setFEntryNote(FEntryNote);
  385. saleOrderEntry.setF_VMKV_MPPRICE(F_VMKV_MPPRICE);
  386. saleOrderEntry.setF_VMKV_SCCQ1(F_VMKV_SCCQ1);
  387. saleOrderEntry.setF_VMKV_JSYQ(F_VMKV_JSYQ);
  388. saleOrderEntry.setF_NLD_BR(F_NLD_BR);
  389. saleOrderEntry.setF_NLD_Hcj(F_NLD_Hcj);
  390. saleOrderEntry.setF_NLD_Hcb(F_NLD_Hcb);
  391. saleOrderEntry.setF_NLD_BH(F_NLD_BH);
  392. saleOrderEntry.setF_NLD_Hk(F_NLD_Hk);
  393. saleOrderEntry.setF_VMKV_GXYQ(F_VMKV_GXYQ);
  394. saleOrderEntry.setFDeliveryControl(FDeliveryControl);
  395. saleOrderEntry.setFDeliveryMaxQty(FDeliveryMaxQty);
  396. saleOrderEntry.setFDeliveryMinQty(FDeliveryMinQty);
  397. //todo 订单图纸附件上传
  398. List<Map> attachments = UtilMap.getList(saleDetail, "Attachment1763102109764");
  399. if (!attachments.isEmpty()){
  400. Map attachment = attachments.get(0);
  401. String refId = UtilMap.getString(attachment, "refId");
  402. String fileName = UtilMap.getString(attachment, "name");
  403. String escapeRefId = new String(Base64.getUrlDecoder().decode(refId), StandardCharsets.UTF_8).substring(5);
  404. String filePath = "/home/data/cloudpivot/file/"+escapeRefId.substring(0,2)+"/"+escapeRefId.substring(2,4)+"/"+escapeRefId;
  405. // String fileName2 = "4.png";
  406. // String filePath2 = "C:\\Users\\EDY\\Pictures\\4.png";
  407. String fileId = kdUpload(fileName, filePath);
  408. saleOrderEntry.setF_Sl_Attachment(fileId);
  409. }
  410. saleOrderEntryList.add(saleOrderEntry);
  411. }
  412. saleOrderModel.setFSaleOrderEntry(saleOrderEntryList);
  413. save.setModel(saleOrderModel);
  414. Gson gson2 = new Gson();
  415. String jsonData = gson2.toJson(save);
  416. log.info(jsonData);
  417. K3CloudApi client = new K3CloudApi(initIden());
  418. //业务对象标识
  419. String formId = "SAL_SaleOrder";
  420. //调用接口
  421. String resultJson = "";
  422. try {
  423. resultJson = client.save(formId,jsonData);
  424. }catch (Exception e){
  425. throw new RuntimeException(e);
  426. }
  427. //用于记录结果
  428. Gson gson = new Gson();
  429. //对返回结果进行解析和校验
  430. RepoRet repoRet = gson.fromJson(resultJson, RepoRet.class);
  431. String saleOrderCode = "";
  432. if (isTrue(repoRet)){
  433. String id = repoRet.getResult().getId();
  434. Submit submit = new Submit();
  435. submit.setIds(id);
  436. //提交客户
  437. String resultJson2 = "";
  438. try {
  439. resultJson2 = client.submit(formId, JSONObject.toJSONString(submit));
  440. }catch (Exception e){
  441. throw new RuntimeException(e);
  442. }
  443. RepoRet repoRet2 = gson.fromJson(resultJson2, RepoRet.class);
  444. isTrue(repoRet2);
  445. saleOrderCode = repoRet2.getResult().getResponseStatus().getSuccessEntitys().get(0).getNumber();
  446. //回写云枢销售订单编号
  447. cpClient.updateCpBo("XSDD",UtilMap.map("id, ShortText1758339123133",objectId,saleOrderCode),null);
  448. if (isTrue(repoRet2)){
  449. Audit audit = new Audit();
  450. audit.setNumbers(Arrays.asList(saleOrderCode));
  451. //审核销售订单
  452. String resultJson3 = "";
  453. try {
  454. resultJson3 = client.audit(formId,JSONObject.toJSONString(audit));
  455. }catch (Exception e){
  456. throw new RuntimeException(e);
  457. }
  458. RepoRet repoRet3 = gson.fromJson(resultJson3, RepoRet.class);
  459. isTrue(repoRet3);
  460. }
  461. }
  462. return McR.success(saleOrderCode);
  463. }
  464. @Async
  465. @Override
  466. public McR createTbProject(Map map) {
  467. //查询云枢重要样品打样申请详情
  468. String objectId = UtilMap.getString(map, "objectId");
  469. Map proofing = cpClient.getCpBo("ZYYPDYSQ", objectId, null);
  470. Map proofingData = cpClient.getCpBoResultData(proofing);
  471. String projectName = UtilMap.getString(proofingData, "ShortText1758525084919");
  472. String templateId = UtilMap.getString(proofingData, "Dropdown1760517115491_key");
  473. Map body = new HashMap();
  474. body.put("name",projectName);
  475. body.put("templateId",templateId);
  476. TBR tbr = (TBR) UtilHttp.doPost("https://open.teambition.com/api/v3/project/create-from-template", initTbHeaderToken(), null,body, TBR.class);
  477. Map result = (Map) tbr.getResult();
  478. String id = result.get("id").toString();
  479. //更新云枢打样申请项目id
  480. cpClient.updateCpBo("ZYYPDYSQ",UtilMap.map("id, ShortText1760517617788",objectId,id),null);
  481. return McR.success(id);
  482. }
  483. private IdentifyInfo initIden(){
  484. //注意 1:此处不再使用参数形式传入用户名及密码等敏感信息,改为在登录配置文件中设置。
  485. //注意 2:必须先配置第三方系统登录授权信息后,再进行业务操作,详情参考各语言版本SDK介绍中的登录配置文件说明。
  486. //读取配置,初始化SDK
  487. IdentifyInfo iden = new IdentifyInfo();
  488. iden.setUserName(kdWebApiConf.getXKDApiUserName());
  489. iden.setAppId(kdWebApiConf.getXKDApiAppID());
  490. iden.setdCID(kdWebApiConf.getXKDApiAcctID());
  491. iden.setAppSecret(kdWebApiConf.getXKDApiAppSec());
  492. iden.setServerUrl(kdWebApiConf.getXKDApiServerUrl());
  493. return iden;
  494. }
  495. private boolean isTrue(RepoRet repoRet){
  496. Gson gson = new Gson();
  497. if (repoRet.getResult().getResponseStatus().isIsSuccess()) {
  498. System.out.printf("接口返回结果: %s%n", gson.toJson(repoRet.getResult()));
  499. return true;
  500. } else {
  501. fail("接口返回结果: " + gson.toJson(repoRet.getResult().getResponseStatus()));
  502. return false;
  503. }
  504. }
  505. private Map<String, String> initTbHeaderToken() {
  506. Map header = new HashMap();
  507. header.put("Authorization", getTbAccessToken());
  508. header.put("X-Tenant-Id", tbConf.getTenantId());
  509. header.put("X-Tenant-Type", "organization");
  510. header.put("x-operator-id", tbConf.getOperatorId());
  511. return header;
  512. }
  513. private String getTbAccessToken() {
  514. synchronized(this.$lock) {
  515. String accessToken = UtilToken.get("invalid-token-teambition");
  516. if (StringUtils.isNotBlank(accessToken)) {
  517. return accessToken;
  518. } else {
  519. Algorithm algorithm = Algorithm.HMAC256(tbConf.getAppSecret());
  520. long timestamp = System.currentTimeMillis();
  521. Date issuedAt = new Date(timestamp);
  522. Date expiresAt = new Date(timestamp + EXPIRES_IN);
  523. accessToken = JWT.create().withClaim("_appId", tbConf.getAppID()).withIssuedAt(issuedAt).withExpiresAt(expiresAt).sign(algorithm);
  524. log.info("响应token, {}", accessToken);
  525. UtilToken.put("invalid-token-teambition", accessToken, EXPIRES_IN);
  526. return accessToken;
  527. }
  528. }
  529. }
  530. private String kdUpload(String fileName,String filePath){
  531. try {
  532. // 1. 读取文件为字节数组
  533. byte[] fileBytes = Files.readAllBytes(Paths.get(filePath));
  534. // 2. 转换为Base64字符串
  535. String base64String = "";
  536. K3CloudApi client = new K3CloudApi(initIden());
  537. // 定义分块大小(4MB)
  538. final int CHUNK_SIZE = 4 * 1024 * 1024;
  539. long fileSize = fileBytes.length;
  540. String fileId = null;
  541. //sdk无直接上传附件接口 临时将附件上传并绑定固定单据 得到fileId
  542. Map map = new HashMap();
  543. map.put("FileName", fileName);//文件名
  544. map.put("FormId", "SAL_SaleOrder");//表单id
  545. map.put("InterId", "104784");//单据内码
  546. map.put("BillNO", "S301-251118005");//单据编号
  547. // 如果文件小于等于4MB,直接上传
  548. if (fileSize <= CHUNK_SIZE) {
  549. base64String = Base64.getEncoder().encodeToString(fileBytes);
  550. map.put("IsLast", true);//是否最后一次上传
  551. map.put("SendByte", base64String);//文件字节数组转base64后的字符串
  552. String resultJson = client.attachmentUpload(JSONObject.toJSONString(map));
  553. Map parse = (Map) JSONObject.parse(resultJson);
  554. Map map1 = UtilMap.getMap(parse, "Result");
  555. fileId = UtilMap.getString(map1, "FileId");
  556. return fileId;
  557. }
  558. // 分块上传逻辑
  559. int totalChunks = (int) Math.ceil((double) fileSize / CHUNK_SIZE);
  560. for (int i = 0; i < totalChunks; i++) {
  561. // 计算当前块的起始和结束位置
  562. int start = i * CHUNK_SIZE;
  563. int end = (int) Math.min(start + CHUNK_SIZE, fileSize);
  564. int chunkLength = end - start;
  565. // 提取当前分块的数据
  566. byte[] chunkBytes = new byte[chunkLength];
  567. System.arraycopy(fileBytes, start, chunkBytes, 0, chunkLength);
  568. // 转换为Base64字符串
  569. base64String = Base64.getEncoder().encodeToString(chunkBytes);
  570. // 第一个块需要获取FileId,后续块需要携带FileId
  571. boolean isLastChunk = (i == totalChunks - 1);
  572. if (i == 0) {
  573. // 第一个块,IsLast为false
  574. map.put("IsLast", false);
  575. map.put("SendByte", base64String);//文件字节数组转base64后的字符串
  576. String resultJson = client.attachmentUpload(JSONObject.toJSONString(map));
  577. Map parse = (Map) JSONObject.parse(resultJson);
  578. Map map1 = UtilMap.getMap(parse, "Result");
  579. fileId = UtilMap.getString(map1, "FileId");
  580. } else {
  581. // 后续块,需要携带FileId
  582. map.put("FileId", fileId);
  583. map.put("IsLast", isLastChunk);
  584. map.put("SendByte", base64String);//文件字节数组转base64后的字符串
  585. String resultJson = client.attachmentUpload(JSONObject.toJSONString(map));
  586. }
  587. }
  588. System.out.println(fileId);
  589. return fileId;
  590. } catch (Exception e) {
  591. throw new RuntimeException(e);
  592. }
  593. }
  594. /*private String kdUpload(String fileName, String filePath) {
  595. try {
  596. // 定义分块大小(4MB)
  597. final int CHUNK_SIZE = 4 * 1024 * 1024;
  598. // 1. 读取文件为字节数组
  599. byte[] fileBytes = Files.readAllBytes(Paths.get(filePath));
  600. long fileSize = fileBytes.length;
  601. String fileId = null;
  602. // 如果文件小于等于4MB,直接上传
  603. if (fileSize <= CHUNK_SIZE) {
  604. String base64String = Base64.getEncoder().encodeToString(fileBytes);
  605. Map<String, Object> body = new HashMap<>();
  606. Map<String, Object> data = new HashMap<>();
  607. data.put("FileName", fileName);
  608. data.put("SendByte", base64String);
  609. data.put("IsLast", true);
  610. body.put("data",data);
  611. // 调用上传接口(带会话检查)
  612. Map<String, Object> result = uploadWithSessionCheck(body, true);
  613. // 获取FileId
  614. Map<String, Object> resultData = UtilMap.getMap(result, "Result");
  615. fileId = UtilMap.getString(resultData, "FileId");
  616. return fileId;
  617. }
  618. // 分块上传逻辑
  619. int totalChunks = (int) Math.ceil((double) fileSize / CHUNK_SIZE);
  620. for (int i = 0; i < totalChunks; i++) {
  621. // 计算当前块的起始和结束位置
  622. int start = i * CHUNK_SIZE;
  623. int end = (int) Math.min(start + CHUNK_SIZE, fileSize);
  624. int chunkLength = end - start;
  625. // 提取当前分块的数据
  626. byte[] chunkBytes = new byte[chunkLength];
  627. System.arraycopy(fileBytes, start, chunkBytes, 0, chunkLength);
  628. // 转换为Base64字符串
  629. String base64String = Base64.getEncoder().encodeToString(chunkBytes);
  630. // 准备请求体
  631. Map<String, Object> body = new HashMap<>();
  632. Map<String,Object> data = new HashMap<>();
  633. data.put("FileName", fileName);
  634. data.put("SendByte", base64String);
  635. body.put("data",data);
  636. // 第一个块需要获取FileId,后续块需要携带FileId
  637. boolean isLastChunk = (i == totalChunks - 1);
  638. if (i == 0) {
  639. // 第一个块,IsLast为false
  640. body.put("IsLast", false);
  641. // 调用上传接口(带会话检查)
  642. Map<String, Object> result = uploadWithSessionCheck(body, false);
  643. // 获取FileId
  644. Map<String, Object> resultData = UtilMap.getMap(result, "Result");
  645. fileId = UtilMap.getString(resultData, "FileId");
  646. } else {
  647. // 后续块,需要携带FileId
  648. body.put("FileId", fileId);
  649. body.put("IsLast", isLastChunk);
  650. // 调用上传接口(带会话检查)
  651. uploadWithSessionCheck(body, isLastChunk);
  652. }
  653. }
  654. return fileId;
  655. } catch (Exception e) {
  656. throw new RuntimeException("文件上传失败: " + e.getMessage(), e);
  657. }
  658. }
  659. // 带会话检查的上传方法(支持单块和多块上传)
  660. private Map<String, Object> uploadWithSessionCheck(Map<String, Object> body, boolean isLastChunk) {
  661. while (true) {
  662. try {
  663. // 调用上传接口
  664. Map<String, Object> result = (Map<String, Object>) JSONObject.parse(UtilHttp.doPost(kdWebApiConf.getXKDApiServerUrl() + "Kingdee.BOS.WebApi.ServicesStub.DynamicFormService.UploadFile.common.kdsvc", null, null, body));
  665. // 检查响应状态
  666. checkResponseStatus(result);
  667. return result;
  668. } catch (RuntimeException e) {
  669. // 解析错误响应
  670. try {
  671. Map<String, Object> responseStatus = (Map<String, Object>) JSONObject.parse(e.getMessage());
  672. // 如果是会话丢失错误
  673. if (responseStatus != null && UtilMap.getString(((List<Map>)UtilMap.getList(responseStatus, "Errors")).get(0),"Message").equals("会话信息已丢失,请重新登录")) {
  674. // 重新登录
  675. kdLogin();
  676. // 如果是最后一块上传失败,需要设置IsLast为true
  677. if (isLastChunk) {
  678. body.put("IsLast", true);
  679. }
  680. // 重试上传
  681. continue;
  682. }
  683. } catch (Exception parseException) {
  684. // 如果不是会话丢失错误,直接抛出原始异常
  685. throw e;
  686. }
  687. // 如果不是会话丢失错误,直接抛出原始异常
  688. throw e;
  689. }
  690. }
  691. }
  692. // 检查响应状态
  693. private void checkResponseStatus(Map<String, Object> result) {
  694. if (result == null || !result.containsKey("Result")) {
  695. throw new RuntimeException("无效的响应格式");
  696. }
  697. Map<String, Object> resultData = UtilMap.getMap(result, "Result");
  698. Map<String, Object> responseStatus = UtilMap.getMap(resultData, "ResponseStatus");
  699. if (responseStatus == null || !UtilMap.getBoolean(responseStatus, "IsSuccess")) {
  700. String message = UtilMap.getString(resultData, "Message");
  701. // 如果有错误码,也包含在异常信息中
  702. int errorCode = UtilMap.getInt(responseStatus, "ErrorCode");
  703. if (errorCode != 0) {
  704. message = "错误码: " + errorCode + ", 消息: " + message;
  705. log.info("message: {}", message);
  706. }
  707. throw new RuntimeException(JSONObject.toJSONString(responseStatus));
  708. }
  709. }
  710. private void kdLogin(){
  711. try {
  712. //金蝶登录
  713. String acctID = kdWebApiConf.getXKDApiAcctID();
  714. String username = kdWebApiConf.getXKDApiUserName();
  715. String appId = kdWebApiConf.getXKDApiAppID();
  716. String appSec = kdWebApiConf.getXKDApiAppSec();
  717. String timestamp = System.currentTimeMillis()/1000 + "";
  718. String[] arr = {acctID,username,appId,appSec,timestamp};
  719. Arrays.sort(arr, String::compareTo);
  720. String str = String.join("", arr);
  721. // 1. 创建 MessageDigest 实例,指定 SHA-256 算法
  722. MessageDigest digest = MessageDigest.getInstance("SHA-256");
  723. // 2. 输入字符串转换为字节数组,并计算哈希值
  724. byte[] hashBytes = digest.digest(str.getBytes(StandardCharsets.UTF_8));
  725. // 3. 将字节数组转换为十六进制字符串
  726. StringBuilder sign = new StringBuilder();
  727. for (byte b : hashBytes) {
  728. String hex = Integer.toHexString(0xff & b);
  729. if (hex.length() == 1) {
  730. sign.append('0'); // 补零
  731. }
  732. sign.append(hex);
  733. }
  734. // 4. 输出结果
  735. System.out.println("SHA-256 哈希值: " + sign.toString());
  736. Map body = new HashMap();
  737. body.put("acctID",acctID);
  738. body.put("username",username);
  739. body.put("appId",appId);
  740. body.put("timestamp",timestamp);
  741. body.put("sign",sign.toString());
  742. body.put("lcid",2052);
  743. UtilHttp.doPost(kdWebApiConf.getXKDApiServerUrl() + "Kingdee.BOS.WebApi.ServicesStub.AuthService.LoginBySign.common.kdsvc", null, null, body);
  744. }catch (Exception e){
  745. throw new RuntimeException(e);
  746. }
  747. }*/
  748. }