Bladeren bron

feat:“收钱吧数币支付1.0“

soobin 1 jaar geleden
bovenliggende
commit
de293c3136

+ 32 - 0
src/main/java/com/szwl/constant/ShouQianBaConstant.java

@@ -0,0 +1,32 @@
+package com.szwl.constant;
+
+public class ShouQianBaConstant {
+
+    /**
+     * 收钱吧服务器
+     */
+    public static final String API_DOMAIN = "https://vsi-api.shouqianba.com";
+    public static final String API_DOMAIN_CONFIG = "https://vapi.shouqianba.com";
+
+
+    public static final String VENDOR_SN = "91802105";
+    public static final String VENDOR_KEY = "58d7e1277bdc44210536172afe6577b9";
+    public static final String CSB_APP_ID="2024051000007013";
+    public static final String BSC_APP_ID="2024051000007012";
+    public static final String TERMINAL_KEY = "400ecbeb7510a5faab91b00d050086cd";
+//    public static final String TERMINAL_SN = "100070120038901052";  // 个人账号
+//    public static final String NEW_TERMINAL_KEY = "aa1178506bc803a3c881447bdd9d8388"; // 个人账号
+
+    public static final String FAIL = "FAIL";
+    public static final String CREATED = "CREATED";
+    public static final String PAID = "PAID";
+    public static final String PAY_ERROR = "PAY_ERROR";
+    public static final String REFUNDED = "REFUNDED";
+    public static final String REFUND_SUCCESS = "REFUND_SUCCESS";
+    public static final String PARTIAL_REFUNDED = "PARTIAL_REFUNDED";
+    public static final String REFUND_IN_PROGRESS = "REFUND_IN_PROGRESS";
+    public static final String REFUND_INPROGRESS = "REFUND_INPROGRESS";
+
+    public static final Integer REMAINING_TIME = 50000;
+
+}

+ 16 - 0
src/main/java/com/szwl/controller/TOrderController.java

@@ -4846,5 +4846,21 @@ public class TOrderController {
         }
         return "success";
     }
+
+    @ApiOperation("收钱吧反扫购物车支付")
+    @PostMapping("/sqbCardPay")
+    @ResponseBody
+    public Object sqbCardPay(String authCode, String frpCode, String clientId, String ip, @RequestBody Map<String,String> productNameMap,HttpServletRequest request) {
+        JsonMessage jsonMessage = orderService.sqbCardPay(authCode, frpCode, clientId, ip, productNameMap, request);
+        return jsonMessage;
+    }
+
+    @ApiOperation("收钱吧发起退款")
+    @PostMapping("/sqbRefund")
+    public ResponseModel<?> sqbRefund(@RequestBody TOrder torder){
+        ResponseModel result = orderService.sqbRefund(torder);
+        return result;
+    }
+
 }
 

+ 53 - 0
src/main/java/com/szwl/controller/TSqbConfigController.java

@@ -0,0 +1,53 @@
+package com.szwl.controller;
+
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.szwl.model.bo.R;
+import com.szwl.model.bo.ResponseModel;
+import com.szwl.model.entity.TSqbConfig;
+import com.szwl.service.TAdminService;
+import com.szwl.service.TSqbConfigService;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * <p>
+ * 收钱吧数币支付配置 前端控制器
+ * </p>
+ *
+ * @author wuhs
+ * @since 2024-07-12
+ */
+@RestController
+@RequestMapping("/tSqbConfig")
+public class TSqbConfigController {
+
+    @Autowired
+    TSqbConfigService sqbConfigService;
+
+    @Autowired
+    TAdminService adminService;
+
+    @ApiOperation("激活配置")
+    @GetMapping("/activate")
+    public ResponseModel<?> activateConfig(Long adminId, String code){
+        String result = sqbConfigService.activateConfig(adminId,code);
+        return R.ok(result);
+    }
+
+    @ApiOperation("查询配置")
+    @GetMapping("/getSqbConfig")
+    public ResponseModel<?> getSqbConfig(Long adminId){
+        LambdaQueryWrapper<TSqbConfig> query = Wrappers.lambdaQuery();
+        query.eq(TSqbConfig::getAdminId,adminId);
+        TSqbConfig sqbConfig = sqbConfigService.getOne(query);
+        return R.ok(sqbConfig);
+    }
+
+}
+

+ 16 - 0
src/main/java/com/szwl/mapper/TSqbConfigMapper.java

@@ -0,0 +1,16 @@
+package com.szwl.mapper;
+
+import com.szwl.model.entity.TSqbConfig;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * <p>
+ * 收钱吧数币支付配置 Mapper 接口
+ * </p>
+ *
+ * @author wuhs
+ * @since 2024-07-12
+ */
+public interface TSqbConfigMapper extends BaseMapper<TSqbConfig> {
+
+}

+ 23 - 0
src/main/java/com/szwl/mapper/xml/TSqbConfigMapper.xml

@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.szwl.mapper.TSqbConfigMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.szwl.model.entity.TSqbConfig">
+        <id column="id" property="id" />
+        <result column="create_date" property="createDate" />
+        <result column="modify_date" property="modifyDate" />
+        <result column="admin_id" property="adminId" />
+        <result column="terminal_sn" property="terminalSn" />
+        <result column="terminal_key" property="terminalKey" />
+        <result column="new_terminal_key" property="newTerminalKey" />
+        <result column="device_id" property="deviceId" />
+        <result column="checkin" property="checkin" />
+    </resultMap>
+
+    <!-- 通用查询结果列 -->
+    <sql id="Base_Column_List">
+        id, create_date, modify_date, admin_id, terminal_sn, terminal_key, new_terminal_key, device_id, checkin
+    </sql>
+
+</mapper>

+ 53 - 0
src/main/java/com/szwl/model/entity/TSqbConfig.java

@@ -0,0 +1,53 @@
+package com.szwl.model.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import java.util.Date;
+import com.baomidou.mybatisplus.annotation.TableId;
+import java.io.Serializable;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * <p>
+ * 收钱吧数币支付配置
+ * </p>
+ *
+ * @author wuhs
+ * @since 2024-07-12
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@ApiModel(value="TSqbConfig对象", description="收钱吧数币支付配置")
+public class TSqbConfig implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @TableId(value = "id", type = IdType.AUTO)
+    private Long id;
+
+    private Date createDate;
+
+    private Date modifyDate;
+
+    @ApiModelProperty(value = "用户ID")
+    private Long adminId;
+
+    @ApiModelProperty(value = "终端号")
+    private String terminalSn;
+
+    @ApiModelProperty(value = "终端签到密钥")
+    private String terminalKey;
+
+    @ApiModelProperty(value = "终端交易密钥")
+    private String newTerminalKey;
+
+    @ApiModelProperty(value = "设备唯一身份ID,用于每日签到")
+    private String deviceId;
+
+    @ApiModelProperty(value = "签到结果,定时每日0点重置,0:未签到,1:已签到")
+    private String checkin;
+
+
+}

+ 21 - 0
src/main/java/com/szwl/service/TOrderService.java

@@ -2,6 +2,8 @@ package com.szwl.service;
 
 import com.alibaba.fastjson.JSONObject;
 import com.alipay.api.AlipayApiException;
+import com.szwl.model.bo.JsonMessage;
+import com.szwl.model.bo.ResponseModel;
 import com.szwl.model.entity.TEquipment;
 import com.szwl.model.entity.TOrder;
 import com.baomidou.mybatisplus.extension.service.IService;
@@ -98,4 +100,23 @@ public interface TOrderService extends IService<TOrder> {
      * @param companyType
      */
     void sendWechatMessage(String openId, TEquipment equipment, TOrder order, String companyType);
+
+    /**
+     * 收钱吧反扫购物车支付
+     * @param authCode
+     * @param frpCode
+     * @param clientId
+     * @param ip
+     * @param productNameMap
+     * @param request
+     * @return
+     */
+    JsonMessage sqbCardPay(String authCode, String frpCode, String clientId, String ip, Map<String, String> productNameMap, HttpServletRequest request);
+
+    /**
+     * 收钱吧发起退款
+     * @param torder
+     * @return
+     */
+    ResponseModel sqbRefund(TOrder torder);
 }

+ 23 - 0
src/main/java/com/szwl/service/TSqbConfigService.java

@@ -0,0 +1,23 @@
+package com.szwl.service;
+
+import com.szwl.model.entity.TSqbConfig;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+ * <p>
+ * 收钱吧数币支付配置 服务类
+ * </p>
+ *
+ * @author wuhs
+ * @since 2024-07-12
+ */
+public interface TSqbConfigService extends IService<TSqbConfig> {
+
+    /**
+     * 激活收钱吧数币支付配置
+     * @param adminId
+     * @param code
+     * @return
+     */
+    String activateConfig(Long adminId, String code);
+}

+ 509 - 19
src/main/java/com/szwl/service/impl/TOrderServiceImpl.java

@@ -31,7 +31,7 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.szwl.service.es.EsTOrderService;
 import com.szwl.utils.HuifuUtils;
 import com.szwl.utils.IDGenerator;
-//import com.szwl.utils.shouqianba.HttpProxy;
+import com.szwl.utils.shouqianba.HttpProxy;
 import com.szwl.weixin.util.HttpUtils;
 import com.wechat.pay.java.core.Config;
 import com.wechat.pay.java.service.payments.nativepay.model.Amount;
@@ -101,18 +101,12 @@ public class TOrderServiceImpl extends ServiceImpl<TOrderMapper, TOrder> impleme
     @Resource
     TAlipayConfigService alipayConfigService;
 
+    @Autowired
+    TSqbConfigService sqbConfigService;
 
     @Autowired
     private TOrderDetailsService orderDetailsService;
 
-    private static final String SZ_ACCESS_TOKEN_KEY = "sz_wechat_access_token";
-    private static final String SC_ACCESS_TOKEN_KEY = "sc_wechat_access_token";
-
-    /**
-     * 缓存1个半小时(90分钟)
-     */
-    private static final long EXPIRATION_TIME = 90 * 60;
-
     @Override
     public synchronized String initSn(Long equipmentId) {
         StringBuilder number = new StringBuilder();
@@ -446,7 +440,7 @@ public class TOrderServiceImpl extends ServiceImpl<TOrderMapper, TOrder> impleme
         } catch (Exception e){
             log.info("异步回调开始,参数,request={}", respData, e);
         }
-        return "退款失败";
+        return "";
     }
 
     @Override
@@ -523,6 +517,16 @@ public class TOrderServiceImpl extends ServiceImpl<TOrderMapper, TOrder> impleme
             if (paySuccess.equals("success")) {
                 order.setIsNotified("1");
             }
+            // 推送微信订单
+            TAdmin admin = R.getDataIfSuccess(szwlFeign.getAdmin(String.valueOf(order.getAdminId())));
+            // 判断是否开启订单推送功能
+            if(admin != null && StringUtils.isNotEmpty(admin.getOrderNotice()) && admin.getOrderNotice().equals("1")) {
+                String openId = R.getDataIfSuccess(szwlFeign.getOpenId(order.getAdminId()));
+                // 获取openId
+                if(StringUtils.isNotEmpty(openId)) {
+                    orderService.sendWechatMessage(openId, equipment, order, admin.getCompanyType());
+                }
+            }
         }
         orderService.updateById(order);
         try {
@@ -552,9 +556,6 @@ public class TOrderServiceImpl extends ServiceImpl<TOrderMapper, TOrder> impleme
         } catch (Exception e) {
             e.printStackTrace();
         }
-//        if(StringUtils.isEmpty(accessToken)) {
-//            accessToken = getAccessToken(companyType);
-//        }
         // 推送消息
         // 模板参数
         Map<String, WeChatTemplateMsg> sendMag = new HashMap();
@@ -591,12 +592,501 @@ public class TOrderServiceImpl extends ServiceImpl<TOrderMapper, TOrder> impleme
             sendBody.put("template_id", HuifuConstant.SC_TEMPLATE_ID);
         }
         sendMessage(accessToken, restTemplate, sendBody);
-//        if (StringUtils.isNotEmpty(messageCode) && messageCode.equals("40001")) {
-//            // 获取到新的accessToken
-//            accessToken = getAccessToken(companyType);
-//            messageCode = sendMessage(accessToken, restTemplate, sendBody);
-//            log.info("微信推送结果:{}","messageCode : " + messageCode);
-//        }
+    }
+
+    public String sqCardPay(String orderNo, BigDecimal amount, String productName, String authCode, TSqbConfig sqbConfig, String userName, String ip) {
+        HttpProxy hp = new HttpProxy(ShouQianBaConstant.API_DOMAIN);
+        try {
+            CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
+                // 异步调用支付接口
+                String payResult = hp.pay(
+                        ip, sqbConfig.getTerminalSn(), sqbConfig.getNewTerminalKey(), orderNo, authCode, amount.toString(), productName, userName);
+                log.info("支付结果:{}", payResult);
+                return payResult;
+            });
+            try {
+                Thread.sleep(3000);
+            } catch (InterruptedException e) {
+                e.printStackTrace();
+            }
+            long startTimestampMs = System.currentTimeMillis();
+            String orderStatus = "";
+            while (System.currentTimeMillis() - startTimestampMs < ShouQianBaConstant.REMAINING_TIME) {
+                String query = hp.query(
+                        sqbConfig.getTerminalSn(), sqbConfig.getNewTerminalKey(), orderNo);
+                log.info("查询结果:{}", query);
+                JSONObject queryJsonObject = JSON.parseObject(query);
+                orderStatus = queryJsonObject.getJSONObject("biz_response").getJSONObject("data")
+                            .getString("order_status");
+                if (orderStatus.equals(ShouQianBaConstant.PAID)) {
+                    log.info("订单支付成功:{}", orderNo);
+                    JSONObject bizResponse = queryJsonObject.getJSONObject("biz_response");
+                    // 付款时间
+                    String channelFinishTime = bizResponse.getJSONObject("data").getString("channel_finish_time");
+                    // 收钱吧订单号
+                    String sn = bizResponse.getJSONObject("data").getString("sn");
+                    LambdaQueryWrapper<TOrder> queryWrapper = Wrappers.lambdaQuery();
+                    queryWrapper.eq(TOrder::getSn, orderNo);
+                    queryWrapper.eq(TOrder::getStatus, 0);
+                    TOrder order = getOne(queryWrapper);
+                    if (order != null) {
+                        order.setStatus(1);
+                        order.setTrxNo(sn);
+                        Date date = new Date();
+                        try {
+                            date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(channelFinishTime);
+                        } catch (ParseException e) {
+                            // 忽略时间转换错误
+                        }
+                        order.setPayDate(date);
+                        // 更新订单明细状态
+                        LambdaQueryWrapper<TOrderDetails> lambdaQueryWrapper = new LambdaQueryWrapper<>();
+                        lambdaQueryWrapper.eq(TOrderDetails::getOrderSn, orderNo);
+                        List<TOrderDetails> orderDetails = orderDetailsService.list(lambdaQueryWrapper);
+                        for (TOrderDetails orderDetail : orderDetails) {
+                            orderDetail.setRefundStatus("1");
+                            orderDetailsService.updateById(orderDetail);
+                        }
+                        // 发送支付成功消息给设备
+                        TEquipment equipment = R.getDataIfSuccess(szwlFeign.findEquipmentByClientId(order.getClientId()));
+                        JSONObject kindData = new JSONObject();
+                        kindData.put("sn", order.getSn());
+                        kindData.put("productName", order.getProductName());
+                        if (!order.getIsNotified().equals("1")) {
+                            String paySuccess = equipmentService.sentMessage(equipment.getClientId(), PushUtils.buildJson("pay_success", kindData.toString()).toString());
+                            if (paySuccess.equals("success")) {
+                                order.setIsNotified("1");
+                            }
+                            // 推送微信订单
+                            TAdmin admin = R.getDataIfSuccess(szwlFeign.getAdmin(String.valueOf(order.getAdminId())));
+                            // 判断是否开启订单推送功能
+                            if(admin != null && StringUtils.isNotEmpty(admin.getOrderNotice()) && admin.getOrderNotice().equals("1")) {
+                                String openId = R.getDataIfSuccess(szwlFeign.getOpenId(order.getAdminId()));
+                                // 获取openId
+                                if(StringUtils.isNotEmpty(openId)) {
+                                    orderService.sendWechatMessage(openId, equipment, order, admin.getCompanyType());
+                                }
+                            }
+                        }
+                        orderService.updateById(order);
+                        try {
+                            // 保存订单信息到ES
+                            if(order.getProductNumber()==null||order.getProductNumber()==0){
+                                order.setProductNumber(1);
+                            }
+                            orderFeign.saveToEs(order);
+                        }catch (Exception e) {
+                            e.printStackTrace();
+                        }
+                    }
+                    break;
+                } else if (!orderStatus.equals(ShouQianBaConstant.CREATED) && !orderStatus.equals(ShouQianBaConstant.PAY_ERROR)) {
+                    break;
+                }
+                try {
+                    Thread.sleep(3000);
+                } catch (InterruptedException e) {
+                    e.printStackTrace();
+                }
+            }
+            return orderStatus;
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    @Override
+    public JsonMessage sqbCardPay(String authCode, String frpCode, String clientId, String ip, Map<String, String> productNameMap, HttpServletRequest request) {
+        if(productNameMap==null){
+            return JsonMessage.error("数据出错");
+        }
+        StringBuilder note = new StringBuilder();
+        StringBuilder productName = new StringBuilder();
+        String productNo = "";
+        Map<String, Integer> productMap = new HashMap<>();
+        int productNumber = 0;
+
+        TEquipment equipment = R.getDataIfSuccess(szwlFeign.findEquipmentByClientId(clientId));
+        if(equipment==null||equipment.getId()==null){
+            return JsonMessage.error("找不到设备");
+        }
+        BigDecimal price = new BigDecimal("0.00");
+        TEquipmentDesc equipmentDesc = R.getDataIfSuccess(szwlFeign.findEquipmentById(equipment.getId()));
+        if(equipmentDesc==null||equipmentDesc.getEquipmentId()==null||equipmentDesc.getPayType()==null||equipmentDesc.getPayType().equals("0")){
+            for (String key : productNameMap.keySet()) {
+                String entryValue = String.valueOf(productNameMap.get(key));
+                List<String> value = JSON.parseArray(entryValue, String.class);
+                List<TPromoCode> promoCodeList = new ArrayList<>();
+                //1,校验优惠码
+                if(value.size()>0){
+                    for(String code:value){
+                        if(!code.equals("0")){
+                            TPromoCode promoCode = new TPromoCode();
+                            ResponseModel<TPromoCode> tPromoCodeResponseModel = szwlFeign.selectTPromoCode(code, equipment.getAdminId().toString());
+                            TPromoCode tPromoCode = tPromoCodeResponseModel.getData();
+                            promoCode = tPromoCode;
+                            if (tPromoCode == null||tPromoCode.getId()==null) {
+                                //不存在
+                                return JsonMessage.success("1");
+                            }
+                            Date lastUseDate = null;
+                            if (promoCode != null) {
+                                lastUseDate = promoCode.getLastUseDate();
+                            }
+
+                            if (lastUseDate != null && lastUseDate.getTime() < ((new Date()).getTime())) {
+                                promoCode.setIsUse("2");
+                                szwlFeign.updatePromoCode(String.valueOf(promoCode.getId()),"2");
+                                //过期
+                                return JsonMessage.success("4");
+                            }
+                            if (promoCode.getId() == null) {
+                                //不存在
+                                return JsonMessage.success("1");
+                            }
+                            if (promoCode.getIsUse().equals("1")) {
+                                //被使用
+                                return JsonMessage.success("2");
+                            }
+                            if(!promoCode.getAdminId().equals("1")){
+                                if (!String.valueOf(equipment.getAdminId()).equals(promoCode.getAdminId())) {
+                                    return JsonMessage.success("3");
+                                }
+                            }
+                            if (promoCode.getDiscount() == null) {
+                                //旧优惠码
+                                return JsonMessage.success("0");
+                            }
+                            if (promoCode.getDiscount() != null && promoCode.getDiscount() == 0) {
+                                //0折
+                                return JsonMessage.success("0");
+                            }
+                            promoCodeList.add(promoCode);
+                        }
+                    }
+                }
+                String[] productNum = key.split("-");
+                String productNamea = productNum[0];
+                String num = productNum[1];
+                productMap.put(productNamea,Integer.valueOf(num));
+                productNumber += Integer.parseInt(num);
+                productName.append(productNamea).append("x").append(num).append(",");
+                TProduct product = R.getDataIfSuccess(szwlFeign.getProduct(String.valueOf(equipment.getId()), productNamea));
+                if (product == null) {
+                    return JsonMessage.error("找不到商品");
+                }
+                note.append(productNamea).append("-").append(product.getNo()).append(":");
+                BigDecimal productPrice = product.getRmbPrice();
+                productNo = product.getNo();
+                if(promoCodeList.size()>0){
+                    //有优惠码
+                    BigDecimal onePrice = new BigDecimal("0.00");
+                    int i;
+                    for( i = 0;i<promoCodeList.size();i++){
+                        BigDecimal discount = BigDecimal.valueOf(promoCodeList.get(i).getDiscount()).setScale(2, RoundingMode.HALF_DOWN);
+                        BigDecimal price1 = productPrice.multiply(discount).divide(new BigDecimal(10)).setScale(2, RoundingMode.HALF_DOWN);
+                        price = price.add(price1);
+                        onePrice = onePrice.add(price1);
+                    }
+                    if(i<Integer.parseInt(num)){
+                        int a = Integer.parseInt(num)-i;
+                        BigDecimal price2 = productPrice.multiply(new BigDecimal(a)).setScale(2, RoundingMode.HALF_DOWN);
+                        price =price.add(price2);
+                        onePrice = onePrice.add(price2);
+                    }
+                    note.append(onePrice).append("-").append(num).append(",");
+                }else {
+                    //1,type=0,原始设定,没有第二件半价
+                    int a = Integer.parseInt(num);
+                    BigDecimal price2 = productPrice.multiply(new BigDecimal(a)).setScale(2, RoundingMode.HALF_DOWN);
+                    price =price.add(price2);
+                    note.append(price2).append("-").append(num).append(",");
+                }
+            }
+        }else {
+            for (String key : productNameMap.keySet()) {
+                String[] productNum = key.split("-");
+                String productNamea = productNum[0];
+                String num = productNum[1];
+                productMap.put(productNamea,Integer.valueOf(num));
+                TProduct product = R.getDataIfSuccess(szwlFeign.getProduct(String.valueOf(equipment.getId()), productNamea));
+                productNo = product.getNo();
+                BigDecimal productPrice = product.getRmbPrice();
+                productName.append(productNamea).append("x").append(num).append(",");
+                note.append(productNamea).append("-").append(product.getNo()).append(":");
+                switch (num) {
+                    case "1":
+                        //1个  0个半价
+                        price =price.add(productPrice);
+                        note.append(price).append("-").append(num).append(",");
+                        break;
+                    case "2":
+                        //2个  1个半价
+                        price =price.add(productPrice);
+                        price =price.add(productPrice.multiply(new BigDecimal(5)).divide(new BigDecimal(10)).setScale(2, RoundingMode.HALF_DOWN));
+                        note.append(price).append("-").append(num).append(",");
+                        break;
+                    case "3":
+                        //3个 1个半价
+                        price =price.add(productPrice);
+                        price =price.add(productPrice.multiply(new BigDecimal(5)).divide(new BigDecimal(10)).setScale(2, RoundingMode.HALF_DOWN));
+                        price =price.add(productPrice);
+                        note.append(price).append("-").append(num).append(",");
+                        break;
+                    case "4":
+                        //4个 2个半价
+                        price =price.add(productPrice);
+                        price =price.add(productPrice.multiply(new BigDecimal(5)).divide(new BigDecimal(10)).setScale(2, RoundingMode.HALF_DOWN));
+                        price =price.add(productPrice);
+                        price =price.add(productPrice.multiply(new BigDecimal(5)).divide(new BigDecimal(10)).setScale(2, RoundingMode.HALF_DOWN));
+                        note.append(price).append("-").append(num).append(",");
+                        break;
+                    case "5":
+                        //5个 2个半价
+                        price =price.add(productPrice);
+                        price =price.add(productPrice.multiply(new BigDecimal(5)).divide(new BigDecimal(10)).setScale(2, RoundingMode.HALF_DOWN));
+                        price =price.add(productPrice);
+                        price =price.add(productPrice.multiply(new BigDecimal(5)).divide(new BigDecimal(10)).setScale(2, RoundingMode.HALF_DOWN));
+                        price =price.add(productPrice);
+                        note.append(price).append("-").append(num).append(",");
+                        break;
+                }
+            }
+        }
+
+        Long equipmentId = equipment.getId();
+        //查找商品
+        if (BigDecimal.ZERO.compareTo(price) >= 0) {
+            return JsonMessage.error("商品价格异常");
+        }
+        Long client6 = Long.parseLong(clientId.substring(clientId.length() - 6));
+        String sn = orderService.initSn(client6);
+        //获取分销  关联设备
+        TAdmin admin = R.getDataIfSuccess(szwlFeign.getAdmin(String.valueOf(equipment.getAdminId())));
+        // 获取收钱吧配置
+        LambdaQueryWrapper<TSqbConfig> sqbConfigQuery = Wrappers.lambdaQuery();
+        sqbConfigQuery.eq(TSqbConfig::getAdminId, admin.getId());
+        TSqbConfig sqbConfig = sqbConfigService.getOne(sqbConfigQuery);
+        if (sqbConfig == null) {
+            return JsonMessage.error("商户未配置");
+        }
+        // 查询是否签到,没有的话就进行签到
+        if (StringUtils.isNotEmpty(sqbConfig.getCheckin()) && sqbConfig.getCheckin().equals("0")) {
+            HttpProxy hp = new HttpProxy(ShouQianBaConstant.API_DOMAIN_CONFIG);
+            org.json.JSONObject terminal = hp.checkin(sqbConfig.getDeviceId(), sqbConfig.getTerminalSn(), sqbConfig.getTerminalKey());
+            if (terminal == null) {
+                return JsonMessage.error("签到失败");
+            }
+            String newTerminalKey = terminal.getString("terminal_key");
+            sqbConfig.setNewTerminalKey(newTerminalKey);
+            sqbConfigService.updateById(sqbConfig);
+        }
+
+        String companyType = admin.getCompanyType();
+        BigDecimal amount = price.setScale(2, RoundingMode.HALF_DOWN);
+        amount = amount.multiply(new BigDecimal(100)).setScale(0);
+        String appid = "";
+        TOrder order = new TOrder();
+        order.setId(IDGenerator.orderID());
+        order.setCreateDate(new Date());
+        order.setModifyDate(new Date());
+        order.setAdminId(admin.getId());
+        order.setSn(sn);
+        if(productNumber == 1) {
+            productName.delete(productName.length() - 3, productName.length());
+        } else {
+            productName.deleteCharAt(productName.length() - 1);
+        }
+        order.setProductName(productName.toString());
+        order.setPrice(price);
+        order.setClientId(equipment.getClientId());
+        order.setEquipmentId(equipmentId);
+        order.setFrpCode(frpCode);
+        order.setProductNumber(productNumber);
+        order.setStatus(0);
+        String payPlatform = "4";
+        order.setPayPlatform(payPlatform);
+        order.setCompanyType(companyType);
+        order.setMachineType(equipment.getMachineType());
+        order.setProductNo(productNo);
+        order.setNote(note.toString());
+
+        // 订单明细表
+        TOrderDetails orderDetails = new TOrderDetails();
+        orderDetails.setAdminId(admin.getId());
+        orderDetails.setEquipmentId(equipmentId);
+        orderDetails.setCreateDate(new Date());
+        orderDetails.setCompanyType(companyType);
+        orderDetails.setRefundStatus("0");
+        orderDetails.setMachineType(equipment.getMachineType());
+        // 添加到订单明细表
+        for (String key : productMap.keySet()) {
+            Integer productNum = productMap.get(key);
+            TProduct product = R.getDataIfSuccess(szwlFeign.getProduct(String.valueOf(equipment.getId()), key));
+            orderDetails.setProductNo(product.getNo());
+            orderDetails.setProductName(key);
+            orderDetails.setPrice(product.getRmbPrice());
+            orderDetails.setProductNumber(productNum);
+            orderDetails.setAmount(product.getRmbPrice().multiply(new BigDecimal(productNum)));
+            orderDetails.setId(HuifuUtils.initDetailsId());
+            orderDetails.setOrderSn(sn);
+            orderDetailsService.save(orderDetails);
+        }
+        orderService.save(order);
+        String productName1 = "";
+        if(productNumber > 1) {
+            productName1 = "棉花糖";
+        } else {
+            productName1 = productName.toString();
+        }
+        String result;
+        try {
+            result = sqCardPay(
+                    sn, amount, productName1,authCode, sqbConfig, admin.getUsername(), ip
+            );
+        } catch (Exception e) {
+            e.printStackTrace();
+            return JsonMessage.error("申请支付失败");
+        }
+        // 微信支付支付申请返回支付二维码图片
+        if (result.equals(ShouQianBaConstant.PAID)) {
+            JSONObject kindData = new JSONObject();
+            kindData.put("sn", sn);
+            return JsonMessage.success(kindData.toString());
+        } else {
+            return JsonMessage.error(result);
+        }
+    }
+
+    @Override
+    public ResponseModel sqbRefund(TOrder torder) {
+        // 退款金额: refusePrice
+        BigDecimal refusePrice = torder.getPrice().setScale(2, RoundingMode.HALF_DOWN);
+        // 退款数量: refundNumber
+        Integer refundNumber = torder.getProductNumber();
+        // 退款明细:note
+        String note = torder.getNote();
+        String[] refundDetails = note.split(",");
+        Map<String, Integer> refundMap = new HashMap<>();
+        for (String refundDetail : refundDetails) {
+            String[] keyValue  = refundDetail.split("-");
+            String key = keyValue[0];
+            String value = keyValue[1];
+            refundMap.put(key, Integer.valueOf(value));
+        }
+
+        if(refusePrice.compareTo(new BigDecimal("0.00"))<=0){
+            return R.fail(ResponseCodesEnum.A0001,"退款金额非法");
+        }
+
+
+        TOrder order = orderService.getById(torder.getId());
+        if(order.getRefundQuantity() != null && order.getRefundQuantity()>0) {
+            order.setRefundQuantity(refundNumber + order.getRefundQuantity());
+        } else {
+            order.setRefundQuantity(refundNumber);
+        }
+
+        if(refusePrice.compareTo(order.getPrice()) > 0) {
+            return R.fail(ResponseCodesEnum.A0001,"退款金额非法");
+        }
+
+        if(order.getRefundAmount() != null && order.getRefundAmount().add(refusePrice).compareTo(order.getPrice()) > 0) {
+            return R.fail(ResponseCodesEnum.A0001,"退款金额非法");
+        }
+
+        if (order.getStatus().equals("0")) {
+            return R.fail(ResponseCodesEnum.A0002,"订单非支付状态");
+        }
+
+        // 获取收钱吧配置
+        LambdaQueryWrapper<TSqbConfig> sqbConfigQuery = Wrappers.lambdaQuery();
+        sqbConfigQuery.eq(TSqbConfig::getAdminId, order.getAdminId());
+        TSqbConfig sqbConfig = sqbConfigService.getOne(sqbConfigQuery);
+        if (sqbConfig == null) {
+            return R.fail(ResponseCodesEnum.A0002,"商户未配置");
+        }
+
+        LambdaQueryWrapper<TOrderDetails> wrapper = new LambdaQueryWrapper<>();
+        wrapper.eq(TOrderDetails::getOrderSn, order.getSn());
+        List<TOrderDetails> orderDetails = orderDetailsService.list(wrapper);
+        HttpProxy hp = new HttpProxy(ShouQianBaConstant.API_DOMAIN);
+        try {
+            String amount = refusePrice.multiply(new BigDecimal(100)).setScale(0).toString();
+            String refund = hp.refund(sqbConfig.getTerminalSn(), sqbConfig.getNewTerminalKey(), order.getSn(), amount);
+            log.info("退款结果:{}", refund);
+            JSONObject jsonObject = JSON.parseObject(refund);
+            String resultCode = jsonObject.getString("result_code");
+            log.info("下单结果码:{}", resultCode);
+            if (resultCode.equals("200")) {
+                String bizResultCode = jsonObject.getJSONObject("biz_response").getString("result_code");
+                log.info("下单业务结果码:{}", bizResultCode);
+                if (bizResultCode.equals(ShouQianBaConstant.REFUND_SUCCESS)) {
+                    String orderStatus = jsonObject.getJSONObject("biz_response").getJSONObject("data").getString("order_status");
+                    log.info("订单状态:{}", orderStatus);
+                    if (orderStatus.equals(ShouQianBaConstant.REFUNDED) || orderStatus.equals(ShouQianBaConstant.PARTIAL_REFUNDED)) {
+                        // 退款序列号
+                        String refundRequestNo = jsonObject.getJSONObject("biz_response").getJSONObject("data").getString("refund_request_no");
+                        // 退款成功
+                        // 已退款
+                        if(order.getRefundQuantity() < order.getProductNumber()) {
+                            order.setStatus(1);
+                        } else {
+                            order.setStatus(3);
+                        }
+                        orderService.updateById(order);
+                        // 修改订单明细
+                        for (TOrderDetails orderDetail : orderDetails) {
+                            String orderDetailId = orderDetail.getId();
+                            Integer productNumber = refundMap.get(orderDetailId);
+                            if(productNumber != null) {
+                                // 退款数量
+                                orderDetail.setRefundQuantity(productNumber);
+                                // 退款状态
+                                if(productNumber < orderDetail.getProductNumber()) {
+                                    // 部分退款
+                                    orderDetail.setRefundStatus("2");
+                                } else {
+                                    // 全部退款
+                                    orderDetail.setRefundStatus("3");
+                                }
+                                // 退款金额
+                                orderDetail.setRefundAmount(orderDetail.getPrice().multiply(new BigDecimal(productNumber)));
+                                orderDetailsService.updateById(orderDetail);
+                            }
+                        }
+                        // 已退款金额
+                        BigDecimal refundAmount = order.getRefundAmount();
+                        BigDecimal price = order.getPrice();
+                        if(refundAmount != null) {
+                            if (price.compareTo(refundAmount) == 0) {
+                                order.setRefundAmount(refundAmount);
+                            } else {
+                                order.setRefundAmount(refundAmount.add(refusePrice));
+                            }
+                        } else {
+                            order.setRefundAmount(refusePrice);
+                        }
+                        // 退款时间
+                        order.setRefundDate(new Date());
+                        order.setModifyDate(new Date());
+                        order.setRefundTrxNo(refundRequestNo);
+                        try {
+                            orderFeign.saveToEs(order);
+                        }catch (Exception e) {
+                            e.printStackTrace();
+                        }finally {
+                            orderService.updateById(order);
+                        }
+                        return R.ok("申请退款已成功");
+                    }
+                }
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return R.fail(ResponseCodesEnum.B0001,"申请退款失败,请联系管理员");
     }
 
     /**

+ 49 - 0
src/main/java/com/szwl/service/impl/TSqbConfigServiceImpl.java

@@ -0,0 +1,49 @@
+package com.szwl.service.impl;
+
+import cn.hutool.core.util.RandomUtil;
+import com.szwl.constant.ShouQianBaConstant;
+import com.szwl.model.entity.TSqbConfig;
+import com.szwl.mapper.TSqbConfigMapper;
+import com.szwl.service.TSqbConfigService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.szwl.utils.shouqianba.HttpProxy;
+import org.json.JSONObject;
+import org.springframework.stereotype.Service;
+
+import java.util.Date;
+
+/**
+ * <p>
+ * 收钱吧数币支付配置 服务实现类
+ * </p>
+ *
+ * @author wuhs
+ * @since 2024-07-12
+ */
+@Service
+public class TSqbConfigServiceImpl extends ServiceImpl<TSqbConfigMapper, TSqbConfig> implements TSqbConfigService {
+
+    @Override
+    public String activateConfig(Long adminId, String code) {
+        String deviceId = "SUNZEE" + RandomUtil.randomNumbers(6);
+        HttpProxy hp = new HttpProxy(ShouQianBaConstant.API_DOMAIN_CONFIG);
+        JSONObject result = hp.activate(ShouQianBaConstant.VENDOR_SN, ShouQianBaConstant.VENDOR_KEY, ShouQianBaConstant.BSC_APP_ID, code, deviceId);
+        if (result != null) {
+            // 激活获取
+            String terminalSn = result.getString("terminal_sn");
+            String terminalKey = result.getString("terminal_key");
+            // 保存配置
+            TSqbConfig tSqbConfig = new TSqbConfig();
+            tSqbConfig.setCreateDate(new Date());
+            tSqbConfig.setModifyDate(new Date());
+            tSqbConfig.setAdminId(adminId);
+            tSqbConfig.setTerminalSn(terminalSn);
+            tSqbConfig.setTerminalKey(terminalKey);
+            tSqbConfig.setDeviceId(deviceId);
+            tSqbConfig.setCheckin("0");
+            save(tSqbConfig);
+            return terminalKey;
+        }
+        return null;
+    }
+}

+ 10 - 0
src/main/java/com/szwl/service/impl/TWechatPayConfigServiceImpl.java

@@ -447,6 +447,16 @@ public class TWechatPayConfigServiceImpl extends ServiceImpl<TWechatPayConfigMap
                         if (paySuccess.equals("success")) {
                             order.setIsNotified("1");
                         }
+                        // 推送微信订单
+                        TAdmin admin = R.getDataIfSuccess(szwlFeign.getAdmin(String.valueOf(order.getAdminId())));
+                        // 判断是否开启订单推送功能
+                        if(admin != null && StringUtils.isNotEmpty(admin.getOrderNotice()) && admin.getOrderNotice().equals("1")) {
+                            String openId = R.getDataIfSuccess(szwlFeign.getOpenId(order.getAdminId()));
+                            // 获取openId
+                            if(StringUtils.isNotEmpty(openId)) {
+                                orderService.sendWechatMessage(openId, equipment, order, admin.getCompanyType());
+                            }
+                        }
                     }
                     orderService.updateById(order);
                     try {

File diff suppressed because it is too large
+ 741 - 0
src/main/java/com/szwl/utils/shouqianba/HttpProxy.java


+ 173 - 0
src/main/java/com/szwl/utils/shouqianba/HttpUtil.java

@@ -0,0 +1,173 @@
+package com.szwl.utils.shouqianba;
+
+import lombok.extern.slf4j.Slf4j;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.ssl.SSLContextBuilder;
+import org.apache.http.ssl.TrustStrategy;
+import org.apache.http.util.EntityUtils;
+
+import javax.net.ssl.SSLContext;
+import java.io.IOException;
+import java.security.KeyManagementException;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.UnrecoverableKeyException;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+
+@Slf4j
+public class HttpUtil {
+
+    public static String httpPostWithoutException(String url, String string,String sign,String sn) {
+        String xmlRes = "{}";
+        try {
+            xmlRes = httpPost(url, string,sign, sn ,"112.74.63.148");
+        } catch (UnrecoverableKeyException e) {
+            log.error("", e);
+        } catch (NoSuchAlgorithmException e) {
+            log.error("", e);
+        } catch (KeyStoreException e) {
+            log.error("", e);
+        } catch (KeyManagementException e) {
+            log.error("", e);
+        }
+        return xmlRes;
+    }
+    /**
+     * http POST 请求
+     * @param  url:请求地址
+     * @param  body: body实体字符串
+     * @param  sign:签名
+     * @param  sn: 序列号
+     * @return
+     */
+    public static String httpPost(String url, String body,String sign, String sn, String ip) throws UnrecoverableKeyException, NoSuchAlgorithmException, KeyStoreException, KeyManagementException {
+        String xmlRes = "{}";
+        HttpClient client = createSSLClientDefault();
+        HttpPost httpost = new HttpPost(url);
+        try {
+            log.debug("Request string: " + body);
+
+            //所有请求的body都需采用UTF-8编码
+            StringEntity entity = new StringEntity(body,"UTF-8");
+            entity.setContentType("application/json");
+            httpost.setEntity(entity);
+
+            //支付平台所有的API仅支持JSON格式的请求调用,HTTP请求头Content-Type设为application/json
+            httpost.addHeader("Content-Type","application/json");
+
+            //支付平台所有的API调用都需要签名验证,签名首部: Authorization: sn + " " + sign
+            httpost.addHeader("Authorization",sn + " " + sign);
+
+            //发起交易终端的真实IP地址
+//            httpost.addHeader("X-Forwarded-For", "113.103.36.206");
+            httpost.addHeader("X-Forwarded-For", ip);
+            HttpResponse response = client.execute(httpost);
+
+            //所有响应也采用UTF-8编码
+            xmlRes = EntityUtils.toString(response.getEntity(), "UTF-8");
+            log.debug("Response string: " + xmlRes);
+        } catch (ClientProtocolException e) {
+            log.error("", e);
+        } catch (IOException e) {
+            log.error("", e);
+        }
+        return xmlRes;
+    }
+
+    /**
+     * http POST 请求
+     * @param  url:请求地址
+     * @param  body: body实体字符串
+     * @param
+     * @return
+     */
+    public static String httpPost(String url, String body) throws UnrecoverableKeyException, NoSuchAlgorithmException, KeyStoreException, KeyManagementException {
+        String xmlRes = "{}";
+        HttpClient client = createSSLClientDefault();
+        HttpPost httpost = new HttpPost(url);
+        try {
+            log.debug("Request string: " + body);
+
+            //所有请求的body都需采用UTF-8编码
+            StringEntity entity = new StringEntity(body,"UTF-8");
+            entity.setContentType("application/json");
+            httpost.setEntity(entity);
+
+            //支付平台所有的API仅支持JSON格式的请求调用,HTTP请求头Content-Type设为application/json
+            // httpost.addHeader("Content-Type","multipart/form-data");
+            httpost.addHeader("Content-Type","application/json");
+            HttpResponse response = client.execute(httpost);
+            //所有响应也采用UTF-8编码
+
+            xmlRes = EntityUtils.toString(response.getEntity(), "UTF-8");
+            log.debug("Response string: " + xmlRes);
+        } catch (ClientProtocolException e) {
+            log.error("", e);
+        } catch (IOException e) {
+            log.error("", e);
+        }
+        return xmlRes;
+    }
+
+    public static CloseableHttpClient createSSLClientDefault() {
+        try {
+            SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
+                //信任所有
+                @Override
+                public boolean isTrusted(X509Certificate[] chain,
+                                         String authType) throws CertificateException {
+                    return true;
+                }
+            }).build();
+            SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext);
+            return HttpClients.custom().setSSLSocketFactory(sslsf).build();
+        } catch (KeyManagementException e) {
+            log.error("", e);
+        } catch (NoSuchAlgorithmException e) {
+            log.error("", e);
+        } catch (KeyStoreException e) {
+            log.error("", e);
+        }
+        return HttpClients.createDefault();
+    }
+
+    public static String doGet(String url,String parameter)
+    {
+        String uriAPI =url+"?"+parameter ; //"http://XXXXX?str=I+am+get+String";
+        String result= "";
+        HttpClient client = createSSLClientDefault();
+        HttpGet httpRequst = new HttpGet(uriAPI);
+        try {
+
+            HttpResponse httpResponse = client.execute(httpRequst);//其中HttpGet是HttpUriRequst的子类
+            if(httpResponse.getStatusLine().getStatusCode() == 200)
+            {
+                HttpEntity httpEntity = httpResponse.getEntity();
+                result = EntityUtils.toString(httpEntity);//取出应答字符串
+                // 一般来说都要删除多余的字符
+                result.replaceAll("\r", "");//去掉返回结果中的"\r"字符,否则会在结果字符串后面显示一个小方格
+            } else {
+                httpRequst.abort();
+            }
+        } catch (ClientProtocolException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+            result = e.getMessage().toString();
+        } catch (IOException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+            result = e.getMessage().toString();
+        }
+        return result;
+    }
+}

+ 23 - 0
src/main/java/com/szwl/utils/shouqianba/IPUtil.java

@@ -0,0 +1,23 @@
+package com.szwl.utils.shouqianba;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+
+public class IPUtil {
+
+    public static String getIp() {
+        InetAddress ia = null;
+        try {
+            ia = InetAddress.getLocalHost();
+        } catch (UnknownHostException e) {
+            e.printStackTrace();
+        }
+        String localip = ia.getHostAddress();
+        if(localip.equals("10.0.0.153")){
+            localip = "112.74.63.148";
+        }else {
+            localip = "47.112.127.131";
+        }
+        return localip;
+    }
+}

+ 16 - 0
src/main/java/com/szwl/utils/shouqianba/MD5Util.java

@@ -0,0 +1,16 @@
+package com.szwl.utils.shouqianba;
+
+import org.apache.commons.codec.digest.DigestUtils;
+
+import java.io.UnsupportedEncodingException;
+
+public class MD5Util {
+
+    public static String encryptMd5(String string) throws UnsupportedEncodingException {
+        return encryptMd5(string, "UTF-8");
+    }
+
+    public static String encryptMd5(String string, String charSet) throws UnsupportedEncodingException {
+        return DigestUtils.md5Hex(string.getBytes(charSet));
+    }
+}

+ 138 - 0
src/main/java/com/szwl/utils/shouqianba/RSASignature.java

@@ -0,0 +1,138 @@
+package com.szwl.utils.shouqianba;
+
+import org.apache.commons.codec.binary.Base64;
+
+import java.security.KeyFactory;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.security.spec.X509EncodedKeySpec;
+
+public class RSASignature {
+    /**
+     * 签名算法
+     */
+    public static final String SIGN_ALGORITHMS = "SHA256WithRSA";
+
+    //编码
+    private static final String CHARSET_UTF_8 = "utf-8";
+
+    /**
+     * RSA签名
+     *
+     * @param content
+     *            待签名数据
+     * @param privateKey
+     *            商户私钥
+     * @param encode
+     *            字符集编码
+     * @return 签名值
+     */
+    public static String sign(String content, String privateKey, String encode) {
+        try {
+            PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec(
+                    Base64.decodeBase64(privateKey));
+
+            KeyFactory keyf = KeyFactory.getInstance("RSA");
+            PrivateKey priKey = keyf.generatePrivate(priPKCS8);
+
+            java.security.Signature signature = java.security.Signature
+                    .getInstance(SIGN_ALGORITHMS);
+
+            signature.initSign(priKey);
+            signature.update(content.getBytes(encode));
+
+            byte[] signed = signature.sign();
+
+            return Base64.encodeBase64String(signed);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+        return null;
+    }
+
+    public static String sign(String content, String privateKey) {
+        try {
+            PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec(
+                    Base64.decodeBase64(privateKey));
+            KeyFactory keyf = KeyFactory.getInstance("RSA");
+            PrivateKey priKey = keyf.generatePrivate(priPKCS8);
+            java.security.Signature signature = java.security.Signature
+                    .getInstance(SIGN_ALGORITHMS);
+            signature.initSign(priKey);
+            signature.update(content.getBytes());
+            byte[] signed = signature.sign();
+            return Base64.encodeBase64String(signed);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    /**
+     * RSA验签名检查
+     *
+     * @param content
+     *            待签名数据
+     * @param sign
+     *            签名值
+     * @param publicKey
+     *            分配给开发商公钥
+     * @param encode
+     *            字符集编码
+     * @return 布尔值
+     */
+    public static boolean doCheck(String content, String sign,
+                                  String publicKey, String encode) {
+        try {
+
+            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
+            byte[] encodedKey = Base64.decodeBase64(publicKey);
+            PublicKey pubKey = keyFactory
+                    .generatePublic(new X509EncodedKeySpec(encodedKey));
+
+            java.security.Signature signature = java.security.Signature
+                    .getInstance(SIGN_ALGORITHMS);
+
+            signature.initVerify(pubKey);
+            signature.update(content.getBytes(encode));
+
+            boolean bverify = signature.verify(Base64.decodeBase64(sign));
+            return bverify;
+
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+        return false;
+    }
+
+    public static boolean doCheck(String content, String sign, String publicKey) {
+        try {
+
+            System.out.println("publicKey:"+publicKey);
+            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
+
+            byte[] encodedKey = Base64.decodeBase64(publicKey);
+
+            PublicKey pubKey = keyFactory
+                    .generatePublic(new X509EncodedKeySpec(encodedKey));
+
+            java.security.Signature signature = java.security.Signature
+                    .getInstance(SIGN_ALGORITHMS);
+
+            signature.initVerify(pubKey);
+            signature.update(content.getBytes());
+
+            boolean bverify = signature.verify(Base64.decodeBase64(sign));
+
+            return bverify;
+
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+        return false;
+    }
+}