CashController.java 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666
  1. package com.sqx.modules.pay.controller;
  2. import cn.hutool.core.bean.BeanUtil;
  3. import com.alibaba.fastjson.JSON;
  4. import com.alibaba.fastjson.JSONArray;
  5. import com.alibaba.fastjson.JSONObject;
  6. import com.alipay.api.AlipayApiException;
  7. import com.alipay.api.AlipayClient;
  8. import com.alipay.api.CertAlipayRequest;
  9. import com.alipay.api.DefaultAlipayClient;
  10. import com.alipay.api.request.AlipayFundTransToaccountTransferRequest;
  11. import com.alipay.api.request.AlipayFundTransUniTransferRequest;
  12. import com.alipay.api.response.AlipayFundTransToaccountTransferResponse;
  13. import com.alipay.api.response.AlipayFundTransUniTransferResponse;
  14. import com.google.common.base.Charsets;
  15. import com.sqx.common.utils.PageUtils;
  16. import com.sqx.common.utils.Result;
  17. import com.sqx.modules.app.dao.UserCashOutDao;
  18. import com.sqx.modules.app.entity.UserEntity;
  19. import com.sqx.modules.app.entity.UserMoneyDetails;
  20. import com.sqx.modules.app.service.UserMoneyDetailsService;
  21. import com.sqx.modules.app.service.UserMoneyService;
  22. import com.sqx.modules.app.service.UserService;
  23. import com.sqx.modules.common.entity.CommonInfo;
  24. import com.sqx.modules.common.service.CommonInfoService;
  25. import com.sqx.modules.invite.dao.InviteMoneyDao;
  26. import com.sqx.modules.message.entity.MessageInfo;
  27. import com.sqx.modules.message.service.MessageService;
  28. import com.sqx.modules.pay.config.AliPayConstants;
  29. import com.sqx.modules.pay.entity.AliPayWithdrawModel;
  30. import com.sqx.modules.pay.entity.CashOut;
  31. import com.sqx.modules.pay.entity.PayDetails;
  32. import com.sqx.modules.pay.service.CashOutService;
  33. import com.sqx.modules.pay.service.PayDetailsService;
  34. import com.sqx.modules.sys.entity.SysUserEntity;
  35. import com.sqx.modules.sys.entity.SysUserRoleEntity;
  36. import com.sqx.modules.sys.service.SysUserService;
  37. import com.sqx.modules.utils.*;
  38. import com.sqx.modules.utils.EasyPoi.ExcelUtils;
  39. import com.wechat.pay.java.service.transferbatch.TransferBatchService;
  40. import io.swagger.annotations.Api;
  41. import io.swagger.annotations.ApiOperation;
  42. import io.swagger.annotations.ApiParam;
  43. import lombok.extern.slf4j.Slf4j;
  44. import lombok.val;
  45. import org.apache.commons.lang.StringUtils;
  46. import org.apache.commons.lang.exception.ExceptionUtils;
  47. import org.apache.shiro.SecurityUtils;
  48. import org.springframework.beans.factory.annotation.Autowired;
  49. import org.springframework.web.bind.annotation.*;
  50. import com.wechat.pay.java.core.Config;
  51. import com.wechat.pay.java.core.RSAAutoCertificateConfig;
  52. import com.wechat.pay.java.service.transferbatch.TransferBatchService;
  53. import com.wechat.pay.java.service.transferbatch.model.InitiateBatchTransferRequest;
  54. import com.wechat.pay.java.service.transferbatch.model.InitiateBatchTransferResponse;
  55. import com.wechat.pay.java.service.transferbatch.model.TransferDetailInput;
  56. import javax.servlet.http.HttpServletResponse;
  57. import java.io.IOException;
  58. import java.math.BigDecimal;
  59. import java.text.SimpleDateFormat;
  60. import java.util.*;
  61. import java.util.concurrent.locks.ReentrantReadWriteLock;
  62. /**
  63. * @author fang
  64. * @date 2020/5/15
  65. */
  66. @Slf4j
  67. @RestController
  68. @Api(value = "管理平台", tags = {"管理平台"})
  69. @RequestMapping(value = "/cash")
  70. public class CashController {
  71. /** 充值记录 */
  72. @Autowired
  73. private PayDetailsService payDetailsService;
  74. /** 提现记录 */
  75. @Autowired
  76. private CashOutService cashOutService;
  77. /** app用户 */
  78. @Autowired
  79. private UserService userService;
  80. /** 通用配置 */
  81. @Autowired
  82. private CommonInfoService commonInfoService;
  83. @Autowired
  84. private UserMoneyDetailsService userMoneyDetailsService;
  85. @Autowired
  86. private MessageService messageService;
  87. @Autowired
  88. private UserCashOutDao userCashOutDao;
  89. @Autowired
  90. private SysUserService sysUserService;
  91. public static TransferBatchService service;
  92. private ReentrantReadWriteLock reentrantReadWriteLock = new ReentrantReadWriteLock(true);
  93. @RequestMapping(value = "/sendMsgByUserId", method = RequestMethod.GET)
  94. @ApiOperation("管理平台主动推送消息(指定用户)")
  95. @ResponseBody
  96. public Result sendMsgByUserId(String title, String content, Long userId) {
  97. UserEntity user = userService.queryByUserId(userId);
  98. send(user, title, content);
  99. return Result.success();
  100. }
  101. @PostMapping(value = "/agentCashMoney")
  102. @ApiOperation("发起提现")
  103. public Result agentCashMoney(Long userId,Double money, Integer classify) {
  104. return cashOutService.cashMoney(userId, money, classify, 1);
  105. }
  106. @RequestMapping(value = "/sendMsg", method = RequestMethod.GET)
  107. @ApiOperation("管理平台主动推送消息")
  108. @ResponseBody
  109. public Result sendMsg(String title, String content, String phone, Integer flag) {
  110. if (flag == 1) {
  111. //根据手机号推送
  112. UserEntity userByPhone = userService.queryByPhone(phone);
  113. if (null == userByPhone) {
  114. return Result.error(-100, "手机号不存在!");
  115. }
  116. send(userByPhone, title, content);
  117. } else {
  118. //所有人推送
  119. List<UserEntity> userInfos = userService.list();
  120. //用户数量较大 使用多线程推送 根据用户数量进行拆分 同时按照3个线程进行推送
  121. int count = userInfos.size() / 3;
  122. new Thread(() -> {
  123. for (int i = 0; i < count; i++) {
  124. send(userInfos.get(i), title, content);
  125. }
  126. }).start();
  127. new Thread(() -> {
  128. for (int i = count; i < count * 2; i++) {
  129. send(userInfos.get(i), title, content);
  130. }
  131. }).start();
  132. new Thread(() -> {
  133. for (int i = count * 2; i < userInfos.size(); i++) {
  134. send(userInfos.get(i), title, content);
  135. }
  136. }).start();
  137. /* for(UserInfo userByPhone:userInfos){
  138. }*/
  139. }
  140. return Result.success();
  141. }
  142. private void send(UserEntity userByPhone, String title, String content) {
  143. if (userByPhone.getClientid() != null) {
  144. userService.pushToSingle(title, content, userByPhone.getClientid());
  145. }
  146. SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  147. MessageInfo messageInfo = new MessageInfo();
  148. messageInfo.setContent(content);
  149. messageInfo.setTitle(title);
  150. messageInfo.setState(String.valueOf(5));
  151. messageInfo.setUserName(userByPhone.getNickName());
  152. messageInfo.setUserId(String.valueOf(userByPhone.getUserId()));
  153. messageInfo.setCreateAt(simpleDateFormat.format(new Date()));
  154. messageInfo.setIsSee("0");
  155. messageService.saveBody(messageInfo);
  156. }
  157. @RequestMapping(value = "/selectCashOut", method = RequestMethod.GET)
  158. @ApiOperation("获取最新的提现信息")
  159. @ResponseBody
  160. public Result selectCashOut() {
  161. return Result.success().put("data", cashOutService.selectCashOutLimit3());
  162. }
  163. @RequestMapping(value = "/selectSumPay", method = RequestMethod.GET)
  164. @ApiOperation("查询用户充值金额")
  165. @ResponseBody
  166. public Result selectSumPay(String createTime, String endTime, Long userId) {
  167. return Result.success().put("data", payDetailsService.selectSumPay(createTime, endTime, userId));
  168. }
  169. @RequestMapping(value = "/selectUserRecharge", method = RequestMethod.GET)
  170. @ApiOperation("查询所有用户充值信息列表")
  171. @ResponseBody
  172. public Result selectUserRecharge(int page, int limit, String startTime, String endTime, Integer state) {
  173. return Result.success().put("data", payDetailsService.selectPayDetails(page, limit, startTime, endTime, null, state));
  174. }
  175. @ApiOperation("查看充值明细")
  176. @GetMapping(value = "/findTopUpMoney")
  177. public Result findTopUpMoney(Integer page, Integer limit, PayDetails payDetails, String startTime, String endTime) {
  178. return payDetailsService.findTopUpMoney( page, limit,payDetails, startTime, endTime);
  179. }
  180. @RequestMapping(value = "/selectUserRechargeByUserId", method = RequestMethod.GET)
  181. @ApiOperation("查询某个用户充值信息列表")
  182. @ResponseBody
  183. public Result selectUserRechargeByUserId(int page, int limit, String startTime, String endTime, Long userId, Integer state) {
  184. return Result.success().put("data", payDetailsService.selectPayDetails(page, limit, startTime, endTime, userId, state));
  185. }
  186. @RequestMapping(value = "/selectUserRechargeByUserIdApp", method = RequestMethod.GET)
  187. @ApiOperation("查询某个用户充值信息列表")
  188. @ResponseBody
  189. public Result selectUserRechargeByUserIdApp(int page, int limit, String startTime, String endTime, Long userId) {
  190. return Result.success().put("data", payDetailsService.selectPayDetails(page, limit, startTime, endTime, userId, 1));
  191. }
  192. @RequestMapping(value = "/selectPayDetails", method = RequestMethod.GET)
  193. @ApiOperation("查询提现记录列表")
  194. @ResponseBody
  195. public Result selectHelpProfit(@ApiParam("页码") int page,
  196. @ApiParam("大小") int limit,
  197. @ApiParam("支付宝名称") String zhifubaoName,
  198. @ApiParam("支付宝账号") String zhifubao,
  199. @ApiParam("用户id") String userId,
  200. @ApiParam("提现状态") Integer state,
  201. @ApiParam("用户手机号") String phone,
  202. @ApiParam("用户类型 1管理端 2用户端") Integer userType,
  203. @ApiParam("分类 1用户提现 2退保障金") String type) {
  204. Map<String, Object> map = new HashMap<>();
  205. map.put("page", page);
  206. map.put("limit", limit);
  207. map.put("zhifubaoName", zhifubaoName);
  208. map.put("zhifubao", zhifubao);
  209. map.put("userId", userId);
  210. map.put("type", type);
  211. map.put("state", state);
  212. map.put("phone", phone);
  213. map.put("userType", userType);
  214. PageUtils pageUtils = cashOutService.selectCashOutList(map);
  215. return Result.success().put("data", pageUtils);
  216. }
  217. /*@ApiOperation("财务提现统计")
  218. @GetMapping("/statisticsCashMoney")
  219. public Result statisticsMoney(String time, Integer flag){
  220. Double sumMoney = cashOutService.sumMoney(time, flag);
  221. Integer countMoney = cashOutService.countMoney(time, flag);
  222. Integer stayMoney = cashOutService.stayMoney(time, flag);
  223. Map<String,Object> map=new HashMap<>();
  224. map.put("sumMoney",sumMoney==null?0.00:sumMoney);
  225. map.put("countMoney",countMoney==null?0:countMoney);
  226. map.put("stayMoney",stayMoney==null?0:stayMoney);
  227. return Result.success().put("data",map);
  228. }*/
  229. @ApiOperation("新财务提现统计")
  230. @GetMapping(value = "statisticsMoney")
  231. public Result statisticsMoney(String date, String dateType) {
  232. return cashOutService.statisticsMoney(date, dateType);
  233. }
  234. @ApiOperation("充值统计")
  235. @GetMapping("/payMember")
  236. public Result payMember(String time, Integer flag, Integer payClassify) {
  237. Double sumMoney = payDetailsService.selectSumPayByClassify(time, flag, null, payClassify);
  238. BigDecimal wxMoney = payDetailsService.getRechargeMoney(1, time, flag);
  239. BigDecimal zfbMoney = payDetailsService.getRechargeMoney(2, time, flag);
  240. Map<String, Object> map = new HashMap<>();
  241. map.put("sumMoney", sumMoney == null ? 0.00 : sumMoney);
  242. map.put("wxMoney", wxMoney);
  243. map.put("zfbMoney", zfbMoney);
  244. return Result.success().put("data", map);
  245. }
  246. /*
  247. @ApiOperation("收入统计")
  248. @GetMapping("/statisticsIncomeMoney")
  249. public Result statisticsIncomeMoney(String time, Integer flag){
  250. Double sumMoney = ordersService.statisticsIncomeMoney(time, flag, null);
  251. Double courseMoney = ordersService.statisticsIncomeMoney(time, flag, 1);
  252. Double vipMoney = ordersService.statisticsIncomeMoney(time, flag, 2);
  253. Map<String,Object> map=new HashMap<>();
  254. map.put("sumMoney",sumMoney==null?0.00:sumMoney);
  255. map.put("courseMoney",courseMoney==null?0.00:courseMoney);
  256. map.put("vipMoney",vipMoney==null?0.00:vipMoney);
  257. return Result.success().put("data",map);
  258. }
  259. */
  260. @RequestMapping(value = "/alipay", method = RequestMethod.POST)
  261. @ApiOperation("管理平台确认提现")
  262. @ResponseBody
  263. public Result alipayPay(Long cashId) {
  264. CashOut one = cashOutService.selectById(cashId);
  265. if (one == null) {
  266. return Result.error("提现记录不存在!");
  267. }
  268. if (one.getState() != 0) {
  269. return Result.error(9999, one.getZhifubaoName() + "转账失败!原因是用户已转账");
  270. }
  271. if (one.getClassify() == null || one.getClassify() == 1) {
  272. //支付宝
  273. return aliPay(one);
  274. } else {
  275. //微信
  276. return wxPay(one);
  277. }
  278. }
  279. private Result wxPay(CashOut one) {
  280. reentrantReadWriteLock.writeLock().lock();
  281. try {
  282. SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  283. UserEntity userEntity = userService.getById(one.getUserId());
  284. if (StringUtils.isEmpty(one.getOrderNumber())) {
  285. one.setOrderNumber(String.valueOf(System.currentTimeMillis()));
  286. }
  287. String value = commonInfoService.findOne(280).getValue();
  288. if ("1".equals(value)) {
  289. //转账金额 微信为分
  290. double v = Double.parseDouble(one.getMoney());
  291. Double mul = AmountCalUtils.mul(v, 100);
  292. Integer amount = mul.intValue();
  293. /** 商户号 */
  294. String merchantId = commonInfoService.findOne(251).getValue();
  295. /** 商户API私钥路径 */
  296. String privateKeyPath = commonInfoService.findOne(629).getValue();
  297. /** 商户证书序列号 */
  298. String merchantSerialNumber = commonInfoService.findOne(630).getValue();
  299. /** 商户APIV3密钥 */
  300. String apiV3Key = commonInfoService.findOne(631).getValue();
  301. Config config = new RSAAutoCertificateConfig.Builder()
  302. .merchantId(merchantId)
  303. .privateKeyFromPath(privateKeyPath)
  304. .merchantSerialNumber(merchantSerialNumber)
  305. .apiV3Key(apiV3Key)
  306. .build();
  307. service = new TransferBatchService.Builder().config(config).build();
  308. InitiateBatchTransferRequest initiateBatchTransferRequest =
  309. new InitiateBatchTransferRequest();
  310. //小程序或公众号appid
  311. if (one.getClassify() == 2) {
  312. CommonInfo mchAppId = commonInfoService.findOne(248);
  313. initiateBatchTransferRequest.setAppid(mchAppId.getValue());
  314. } else if (one.getClassify() == 3) {
  315. CommonInfo mchAppId = commonInfoService.findOne(262);
  316. initiateBatchTransferRequest.setAppid(mchAppId.getValue());
  317. }
  318. CommonInfo one1 = commonInfoService.findOne(12);
  319. //【商家批次单号】 商户系统内部的商家批次单号,要求此参数只能由数字、大小写字母组成,在商户系统内部唯一
  320. initiateBatchTransferRequest.setOutBatchNo(one.getOrderNumber());
  321. //【批次名称】 该笔批量转账的名称
  322. initiateBatchTransferRequest.setBatchName(one1.getValue() + "提现金额到账");
  323. //【批次备注】 转账说明,UTF8编码,最多允许32个字符
  324. initiateBatchTransferRequest.setBatchRemark(one1.getValue() + "提现金额到账");
  325. //【转账总金额】 转账金额单位为“分”。转账总金额必须与批次内所有明细转账金额之和保持一致,否则无法发起转账操作
  326. initiateBatchTransferRequest.setTotalAmount(amount.longValue());
  327. //【转账总笔数】 一个转账批次单最多发起一千笔转账。转账总笔数必须与批次内所有明细之和保持一致,否则无法发起转账操作
  328. initiateBatchTransferRequest.setTotalNum(1);
  329. {
  330. //【转账明细列表】 发起批量转账的明细列表,最多一千笔
  331. List<TransferDetailInput> transferDetailListList = new ArrayList<>();
  332. {
  333. TransferDetailInput transferDetailInput = new TransferDetailInput();
  334. //【商家明细单号】 商户系统内部区分转账批次单下不同转账明细单的唯一标识,要求此参数只能由数字、大小写字母组成
  335. transferDetailInput.setOutDetailNo(one.getOrderNumber());
  336. //【转账金额】 转账金额单位为“分”
  337. transferDetailInput.setTransferAmount(amount.longValue());
  338. //【转账备注】 单条转账备注(微信用户会收到该备注),UTF8编码,最多允许32个字符
  339. transferDetailInput.setTransferRemark(one1.getValue() + "提现金额到账");
  340. //【收款用户openid】 商户appid下,某用户的openid
  341. if (one.getClassify() == 2) {
  342. transferDetailInput.setOpenid(userEntity.getRiderOpenId());
  343. } else if (one.getClassify() == 3) {
  344. transferDetailInput.setOpenid(userEntity.getRiderAccountOpenId());
  345. }
  346. //【收款用户姓名】 收款方真实姓名。支持标准RSA算法和国密算法,公钥由微信侧提供
  347. //明细转账金额<0.3元时,不允许填写收款用户姓名
  348. //明细转账金额 >= 2,000元时,该笔明细必须填写收款用户姓名
  349. //同一批次转账明细中的姓名字段传入规则需保持一致,也即全部填写、或全部不填写
  350. //若商户传入收款用户姓名,微信支付会校验用户openID与姓名是否一致,并提供电子回单
  351. //transferDetailInput.setUserName("757b340b45ebef5467rter35gf464344v3542sdf4t6re4tb4f54ty45t4yyry45");
  352. transferDetailListList.add(transferDetailInput);
  353. }
  354. initiateBatchTransferRequest.setTransferDetailList(
  355. transferDetailListList);
  356. }
  357. //【转账场景ID】 该批次转账使用的转账场景,如不填写则使用商家的默认场景,如无默认场景可为空,可前往“商家转账到零钱-前往功能”中申请。
  358. //如:1001-现金营销
  359. //initiateBatchTransferRequest.setTransferSceneId("1000");
  360. //【通知地址】 异步接收微信支付结果通知的回调地址,通知url必须为公网可访问的url,必须为https,不能携带参数。
  361. //initiateBatchTransferRequest.setNotifyUrl("https://www.weixin.qq.com/wxpay/pay.php");
  362. try {
  363. InitiateBatchTransferResponse response = service.initiateBatchTransfer(initiateBatchTransferRequest);
  364. one.setState(1);
  365. one.setOutAt(sdf.format(new Date()));
  366. cashOutService.update(one);
  367. UserEntity userInfo = userService.getById(one.getUserId());
  368. MessageInfo messageInfo = new MessageInfo();
  369. messageInfo.setContent(one.getMoney() + "提现已到账");
  370. messageInfo.setTitle("提现到账");
  371. messageInfo.setState(String.valueOf(5));
  372. messageInfo.setUserName(userInfo.getNickName());
  373. messageInfo.setUserId(String.valueOf(userInfo.getUserId()));
  374. messageInfo.setCreateAt(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
  375. messageService.saveBody(messageInfo);
  376. return Result.success(one.getZhifubaoName() + "转账成功");
  377. }catch (Exception e){
  378. e.printStackTrace();
  379. String message = e.getMessage();
  380. int i = message.indexOf("\"message\":\"");
  381. int i1 = message.indexOf("\"}]");
  382. String substring = message.substring(i + 11, i1);
  383. return Result.error("转账失败!原因:" + substring);
  384. }
  385. } else {
  386. Date now = new Date();
  387. one.setState(1);
  388. one.setOutAt(sdf.format(now));
  389. cashOutService.update(one);
  390. UserEntity userInfo = userService.queryByUserId(one.getUserId());
  391. cashOutService.cashOutSuccess(userInfo, one.getOutAt(), one.getMoney(), one.getZhifubao(), commonInfoService.findOne(19).getValue());
  392. return Result.success(one.getZhifubaoName() + "转账成功");
  393. }
  394. } catch (Exception e) {
  395. e.printStackTrace();
  396. log.error("转账出错了!!!" + e.getMessage(), e);
  397. } finally {
  398. reentrantReadWriteLock.writeLock().unlock();
  399. }
  400. return Result.error("转账失败!");
  401. }
  402. private Result aliPay(CashOut one) {
  403. reentrantReadWriteLock.writeLock().lock();
  404. try {
  405. log.error("进来了!!!");
  406. if (one == null) {
  407. return Result.error("提现记录不存在!");
  408. }
  409. if (one.getState() != 0) {
  410. return Result.error(9999, one.getZhifubaoName() + "转账失败!原因是用户已转账");
  411. }
  412. if (StringUtils.isEmpty(one.getOrderNumber())) {
  413. one.setOrderNumber(String.valueOf(System.currentTimeMillis()));
  414. }
  415. CommonInfo commonInfo = commonInfoService.findOne(98);
  416. CommonInfo name = commonInfoService.findOne(12);
  417. if (commonInfo.getValue() != null && commonInfo.getValue().equals("1")) {
  418. AlipayClient alipayClient = new DefaultAlipayClient(AliPayConstants.REQUEST_URL,
  419. commonInfoService.findOne(63).getValue(), commonInfoService.findOne(65).getValue(), AliPayConstants.FORMAT,
  420. AliPayConstants.CHARSET, commonInfoService.findOne(64).getValue(), AliPayConstants.SIGNTYPE);
  421. val aliPayWithdrawModel = AliPayWithdrawModel.builder()
  422. .out_biz_no(one.getOrderNumber())
  423. .amount(new BigDecimal(one.getMoney()))
  424. .payee_account(one.getZhifubao())
  425. .payee_real_name(one.getZhifubaoName())
  426. .payee_type(AliPayConstants.PAY_TYPE)
  427. .remark(name.getValue())
  428. .build();
  429. String json = JSON.toJSONString(aliPayWithdrawModel);
  430. //实例化连接对象
  431. AlipayFundTransToaccountTransferRequest withdrawRequest = new AlipayFundTransToaccountTransferRequest();
  432. withdrawRequest.setBizContent(json);
  433. try {
  434. AlipayFundTransToaccountTransferResponse response = alipayClient.execute(withdrawRequest);
  435. if (AliPayConstants.SUCCESS_CODE.equalsIgnoreCase(response.getCode())) {
  436. SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  437. one.setState(1);
  438. one.setOutAt(sdf.format(new Date()));
  439. cashOutService.update(one);
  440. UserEntity userInfo = userService.getById(one.getUserId());
  441. MessageInfo messageInfo = new MessageInfo();
  442. messageInfo.setCreateAt(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
  443. messageInfo.setContent(one.getMoney() + "提现已到账");
  444. messageInfo.setTitle("提现到账");
  445. messageInfo.setState(String.valueOf(5));
  446. messageInfo.setUserName(userInfo.getNickName());
  447. messageInfo.setUserId(String.valueOf(userInfo.getUserId()));
  448. messageService.saveBody(messageInfo);
  449. return Result.success(one.getZhifubaoName() + "转账成功");
  450. } else {
  451. return Result.error(9999, one.getZhifubaoName() + "转账失败!" + response.getSubMsg());
  452. }
  453. } catch (AlipayApiException e) {
  454. log.error("零钱提现异常原因:" + e.getMessage());
  455. e.printStackTrace();
  456. return Result.error(9999, one.getZhifubaoName() + "转账失败!" + e.getMessage());
  457. }
  458. } else if (commonInfo.getValue() != null && commonInfo.getValue().equals("2")) {
  459. try {
  460. CertAlipayRequest certAlipayRequest = new CertAlipayRequest();
  461. certAlipayRequest.setServerUrl("https://openapi.alipay.com/gateway.do"); //gateway:支付宝网关(固定)https://openapi.alipay.com/gateway.do
  462. certAlipayRequest.setAppId(commonInfoService.findOne(266).getValue()); //APPID 即创建应用后生成,详情见创建应用并获取 APPID
  463. certAlipayRequest.setPrivateKey(commonInfoService.findOne(267).getValue()); //开发者应用私钥,由开发者自己生成
  464. certAlipayRequest.setFormat("json"); //参数返回格式,只支持 json 格式
  465. certAlipayRequest.setCharset(AliPayConstants.CHARSET); //请求和签名使用的字符编码格式,支持 GBK和 UTF-8
  466. certAlipayRequest.setSignType(AliPayConstants.SIGNTYPE); //商户生成签名字符串所使用的签名算法类型,目前支持 RSA2 和 RSA,推荐商家使用 RSA2。
  467. CommonInfo url = commonInfoService.findOne(265);
  468. certAlipayRequest.setCertPath(url.getValue() + "/appCertPublicKey.crt"); //应用公钥证书路径(app_cert_path 文件绝对路径)
  469. certAlipayRequest.setAlipayPublicCertPath(url.getValue() + "/alipayCertPublicKey_RSA2.crt"); //支付宝公钥证书文件路径(alipay_cert_path 文件绝对路径)
  470. certAlipayRequest.setRootCertPath(url.getValue() + "/alipayRootCert.crt"); //支付宝CA根证书文件路径(alipay_root_cert_path 文件绝对路径)
  471. AlipayClient alipayClient = new DefaultAlipayClient(certAlipayRequest);
  472. AlipayFundTransUniTransferRequest request = new AlipayFundTransUniTransferRequest();
  473. request.setBizContent("{" +
  474. "\"out_biz_no\":\"" + one.getOrderNumber() + "\"," +
  475. "\"trans_amount\":" + new BigDecimal(one.getMoney()) + "," +
  476. "\"product_code\":\"TRANS_ACCOUNT_NO_PWD\"," +
  477. "\"biz_scene\":\"DIRECT_TRANSFER\"," +
  478. "\"order_title\":\"" + name.getValue() + "佣金结算" + "\"," +
  479. "\"payee_info\":{" +
  480. "\"identity\":\"" + one.getZhifubao() + "\"," +
  481. "\"identity_type\":\"ALIPAY_LOGON_ID\"," +
  482. "\"name\":\"" + one.getZhifubaoName() + "\"," +
  483. "}," +
  484. "\"remark\":\"" + name.getValue() + "佣金结算" + "\"" +
  485. "}");
  486. AlipayFundTransUniTransferResponse response = null;
  487. response = alipayClient.certificateExecute(request);
  488. log.error("支付宝转账返回值:" + response.getBody());
  489. if (AliPayConstants.SUCCESS_CODE.equalsIgnoreCase(response.getCode())) {
  490. SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  491. one.setState(1);
  492. one.setOutAt(sdf.format(new Date()));
  493. cashOutService.update(one);
  494. UserEntity userInfo = userService.getById(one.getUserId());
  495. MessageInfo messageInfo = new MessageInfo();
  496. messageInfo.setCreateAt(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
  497. messageInfo.setContent(one.getMoney() + "提现已到账");
  498. messageInfo.setTitle("提现到账");
  499. messageInfo.setState(String.valueOf(5));
  500. messageInfo.setUserName(userInfo.getNickName());
  501. messageInfo.setUserId(String.valueOf(userInfo.getUserId()));
  502. messageService.saveBody(messageInfo);
  503. return Result.success(one.getZhifubaoName() + "转账成功");
  504. } else {
  505. return Result.error(9999, one.getZhifubaoName() + "转账失败!" + response.getSubMsg());
  506. }
  507. } catch (AlipayApiException e) {
  508. log.error("零钱提现异常原因:" + e.getMessage());
  509. e.printStackTrace();
  510. return Result.error(9999, one.getZhifubaoName() + "转账失败!" + e.getMessage());
  511. }
  512. } else {
  513. //人工转账后改变状态的
  514. SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  515. Date now = new Date();
  516. one.setState(1);
  517. one.setOutAt(sdf.format(now));
  518. cashOutService.update(one);
  519. UserEntity userInfo = userService.getById(one.getUserId());
  520. MessageInfo messageInfo = new MessageInfo();
  521. messageInfo.setCreateAt(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
  522. messageInfo.setContent(one.getMoney() + "提现已到账");
  523. messageInfo.setTitle("提现到账");
  524. messageInfo.setState(String.valueOf(5));
  525. messageInfo.setUserName(userInfo.getNickName());
  526. messageInfo.setUserId(String.valueOf(userInfo.getUserId()));
  527. messageService.saveBody(messageInfo);
  528. return Result.success(one.getZhifubaoName() + "转账成功");
  529. }
  530. } catch (Exception e) {
  531. e.printStackTrace();
  532. log.error("转账异常" + e.getMessage());
  533. } finally {
  534. reentrantReadWriteLock.writeLock().unlock();
  535. }
  536. return Result.error("系统繁忙,请稍后再试!");
  537. }
  538. @RequestMapping(value = "/refund", method = RequestMethod.POST)
  539. @ApiOperation("管理平台退款")
  540. @ResponseBody
  541. public Result refund(Long cashId, String content) {
  542. CashOut one = cashOutService.selectById(cashId);
  543. if (one == null) {
  544. return Result.error("提现信息不存在");
  545. }
  546. //将状态为待提现的退款
  547. if (one.getState() != 0) {
  548. return Result.error(-100, "状态错误,已经转账或退款!");
  549. }
  550. SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  551. Date now = new Date();
  552. //修改提现订单状态
  553. one.setState(-1);
  554. one.setRefund(content);
  555. one.setOutAt(sdf.format(now));
  556. cashOutService.update(one);
  557. Long userId = one.getUserId();
  558. UserEntity userInfo = userService.queryByUserId(userId);
  559. if (userInfo != null) {
  560. if (one.getType() == 1) {
  561. BigDecimal money = BigDecimal.valueOf(one.getRate());
  562. //用户提现 退款到钱包
  563. //将金额退还
  564. UserMoneyDetails userMoneyDetails = new UserMoneyDetails();
  565. userMoneyDetails.setUserId(userInfo.getUserId());
  566. userMoneyDetails.setUserType(2);
  567. userMoneyDetails.setTitle("提现失败退款");
  568. userMoneyDetails.setContent("退款原因:" + content);
  569. userMoneyDetails.setType(1);
  570. userMoneyDetails.setClassify(6);
  571. userMoneyDetails.setMoney(money);
  572. userMoneyDetails.setCreateTime(sdf.format(now));
  573. userMoneyDetailsService.save(userMoneyDetails);
  574. userCashOutDao.updateMoney(1, userId, money.doubleValue());
  575. cashOutService.refundSuccess(userInfo, one.getOutAt(), one.getMoney(), commonInfoService.findOne(19).getValue(), content);
  576. } else {
  577. //保障金退款 退款到保障金账户
  578. UserMoneyDetails userMoneyDetails = new UserMoneyDetails();
  579. userMoneyDetails.setUserId(userInfo.getUserId());
  580. userMoneyDetails.setUserType(2);
  581. userMoneyDetails.setTitle("[退款提醒]退款:" + one.getRate());
  582. userMoneyDetails.setContent("保障金已退款到您的保障金中,退款原因:" + content);
  583. userMoneyDetails.setType(1);
  584. userMoneyDetails.setMoney(BigDecimal.valueOf(one.getRate()));
  585. userMoneyDetails.setCreateTime(sdf.format(now));
  586. userMoneyDetailsService.save(userMoneyDetails);
  587. UserEntity user = new UserEntity();
  588. user.setUserId(one.getUserId());
  589. user.setCashDeposit(BigDecimal.valueOf(one.getRate()));
  590. userService.updateById(user);
  591. cashOutService.refundSuccess(userInfo, one.getOutAt(), one.getMoney(), commonInfoService.findOne(19).getValue(), content);
  592. }
  593. }
  594. return Result.success();
  595. }
  596. @GetMapping("/exportExcel")
  597. public void cashListExcel(CashOut cashOut, String startTime, String endTime, HttpServletResponse response) throws IOException {
  598. List<CashOut> list = cashOutService.selectAdminHelpProfit(null, null, startTime, endTime, cashOut).getRecords();
  599. ExcelUtils.exportExcel(list, "提现统计表", "提现统计Sheet", CashOut.class, "提现统计表", response);
  600. }
  601. @RequestMapping(value = "/selectAdminHelpProfit", method = RequestMethod.GET)
  602. @ApiOperation("管理员查询提现记录列表")
  603. @ResponseBody
  604. public Result selectAdminHelpProfit(Integer page, Integer limit, String startTime, String endTime, CashOut cashOut) {
  605. return Result.success().put("data", cashOutService.selectAdminHelpProfit(page, limit, startTime, endTime, cashOut));
  606. }
  607. @RequestMapping(value = "/selectAgentHelpProfit", method = RequestMethod.GET)
  608. @ApiOperation("代理查询提现记录列表")
  609. @ResponseBody
  610. public Result selectAgentHelpProfit(Integer page, Integer limit, String startTime, String endTime, CashOut cashOut) {
  611. cashOut.setUserType(2);
  612. SysUserRoleEntity loginUserCityRole = sysUserService.getLoginUserCityRole();
  613. if (loginUserCityRole != null) {
  614. cashOut.setUserId(loginUserCityRole.getUserId());
  615. return Result.success().put("data", cashOutService.selectAdminHelpProfit(page, limit, startTime, endTime, cashOut));
  616. } else {
  617. return Result.success().put("data", null);
  618. }
  619. }
  620. }