WechatController.java 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753
  1. package com.chuanghai.smartschool.tuitionpayment.controller;
  2. import com.alibaba.fastjson.JSON;
  3. import com.alibaba.fastjson.JSONArray;
  4. import com.alibaba.fastjson.JSONObject;
  5. import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
  6. import com.chuanghai.smartschool.tuitionpayment.common.exception.BizCodeEnume;
  7. import com.chuanghai.smartschool.tuitionpayment.common.exception.RRException;
  8. import com.chuanghai.smartschool.tuitionpayment.common.utils.CommonResult;
  9. import com.chuanghai.smartschool.tuitionpayment.config.WechatConfig;
  10. import com.chuanghai.smartschool.tuitionpayment.config.WeixiaoConfig;
  11. import com.chuanghai.smartschool.tuitionpayment.entity.*;
  12. import com.chuanghai.smartschool.tuitionpayment.service.*;
  13. import com.chuanghai.smartschool.tuitionpayment.vo.PayableInfoStudentResultVO;
  14. import com.chuanghai.smartschool.tuitionpayment.vo.WeixiaoVO;
  15. import com.fasterxml.jackson.core.type.TypeReference;
  16. import com.fasterxml.jackson.databind.JsonNode;
  17. import com.fasterxml.jackson.databind.ObjectMapper;
  18. import org.apache.poi.ss.formula.functions.T;
  19. import org.springframework.beans.factory.annotation.Autowired;
  20. import org.springframework.http.HttpEntity;
  21. import org.springframework.http.HttpHeaders;
  22. import org.springframework.http.MediaType;
  23. import org.springframework.http.ResponseEntity;
  24. import org.springframework.http.converter.StringHttpMessageConverter;
  25. import org.springframework.scheduling.annotation.Scheduled;
  26. import org.springframework.stereotype.Controller;
  27. import org.springframework.util.LinkedMultiValueMap;
  28. import org.springframework.util.MultiValueMap;
  29. import org.springframework.web.bind.annotation.*;
  30. import org.springframework.web.client.RestTemplate;
  31. import java.net.URLEncoder;
  32. import java.nio.charset.StandardCharsets;
  33. import java.util.*;
  34. /**
  35. * 微信相关接口
  36. *
  37. * @author codingliang
  38. * @email codingliang@gmail.com
  39. * @date 2021-08-12 16:04
  40. */
  41. @Controller
  42. @RequestMapping("tuitionpayment/wechat")
  43. public class WechatController {
  44. @Autowired
  45. private WechatConfig wechatConfig;
  46. @Autowired
  47. private WeixiaoConfig weixiaoConfig;
  48. @Autowired
  49. private PayableInfoService payableInfoService;
  50. @Autowired
  51. private PayableInfoWaterService payableInfoWaterService;
  52. @Autowired
  53. private PayOrderService payOrderService;
  54. @Autowired
  55. private FeedbackMsgController feedbackMsgController;
  56. @Autowired
  57. private PayItemService payItemService;
  58. @Autowired
  59. private SchoolUserService schoolUserService;
  60. /**
  61. * 用于记录用户的access_token
  62. */
  63. private String accessTokenPublic = "";
  64. /**
  65. * 用于记录催缴的次数 计时器
  66. */
  67. private Integer askCount = 0;
  68. /**
  69. * 微校中的学校组织代码
  70. */
  71. private String schoolOrgId;
  72. /**
  73. * 用于记录当前获取微校用户的页码信息
  74. */
  75. private static Integer userPage = 1;
  76. /**
  77. * 微信授权回调地址
  78. *
  79. * @param code 微信code
  80. * @apiNote 用户跳转到微信授权链接上,微信服务器接收用户授权后会携带code回调到该接口上,该接口使用code获取到用户的openId信息。
  81. * 如果openId获取成功,该接口会以 【fontendUrl + 路由地址 + ?openId=wx123456】 的形式跳回到前端应用页面;
  82. * 如果openId获取失败,该接口会以 【fontendUrl + /error/?errorMsg=获取用户openId失败】 的形式跳回到前端应用页面。
  83. * <strong>注意:</strong>
  84. * fontendUrl + 路由地址:前端项目地址+页面路由地址,用于前端页面接收用户的信息或错误信息,该地址需要前端人员与后台开发人员协调好。
  85. */
  86. @GetMapping("pub/auth")
  87. public String pubAuth(String code, String state) {
  88. // code换取access_token
  89. String url = "https://api.weixin.qq.com/sns/oauth2/access_token?" +
  90. "appid=" + wechatConfig.getAppid() +
  91. "&secret=" + wechatConfig.getSecret() +
  92. "&code=" + code +
  93. "&grant_type=authorization_code";
  94. try {
  95. RestTemplate restTemplate = new RestTemplate();
  96. restTemplate.getMessageConverters().set(1, new StringHttpMessageConverter(StandardCharsets.UTF_8)); // 解决回参中文乱码
  97. String response = restTemplate.getForObject(url, String.class);
  98. ObjectMapper mapper = new ObjectMapper();
  99. JsonNode jsonNode = mapper.readTree(response);
  100. String openid = jsonNode.get("openid").asText();
  101. return "redirect:" + wechatConfig.getFontendUrl() + "/#/" + state + "/?openId=" + openid;
  102. } catch (Exception e) {
  103. return "redirect:" + wechatConfig.getFontendUrl() + "/error/?errorMsg=获取用户openId失败";
  104. }
  105. }
  106. /**
  107. * 微校授权回调地址
  108. *
  109. * @param wxcode 微校code
  110. * @param state 透传数据
  111. * @return
  112. * @apiNote 用户跳转到微校授权链接上,微校服务器接收用户授权后会携带wxcode回调到该接口上,该接口使用wxcode获取到用户的信息。
  113. * 如果用户信息获取成功,该接口会以 【fontendUrl + /?cardNumber=wx123456&name=测试用户】 的形式跳回到前端应用页面;
  114. * 如果用户信息获取失败,该接口会以 【fontendUrl + /error/?errorMsg=获取用户信息失败】 的形式跳回到前端应用页面。
  115. * <strong>注意:</strong>
  116. * fontendUrl + 路由地址:前端项目地址+页面路由地址,用于前端页面接收用户的信息或错误信息,该地址需要前端人员与后台开发人员协调好。
  117. * </p>
  118. */
  119. @GetMapping("weixiao/auth")
  120. public String weixiaoAuth(String wxcode, String state) {
  121. String tokenUrl = "https://open.wecard.qq.com/connect/oauth2/token";
  122. Map<String, String> tokenParams = new HashMap<>();
  123. tokenParams.put("wxcode", wxcode);
  124. tokenParams.put("app_key", weixiaoConfig.getAppKey());
  125. tokenParams.put("app_secret", weixiaoConfig.getAppSecret());
  126. tokenParams.put("grant_type", "authorization_code");
  127. tokenParams.put("redirect_uri", state); // 该地址需要与发起授权地址保持一直
  128. try {
  129. // wecode换取token
  130. RestTemplate client = new RestTemplate();
  131. HttpHeaders headers = new HttpHeaders();
  132. headers.setContentType(MediaType.APPLICATION_JSON);
  133. HttpEntity<Map<String, String>> request = new HttpEntity<>(tokenParams, headers);
  134. //ResponseEntity<String> tokenResponse = client.postForEntity(tokenUrl, tokenParams, String.class);
  135. ResponseEntity<String> tokenResponse = client.postForEntity(tokenUrl, request, String.class);
  136. ObjectMapper mapper = new ObjectMapper();
  137. Map<String, Object> jsonMap = mapper.readValue(tokenResponse.getBody(), new TypeReference<Map<String, Object>>() {
  138. });
  139. String accessToken = (String) jsonMap.get("access_token");
  140. // token换取用户信息
  141. String userInfoUrl = "https://open.wecard.qq.com/connect/oauth/get-user-info";
  142. Map<String, String> userInfoParam = new HashMap<>();
  143. userInfoParam.put("access_token", accessToken);
  144. ResponseEntity<String> userInfoResponse = client.postForEntity(userInfoUrl, userInfoParam, String.class);
  145. Map<String, Object> userInfoMap = mapper.readValue(userInfoResponse.getBody(), new TypeReference<Map<String, Object>>() {
  146. });
  147. String cardNumber = userInfoMap.get("card_number").toString();
  148. String encodeName = URLEncoder.encode(userInfoMap.get("name").toString(), "utf-8");
  149. return "redirect:" + weixiaoConfig.getFontendUrl() + "/#/pages/index/index/?cardNumber=" + cardNumber + "&name=" + encodeName;
  150. } catch (Exception e) {
  151. e.printStackTrace();
  152. return "redirect:" + weixiaoConfig.getFontendUrl() + "/#/error/";
  153. }
  154. }
  155. /**
  156. * 获取微校的应用有效凭证 7200s有效 两小时内有效
  157. *
  158. * @return
  159. */
  160. @Scheduled(fixedDelay = 7190000)
  161. public void getWeiXiaoToken() {
  162. try {
  163. RestTemplate client = new RestTemplate();
  164. ObjectMapper mapper = new ObjectMapper();
  165. String userInfoUrl = "https://open.wecard.qq.com/cgi-bin/oauth2/token";
  166. Map<String, String> userInfoParam = new HashMap<>();
  167. // userInfoParam.put("app_key","48103AB41FFBC5FE");
  168. // userInfoParam.put("app_secret", "5B7FB4D3CC243695EED3693044D0FC54");
  169. userInfoParam.put("app_key", weixiaoConfig.getAppKey());
  170. userInfoParam.put("app_secret", weixiaoConfig.getAppSecret());
  171. userInfoParam.put("grant_type", "client_credentials");
  172. userInfoParam.put("scope", "base");
  173. userInfoParam.put("ocode", "1015730314");
  174. ResponseEntity<String> userInfoResponse = client.postForEntity(userInfoUrl, userInfoParam, String.class);
  175. Map<String, Object> userInfoMap = mapper.readValue(userInfoResponse.getBody(), new TypeReference<Map<String, Object>>() {
  176. });
  177. accessTokenPublic = userInfoMap.get("access_token").toString();
  178. } catch (Exception e) {
  179. throw new RRException(BizCodeEnume.TOKET_INVALID, "微校token获取失败");
  180. }
  181. }
  182. /**
  183. * 获取微校的组织结构
  184. *
  185. * @return
  186. */
  187. @PostMapping("/getSchoolOrg")
  188. public String getSchoolOrg() {
  189. String orgInfoUrl = "https://open.wecard.qq.com/cgi-bin/user/org-edu-list";
  190. MultiValueMap<String, Object> map = new LinkedMultiValueMap<>();
  191. map.add("access_token", accessTokenPublic);
  192. RestTemplate restTemplate = new RestTemplate();
  193. HttpHeaders headers = new HttpHeaders();
  194. headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
  195. HttpEntity<MultiValueMap<String, Object>> request = new HttpEntity<>(map, headers);
  196. ResponseEntity<String> responseEntity = restTemplate.postForEntity(orgInfoUrl, request, String.class);
  197. JSONObject jsonObj = JSON.parseObject(responseEntity.getBody());
  198. JSONArray orgArray = jsonObj.getJSONArray("organization");
  199. if (orgArray != null) {
  200. JSONObject jsonObject = JSONObject.parseObject(orgArray.get(0).toString());
  201. schoolOrgId = jsonObject.get("id").toString();
  202. }
  203. return schoolOrgId;
  204. }
  205. /**
  206. * 获取微校用户的信息
  207. *
  208. * @return
  209. */
  210. @PostMapping("getSchoolUser")
  211. @ResponseBody
  212. public String getSchoolUser() {
  213. //先判断是否获取过学校的组织结构编号
  214. if (schoolOrgId == null) {
  215. getSchoolOrg();
  216. }
  217. String userInfoUrl = "https://open.wecard.qq.com/cgi-bin/user/get-org-users";
  218. MultiValueMap<String, Object> map = new LinkedMultiValueMap<>();
  219. map.add("access_token", accessTokenPublic);
  220. map.add("org_id", schoolOrgId);
  221. map.add("fetch_child", 1);
  222. map.add("page", userPage);
  223. map.add("page_size", 5000);//5000
  224. RestTemplate restTemplate = new RestTemplate();
  225. HttpHeaders headers = new HttpHeaders();
  226. headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
  227. HttpEntity<MultiValueMap<String, Object>> request = new HttpEntity<>(map, headers);
  228. ResponseEntity<String> responseEntity = restTemplate.postForEntity(userInfoUrl, request, String.class);
  229. JSONObject jsonObj = JSON.parseObject(responseEntity.getBody());
  230. Integer total = Integer.parseInt(jsonObj.get("total").toString());
  231. //获得总页码数
  232. int totalPage = (int) Math.ceil(total / 5000);//5000
  233. JSONArray userlist = jsonObj.getJSONArray("userlist");
  234. ObjectMapper mapper = new ObjectMapper();
  235. ArrayList<SchoolUser> schoolUserList = new ArrayList<>();
  236. if (userlist != null) {
  237. userlist.forEach(user -> {
  238. SchoolUser schoolUser = new SchoolUser();
  239. Calendar calendar = Calendar.getInstance();
  240. int year = calendar.getWeekYear();
  241. try {
  242. Map<String, Object> jsonMap = mapper.readValue(JSONObject.toJSON(user).toString(), new TypeReference<Map<String, Object>>() {
  243. });
  244. if (jsonMap.get("card_number") != null) {
  245. schoolUser.setCardNumber(jsonMap.get("card_number").toString());
  246. String card_number = jsonMap.get("card_number").toString();
  247. if (!card_number.startsWith("VIS") && !card_number.startsWith("REG") && !card_number.startsWith("p")) {
  248. if (card_number.length() > 5 && card_number.length() < 18) {
  249. if (card_number.length() != 11) {
  250. schoolUser.setStudentNo(card_number);
  251. }
  252. }
  253. }
  254. }
  255. if (jsonMap.get("serial_number") != null) {
  256. if (!(jsonMap.get("serial_number").toString().equals(""))) {
  257. schoolUser.setStudentNo(jsonMap.get("serial_number").toString());
  258. }
  259. }
  260. if (jsonMap.get("name") != null) {
  261. schoolUser.setName(jsonMap.get("name").toString());
  262. }
  263. if (jsonMap.get("id_card") != null) {
  264. schoolUser.setIdCard(jsonMap.get("id_card").toString());
  265. }
  266. } catch (Exception e) {
  267. e.printStackTrace();
  268. }
  269. // 通过cardNumbe查询用户是否存在
  270. SchoolUser schoolUserInBase = querySchoolUser(schoolUser.getCardNumber());
  271. if (schoolUserInBase.getId() != null) {
  272. schoolUser.setId(schoolUserInBase.getId());
  273. }
  274. //将得到的数据封装进list集合中,批量添加数据
  275. schoolUserList.add(schoolUser);
  276. });
  277. }
  278. //批量添加数据
  279. if (schoolUserList.size() > 0){
  280. schoolUserService.saveOrUpdateBatch(schoolUserList);
  281. }
  282. if (userPage <= totalPage) {
  283. userPage += 1;
  284. getSchoolUser();
  285. } else {
  286. return String.valueOf(userPage);
  287. }
  288. return String.valueOf(totalPage);
  289. }
  290. /**
  291. * 重置微校的计数页码
  292. * @param page
  293. * @return
  294. */
  295. @GetMapping("resetUserPage")
  296. @ResponseBody
  297. public String resetUserPage(String page){
  298. Integer thisUserOage = userPage;
  299. userPage = Integer.parseInt(page);
  300. return "修改前页码计数器 --"+thisUserOage+" 修改后页码计数器---"+userPage;
  301. }
  302. /**
  303. * 通过cardNumber判断该用户是否存在于数据库SchoolUser表当中
  304. *
  305. * @param cardNumber
  306. * @param
  307. * @return
  308. */
  309. @PostMapping("/querySchoolUser")
  310. public SchoolUser querySchoolUser(String cardNumber) {
  311. QueryWrapper<SchoolUser> wrapper = new QueryWrapper<>();
  312. //通过微校用户的 cardNumber idCard workNo studentNo 四者均为唯一标识查找用户是否存在数据库中
  313. wrapper.eq("card_number", cardNumber);
  314. List<SchoolUser> list = schoolUserService.list(wrapper);
  315. SchoolUser schoolUser = new SchoolUser();
  316. if (list.size() > 0) {
  317. schoolUser = list.get(0);
  318. }
  319. return schoolUser;
  320. }
  321. /**
  322. * 通过card_number查询身份证
  323. *
  324. * @param cardNumber
  325. * @return
  326. */
  327. @GetMapping("getIdCard")
  328. @ResponseBody
  329. public String getIdCard(String cardNumber) {
  330. RestTemplate client = new RestTemplate();
  331. ObjectMapper mapper = new ObjectMapper();
  332. String userInfoUrl = "https://open.wecard.qq.com/cgi-bin/user/search";
  333. Map<String, String> userInfoParam = new HashMap<>();
  334. userInfoParam.put("access_token", accessTokenPublic);
  335. userInfoParam.put("keywords", cardNumber);
  336. ResponseEntity<String> userInfoResponse = client.postForEntity(userInfoUrl, userInfoParam, String.class);
  337. JSONObject jsonObj = JSON.parseObject(userInfoResponse.getBody());
  338. JSONArray userlist = jsonObj.getJSONArray("userlist");
  339. String id_card = "";
  340. try {
  341. Map<String, Object> userInfoMap = mapper.readValue(userlist.get(0).toString(), new TypeReference<Map<String, Object>>() {
  342. });
  343. if (userInfoMap.get("id_card") != null) {
  344. id_card = userInfoMap.get("id_card").toString();
  345. }
  346. } catch (Exception e) {
  347. e.printStackTrace();
  348. }
  349. return id_card;
  350. }
  351. /**
  352. * 通过学生姓名 身份证查找用户的cardNumber
  353. *
  354. * @param studentName
  355. * @param idCard
  356. * @return
  357. */
  358. @GetMapping("getUserCardNumber")
  359. @ResponseBody
  360. public String getUserCardNumber(String studentName, String idCard) {
  361. RestTemplate client = new RestTemplate();
  362. ObjectMapper mapper = new ObjectMapper();
  363. String userInfoUrl = "https://open.wecard.qq.com/cgi-bin/user/search";
  364. Map<String, String> userInfoParam = new HashMap<>();
  365. userInfoParam.put("access_token", accessTokenPublic);
  366. userInfoParam.put("keywords", studentName);
  367. ResponseEntity<String> userInfoResponse = client.postForEntity(userInfoUrl, userInfoParam, String.class);
  368. JSONObject jsonObj = JSON.parseObject(userInfoResponse.getBody());
  369. JSONArray userlist = jsonObj.getJSONArray("userlist");
  370. String id_card = "";
  371. String card_numbner = "";
  372. if (userlist.size() > 0) {
  373. for (int m = 0; m < userlist.size(); m++) {
  374. System.out.println(userlist.get(m));
  375. try {
  376. Map<String, Object> userInfoMap = mapper.readValue(userlist.get(m).toString(), new TypeReference<Map<String, Object>>() {
  377. });
  378. //匹配传递的参数,匹配成功则返回相应的card_number
  379. if (userInfoMap.get("id_card") != null) {
  380. if (userInfoMap.get("id_card").toString().equals(idCard)) {
  381. if (userInfoMap.get("card_number") != null){
  382. card_numbner = userInfoMap.get("card_number").toString();
  383. }
  384. }
  385. }
  386. } catch (Exception e) {
  387. e.printStackTrace();
  388. }
  389. }
  390. }
  391. return card_numbner;
  392. }
  393. public PayableInfoStudentResultVO queryStudent() {
  394. PayableInfoStudentResultVO payableInfoStudentResultVO = new PayableInfoStudentResultVO();
  395. try {
  396. // token换取用户信息
  397. RestTemplate client = new RestTemplate();
  398. ObjectMapper mapper = new ObjectMapper();
  399. String userInfoUrl = "https://open.wecard.qq.com/connect/oauth/get-user-info";
  400. Map<String, String> userInfoParam = new HashMap<>();
  401. userInfoParam.put("access_token", accessTokenPublic);
  402. ResponseEntity<String> userInfoResponse = client.postForEntity(userInfoUrl, userInfoParam, String.class);
  403. Map<String, Object> userInfoMap = mapper.readValue(userInfoResponse.getBody(), new TypeReference<Map<String, Object>>() {
  404. });
  405. String name = userInfoMap.get("name").toString();
  406. String card_number = userInfoMap.get("card_number").toString();
  407. String grade = userInfoMap.get("grade").toString();
  408. grade = grade.substring(2, grade.length());
  409. String clazz = userInfoMap.get("class").toString();
  410. payableInfoStudentResultVO.setIdCard(card_number);
  411. payableInfoStudentResultVO.setStudentName(name);
  412. payableInfoStudentResultVO.setMajor(grade + clazz);
  413. } catch (Exception e) {
  414. e.printStackTrace();
  415. }
  416. return payableInfoStudentResultVO;
  417. }
  418. /**
  419. * 实现同步下发缴费订单功能
  420. *
  421. * @param itemName
  422. * @return
  423. */
  424. @PostMapping("/oneKey")
  425. @ResponseBody
  426. public CommonResult<T> oneKey(String itemName) {
  427. WeixiaoVO weixiaoVO = new WeixiaoVO();
  428. QueryWrapper<PayableInfoEntity> wrapper = new QueryWrapper<>();
  429. QueryWrapper<PayableInfoWaterEntity> water = new QueryWrapper<>();
  430. wrapper.eq("payment_item", itemName)
  431. .eq("pay_notice_type", "1");
  432. water.eq("payment_item", itemName)
  433. .eq("pay_notice_type", "1");
  434. List<PayableInfoEntity> payableInfoEntityList = payableInfoService.list(wrapper);
  435. List<PayableInfoWaterEntity> payableInfoWaterEntityList = payableInfoWaterService.list(water);
  436. List<String> cardNumberList = new ArrayList<>();
  437. if (payableInfoEntityList.size() > 0) {
  438. payableInfoEntityList.forEach(payableInfoEntity -> {
  439. payableInfoEntity.setPayNoticeType("2");
  440. cardNumberList.add(payableInfoEntity.getCardNumber());
  441. payableInfoService.updateById(payableInfoEntity);
  442. });
  443. }
  444. if (payableInfoWaterEntityList.size() > 0) {
  445. payableInfoWaterEntityList.forEach(payableInfoEntityWater -> {
  446. payableInfoEntityWater.setPayNoticeType("2");
  447. cardNumberList.add(payableInfoEntityWater.getCardNumber());
  448. payableInfoWaterService.updateById(payableInfoEntityWater);
  449. });
  450. }
  451. weixiaoVO.setCardNumberList(cardNumberList);
  452. weixiaoVO.setCardNumberList(cardNumberList);
  453. weixiaoVO.setTitle(itemName + "缴纳通知");
  454. weixiaoVO.setSender("南昌交通学院");
  455. weixiaoVO.setContent("您有一笔" + itemName + "账单,请尽快缴纳");
  456. JSONObject jsonObject = (JSONObject) JSONObject.toJSON(weixiaoVO);
  457. return notice(jsonObject);
  458. }
  459. /**
  460. * 实现催缴下发缴费订单功能
  461. *
  462. * @param jsonObject
  463. * @return
  464. */
  465. @PostMapping("/oneKeyNotice")
  466. @ResponseBody
  467. public CommonResult<T> oneKeyNotice(@RequestBody JSONObject jsonObject) {
  468. String itemName = jsonObject.get("itemName").toString();
  469. JSONArray cardNumberList = jsonObject.getJSONArray("cardNumberList");
  470. if (cardNumberList.size() == 0) {
  471. QueryWrapper<PayableInfoEntity> wrapper = new QueryWrapper<>();
  472. QueryWrapper<PayableInfoWaterEntity> water = new QueryWrapper<>();
  473. wrapper.in("pay_item_type", "1", "3")
  474. .eq("payment_item", itemName);
  475. water.eq("pay_item_type", "1")
  476. .eq("payment_item", itemName);
  477. List<PayableInfoEntity> payableInfoEntityList = payableInfoService.list(wrapper);
  478. List<PayableInfoWaterEntity> payableInfoWaterEntityList = payableInfoWaterService.list(water);
  479. if (payableInfoEntityList.size() > 0) {
  480. payableInfoEntityList.forEach(payableInfoEntity -> {
  481. cardNumberList.add(payableInfoEntity.getCardNumber());
  482. });
  483. }
  484. if (payableInfoWaterEntityList.size() > 0) {
  485. payableInfoWaterEntityList.forEach(payableInfoEntityWater -> {
  486. cardNumberList.add(payableInfoEntityWater.getCardNumber());
  487. });
  488. }
  489. }
  490. WeixiaoVO weixiaoVO = new WeixiaoVO();
  491. weixiaoVO.setCardNumberList(cardNumberList);
  492. weixiaoVO.setTitle(itemName + "催缴通知");
  493. weixiaoVO.setSender("南昌交通学院");
  494. weixiaoVO.setContent("您有一笔" + itemName + "账单,请尽快缴纳");
  495. JSONObject json = (JSONObject) JSONObject.toJSON(weixiaoVO);
  496. return notice(json);
  497. }
  498. /**
  499. * @param jsonObject 封装了发送微校通知的参数信息
  500. * * @param jsonObject 封装了发送微校通知的参数信息
  501. * @return
  502. */
  503. @PostMapping("weixiao/notice")
  504. @ResponseBody
  505. public CommonResult<T> notice(@RequestBody JSONObject jsonObject) {
  506. WeixiaoVO weixiaoVO = JSONObject.toJavaObject(jsonObject, WeixiaoVO.class);
  507. Map<String, String> param = new HashMap<>();
  508. param.put("title", weixiaoVO.getTitle());
  509. String s = JSON.parseArray(weixiaoVO.getCardNumberList().toString()).toJSONString();
  510. param.put("cards", s);
  511. param.put("content", weixiaoVO.getContent());
  512. param.put("sender", weixiaoVO.getSender());
  513. String url = "https://open.wecard.qq.com/cgi-bin/notice/send?access_token=" + accessTokenPublic;
  514. try {
  515. RestTemplate restTemplate = new RestTemplate();
  516. HttpHeaders headers = new HttpHeaders();
  517. headers.setContentType(MediaType.APPLICATION_JSON);
  518. HttpEntity<Map<String, String>> request = new HttpEntity<>(param, headers);
  519. ResponseEntity<String> responseEntity = restTemplate.postForEntity(url, request, String.class);
  520. } catch (Exception e) {
  521. throw new RRException(BizCodeEnume.TOKET_INVALID);
  522. }
  523. return CommonResult.ok();
  524. }
  525. /**
  526. * 缴费异常订单自动发送微校通知
  527. * itemName 缴费项目
  528. *
  529. * @return
  530. */
  531. @ResponseBody
  532. public CommonResult<T> sendException(String itemName, String orderNo) {
  533. QueryWrapper<PayItem> wrapper1 = new QueryWrapper<>();
  534. wrapper1.eq("item_name", itemName);
  535. PayItem payItem = payItemService.getOne(wrapper1);
  536. //查询微校通知数据 isSend 2 表示开启推送
  537. if (payItem.getItemExcept()) {
  538. QueryWrapper<PayOrderEntity> wrapper = new QueryWrapper<>();
  539. wrapper.eq("status", "1");
  540. wrapper.eq("except_type", "1");
  541. wrapper.eq("pay_item", itemName);
  542. wrapper.eq("order_no", orderNo);
  543. PayOrderEntity payOrder = payOrderService.getOne(wrapper);
  544. List<String> cardNumberList = new ArrayList<>();
  545. WeixiaoVO weixiaoVO = new WeixiaoVO();
  546. if (payOrder != null) {
  547. payOrder.setExceptType("2");
  548. String cardNumber = payOrder.getPayerIdentify();
  549. cardNumberList.add(cardNumber);
  550. weixiaoVO.setTitle(payOrder.getPayItem() + "缴纳异常通知");
  551. }
  552. weixiaoVO.setCardNumberList(cardNumberList);
  553. weixiaoVO.setContent("您的" + itemName + "订单缴费失败,请尽快查看缴费详情,并再次缴费。若为系统原因,请及时反馈!");
  554. weixiaoVO.setSender("南昌交通学院");
  555. JSONObject jsonObject = (JSONObject) JSONObject.toJSON(weixiaoVO);
  556. notice(jsonObject);
  557. //更新订单异常推送的状态
  558. payOrderService.updateById(payOrder);
  559. }
  560. return CommonResult.ok();
  561. }
  562. /**
  563. * 每天执行一次催缴 下午15点
  564. */
  565. @Scheduled(fixedDelay = 20000)
  566. // @Scheduled(cron = "0 0 15 * * ?")
  567. public void autoTiming() {
  568. List<PayItem> payItemList = payItemService.list();
  569. for (int i = 0; i < payItemList.size(); i++) {
  570. PayItem payItem = (PayItem) payItemList.get(i);
  571. String itemName = payItem.getItemName();
  572. Boolean itemAsk = payItem.getItemAsk();
  573. Integer itemAskDay = Integer.parseInt(payItem.getItemAskDay());
  574. //获取设置的请求次数
  575. Integer itemAskCount = Integer.parseInt(payItem.getItemAskCount());
  576. //获取本请求成功的次数
  577. Integer count = Integer.parseInt(payItem.getRequestCount());
  578. if (itemAsk) {
  579. if ((count < itemAskCount) && (askCount % itemAskDay == 0)) {
  580. askPay(itemName);
  581. count += 1;
  582. payItem.setRequestCount(String.valueOf(count));
  583. payItemService.updateById(payItem);
  584. }
  585. }
  586. }
  587. //催缴计数器累加
  588. askCount += 1;
  589. }
  590. /**
  591. * 是否催缴,发送微校通知
  592. *
  593. * @return
  594. */
  595. public CommonResult<T> askPay(String itemName) {
  596. QueryWrapper<PayItem> wrapper1 = new QueryWrapper<>();
  597. wrapper1.eq("item_name", itemName);
  598. PayItem payItem = payItemService.getOne(wrapper1);
  599. if (!itemName.equals("水费缴纳")) {
  600. WeixiaoVO weixiaoVO = new WeixiaoVO();
  601. List<String> cardNumberList = new ArrayList<>();
  602. //查询微校通知数据 isSend 2 表示开启推送
  603. QueryWrapper<PayableInfoEntity> wapper = new QueryWrapper<>();
  604. wapper.eq("pay_notice_type", "2")
  605. .eq("pay_item_type", "1")
  606. .eq("payment_item", itemName);
  607. List<PayableInfoEntity> list = payableInfoService.list(wapper);
  608. //催缴的人员编号
  609. if (list.size() > 0) {
  610. list.forEach(payableInfoEntity -> {
  611. String cardNumber = payableInfoEntity.getCardNumber();
  612. cardNumberList.add(cardNumber);
  613. weixiaoVO.setTitle(payableInfoEntity.getPaymentItem() + "缴纳通知");
  614. });
  615. }
  616. weixiaoVO.setCardNumberList(cardNumberList);
  617. weixiaoVO.setCardNumberList(cardNumberList);
  618. weixiaoVO.setSender("南昌交通学院");
  619. weixiaoVO.setContent("您有一笔" + itemName + "账单,请尽快缴纳");
  620. JSONObject jsonObject = (JSONObject) JSONObject.toJSON(weixiaoVO);
  621. return notice(jsonObject);
  622. } else {
  623. WeixiaoVO weixiaoVO = new WeixiaoVO();
  624. List<String> cardNumberList = new ArrayList<>();
  625. //查询微校通知数据 isSend 2 表示开启推送
  626. QueryWrapper<PayableInfoWaterEntity> wapper1 = new QueryWrapper<>();
  627. wapper1.eq("pay_notice_type", "2")
  628. .eq("pay_item_type", "1")
  629. .eq("payment_item", itemName);
  630. List<PayableInfoWaterEntity> list1 = payableInfoWaterService.list(wapper1);
  631. //催缴的人员编号
  632. if (list1.size() > 0) {
  633. list1.forEach(payableInfoEntity -> {
  634. String cardNumber = payableInfoEntity.getCardNumber();
  635. cardNumberList.add(cardNumber);
  636. weixiaoVO.setTitle(payableInfoEntity.getPaymentItem() + "缴纳通知");
  637. });
  638. weixiaoVO.setCardNumberList(cardNumberList);
  639. weixiaoVO.setCardNumberList(cardNumberList);
  640. weixiaoVO.setSender("南昌交通学院");
  641. weixiaoVO.setContent("您有一笔" + itemName + "账单,请尽快缴纳");
  642. JSONObject jsonObject = (JSONObject) JSONObject.toJSON(weixiaoVO);
  643. return notice(jsonObject);
  644. }
  645. }
  646. return CommonResult.ok();
  647. }
  648. /**
  649. * 处理反馈后开启反馈通知功能
  650. *
  651. * @param cardNumber 反馈通知对象的微校账号 card_number
  652. * @param content 处理内容
  653. * @return
  654. */
  655. @GetMapping("/disposeSend")
  656. @ResponseBody
  657. public CommonResult<T> disposeSend(@RequestParam("cardNumber") String cardNumber,
  658. @RequestParam("content") String content,
  659. @RequestParam("id") Long id) {
  660. List<String> cardNumberList = new ArrayList<>();
  661. cardNumberList.add(cardNumber);
  662. WeixiaoVO weixiaoVO = new WeixiaoVO();
  663. weixiaoVO.setTitle("缴费反馈处理通知");
  664. weixiaoVO.setCardNumberList(cardNumberList);
  665. weixiaoVO.setContent(content);
  666. weixiaoVO.setSender("南昌交通学院");
  667. JSONObject jsonObject = (JSONObject) JSONObject.toJSON(weixiaoVO);
  668. feedbackMsgController.handleFeedbackMsg(id, content);
  669. return notice(jsonObject);
  670. }
  671. }