WxPayController.java 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528
  1. package com.rf.psychological.wxpay.controller;
  2. import cn.hutool.core.date.DateUtil;
  3. import com.alibaba.fastjson.JSON;
  4. import com.alibaba.fastjson.JSONObject;
  5. import com.google.gson.Gson;
  6. import com.google.gson.internal.LinkedTreeMap;
  7. import com.rf.psychological.base.rest.BaseController;
  8. import com.rf.psychological.enums.UserRole;
  9. import com.rf.psychological.group.service.GroupInfoService;
  10. import com.rf.psychological.security.AesEncryptUtils;
  11. import com.rf.psychological.security.SafetyProcess;
  12. import com.rf.psychological.user.dao.model.OpenIdEntity;
  13. import com.rf.psychological.user.dao.model.UserEntity;
  14. import com.rf.psychological.user.service.OpenidService;
  15. import com.rf.psychological.user.service.UserService;
  16. import com.rf.psychological.utils.Constant;
  17. import com.rf.psychological.utils.IPUtiles;
  18. import com.rf.psychological.utils.JWTUtil;
  19. import com.rf.psychological.utils.Result;
  20. import com.rf.psychological.wxpay.config.WxPayConfig;
  21. import com.rf.psychological.wxpay.service.WxPayService;
  22. import com.rf.psychological.wxpay.utils.HttpUtils;
  23. import com.rf.psychological.wxpay.utils.WechatPay2ValidatorForRequest;
  24. import com.wechat.pay.contrib.apache.httpclient.auth.Verifier;
  25. import io.swagger.annotations.Api;
  26. import io.swagger.annotations.ApiOperation;
  27. import lombok.extern.slf4j.Slf4j;
  28. import org.apache.commons.lang.StringUtils;
  29. import org.apache.http.client.methods.CloseableHttpResponse;
  30. import org.apache.http.client.methods.HttpGet;
  31. import org.apache.http.client.methods.HttpPost;
  32. import org.apache.http.entity.StringEntity;
  33. import org.apache.http.impl.client.CloseableHttpClient;
  34. import org.apache.http.util.EntityUtils;
  35. import org.springframework.beans.factory.annotation.Autowired;
  36. import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
  37. import org.springframework.web.bind.annotation.*;
  38. import javax.annotation.Resource;
  39. import javax.servlet.http.HttpServletRequest;
  40. import javax.servlet.http.HttpServletResponse;
  41. import java.io.IOException;
  42. import java.util.HashMap;
  43. import java.util.Map;
  44. /**
  45. * @Description:微信支付接口
  46. * @Author: zsf
  47. * @Date: 2022/6/21
  48. */
  49. @CrossOrigin //跨域
  50. @RestController
  51. @RequestMapping("/api/wx-pay")
  52. @Api(tags = "网站微信支付APIv3")
  53. @Slf4j
  54. @ConditionalOnProperty(prefix="wx.pay",name = "is_lan", havingValue = "false")
  55. public class WxPayController extends BaseController {
  56. @Autowired
  57. private WxPayService wxPayService;
  58. @Autowired
  59. private WxPayConfig wxPayConfig;
  60. @Autowired
  61. private Verifier verifier;
  62. @Autowired
  63. private OpenidService openidService;
  64. @Resource
  65. private CloseableHttpClient wxPayClient;
  66. @Autowired
  67. private UserService userService;
  68. @Autowired
  69. private GroupInfoService groupInfoService;
  70. /**
  71. * 调用统一下单API,生成支付二维码
  72. * @return
  73. */
  74. @SafetyProcess
  75. @ApiOperation(value = "调用统一下单API,生成支付二维码",notes = "json字符串形式传参(加密)," +
  76. "data参数中包括(必传):productId:量表id,userId:用户id,resultId:测试结果id,description:订单描述信息," +
  77. "total:订单总金额,单位为分;")
  78. @PostMapping("/native")
  79. public Result<Map<String,Object>> nativePay(@RequestBody String paramJson){
  80. try {
  81. log.info(paramJson);
  82. String paramData = AesEncryptUtils.decrypt(JSONObject.parseObject(paramJson).getString("data"));
  83. log.info(paramData);
  84. if (StringUtils.isEmpty(paramData)){
  85. return fail(null,"参数不能为空");
  86. }
  87. Map<String,Object> map = wxPayService.nativePay(JSON.parseObject(paramData));
  88. return success(map);
  89. }catch (Exception e){
  90. e.printStackTrace();
  91. return fail("二维码生成失败");
  92. }
  93. }
  94. /**
  95. * h5下单API,生成支付二维码
  96. * @return
  97. */
  98. @SafetyProcess
  99. @ApiOperation(value = "h5下单API,生成支付二维码",notes = "json字符串形式传参(加密)," +
  100. "data参数中包括(必传):productId:量表id,userId:用户id,resultId:测试结果id,description:订单描述信息," +
  101. "payerClientIp:用户的客户端IP,支持IPv4和IPv6两种格式的IP地址,sceneType:场景类型ios、Android," +
  102. "total:订单总金额,单位为分")
  103. @PostMapping("/h5Pay")
  104. public Result h5Pay(@RequestBody String paramJson, HttpServletRequest request) throws Exception {
  105. try {
  106. String paramData = AesEncryptUtils.decrypt(JSONObject.parseObject(paramJson).getString("data"));
  107. log.info("paramData:"+paramData);
  108. if (StringUtils.isEmpty(paramData)){
  109. return fail(null,"参数不能为空");
  110. }
  111. //获取必要参数
  112. JSONObject paramObject = JSONObject.parseObject(paramData);
  113. //获取ip
  114. String payerClientIp = IPUtiles.getRealIp(request);
  115. paramObject.put("payerClientIp",payerClientIp);
  116. Map result = wxPayService.h5Pay(paramObject);
  117. return success(result);
  118. }catch (Exception e){
  119. e.printStackTrace();
  120. return fail("h5_url生成失败");
  121. }
  122. }
  123. @SafetyProcess
  124. @ApiOperation(value = "小程序预下单",notes = "参数同native下单")
  125. @PostMapping("/aspiPay")
  126. public Result aspiPay(@RequestBody String json){
  127. log.info("json请求参数:{}",json);
  128. try {
  129. String paramData = AesEncryptUtils.decrypt(JSONObject.parseObject(json).getString("data"));
  130. if (StringUtils.isEmpty(paramData)){
  131. return fail(null,"参数不能为空");
  132. }
  133. //获取必要参数
  134. JSONObject paramObject = JSONObject.parseObject(paramData);
  135. if(!paramObject.containsKey("openId")||StringUtils.isBlank(paramObject.getString("openId"))){
  136. UserEntity userEntity = userService.findUserById(paramObject.getString("userId"));
  137. // OpenIdEntity openIdEntity = this.openidService.findByUserId(paramObject.getString("userId"));
  138. if(userEntity == null){
  139. return fail("用户未登录");
  140. }
  141. paramObject.put("openId",userEntity.getPhone());
  142. }
  143. Map result = wxPayService.aspiPay(paramObject);
  144. return success(result);
  145. }catch (Exception e){
  146. e.printStackTrace();
  147. return fail("生成失败");
  148. }
  149. }
  150. @SafetyProcess
  151. @ApiOperation(value = "JSAPI支付",notes = "参数同native下单")
  152. @PostMapping("/jsapiPay")
  153. public Result jsapiPay(@RequestBody String json){
  154. log.info("json请求参数:{}",json);
  155. try {
  156. String paramData = AesEncryptUtils.decrypt(JSONObject.parseObject(json).getString("data"));
  157. if (StringUtils.isEmpty(paramData)){
  158. return fail(null,"参数不能为空");
  159. }
  160. //获取必要参数
  161. JSONObject paramObject = JSONObject.parseObject(paramData);
  162. Map result = wxPayService.jsapiPay(paramObject);
  163. return success(result);
  164. }catch (Exception e){
  165. e.printStackTrace();
  166. return fail("生成失败");
  167. }
  168. }
  169. /**
  170. * 支付通知 微信支付通过支付通知接口将用户支付成功消息通知给商户
  171. * @param request
  172. * @param response
  173. * @return
  174. */
  175. @ApiOperation("支付通知")
  176. @PostMapping("/native/notify")
  177. public String nativeNotify(HttpServletRequest request, HttpServletResponse response){
  178. log.info("支付通知====================================================");
  179. Gson gson = new Gson();
  180. Map<String,Object> map = new HashMap<>();
  181. //处理通知参数
  182. try {
  183. String body = HttpUtils.readData( request);
  184. Map<String,Object> bodyMap = gson.fromJson(body, HashMap.class);
  185. String requestId = (String)bodyMap.get("id");
  186. log.info("支付通知的id ===> {}", requestId);
  187. log.info("支付通知的完整数据 ===> {}", body);
  188. //签名的验证
  189. WechatPay2ValidatorForRequest wechatPay2ValidatorForRequest
  190. = new WechatPay2ValidatorForRequest(verifier, requestId, body);
  191. if(!wechatPay2ValidatorForRequest.validate(request)){
  192. log.error("通知验签失败");
  193. //失败应答
  194. response.setStatus(500);
  195. map.put("code", "ERROR");
  196. map.put("message", "通知验签失败");
  197. return gson.toJson(map);
  198. }
  199. log.info("通知验签成功");
  200. //处理订单
  201. wxPayService.processOrder(bodyMap);
  202. //成功应答
  203. response.setStatus(200);
  204. map.put("code", "SUCCESS");
  205. map.put("message", "成功");
  206. return gson.toJson(map);
  207. }catch (Exception e){
  208. e.printStackTrace();
  209. //失败应答
  210. response.setStatus(500);
  211. map.put("code", "ERROR");
  212. map.put("message", "失败");
  213. return gson.toJson(map);
  214. }
  215. }
  216. /**
  217. * 用户取消订单
  218. * @param orderNo
  219. * @return
  220. * @throws Exception
  221. */
  222. @ApiOperation("用户取消订单-PC")
  223. @GetMapping("/cancel/{orderNo}")
  224. public Result cancel(@PathVariable String orderNo) throws Exception {
  225. log.info("取消订单");
  226. wxPayService.cancelOrder(orderNo);
  227. return success(null,"订单已取消");
  228. }
  229. @SafetyProcess
  230. @ApiOperation("查询订单")
  231. @GetMapping("/queryOrder/{orderNo}")
  232. public Result queryOrder(@PathVariable String orderNo) throws Exception {
  233. log.info("查询订单订单");
  234. return success( wxPayService.queryOrder(orderNo));
  235. }
  236. @ApiOperation("交易账单--暂未开发")
  237. @GetMapping("/queryTradeBill/{billDate}/{type}")
  238. public Result queryTradeBill(@PathVariable String billDate, @PathVariable String type){
  239. return success();
  240. }
  241. @GetMapping("/refund/{orderNo}")
  242. public Result refund(@PathVariable String orderNo) throws IOException {
  243. wxPayService.refund(orderNo);
  244. return success();
  245. }
  246. // @PostMapping("/code2openid")
  247. // @ApiOperation(value = "code 换 opernid",notes = "modelPhone:手机号;code:临时code,获取openid;petName:用户名")
  248. // @SafetyProcess
  249. // public Result<JSONObject> code2id(@RequestBody String json) throws Exception {
  250. // JSONObject resultJson = new JSONObject();
  251. // JSONObject data = JSONObject.parseObject(AesEncryptUtils.decrypt(JSONObject.parseObject(json).getString("data")));
  252. // OpenIdEntity openIdEntity = this.openidService.findByPhone(data.getString("modelPhone"));
  253. // if(openIdEntity == null){
  254. // CloseableHttpResponse response = getToken(data.getString("code"));
  255. // int statusCode = response.getStatusLine().getStatusCode();//响应状态码
  256. // String body = EntityUtils.toString(response.getEntity());
  257. // Gson gson = new Gson();
  258. // HashMap resultBody = gson.fromJson(body, HashMap.class);
  259. // if(statusCode == 200 || statusCode == 204){
  260. // openIdEntity = new OpenIdEntity();
  261. // openIdEntity.setOpenId((String) resultBody.get("openid"));
  262. // openIdEntity.setAuthType("vx");
  263. // }else{
  264. // log.error("获取openid失败:错误码 "+resultBody.get("errcode")+" "+resultBody.get("errmsg"));
  265. // log.error("错误码:{}",resultBody.get("errcode"));
  266. // log.error("错误消息:{}",resultBody.get("errmsg"));
  267. // return fail();
  268. // }
  269. // }
  270. // //静默注册登录
  271. // UserEntity userEntity = this.userService.findPhoneAndInstitutionNoAndRoleType(data.getString("modelPhone"), Constant.WEB_INSTITUTION_CODE, UserRole.COMMON.getType());
  272. // if(userEntity != null){
  273. // openIdEntity.setUserId(userEntity.getId());
  274. // openIdEntity.setPhone(data.getString("modelPhone"));
  275. // openIdEntity = this.openidService.save(openIdEntity);
  276. //
  277. // if(StringUtils.isNotBlank(data.getString("petName"))&&(!userEntity.getPetName().equals(data.getString("petName")))){
  278. // userEntity.setPetName(data.getString("petName"));
  279. // this.userService.save(userEntity);
  280. // }
  281. // userEntity.setPassword("-");
  282. // resultJson.put("user", userEntity);
  283. // resultJson.put("type", userEntity.getRoleType());
  284. // resultJson.put("improve",false);
  285. // }else{
  286. // //注册
  287. // userEntity = new UserEntity();
  288. // userEntity.setPassword("-");
  289. // userEntity.setModelPhone(data.getString("modelPhone"));
  290. // userEntity.setGId(this.groupInfoService.findGroupByInstitutionNoAndName(Constant.WEB_INSTITUTION_CODE,Constant.DEFAULT_GROUP_NAME).getId());
  291. // userEntity.setInstitutionName(Constant.WEB_INSTITUTION_NAME);
  292. // userEntity.setInstitutionNo(Constant.WEB_INSTITUTION_CODE);
  293. // userEntity.setUserStatus(Constant.USER_STATUS_NORMAL);
  294. // userEntity.setBirthday("-");
  295. // userEntity.setGender("-");
  296. // userEntity.setPetName(data.getString("petName"));
  297. // userEntity.setProfession("-");
  298. // userEntity.setAdditionInfo("微信小程序注册用户");
  299. // userEntity.setPhone(data.getString("modelPhone"));
  300. // userEntity.setRoleType(UserRole.COMMON.getType());
  301. // userEntity = this.userService.save(userEntity);
  302. // resultJson.put("improve",true);
  303. // //保存三方授权信息 openid
  304. // openIdEntity.setUserId(userEntity.getId());
  305. // openIdEntity.setPhone(data.getString("modelPhone"));
  306. // openIdEntity = this.openidService.save(openIdEntity);
  307. // //登录
  308. //// TODO 将登录用户放入redis已登录用户信息,统计在线人数
  309. // }
  310. //
  311. // resultJson.put("token", JWTUtil.getTokenByUserInfo(userEntity));
  312. // resultJson.put("user",userEntity);
  313. // resultJson.put("type",userEntity.getRoleType());
  314. // resultJson.put("openId",openIdEntity);
  315. // log.info("响应消息:"+resultJson.toJSONString());
  316. // return success(resultJson);
  317. // }
  318. @PostMapping("/code2openid2")
  319. @ApiOperation(value = "code 换 opernid",notes = "code:临时code,获取openid;petName:用户名")
  320. @SafetyProcess
  321. public Result<JSONObject> code2openid2(@RequestBody String json) throws Exception {
  322. JSONObject resultJson = new JSONObject();
  323. JSONObject data = JSONObject.parseObject(AesEncryptUtils.decrypt(JSONObject.parseObject(json).getString("data")));
  324. String openId;
  325. CloseableHttpResponse response = getToken(data.getString("code"));
  326. int statusCode = response.getStatusLine().getStatusCode();//响应状态码
  327. String body = EntityUtils.toString(response.getEntity());
  328. Gson gson = new Gson();
  329. HashMap resultBody = gson.fromJson(body, HashMap.class);
  330. if(statusCode == 200 || statusCode == 204){
  331. openId = (String) resultBody.get("openid");
  332. }else{
  333. log.error("获取openid失败:错误码 "+resultBody.get("errcode")+" "+resultBody.get("errmsg"));
  334. log.error("错误码:{}",resultBody.get("errcode"));
  335. log.error("错误消息:{}",resultBody.get("errmsg"));
  336. return fail();
  337. }
  338. //静默注册登录
  339. UserEntity userEntity = this.userService.findPhoneAndInstitutionNoAndRoleType(openId, Constant.WEB_INSTITUTION_CODE, UserRole.COMMON.getType());
  340. if(userEntity != null){
  341. // if(StringUtils.isNotBlank(data.getString("petName"))&&(!userEntity.getPetName().equals(data.getString("petName")))){
  342. // userEntity.setPetName(data.getString("petName"));
  343. // this.userService.save(userEntity);
  344. // }
  345. userEntity.setPassword("-");
  346. resultJson.put("user", userEntity);
  347. resultJson.put("type", userEntity.getRoleType());
  348. resultJson.put("improve",false);
  349. }else{
  350. //注册
  351. userEntity = new UserEntity();
  352. userEntity.setPassword("-");
  353. userEntity.setGId(this.groupInfoService.findGroupByInstitutionNoAndName(Constant.WEB_INSTITUTION_CODE,Constant.DEFAULT_GROUP_NAME).getId());
  354. userEntity.setInstitutionName(Constant.WEB_INSTITUTION_NAME);
  355. userEntity.setInstitutionNo(Constant.WEB_INSTITUTION_CODE);
  356. userEntity.setUserStatus(Constant.USER_STATUS_NORMAL);
  357. userEntity.setBirthday("-");
  358. userEntity.setGender("-");
  359. userEntity.setPetName("微信用户");
  360. userEntity.setProfession(DateUtil.now());
  361. userEntity.setAdditionInfo("微信小程序注册用户");
  362. userEntity.setPhone(openId);
  363. userEntity.setRoleType(UserRole.COMMON.getType());
  364. userEntity = this.userService.save(userEntity);
  365. resultJson.put("improve",true);
  366. }
  367. resultJson.put("token", JWTUtil.getTokenByUserInfo(userEntity));
  368. resultJson.put("user",userEntity);
  369. resultJson.put("type",userEntity.getRoleType());
  370. resultJson.put("openId",openId);
  371. log.info("响应消息:"+resultJson.toJSONString());
  372. return success(resultJson);
  373. }
  374. @GetMapping("/getPhone/{code}")
  375. @SafetyProcess
  376. @ApiOperation(value = "获取用户手机号",notes = "code :临时code")
  377. public Result getPhone(@PathVariable String code) throws IOException {
  378. // 1、获取access_token
  379. String access_token = wxPayService.getAccessToken();
  380. // 2、获取用户手机号
  381. HashMap map = getPhoneNumber(code,access_token);
  382. int errcode = ((Number) map.get("errcode")).intValue();
  383. if(errcode == 0){
  384. //{"errcode":0,"errmsg":"ok","phone_info":{"phoneNumber":"19138984495","purePhoneNumber":"19138984495","countryCode":"86","watermark":{"timestamp":1661308946,"appid":"wx2f422a2a1cb24c3c"}}}
  385. LinkedTreeMap map2 = (LinkedTreeMap) map.get("phone_info");
  386. String phoneNumber = String.valueOf(map2.get("phoneNumber"));
  387. if(StringUtils.isBlank(phoneNumber)){
  388. phoneNumber = String.valueOf(map2.get("purePhoneNumber"));
  389. }
  390. JSONObject resultJson = new JSONObject();
  391. resultJson.put("phone",phoneNumber);
  392. UserEntity userEntity = this.userService.findPhoneAndInstitutionNoAndRoleType(phoneNumber,Constant.WEB_INSTITUTION_CODE,Constant.DEFAULT_VALUE_ONE);
  393. if(userEntity != null){
  394. resultJson.put("newer","0");
  395. }else {
  396. resultJson.put("newer","1");
  397. }
  398. return success(resultJson);
  399. }else if (errcode == -1){
  400. return fail("系统繁忙");
  401. }else if (errcode == 40029){
  402. log.info("code 不合法");
  403. return fail("获取手机号失败");
  404. }else {
  405. log.info("获取手机号失败错误码:{},错误消息{}",errcode,map.get("errmsg"));
  406. return fail("获取手机号失败");
  407. }
  408. }
  409. /**
  410. * 获取
  411. * @param code
  412. * @param access_token
  413. * @return
  414. */
  415. private HashMap getPhoneNumber(String code, String access_token) throws IOException {
  416. String url = "https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token="+access_token;
  417. HttpPost httpPost = new HttpPost(url);
  418. httpPost.setHeader("Accept", "application/json");
  419. Map<String,Object> paramsMap = new HashMap<>();
  420. paramsMap.put("code",code);
  421. Gson gson = new Gson();
  422. String jsonParams = gson.toJson(paramsMap);
  423. StringEntity entity = new StringEntity(jsonParams,"utf-8");
  424. entity.setContentType("application/json");
  425. httpPost.setEntity(entity);
  426. httpPost.setHeader("Accept","application/json");
  427. CloseableHttpResponse response = wxPayClient.execute(httpPost);
  428. String body = EntityUtils.toString(response.getEntity());//获取响应体
  429. log.info("获取手机号:响应体{}",body);
  430. //响应结果
  431. return gson.fromJson(body,HashMap.class);
  432. }
  433. /**
  434. * 获取access_token
  435. * @return
  436. * @throws IOException
  437. */
  438. // public String getAccessToken() throws IOException {
  439. // String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+wxPayConfig.getAspi_appid()+"&secret="+wxPayConfig.getAspi_secret() ;
  440. // HttpGet httpGet = new HttpGet(url);
  441. // CloseableHttpResponse response = wxPayClient.execute(httpGet);
  442. // String body = EntityUtils.toString(response.getEntity());
  443. // Gson gson = new Gson();
  444. // HashMap resultBody = gson.fromJson(body, HashMap.class);
  445. // if(resultBody.containsKey("errcode")){
  446. // log.error("获取token异常:");
  447. // log.error("errcode:"+resultBody.get("errcode"));
  448. // log.error("errmsg:"+resultBody.get("errmsg"));
  449. // }else{
  450. // return (String) resultBody.get("access_token");
  451. // }
  452. // return null;
  453. // }
  454. public CloseableHttpResponse getToken(String code) throws IOException {
  455. String url = wxPayConfig.getAspi_url() +
  456. "?appid=" + wxPayConfig.getAspi_appid() +
  457. "&secret=" + wxPayConfig.getAspi_secret() +
  458. "&js_code=" + code +
  459. "&grant_type=authorization_code";
  460. log.info("code2openid URL :"+url);
  461. HttpGet httpGet = new HttpGet(url);
  462. httpGet.setHeader("Accept", "application/json");
  463. return wxPayClient.execute(httpGet);
  464. }
  465. @GetMapping("/generateShortLink")
  466. @ApiOperation(value = "获取到分享链接",notes = "path:跳转路径和参数")
  467. public Result generateShortLink(@RequestParam String path,@RequestParam String query){
  468. try {
  469. if (StringUtils.isEmpty(path)){
  470. return fail(null,"参数不能为空");
  471. }
  472. String link = wxPayService.generateLink(path,query);
  473. return success(link);
  474. }catch (Exception e){
  475. e.printStackTrace();
  476. return fail("操作失败");
  477. }
  478. }
  479. @GetMapping("/generateWxCode")
  480. @SafetyProcess
  481. @ApiOperation(value = "获取到小程序",notes = "page:跳转路径scene参数envVersion环境")
  482. public Result generateWxCode(@RequestParam String page,@RequestParam String scene,@RequestParam(required = false) String envVersion){
  483. try {
  484. if (StringUtils.isEmpty(page)){
  485. return fail(null,"参数不能为空");
  486. }
  487. String link = wxPayService.generateWxCode(page,scene,envVersion);
  488. return success(link);
  489. }catch (Exception e){
  490. e.printStackTrace();
  491. return fail("操作失败");
  492. }
  493. }
  494. }