|
|
@@ -2,29 +2,42 @@ package com.fs.app.controller.store;
|
|
|
|
|
|
import cn.hutool.json.JSONUtil;
|
|
|
import com.fs.app.controller.AppBaseController;
|
|
|
+import com.fs.common.annotation.Log;
|
|
|
import com.fs.common.core.domain.R;
|
|
|
-import com.fs.common.core.page.TableDataInfo;
|
|
|
+import com.fs.common.enums.BusinessType;
|
|
|
+import com.fs.common.exception.ServiceException;
|
|
|
+import com.fs.common.exception.CustomException;
|
|
|
+import com.fs.company.service.ICompanyService;
|
|
|
import com.fs.hisStore.config.StoreConfig;
|
|
|
+import com.fs.hisStore.domain.FsStorePaymentScrm;
|
|
|
import com.fs.hisStore.param.FsStoreScanPaymentStatParam;
|
|
|
import com.fs.hisStore.service.IFsStorePaymentScrmService;
|
|
|
-import com.fs.hisStore.vo.FsArticleListQueryVO;
|
|
|
+import com.fs.hisStore.vo.FsStoreScanPaymentDetailVo;
|
|
|
import com.fs.hisStore.vo.FsStoreScanPaymentStatDetailsVo;
|
|
|
import com.fs.hisStore.vo.FsStoreScanPaymentStatVo;
|
|
|
+import com.fs.huifuPay.domain.HuiFuRefundResult;
|
|
|
+import com.fs.huifuPay.sdk.opps.core.request.V2TradePaymentScanpayRefundRequest;
|
|
|
+import com.fs.huifuPay.service.HuiFuService;
|
|
|
import com.fs.system.service.ISysConfigService;
|
|
|
+import com.fs.company.domain.CompanyUser;
|
|
|
+import com.fs.company.service.ICompanyUserService;
|
|
|
import com.github.pagehelper.PageHelper;
|
|
|
import com.github.pagehelper.PageInfo;
|
|
|
import io.swagger.annotations.Api;
|
|
|
import io.swagger.annotations.ApiOperation;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.security.access.prepost.PreAuthorize;
|
|
|
+import org.springframework.transaction.annotation.Transactional;
|
|
|
+import org.springframework.transaction.interceptor.TransactionAspectSupport;
|
|
|
import org.springframework.web.bind.annotation.*;
|
|
|
|
|
|
import javax.validation.Valid;
|
|
|
import java.math.BigDecimal;
|
|
|
-import java.util.Collections;
|
|
|
-import java.util.HashMap;
|
|
|
-import java.util.List;
|
|
|
-import java.util.Map;
|
|
|
+import java.text.SimpleDateFormat;
|
|
|
+import java.util.*;
|
|
|
|
|
|
+@Slf4j
|
|
|
@Api("扫码流水统计接口")
|
|
|
@RestController
|
|
|
@RequestMapping("/store/app/scan/payment")
|
|
|
@@ -34,6 +47,14 @@ public class FsStoreScanPaymentStatController extends AppBaseController {
|
|
|
|
|
|
@Autowired
|
|
|
private ISysConfigService configService;
|
|
|
+ @Autowired
|
|
|
+ private IFsStorePaymentScrmService fsStorePaymentService;
|
|
|
+ @Autowired
|
|
|
+ HuiFuService huiFuService;
|
|
|
+ @Autowired
|
|
|
+ private ICompanyService companyService;
|
|
|
+ @Autowired
|
|
|
+ private ICompanyUserService companyUserService;
|
|
|
|
|
|
/**
|
|
|
* 扫码支付统计接口
|
|
|
@@ -83,6 +104,199 @@ public class FsStoreScanPaymentStatController extends AppBaseController {
|
|
|
return R.ok().put("data",listPageInfo);
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * 扫码支付流水详情接口
|
|
|
+ */
|
|
|
+ @ApiOperation("扫码支付流水详情")
|
|
|
+ @GetMapping("/getPaymentDetail/{paymentId}")
|
|
|
+ public R getPaymentDetail(@PathVariable("paymentId") Long paymentId) {
|
|
|
+ try {
|
|
|
+ FsStoreScanPaymentDetailVo paymentDetail = paymentService.getScanPaymentDetail(paymentId);
|
|
|
+ return R.ok().put("data", paymentDetail);
|
|
|
+ } catch (ServiceException e) {
|
|
|
+ return R.error(e.getMessage());
|
|
|
+ } catch (Exception e) {
|
|
|
+ return R.error("查询流水详情失败,请稍后重试");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 扫码支付退款接口(统一入口)
|
|
|
+ * 根据当前用户权限决定调用直接退款还是退款审核
|
|
|
+ */
|
|
|
+ @ApiOperation("扫码支付退款统一接口")
|
|
|
+ @PostMapping("/refund")
|
|
|
+ @Transactional
|
|
|
+ public R refundPayment(@RequestParam("token") String token,
|
|
|
+ @RequestBody FsStorePaymentScrm fsStorePayment) {
|
|
|
+ try {
|
|
|
+ // 从 Redis 中获取用户ID
|
|
|
+ Long companyUserId = redisCache.getCacheObject("company-user-token:" + token);
|
|
|
+ if (companyUserId == null) {
|
|
|
+ return R.error("用户未登录或登录已过期,请重新登录");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 查询用户信息
|
|
|
+ CompanyUser companyUser = companyUserService.selectCompanyUserById(companyUserId);
|
|
|
+ if (companyUser == null) {
|
|
|
+ return R.error("用户不存在");
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!companyUser.getStatus().equals("0")) {
|
|
|
+ return R.error("用户已禁用");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 根据用户权限调用不同的方法
|
|
|
+ if (companyUser.isAdmin()) {
|
|
|
+ // 管理员直接退款
|
|
|
+ log.info("管理员[{}]执行直接退款, 支付ID: {}", companyUser.getUserName(), fsStorePayment.getPaymentId());
|
|
|
+ return refundStorePayment(fsStorePayment);
|
|
|
+ } else {
|
|
|
+ // 非管理员提交退款审核
|
|
|
+ log.info("非管理员[{}]提交退款审核, 支付ID: {}", companyUser.getUserName(), fsStorePayment.getPaymentId());
|
|
|
+
|
|
|
+ Map<String, Object> auditData = new HashMap<>();
|
|
|
+ auditData.put("paymentId", fsStorePayment.getPaymentId());
|
|
|
+ auditData.put("refundAuditStatus", 1); // 1表示待审核
|
|
|
+ auditData.put("auditRemark", "用户提交退款申请");
|
|
|
+ auditData.put("auditor", companyUser.getUserName());
|
|
|
+
|
|
|
+ return auditRefund(auditData);
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("退款处理异常, token: {}, paymentId: {}", token, fsStorePayment.getPaymentId(), e);
|
|
|
+ return R.error("退款处理失败:" + e.getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 扫码支付退款接口(管理员专用)
|
|
|
+ */
|
|
|
+
|
|
|
+ @ApiOperation("扫码支付退款接口(管理员专用)")
|
|
|
+ @PostMapping("refundStorePayment")
|
|
|
+ @Transactional
|
|
|
+ public R refundStorePayment(@RequestBody FsStorePaymentScrm fsStorePayment)
|
|
|
+ {
|
|
|
+ FsStorePaymentScrm payment=fsStorePaymentService.selectFsStorePaymentById(fsStorePayment.getPaymentId());
|
|
|
+ if(payment.getStatus()!=1){
|
|
|
+ return R.error("非法操作");
|
|
|
+ }
|
|
|
+ if(payment.getPayTypeCode().equals("weixin")){
|
|
|
+ if (payment.getPayMode()!=null&&payment.getPayMode().equals("hf")){
|
|
|
+ V2TradePaymentScanpayRefundRequest request = new V2TradePaymentScanpayRefundRequest();
|
|
|
+ request.setOrdAmt(payment.getPayMoney().toString());
|
|
|
+ request.setOrgReqDate(new SimpleDateFormat("yyyyMMdd").format(payment.getCreateTime()));
|
|
|
+ request.setReqSeqId("refund-"+payment.getPayCode());
|
|
|
+ Map<String, Object> extendInfoMap = new HashMap<>();
|
|
|
+ extendInfoMap.put("org_party_order_id", payment.getBankSerialNo());
|
|
|
+ request.setExtendInfo(extendInfoMap);
|
|
|
+ HuiFuRefundResult refund = huiFuService.refund(request);
|
|
|
+ log.info("退款:"+refund);
|
|
|
+ if((refund.getResp_code().equals("00000000")||refund.getResp_code().equals("00000100"))&&(refund.getTrans_stat().equals("S")||refund.getTrans_stat().equals("P"))){
|
|
|
+ payment.setRefundMoney(fsStorePayment.getRefundMoney());
|
|
|
+ payment.setStatus(-1);
|
|
|
+ payment.setRefundAuditTime(new Date());
|
|
|
+ payment.setRefundAuditStatus(2);
|
|
|
+ fsStorePaymentService.updateFsStorePayment(payment);
|
|
|
+ //收款 减去所有
|
|
|
+ if(payment.getCompanyId()!=null&&payment.getCompanyId()>0){
|
|
|
+ companyService.subCompanyPaymentMoney(payment);
|
|
|
+ }
|
|
|
+ return R.ok();
|
|
|
+ }else {
|
|
|
+ TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
|
|
|
+ return R.error(refund.getResp_desc());
|
|
|
+ }
|
|
|
+
|
|
|
+ }else if (payment.getPayMode()!=null&&payment.getPayMode().equals("wx")){
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ //小雨点退款
|
|
|
+// payment.setRefundMoney(fsStorePayment.getRefundMoney());
|
|
|
+// fsStorePaymentService.updateFsStorePayment(payment);
|
|
|
+//
|
|
|
+// RefundDTO refundDTO=new RefundDTO();
|
|
|
+// refundDTO.setMerchOrderNo(Ids.oid());
|
|
|
+// refundDTO.setAmount(fsStorePayment.getRefundMoney().toString());
|
|
|
+// refundDTO.setOrigMerchOrderNo("payment-"+payment.getPayCode());
|
|
|
+// return payService.refundOrder(refundDTO);
|
|
|
+ }
|
|
|
+ else if(payment.getPayTypeCode().equals("alipay")){
|
|
|
+ try {
|
|
|
+ // 注意:这里的AliPayApiConfig、AliPayApiConfigKit、AliPayApi等类需要确保项目中有相应的依赖
|
|
|
+ // 如果没有,建议注释掉支付宝退款部分或添加相应依赖
|
|
|
+ /*
|
|
|
+ AliPayApiConfig aliPayApiConfig;
|
|
|
+ try {
|
|
|
+ aliPayApiConfig = AliPayApiConfigKit.getApiConfig(aliPayBean.getAppId());
|
|
|
+ } catch (Exception e) {
|
|
|
+ aliPayApiConfig = AliPayApiConfig.builder()
|
|
|
+ .setAppId(aliPayBean.getAppId())
|
|
|
+ .setAliPayPublicKey(aliPayBean.getPublicKey())
|
|
|
+ .setAppCertPath(aliPayBean.getAppCertPath())
|
|
|
+ .setAliPayCertPath(aliPayBean.getAliPayCertPath())
|
|
|
+ .setAliPayRootCertPath(aliPayBean.getAliPayRootCertPath())
|
|
|
+ .setCharset("UTF-8")
|
|
|
+ .setPrivateKey(aliPayBean.getPrivateKey())
|
|
|
+ .setServiceUrl(aliPayBean.getServerUrl())
|
|
|
+ .setSignType("RSA2")
|
|
|
+ // 普通公钥方式
|
|
|
+ .build();
|
|
|
+ // 证书模式
|
|
|
+// .buildByCert();
|
|
|
+ }
|
|
|
+ AliPayApiConfigKit.putApiConfig(aliPayApiConfig);
|
|
|
+ AlipayTradeRefundModel model = new AlipayTradeRefundModel();
|
|
|
+ model.setOutTradeNo("payment-"+payment.getPayCode());
|
|
|
+ model.setTradeNo(payment.getTradeNo());
|
|
|
+ model.setRefundAmount(fsStorePayment.getRefundMoney().toString());
|
|
|
+ model.setRefundReason("退款");
|
|
|
+ String result= AliPayApi.tradeRefundToResponse(model).getBody();
|
|
|
+ cn.hutool.json.JSONObject json= JSONUtil.parseObj(result);
|
|
|
+ cn.hutool.json.JSONObject jsonInfo= (cn.hutool.json.JSONObject) json.get("alipay_trade_refund_response");
|
|
|
+ String code=(String)jsonInfo.get("code");
|
|
|
+ String msg=(String)jsonInfo.get("sub_msg");
|
|
|
+ //{"{"alipay_trade_refund_response":{"code":"10000","msg":"Success","buyer_logon_id":"270***@qq.com","buyer_user_id":"2088402776950529","fund_change":"Y","gmt_refund_pay":"2022-04-27 18:27:28","out_trade_no":"goods-202204271826530001","refund_fee":"0.10","send_back_fee":"0.00","trade_no":"2022042722001450521456255417"},"sign":"hU+dy17/juMYQEQpO7Yy7jxkx9h5ebSbN3xdZr58msfOfJEUknqra6w4L37pgoZSx1Vj00jK3Ds06vrph6mSEliq3PQ37PwbZiRK3ZHaaKlz+9ndjoBTFYAxP60zLASfTq+W+dczDq4KOrvwhprFGt7YwKXGU42PgfOPb5EOgWyYUP6ivP0r06OzTo0f2lB28w6AQ4m4IQjdIL/tWbDaKl+ld8MPMLIgw5k9BmMcP8LV8ENC6+Gl1u5GwgAMjwHfk0RfB/kTFTHUTa7fgaO22w3pT8YKFMnOdKA0cVuJ2LE4SdxepqlprWJdCtLOeoQUX6PkEtoJGywPWAyjgdJ6Pg=="}
|
|
|
+ if(code.equals("10000")){
|
|
|
+ payment.setRefundMoney(fsStorePayment.getRefundMoney());
|
|
|
+ fsStorePaymentService.updateFsStorePayment(payment);
|
|
|
+ fsStorePaymentService.refund(payment.getPayCode());
|
|
|
+ return R.ok("退款成功");
|
|
|
+
|
|
|
+ }
|
|
|
+ else{
|
|
|
+ TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
|
|
|
+ return R.error("退款失败:"+msg);
|
|
|
+
|
|
|
+ }
|
|
|
+ */
|
|
|
+ return R.error("支付宝退款功能暂未配置,请联系系统管理员");
|
|
|
+ //退款成功
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ return R.error("支付宝退款异常:" + e.getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return R.error("非法操作");
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ @ApiOperation("退款审核接口(非管理员专用)")
|
|
|
+ @Log(title = "退款审核", businessType = BusinessType.UPDATE)
|
|
|
+ @PutMapping("/refund/audit")
|
|
|
+ public R auditRefund(@RequestBody Map<String, Object> auditData)
|
|
|
+ {
|
|
|
+ Long paymentId = Long.valueOf(auditData.get("paymentId").toString());
|
|
|
+ Integer auditStatus = Integer.valueOf(auditData.get("refundAuditStatus").toString());
|
|
|
+ String auditRemark = auditData.get("auditRemark") != null ? auditData.get("auditRemark").toString() : "";
|
|
|
+ String auditor = auditData.get("auditor") != null ? auditData.get("auditor").toString() : "";
|
|
|
+
|
|
|
+ return fsStorePaymentService.auditRefund(paymentId, auditStatus, auditRemark , auditor);
|
|
|
+ }
|
|
|
/**
|
|
|
* 验证立减配置是否有效
|
|
|
* @param config 店铺配置对象
|