记得上下班打卡 | git大法好,push需谨慎

Commit 92bb4c12 authored by 姜秀龙's avatar 姜秀龙

Merge branch 'jxl-lixianzhifu' into 'master'

Jxl lixianzhifu

See merge request !392
parents 0c1a0c2e 412ad6f7
......@@ -356,6 +356,20 @@ public class GoblinRedisConst {
public static final String GOBLIN_MIX_RESERVE_UID = PREFIX.concat("mix:reserve:uid:");//$mixId:$uid 混合售用户预约保存
// 迈之
// 充值配置的需要充值金额的列表
public static final String GOBLIN_RECHARGE_WRISTBAND = PREFIX.concat("recharge:wristband");
// 迈之的accessToken
public static final String GOBLIN_RECHARGE_MAIZHI_TOKEN = PREFIX.concat("recharge:maizhitoken");
// 获取设备编号定时任务最后一次的时间
public static final String GOBLIN_RECHARGE_DEVICE_NUMBER_ENDTIME = PREFIX.concat("recharge:deviceNumber:endtime:operationNo:");
// 通过分订单号获取订单 id
public static final String GOBLIN_RECHARGE_FOUT_TRADE_NO = PREFIX.concat("recharge:foutTradeNo:");
// 手环订单
public static final String GOBLIN_BRACELET_ORDERID = PREFIX.concat("bracelet:orderId:");
public static final String GOBLIN_BRACELET_RELATED_ORDER = PREFIX.concat("bracelet:reqSeqId:");
/* ----------------------------------------------------------------- */
public static final String GOBLIN_ORDER_LOG = PREFIX.concat("order:log:");//无用
......
package com.liquidnet.service.goblin.dto.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.liquidnet.commons.lang.util.DateUtil;
import com.liquidnet.service.goblin.entity.GoblinBraceletOrder;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.springframework.beans.BeanUtils;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDateTime;
/**
* 手环-订单VO
*/
@Data
@EqualsAndHashCode(callSuper = false)
@ApiModel(value = "手环订单vo")
public class GoblinBraceletOrderVo implements Serializable, Cloneable {
private static final long serialVersionUID = 1L;
/**
* 订单ID
*/
@ApiModelProperty(value = "订单ID")
private String orderId;
/**
* 用户ID
*/
@ApiModelProperty(value = "用户ID")
private String userId;
/**
* 绑定用户姓名
*/
@ApiModelProperty(value = "绑定用户姓名")
private String bindName;
/**
* 绑定用户手机号
*/
@ApiModelProperty(value = "绑定用户手机号")
private String bindMobile;
/**
* 绑定用户身份证号码
*/
@ApiModelProperty(value = "绑定用户身份证号码")
private String bindIdcard;
/**
* 请求日期
*/
@ApiModelProperty(value = "请求日期")
private String reqDate;
/**
* 商品描述
*/
@ApiModelProperty(value = "商品描述")
private String goodsDesc;
/**
* 手环ID
*/
@ApiModelProperty(value = "手环ID")
private String wristbandId;
/**
*手环金额
*/
@ApiModelProperty(value = "手环金额")
private BigDecimal wristbandPrice;
/**
*充值金额ID
*/
@ApiModelProperty(value = "充值金额ID")
private String amountId;
/**
*充值金额
*/
@ApiModelProperty(value = "充值金额")
private BigDecimal amountPrice;
/**
* 请求流水号
*/
@ApiModelProperty(value = "请求流水号")
private String reqSeqId;
/**
* 全局流水号
*/
@ApiModelProperty(value = "全局流水号")
private String hfSeqId;
/**
* 交易类型:
* T_JSAPI: 微信公众号支付
* T_MINIAPP: 微信小程序支付
* A_JSAPI: 支付宝JS
* A_NATIVE: 支付宝正扫
* U_NATIVE: 银联正扫
* U_JSAPI: 银联 JS
* D_NATIVE: 数字人民币正扫
* T_H5:微信直连H5支付
* T_APP:微信APP支付
* T_NATIVE:微信正扫
*/
@ApiModelProperty(value = "交易类型")
private String tradeType;
/**
* 用户账单上的交易订单号
*/
@ApiModelProperty(value = "用户账单上的交易订单号")
private String outTransId;
/**
* 用户账单上的商户订单号
*/
@ApiModelProperty(value = "用户账单上的商户订单号")
private String partyOrderId;
/**
* 支付完成时间 格式yyyyMMddHHmmss
*/
@ApiModelProperty(value = "支付完成时间 格式yyyyMMddHHmmss")
private String endTime;
/**
* 入账时间 格式为yyyyMMdd
*/
@ApiModelProperty(value = "入账时间 格式为yyyyMMdd")
private String acctDate;
/**
* 单价
*/
@ApiModelProperty(value = "单价")
private BigDecimal price;
/**
* 应付价格
*/
@ApiModelProperty(value = "应付价格")
private BigDecimal priceTotal;
/**
* 实付价格
*/
@ApiModelProperty(value = "实付价格")
private BigDecimal priceActual;
/**
* 退款价格
*/
@ApiModelProperty(value = "退款价格")
private BigDecimal priceRefund;
/**
* 退款扣除的手续费金额
*/
@ApiModelProperty(value = "退款扣除的手续费金额")
private BigDecimal refundPriceCharges;
/**
* 退款数
*/
@ApiModelProperty(value = "退款数")
private Integer refundNumber;
/**
* 支付时间
*/
@ApiModelProperty(value = "支付时间")
private String timePay;
/**
* 订单状态:
* 0 待付款
* 1 已付款
* 2 已关闭
* 3 正在退款
* 4 已退款
* 5 待关闭
* 6 部分退款
* 7 退款失败
*/
@ApiModelProperty(value = "订单状态")
private Integer status;
/**
* 支付状态:
* 0 未支付
* 1 已支付
* 2 支付失败
*/
@ApiModelProperty(value = "支付状态")
private Integer payStatus;
/**
* 迈之的分订单号
*/
@ApiModelProperty(value = "迈之的分订单号")
private String foutTradeNo;
/**
* 迈之的设备编号
*/
@ApiModelProperty(value = "迈之的设备编号")
private String cardno;
/**
* 迈之的分订单号
*/
@ApiModelProperty(value = "迈之的分订单号")
private Integer refundStatus;
/**
* 迈之的设备编号
*/
@ApiModelProperty(value = "迈之的设备编号")
private String refundStatusNote;
/**
* 创建时间
*/
@ApiModelProperty(value = "创建时间")
private LocalDateTime createdAt;
/**
* 更新时间
*/
@ApiModelProperty(value = "更新时间")
private LocalDateTime updatedAt;
private static final GoblinBraceletOrderVo obj = new GoblinBraceletOrderVo();
public static GoblinBraceletOrderVo getNew() {
try {
return (GoblinBraceletOrderVo) obj.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return new GoblinBraceletOrderVo();
}
public GoblinBraceletOrderVo copy(GoblinBraceletOrder goblinBraceletOrder){
if (goblinBraceletOrder == null) return this;
BeanUtils.copyProperties(goblinBraceletOrder, this);
return this;
}
}
package com.liquidnet.service.goblin.dto.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
import java.math.BigDecimal;
@Data
@EqualsAndHashCode(callSuper = false)
@ApiModel(value = "手环下单结果vo")
public class GoblinBraceletPayResultVo implements Serializable, Cloneable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(position = 1, value = "订单ID")
private String orderId;
@ApiModelProperty(position = 3, value = "价格")
private BigDecimal price;
@ApiModelProperty(position = 5, value = "三方支付信息")
private Object payInfo;
private static final GoblinBraceletPayResultVo obj = new GoblinBraceletPayResultVo();
public static GoblinBraceletPayResultVo getNew() {
try {
return (GoblinBraceletPayResultVo) obj.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return new GoblinBraceletPayResultVo();
}
}
package com.liquidnet.service.goblin.dto.vo;
import lombok.Data;
/**
*
*/
@Data
public class GoblinBraceletRelatedOrderVo {
// 用户ID
private String uid;
// 手环订单ID
private String orderId;
// 调用斗拱请求ID
private String reqSeqId;
}
package com.liquidnet.service.goblin.dto.vo;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
import java.math.BigDecimal;
@Data
@EqualsAndHashCode(callSuper = false)
public class GoblinRechargeAmountVo implements Serializable, Cloneable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = " 金额ID")
private String amountId;
@ApiModelProperty(value = "金额名称")
private String name;
@ApiModelProperty(value = "充值金额")
private BigDecimal price;
private final static GoblinRechargeAmountVo obj = new GoblinRechargeAmountVo();
public static GoblinRechargeAmountVo getNew() {
try {
return (GoblinRechargeAmountVo) obj.clone();
} catch (CloneNotSupportedException e) {
return new GoblinRechargeAmountVo();
}
}
}
package com.liquidnet.service.goblin.dto.vo;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.List;
@Data
@EqualsAndHashCode(callSuper = false)
public class GoblinRechargeWristbandVo implements Serializable, Cloneable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = " 手环ID")
private String wristbandId;
@ApiModelProperty(value = "手环名称")
private String name;
@ApiModelProperty(value = "手环价格")
private BigDecimal price;
@ApiModelProperty(value = "充值金额")
private List<GoblinRechargeAmountVo> amonutList;
private final static GoblinRechargeWristbandVo obj = new GoblinRechargeWristbandVo();
public static GoblinRechargeWristbandVo getNew() {
try {
return (GoblinRechargeWristbandVo) obj.clone();
} catch (CloneNotSupportedException e) {
return new GoblinRechargeWristbandVo();
}
}
}
package com.liquidnet.service.goblin.dto.vo;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.math.BigDecimal;
import java.util.List;
/**
* <p>
* xx 服务实现类
* </p>
*
* @author jiangxiulong
* @since 2025-07-03 17:38
*/
@Data
@EqualsAndHashCode(callSuper = false)
public class MaiZhiAllVo {
// 基础响应类
@Data
public static class BaseResponse<T> {
private String msg;
private Integer errcode;
private T data;
}
// 登录授权
@Data
public static class AuthParam {
private String appid;
private String appSecret;
}
@Data
public static class AuthResponse extends BaseResponse<AuthResponse.DataRes> {
@Data
public static class DataRes {
private String accessToken;
private Integer expire;
}
}
// 实名
@Data
public static class IdCardParam {
@ApiModelProperty(value = "姓名")
private String name;
@ApiModelProperty(value = "身份证")
private String idcard;
}
@Data
public static class CheckIdcardResponse {
private String message;
private String msg;
private Integer result;
private String resultDesc;
private Integer gender;
private Integer age;
private String area;
private Integer errcode;
}
// 新增订单
@Data
public static class OrderParam implements Cloneable {
private String operationNo;
private String out_trade_no;
private String dgoid;
private BigDecimal receipt_amount;
private Integer total;
private String payTime;
private List<User> userList;
@Data
public static class User implements Cloneable {
private String name;
private String phone;
private String idcard;
private BigDecimal money;
private static final User obj = new User();
public static User getNew() {
try {
return (User) obj.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return new User();
}
}
private static final OrderParam obj = new OrderParam();
public static OrderParam getNew() {
try {
return (OrderParam) obj.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return new OrderParam();
}
}
@Data
public static class OrderResponse extends BaseResponse<String> {
}
// 订单查询
@Data
public static class OrderInfoParam implements Cloneable {
private List<String> orderList;
private static final OrderInfoParam obj = new OrderInfoParam();
public static OrderInfoParam getNew() {
try {
return (OrderInfoParam) obj.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return new OrderInfoParam();
}
}
@Data
public static class OrderInfoResponse {
private Integer errcode;
private List<OrderList> outlist;
@Data
public static class OrderList {
private String out_trade_no;
private Integer status;
private BigDecimal receipt_amount;
private String time;
private List<UserOrder> user_order;
@Data
public static class UserOrder {
private String fout_trade_no;
private Integer status;
private String name;
private String phone;
private String idcard;
private BigDecimal money;
}
}
}
// 核销码
@Data
public static class GenerateDeviceCodeResponse {
private String qrcode_str;
private Integer errcode;
}
// 设备编号获取
@Data
public static class DeviceNumberResponse {
private List<NumberList> list;
private Integer errcode;
@Data
public static class NumberList {
private String fout_trade_no;
private String cardno;
}
}
// 设备余额
@Data
public static class DeviceBalanceResponse {
private String cardno;
private BigDecimal money;
private String time;
private String msg;
private Integer errcode;
}
// 设备记录查询
@Data
public static class DeviceRecordResponse {
private List<Record> list;
private String msg;
private Integer errcode;
private String cardno;
private Integer total;
private Integer page;
@Data
public static class Record {
private String note;
private BigDecimal amt;
private BigDecimal ftbal;
private String time;
}
}
// 变更设备状态
@Data
public static class ChangeDeviceStatusResponse implements Cloneable {
private String msg;
private Integer errcode;
private Integer status;
private String note;
private static final ChangeDeviceStatusResponse obj = new ChangeDeviceStatusResponse();
public static ChangeDeviceStatusResponse getNew() {
try {
return (ChangeDeviceStatusResponse) obj.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return new ChangeDeviceStatusResponse();
}
}
}
package com.liquidnet.service.goblin.enums;
/**
* 订单状态枚举
*/
public enum OrderStatus {
PENDING_PAYMENT(0, "待付款"),
PAID(1, "已付款"),
CLOSED(2, "已关闭"),
REFUNDING(3, "正在退款"),
REFUNDED(4, "已退款"),
PENDING_CLOSE(5, "待关闭"),
PARTIAL_REFUND(6, "部分退款");
private final int code;
private final String description;
OrderStatus(int code, String description) {
this.code = code;
this.description = description;
}
public int getCode() {
return code;
}
public String getDescription() {
return description;
}
// 通过code获取对应的枚举值
public static OrderStatus fromCode(int code) {
for (OrderStatus status : values()) {
if (status.getCode() == code) {
return status;
}
}
throw new IllegalArgumentException("无效的状态码: " + code);
}
}
package com.liquidnet.service.goblin.enums;
/**
* 支付状态枚举
*/
public enum PayStatus {
NOT_PAID(0, "未支付"),
PAID(1, "已支付"),
PAYMENT_FAILED(2, "支付失败");
private final int code;
private final String description;
PayStatus(int code, String description) {
this.code = code;
this.description = description;
}
public int getCode() {
return code;
}
public String getDescription() {
return description;
}
// 根据 code 获取枚举实例
public static PayStatus fromCode(int code) {
for (PayStatus status : values()) {
if (status.getCode() == code) {
return status;
}
}
throw new IllegalArgumentException("无效的支付状态码: " + code);
}
@Override
public String toString() {
return description;
}
}
package com.liquidnet.service.goblin.param;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import java.io.Serializable;
@ApiModel(value = "GoblinBraceletOrderPayParam", description = "手环下单请求参数")
@Data
public class GoblinBraceletOrderPayParam implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "手环ID")
@NotBlank(message = "wristbandId不能为空")
private String wristbandId;
@ApiModelProperty(value = "金额ID")
@NotBlank(message = "金额ID不能为空")
private String amountId;
@ApiModelProperty(value = "姓名")
@NotBlank(message = "绑定姓名不能为空")
private String name;
@ApiModelProperty(value = "手机号")
@NotBlank(message = "绑定手机号不能为空")
private String mobile;
@ApiModelProperty(value = "身份证号码")
@NotBlank(message = "绑定身份证号码不能为空")
private String idCard;
@ApiModelProperty(value = "子商户用户标识")
@NotBlank(message = "openId不能为空")
private String subOpenId;
}
package com.liquidnet.service.goblin.param.dougong;
import lombok.Data;
import java.util.List;
/**
* 调用斗拱业务层参数
*/
@Data
public class DougongJsPayData {
// 请求日期
private String reqDate;
// 请求流水号
private String reqSeqId;
// 交易类型
private String tradeType;
// 商品描述
private String goodsDesc;
// 交易总金额
private String transAmt;
// 交易有效期
private String timeExpire;
// 商品列表
private List<DougongRequestParam.WxDataGoodsDetail> goodsDetailList;
// 子商户用户标识
private String subOpenid;
}
package com.liquidnet.service.goblin.param.dougong;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
/**
* 斗拱-请求jspay-参数
*/
@Data
public class DougongRequestParam {
// 请求日期
@JsonProperty("req_date")
private String reqDate;
// 请求流水号
@JsonProperty("req_seq_id")
private String reqSeqId;
// 商户号
@JsonProperty("huifu_id")
private String huifuId;
// 商品描述
@JsonProperty("goods_desc")
private String goodsDesc;
//交易类型
//T_JSAPI: 微信公众号
//T_MINIAPP: 微信小程序
//A_JSAPI: 支付宝JS
//A_NATIVE: 支付宝正扫
//U_NATIVE: 银联正扫
//U_JSAPI: 银联JS
//D_NATIVE: 数字人民币正扫
//T_H5:微信直连H5支付
//T_APP:微信APP支付
//T_NATIVE:微信正扫
@JsonProperty("trade_type")
private String tradeType;
// 交易金额
@JsonProperty("trans_amt")
private String transAmt;
// 交易有效期
@JsonProperty("time_expire")
private String timeExpire;
// 微信参数集合 WxData
@JsonProperty("wx_data")
private String wxData;
// 是否延迟交易
@JsonProperty("delay_acct_flag")
private String delayAcctFlag = "N";
// 异步通知地址
@JsonProperty("notify_url")
private String notifyUrl;
@Data
public static class WxData {
//子商户应用ID
@JsonProperty("sub_appid")
private String subAppid;
// 子商户用户标识
@JsonProperty("sub_openid")
private String subOpenid;
//商品描述
@JsonProperty("body")
private String body;
// 商品详情
@JsonProperty("detail")
private WxDataDetail detail;
}
@Data
public static class WxDataDetail {
@JsonProperty("cost_price")
private String costPrice;
@JsonProperty("goods_detail")
private List<WxDataGoodsDetail> goodsDetail;
}
@Data
@NoArgsConstructor
@AllArgsConstructor
public static class WxDataGoodsDetail {
// 商品编码
@JsonProperty("goods_id")
private String goodsId;
// 商品名称
@JsonProperty("goods_name")
private String goodsName;
// 商品单价(元)
@JsonProperty("price")
private String price;
// 商品数量
@JsonProperty("quantity")
private Integer quantity;
}
}
package com.liquidnet.service.goblin.param.dougong;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
@Data
public class DougongSyncCallbackRespData {
// 业务响应码
@JsonProperty("resp_code")
private String respCode;
//业务响应信息
@JsonProperty("resp_code")
private String respDesc;
//商户号
@JsonProperty("huifu_id")
private String huifuId;
//请求流水号
@JsonProperty("req_seq_id")
private String reqSeqId;
//请求日期
@JsonProperty("req_date")
private String reqDate;
//交易类型
@JsonProperty("trans_type")
private String transType;
//全局流水号
@JsonProperty("hf_seq_id")
private String hfSeqId;
//交易金额
@JsonProperty("trans_amt")
private String transAmt;
//消费者实付金额
@JsonProperty("pay_amt")
private String payAmt;
// 支付完成时间 格式yyyyMMddHHmmss
@JsonProperty("end_time")
private String endTime;
//入账时间 格式为yyyyMMdd
@JsonProperty("acct_date")
private String acctDate;
// 交易状态 S:成功、F:失败,交易状态以此字段为准
@JsonProperty("trans_stat")
private String transStat;
//通知类型 1:通道通知,2:账务通知
@JsonProperty("notify_type")
private Integer notifyType;
@JsonProperty("out_trans_id")
private String outTransId;
}
package com.liquidnet.service.goblin.param.dougong;
import lombok.Data;
/**
* 异步返回参数
* 公共返回
*/
@Data
public class DougongSyncCallbackparam {
private String respCode;
private String respDesc;
private String sign;
private String respData;
}
package com.liquidnet.service.goblin.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.liquidnet.service.base.ResponseDto;
import com.liquidnet.service.goblin.dto.vo.GoblinBraceletOrderVo;
import com.liquidnet.service.goblin.dto.vo.GoblinBraceletPayResultVo;
import com.liquidnet.service.goblin.entity.GoblinBraceletOrder;
import com.liquidnet.service.goblin.param.GoblinBraceletOrderPayParam;
import com.liquidnet.service.goblin.param.dougong.DougongSyncCallbackparam;
import java.util.List;
import java.util.Map;
public interface IGoblinBraceletOrderService extends IService<GoblinBraceletOrder> {
/**
* 下单
* @param payParam
* @return
*/
ResponseDto<GoblinBraceletPayResultVo> checkOrder(GoblinBraceletOrderPayParam payParam);
/**
* 校验订单状态
*
* @param orderId
* @return
*/
ResponseDto<Map<String, Object>> checkOrderResult(String orderId);
/**
* 斗拱支付回调
* @return
*/
ResponseDto<Boolean> dougongCallBack(DougongSyncCallbackparam callbackparam);
/**
* 获取订单列表
* @return
*/
List<GoblinBraceletOrderVo> getOrderList();
}
package com.liquidnet.service.goblin.service;
import com.liquidnet.service.goblin.param.dougong.DougongJsPayData;
import java.util.Map;
public interface IGoblinDougongPayService {
/**
* @return
*/
Map<String, Object> jsPay(DougongJsPayData data);
boolean verifySign(String data, String sign);
}
package com.liquidnet.service.goblin.service;
import com.liquidnet.service.goblin.entity.GoblinRechargeAmount;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* <p>
* 充值金额选项表 服务类
* </p>
*
* @author jiangxiulong
* @since 2025-07-03
*/
public interface IGoblinRechargeAmountService extends IService<GoblinRechargeAmount> {
}
package com.liquidnet.service.goblin.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.liquidnet.service.goblin.dto.vo.GoblinRechargeWristbandVo;
import com.liquidnet.service.goblin.dto.vo.MaiZhiAllVo.*;
import com.liquidnet.service.goblin.entity.GoblinRechargeWristband;
/**
* <p>
* 手环信息表 服务类
* </p>
*
* @author jiangxiulong
* @since 2025-07-03
*/
public interface IGoblinRechargeWristbandService extends IService<GoblinRechargeWristband> {
GoblinRechargeWristbandVo getList();
CheckIdcardResponse auth(IdCardParam param);
OrderResponse createOrder(OrderParam param, String orderId);
OrderInfoResponse getOrder(OrderInfoParam param, String orderId);
GenerateDeviceCodeResponse getQrcode(String outno);
Boolean getDeviceNumber(Integer operationNo);
DeviceBalanceResponse getDeviceBalance(String cardno);
DeviceRecordResponse getDeviceRecord(String cardno, Integer page);
ChangeDeviceStatusResponse changeDeviceStatus(String orderId, int type);
Boolean refundRes();
}
......@@ -49,4 +49,8 @@ public class RedisKeyExpireConst {
// sweet:doudou:scope:mobile 过期时间3天
public static final long SWEET_DOUDOU_SCOPE_MOBILE_EXPIRE = 3 * 24 * 60 * 60;
// GOBLIN_BRACELET_USER 过期时间3天
public static final long GOBLIN_BRACELET_USER_EXPIRE = 30 * 24 * 60 * 60;
// GOBLIN_BRACELET_RELATED_ORDER 过期30天
public static final long GOBLIN_BRACELET_RELATED_ORDER_EXPIRE = 30 * 24 * 60 * 60;
}
......@@ -16,3 +16,13 @@ liquidnet:
mongodb:
sslEnabled: false
database: dev_ln_scene
lxpay:
apps:
dougong:
huifu-id: '6666000171841162'
sys-id: '6666000162031620'
product-id: 'PAYUN'
sub-app-id: 'wx4732efeaa2b08086'
public-key: "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArR8pqWsRMqiunn8uEZGF9AeizJK0vuWjlcNnTbw9Sb96dMVuYu3SRj+Dx4E4SgyEL4CYROou1xwY57kAKEqHdH7o1W41O9jYjXZG38BrtBR+D9Qh9OqGxCZ+e4Gi38XHGg6fn67iXefOqp1kWGd4qc8tIZO1lIDXS19R09D/mESNBMulQdVPyZF7gvd11A+7EEOfRlSOjrtqIoUWV0GIqhLPUtGJk8Uq/d9NLitJyvK3tgz8cvJ4RyK6UpGtRDrqiBiQxbvK9EqMd1sw3zkvM03szSWon4LHFNqvDr6RYfFyFUCvX9UPYmeritENnroEuTBlTFLLb68ed4HZEZDPTQIDAQAB"
private-key: "MIIEwAIBADANBgkqhkiG9w0BAQEFAASCBKowggSmAgEAAoIBAQDJAOaA1ikJzDL0vUuTyl3/vlHyuSod6/gFLLrSTD6EJkma5Ld34HHu82/5pEojEvbcU113L9j3fUJlpyjX6CFk6j2KjMIuyFxhgrVFi5WT5m74wYohoWNifkQrgwsO3oxI7cewWFu/w7/yCK9dzI4QxasGUKH9iPweI+26IR0DBbOfC9GVudOy2b2xLrGAevEEHdVTNqrQNdlrTzqAH7r3uk8s2vaBZX+O4gyf7eKdHdC4CVSWfYPLO1sA48MxNwI7OExxfGeV+0wmBMGRSoZ5FhWsqZs+f9jGcmfF+uEfAO71PqHjezXYxq7+oWDfDBPCTc5fo9w5v1HV0aZaYOe1AgMBAAECggEBAI4yR98fInse7XF8NOpBwIv6/QhEfAoc9CHdCfFaJOPiHjIo2a5BpvhPWYj288eqU998TmPSAqDbCUzWm6taOb2lhJHukDT+Y3RMPqcLX275Fsp+SJUQEjoMb3eExh7ny8CQDrOvXoDkH3c/M6ic3Gf7Hslh46dz8D/2VOhXIqoObPlSLzniwiMTDBEwB7IRc3Q+r4V6ZnKt8wjKQZpotBA3TlJlEBBj/h5SbWokwMQbTqFkjl7gVe0ase2WfV+cD4qhPZx6CWphPVyWelg+wpDqXOIQdnE8pgri5a9ZkzgPTOrKyCm+EOa9lZAp81tnb2iFhrlkKPSWUW8zLtZzxMECgYEA+sNyF0U9anyxeKxXtlGKKuMHJSnBpZeU6FSvZjTewFH2Sxh3QwZjg6h5BfvTLH1XfNerx3gdpAPJ+EyAZuEibDr47bp+j4CtT27dVolz5XQ5ugOadwzdNZkq6vhuq1aGATmS/mlNE1/pdMEP9F6hi2HYncER6BFOy0xSwMKCnRECgYEAzTNxhvZ0pb2hPKylxHUydkm3Uznq5Zkquv6II6W5aiKvceETHwdRZLoKc+I0kd0/4fBfJI2Jsjexy51ERiG+8y4wVrcrky6NLw6mnXSvnTSQCftbexheJTg9c5dpfKIj+rxtuBeZ3Sj1MJQ6OSBUYu3iTqstO0Rgp/1ofWQJ8GUCgYEAspxzr0+KJ0cZwbI/54S8vT9n33iWjbQiRDnNlScjYij/HQ4YJI1wZF6jlTeBerbskeesWy+bLS/ltA4Jhz3knuKCXBHyA5TL3UBCN1lAS7c1RuE6LIHlLkAi6ap6aV//ou+3W671T0+JobfB/XVJ61WOTQ8wCfQKA5QhfVsOXYECgYEAvzbm3Ysfm6qfazi+p9lGErASov1fhGA8T1AMcJtnsh1sO8Qu20UodaJfRylNL3dqphIltpwl6eq4RTLhgjDEDTvHU6cQdfB1I5qVbDhlxSpL5uFRl91XLXvA18wKQledC3M3Esr7V/loscIOl1knCaD+t6wPVCEdqK0dB2uHT3kCgYEA3p3rlmCmWzkZ/U8jE4087YEkJWV+r86YC63r4YZEqZtfHk4hNchAYke4jYPqkTtmRVZi2C6KuVr5M3ASHmGWorBY0VA9Abd3daniNocZCeMOt4Z7U6MIbqW7KYSrjx8V8HIsdH7HF97ofRuMH6oaz9bFMM6XwrEAMY+zTdH9A4Y="
notify-url: 'https://testgoblin.zhengzai.tv/goblin/bracelet/callback'
......@@ -16,3 +16,13 @@ liquidnet:
mongodb:
sslEnabled: false
database: test_ln_scene
lxpay:
apps:
dougong:
huifu-id: '6666000171841162'
sys-id: '6666000162031620'
product-id: 'PAYUN'
sub-app-id: 'wx4732efeaa2b08086'
public-key: "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArR8pqWsRMqiunn8uEZGF9AeizJK0vuWjlcNnTbw9Sb96dMVuYu3SRj+Dx4E4SgyEL4CYROou1xwY57kAKEqHdH7o1W41O9jYjXZG38BrtBR+D9Qh9OqGxCZ+e4Gi38XHGg6fn67iXefOqp1kWGd4qc8tIZO1lIDXS19R09D/mESNBMulQdVPyZF7gvd11A+7EEOfRlSOjrtqIoUWV0GIqhLPUtGJk8Uq/d9NLitJyvK3tgz8cvJ4RyK6UpGtRDrqiBiQxbvK9EqMd1sw3zkvM03szSWon4LHFNqvDr6RYfFyFUCvX9UPYmeritENnroEuTBlTFLLb68ed4HZEZDPTQIDAQAB"
private-key: "MIIEwAIBADANBgkqhkiG9w0BAQEFAASCBKowggSmAgEAAoIBAQDJAOaA1ikJzDL0vUuTyl3/vlHyuSod6/gFLLrSTD6EJkma5Ld34HHu82/5pEojEvbcU113L9j3fUJlpyjX6CFk6j2KjMIuyFxhgrVFi5WT5m74wYohoWNifkQrgwsO3oxI7cewWFu/w7/yCK9dzI4QxasGUKH9iPweI+26IR0DBbOfC9GVudOy2b2xLrGAevEEHdVTNqrQNdlrTzqAH7r3uk8s2vaBZX+O4gyf7eKdHdC4CVSWfYPLO1sA48MxNwI7OExxfGeV+0wmBMGRSoZ5FhWsqZs+f9jGcmfF+uEfAO71PqHjezXYxq7+oWDfDBPCTc5fo9w5v1HV0aZaYOe1AgMBAAECggEBAI4yR98fInse7XF8NOpBwIv6/QhEfAoc9CHdCfFaJOPiHjIo2a5BpvhPWYj288eqU998TmPSAqDbCUzWm6taOb2lhJHukDT+Y3RMPqcLX275Fsp+SJUQEjoMb3eExh7ny8CQDrOvXoDkH3c/M6ic3Gf7Hslh46dz8D/2VOhXIqoObPlSLzniwiMTDBEwB7IRc3Q+r4V6ZnKt8wjKQZpotBA3TlJlEBBj/h5SbWokwMQbTqFkjl7gVe0ase2WfV+cD4qhPZx6CWphPVyWelg+wpDqXOIQdnE8pgri5a9ZkzgPTOrKyCm+EOa9lZAp81tnb2iFhrlkKPSWUW8zLtZzxMECgYEA+sNyF0U9anyxeKxXtlGKKuMHJSnBpZeU6FSvZjTewFH2Sxh3QwZjg6h5BfvTLH1XfNerx3gdpAPJ+EyAZuEibDr47bp+j4CtT27dVolz5XQ5ugOadwzdNZkq6vhuq1aGATmS/mlNE1/pdMEP9F6hi2HYncER6BFOy0xSwMKCnRECgYEAzTNxhvZ0pb2hPKylxHUydkm3Uznq5Zkquv6II6W5aiKvceETHwdRZLoKc+I0kd0/4fBfJI2Jsjexy51ERiG+8y4wVrcrky6NLw6mnXSvnTSQCftbexheJTg9c5dpfKIj+rxtuBeZ3Sj1MJQ6OSBUYu3iTqstO0Rgp/1ofWQJ8GUCgYEAspxzr0+KJ0cZwbI/54S8vT9n33iWjbQiRDnNlScjYij/HQ4YJI1wZF6jlTeBerbskeesWy+bLS/ltA4Jhz3knuKCXBHyA5TL3UBCN1lAS7c1RuE6LIHlLkAi6ap6aV//ou+3W671T0+JobfB/XVJ61WOTQ8wCfQKA5QhfVsOXYECgYEAvzbm3Ysfm6qfazi+p9lGErASov1fhGA8T1AMcJtnsh1sO8Qu20UodaJfRylNL3dqphIltpwl6eq4RTLhgjDEDTvHU6cQdfB1I5qVbDhlxSpL5uFRl91XLXvA18wKQledC3M3Esr7V/loscIOl1knCaD+t6wPVCEdqK0dB2uHT3kCgYEA3p3rlmCmWzkZ/U8jE4087YEkJWV+r86YC63r4YZEqZtfHk4hNchAYke4jYPqkTtmRVZi2C6KuVr5M3ASHmGWorBY0VA9Abd3daniNocZCeMOt4Z7U6MIbqW7KYSrjx8V8HIsdH7HF97ofRuMH6oaz9bFMM6XwrEAMY+zTdH9A4Y="
notify-url: 'https://testgoblin.zhengzai.tv/goblin/bracelet/callback'
\ No newline at end of file
......@@ -73,7 +73,7 @@ spring:
autoconfigure:
exclude:
- org.springframework.cloud.bus.BusAutoConfiguration
- org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
# - org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
redis:
queue:
database: ${liquidnet.redis.queue.database}
......@@ -102,6 +102,17 @@ spring:
uri: mongodb://${liquidnet.mongodb.user}:${liquidnet.mongodb.pwd}@${liquidnet.mongodb.host}/?authSource=admin&maxPoolSize=200&waitQueueMultiple=100
sslEnabled: ${liquidnet.mongodb.sslEnabled}
database: ${liquidnet.mongodb.database}
datasource:
name: ${liquidnet.mysql.database-name}
url: jdbc:mysql://${liquidnet.mysql.urlHostAndPort}/${liquidnet.mysql.database-name}?serverTimezone=UTC&characterEncoding=utf-8&useSSL=false
username: ${liquidnet.mysql.username}
password: ${liquidnet.mysql.password}
# type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
hikari:
maximum-pool-size: 45
minimum-idle: 8
connection-test-query: SELECT 1
# -----------------------------------------------------------
......@@ -134,6 +145,7 @@ global-auth:
- ${liquidnet.info.context}/app/mix/list
- ${liquidnet.info.context}/app/mix/details
- ${liquidnet.info.context}/wdt/**
- ${liquidnet.info.context}/bracelet/callback
oncheck-url-pattern:
-
# -----------------------------------------------------------
......
package com.liquidnet.service.goblin.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDateTime;
/**
* 手环订单表实体类
*/
@Data
@EqualsAndHashCode(callSuper = false)
public class GoblinBraceletOrder implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 主键ID
*/
@TableId(value = "mid", type = IdType.AUTO)
private Long mid;
/**
* 订单ID
*/
private String orderId;
/**
* 用户ID
*/
private String userId;
/**
* 绑定用户姓名
*/
private String bindName;
/**
* 绑定用户手机号
*/
private String bindMobile;
/**
* 绑定用户身份证号码
*/
private String bindIdcard;
/**
* 请求日期
*/
private String reqDate;
/**
* 商品描述
*/
private String goodsDesc;
/**
* 手环ID
*/
private String wristbandId;
/**
*手环金额
*/
private BigDecimal wristbandPrice;
/**
*充值金额ID
*/
private String amountId;
/**
*充值金额
*/
private BigDecimal amountPrice;
/**
* 请求流水号
*/
private String reqSeqId;
/**
* 全局流水号
*/
private String hfSeqId;
/**
* 交易类型:
* T_JSAPI: 微信公众号支付
* T_MINIAPP: 微信小程序支付
* A_JSAPI: 支付宝JS
* A_NATIVE: 支付宝正扫
* U_NATIVE: 银联正扫
* U_JSAPI: 银联 JS
* D_NATIVE: 数字人民币正扫
* T_H5:微信直连H5支付
* T_APP:微信APP支付
* T_NATIVE:微信正扫
*/
private String tradeType;
/**
* 用户账单上的交易订单号
*/
private String outTransId;
/**
* 用户账单上的商户订单号
*/
private String partyOrderId;
/**
* 支付完成时间 格式yyyyMMddHHmmss
*/
private String endTime;
/**
* 入账时间 格式为yyyyMMdd
*/
private String acctDate;
/**
* 单价
*/
private BigDecimal price;
/**
* 应付价格
*/
private BigDecimal priceTotal;
/**
* 实付价格
*/
private BigDecimal priceActual;
/**
* 退款价格
*/
private BigDecimal priceRefund;
/**
* 退款扣除的手续费金额
*/
private BigDecimal refundPriceCharges;
/**
* 退款数
*/
private Integer refundNumber;
/**
* 支付时间
*/
private String timePay;
/**
* 订单状态:
* 0 待付款
* 1 已付款
* 2 已关闭
* 3 正在退款
* 4 已退款
* 5 待关闭
* 6 部分退款
* 7 退款失败
*/
private Integer status;
/**
* 支付状态:
* 0 未支付
* 1 已支付
* 2 支付失败
*/
private Integer payStatus;
/**
* 迈之的分订单号
*/
private String foutTradeNo;
/**
* 迈之的设备编号
*/
private String cardno;
/**
* 迈之的分订单号
*/
private Integer refundStatus;
/**
* 迈之的设备编号
*/
private String refundStatusNote;
/**
* 创建时间
*/
private LocalDateTime createdAt;
/**
* 更新时间
*/
private LocalDateTime updatedAt;
/**
* 备注
*/
private String comment;
}
package com.liquidnet.service.goblin.entity;
import java.math.BigDecimal;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import java.time.LocalDateTime;
import java.io.Serializable;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* <p>
* 充值金额选项表
* </p>
*
* @author jiangxiulong
* @since 2025-07-03
*/
@Data
@EqualsAndHashCode(callSuper = false)
public class GoblinRechargeAmount implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(value = "mid", type = IdType.AUTO)
private Long mid;
/**
* 金额ID
*/
private String amountId;
/**
* 金额名称
*/
private String name;
/**
* 充值金额
*/
private BigDecimal price;
/**
* 创建时间
*/
private LocalDateTime createdAt;
/**
* 更新时间
*/
private LocalDateTime updatedAt;
}
package com.liquidnet.service.goblin.entity;
import java.math.BigDecimal;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import java.time.LocalDateTime;
import java.io.Serializable;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* <p>
* 手环信息表
* </p>
*
* @author jiangxiulong
* @since 2025-07-03
*/
@Data
@EqualsAndHashCode(callSuper = false)
public class GoblinRechargeWristband implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(value = "mid", type = IdType.AUTO)
private Long mid;
/**
* 手环ID
*/
private String wristbandId;
/**
* 手环名称
*/
private String name;
/**
* 手环价格
*/
private BigDecimal price;
/**
* 创建时间
*/
private LocalDateTime createdAt;
/**
* 更新时间
*/
private LocalDateTime updatedAt;
}
package com.liquidnet.service.goblin.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.liquidnet.service.goblin.entity.GoblinBraceletOrder;
/**
* <p>
* Mapper 接口
* </p>
*
* @author jxl
*/
public interface GoblinBraceletOrderMapper extends BaseMapper<GoblinBraceletOrder> {
}
package com.liquidnet.service.goblin.mapper;
import com.liquidnet.service.goblin.entity.GoblinRechargeAmount;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* <p>
* 充值金额选项表 Mapper 接口
* </p>
*
* @author jiangxiulong
* @since 2025-07-03
*/
public interface GoblinRechargeAmountMapper extends BaseMapper<GoblinRechargeAmount> {
}
package com.liquidnet.service.goblin.mapper;
import com.liquidnet.service.goblin.entity.GoblinRechargeWristband;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* <p>
* 手环信息表 Mapper 接口
* </p>
*
* @author jiangxiulong
* @since 2025-07-03
*/
public interface GoblinRechargeWristbandMapper extends BaseMapper<GoblinRechargeWristband> {
}
<?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.liquidnet.service.goblin.mapper.GoblinRechargeAmountMapper">
</mapper>
<?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.liquidnet.service.goblin.mapper.GoblinRechargeWristbandMapper">
</mapper>
......@@ -22,4 +22,10 @@ public interface FeignGoblinTaskClient {
@GetMapping("rsc/nft/job/mixList")
ResponseDto<Boolean> mixList();
@GetMapping("/rsc/maizhi/job/getDeviceNumber")
ResponseDto<Boolean> getDeviceNumber();
@GetMapping("/rsc/maizhi/job/refundRes")
ResponseDto<Boolean> refundRes();
}
......@@ -48,4 +48,24 @@ public class GoblinTaskHandler {
XxlJobHelper.handleFail();
}
}
@XxlJob(value = "sev-goblin:getDeviceNumber")
public void getDeviceNumber() {
try {
XxlJobHelper.handleSuccess("结果:" + feignGoblinTaskClient.getDeviceNumber().getData());
} catch (Exception e) {
XxlJobHelper.log(e);
XxlJobHelper.handleFail();
}
}
@XxlJob(value = "sev-goblin:refundRes")
public void refundRes() {
try {
XxlJobHelper.handleSuccess("结果:" + feignGoblinTaskClient.refundRes().getData());
} catch (Exception e) {
XxlJobHelper.log(e);
XxlJobHelper.handleFail();
}
}
}
-- 创建手环产品表
CREATE TABLE IF NOT EXISTS goblin_recharge_wristband
(
mid BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
wristband_id VARCHAR(64) NOT NULL DEFAULT '' COMMENT '手环ID',
name VARCHAR(255) NOT NULL DEFAULT '' COMMENT '手环名称',
price DECIMAL(10, 2) NOT NULL DEFAULT 0 COMMENT '手环价格',
created_at timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
updated_at timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '更新时间'
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4 COMMENT ='手环信息表';
-- 创建充值金额表
CREATE TABLE IF NOT EXISTS goblin_recharge_amount
(
mid BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
amount_id VARCHAR(64) NOT NULL DEFAULT '' COMMENT '金额ID',
name VARCHAR(255) NOT NULL DEFAULT '' COMMENT '金额名称',
price DECIMAL(10, 2) NOT NULL DEFAULT 0 COMMENT '充值金额',
created_at timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
updated_at timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '更新时间'
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4 COMMENT ='充值金额选项表';
-- 手环订单表
CREATE TABLE goblin_bracelet_order
(
`mid` int(10) unsigned NOT NULL AUTO_INCREMENT,
`order_id` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT 'order_id',
`user_id` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '用户id',
`bind_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '绑定用户姓名',
`bind_mobile` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '绑定用户手机号',
`bind_idcard` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '绑定用户身份证号码',
`req_date` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '请求日期',
`goods_desc` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '商品描述',
`wristband_id` VARCHAR(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '手环ID',
`wristband_price` DECIMAL(10, 2) NOT NULL DEFAULT '0.00' COMMENT '手环金额',
`amount_id` VARCHAR(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '金额ID',
`amount_price` DECIMAL(10, 2) NOT NULL DEFAULT '0.00' COMMENT '充值金额',
`req_seq_id` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '请求流水号',
`hf_seq_id` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '全局流水号',
`trade_type` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '交易类型 T_JSAPI: 微信公众号支付 T_MINIAPP: 微信小程序支付 A_JSAPI: 支付宝JS A_NATIVE: 支付宝正扫 U_NATIVE: 银联正扫 U_JSAPI: 银联 JS D_NATIVE: 数字人民币正扫 T_H5:微信直连H5支付 T_APP:微信APP支付 T_NATIVE:微信正扫',
`out_trans_id` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '用户账单上的交易订单号',
`party_order_id` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '用户账单上的商户订单号',
`end_time` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '支付完成时间 格式yyyyMMddHHmmss',
`acct_date` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '入账时间 格式为yyyyMMdd',
`price` decimal(8, 2) NOT NULL DEFAULT '0.00' COMMENT '单价',
`price_total` decimal(8, 2) NOT NULL DEFAULT '0.00' COMMENT '应付价格',
`price_actual` decimal(8, 2) NOT NULL DEFAULT '0.00' COMMENT '实付价格',
`price_refund` decimal(8, 2) NOT NULL DEFAULT '0.00' COMMENT '退款价格',
`refund_price_charges` decimal(10, 2) NOT NULL DEFAULT '0.00' COMMENT '退款扣除的手续费金额',
`refund_number` int(11) NOT NULL DEFAULT '0' COMMENT '退款数',
`time_pay` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '支付时间',
`status` tinyint(4) NOT NULL DEFAULT '0' COMMENT '订单状态:0待付款,1已付款,2已关闭,3正在退款,4已退款, 5待关闭 6部分退款',
`pay_status` tinyint(4) NOT NULL DEFAULT '0' COMMENT '支付状态:0未支付 1已支付 2支付失败',
`fout_trade_no` varchar(255) NOT NULL DEFAULT '' COMMENT '迈之的分订单号',
`cardno` varchar(255) NOT NULL DEFAULT '' COMMENT '迈之的设备编号',
`refund_status` tinyint(4) NOT NULL DEFAULT '0' COMMENT '迈之退款审核状态:0待审核 1 审核通过 2 审核驳回',
`refund_status_note` varchar(255) NOT NULL DEFAULT '' COMMENT '迈之退款驳回原因',
`created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '更新时间',
`comment` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT 'comment',
PRIMARY KEY (`mid`)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_0900_ai_ci COMMENT ='手环订单表';
......@@ -97,6 +97,12 @@
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
</dependency>
<dependency>
<groupId>com.huifu.bspay.sdk</groupId>
<artifactId>dg-java-sdk</artifactId>
<version>3.0.27</version>
</dependency>
</dependencies>
<build>
......
package com.liquidnet.service;
import lombok.extern.slf4j.Slf4j;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
......@@ -14,6 +15,7 @@ import java.util.Arrays;
@Slf4j
@EnableFeignClients
@SpringBootApplication(scanBasePackages = {"com.liquidnet"})
@MapperScan(basePackages = {"com.liquidnet.service.*.mapper"})
public class ServiceGoblinApplication implements CommandLineRunner {
@Autowired
private Environment environment;
......
package com.liquidnet.service.goblin.config.properties;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.util.Map;
@ConfigurationProperties(prefix = "liquidnet.lxpay")
@Component
@Setter
@Getter
public class AppProperties {
private Map<String, AppInfo> apps;
@Data
public static class AppInfo {
private String productId;
private String sysId;
private String huifuId;
private String subAppId;
private String publicKey;
private String privateKey;
private String notifyUrl;
}
}
package com.liquidnet.service.goblin.controller;
import com.liquidnet.commons.lang.util.JsonUtils;
import com.liquidnet.service.base.ResponseDto;
import com.liquidnet.service.base.codec.annotation.DecryptAndVerify;
import com.liquidnet.service.base.codec.vo.EncryptedReq;
import com.liquidnet.service.goblin.dto.vo.GoblinBraceletOrderVo;
import com.liquidnet.service.goblin.dto.vo.GoblinBraceletPayResultVo;
import com.liquidnet.service.goblin.param.GoblinBraceletOrderPayParam;
import com.liquidnet.service.goblin.param.dougong.DougongSyncCallbackparam;
import com.liquidnet.service.goblin.service.IGoblinBraceletOrderService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import java.util.List;
import java.util.Map;
@Slf4j
@Api(tags = "商城-手环相关")
@RestController
@RequestMapping("/bracelet")
public class GoblinBraceletOrderController {
@Autowired
private IGoblinBraceletOrderService braceLetOrderService;
@PostMapping("/pre")
@ApiOperation("下单(加密)")
@DecryptAndVerify(decryptedClass = GoblinBraceletOrderPayParam.class)
public ResponseDto<GoblinBraceletPayResultVo> checkOrder(@RequestBody @Valid EncryptedReq<GoblinBraceletOrderPayParam> payParam) {
return braceLetOrderService.checkOrder(payParam.getData());
}
@PostMapping("/fc7bce6d6c2213b866f76493f92224b8")
@ApiOperation("下单(非加密)")
public ResponseDto<GoblinBraceletPayResultVo> checkOrder(@RequestBody @Valid GoblinBraceletOrderPayParam payParam) {
return braceLetOrderService.checkOrder(payParam);
}
@GetMapping("/checkPayment")
@ApiOperation("查询订单状态")
@ApiImplicitParams({
@ApiImplicitParam(type = "form", required = true, dataType = "String", name = "orderId", value = "订单ID", example = "1"),
})
public ResponseDto<Map<String, Object>> checkOrderResult(@RequestParam("orderId") @NotBlank(message = "订单ID不能为空") String orderId) {
return braceLetOrderService.checkOrderResult(orderId);
}
@GetMapping("/order/list")
@ApiOperation("查询订单列表")
public ResponseDto<List<GoblinBraceletOrderVo>> getOrderList() {
return ResponseDto.success(braceLetOrderService.getOrderList());
}
@PostMapping("/callback")
// @ApiOperation("斗拱支付回调")
public ResponseDto<Boolean> dougongCallBack(@RequestParam Map<String, Object> params) {
log.info("dougong-callback: {}.", JsonUtils.toJson(params));
DougongSyncCallbackparam dougongSyncCallbackparam = new DougongSyncCallbackparam();
dougongSyncCallbackparam.setRespCode((String) params.get("resp_code"));
dougongSyncCallbackparam.setRespDesc((String) params.get("resp_code"));
dougongSyncCallbackparam.setSign((String) params.get("sign"));
dougongSyncCallbackparam.setRespData((String) params.get("resp_data"));
return braceLetOrderService.dougongCallBack(dougongSyncCallbackparam);
}
}
package com.liquidnet.service.goblin.controller;
import com.liquidnet.service.base.ResponseDto;
import com.liquidnet.service.goblin.dto.vo.GoblinRechargeWristbandVo;
import com.liquidnet.service.goblin.dto.vo.MaiZhiAllVo.*;
import com.liquidnet.service.goblin.service.IGoblinRechargeWristbandService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
import java.util.List;
@Slf4j
@Api(tags = "充值金额")
@RestController
@Validated
@RequestMapping("/recharge")
public class GoblinRechargeAmountController {
@Autowired
private IGoblinRechargeWristbandService iGoblinRechargeWristbandService;
@GetMapping("goods/list")
@ApiOperation("获得金额列表")
public ResponseDto<GoblinRechargeWristbandVo> getList() {
return ResponseDto.success(iGoblinRechargeWristbandService.getList());
}
@PostMapping("auth")
@ApiOperation("二要素认证")
public ResponseDto<String> auth(@RequestBody IdCardParam param) {
CheckIdcardResponse res = iGoblinRechargeWristbandService.auth(param);
if (null != res && res.getErrcode() == 200) {
return ResponseDto.success(res.getMessage());
} else {
return ResponseDto.failure(res.getMsg());
}
}
/*@PostMapping("order/create")
@ApiOperation("创建订单")
public ResponseDto<String> createOrder(@RequestBody OrderParam param) {
OrderResponse res = iGoblinRechargeWristbandService.createOrder(param);
if (null != res && res.getErrcode() == 200) {
return ResponseDto.success(res.getMsg());
} else {
return ResponseDto.failure(res.getMsg());
}
}*/
/*@PostMapping("order/info")
@ApiOperation("订单查询")
public ResponseDto<List<OrderInfoResponse.OrderList>> getOrder(@RequestBody OrderInfoParam param) {
OrderInfoResponse res = iGoblinRechargeWristbandService.getOrder(param);
if (null != res && res.getErrcode() == 200) {
return ResponseDto.success(res.getOutlist());
} else {
return ResponseDto.failure();
}
}*/
@GetMapping("order/qrcode")
@ApiOperation("获取二维码字符串")
@ApiImplicitParams({
@ApiImplicitParam(type = "param", required = true, name = "outno", value = "分订单号"),
})
public ResponseDto<String> getQrcode(@NotBlank(message = "参数无效:outno") @RequestParam("outno") String outno) {
GenerateDeviceCodeResponse res = iGoblinRechargeWristbandService.getQrcode(outno);
if (null != res && res.getErrcode() == 200) {
return ResponseDto.success(res.getQrcode_str());
} else {
return ResponseDto.failure();
}
}
/*@GetMapping("device/mumber")
@ApiOperation("获取设备编号列表")
@ApiImplicitParams({
@ApiImplicitParam(type = "param", required = true, name = "operationNo", value = "活动号"),
})
public ResponseDto<Boolean> getDeviceNumber(
@NotNull(message = "参数无效") @RequestParam("operationNo") Integer operationNo
) {
Boolean res = iGoblinRechargeWristbandService.getDeviceNumber(operationNo);
if (res) {
return ResponseDto.success();
} else {
return ResponseDto.failure();
}
}*/
@GetMapping("device/balance")
@ApiOperation("获取余额")
@ApiImplicitParams({
@ApiImplicitParam(type = "param", required = true, name = "cardno", value = "设备编号"),
})
public ResponseDto<BigDecimal> getDeviceBalance(
@NotBlank(message = "参数无效:cardno") @RequestParam("cardno") String cardno
) {
DeviceBalanceResponse res = iGoblinRechargeWristbandService.getDeviceBalance(cardno);
if (null != res && res.getErrcode() == 200) {
return ResponseDto.success(res.getMoney());
} else {
return ResponseDto.failure(res.getMsg());
}
}
@GetMapping("device/record")
@ApiOperation("获取设备记录")
@ApiImplicitParams({
@ApiImplicitParam(type = "param", required = true, name = "cardno", value = "设备编号"),
@ApiImplicitParam(type = "param", required = true, name = "page", value = "分页"),
})
public ResponseDto<DeviceRecordResponse> getDeviceRecord(
@NotBlank(message = "参数无效:cardno") @RequestParam("cardno") String cardno,
@NotNull(message = "参数无效:page") @RequestParam("page") Integer page
) {
DeviceRecordResponse res = iGoblinRechargeWristbandService.getDeviceRecord(cardno, page);
if (null != res && res.getErrcode() == 200) {
return ResponseDto.success(res);
} else {
return ResponseDto.failure(res.getMsg());
}
}
@GetMapping("order/refund/apply")
@ApiOperation("退款申请")
@ApiImplicitParams({
@ApiImplicitParam(type = "param", required = true, name = "orderId", value = "订单编号"),
})
public ResponseDto<ChangeDeviceStatusResponse> refundApply(
@NotBlank(message = "参数无效:orderId") @RequestParam("orderId") String orderId
) {
ChangeDeviceStatusResponse res = iGoblinRechargeWristbandService.changeDeviceStatus(orderId, 1);
if (null != res && res.getErrcode() == 200) {
return ResponseDto.success(res);
} else {
return ResponseDto.failure(res.getMsg());
}
}
/*@GetMapping("order/refund/result")
@ApiOperation("退款结果查询")
public ResponseDto<Boolean> refundRes() {
Boolean res = iGoblinRechargeWristbandService.refundRes();
if (res) {
return ResponseDto.success();
} else {
return ResponseDto.failure();
}
}*/
}
package com.liquidnet.service.goblin.controller.Inner;
import com.liquidnet.service.base.ResponseDto;
import com.liquidnet.service.goblin.service.IGoblinRechargeWristbandService;
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.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@Slf4j
@Api(tags = "@API:RSC")
@RestController
@Validated
@RequestMapping("/rsc/maizhi/job")
public class GoblinMaiZhiJobController {
@Autowired
private IGoblinRechargeWristbandService iGoblinRechargeWristbandService;
@GetMapping("getDeviceNumber")
@ApiOperation("获取设备编号JOB")
public ResponseDto<Boolean> getDeviceNumber() {
return ResponseDto.success(iGoblinRechargeWristbandService.getDeviceNumber(2));
}
@GetMapping("refundRes")
@ApiOperation("获取设备编号JOB")
public ResponseDto<Boolean> refundRes() {
return ResponseDto.success(iGoblinRechargeWristbandService.refundRes());
}
}
package com.liquidnet.service.goblin.service.impl;
import com.huifu.bspay.sdk.opps.core.BasePay;
import com.huifu.bspay.sdk.opps.core.config.MerConfig;
import com.huifu.bspay.sdk.opps.core.net.BasePayRequest;
import com.liquidnet.commons.lang.util.JsonUtils;
import com.liquidnet.service.goblin.config.properties.AppProperties;
import com.liquidnet.service.goblin.param.dougong.DougongJsPayData;
import com.liquidnet.service.goblin.param.dougong.DougongRequestParam;
import com.liquidnet.service.goblin.service.IGoblinDougongPayService;
import com.liquidnet.service.goblin.util.DougongSignUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import java.util.Map;
@Slf4j
@Service
public class GoblinDougongPayServiceImpl implements IGoblinDougongPayService {
private final AppProperties.AppInfo appInfo;
public GoblinDougongPayServiceImpl(AppProperties appProperties) {
this.appInfo = appProperties.getApps().get("dougong");
if (this.appInfo == null) {
throw new IllegalArgumentException("找不到应用配置");
}
}
@PostConstruct
public void init() {
MerConfig merConfig = new MerConfig();
merConfig.setProcutId(appInfo.getProductId());
merConfig.setSysId(appInfo.getSysId());
merConfig.setRsaPrivateKey(appInfo.getPrivateKey());
merConfig.setRsaPublicKey(appInfo.getPublicKey());
try {
BasePay.initWithMerConfig(merConfig);
} catch (Exception e) {
log.error("初始化支付配置失败", e);
throw new RuntimeException("初始化支付配置失败", e);
}
}
@Override
public Map<String, Object> jsPay(DougongJsPayData data) {
DougongRequestParam requestParam = buildDougongRequestParam(data);
log.info("request param: {}.", JsonUtils.toJson(requestParam));
if (requestParam == null) {
log.error("构建下单参数失败");
return null;
}
try {
Map<String, Object> map = JsonUtils.fromJson(JsonUtils.toJson(requestParam), Map.class);
//3. 发起API调用
Map<String, Object> response = BasePayRequest.requestBasePay("v3/trade/payment/jspay", map, null, false);
log.info("response: {}.", JsonUtils.toJson(response));
if (response != null && "00000100".equals(response.get("resp_code"))
&& "P".equals(response.get("trans_stat"))){
return response;
}
} catch (Exception e) {
log.error("error", e);
}
return null;
}
@Override
public boolean verifySign(String data, String sign) {
boolean verify = DougongSignUtils.verify(data, appInfo.getPublicKey(), sign);
return verify;
}
private DougongRequestParam buildDougongRequestParam(DougongJsPayData data){
if (data == null) {
return null;
}
DougongRequestParam requestParam = new DougongRequestParam();
requestParam.setReqDate(data.getReqDate());
requestParam.setReqSeqId(data.getReqSeqId());
requestParam.setHuifuId(appInfo.getHuifuId());
requestParam.setGoodsDesc(data.getGoodsDesc());
requestParam.setTradeType(data.getTradeType());
requestParam.setTransAmt(data.getTransAmt());
requestParam.setTimeExpire(data.getTimeExpire());
requestParam.setWxData(buildWxData(data));
requestParam.setNotifyUrl(appInfo.getNotifyUrl());
return requestParam;
}
private String buildWxData(DougongJsPayData data) {
DougongRequestParam.WxData wxData = new DougongRequestParam.WxData();
wxData.setSubAppid(appInfo.getSubAppId());
wxData.setSubOpenid(data.getSubOpenid());
wxData.setBody(data.getGoodsDesc());
wxData.setDetail(buildWxDataDetail(data));
return JsonUtils.toJson(wxData);
}
private DougongRequestParam.WxDataDetail buildWxDataDetail(DougongJsPayData data) {
DougongRequestParam.WxDataDetail wxDataDetail = new DougongRequestParam.WxDataDetail();
wxDataDetail.setCostPrice(data.getTransAmt());
wxDataDetail.setGoodsDetail(data.getGoodsDetailList());
return wxDataDetail;
}
}
package com.liquidnet.service.goblin.service.impl;
import com.liquidnet.service.goblin.entity.GoblinRechargeAmount;
import com.liquidnet.service.goblin.mapper.GoblinRechargeAmountMapper;
import com.liquidnet.service.goblin.service.IGoblinRechargeAmountService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
/**
* <p>
* 充值金额选项表 服务实现类
* </p>
*
* @author jiangxiulong
* @since 2025-07-03
*/
@Service
public class GoblinRechargeAmountServiceImpl extends ServiceImpl<GoblinRechargeAmountMapper, GoblinRechargeAmount> implements IGoblinRechargeAmountService {
}
package com.liquidnet.service.goblin.util;
import lombok.extern.slf4j.Slf4j;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
@Slf4j
public class DougongSignUtils {
/**
* RSA私钥签名:签名方式SHA256WithRSA
* @param data 待签名字符串
* @param privateKeyBase64 私钥(Base64编码)
* @return 签名byte[]
* @throws Exception
*/
public static String sign(String data, String privateKeyBase64) {
// Base64 --> Key
try {
byte[] bytes = Base64.getDecoder().decode(privateKeyBase64);
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(bytes);
KeyFactory keyFactory;
keyFactory = KeyFactory.getInstance("RSA");
PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
// Sign
Signature signature = Signature.getInstance("SHA256WithRSA");
signature.initSign(privateKey);
signature.update(data.getBytes("UTF-8"));
return Base64.getEncoder().encodeToString(signature.sign());
} catch (Exception e) {
return null;
}
}
/**
* 使用汇付RSA公钥验签
* @param data 待签名字符串
* @param publicKeyBase64 公钥(Base64编码)
* @return 验签结果
* @throws Exception
*/
public static boolean verify(String data, String publicKeyBase64, String sign) {
// Base64 --> Key
try {
byte[] bytes = Base64.getDecoder().decode(publicKeyBase64);
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(bytes);
KeyFactory keyFactory;
keyFactory = KeyFactory.getInstance("RSA");
PublicKey publicKey = keyFactory.generatePublic(keySpec);
// verify
Signature signature = Signature.getInstance("SHA256WithRSA");
signature.initVerify(publicKey);
signature.update(data.getBytes("UTF-8"));
return signature.verify(Base64.getDecoder().decode(sign));
} catch (Exception e) {
log.error("Exception", e);
return false;
}
}
}
package com.liquidnet.service.goblin.util;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.liquidnet.common.cache.redis.util.RedisUtil;
......@@ -8,6 +10,7 @@ import com.liquidnet.commons.lang.util.JsonUtils;
import com.liquidnet.commons.lang.util.RandomUtil;
import com.liquidnet.service.base.ErrorMapping;
import com.liquidnet.service.base.ResponseDto;
import com.liquidnet.service.base.constant.RedisKeyExpireConst;
import com.liquidnet.service.galaxy.constant.GalaxyEnum;
import com.liquidnet.service.goblin.constant.GoblinRedisConst;
import com.liquidnet.service.goblin.constant.GoblinStatusConst;
......@@ -17,9 +20,11 @@ import com.liquidnet.service.goblin.dto.GoblinUserSafeConfigDto;
import com.liquidnet.service.goblin.dto.manage.vo.GoblinGoodsAnticipateValueVo;
import com.liquidnet.service.goblin.dto.manage.vo.GoblinMgtCategorySpecVo;
import com.liquidnet.service.goblin.dto.vo.*;
import com.liquidnet.service.goblin.entity.GoblinBraceletOrder;
import com.liquidnet.service.goblin.entity.GoblinFrontBanner;
import com.liquidnet.service.goblin.entity.GoblinFrontHotWord;
import com.liquidnet.service.goblin.entity.GoblinFrontNavigation;
import com.liquidnet.service.goblin.mapper.GoblinBraceletOrderMapper;
import com.liquidnet.service.goblin.service.impl.inner.GoblinNftJobServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
......@@ -48,6 +53,8 @@ public class GoblinRedisUtils {
GoblinMongoUtils goblinMongoUtils;
@Autowired
GoblinNftJobServiceImpl goblinNftJobService;
@Autowired
private GoblinBraceletOrderMapper braceletOrderMapper;
@Value("${liquidnet.secret.passwd-salt}")
private String passwdSalt;
......@@ -2923,6 +2930,124 @@ public class GoblinRedisUtils {
return (int) redisUtil.rightPush(rdk, orderId);
}
public GoblinRechargeWristbandVo getRechargeWristbandVo() {
Object obj = redisUtil.get(GoblinRedisConst.GOBLIN_RECHARGE_WRISTBAND);
if (obj == null) {
return null;
} else {
return (GoblinRechargeWristbandVo) obj;
}
}
public void setRechargeWristbandVo(GoblinRechargeWristbandVo vo) {
String rdk = GoblinRedisConst.GOBLIN_RECHARGE_WRISTBAND;
redisUtil.set(rdk, vo);
}
public void setMaiZhiAccessToken(String token, int time) {
String rdk = GoblinRedisConst.GOBLIN_RECHARGE_MAIZHI_TOKEN;
redisUtil.set(rdk, token, time);
}
public String getMaiZhiAccessToken() {
Object obj = redisUtil.get(GoblinRedisConst.GOBLIN_RECHARGE_MAIZHI_TOKEN);
if (obj == null) {
return null;
} else {
return (String) obj;
}
}
public void setBraceletRelatedOrderVo(String reqSeqId, String orderId){
String key = GoblinRedisConst.GOBLIN_BRACELET_RELATED_ORDER.concat(reqSeqId);
redisUtil.set(key, orderId, RedisKeyExpireConst.GOBLIN_BRACELET_RELATED_ORDER_EXPIRE);
}
/**
*
* @param reqSeqId 调用斗拱-请求流水号
* @return orderId 手环订单ID
*/
public String getBraceletRelatedOrderVo(String reqSeqId){
String key = GoblinRedisConst.GOBLIN_BRACELET_RELATED_ORDER.concat(reqSeqId);
Object obj = redisUtil.get(key);
if (obj == null) {
// 从数据库查询
LambdaQueryWrapper<GoblinBraceletOrder> lambdaed = new QueryWrapper<GoblinBraceletOrder>()
.lambda().eq(GoblinBraceletOrder::getReqSeqId, reqSeqId);
List<GoblinBraceletOrder> goblinBraceletOrders = braceletOrderMapper.selectList(lambdaed);
if (goblinBraceletOrders.isEmpty()) {
return "";
}
GoblinBraceletOrder goblinBraceletOrder = goblinBraceletOrders.get(0);
String orderId = goblinBraceletOrder.getOrderId();
setBraceletRelatedOrderVo(goblinBraceletOrder.getReqSeqId(), orderId);
return orderId;
}else {
return (String) obj;
}
}
public void setBraceletOrderVo(GoblinBraceletOrderVo orderVo) {
String key = GoblinRedisConst.GOBLIN_BRACELET_ORDERID.concat(orderVo.getOrderId());
redisUtil.set(key, orderVo, RedisKeyExpireConst.GOBLIN_BRACELET_USER_EXPIRE);
}
/**
* 获取手环订单信息
* @param orderId
* @return
*/
public GoblinBraceletOrderVo getBraceletOrderVo(String orderId){
String key = GoblinRedisConst.GOBLIN_BRACELET_ORDERID.concat(orderId);
Object obj = redisUtil.get(key);
if (obj == null) {
// 从数据库查询
LambdaQueryWrapper<GoblinBraceletOrder> queryWrapper = new QueryWrapper<GoblinBraceletOrder>().lambda()
.eq(GoblinBraceletOrder::getOrderId, orderId);
List<GoblinBraceletOrder> goblinBraceletOrders = braceletOrderMapper.selectList(queryWrapper);
if (goblinBraceletOrders.isEmpty()) {
return null;
}
GoblinBraceletOrderVo orderVo = GoblinBraceletOrderVo.getNew().copy(goblinBraceletOrders.get(0));
setBraceletOrderVo(orderVo);
return orderVo;
} else {
return (GoblinBraceletOrderVo) obj;
}
}
public String getDeviceNumberEndTime(Integer operationNo) {
String key = GoblinRedisConst.GOBLIN_RECHARGE_DEVICE_NUMBER_ENDTIME.concat(String.valueOf(operationNo));
Object obj = redisUtil.get(key);
if (obj == null) {
return null;
} else {
return (String) obj;
}
}
public void setDeviceNumberEndTime(Integer operationNo, String endTime) {
String key = GoblinRedisConst.GOBLIN_RECHARGE_DEVICE_NUMBER_ENDTIME.concat(String.valueOf(operationNo));
redisUtil.set(key, endTime);
}
public String getOrderIdByFoutTradeNo(String foutTradeNo) {
String key = GoblinRedisConst.GOBLIN_RECHARGE_FOUT_TRADE_NO.concat(foutTradeNo);
Object obj = redisUtil.get(key);
if (obj == null) {
return null;
} else {
return (String) obj;
}
}
public void setOrderIdByFoutTradeNo(String foutTradeNo, String orderId) {
String key = GoblinRedisConst.GOBLIN_RECHARGE_FOUT_TRADE_NO.concat(foutTradeNo);
redisUtil.set(key, orderId);
}
/* ---------------------------------------- ---------------------------------------- */
/* ---------------------------------------- ---------------------------------------- */
/* ---------------------------------------- ---------------------------------------- */
......
......@@ -195,3 +195,9 @@ goblin_sku.stock=UPDATE goblin_goods_sku SET sku_stock = ? , stock = ?, updated_
candy_user_coupon.update_apply_refund=UPDATE candy_user_coupon SET state=?,operator=?,updated_at=? WHERE ucoupon_id=?
#----
#----
# ---- \u624B\u73AF\u8BA2\u5355 ----
goblin_bracelet_order_insert = INSERT INTO `goblin_bracelet_order`(`order_id`, `user_id`, `bind_name`, `bind_mobile`, `bind_idcard`, `req_date`, `goods_desc`, `wristband_id`, `wristband_price`, `amount_id`, `amount_price`, `req_seq_id`, `hf_seq_id`, `trade_type`, `party_order_id`, `price`, `price_total`, `price_refund`, `refund_price_charges`, `refund_number`, `status`, `pay_status`, `created_at`, `updated_at`) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)
gpblin_bracelet_order_update= update goblin_bracelet_order set out_trans_id=?, end_time=?, acct_date=?, price_actual=?, time_pay=?, status=?, pay_status=?, updated_at=? where order_id=?
goblin_bracelet_order_update_cardno=UPDATE goblin_bracelet_order SET cardno=?,updated_at=? WHERE order_id=?
goblin_bracelet_order_update_fout_trade_no=UPDATE goblin_bracelet_order SET fout_trade_no=?,updated_at=? WHERE order_id=?
goblin_bracelet_order_update_refund=UPDATE goblin_bracelet_order SET status=?,refund_status=?,refund_status_note=?,updated_at=? WHERE order_id=?
\ No newline at end of file
package com.liquidnet.service.goblin.test;
import com.liquidnet.commons.lang.util.JsonUtils;
import com.liquidnet.service.base.ResponseDto;
import com.liquidnet.service.goblin.param.dougong.DougongSyncCallbackparam;
import com.liquidnet.service.goblin.service.IGoblinBraceletOrderService;
import lombok.extern.slf4j.Slf4j;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import java.util.Map;
@Slf4j
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
public class GoblinBraceletOrderServiceTest {
@Autowired
private IGoblinBraceletOrderService goblinBraceletorderservice;
@Test
public void dougongCallBackTest(){
DougongSyncCallbackparam callbackparam = new DougongSyncCallbackparam();
callbackparam.setRespCode("00000000");
callbackparam.setSign("gsbW6XtkMbtpM9kI2sZ+aAMB2/QHH7YFN7ecBcfUmPe93LdC+BwKPxhT587zr7LlDzwfhmv+xVcbWTKrol5THa7dK8+RqYNbijKxZFba+oNi2dVWeRmSXVgL5yZ8+DsrXdTms9uv5WP19vuLMVh+UCh1n7zDBhJPMsW6w9LPEaCWXJcLJ8xgzBm/JtAQNZO7WWxFdHJShYmUssRfQvq8a/TXwBxlAB07hjQmI9rhTDL0UY39sfh1a9NVUrwmRPunDtq9WvV+/8I3VL4yZNWO9w4V56VrZj24SmmHBb2EDeHzx4qfky6DK9Djk/ZJBqFeOi/N0YKkzR6X2CsL7ab72A==");
callbackparam.setRespDesc("交易成功[000]");
callbackparam.setRespData("{\"acct_id\":\"F00300982\",\"acct_split_bunch\":{\"acct_infos\":[{\"acct_id\":\"F00300982\",\"div_amt\":\"0.02\",\"huifu_id\":\"6666000109133323\"}],\"fee_acct_id\":\"F00380563\",\"fee_amt\":\"0.01\",\"fee_huifu_id\":\"6666000109133323\"},\"acct_stat\":\"I\",\"atu_sub_mer_id\":\"460360228\",\"avoid_sms_flag\":\"\",\"bagent_id\":\"6666000108840829\",\"bank_code\":\"SUCCESS\",\"bank_desc\":\"交易成功\",\"bank_message\":\"交易成功\",\"bank_order_no\":\"4200002303202406139053495866\",\"bank_seq_id\":\"800448\",\"bank_type\":\"OTHERS\",\"base_acct_id\":\"F00300982\",\"batch_id\":\"240613\",\"channel_type\":\"U\",\"charge_flags\":\"758_0\",\"combinedpay_data\":[],\"combinedpay_fee_amt\":\"0.00\",\"debit_type\":\"0\",\"delay_acct_flag\":\"N\",\"div_flag\":\"0\",\"end_time\":\"20240613105518\",\"fee_amount\":\"0.01\",\"fee_amt\":\"0.01\",\"fee_flag\":1,\"fee_formula_infos\":[{\"fee_formula\":\"MAX(0.01,AMT*0.01)\",\"fee_type\":\"TRANS_FEE\"}],\"fee_rec_type\":\"1\",\"fee_type\":\"OUTSIDE\",\"gate_id\":\"VN\",\"hf_seq_id\":\"002900TOP2B240613105504P831ac139c2000000\",\"huifu_id\":\"6666000109133323\",\"is_delay_acct\":\"0\",\"is_div\":\"0\",\"maze_resp_code\":\"\",\"mer_name\":\"上海汇涵信息科技服务有限公司\",\"mer_ord_id\":\"20240613105441800448\",\"mypaytsf_discount\":\"0.00\",\"need_big_object\":true,\"notify_type\":1,\"org_auth_no\":\"\",\"org_huifu_seq_id\":\"\",\"org_trans_date\":\"\",\"out_ord_id\":\"4200002303202406139053495866\",\"out_trans_id\":\"4200002303202406139053495866\",\"party_order_id\":\"03242406133930500803797\",\"pay_amt\":\"0.02\",\"pay_scene\":\"02\",\"posp_seq_id\":\"03242406133930500803797\",\"product_id\":\"YYZY\",\"ref_no\":\"105504800448\",\"req_date\":\"20240613\",\"req_seq_id\":\"20240613105441800448\",\"resp_code\":\"00000000\",\"resp_desc\":\"交易成功\",\"risk_check_data\":{\"ip_addr\":\"192.1.1.1\"},\"risk_check_info\":{\"client_ip\":\"192.1.1.1\"},\"settlement_amt\":\"0.02\",\"sub_resp_code\":\"00000000\",\"sub_resp_desc\":\"交易成功\",\"subsidy_stat\":\"I\",\"sys_id\":\"6666000108840829\",\"trade_type\":\"T_JSAPI\",\"trans_amt\":\"0.02\",\"trans_date\":\"20240613\",\"trans_fee_allowance_info\":{\"actual_fee_amt\":\"0.01\",\"allowance_fee_amt\":\"0.00\",\"allowance_type\":\"0\",\"cur_allowance_config_infos\":{\"activity_id\":\"AYYZY202403281643407965739\",\"activity_name\":\"\",\"allowance_sys\":\"1\",\"allowance_sys_id\":\"1234567891011\",\"create_by\":\"yunlong.zhang\",\"create_time\":1711615421000,\"end_time\":\"20241201\",\"human_flag\":\"N\",\"is_delay_allowance\":\"2\",\"is_share\":\"Y\",\"merchant_group\":\"6666000109133323\",\"pos_credit_limit_amt\":\"1000.00\",\"pos_debit_limit_amt\":\"1000.00\",\"pos_limit_amt\":\"2000.00\",\"qr_limit_amt\":\"1.00\",\"start_time\":\"20240101\",\"status\":\"1\",\"total_limit_amt\":\"1900.00\",\"update_time\":1711615421000},\"no_allowance_desc\":\"8\",\"receivable_fee_amt\":\"0.01\"},\"trans_order_info\":{\"acct_id\":\"F00300982\",\"acct_stat\":\"I\",\"agent_id\":\"6666000108840829\",\"atu_sub_mer_id\":\"460360228\",\"bagent_id\":\"6666000108840829\",\"bank_mer_id\":\"W1035134718836156463\",\"bank_mer_name\":\"上海汇涵信息科技服务有限公司\",\"bank_resp_code\":\"SUCCESS\",\"bank_resp_desc\":\"交易成功\",\"bank_seq_id\":\"800448\",\"bank_type\":\"OTHERS\",\"batch_id\":\"240613\",\"card_channel_type\":\"\",\"card_sign\":\"\",\"cash_req_date\":\"20240613105504\",\"cash_resp_code\":\"000\",\"cash_resp_desc\":\"成功\",\"cash_trans_id\":\"20240613241pkafk\",\"cashier_version\":\"V2\",\"channel_code\":\"00\",\"channel_finish_time\":1718247318000,\"channel_message\":\"交易成功\",\"channel_stat\":\"S\",\"channel_type\":\"U\",\"check_cash_flag\":\"I\",\"close_trans_stat\":\"\",\"create_time\":1718247304000,\"creator\":\"\",\"credit_fee_amt\":0.00,\"credit_type\":\"\",\"db_unit\":\"2\",\"debit_fee_amt\":0.00,\"double_limit_amt\":0.00,\"fee_acct_id\":\"F00380563\",\"fee_allowance_flag\":0,\"fee_amt\":0.01,\"fee_flag\":1,\"fee_formula\":\"\",\"fee_huifu_id\":\"6666000109133323\",\"fee_real_acct_id\":\"F00380563\",\"fee_real_cust_id\":\"6666000109133323\",\"fee_rec_type\":1,\"fee_source\":\"'SERVER'\",\"fee_split_type\":\"\",\"gate_id\":\"SPIN002\",\"goods_desc\":\"微信测试商品-无线鼠标\",\"hf_seq_id\":\"002900TOP2B240613105504P831ac139c2000000\",\"huifu_id\":\"6666000109133323\",\"icc_data\":\"\",\"id\":4175314075,\"is_acct_div\":0,\"is_acct_div_param\":0,\"is_delay_acct\":0,\"is_deleted\":0,\"is_route\":\"\",\"iss_inst_id\":\"\",\"maze_bg_date\":\"\",\"maze_bg_seq_id\":\"\",\"maze_pnr_dev_id\":\"\",\"maze_resp_code\":\"\",\"maze_resp_desc\":\"\",\"mcc\":\"\",\"mer_name\":\"上海汇涵信息科技服务有限公司\",\"mer_ord_id\":\"20240613105441800448\",\"modifier\":\"\",\"modify_time\":1718247318000,\"mypaytsf_discount\":0.00,\"ord_amt\":0.02,\"ord_id\":\"202406131055040TOP2_BL2684095952\",\"org_acct_id\":\"F00300982\",\"org_auth_no\":\"\",\"org_huifu_seq_id\":\"\",\"org_trans_date\":\"\",\"out_trans_id\":\"4200002303202406139053495866\",\"pa_mer_id\":\"SSP001\",\"party_order_id\":\"03242406133930500803797\",\"pay_amt\":0.02,\"pay_channel\":\"T\",\"pay_channel_id\":\"10000001\",\"pay_scene\":\"02\",\"pay_type\":\"JSAPI\",\"product_id\":\"YYZY\",\"real_acct_id\":\"F00300982\",\"real_cust_id\":\"6666000109133323\",\"real_gate_id\":\"VN\",\"ref_amt\":0.02,\"ref_cnt\":0,\"ref_fee_amt\":0.01,\"ref_num\":\"105504800448\",\"region_id\":\"TOP2_B\",\"req_date\":\"20240613\",\"req_seq_id\":\"20240613105441800448\",\"route_region_id\":\"C24_A\",\"settle_amt\":0.02,\"settle_trans_stat\":\"\",\"sn_code\":\"\",\"source_region_id\":\"TOP2_B\",\"subsidy_amt\":0.00,\"subsidy_ref_amt\":0.00,\"subsidy_stat\":\"I\",\"sys_id\":\"6666000108840829\",\"sys_trace_audit_num\":\"\",\"term_div_coupon_type\":3,\"time_expire\":\"20240613110004\",\"trans_date\":\"20240613\",\"trans_finish_time\":1718247319000,\"trans_notify_url\":\"VIRGO://https://iotpush.cloudpnr.com/ws-mgnt-ser/callback/jspay\",\"trans_stat\":\"S\",\"trans_type\":\"1000\",\"un_scene_info\":\"\",\"unconfirm_amt\":0.02,\"unconfirm_fee_amt\":0.01,\"version\":3},\"trans_stat\":\"S\",\"trans_time\":\"105504\",\"trans_type\":\"T_JSAPI\",\"wx_response\":{\"bank_type\":\"OTHERS\",\"coupon_fee\":\"0.00\",\"openid\":\"o8jhot5QnK-AmVoARPMJjMT-SsX0\",\"sub_appid\":\"wxdfe9a5d141f96685\",\"sub_openid\":\"oozDJ52_y7RMnxObV04Q4bpuNZEM\"}}");
Map map = JsonUtils.fromJson(callbackparam.getRespData(), Map.class);
ResponseDto<Boolean> responseDto = goblinBraceletorderservice.dougongCallBack(callbackparam);
Assert.assertTrue(responseDto.isSuccess());
}
}
package com.liquidnet.service.goblin.test;
import com.liquidnet.commons.lang.util.IDGenerator;
import com.liquidnet.service.goblin.param.dougong.DougongJsPayData;
import com.liquidnet.service.goblin.param.dougong.DougongRequestParam;
import com.liquidnet.service.goblin.service.IGoblinDougongPayService;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Slf4j
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
public class GoblinDougongPayServiceImplTest {
@Autowired
private IGoblinDougongPayService goblinDougongPayService;
private List<DougongRequestParam.WxDataGoodsDetail> getWxDataGoodsDetails() {
HashMap<String, Object> goods1 = new HashMap<>();
goods1.put("id", "1");
goods1.put("name", "手环");
goods1.put("price", "1");
goods1.put("number", 1);
HashMap<String, Object> goods2 = new HashMap<>();
goods2.put("id", "2");
goods2.put("name", "面额充值50元");
goods2.put("price", "50");
goods2.put("number", 1);
// 商品列表
ArrayList<Map<String, Object>> goodsList = new ArrayList<>();
goodsList.add(goods1);
goodsList.add(goods2);
ArrayList<DougongRequestParam.WxDataGoodsDetail> wxDataGoodsDetails = new ArrayList<>();
for (Map<String, Object> stringObjectMap : goodsList) {
DougongRequestParam.WxDataGoodsDetail wxDataGoodsDetail = new DougongRequestParam.WxDataGoodsDetail();
wxDataGoodsDetail.setGoodsId(String.valueOf(stringObjectMap.get("id")));
wxDataGoodsDetail.setGoodsName(String.valueOf(stringObjectMap.get("name")));
wxDataGoodsDetail.setPrice(String.valueOf(stringObjectMap.get("price")));
wxDataGoodsDetail.setQuantity((Integer) stringObjectMap.get("number"));
wxDataGoodsDetails.add(wxDataGoodsDetail);
}
return wxDataGoodsDetails;
}
@Test
public void jsPay() {
// 商品描述
String goodsDesc = "手环充值";
// 商品金额
BigDecimal totalAmt = new BigDecimal("51.00");
// 请求日期
String reqDate = "20250708";
// 交易类型
String tradeType = "T_MINIAPP";
DougongRequestParam requestParam = new DougongRequestParam();
requestParam.setHuifuId("6666000109133323");//TODO 配置
requestParam.setTimeExpire("20250718235959"); //TODO 在计算
requestParam.setNotifyUrl("http://www.baidu.com");//TODO 配置
DougongJsPayData dougongJsPayData = new DougongJsPayData();
dougongJsPayData.setReqDate(reqDate);
dougongJsPayData.setReqSeqId(IDGenerator.nextSnowId());
dougongJsPayData.setGoodsDesc(goodsDesc);
dougongJsPayData.setTradeType(tradeType);
dougongJsPayData.setTransAmt(totalAmt.toString());
dougongJsPayData.setTimeExpire("20250718235959"); //TODO 在计算
dougongJsPayData.setSubOpenid("o8jhotzittQSetZ-N0Yj4Hz91Rqc"); //TODO 前端带过来
dougongJsPayData.setGoodsDetailList(getWxDataGoodsDetails());
System.out.println(goblinDougongPayService.jsPay(dougongJsPayData));
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment