2021与蓝度共同重构项目,服务端
liuhaonan
2022-06-28 3c88ed137df2428dd43a405336cbd79011345efd
支付配置
已添加1个文件
已修改10个文件
673 ■■■■■ 文件已修改
dao/src/main/java/com/sandu/ximon/dao/bo/C3mOrderBo.java 102 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
dao/src/main/java/com/sandu/ximon/dao/mapper/C3mOrderMapper.java 27 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
dao/src/main/resources/mapper/C3mOrderMapper.xml 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ximon-admin/src/main/java/com/sandu/ximon/admin/controller/C3mChargingChargeController.java 15 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ximon-admin/src/main/java/com/sandu/ximon/admin/controller/C3mOrderController.java 127 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ximon-admin/src/main/java/com/sandu/ximon/admin/param/PayParam.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ximon-admin/src/main/java/com/sandu/ximon/admin/pay/wx/WxFastPayService.java 134 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ximon-admin/src/main/java/com/sandu/ximon/admin/pay/wx/WxPayConfiguration.java 52 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ximon-admin/src/main/java/com/sandu/ximon/admin/service/C3mChargingChargeService.java 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ximon-admin/src/main/java/com/sandu/ximon/admin/service/C3mOrderService.java 87 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ximon-admin/src/main/resources/application.yml 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
dao/src/main/java/com/sandu/ximon/dao/bo/C3mOrderBo.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,102 @@
package com.sandu.ximon.dao.bo;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;
/**
 * @author LiuHaoNan
 * @date 2022/6/28
 * è®¢å•列表字段
 */
@Data
public class C3mOrderBo {
    /**
     * è®¢å•ID
     */
    private Long orderId;
    /**
     * ç¯æ†ID
     */
    private Long poleId;
    /**
     * å¯¹åº”的灯杆设备mac
     */
    private String poleMac;
    /**
     * è®¢å•商户号
     */
    private String outTradeNo;
    /**
     * è®¢å•总金额
     */
    private Double totalAmount;
    /**
     * å®žæ”¶é‡‘额
     */
    private Double receiptAmount;
    /**
     * é€€æ¬¾
     */
    private Double refundAmount;
    /**
     * é¢„约电量
     */
    private Integer subscribeChargingCapacity;
    /**
     * å®žå……电量
     */
    private Double actualChargingCapacity;
    /**
     * è®¢å•支付时间戳
     */
    private Long payTimestamp;
    /**
     * è®¢å•退款时间戳
     */
    private Long refundTimestamp;
    /**
     * å¼€å§‹å……电时间戳
     */
    private Long startChargingTimestamp;
    /**
     * ç»“束充电时间戳
     */
    private Long stopChargingTimestamp;
    /**
     * è®¢å•状态:// å·²æ”¯ä»˜(1),退款中(2),已退款(3),订单完成(4),退款失败5)
     */
    private Integer orderStatus;
    /**
     * å……电桩名称
     */
    private String c3Name;
    /**
     * ç¯æ†åç§°
     */
//    private String poleName;
    /**
     * 0 å……电中   1充电结束
     */
    private Integer changingStates;
}
dao/src/main/java/com/sandu/ximon/dao/mapper/C3mOrderMapper.java
@@ -1,27 +1,42 @@
package com.sandu.ximon.dao.mapper;
import com.sandu.ximon.dao.domain.C3mOrder;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.sandu.ximon.dao.bo.C3mOrderBo;
import com.sandu.ximon.dao.domain.C3mOrder;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
import java.util.List;
/**
* @author Administrator
* @description é’ˆå¯¹è¡¨ã€c3_order(C3订单表)】的数据库操作Mapper
* @createDate 2022-06-27 12:11:23
* @Entity com.sandu.ximon.dao.domain.C3mOrder
*/
 * @author Administrator
 * @description é’ˆå¯¹è¡¨ã€c3_order(C3订单表)】的数据库操作Mapper
 * @createDate 2022-06-27 12:11:23
 * @Entity com.sandu.ximon.dao.domain.C3mOrder
 */
@Mapper
public interface C3mOrderMapper extends BaseMapper<C3mOrder> {
    /**
     * è®¢å•详情
     *
     * @param outTradeNo
     * @return
     */
    @Select("select * from c3_order where out_trade_no = #{outTradeNo}")
    C3mOrder getOrderByOutTradeNo(@Param("outTradeNo") String outTradeNo);
    /**
     * é€€æ¬¾  æ›´æ–°è®¢å•状态
     *
     * @param c3mOrderEntity
     */
    @Update("update c3_order set refund_amount = #{refundAmount},refund_timestamp=#{refundTimestamp},order_status=#{orderStatus}, refund_msg = #{refundMsg} where order_id = #{orderId}")
    void updateRefundOrder(C3mOrder c3mOrderEntity);
    List<C3mOrderBo> orderList(Long userId);
}
dao/src/main/resources/mapper/C3mOrderMapper.xml
@@ -5,33 +5,34 @@
<mapper namespace="com.sandu.ximon.dao.mapper.C3mOrderMapper">
    <resultMap id="BaseResultMap" type="com.sandu.ximon.dao.domain.C3mOrder">
            <id property="orderId" column="order_id" jdbcType="BIGINT"/>
            <result property="poleId" column="pole_id" jdbcType="BIGINT"/>
            <result property="c3Mac" column="c3_mac" jdbcType="VARCHAR"/>
            <result property="poleMac" column="pole_mac" jdbcType="VARCHAR"/>
            <result property="outTradeNo" column="out_trade_no" jdbcType="VARCHAR"/>
            <result property="orderType" column="order_type" jdbcType="VARCHAR"/>
            <result property="totalAmount" column="total_amount" jdbcType="DECIMAL"/>
            <result property="receiptAmount" column="receipt_amount" jdbcType="DECIMAL"/>
            <result property="refundAmount" column="refund_amount" jdbcType="DECIMAL"/>
            <result property="aliBuyerLogonId" column="ali_buyer_logon_id" jdbcType="VARCHAR"/>
            <result property="subscribeChargingCapacity" column="subscribe_charging_capacity" jdbcType="INTEGER"/>
            <result property="actualChargingCapacity" column="actual_charging_capacity" jdbcType="DOUBLE"/>
            <result property="createTimestamp" column="create_timestamp" jdbcType="BIGINT"/>
            <result property="payTimestamp" column="pay_timestamp" jdbcType="BIGINT"/>
            <result property="refundTimestamp" column="refund_timestamp" jdbcType="BIGINT"/>
            <result property="refundMsg" column="refund_msg" jdbcType="VARCHAR"/>
            <result property="startChargingTimestamp" column="start_charging_timestamp" jdbcType="BIGINT"/>
            <result property="stopChargingTimestamp" column="stop_charging_timestamp" jdbcType="BIGINT"/>
            <result property="orderStatus" column="order_status" jdbcType="INTEGER"/>
            <result property="c3Name" column="c3_name" jdbcType="VARCHAR"/>
            <result property="poleName" column="pole_name" jdbcType="VARCHAR"/>
            <result property="changingStates" column="changing_states" jdbcType="INTEGER"/>
            <result property="userCode" column="user_code" jdbcType="VARCHAR"/>
        <id property="orderId" column="order_id" jdbcType="BIGINT"/>
        <result property="poleId" column="pole_id" jdbcType="BIGINT"/>
        <result property="c3Mac" column="c3_mac" jdbcType="VARCHAR"/>
        <result property="poleMac" column="pole_mac" jdbcType="VARCHAR"/>
        <result property="outTradeNo" column="out_trade_no" jdbcType="VARCHAR"/>
        <result property="orderType" column="order_type" jdbcType="VARCHAR"/>
        <result property="totalAmount" column="total_amount" jdbcType="DECIMAL"/>
        <result property="receiptAmount" column="receipt_amount" jdbcType="DECIMAL"/>
        <result property="refundAmount" column="refund_amount" jdbcType="DECIMAL"/>
        <result property="aliBuyerLogonId" column="ali_buyer_logon_id" jdbcType="VARCHAR"/>
        <result property="subscribeChargingCapacity" column="subscribe_charging_capacity" jdbcType="INTEGER"/>
        <result property="actualChargingCapacity" column="actual_charging_capacity" jdbcType="DOUBLE"/>
        <result property="createTimestamp" column="create_timestamp" jdbcType="BIGINT"/>
        <result property="payTimestamp" column="pay_timestamp" jdbcType="BIGINT"/>
        <result property="refundTimestamp" column="refund_timestamp" jdbcType="BIGINT"/>
        <result property="refundMsg" column="refund_msg" jdbcType="VARCHAR"/>
        <result property="startChargingTimestamp" column="start_charging_timestamp" jdbcType="BIGINT"/>
        <result property="stopChargingTimestamp" column="stop_charging_timestamp" jdbcType="BIGINT"/>
        <result property="orderStatus" column="order_status" jdbcType="INTEGER"/>
        <result property="c3Name" column="c3_name" jdbcType="VARCHAR"/>
        <result property="poleName" column="pole_name" jdbcType="VARCHAR"/>
        <result property="changingStates" column="changing_states" jdbcType="INTEGER"/>
        <result property="userCode" column="user_code" jdbcType="VARCHAR"/>
    </resultMap>
    <sql id="Base_Column_List">
        order_id,pole_id,c3_mac,
        order_id
        ,pole_id,c3_mac,
        pole_mac,out_trade_no,order_type,
        total_amount,receipt_amount,refund_amount,
        ali_buyer_logon_id,subscribe_charging_capacity,actual_charging_capacity,
@@ -40,4 +41,15 @@
        order_status,c3_name,pole_name,
        changing_states,user_code
    </sql>
    <select id="orderList" resultType="com.sandu.ximon.dao.bo.C3mOrderBo" parameterType="java.lang.Long">
        SELECT
        t1.*
        FROM
        c3_order t1
        LEFT JOIN pole t2 ON t1.pole_id = t2.id
        <if test="userId != null">
            WHERE (t1.userId = #{userId} OR t1.client_id= #{userId})
        </if>
    </select>
</mapper>
ximon-admin/src/main/java/com/sandu/ximon/admin/controller/C3mChargingChargeController.java
@@ -1,10 +1,8 @@
package com.sandu.ximon.admin.controller;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.sandu.common.domain.ResponseVO;
import com.sandu.common.execption.BusinessException;
import com.sandu.common.util.ResponseUtil;
import com.sandu.ximon.admin.param.C3mChargingChargeParam;
import com.sandu.ximon.admin.service.C3mChargingChargeService;
import com.sandu.ximon.dao.domain.C3mChargingCharge;
import lombok.AllArgsConstructor;
@@ -27,6 +25,7 @@
    /**
     * ç¼–辑充电桩费率
     *
     * @param chargeEntities
     * @return
     */
@@ -42,15 +41,23 @@
    }
    @GetMapping("/getChargeByC3Id/{c3mId}")  //未同步文档
    @GetMapping("/getChargeByC3Id/{c3mId}")
    public ResponseVO<Object> getChargeByC3Id(@PathVariable Integer c3mId) {
        return ResponseUtil.success(chargeService.getChargeByC3Id(c3mId));
    }
    @GetMapping("/getChargeByPoleId/{PoleId}") //为未同步文档
    @GetMapping("/getChargeByPoleId/{PoleId}")
    public ResponseVO<Object> getChargeByPoleId(@PathVariable Long PoleId) {
        return ResponseUtil.success(chargeService.getChargeByPoleId(PoleId));
    }
    /**
     * æ ¹æ®å……电桩mac获取当前时间段的费率
     */
    @GetMapping("/getChargeByMac/{mac}")
    public ResponseVO<Object> getChargeByMac(@PathVariable Long mac, Integer power) {
        return ResponseUtil.success(chargeService.getCostByC3id(mac, power));
    }
}
ximon-admin/src/main/java/com/sandu/ximon/admin/controller/C3mOrderController.java
@@ -1,34 +1,25 @@
package com.sandu.ximon.admin.controller;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradeWapPayModel;
import com.alipay.api.request.AlipayTradeWapPayRequest;
import com.sandu.common.domain.ResponseVO;
import com.sandu.common.execption.BusinessException;
import com.sandu.common.object.BaseConditionVO;
import com.sandu.common.util.ResponseUtil;
import com.sandu.ximon.admin.config.AlipayConfig;
import com.sandu.ximon.admin.param.PayParam;
import com.sandu.ximon.admin.pay.alipay.UsrAlipayConfigService;
import com.sandu.ximon.admin.pay.wx.WxFastPayService;
import com.sandu.ximon.admin.service.C3ChargingService;
import com.sandu.ximon.admin.service.C3mChargingChargeService;
import com.sandu.ximon.admin.service.C3mOrderService;
import com.sandu.ximon.admin.utils.AliPayUtils;
import com.sandu.ximon.admin.utils.ConfigCheckUtils;
import com.sandu.ximon.dao.domain.AliConfigEntity;
import com.sandu.ximon.dao.bo.C3mOrderBo;
import com.sandu.ximon.dao.domain.C3mCharging;
import com.sandu.ximon.dao.domain.C3mOrder;
import com.sandu.ximon.dao.enums.OrderType;
import lombok.AllArgsConstructor;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Date;
import java.util.Map;
import java.math.BigDecimal;
import java.util.List;
import java.util.SortedMap;
/**
@@ -44,6 +35,7 @@
    private final C3ChargingService c3mService;
    private final UsrAlipayConfigService alipayConfigService;
    private final WxFastPayService wxPayService;
    private final C3mChargingChargeService c3mChargingChargeService;
    /**
@@ -52,11 +44,13 @@
     * @return
     */
    @PostMapping("/refond")
    public ResponseVO<Object> refond(@RequestBody Map params) {
//        c3mOrderService.orderRefund( (String)params.get("outTradeNo"),
//                (Double)params.get("refundAmount"));
        return ResponseUtil.success(c3mOrderService.orderRefund((String) params.get("outTradeNo"),
                (Double) params.get("refundAmount")));
    public ResponseVO<Object> refond(@RequestBody PayParam params) {
        if (params.getOutTradeNo().isEmpty() || params.getRefundAmount() == null) {
            throw new BusinessException("退款参数不能为空");
        }
        return ResponseUtil.success(c3mOrderService.orderRefund(params.getOutTradeNo(),
                params.getRefundAmount()));
    }
@@ -75,13 +69,15 @@
        if (null == c3m) {
            throw new BusinessException("未找到当前充电桩");
        }
        //获取预付金额
        BigDecimal TotalAmount = c3mChargingChargeService.getCostByC3id(c3m.getC3Id(), param.getSubscribeChargingCapacity());
        //转换为double类型
        double totalAmount = TotalAmount.doubleValue();
        C3mOrder c3mOrderEntity = c3mOrderService.advancePayOrder(param.getPoleId(), c3m, "wxpay"
                , param.getTotalAmount(), param.getSubscribeChargingCapacity());
                , totalAmount, param.getSubscribeChargingCapacity());
        if (null == c3mOrderEntity) {
            throw new BusinessException("该充电桩正被使用!");
        }
//        return R.ok().put("outTradeNo",c3mOrderEntity.getOutTradeNo())
//                .put("totalAmount",totalAmount);
        param.setOutTradeNo(c3mOrderEntity.getOutTradeNo());
        param.setTotalAmount(c3mOrderEntity.getTotalAmount());
@@ -91,76 +87,12 @@
    }
    @PostMapping("/aliPay")
    public ResponseVO<Object> c3AliPay(@RequestBody PayParam param, HttpServletResponse response) {
        // å•†æˆ·è®¢å•号,商户网站订单系统中唯一订单号,必填
        String out_trade_no = param.getOutTradeNo();
        System.out.println("订单号:" + out_trade_no);
        // è®¢å•名称,必填
        String subject = "扫码充电支付(C3充电桩)";
        // ä»˜æ¬¾é‡‘额,必填,单位为元,精确到小数点后两位,取值范围[0.01,100000000]
        String total_amount = param.getTotalAmount().toString();
        // å•†å“æè¿°ï¼Œå¯ç©º
        String body = "请勿付款,测试用";
        // è¶…æ—¶æ—¶é—´ å¯ç©º
        String timeout_express = "5m";
        // é”€å”®äº§å“ç  å¿…å¡«
        String product_code = "QUICK_WAP_WAY";
        /**********************/
        AliConfigEntity alipayConfigEntity = alipayConfigService.getConfigByPoleId(param.getPoleId());
        String checkStr = ConfigCheckUtils.checkAlipayConfig(alipayConfigEntity);
        if (checkStr != null) {
            try {
                response.getWriter().write(checkStr);
                return ResponseUtil.fail("支付完成失败");
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        //调用RSA签名方式
        AlipayClient client = new DefaultAlipayClient(AlipayConfig.gatewayUrl, alipayConfigEntity.getAppId(), alipayConfigEntity.getPrivateKey(), AlipayConfig.format, AlipayConfig.charset, alipayConfigEntity.getPublicKey(), AlipayConfig.sign_type);
        AlipayTradeWapPayRequest alipay_request = new AlipayTradeWapPayRequest();
        // å°è£…请求支付信息
        AlipayTradeWapPayModel model = new AlipayTradeWapPayModel();
        model.setOutTradeNo(out_trade_no);
        model.setSubject(subject);
        model.setTotalAmount(total_amount);
        model.setBody(body);
        model.setTimeoutExpress(timeout_express);
        model.setProductCode(product_code);
        model.setQuitUrl(C3mOrder.REQUEST_URL + param.getPoleId() + "/" + new Date().getTime());
        alipay_request.setBizModel(model);
        // è®¾ç½®å¼‚步通知地址
        alipay_request.setNotifyUrl(C3mOrder.REQUEST_URL + param.getPoleId() + "/" + new Date().getTime());
        // è®¾ç½®åŒæ­¥åœ°å€
        alipay_request.setReturnUrl(C3mOrder.REQUEST_URL + param.getPoleId() + "/" + new Date().getTime());
        // form表单生产
        String form = "";
        try {
            // è°ƒç”¨SDK生成表单
            form = client.pageExecute(alipay_request).getBody();
            response.setContentType("text/html;charset=" + AlipayConfig.charset);
            response.getWriter().write(form);//直接将完整的表单html输出到页面
            response.getWriter().flush();
            response.getWriter().close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ResponseUtil.success("支付完成");
    }
//    @RequestMapping("/wxpay")
//    public ResponseVO<Object> c3Wxpay(@RequestBody PayParam param) {
//
//        //String result = wxPayService.miniAppPay(outTradeNo, totalAmount, streetlightId);
//        SortedMap<Object, Object> result = wxPayService.appPay("扫码充电支付(C3充电桩)", param.getOutTradeNo(), param.getWxPayTotalAmount(), param.getPoleId(),c3mOrderEntity);
//
//        return ResponseUtil.success(result);
//    }
    /**
     * è®¢å•状态查询  å¾®ä¿¡æ”¯ä»˜
     *
     * @param param
     * @return
     */
    @RequestMapping("/queryOrder")
    public ResponseVO<Object> queryOrder(@RequestBody PayParam param) {
        if (param.getOrderId() == null) {
@@ -180,4 +112,13 @@
    }
    /**
     * è®¢å•列表
     */
    @GetMapping("/list")
    public ResponseVO<Object> list(BaseConditionVO baseConditionVO) {
        List<C3mOrderBo> list = c3mOrderService.orderList(baseConditionVO);
        return ResponseUtil.successPage(list);
    }
}
ximon-admin/src/main/java/com/sandu/ximon/admin/param/PayParam.java
@@ -19,6 +19,11 @@
    private Double totalAmount;
    /**
     * ç”¨æˆ·æ ‡è¯†
     */
    private  String user_code;
    /**
     * å¾®ä¿¡æ”¯ä»˜é‡‘额
     */
    private Integer WxPayTotalAmount;
@@ -28,7 +33,14 @@
     */
    private Integer subscribeChargingCapacity;
    private Long orderId;
    /**
     * é€€æ¬¾æ—¶ä½¿ç”¨
     */
    private Double refundAmount;
    private String outTradeNo;
    private Long orderId;
}
ximon-admin/src/main/java/com/sandu/ximon/admin/pay/wx/WxFastPayService.java
@@ -10,6 +10,7 @@
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
import com.github.binarywang.wxpay.bean.result.WxPayRefundResult;
import com.github.binarywang.wxpay.bean.result.WxPayUnifiedOrderResult;
import com.github.binarywang.wxpay.config.WxPayConfig;
import com.github.binarywang.wxpay.constant.WxPayConstants;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.sandu.common.execption.BusinessException;
@@ -19,6 +20,7 @@
import com.sandu.ximon.dao.domain.WxConfigEntity;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -43,75 +45,6 @@
    private final UsrWxPayConfigService wxPayConfigService;
    /**
     * app支付
     *
     * @param body     å•†å“æè¿°
     * @param
     * @param totalFee æ”¯ä»˜é‡‘额(分)
     * @return
     */
    public SortedMap<Object, Object> appPay(String body, String orderSn, int totalFee, Long poleId) {
        WxConfigEntity wxConfig = wxPayConfigService.getConfigByPoleId(poleId);
        wxConfig.setMchId(wxConfig.getMchId().trim());
        WxPayUnifiedOrderRequest wxPayUnifiedOrderRequest = new WxPayUnifiedOrderRequest();
        wxPayUnifiedOrderRequest.setBody(body);
        wxPayUnifiedOrderRequest.setOutTradeNo(orderSn);
        wxPayUnifiedOrderRequest.setTotalFee(totalFee);
        wxPayUnifiedOrderRequest.setOpenid("otiM54x_hc_5gbhMY5aZxo7UByNo");
        wxPayUnifiedOrderRequest.setSignType(WxPayConstants.SignType.MD5);
        wxPayUnifiedOrderRequest.setSpbillCreateIp(IpUtil.getRealIp());
        wxPayUnifiedOrderRequest.setNotifyUrl(WECHAT_ORDER_PAY_CALLBACK_URL);
        wxPayUnifiedOrderRequest.setTradeType(WxPayConstants.TradeType.JSAPI);
        try {
            WxPayUnifiedOrderResult wxPayUnifiedOrderResult = wxPayService.unifiedOrder(wxPayUnifiedOrderRequest);
            System.out.println("********************************");
            String time = String.valueOf(System.currentTimeMillis() / 1000);
            if (WxPayConstants.ResultCode.SUCCESS.equals(wxPayUnifiedOrderResult.getResultCode())) {
                SortedMap<Object, Object> parameters = new TreeMap<>();
                parameters.put("appid", wxPayUnifiedOrderResult.getAppid());
                parameters.put("noncestr", wxPayUnifiedOrderResult.getNonceStr()); // éšæœºå­—符串
                parameters.put("partnerid", wxConfig.getMchId()); // å•†æˆ·id
                //  parameters.put("out_trade_no", orderId);//商户订单号
                parameters.put("prepayid", wxPayUnifiedOrderResult.getPrepayId());
                parameters.put("package", "Sign=WXPay");
                parameters.put("timestamp", time);
                String sign = createSign(wxConfig.getPrivateKey(), parameters);
                //hashMap.put("paySign", wechatSign);
                parameters.put("Sign", sign);
                return parameters;
            } else {
                log.error("微信支付失败,{}", wxPayUnifiedOrderResult.getErrCodeDes());
                throw new BusinessException("微信支付失败," + wxPayUnifiedOrderResult.getErrCodeDes());
            }
        } catch (WxPayException e) {
            log.error("微信支付失败,{}", e.getErrCodeDes());
            throw new BusinessException("微信支付失败," + e.getErrCodeDes());
        }
    }
    /*    private String createSign(SortedMap<Object, Object> parameters) {
            StringBuffer sb = new StringBuffer();
            Set es = parameters.entrySet();// æ‰€æœ‰å‚与传参的参数按照accsii排序(升序)
            for (Object e : es) {
                Map.Entry entry = (Map.Entry) e;
                String k = (String) entry.getKey();
                Object v = entry.getValue();
                if (null != v && !"".equals(v) && !"sign".equals(k) && !"key".equals(k)) {
                    sb.append(k + "=" + v + "&");
                }
            }
            sb.append("key=" + wxPayProperties.getMchKey());
            System.out.println("字符串拼接后是:" + sb.toString());
            return SecureUtil.md5(sb.toString()).toUpperCase();
        }*/
    /**
@@ -207,38 +140,6 @@
    /**
     * ç”ŸæˆäºŒç»´ç ä»˜æ¬¾
     */
    public String generateQRCodePay(String body,
                                    String orderId, int totalFee, String callbackUrl) {
        WxPayUnifiedOrderRequest wxPayUnifiedOrderRequest = new WxPayUnifiedOrderRequest();
        wxPayUnifiedOrderRequest.setBody(body);
        wxPayUnifiedOrderRequest.setOutTradeNo(orderId);
        wxPayUnifiedOrderRequest.setTotalFee(totalFee);
        wxPayUnifiedOrderRequest.setProductId(orderId);
        wxPayUnifiedOrderRequest.setSignType(WxPayConstants.SignType.MD5);
        wxPayUnifiedOrderRequest.setSpbillCreateIp(IpUtil.getRealIp());
        wxPayUnifiedOrderRequest.setNotifyUrl(callbackUrl);
        wxPayUnifiedOrderRequest.setTradeType(WxPayConstants.TradeType.NATIVE);
        try {
            WxPayUnifiedOrderResult wxPayUnifiedOrderResult = wxPayService.unifiedOrder(wxPayUnifiedOrderRequest);
            if (WxPayConstants.ResultCode.SUCCESS.equals(wxPayUnifiedOrderResult.getResultCode())) {
                byte[] scanPayQrcodeMode2 = wxPayService.createScanPayQrcodeMode2(wxPayUnifiedOrderResult.getCodeURL(), null, null);
                String encode = Base64.encode(scanPayQrcodeMode2);
                return encode;
            } else {
                log.error("微信支付失败,{}", wxPayUnifiedOrderResult.getErrCodeDes());
                throw new BusinessException("微信支付失败," + wxPayUnifiedOrderResult.getErrCodeDes());
            }
        } catch (WxPayException e) {
            log.error("微信支付失败,{}", e.getErrCodeDes());
            throw new BusinessException("微信支付失败," + e.getErrCodeDes());
        }
    }
    /**
     * é€€æ¬¾
     *
     * @param totalAmount
@@ -247,11 +148,16 @@
     * @param poleId
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean refund(Double totalAmount, Double refundAmount, String outTradeNo, Long poleId) {
        WxConfigEntity wxConfig = UsrWxPayConfigService.getBean().getConfigByPoleId(poleId);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        String refundNo = sdf.format(new Date());
        WxPayRefundRequest refundRequest = new WxPayRefundRequest();
        //退款金额不能大于订单总金额
        if (refundAmount > totalAmount) {
            throw new BusinessException("退款金额不能大于订单总金额");
        }
        refundRequest.setOutTradeNo(outTradeNo);
        refundRequest.setOutRefundNo(refundNo);
        refundRequest.setTotalFee(Integer.valueOf(parseWxAmount((totalAmount + ""))));
@@ -285,24 +191,44 @@
        return amount;
    }
    /**
     * å°ç¨‹åºæ”¯ä»˜  å¾®ä¿¡
     *
     * @param body
     * @param orderId
     * @param totalFee
     * @param poleId
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public SortedMap<Object, Object> miniAppPay(String body,
                                                String orderId, int totalFee, Long poleId) {
        WxConfigEntity wxConfig = wxPayConfigService.getConfigByPoleId(poleId);
        wxConfig.setMchId(wxConfig.getMchId().trim());
        //设置微信支付参数
        WxPayConfig payConfig = new WxPayConfig();
        payConfig.setAppId(StringUtils.trimToNull(wxConfig.getAppid()));
        payConfig.setMchId(StringUtils.trimToNull(wxConfig.getMchId()));
        payConfig.setMchKey(StringUtils.trimToNull(wxConfig.getPrivateKey()));
        payConfig.setSubAppId(StringUtils.trimToNull(null));
        payConfig.setSubMchId(StringUtils.trimToNull(null));
        payConfig.setKeyPath(StringUtils.trimToNull(null));
        wxPayService.setConfig(payConfig);
        //设置微信同一订单请求
        WxPayUnifiedOrderRequest wxPayUnifiedOrderRequest = new WxPayUnifiedOrderRequest();
        wxPayUnifiedOrderRequest.setBody(body);
        wxPayUnifiedOrderRequest.setOutTradeNo(orderId);
        wxPayUnifiedOrderRequest.setTotalFee(totalFee);
        wxPayUnifiedOrderRequest.setOpenid("otiM54x_hc_5gbhMY5aZxo7UByNo");
//        wxPayUnifiedOrderRequest.setOpenid("otiM54x_hc_5gbhMY5aZxo7UByNo");
        wxPayUnifiedOrderRequest.setSignType(WxPayConstants.SignType.MD5);
        wxPayUnifiedOrderRequest.setSpbillCreateIp(IpUtil.getRealIp());
        wxPayUnifiedOrderRequest.setNotifyUrl(WECHAT_ORDER_PAY_CALLBACK_URL);
        wxPayUnifiedOrderRequest.setTradeType(WxPayConstants.TradeType.JSAPI);
        System.out.println("-----------"+wxPayUnifiedOrderRequest);
        System.out.println("-----------" + wxPayUnifiedOrderRequest);
        try {
            WxPayUnifiedOrderResult wxPayUnifiedOrderResult = wxPayService.unifiedOrder(wxPayUnifiedOrderRequest);
            String time = String.valueOf(System.currentTimeMillis() / 1000);
ximon-admin/src/main/java/com/sandu/ximon/admin/pay/wx/WxPayConfiguration.java
@@ -14,30 +14,30 @@
/**
 * @author Binary Wang
 */
//@Configuration
//@ConditionalOnClass(WxPayService.class)
//@EnableConfigurationProperties(WxPayProperties.class)
//@AllArgsConstructor
//public class WxPayConfiguration {
//  private WxPayProperties properties;
//
//  @Bean
//  @ConditionalOnMissingBean
//  public WxPayService wxService() {
//    WxPayConfig payConfig = new WxPayConfig();
//    payConfig.setAppId(StringUtils.trimToNull(this.properties.getAppId()));
//    payConfig.setMchId(StringUtils.trimToNull(this.properties.getMchId()));
//    payConfig.setMchKey(StringUtils.trimToNull(this.properties.getMchKey()));
//    payConfig.setSubAppId(StringUtils.trimToNull(this.properties.getSubAppId()));
//    payConfig.setSubMchId(StringUtils.trimToNull(this.properties.getSubMchId()));
//    payConfig.setKeyPath(StringUtils.trimToNull(this.properties.getKeyPath()));
//
//    // å¯ä»¥æŒ‡å®šæ˜¯å¦ä½¿ç”¨æ²™ç®±çŽ¯å¢ƒ
//    payConfig.setUseSandboxEnv(false);
//
//    WxPayService wxPayService = new WxPayServiceImpl();
@Configuration
@ConditionalOnClass(WxPayService.class)
@EnableConfigurationProperties(WxPayProperties.class)
@AllArgsConstructor
public class WxPayConfiguration {
  private WxPayProperties properties;
  @Bean
  @ConditionalOnMissingBean
  public WxPayService wxService() {
    WxPayConfig payConfig = new WxPayConfig();
    payConfig.setAppId(StringUtils.trimToNull(this.properties.getAppId()));
    payConfig.setMchId(StringUtils.trimToNull(this.properties.getMchId()));
    payConfig.setMchKey(StringUtils.trimToNull(this.properties.getMchKey()));
    payConfig.setSubAppId(StringUtils.trimToNull(this.properties.getSubAppId()));
    payConfig.setSubMchId(StringUtils.trimToNull(this.properties.getSubMchId()));
    payConfig.setKeyPath(StringUtils.trimToNull(this.properties.getKeyPath()));
    // å¯ä»¥æŒ‡å®šæ˜¯å¦ä½¿ç”¨æ²™ç®±çŽ¯å¢ƒ
    payConfig.setUseSandboxEnv(false);
    WxPayService wxPayService = new WxPayServiceImpl();
//    wxPayService.setConfig(payConfig);
//    return wxPayService;
//  }
//
//}
    return wxPayService;
  }
}
ximon-admin/src/main/java/com/sandu/ximon/admin/service/C3mChargingChargeService.java
@@ -14,6 +14,8 @@
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.time.LocalTime;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
@@ -167,4 +169,50 @@
    public boolean deleteC3mCharging(Integer c3mId) {
        return c3mChargingChargeMapper.deleteCharge(c3mId);
    }
    /**
     * æ ¹æ®c3Id查找费率  å¹¶è®¡ç®—花费
     *
     * @param c3Id
     * @return
     */
    public BigDecimal getCostByC3id(Long c3Id, Integer power) {
        List<C3mChargingCharge> list = list(Wrappers.lambdaQuery(C3mChargingCharge.class).eq(C3mChargingCharge::getC3Id, c3Id));
        //获取当前时间
        LocalTime localTime = LocalTime.now();
        //遍历费率集合  åˆ¤æ–­å½“前时间是否在费率时间段内
        LocalTime startTime;
        LocalTime endTime;
        //默认费率
        Double charge = 8.8;
        if (list.size() > 1) {
            //费率条数大于1时,遍历费率集合  èŽ·å–å½“å‰æ—¶é—´æ®µçš„è´¹çŽ‡
            for (int i = 0; i < list.size(); i++) {
                //获取费率时间段  è½¬åŒ–为LocalTime
                startTime = LocalTime.of(list.get(i).getHour(), list.get(i).getMin());
                endTime = LocalTime.of(list.get(i + 1).getHour(), list.get(i + 1).getMin());
                if (i == list.size()) {
                    startTime = LocalTime.of(list.get(i).getHour(), list.get(i).getMin());
                    endTime = LocalTime.of(list.get(0).getHour(), list.get(0).getMin());
                }
                //判断当前时间是否在费率时间段内
                if (localTime.isAfter(startTime) && localTime.isBefore(endTime)) {
                    //获取费率
                    charge = list.get(i).getCharge();
                }
            }
        } else if (list.size() == 1) {
            //只有一条费率时,直接获取费率
            charge = list.get(0).getCharge();
        } else {
            //其他费率时,获取默认费率
            charge = 8.8;
        }
        //计算花费  è´¹çއ*电量
        BigDecimal chargeDecimal = new BigDecimal(charge);
        BigDecimal powerDecimal = new BigDecimal(power);
        BigDecimal result = chargeDecimal.multiply(powerDecimal);
        return result;
    }
}
ximon-admin/src/main/java/com/sandu/ximon/admin/service/C3mOrderService.java
@@ -1,32 +1,35 @@
package com.sandu.ximon.admin.service;
import com.alibaba.fastjson.JSON;
import cn.hutool.core.lang.Snowflake;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.binarywang.wxpay.bean.notify.WxPayNotifyResponse;
import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
import com.github.pagehelper.PageHelper;
import com.sandu.common.execption.BusinessException;
import com.sandu.common.object.BaseConditionVO;
import com.sandu.common.service.impl.BaseServiceImpl;
import com.sandu.ximon.admin.config.C3mRedisConfig;
import com.sandu.ximon.admin.manager.iot.rrpc.enums.C3mRedisConstant;
import com.sandu.ximon.admin.pay.OrderStatusEnums;
import com.sandu.ximon.admin.pay.wx.WxFastPayService;
import com.sandu.ximon.admin.security.SecurityUtils;
import com.sandu.ximon.admin.security.order.OrderQueryListener;
import com.sandu.ximon.admin.security.order.OrderScanType;
import com.sandu.ximon.admin.utils.AliPayUtils;
import com.sandu.ximon.admin.utils.RedisUtils;
import com.sandu.ximon.admin.vo.C3mOrderVO;
import com.sandu.ximon.dao.bo.C3mOrderBo;
import com.sandu.ximon.dao.domain.C3mCharging;
import com.sandu.ximon.dao.domain.C3mOrder;
import com.sandu.ximon.dao.domain.Pole;
import com.sandu.ximon.admin.manager.iot.rrpc.enums.C3mRedisConstant;
import com.sandu.ximon.dao.enums.OrderStatus;
import com.sandu.ximon.dao.enums.OrderType;
import com.sandu.ximon.dao.mapper.C3mOrderMapper;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Date;
import java.util.List;
/**
 * @Author liuhaonan
@@ -42,6 +45,7 @@
    private final C3mOrderMapper c3mOrderMapper;
    private final WxFastPayService fastPayService;
    private final OrderQueryListener orderQueryListener;
    private final Snowflake snowflake;
    public boolean orderRefund(String outTradeNo, Double refundAmount/*, Long userId, String username*/) {
        Long userId = SecurityUtils.getUserId();
@@ -50,8 +54,8 @@
        if (orderByOutTradeNo.getTotalAmount() < refundAmount) {
            throw new BusinessException("退款金额错误,不能大于付款金额");
        }
        if (null == orderByOutTradeNo) {
            return false;
        if (orderByOutTradeNo == null) {
            throw new BusinessException("未找到订单");
        } else {
            orderByOutTradeNo.setRefundAmount(refundAmount);
            return c3mOrderRefund(orderByOutTradeNo, "充电桩退款", userId, username);
@@ -61,6 +65,16 @@
    }
    /**
     * é€€æ¬¾
     *
     * @param C3mOrder
     * @param msg
     * @param userId
     * @param username
     * @return
     */
//    @Transactional(rollbackFor = Exception.class)
    private boolean c3mOrderRefund(C3mOrder C3mOrder, String msg, Long userId, String username) {
        //  è¿›è¡Œé€€æ¬¾ï¼Œè®¾ç½®è®¢å•状态为已退款
        boolean b = false;
@@ -109,6 +123,16 @@
        }
    }
    /**
     * åˆ›å»ºè®¢å•
     *
     * @param streetlightId
     * @param c3m
     * @param orderType
     * @param totalAmount
     * @param subscribeChargingCapacity
     * @return
     */
    public C3mOrder advancePayOrder(Long streetlightId, C3mCharging c3m, String orderType, Double totalAmount,
                                    Integer subscribeChargingCapacity) {
@@ -131,16 +155,26 @@
                subscribeChargingCapacity
        );
        //  åŠ è½½åˆ°redis缓存中, æŸ¥è¯¢æ¨¡å—自动查询状态并处理
        boolean b = redisUtils.set(
                C3mRedisConstant.C3_NO_PAY_ORDER.getCode() + c3m.getC3Mac() + c3mOrderEntity.getOutTradeNo(),
                JSON.toJSONString(c3mOrderEntity),
                C3mRedisConfig.ORDER_MAX_TIME
        );
//        boolean b = redisUtils.set(
//                C3mRedisConstant.C3_NO_PAY_ORDER.getCode() + c3m.getC3Mac() + c3mOrderEntity.getOutTradeNo(),
//                JSON.toJSONString(c3mOrderEntity),
//                C3mRedisConfig.ORDER_MAX_TIME  // TODO  æµ‹è¯•时关闭
//        );
        boolean b = true;
        c3mOrderEntity.setOrderId(snowflake.nextId());
        c3mOrderEntity.setC3Mac(c3m.getC3Name());
        c3mOrderEntity.setPoleId(streetlightId);
        c3mOrderEntity.setPoleMac(pole.getDeviceCode());
        c3mOrderEntity.setPoleName(pole.getPoleName());
        c3mOrderEntity.setC3Mac(c3m.getC3Mac());
        c3mOrderEntity.setOrderStatus(0);
        //  æŽ¨é€åˆ°è‡ªåŠ¨æŸ¥è¯¢æ¨¡å—ï¼Œè¿›è¡Œæ‰«æå¯åŠ¨
        orderQueryListener.startScan(OrderScanType.C3M.getType());
//        if(b){
//            save(c3mOrderEntity);
//        }
//        orderQueryListener.startScan(OrderScanType.C3M.getType());   // TODO  æµ‹è¯•时关闭
        if (b) {
            this.save(c3mOrderEntity);
        }
        return b ? c3mOrderEntity : null;
    }
@@ -167,14 +201,35 @@
        if (!updateById(userOrder)) {
            return WxPayNotifyResponse.fail("更新数据已失效");
        }
        /**
         * è°ƒèµ·å¼€å§‹å……电接口  // TODO
         */
        return WxPayNotifyResponse.success("更新数据成功");
    }
    /**
     * è®¢å•详情  by orderSn
     *
     * @param orderSn
     * @return
     */
    public C3mOrder getByOrderSn(String orderSn) {
        LambdaQueryWrapper<C3mOrder> wrapper = Wrappers.lambdaQuery(C3mOrder.class).eq(C3mOrder::getOutTradeNo, orderSn).last("limit 1");
        return getOne(wrapper);
    }
    /**
     * è®¢å•列表
     *
     * @param baseConditionVO
     * @return
     */
    public List<C3mOrderBo> orderList(BaseConditionVO baseConditionVO) {
        Long userId = SecurityUtils.getClientId();
        PageHelper.startPage(baseConditionVO.getPageNo(), baseConditionVO.getPageSize());
        List<C3mOrderBo> list = baseMapper.orderList(userId);
        return list;
    }
}
ximon-admin/src/main/resources/application.yml
@@ -1,6 +1,6 @@
spring:
  profiles:
       active: dev
       active: local
  jackson:
    date-format: yyyy-MM-dd HH:mm:ss
    time-zone: GMT+8
@@ -22,6 +22,11 @@
logging:
  file:
    path: logs
wx:
  pay:
    appId: dsd #微信公众号或者小程序等的appid
    mchId: dsdsd #微信支付商户号
    mchKey: dsd #微信支付商户密钥
# led屏幕服务器地址(更改需要同时更改)