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

Commit 964a3cfe authored by wangyifan's avatar wangyifan

Merge branch 'master' into dev-caomeihuzhao-V1.1

parents 633e0966 f2af79bb
-- 商品订单:粉丝俱乐部来源(与 source[app|h5|applet] 语义分离)
ALTER TABLE goblin_store_order
ADD COLUMN order_source varchar(255) NOT NULL DEFAULT '' COMMENT '粉丝俱乐部来源标识' AFTER source,
ADD COLUMN referrer_user_id varchar(64) NOT NULL DEFAULT '' COMMENT '粉丝俱乐部侧用户id' AFTER order_source;
-- 演出订单:粉丝俱乐部来源标记
ALTER TABLE kylin_order_tickets
ADD COLUMN referrer_user_id varchar(64) NOT NULL DEFAULT '' COMMENT '粉丝俱乐部侧用户id' AFTER order_source;
This diff is collapsed.
...@@ -47,8 +47,10 @@ public class DragonConstant { ...@@ -47,8 +47,10 @@ public class DragonConstant {
} }
public enum DeviceFromEnum{ public enum DeviceFromEnum{
WEB("web",""),WAP("wap",""),WAPPAGE("wappage","") WEB("web","PC网页"),WAP("wap","手机网页"),WAPPAGE("wappage","WAP页")
,APP("app",""),JS("js",""),APPLET("applet",""),APPLETB("appletb",""),MICROPAY("micropay",""); ,APP("app","App"),JS("js","微信内网页"),APPLET("applet","正在现场小程序"),APPLETB("appletb","摩登小程序")
,APPLET_DOUDOU("appletdoudou","DouDou小程序"),APPLET_MOOTOO("appletmootoo","mootoo小程序")
,APPLET_WENQUE("appletwenque","wenque小程序"),MICROPAY("micropay","付款码/扫码枪");
private String code; private String code;
private String message; private String message;
DeviceFromEnum(String code, String message) { DeviceFromEnum(String code, String message) {
...@@ -216,6 +218,10 @@ public class DragonConstant { ...@@ -216,6 +218,10 @@ public class DragonConstant {
return arry[i]; return arry[i];
} }
} }
// 兼容 APPLETDOUDOUWEPAY 等新类型:查单仍走小程序微信策略
if (code != null && code.contains("APPLET") && code.endsWith("WEPAY")) {
return PAYMENT_TYPE_APPLET_WEPAY;
}
return null; return null;
} }
......
package com.liquidnet.service.dragon.doc;
/**
* 支付相关 Swagger 文案(与 {@link com.liquidnet.service.dragon.support.WepayAppletPaySupport} 业务逻辑分离)。
*/
public final class DragonPaySwaggerDoc {
public static final String DEVICE_FROM_VALUE =
"支付终端。微信小程序微信支付:applet=正在现场,appletb=摩登,appletdoudou=DouDou,appletmootoo=mootoo,appletwenque=wenque;"
+ "须配合 payType=wepay 并传当前小程序 openId(sweet maOpenId type 分别为 4/7/8/9/10)。"
+ "其他:app、wap、js、web、wappage;micropay=付款码/扫码枪(payType 传 wepay 或 alipay,须 authCode,非银联)。"
+ "银联云闪付用 payType=unionpay,deviceFrom 一般为 app 或 wap,与 micropay 无关。";
public static final String DEVICE_FROM_ALLOWABLE =
"applet,appletb,appletdoudou,appletmootoo,appletwenque,app,wap,js,web,wappage,micropay";
public static final String PAY_TYPE_VALUE = "支付方式:wepay、alipay、douyinpay、unionpay、applepay 等";
public static final String PAY_TYPE_ALLOWABLE = "wepay,alipay,douyinpay,unionpay,applepay";
public static final String OPEN_ID_VALUE =
"微信 JSAPI/小程序支付必填,须为当前 deviceFrom 对应小程序的 openId";
private DragonPaySwaggerDoc() {
}
}
package com.liquidnet.service.dragon.support;
import com.liquidnet.service.dragon.dto.DragonPayBaseReqDto;
/**
* 微信小程序支付:deviceFrom / appIdType / paymentType 约定(不含 appid,appid 见 order 内 {@code WepayAppletPayConfigure})。
*/
public final class WepayAppletPaySupport {
public static final String DEVICE_APPLETB = "appletb";
public static final String DEVICE_APPLET_DOUDOU = "appletdoudou";
public static final String DEVICE_APPLET_MOOTOO = "appletmootoo";
public static final String DEVICE_APPLET_WENQUE = "appletwenque";
public static final String APP_ID_TYPE_B = "b";
public static final String APP_ID_TYPE_DOUDOU = "doudou";
public static final String APP_ID_TYPE_MOOTOO = "mootoo";
public static final String APP_ID_TYPE_WENQUE = "wenque";
private WepayAppletPaySupport() {
}
public static boolean requiresWechatOpenId(String deviceFrom) {
if (deviceFrom == null) {
return false;
}
return "js".equalsIgnoreCase(deviceFrom)
|| "applet".equalsIgnoreCase(deviceFrom)
|| DEVICE_APPLETB.equalsIgnoreCase(deviceFrom)
|| DEVICE_APPLET_DOUDOU.equalsIgnoreCase(deviceFrom)
|| DEVICE_APPLET_MOOTOO.equalsIgnoreCase(deviceFrom)
|| DEVICE_APPLET_WENQUE.equalsIgnoreCase(deviceFrom);
}
/**
* 将 appletdoudou 等 deviceFrom 规范为 applet,并写入 appIdType。
*/
public static void applyAppletDeviceFrom(DragonPayBaseReqDto dto) {
if (dto == null || dto.getDeviceFrom() == null) {
return;
}
String deviceFrom = dto.getDeviceFrom();
if (DEVICE_APPLETB.equals(deviceFrom)) {
dto.setDeviceFrom("applet");
dto.setAppIdType(APP_ID_TYPE_B);
} else if (DEVICE_APPLET_DOUDOU.equals(deviceFrom)) {
dto.setDeviceFrom("applet");
dto.setAppIdType(APP_ID_TYPE_DOUDOU);
} else if (DEVICE_APPLET_MOOTOO.equals(deviceFrom)) {
dto.setDeviceFrom("applet");
dto.setAppIdType(APP_ID_TYPE_MOOTOO);
} else if (DEVICE_APPLET_WENQUE.equals(deviceFrom)) {
dto.setDeviceFrom("applet");
dto.setAppIdType(APP_ID_TYPE_WENQUE);
}
}
public static boolean usesMerchantB(String appIdType) {
return APP_ID_TYPE_B.equals(appIdType);
}
public static boolean usesMerchantBByPaymentType(String paymentType) {
return paymentType != null && paymentType.contains("APPLETB");
}
/**
* 小程序微信 JSAPI:含历史 APPLETWEPAY、APPLETBWEPAY 及 APPLETDOUDOUWEPAY 等。
*/
public static boolean isAppletWechatPaymentType(String paymentType) {
return paymentType != null && paymentType.contains("APPLET") && paymentType.endsWith("WEPAY");
}
/** 场次批量退款统计:微信渠道 payment_type 白名单 */
public static String[] wechatPaymentTypesForRefundStatis() {
return new String[]{
"APPWEPAY", "APPLETWEPAY", "APPLETBWEPAY",
"APPLETDOUDOUWEPAY", "APPLETMOOTOOWEPAY", "APPLETWENQUEWEPAY",
"WAPWEPAY", "JSWEPAY", "wepay", "MICROPAYWEPAY"
};
}
/** 场次批量退款统计:支付宝渠道 payment_type 白名单 */
public static String[] alipayPaymentTypesForRefundStatis() {
return new String[]{"APPALIPAY", "WAPALIPAY", "APPLETALIPAY", "alipay"};
}
/** Admin 列表/详情:payment_type 展示文案 */
public static String paymentChannelDisplayLabel(String paymentType) {
if (paymentType == null || paymentType.trim().isEmpty()) {
return "";
}
String pt = paymentType.trim();
if (pt.contains("UNIONPAY")) {
return "银联云闪付";
}
if (pt.contains("DOUYIN")) {
return "抖音支付";
}
if (pt.contains("ALIPAY") || "alipay".equalsIgnoreCase(pt)) {
return "支付宝";
}
if (isAppletWechatPaymentType(pt)) {
if (pt.contains("DOUDOU")) {
return "微信(DouDou)";
}
if (pt.contains("MOOTOO")) {
return "微信(mootoo)";
}
if (pt.contains("WENQUE")) {
return "微信(wenque)";
}
if (pt.contains("APPLETB")) {
return "微信(摩登)";
}
return "微信小程序";
}
if (pt.endsWith("WEPAY") || "wepay".equalsIgnoreCase(pt)) {
return "微信";
}
return pt;
}
}
...@@ -27,6 +27,12 @@ ...@@ -27,6 +27,12 @@
<artifactId>liquidnet-service-dragon-api</artifactId> <artifactId>liquidnet-service-dragon-api</artifactId>
<version>1.0-SNAPSHOT</version> <version>1.0-SNAPSHOT</version>
</dependency> </dependency>
<dependency>
<groupId>com.liquidnet</groupId>
<artifactId>liquidnet-common-third-sqb</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies> </dependencies>
</project> </project>
\ No newline at end of file
package com.liquidnet.service.goblin.constant;
import com.liquidnet.service.goblin.dto.vo.GoblinGoodsInfoVo;
/**
* 商品「是否展示到商城」取值约定:0-否,1-是。
* 落库 / 写 SQL 参数时统一通过 {@link #resolve(GoblinGoodsInfoVo)},避免各处 magic number。
*/
public final class GoblinGoodsShowInMallHelper {
public static final int SHOW_IN_MALL_YES = 1;
public static final int SHOW_IN_MALL_NO = 0;
/** 收钱吧演出关联商品,与前台 {@code spuType=33} 约定一致 */
public static final int SQB_SPU_TYPE = 33;
private GoblinGoodsShowInMallHelper() {
}
/**
* 解析落库用的 show_in_mall:VO 已赋值则沿用;未赋值时普通商品默认展示,SQB 商品默认不展示。
*/
public static int resolve(GoblinGoodsInfoVo vo) {
if (vo == null) {
return SHOW_IN_MALL_YES;
}
if (vo.getShowInMall() != null) {
return vo.getShowInMall();
}
return vo.getSpuType() == SQB_SPU_TYPE ? SHOW_IN_MALL_NO : SHOW_IN_MALL_YES;
}
/** 请求参数未传时的默认值(普通商品 add/edit) */
public static int defaultFromRequest(Integer showInMall) {
return showInMall == null ? SHOW_IN_MALL_YES : showInMall;
}
}
...@@ -430,4 +430,39 @@ public class GoblinRedisConst { ...@@ -430,4 +430,39 @@ public class GoblinRedisConst {
/* ----------------------------------------------------------------- */ /* ----------------------------------------------------------------- */
/* ----------------------------------------------------------------- */ /* ----------------------------------------------------------------- */
/* ----------------------------------------------------------------- */ /* ----------------------------------------------------------------- */
/**
* 收钱吧订单详情
*/
public static final String SQB_ORDER = PREFIX.concat("sqb:order:");
/**
* 演出关联收钱吧商品缓存 performancesId
*/
public static final String SQB_PERFORMANCE_GOODS = PREFIX.concat("sqb:perf:goods:");
/**
* 收钱吧下单防重锁
*/
public static final String SQB_ORDER_LOCK = PREFIX.concat("sqb:order:lock:");
/**
* 收钱吧订单扩展 key
*/
public static final String SQB_GOBLIN_GOODS_EXT_KEY = PREFIX.concat("sqb:goods:ext:");
/**
* 收钱吧 orderSn与正在orderId 对应关系 key
*/
public static final String SQB_GOBLIN_ORDER_SN_KEY = PREFIX.concat("sqb:orderSn:");
/**
* 收钱吧 用户订单列表
*/
public static final String SQB_GOBLIN_ORDER_LIST = PREFIX.concat("sqb:order:id:list:");//用户订单id列表 key:$uid
/**
* 演出关联收钱吧商品换购价 缓存 performancesId:skuId
*/
public static final String SQB_SKU_PRICE = PREFIX.concat("sqb:sku:price:");
} }
package com.liquidnet.service.goblin.dto.manage; package com.liquidnet.service.goblin.dto.manage;
import com.liquidnet.service.dragon.doc.DragonPaySwaggerDoc;
import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
...@@ -9,7 +10,7 @@ import java.util.ArrayList; ...@@ -9,7 +10,7 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
@ApiModel(value = "GoblinOrderParam") @ApiModel(value = "GoblinOrderParam", description = "POST /goblin/pre 商城下单。微信小程序微信支付见 deviceFrom 与 openId 说明。")
@Data @Data
public class GoblinOrderParam { public class GoblinOrderParam {
...@@ -17,13 +18,13 @@ public class GoblinOrderParam { ...@@ -17,13 +18,13 @@ public class GoblinOrderParam {
private ArrayList<String> addressIds; private ArrayList<String> addressIds;
@ApiModelProperty(value = "代理id") @ApiModelProperty(value = "代理id")
private String agentId; private String agentId;
@ApiModelProperty(value = "支付类型") @ApiModelProperty(value = DragonPaySwaggerDoc.PAY_TYPE_VALUE, allowableValues = DragonPaySwaggerDoc.PAY_TYPE_ALLOWABLE, example = "wepay")
@NotNull(message = "支付类型不能为空") @NotNull(message = "支付类型不能为空")
private String payType; private String payType;
@ApiModelProperty(value = "支付来源 [新增micropay-微信扫码支付]") @ApiModelProperty(value = DragonPaySwaggerDoc.DEVICE_FROM_VALUE, allowableValues = DragonPaySwaggerDoc.DEVICE_FROM_ALLOWABLE, example = "applet")
@NotNull(message = "支付来源不能为空") @NotNull(message = "支付来源不能为空")
private String deviceFrom; private String deviceFrom;
@ApiModelProperty(value = "openId") @ApiModelProperty(value = DragonPaySwaggerDoc.OPEN_ID_VALUE)
private String openId; private String openId;
@ApiModelProperty(value = "showUrl") @ApiModelProperty(value = "showUrl")
private String showUrl; private String showUrl;
...@@ -37,5 +38,9 @@ public class GoblinOrderParam { ...@@ -37,5 +38,9 @@ public class GoblinOrderParam {
private AddressVo addressesVo; private AddressVo addressesVo;
@ApiModelProperty(value = "商品相关参数集合") @ApiModelProperty(value = "商品相关参数集合")
private List<GoblinOrderStoreParam> goblinOrderStoreParamList; private List<GoblinOrderStoreParam> goblinOrderStoreParamList;
@ApiModelProperty(value = "粉丝俱乐部来源标识,如DOUDOU之家;与 referrerUserId 同时传才打标")
private String referrerApp;
@ApiModelProperty(value = "粉丝俱乐部侧用户id")
private String referrerUserId;
} }
package com.liquidnet.service.goblin.dto.manage;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
@ApiModel(value = "GoblinSqbOrderParam")
@Data
public class GoblinSqbOrderParam {
@ApiModelProperty(required = true, value = "apuId")
@NotBlank(message = "商品不能为空")
private String spuId;
@ApiModelProperty(required = true, value = "skuId")
@NotBlank(message = "商品规格不能为空")
private String skuId;
@ApiModelProperty(required = true, value = "购买数量")
@NotNull(message = "购买数量不能为空")
private Integer quantity;
@ApiModelProperty(required = true, value = "关联演出ID(须与后台演出-商品关联一致;有换购价时按换购价计价)")
@NotBlank(message = "关联演出ID不能为空")
private String performancesId;
@ApiModelProperty(required = true, value = "微信 openId(对应支付小程序 appid 下的用户唯一 openid)")
@NotBlank(message = "openId不能为空")
private String openId;
}
...@@ -6,6 +6,7 @@ import com.liquidnet.commons.lang.util.CollectionUtil; ...@@ -6,6 +6,7 @@ import com.liquidnet.commons.lang.util.CollectionUtil;
import com.liquidnet.commons.lang.util.DateUtil; import com.liquidnet.commons.lang.util.DateUtil;
import com.liquidnet.commons.lang.util.IDGenerator; import com.liquidnet.commons.lang.util.IDGenerator;
import com.liquidnet.service.base.ErrorMapping; import com.liquidnet.service.base.ErrorMapping;
import com.liquidnet.service.goblin.constant.GoblinGoodsShowInMallHelper;
import com.liquidnet.service.goblin.dto.GoblinGoodsSpecDto; import com.liquidnet.service.goblin.dto.GoblinGoodsSpecDto;
import com.liquidnet.service.goblin.dto.vo.GoblinGoodsInfoVo; import com.liquidnet.service.goblin.dto.vo.GoblinGoodsInfoVo;
import com.liquidnet.service.goblin.dto.vo.GoblinGoodsSkuInfoVo; import com.liquidnet.service.goblin.dto.vo.GoblinGoodsSkuInfoVo;
...@@ -18,6 +19,8 @@ import org.apache.commons.lang3.StringUtils; ...@@ -18,6 +19,8 @@ import org.apache.commons.lang3.StringUtils;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
import javax.validation.Valid; import javax.validation.Valid;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull; import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern; import javax.validation.constraints.Pattern;
...@@ -128,6 +131,10 @@ public class GoblinStoreMgtGoodsAddParam implements Serializable { ...@@ -128,6 +131,10 @@ public class GoblinStoreMgtGoodsAddParam implements Serializable {
@ApiModelProperty(position = 31, required = true, value = "是否虚拟商品[0-否|1-是]", allowableValues = "0,1", example = "0") @ApiModelProperty(position = 31, required = true, value = "是否虚拟商品[0-否|1-是]", allowableValues = "0,1", example = "0")
@Pattern(regexp = "\\b(0|1)\\b", message = "是否虚拟商品参数无效") @Pattern(regexp = "\\b(0|1)\\b", message = "是否虚拟商品参数无效")
private String virtualFlg; private String virtualFlg;
@ApiModelProperty(position = 31, required = false, value = "是否展示到商城[0-否|1-是]", allowableValues = "0,1", example = "1")
@Min(value = 0, message = "是否展示到商城参数无效")
@Max(value = 1, message = "是否展示到商城参数无效")
private Integer showInMall;
/** /**
* ---------------------------- 服务保障 ---------------------------- * ---------------------------- 服务保障 ----------------------------
...@@ -191,6 +198,7 @@ public class GoblinStoreMgtGoodsAddParam implements Serializable { ...@@ -191,6 +198,7 @@ public class GoblinStoreMgtGoodsAddParam implements Serializable {
vo.setShelvesTime(this.getShelvesTime()); vo.setShelvesTime(this.getShelvesTime());
vo.setSpuValidity(this.getSpuValidity()); vo.setSpuValidity(this.getSpuValidity());
vo.setVirtualFlg(this.getVirtualFlg()); vo.setVirtualFlg(this.getVirtualFlg());
vo.setShowInMall(GoblinGoodsShowInMallHelper.defaultFromRequest(this.getShowInMall()));
vo.setStatus("3"); vo.setStatus("3");
// vo.setReason(null); // vo.setReason(null);
// vo.setShelvesStatus("0"); // vo.setShelvesStatus("0");
...@@ -244,6 +252,7 @@ public class GoblinStoreMgtGoodsAddParam implements Serializable { ...@@ -244,6 +252,7 @@ public class GoblinStoreMgtGoodsAddParam implements Serializable {
vo.setShelvesTime(this.getShelvesTime()); vo.setShelvesTime(this.getShelvesTime());
vo.setSpuValidity(this.getSpuValidity()); vo.setSpuValidity(this.getSpuValidity());
vo.setVirtualFlg(this.getVirtualFlg()); vo.setVirtualFlg(this.getVirtualFlg());
vo.setShowInMall(GoblinGoodsShowInMallHelper.defaultFromRequest(this.getShowInMall()));
vo.setImageList(this.getImageList()); vo.setImageList(this.getImageList());
vo.setLogisticsTemplate(this.getLogisticsTemplate()); vo.setLogisticsTemplate(this.getLogisticsTemplate());
// vo.setErpType();// 暂不考虑更改ERP类型 // vo.setErpType();// 暂不考虑更改ERP类型
......
...@@ -4,6 +4,7 @@ import com.liquidnet.commons.lang.constant.LnsRegex; ...@@ -4,6 +4,7 @@ import com.liquidnet.commons.lang.constant.LnsRegex;
import com.liquidnet.commons.lang.util.CollectionUtil; import com.liquidnet.commons.lang.util.CollectionUtil;
import com.liquidnet.commons.lang.util.DateUtil; import com.liquidnet.commons.lang.util.DateUtil;
import com.liquidnet.commons.lang.util.IDGenerator; import com.liquidnet.commons.lang.util.IDGenerator;
import com.liquidnet.service.goblin.constant.GoblinGoodsShowInMallHelper;
import com.liquidnet.service.goblin.dto.GoblinGoodsSpecDto; import com.liquidnet.service.goblin.dto.GoblinGoodsSpecDto;
import com.liquidnet.service.goblin.dto.vo.GoblinGoodsInfoVo; import com.liquidnet.service.goblin.dto.vo.GoblinGoodsInfoVo;
import com.liquidnet.service.goblin.dto.vo.GoblinGoodsSkuInfoVo; import com.liquidnet.service.goblin.dto.vo.GoblinGoodsSkuInfoVo;
...@@ -189,6 +190,7 @@ public class GoblinStoreMgtGoodsCouponAddParam implements Serializable { ...@@ -189,6 +190,7 @@ public class GoblinStoreMgtGoodsCouponAddParam implements Serializable {
vo.setShelvesStatus("0"); vo.setShelvesStatus("0");
} }
vo.setSpuAppear("0"); vo.setSpuAppear("0");
vo.setShowInMall(GoblinGoodsShowInMallHelper.SHOW_IN_MALL_YES);
vo.setDelFlg("0"); vo.setDelFlg("0");
// vo.setShelvesAt(null); // vo.setShelvesAt(null);
vo.setImageList(this.getImageList()); vo.setImageList(this.getImageList());
......
...@@ -47,9 +47,8 @@ public class GoblinStoreMgtGoodsEditSkuParam implements Serializable { ...@@ -47,9 +47,8 @@ public class GoblinStoreMgtGoodsEditSkuParam implements Serializable {
@NotNull(message = "单品默认图片不能为空") @NotNull(message = "单品默认图片不能为空")
@Size(max = 256, message = "单品默认图片URL过长") @Size(max = 256, message = "单品默认图片URL过长")
private String skuPic; private String skuPic;
@ApiModelProperty(position = 14, required = true, value = "单品规格信息") @ApiModelProperty(position = 14, required = false, value = "单品规格信息;编辑时可不传或传[]表示沿用/无规格(如收钱吧同步SKU)")
@Valid @Valid
@NotNull(message = "规格信息不能为空")
private List<GoblinGoodsSpecDto> skuSpecList; private List<GoblinGoodsSpecDto> skuSpecList;
@ApiModelProperty(position = 15, required = false, value = "单品销售价-原价[20,2]") @ApiModelProperty(position = 15, required = false, value = "单品销售价-原价[20,2]")
private BigDecimal sellPrice; private BigDecimal sellPrice;
......
package com.liquidnet.service.goblin.dto.manage;
import com.liquidnet.commons.lang.constant.LnsRegex;
import com.liquidnet.service.goblin.dto.GoblinGoodsSpecDto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.*;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.List;
@ApiModel(value = "GoblinStoreMgtGoodsSqbAddSkuParam", description = "商品管理:添加收钱吧商品:添加SKU入参")
@Data
public class GoblinStoreMgtGoodsSqbAddSkuParam implements Serializable {
private static final long serialVersionUID = 7886534346305369761L;
@ApiModelProperty(position = 10, required = false, value = "单品ID[编辑时必传]")
private String skuId;
// @ApiModelProperty(position = 11, required = false, value = "单品编码[默认为系统编码,也可手动输入商家自己的编码]")
// @Pattern(regexp = LnsRegex.Valid.ALPHABET_NUMBER_UNDER_50, message = "单品编码格式或长度有误")
// private String skuNo;
// @ApiModelProperty(position = 12, required = false, value = "单品条码")
// @Pattern(regexp = LnsRegex.Valid.ALPHABET_NUMBER_32, message = "单品条码格式或长度有误")
// private String skuBarCode;
// @ApiModelProperty(position = 13, required = false, value = "ERP商家编码")
// @Size(max = 40, message = "ERP商家编码长度限制40")
// private String skuErpCode;//-
// @ApiModelProperty(position = 14, required = false, value = "ERP托管[0-否|1-是],默认0")
// @Pattern(regexp = "\\b(0|1)\\b", message = "ERP托管参数无效")
// private String erpHosting;//-
// @ApiModelProperty(position = 15, required = false, value = "ERP仓库编号")
// @Size(max = 40, message = "ERP仓库编号长度限制40")
// private String erpWarehouseNo;//-
// @ApiModelProperty(position = 16, required = false, value = "单品默认图片的url[256]")
// @NotBlank(message = "单品图片不能为空")
// private String skuPic;
@ApiModelProperty(position = 12, required = false, value = "单品规格信息")
// @NotNull(message = "规格信息不能为空")
// @Valid// 初始化写死['规格':'张']
private List<GoblinGoodsSpecDto> skuSpecList;
// @ApiModelProperty(position = 18, required = false, value = "单品销售价-原价[20,2]")
// private BigDecimal sellPrice;
@ApiModelProperty(position = 19, required = true, value = "单品现价[20,2]")
@Digits(integer = 6, fraction = 2, message = "参数'单品现价'无效")
@DecimalMin(value = "0.01", message = "参数'单品现价'必须为大于0")
private BigDecimal price;
// @ApiModelProperty(position = 20, required = false, value = "单品会员价格[20,2]")
// @NotNull(message = "单品会员价格不能为空")
// @Min(value = 0, message = "单品会员价格不能小于0")
// private BigDecimal priceMember;
// @ApiModelProperty(position = 21, required = false, value = "单品的重量[20,2]")
// private BigDecimal weight;//-
@ApiModelProperty(position = 20, required = true, value = "总库存")
@Min(value = 0, message = "总库存不能小于0")
private Integer stock;
// @ApiModelProperty(position = 21, required = false, value = "预警库存")
// private Integer warningStock;
// @ApiModelProperty(position = 22, required = false, value = "ISBN,针对CD/图书等[100]")
// private String skuIsbn;//-
// @ApiModelProperty(position = 23, required = false, value = "购买限制[0-全部用户|1-仅会员|2-指定用户]")
// @NotNull(message = "购买限制不能为空")
// private String buyFactor;
// @ApiModelProperty(position = 24, required = false, value = "购买限制人员名单[购买限制为2-指定用户时必填]")
// private String buyRoster;
@ApiModelProperty(position = 25, required = false, value = "限量[0-无限制|X:限购数量]")
private Integer buyLimit;
// @ApiModelProperty(position = 26, required = false, value = "单品有效期[yyyy-MM-dd HH:mm:ss]")
// @Pattern(regexp = LnsRegex.Valid.DATETIME_FULL, message = "单品有效期格式有误")
// private String skuValidity;
// @ApiModelProperty(position = 27, required = false, value = "自定义展示[0-默认展示|1-隐藏不可购买]")
// private String skuAppear;
/**
* ---------------------------- 收钱吧商品-代金券属性 ----------------------------
*/
@ApiModelProperty(position = 28, required = true, value = "是否实名[0-否|1-是,表示该商品需要实名关联]", allowableValues = "0,1", example = "1")
@Pattern(regexp = "\\b(0|1)\\b", message = "参数'是否实名'无效")
private String isTrueName;
@ApiModelProperty(position = 29, required = true, value = "适用范围[101-音乐节|102-小型演出(livehouse演出)|103-巡演]", allowableValues = "101,102,103", example = "101")
@Pattern(regexp = "\\b(101|102|103)\\b", message = "参数'适用范围'无效")
private String useScope;
@ApiModelProperty(position = 30, required = true, value = "面值", example = "99.00")
@Digits(integer = 3, fraction = 2, message = "参数'面值'无效")
@DecimalMin(value = "0.01", message = "参数'面值'必须为大于0")
private BigDecimal valFace;
@ApiModelProperty(position = 31, required = true, value = "开始时间[yyyy-MM-dd HH:mm:ss]", example = "2024-01-01 00:00:00")
@Pattern(regexp = LnsRegex.Valid.DATETIME_FULL, message = "开始时间格式有误")
@NotNull(message = "参数'开始时间'不可为空")
private String effectAt;
@ApiModelProperty(position = 32, required = true, value = "结束时间[yyyy-MM-dd HH:mm:ss]", example = "2024-12-31 00:00:00")
@Pattern(regexp = LnsRegex.Valid.DATETIME_FULL, message = "结束时间格式有误")
@NotNull(message = "参数'结束时间'不可为空")
private String expireAt;
}
package com.liquidnet.service.goblin.dto.manage;
import com.liquidnet.commons.lang.constant.LnsRegex;
import com.liquidnet.commons.lang.util.DateUtil;
import com.liquidnet.service.goblin.dto.vo.GoblinGoodsSkuInfoVo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.*;
import java.io.Serializable;
import java.math.BigDecimal;
@ApiModel(value = "GoblinStoreMgtGoodsSqbEditSkuParam", description = "商品管理:编辑收钱吧商品:编辑SKU入参")
@Data
public class GoblinStoreMgtGoodsSqbEditSkuParam implements Serializable {
private static final long serialVersionUID = 8174428924922310702L;
@ApiModelProperty(position = 10, required = true, value = "店铺ID[64]")
@NotBlank(message = "店铺ID不能为空")
private String storeId;
@ApiModelProperty(position = 11, required = true, value = "商品ID[64]")
@NotNull(message = "商品ID不能为空")
private String spuId;
@ApiModelProperty(position = 12, required = true, value = "单品ID[编辑时必传]")
@NotNull(message = "商品SKU_ID不能为空")
private String skuId;
@ApiModelProperty(position = 13, required = true, value = "单品现价[20,2]")
@Digits(integer = 3, fraction = 2, message = "参数'单品现价'无效")
@DecimalMin(value = "0.01", message = "参数'单品现价'必须为大于0")
private BigDecimal price;
@ApiModelProperty(position = 14, required = true, value = "限量[0-无限制|X:限购数量]")
@Min(value = 0, message = "参数'限购数量'不能小于0")
@NotNull(message = "参数'限购数量'不可为空")
private Integer buyLimit;
@ApiModelProperty(position = 15, required = false, value = "总库存")
private Integer stock;
@ApiModelProperty(position = 16, required = false, value = "总库存")
private Integer skuStock;
@ApiModelProperty(position = 17, required = false, value = "加减库存")
private Integer operStock;
/**
* ---------------------------- 收钱吧商品-代金券属性 ----------------------------
*/
@ApiModelProperty(position = 18, required = true, value = "是否实名[0-否|1-是,表示该商品需要实名关联]", example = "1")
@Pattern(regexp = "\\b(0|1)\\b", message = "参数'是否实名'无效")
private String isTrueName;
@ApiModelProperty(position = 19, required = true, value = "适用范围[101-音乐节|102-小型演出(livehouse演出)|103-巡演]")
@Pattern(regexp = "\\b(101|102|103)\\b", message = "参数'适用范围'无效")
private String useScope;
@ApiModelProperty(position = 20, required = true, value = "面值", example = "99.00")
@Digits(integer = 3, fraction = 2, message = "参数'面值'无效")
@DecimalMin(value = "0.01", message = "参数'面值'必须为大于0")
private BigDecimal valFace;
@ApiModelProperty(position = 21, required = true, value = "结束时间[yyyy-MM-dd HH:mm:ss]", example = "2024-01-01 00:00:00")
@Pattern(regexp = LnsRegex.Valid.DATETIME_FULL, message = "开始时间格式有误")
@NotNull(message = "参数'开始时间'不可为空")
private String effectAt;
@ApiModelProperty(position = 22, required = true, value = "结束时间[yyyy-MM-dd HH:mm:ss]", example = "2024-12-31 00:00:00")
@Pattern(regexp = LnsRegex.Valid.DATETIME_FULL, message = "结束时间格式有误")
@NotNull(message = "参数'结束时间'不可为空")
private String expireAt;
public GoblinGoodsSkuInfoVo initEditGoodsSkuInfoVo() {
GoblinGoodsSkuInfoVo goodsSkuInfoVo = GoblinGoodsSkuInfoVo.getNew();
goodsSkuInfoVo.setSkuType(2);
goodsSkuInfoVo.setSkuId(this.getSkuId());
goodsSkuInfoVo.setPrice(this.getPrice());
goodsSkuInfoVo.setPriceMember(this.getPrice());
goodsSkuInfoVo.setBuyLimit(this.getBuyLimit());
goodsSkuInfoVo.setStock(this.getStock());
goodsSkuInfoVo.setSkuStock(this.getSkuStock());
goodsSkuInfoVo.setIsTrueName(Integer.valueOf(this.getIsTrueName()));
goodsSkuInfoVo.setUseScope(Integer.valueOf(this.getUseScope()));
goodsSkuInfoVo.setValFace(this.getValFace());
goodsSkuInfoVo.setEffectAt(DateUtil.Formatter.yyyyMMddHHmmss.parse(this.getEffectAt()));
goodsSkuInfoVo.setExpireAt(DateUtil.Formatter.yyyyMMddHHmmss.parse(this.getExpireAt()));
return goodsSkuInfoVo;
}
}
package com.liquidnet.service.goblin.dto.manage; package com.liquidnet.service.goblin.dto.manage;
import com.liquidnet.service.dragon.doc.DragonPaySwaggerDoc;
import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
...@@ -17,13 +18,13 @@ public class MixOrderParam { ...@@ -17,13 +18,13 @@ public class MixOrderParam {
private String mixId; private String mixId;
@ApiModelProperty(value = "入场人地址vo") @ApiModelProperty(value = "入场人地址vo")
private AddressVo addressesVo; private AddressVo addressesVo;
@ApiModelProperty(value = "支付类型") @ApiModelProperty(value = DragonPaySwaggerDoc.PAY_TYPE_VALUE, allowableValues = DragonPaySwaggerDoc.PAY_TYPE_ALLOWABLE, example = "wepay")
@NotNull(message = "支付类型不能为空") @NotNull(message = "支付类型不能为空")
private String payType; private String payType;
@ApiModelProperty(value = "支付来源 [新增micropay-微信扫码支付]") @ApiModelProperty(value = DragonPaySwaggerDoc.DEVICE_FROM_VALUE, allowableValues = DragonPaySwaggerDoc.DEVICE_FROM_ALLOWABLE, example = "applet")
@NotNull(message = "支付来源不能为空") @NotNull(message = "支付来源不能为空")
private String deviceFrom; private String deviceFrom;
@ApiModelProperty(value = "openId") @ApiModelProperty(value = DragonPaySwaggerDoc.OPEN_ID_VALUE)
private String openId; private String openId;
@ApiModelProperty(value = "showUrl") @ApiModelProperty(value = "showUrl")
private String showUrl; private String showUrl;
......
package com.liquidnet.service.goblin.dto.vo;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
import java.math.BigDecimal;
@Data
public class GoblinAdminSqbGoodsVo implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "商品spuId")
private String spuId;
@ApiModelProperty(value = "商品skuId")
private String skuId;
@ApiModelProperty(value = "商品(SPU)名称,用于按商品名搜索与展示")
private String spuTitle;
@ApiModelProperty(value = "规格(SKU)名称")
private String skuTitle;
@ApiModelProperty(value = "单品默认图片的url")
private String skuPic;
@ApiModelProperty(value = "商品描述")
private String productIntroduction;
@ApiModelProperty(value = "列表展示用:一般为 spuTitle-skuTitle")
private String title;
@ApiModelProperty(value = "单品现价")
private BigDecimal price;
@ApiModelProperty(value = "单品库存")
private Integer skuStock;
@ApiModelProperty(value = "是否允许关联演出(SPU+SKU 均上架且未删除)")
private Boolean linkable;
@ApiModelProperty(value = "上下架展示:上架 / 已下架 等")
private String shelfStatusLabel;
}
...@@ -55,6 +55,10 @@ public class GoblinAppOrderListVo implements Serializable, Cloneable { ...@@ -55,6 +55,10 @@ public class GoblinAppOrderListVo implements Serializable, Cloneable {
private String mixId; private String mixId;
@ApiModelProperty(value = " 混合售名称") @ApiModelProperty(value = " 混合售名称")
private String mixName; private String mixName;
@ApiModelProperty(value = "粉丝俱乐部来源标识")
private String referrerApp;
@ApiModelProperty(value = "粉丝俱乐部侧用户id")
private String referrerUserId;
private static final GoblinAppOrderListVo obj = new GoblinAppOrderListVo(); private static final GoblinAppOrderListVo obj = new GoblinAppOrderListVo();
public static GoblinAppOrderListVo getNew() { public static GoblinAppOrderListVo getNew() {
......
...@@ -21,16 +21,22 @@ import java.util.List; ...@@ -21,16 +21,22 @@ import java.util.List;
public class GoblinFrontGoodDetailVo implements Serializable { public class GoblinFrontGoodDetailVo implements Serializable {
//spu //spu
GoblinGoodsInfoDetailVo goblinGoodsInfoVo; GoblinGoodsInfoDetailVo goblinGoodsInfoVo;
//sku //sku
List<GoblinGoodsSkuInfoDetailVo> goblinGoodsSkuInfoVolist; List<GoblinGoodsSkuInfoDetailVo> goblinGoodsSkuInfoVolist;
@ApiModelProperty(value = "商铺名称") @ApiModelProperty(value = "商铺名称")
String storeName; String storeName;
@ApiModelProperty(value = "商品可参与券类型") @ApiModelProperty(value = "商品可参与券类型")
ArrayList<String> getSpuType; ArrayList<String> getSpuType;
@ApiModelProperty(value = "条码识别到的SKUID列表", notes = "仅当条码识别时有效") @ApiModelProperty(value = "条码识别到的SKUID列表", notes = "仅当条码识别时有效")
private List<String> hitSkuIdList; private List<String> hitSkuIdList;
@ApiModelProperty(value = "当前用户是否已购买本场演出门票(与收钱吧下单换购价校验一致);仅收钱吧商品(spuType=33)且传入 performancesId 时返回 true/false,其他情况为 null;未登录为 false")
private Boolean boughtPerformance;
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
private static final GoblinFrontGoodDetailVo obj = new GoblinFrontGoodDetailVo(); private static final GoblinFrontGoodDetailVo obj = new GoblinFrontGoodDetailVo();
......
...@@ -91,6 +91,8 @@ public class GoblinGoodsInfoVo implements Serializable, Cloneable { ...@@ -91,6 +91,8 @@ public class GoblinGoodsInfoVo implements Serializable, Cloneable {
private String shelvesStatus; private String shelvesStatus;
@ApiModelProperty(position = 37, value = "是否隐藏[0-默认展示|1-隐藏]") @ApiModelProperty(position = 37, value = "是否隐藏[0-默认展示|1-隐藏]")
private String spuAppear; private String spuAppear;
@ApiModelProperty(position = 37, value = "是否展示到商城[0-否|1-是]")
private Integer showInMall;
@ApiModelProperty(position = 37, value = "是否购买[0-否|1-是]") @ApiModelProperty(position = 37, value = "是否购买[0-否|1-是]")
private String spuCanbuy; private String spuCanbuy;
@ApiModelProperty(position = 37, value = "创作者") @ApiModelProperty(position = 37, value = "创作者")
...@@ -146,6 +148,13 @@ public class GoblinGoodsInfoVo implements Serializable, Cloneable { ...@@ -146,6 +148,13 @@ public class GoblinGoodsInfoVo implements Serializable, Cloneable {
@ApiModelProperty(position = 63, value = "skuList") @ApiModelProperty(position = 63, value = "skuList")
private List<GoblinGoodsSkuInfoVo> goblinOrderSkuVos; private List<GoblinGoodsSkuInfoVo> goblinOrderSkuVos;
@ApiModelProperty(position = 70, value = "收钱吧SPU ID")
private String sqbSpuId;
@ApiModelProperty(position = 71, value = "收钱吧商城编号")
private String mallSn;
@ApiModelProperty(position = 71, value = "收钱吧商城名称")
private String sqbStoreName;
public String getMarketType() { public String getMarketType() {
if (marketId == null) { if (marketId == null) {
return ""; return "";
......
...@@ -32,19 +32,26 @@ public class GoblinGoodsSkuInfoDetailVo implements Serializable, Cloneable { ...@@ -32,19 +32,26 @@ public class GoblinGoodsSkuInfoDetailVo implements Serializable, Cloneable {
private String skuAppear; private String skuAppear;
@ApiModelProperty(position = 11, value = "商品ID[64]") @ApiModelProperty(position = 11, value = "商品ID[64]")
private String spuId; private String spuId;
@ApiModelProperty(position = 12, value = "true 没有库存了, false 有库存") @ApiModelProperty(position = 12, value = "是否无库存(实时:Redis 库存 getSkuStock,stock<=0 为 true;售罄判断优先用此字段或 restStock)")
private boolean stockLess; private boolean stockLess;
@ApiModelProperty(position = 13, value = "可以购买数量") @ApiModelProperty(position = 13, value = "限购维度可买数:buyLimit=0 时为 -9999 表示不限购;否则为 buyLimit-用户已购数(与 restStock 无强制取小,下单仍以库存为准)")
private int canBuy; private int canBuy;
@ApiModelProperty(position = 13, value = "单品的名称[100]") @ApiModelProperty(position = 13, value = "单品的名称[100]")
private String name; private String name;
@ApiModelProperty(position = 20, value = "单品销售价-原价[20,2]") @ApiModelProperty(position = 20, value = "单品销售价-原价[20,2]")
private BigDecimal sellPrice; private BigDecimal sellPrice;
@ApiModelProperty(value = "收钱吧商品(spuType=33)演出关联换购价(元);其他商品类型恒为 null;SQB 且传入 performancesId 且后台已配置时返回")
private BigDecimal settlementPrice;
@ApiModelProperty(position = 26, value = "限量[0-无限制|X:限购数量]") @ApiModelProperty(position = 26, value = "限量[0-无限制|X:限购数量]")
private Integer buyLimit; private Integer buyLimit;
@ApiModelProperty(position = 27, value = "剩余库存") @ApiModelProperty(position = 27, value = "剩余库存(实时:Redis getSkuStock)")
private Integer restStock; private Integer restStock;
@ApiModelProperty(position = 28, value = "单品是否可买[0-否|1-是](来自 Redis/Mongo SKU 文档,BeanUtils 拷贝;与 stockLess 可能不同步时以 stockLess/restStock 为准)")
private String skuCanbuy;
@ApiModelProperty(position = 29, value = "是否售罄标记[0-否|1-是](SKU 主数据字段;列表/详情中实时售罄以 stockLess、restStock 为准)")
private String soldoutStatus;
@ApiModelProperty(position = 51, value = "是否实名[0-否|1-是,表示该商品需要实名关联]") @ApiModelProperty(position = 51, value = "是否实名[0-否|1-是,表示该商品需要实名关联]")
private Integer isTrueName; private Integer isTrueName;
......
...@@ -78,7 +78,7 @@ public class GoblinOrderSkuVo implements Serializable, Cloneable { ...@@ -78,7 +78,7 @@ public class GoblinOrderSkuVo implements Serializable, Cloneable {
* ---------------------------- 以下为券类商品-代金券属性 ---------------------------- * ---------------------------- 以下为券类商品-代金券属性 ----------------------------
*/ */
@ApiModelProperty(value = "商品类型[0-常规|1-数字藏品|2-券类商品]") @ApiModelProperty(value = "商品类型[0-常规|1-数字藏品|2-券类商品] 33-收钱吧商品")
private Integer skuType; private Integer skuType;
@ApiModelProperty(value = "是否实名[0-否|1-是,表示该商品需要实名关联],这里默认0") @ApiModelProperty(value = "是否实名[0-否|1-是,表示该商品需要实名关联],这里默认0")
private Integer isTrueName; private Integer isTrueName;
......
package com.liquidnet.service.goblin.dto.vo;
import io.swagger.annotations.ApiModel;
import lombok.Data;
import java.io.Serializable;
@Data
@ApiModel(value = "用户端-查询券码-VO")
public class GoblinSqbCouponVo implements Serializable {
private static final long serialVersionUID = 1L;
private String couponSn;
private String couponQrCode;
private String couponExpireTime;
}
package com.liquidnet.service.goblin.dto.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import java.io.Serializable;
@Data
@ApiModel(value = "收钱吧商品扩展-VO-redis")
public class GoblinSqbGoodsExtVo implements Serializable {
@ApiModelProperty(value = " goblin_goods.spu_id")
private String spuId;
@ApiModelProperty(value = "关联 goblin_goods_sku.sku_id")
private String skuId;
@ApiModelProperty(value = "所属收钱吧商城编号")
private String mallSn;
@ApiModelProperty(value = "商城签名")
private String signature;
@ApiModelProperty(value = "收钱吧商品ID")
private String sqbSpuId;
@ApiModelProperty(value = "收钱吧规格ID (skuId)")
private String sqbSkuId;
public static GoblinSqbGoodsExtVo of(String spuId,
String skuId,
String mallSn,
String signature,
String sqbSpuId,
String sqbSkuId) {
GoblinSqbGoodsExtVo extVo = new GoblinSqbGoodsExtVo();
extVo.setSpuId(spuId);
extVo.setSkuId(skuId);
extVo.setMallSn(mallSn);
extVo.setSignature(signature);
extVo.setSqbSpuId(sqbSpuId);
extVo.setSqbSkuId(sqbSkuId);
return extVo;
}
}
package com.liquidnet.service.goblin.dto.vo;
import lombok.Data;
import java.io.Serializable;
@Data
public class GoblinSqbOrderCreateVo implements Serializable {
private static final long serialVersionUID = 1L;
private String orderId;
private String acquiringSn;
// paymentVoucher fields
private String timeStamp;
private String packageStr;
private String paySign;
private String appId;
private String signType;
private String nonceStr;
}
package com.liquidnet.service.goblin.dto.vo;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
import java.math.BigDecimal;
/**
* 收钱吧订单列表/详情展示 VO
* 融合:GoblinStoreOrderVo(基础信息)+ GoblinOrderSkuVo(商品信息)+ GoblinSqbOrderVo(收钱吧扩展)
*/
@Data
public class GoblinSqbOrderDetailVo implements Serializable {
private static final long serialVersionUID = 1L;
// ========== 来自 GoblinStoreOrderVo(现有订单体系) ==========
@ApiModelProperty(value = "本地订单ID")
private String orderId;
@ApiModelProperty(value = "订单号")
private String orderCode;
@ApiModelProperty(value = "商城主单状态(goblin_store_order):[0-待付款|2-代发货/已付款|3-代收货|4-已完成|5-取消(未付款前)|6-退款通过|7-退货通过|61-发起退款/退款中]")
private Integer status;
@ApiModelProperty(value = "实付金额")
private BigDecimal priceActual;
@ApiModelProperty(value = "创建时间")
private String createdAt;
@ApiModelProperty(value = "支付时间")
private String payTime;
// ========== 来自 GoblinOrderSkuVo(sku商品信息) ==========
@ApiModelProperty(value = "商品SPU ID")
private String spuId;
@ApiModelProperty(value = "商品名称")
private String spuName;
@ApiModelProperty(value = "商品SKU ID")
private String skuId;
@ApiModelProperty(value = "款式名称")
private String skuName;
@ApiModelProperty(value = "款式图片")
private String skuImage;
@ApiModelProperty(value = "购买数量")
private Integer quantity;
// ========== 来自 GoblinSqbOrderVo(收钱吧扩展字段) ==========
@ApiModelProperty(value = "关联演出ID")
private String performancesId;
@ApiModelProperty(value = "收钱吧收单号")
private String sqbAcquiringSn;
@ApiModelProperty(value = "券码编号")
private String couponSn;
@ApiModelProperty(value = "核销二维码")
private String couponQrCode;
@ApiModelProperty(value = "券码过期时间:取的演出结束时间")
private String couponExpireTime;
@ApiModelProperty(value = "券核销标记:0-未核销 1-已核销")
private Integer couponUsedStatus;
@ApiModelProperty(value = "修改时间")
private String updateTime;
}
package com.liquidnet.service.goblin.dto.vo;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.Data;
import java.io.Serializable;
@Data
@JsonIgnoreProperties(ignoreUnknown = true)
public class GoblinSqbOrderVo implements Serializable {
private static final long serialVersionUID = 1L;
private String orderId;
private String userId;
private String performancesId;
/**
* 微信 openId(对应支付小程序 appid 下的用户唯一 openid)
* 用于收钱吧创建预支付时的 identity,以及待支付状态下的再次拉起支付。
*/
private String openId;
// 正在spuId
private String spuId;
// 正在skuId
private String skuId;
// 数量
private Integer quantity;
// 金额(分为单位)
private Long amount;
// 订单编号
private String sqbOrderSn;
// 订单密钥
private String sqbOrderSignature;
// 收单号
private String sqbAcquiringSn;
// 收单密钥
private String sqbAcquiringSign;
// 结算项ID
private String sqbCheckoutItemsId;
// 收钱吧-券码编号
private String couponSn;
// 收钱吧-券二维码url
private String couponQrCode;
// 券核销时间?
private String couponExpireTime;
// 退款备注
private String refundReason;
// 退款单号
private String refundSn;
// 退款单号密码
private String refundSignature;
// 创建时间
private String createdAt;
// 修改时间
private String updatedAt;
// 扩展属性
// 券核销状态 0-未核销 1-已核销(仅券回调 targetState=1 时置 1,与主单状态解耦)
private Integer couponUsedStatus;
}
package com.liquidnet.service.goblin.dto.vo;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.liquidnet.common.third.sqb.param.response.data.MallProductsQueryData;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.List;
@Data
public class GoblinSqbPerfGoodsVo implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty("商城编号")
private String mallSn;
@ApiModelProperty("商城名称")
private String mallName;
@ApiModelProperty("商城签名")
private String signature;
@ApiModelProperty(value = "商品spuId")
private String spuId;
@ApiModelProperty(value = "商品图片")
private List<String> converImages;
@ApiModelProperty(value = "商品描述")
private String productIntroduction;
@ApiModelProperty(value = "商品标题")
private String title;
@ApiModelProperty(value = "商品规格")
private List<MallProductsQueryData.Sku> skuResults;
@ApiModelProperty("是否已同步")
private Boolean synced;
@Data
@JsonIgnoreProperties(ignoreUnknown = true)
@ApiModel(value = "商品规格")
public static class Sku {
@ApiModelProperty(value = "库存类型")
private Integer stockType;
@ApiModelProperty(value = "商品skuId")
private String skuId;
@ApiModelProperty(value = "库存值")
private BigDecimal quantity;
@ApiModelProperty(value = "规格标题")
private String skuTitle;
@ApiModelProperty(value = "规格名称")
private String skuName;
@ApiModelProperty(value = "价格")
private Long price;
}
}
package com.liquidnet.service.goblin.dto.vo;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
import java.math.BigDecimal;
/**
* 演出关联收钱吧商品列表项(本地关联视图)
*/
@Data
public class GoblinSqbPerfLinkedGoodsVo implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "商品skuId(本地)")
private String skuId;
@ApiModelProperty(value = "商品spuId(本地)")
private String spuId;
@ApiModelProperty(value = "商品spu名称(本地)")
private String spuName;
@ApiModelProperty(value = "商品sku名称(本地)")
private String skuName;
@ApiModelProperty(value = "商品头图(本地)")
private String coverPic;
@ApiModelProperty(value = "商品售价(元,与 goblin_goods_sku.price 一致)")
private BigDecimal price;
@ApiModelProperty(value = "商品库存(本地)")
private Integer stock;
@ApiModelProperty(value = "排序权重")
private Integer sort;
@ApiModelProperty(value = "换购价格")
private BigDecimal settlementPrice;
@ApiModelProperty(value = "状态 0-禁用 1-启用")
private Integer status;
@ApiModelProperty(value = "是否满足上架可售(与前台一致:SPU/SKU 上架且未删)")
private Boolean linkable;
@ApiModelProperty(value = "上下架展示文案")
private String shelfStatusLabel;
}
package com.liquidnet.service.goblin.dto.vo;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
@Data
public class GoblinSqbPerfListRespVo implements Serializable {
private static final long serialVersionUID = 1L;
/** 演出结束后不在前台列表展示 0-否 1-是(全局配置,仅列表隐藏) */
private Integer autoOffline;
/** 关联商品列表 */
private List<GoblinSqbPerfLinkedGoodsVo> goodsList;
}
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.math.BigDecimal;
import java.util.List;
/**
* 收钱吧-演出关联商品前端展示VO
*/
@Data
@EqualsAndHashCode(callSuper = true)
@ApiModel(value = "GoblinSqbPerformanceGoodsInfoVo", description = "收钱吧-演出关联商品前端展示VO")
public class GoblinSqbPerformanceGoodsInfoVo extends GoblinGoodsInfoVo {
@ApiModelProperty(value = "正常售价")
private BigDecimal price;
@ApiModelProperty(value = "收钱吧商品(spuType=33)换购价展示(元):关联 SKU 换购价最小值;非 SQB 商品恒为 null;未配置换购价时不返回")
private BigDecimal settlementPrice;
@ApiModelProperty(value = "已上架 SKU 明细(含 restStock、stockLess、canBuy 等,与商品详情接口字段一致)")
private List<GoblinGoodsSkuInfoDetailVo> goblinGoodsSkuInfoVolist;
}
package com.liquidnet.service.goblin.dto.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
/**
* 收钱吧-按演出查询关联商品列表(与 {@link GoblinFrontSelectGoodVo} 字段名一致,便于前端复用同一解析逻辑)
*/
@ApiModel(value = "GoblinSqbPerformanceSelectGoodVo", description = "收钱吧-演出关联商品列表")
@Data
public class GoblinSqbPerformanceSelectGoodVo implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "满足展示条件、分页前的商品总数(按 SPU 去重后)")
private int count;
@ApiModelProperty(value = "商品列表,元素为 GoblinSqbPerformanceGoodsInfoVo(含 price/settlementPrice、goblinGoodsSkuInfoVolist 等)")
private List<GoblinSqbPerformanceGoodsInfoVo> goblinGoodsInfoVoList;
public static GoblinSqbPerformanceSelectGoodVo getNew() {
GoblinSqbPerformanceSelectGoodVo vo = new GoblinSqbPerformanceSelectGoodVo();
vo.setGoblinGoodsInfoVoList(new ArrayList<GoblinSqbPerformanceGoodsInfoVo>());
return vo;
}
}
package com.liquidnet.service.goblin.dto.vo; package com.liquidnet.service.goblin.dto.vo;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.liquidnet.service.goblin.entity.GoblinOrderAttr;
import com.liquidnet.service.goblin.entity.GoblinStoreOrder; import com.liquidnet.service.goblin.entity.GoblinStoreOrder;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import lombok.AccessLevel;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import lombok.Getter;
import java.io.Serializable; import java.io.Serializable;
import java.math.BigDecimal; import java.math.BigDecimal;
...@@ -66,8 +67,10 @@ public class GoblinStoreOrderVo implements Serializable, Cloneable { ...@@ -66,8 +67,10 @@ public class GoblinStoreOrderVo implements Serializable, Cloneable {
@ApiModelProperty(value = "正在下单是否出货[0-未出货|1-已出货]") @ApiModelProperty(value = "正在下单是否出货[0-未出货|1-已出货]")
private Integer zhengzaiStatus; private Integer zhengzaiStatus;
@ApiModelProperty(value = " 券id") @ApiModelProperty(value = " 券id")
@Getter(AccessLevel.NONE)
private String ucouponId; private String ucouponId;
@ApiModelProperty(value = " 店铺券id") @ApiModelProperty(value = " 店铺券id")
@Getter(AccessLevel.NONE)
private String storeCouponId; private String storeCouponId;
@ApiModelProperty(value = " 支付类型[wepay-微信支付|alipay-阿里支付|douyinpay-抖音支付|unionpay-银联支付]") @ApiModelProperty(value = " 支付类型[wepay-微信支付|alipay-阿里支付|douyinpay-抖音支付|unionpay-银联支付]")
private String payType; private String payType;
...@@ -77,6 +80,10 @@ public class GoblinStoreOrderVo implements Serializable, Cloneable { ...@@ -77,6 +80,10 @@ public class GoblinStoreOrderVo implements Serializable, Cloneable {
private String cancelReason; private String cancelReason;
@ApiModelProperty(value = " 订单来源[app|h5|applet]") @ApiModelProperty(value = " 订单来源[app|h5|applet]")
private String source; private String source;
@ApiModelProperty(value = "粉丝俱乐部来源标识")
private String referrerApp;
@ApiModelProperty(value = "粉丝俱乐部侧用户id")
private String referrerUserId;
@ApiModelProperty(value = " 版本号") @ApiModelProperty(value = " 版本号")
private String version; private String version;
@ApiModelProperty(value = " 是否会员") @ApiModelProperty(value = " 是否会员")
...@@ -97,7 +104,7 @@ public class GoblinStoreOrderVo implements Serializable, Cloneable { ...@@ -97,7 +104,7 @@ public class GoblinStoreOrderVo implements Serializable, Cloneable {
private Integer payCountdownMinute; private Integer payCountdownMinute;
@ApiModelProperty(value = " 快递单号[废弃]") @ApiModelProperty(value = " 快递单号[废弃]")
private String mailNo; private String mailNo;
@ApiModelProperty(value = " 发货时间[废弃]") @ApiModelProperty(value = "订单完成时间")
private String deliveryTime; private String deliveryTime;
@ApiModelProperty(value = " 物流公司姓名[废弃]") @ApiModelProperty(value = " 物流公司姓名[废弃]")
private String logisticsCompany; private String logisticsCompany;
...@@ -158,6 +165,17 @@ public class GoblinStoreOrderVo implements Serializable, Cloneable { ...@@ -158,6 +165,17 @@ public class GoblinStoreOrderVo implements Serializable, Cloneable {
return mixName == null ? "" : mixName; return mixName == null ? "" : mixName;
} }
/**
* 与历史数据/下游逻辑一致:未用券时为非 null 的空串,避免队里关单等处 {@code getXxx().equals("")} 在字段为 null 时 NPE。
* 字段本身仍可为 null(反序列化),对外读取统一走空串。
*/
public String getStoreCouponId() {
return storeCouponId == null ? "" : storeCouponId;
}
public String getUcouponId() {
return ucouponId == null ? "" : ucouponId;
}
public GoblinStoreOrderVo copy(GoblinStoreOrder source,int erpHosting) { public GoblinStoreOrderVo copy(GoblinStoreOrder source,int erpHosting) {
if (null == source) return this; if (null == source) return this;
...@@ -186,6 +204,8 @@ public class GoblinStoreOrderVo implements Serializable, Cloneable { ...@@ -186,6 +204,8 @@ public class GoblinStoreOrderVo implements Serializable, Cloneable {
this.setDeviceFrom(source.getDeviceFrom()); this.setDeviceFrom(source.getDeviceFrom());
this.setCancelReason(source.getCancelReason()); this.setCancelReason(source.getCancelReason());
this.setSource(source.getSource()); this.setSource(source.getSource());
this.setReferrerApp(source.getOrderSource() == null ? "" : source.getOrderSource());
this.setReferrerUserId(source.getReferrerUserId() == null ? "" : source.getReferrerUserId());
this.setVersion(source.getVersion()); this.setVersion(source.getVersion());
this.setIsMember(source.getIsMember()); this.setIsMember(source.getIsMember());
this.setOrderType(source.getOrderType()); this.setOrderType(source.getOrderType());
...@@ -237,6 +257,8 @@ public class GoblinStoreOrderVo implements Serializable, Cloneable { ...@@ -237,6 +257,8 @@ public class GoblinStoreOrderVo implements Serializable, Cloneable {
this.setDeviceFrom(source.getDeviceFrom()); this.setDeviceFrom(source.getDeviceFrom());
this.setCancelReason(source.getCancelReason()); this.setCancelReason(source.getCancelReason());
this.setSource(source.getSource()); this.setSource(source.getSource());
this.setReferrerApp(source.getOrderSource() == null ? "" : source.getOrderSource());
this.setReferrerUserId(source.getReferrerUserId() == null ? "" : source.getReferrerUserId());
this.setVersion(source.getVersion()); this.setVersion(source.getVersion());
this.setIsMember(source.getIsMember()); this.setIsMember(source.getIsMember());
this.setOrderType(source.getOrderType()); this.setOrderType(source.getOrderType());
......
package com.liquidnet.service.goblin.param; package com.liquidnet.service.goblin.param;
import com.liquidnet.service.dragon.doc.DragonPaySwaggerDoc;
import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
...@@ -10,18 +11,18 @@ import javax.validation.constraints.NotNull; ...@@ -10,18 +11,18 @@ import javax.validation.constraints.NotNull;
@Data @Data
public class GoblinNftOrderPayAgainParam { public class GoblinNftOrderPayAgainParam {
@ApiModelProperty(value = "openId") @ApiModelProperty(value = DragonPaySwaggerDoc.OPEN_ID_VALUE)
private String openId; private String openId;
@ApiModelProperty(value = "订单id") @ApiModelProperty(value = "订单id")
@NotNull(message = "订单ID不能为空") @NotNull(message = "订单ID不能为空")
private String orderId; private String orderId;
@ApiModelProperty(value = "支付类型") @ApiModelProperty(value = DragonPaySwaggerDoc.PAY_TYPE_VALUE, allowableValues = DragonPaySwaggerDoc.PAY_TYPE_ALLOWABLE, example = "wepay")
@NotNull(message = "支付类型不能为空") @NotNull(message = "支付类型不能为空")
private String payType; private String payType;
@ApiModelProperty(value = "支付来源") @ApiModelProperty(value = DragonPaySwaggerDoc.DEVICE_FROM_VALUE, allowableValues = DragonPaySwaggerDoc.DEVICE_FROM_ALLOWABLE, example = "applet")
@NotNull(message = "支付来源不能为空") @NotNull(message = "支付来源不能为空")
private String deviceFrom; private String deviceFrom;
......
package com.liquidnet.service.goblin.param; package com.liquidnet.service.goblin.param;
import com.liquidnet.commons.lang.constant.LnsRegex; import com.liquidnet.commons.lang.constant.LnsRegex;
import com.liquidnet.service.dragon.doc.DragonPaySwaggerDoc;
import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
...@@ -12,7 +13,7 @@ import javax.validation.constraints.Pattern; ...@@ -12,7 +13,7 @@ import javax.validation.constraints.Pattern;
@Data @Data
public class GoblinNftOrderPayParam { public class GoblinNftOrderPayParam {
@ApiModelProperty(position = 10, value = "openId微信内网页及小程序支付必传") @ApiModelProperty(position = 10, value = DragonPaySwaggerDoc.OPEN_ID_VALUE)
private String openId; private String openId;
@ApiModelProperty(position = 11, required = true, value = "skuId") @ApiModelProperty(position = 11, required = true, value = "skuId")
...@@ -25,12 +26,12 @@ public class GoblinNftOrderPayParam { ...@@ -25,12 +26,12 @@ public class GoblinNftOrderPayParam {
@ApiModelProperty(position = 13, value = "商品券码") @ApiModelProperty(position = 13, value = "商品券码")
private String storeVoucherCode;*/ private String storeVoucherCode;*/
@ApiModelProperty(position = 14, required = true, value = "支付方式", allowableValues = "alipay,wepay,douyinpay,unionpay,applepay") @ApiModelProperty(position = 14, required = true, value = DragonPaySwaggerDoc.PAY_TYPE_VALUE, allowableValues = DragonPaySwaggerDoc.PAY_TYPE_ALLOWABLE, example = "wepay")
@Pattern(regexp = LnsRegex.Valid.TRIPLE_PF_FOR_PAY, message = "支付方式无效") @Pattern(regexp = LnsRegex.Valid.TRIPLE_PF_FOR_PAY, message = "支付方式无效")
@NotBlank(message = "支付方式不能为空") @NotBlank(message = "支付方式不能为空")
private String payType; private String payType;
@ApiModelProperty(position = 15, required = true, value = "支付终端", allowableValues = "app,wap,js,applet") @ApiModelProperty(position = 15, required = true, value = DragonPaySwaggerDoc.DEVICE_FROM_VALUE, allowableValues = DragonPaySwaggerDoc.DEVICE_FROM_ALLOWABLE, example = "applet")
@Pattern(regexp = LnsRegex.Valid.TRIPLE_PF_FOR_PAY_TERMINAL, message = "支付终端类型无效") @Pattern(regexp = LnsRegex.Valid.TRIPLE_PF_FOR_PAY_TERMINAL, message = "支付终端类型无效")
@NotBlank(message = "支付终端不能为空") @NotBlank(message = "支付终端不能为空")
private String deviceFrom; private String deviceFrom;
......
...@@ -4,6 +4,7 @@ import com.liquidnet.service.goblin.dto.manage.GoblinOrderSkuParam; ...@@ -4,6 +4,7 @@ import com.liquidnet.service.goblin.dto.manage.GoblinOrderSkuParam;
import com.liquidnet.service.goblin.entity.GoblinOrderAttr; import com.liquidnet.service.goblin.entity.GoblinOrderAttr;
import com.liquidnet.service.goblin.entity.GoblinOrderSku; import com.liquidnet.service.goblin.entity.GoblinOrderSku;
import com.liquidnet.service.goblin.entity.GoblinStoreOrder; import com.liquidnet.service.goblin.entity.GoblinStoreOrder;
import com.liquidnet.service.dragon.doc.DragonPaySwaggerDoc;
import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
...@@ -35,12 +36,13 @@ public class GoblinOrderPreParam implements Cloneable{ ...@@ -35,12 +36,13 @@ public class GoblinOrderPreParam implements Cloneable{
@ApiModelProperty(required = true, value = "订单过期时间") @ApiModelProperty(required = true, value = "订单过期时间")
private int expireTime; private int expireTime;
@ApiModelProperty(value = DragonPaySwaggerDoc.DEVICE_FROM_VALUE, allowableValues = DragonPaySwaggerDoc.DEVICE_FROM_ALLOWABLE, example = "applet")
private String deviceFrom; private String deviceFrom;
private String authCode; private String authCode;
@ApiModelProperty(required = true, value = "支付方式[pos_crash-现金支付|]") @ApiModelProperty(required = true, value = DragonPaySwaggerDoc.PAY_TYPE_VALUE, allowableValues = DragonPaySwaggerDoc.PAY_TYPE_ALLOWABLE, example = "wepay")
private String payType; private String payType;
@ApiModelProperty(value = DragonPaySwaggerDoc.OPEN_ID_VALUE)
private String openId; private String openId;
private String returnUrl; private String returnUrl;
private String showUrl; private String showUrl;
......
package com.liquidnet.service.goblin.param; package com.liquidnet.service.goblin.param;
import com.liquidnet.service.dragon.doc.DragonPaySwaggerDoc;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
...@@ -10,13 +11,13 @@ public class PayAgainParam { ...@@ -10,13 +11,13 @@ public class PayAgainParam {
@ApiModelProperty(value = "订单id") @ApiModelProperty(value = "订单id")
@NotNull(message = "订单ID不能为空") @NotNull(message = "订单ID不能为空")
private String orderId; private String orderId;
@ApiModelProperty(value = "支付类型") @ApiModelProperty(value = DragonPaySwaggerDoc.PAY_TYPE_VALUE, allowableValues = DragonPaySwaggerDoc.PAY_TYPE_ALLOWABLE, example = "wepay")
@NotNull(message = "支付类型不能为空") @NotNull(message = "支付类型不能为空")
private String payType; private String payType;
@ApiModelProperty(value = "支付来源") @ApiModelProperty(value = DragonPaySwaggerDoc.DEVICE_FROM_VALUE, allowableValues = DragonPaySwaggerDoc.DEVICE_FROM_ALLOWABLE, example = "applet")
@NotNull(message = "支付来源不能为空") @NotNull(message = "支付来源不能为空")
private String deviceFrom; private String deviceFrom;
@ApiModelProperty(value = "openId") @ApiModelProperty(value = DragonPaySwaggerDoc.OPEN_ID_VALUE)
private String openId; private String openId;
@ApiModelProperty(value = "showUrl") @ApiModelProperty(value = "showUrl")
private String showUrl; private String showUrl;
......
...@@ -42,6 +42,11 @@ public interface GoblinFrontService { ...@@ -42,6 +42,11 @@ public interface GoblinFrontService {
*/ */
GoblinFrontSelectGoodVo getSelectGoods(int page, int pageSize); GoblinFrontSelectGoodVo getSelectGoods(int page, int pageSize);
/**
* 按演出ID查询已关联商品列表
*/
GoblinSqbPerformanceSelectGoodVo getPerformanceSelectGoods(String performancesId, int page, int pageSize);
//根据艺人标签和演出id查询商品列表 //根据艺人标签和演出id查询商品列表
List<GoblinGoodsInfoVo> getGoodByMusicTagP(String musicTag, String performanceId); List<GoblinGoodsInfoVo> getGoodByMusicTagP(String musicTag, String performanceId);
......
package com.liquidnet.service.goblin.service;
import com.liquidnet.common.third.sqb.param.callback.CouponCallbackContent;
import com.liquidnet.common.third.sqb.param.callback.OrderCallbackContent;
import com.liquidnet.common.third.sqb.param.callback.RefundCallbackContent;
import com.liquidnet.service.base.ResponseDto;
import com.liquidnet.service.goblin.dto.manage.GoblinSqbOrderParam;
import com.liquidnet.service.goblin.dto.vo.GoblinSqbOrderCreateVo;
/**
* 收钱吧订单服务接口
*/
public interface IGoblinSqbOrderService {
/**
* 创建收钱吧订单
*
* @param userId 用户ID(从 token 获取)
* @param orderParam
* @return 订单创建结果(orderId、acquiringSn、paymentVoucher)
*/
ResponseDto<GoblinSqbOrderCreateVo> createOrder(String userId, GoblinSqbOrderParam orderParam);
/**
* 再次付款(待支付状态下重新拉起微信支付)
*
* @param userId 用户ID
* @param orderId 本地订单ID
* @return 新的 paymentVoucher(复用原 orderId)
*/
ResponseDto<GoblinSqbOrderCreateVo> repay(String userId, String orderId);
/**
* 查询支付状态
*
* @param userId 用户ID
* @param orderId 本地订单ID
* @return 支付状态(0-待支付 1-已支付 9-失败)
*/
ResponseDto<Integer> queryPayStatus(String userId, String orderId);
/**
* 支付成功回调(收钱吧主动推送)
*
* @param orderCallbackContent@return "success"
*/
ResponseDto<String> handlePayCallback(OrderCallbackContent orderCallbackContent);
/**
* 退款成功回调(收钱吧主动推送)
*
* @param refundCallbackContent@return "success"
*/
ResponseDto<String> handleRefundCallback(RefundCallbackContent refundCallbackContent);
/**
* 券状态变更回调(收钱吧主动推送)
*
* @param callbackContent@return "success"
*/
ResponseDto<String> handleCouponCallback(CouponCallbackContent callbackContent);
}
package com.liquidnet.service.goblin.service;
import com.liquidnet.service.base.ResponseDto;
import com.liquidnet.service.goblin.dto.vo.GoblinSqbCouponVo;
import com.liquidnet.service.goblin.dto.vo.GoblinSqbOrderDetailVo;
import java.util.List;
public interface IGoblinSqbService {
/**
* 获取核销二维码(券码)
*
* @param userId 用户ID
* @param orderId 本地订单ID
* @return 券码信息(couponSn、couponQrCode、couponExpireTime)
*/
ResponseDto<GoblinSqbCouponVo> queryCoupon(String userId, String orderId);
/**
* 申请退款
*
* @param userId 用户ID
* @param orderId 本地订单ID
* @param reason 退款原因
* @return 退款结果
*/
ResponseDto<Boolean> refund(String userId, String orderId, String reason);
/**
* 主动同步核销状态
*
* @param userId 用户ID
* @param orderId 本地订单ID
* @return 同步结果
*/
ResponseDto<Boolean> syncCouponStatus(String userId, String orderId);
/**
* 演出结束自动退款(定时任务调用)
* SQL 已联表过滤:收钱吧扩展单、主单已支付(2)、演出已结束、扩展未核销;循环内仅调 refund。
*
* @param performancesId 演出ID,传 null 或空则不按演出缩小(全库符合条件候选,慎用)
* @return 处理结果摘要(成功/失败笔数)
*/
ResponseDto<String> autoRefundByPerformance(String performancesId);
/**
* 查询用户收钱吧订单列表
*
* @param userId 用户ID
* @return 收钱吧订单列表(仅 skuType=33 的订单,按下单时间倒序)
*/
ResponseDto<List<GoblinSqbOrderDetailVo>> getOrderList(String userId);
/**
* 查询收钱吧订单详情
*
* @param userId 用户ID
* @param orderId 本地订单ID
* @return 订单详情(基础信息 + 收钱吧扩展信息)
*/
ResponseDto<GoblinSqbOrderDetailVo> getOrderDetail(String userId, String orderId);
}
package com.liquidnet.service.goblin.service.manage;
import com.liquidnet.service.base.ResponseDto;
import com.liquidnet.service.goblin.dto.vo.GoblinGoodsInfoVo;
import com.liquidnet.service.goblin.dto.vo.GoblinGoodsSkuInfoVo;
import com.liquidnet.service.goblin.dto.vo.GoblinSqbPerfGoodsVo;
import java.util.List;
/**
* 商品管理:收钱吧商品(独立接口)
*/
public interface IGoblinStoreMgtSqbGoodsService {
/**
* 根据搜索条件拉取商城商品列表
*
* @return 过滤后的商品列表
*/
ResponseDto<List<GoblinSqbPerfGoodsVo>> getProductList();
/**
* 商品管理:SPU添加-收钱吧商品
*/
void sqbGoodsAdd(GoblinGoodsInfoVo goodsInfoVo, List<GoblinGoodsSkuInfoVo> goodsSkuInfoVoList);
/**
* 商品管理:商品编辑:SPU编辑-收钱吧商品
*/
boolean sqbGoodsEditSpu(String uid, GoblinSqbPerfGoodsVo mgtGoodsSqbParam, GoblinGoodsInfoVo goodsInfoVo);
/**
* 通过商城编号查询收钱吧商品
* @param mallSn
* @param sqbSpuId
* @param signature
* @return
*/
GoblinSqbPerfGoodsVo fetchSqbGoodsByMallAndSpu(String mallSn, String sqbSpuId, String signature);
}
...@@ -17,6 +17,11 @@ ...@@ -17,6 +17,11 @@
<version>1.0-SNAPSHOT</version> <version>1.0-SNAPSHOT</version>
<scope>compile</scope> <scope>compile</scope>
</dependency> </dependency>
<dependency>
<groupId>com.liquidnet</groupId>
<artifactId>liquidnet-service-dragon-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies> </dependencies>
</project> </project>
package com.liquidnet.service.kylin.dto.param; package com.liquidnet.service.kylin.dto.param;
import com.liquidnet.service.dragon.doc.DragonPaySwaggerDoc;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
...@@ -10,13 +11,13 @@ public class PayAgainParam { ...@@ -10,13 +11,13 @@ public class PayAgainParam {
@ApiModelProperty(value = "订单id") @ApiModelProperty(value = "订单id")
@NotNull(message = "订单ID不能为空") @NotNull(message = "订单ID不能为空")
private String orderId; private String orderId;
@ApiModelProperty(value = "支付类型") @ApiModelProperty(value = DragonPaySwaggerDoc.PAY_TYPE_VALUE, allowableValues = DragonPaySwaggerDoc.PAY_TYPE_ALLOWABLE, example = "wepay")
@NotNull(message = "支付类型不能为空") @NotNull(message = "支付类型不能为空")
private String payType; private String payType;
@ApiModelProperty(value = "支付来源") @ApiModelProperty(value = DragonPaySwaggerDoc.DEVICE_FROM_VALUE, allowableValues = DragonPaySwaggerDoc.DEVICE_FROM_ALLOWABLE, example = "applet")
@NotNull(message = "支付来源不能为空") @NotNull(message = "支付来源不能为空")
private String deviceFrom; private String deviceFrom;
@ApiModelProperty(value = "openId") @ApiModelProperty(value = DragonPaySwaggerDoc.OPEN_ID_VALUE)
private String openId; private String openId;
@ApiModelProperty(value = "showUrl") @ApiModelProperty(value = "showUrl")
private String showUrl; private String showUrl;
......
package com.liquidnet.service.kylin.dto.param; package com.liquidnet.service.kylin.dto.param;
import com.liquidnet.service.dragon.doc.DragonPaySwaggerDoc;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import lombok.Builder; import lombok.Builder;
...@@ -10,7 +11,7 @@ import javax.validation.constraints.Min; ...@@ -10,7 +11,7 @@ import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull; import javax.validation.constraints.NotNull;
import java.util.List; import java.util.List;
@Api @Api(tags = "演出下单", description = "POST /order/pre。微信小程序微信支付见 deviceFrom 与 openId 说明。")
@Data @Data
public class PayOrderParam { public class PayOrderParam {
@ApiModelProperty(value = "演出id") @ApiModelProperty(value = "演出id")
...@@ -40,13 +41,13 @@ public class PayOrderParam { ...@@ -40,13 +41,13 @@ public class PayOrderParam {
@ApiModelProperty(value = "快递类型[0无类型|1寄付|2到付|3包邮]") @ApiModelProperty(value = "快递类型[0无类型|1寄付|2到付|3包邮]")
@NotNull(message = "快递方式不能为空") @NotNull(message = "快递方式不能为空")
private Integer expressType; private Integer expressType;
@ApiModelProperty(value = "支付类型") @ApiModelProperty(value = DragonPaySwaggerDoc.PAY_TYPE_VALUE, allowableValues = DragonPaySwaggerDoc.PAY_TYPE_ALLOWABLE, example = "wepay")
@NotNull(message = "支付类型不能为空") @NotNull(message = "支付类型不能为空")
private String payType; private String payType;
@ApiModelProperty(value = "支付来源") @ApiModelProperty(value = DragonPaySwaggerDoc.DEVICE_FROM_VALUE, allowableValues = DragonPaySwaggerDoc.DEVICE_FROM_ALLOWABLE, example = "applet")
@NotNull(message = "支付来源不能为空") @NotNull(message = "支付来源不能为空")
private String deviceFrom; private String deviceFrom;
@ApiModelProperty(value = "openId") @ApiModelProperty(value = DragonPaySwaggerDoc.OPEN_ID_VALUE)
private String openId; private String openId;
@ApiModelProperty(value = "showUrl") @ApiModelProperty(value = "showUrl")
private String showUrl; private String showUrl;
...@@ -66,4 +67,8 @@ public class PayOrderParam { ...@@ -66,4 +67,8 @@ public class PayOrderParam {
private AddressVo addressesVo; private AddressVo addressesVo;
@ApiModelProperty(value = "联系方式") @ApiModelProperty(value = "联系方式")
private String userMobile; private String userMobile;
@ApiModelProperty(value = "粉丝俱乐部来源标识,如DOUDOU之家;与 referrerUserId 同时传才打标")
private String referrerApp;
@ApiModelProperty(value = "粉丝俱乐部侧用户id")
private String referrerUserId;
} }
...@@ -45,7 +45,11 @@ public class KylinOrderTicketVo implements Serializable, Cloneable { ...@@ -45,7 +45,11 @@ public class KylinOrderTicketVo implements Serializable, Cloneable {
private String qrCode; private String qrCode;
@ApiModelProperty(position = 18, value = "下单方式") @ApiModelProperty(position = 18, value = "下单方式")
private String orderType; private String orderType;
@ApiModelProperty(position = 19, value = "下单版本") @ApiModelProperty(position = 19, value = "粉丝俱乐部来源标识")
private String referrerApp;
@ApiModelProperty(position = 19, value = "粉丝俱乐部侧用户id")
private String referrerUserId;
@ApiModelProperty(position = 20, value = "下单版本")
private String orderVersion; private String orderVersion;
@ApiModelProperty(position = 20, value = "数量") @ApiModelProperty(position = 20, value = "数量")
private Integer number; private Integer number;
...@@ -156,6 +160,8 @@ public class KylinOrderTicketVo implements Serializable, Cloneable { ...@@ -156,6 +160,8 @@ public class KylinOrderTicketVo implements Serializable, Cloneable {
public void setOrderTicket(KylinOrderTickets orderTicket) { public void setOrderTicket(KylinOrderTickets orderTicket) {
BeanUtils.copyProperties(orderTicket, this); BeanUtils.copyProperties(orderTicket, this);
this.referrerApp = orderTicket.getOrderSource() == null ? "" : orderTicket.getOrderSource();
this.referrerUserId = orderTicket.getReferrerUserId() == null ? "" : orderTicket.getReferrerUserId();
} }
public void setOrderTicketStatus(KylinOrderTicketStatus orderTicketStatus) { public void setOrderTicketStatus(KylinOrderTicketStatus orderTicketStatus) {
......
...@@ -49,6 +49,10 @@ public class KylinOrderListVo implements Serializable, Cloneable { ...@@ -49,6 +49,10 @@ public class KylinOrderListVo implements Serializable, Cloneable {
private Integer transferStatus; private Integer transferStatus;
@ApiModelProperty(value = "创建时间", example = "") @ApiModelProperty(value = "创建时间", example = "")
private String createdAt; private String createdAt;
@ApiModelProperty(value = "粉丝俱乐部来源标识")
private String referrerApp;
@ApiModelProperty(value = "粉丝俱乐部侧用户id")
private String referrerUserId;
private static final KylinOrderListVo obj = new KylinOrderListVo(); private static final KylinOrderListVo obj = new KylinOrderListVo();
...@@ -116,6 +120,8 @@ public class KylinOrderListVo implements Serializable, Cloneable { ...@@ -116,6 +120,8 @@ public class KylinOrderListVo implements Serializable, Cloneable {
} else { } else {
this.status = vo.getStatus(); this.status = vo.getStatus();
} }
this.referrerApp = vo.getReferrerApp() == null ? "" : vo.getReferrerApp();
this.referrerUserId = vo.getReferrerUserId() == null ? "" : vo.getReferrerUserId();
return this; return this;
} }
} }
package com.liquidnet.client.admin.web.controller.zhengzai.goblin;
import com.liquidnet.client.admin.common.core.controller.BaseController;
import com.liquidnet.client.admin.common.core.domain.AjaxResult;
import com.liquidnet.client.admin.zhengzai.goblin.dto.SqbPerfGoodsBindItemParam;
import com.liquidnet.client.admin.zhengzai.goblin.service.ISqbPerformanceGoodsService;
import com.liquidnet.service.base.ResponseDto;
import com.liquidnet.service.goblin.dto.vo.GoblinAdminSqbGoodsVo;
import com.liquidnet.service.goblin.dto.vo.GoblinSqbPerfGoodsVo;
import com.liquidnet.service.goblin.dto.vo.GoblinSqbPerfListRespVo;
import io.swagger.annotations.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 演出-收钱吧商品关联管理
*/
@Slf4j
@Controller
@Api(tags = "收钱吧-演出商品关联管理")
@RequestMapping("sqb/performance/goods")
public class SqbPerformanceGoodsController extends BaseController {
private final String prefix = "zhengzai/goblin/sqbGoods";
@Autowired
private ISqbPerformanceGoodsService sqbPerformanceGoodsService;
/**
* 关联商品管理页面(iframe 内嵌)
*/
@GetMapping("page/{performancesId}")
public String sqbGoodsPage(@PathVariable("performancesId") String performancesId, ModelMap mmap) {
mmap.put("performancesId", performancesId);
return prefix + "/index";
}
/**
* 搜索可选商品(skuType=33);有关键词时按 SPU 商品名称(goblin_goods.name)模糊匹配,返回展示为「商品名-规格名」
*/
@GetMapping("search")
@ResponseBody
@ApiOperation("搜索收钱吧候选商品(按商品名称;展示 spu-sku)")
@ApiImplicitParams({
@ApiImplicitParam(type = "query", dataType = "String", name = "keyword", value = "商品名称关键词(匹配 SPU 名称)", required = false),
})
public AjaxResult searchGoods(@RequestParam(value = "keyword", required = false) String keyword) {
ResponseDto<List<GoblinAdminSqbGoodsVo>> resp = sqbPerformanceGoodsService.searchGoods(keyword);
if (resp.isSuccess()) {
return AjaxResult.success(resp.getData());
}
return AjaxResult.error(resp.getMessage());
}
/**
* 批量绑定/保存关联商品配置
*/
@PostMapping("bind")
@ResponseBody
@ApiOperation("批量绑定演出与商品(含换购价、演出级自动下架全局配置)")
@ApiImplicitParams({
@ApiImplicitParam(type = "query", required = true, dataType = "String", name = "performancesId", value = "演出ID"),
@ApiImplicitParam(type = "query", required = false, dataType = "int", name = "autoOffline", value = "演出结束后不在前台列表展示 0-否 1-是(不取消关联、不改商品上下架)"),
})
public AjaxResult bind(@RequestParam("performancesId") String performancesId,
@RequestParam(value = "autoOffline", required = false, defaultValue = "0") Integer autoOffline,
@RequestBody List<SqbPerfGoodsBindItemParam> items) {
ResponseDto<Boolean> resp = sqbPerformanceGoodsService.bind(performancesId, items, autoOffline);
if (resp.isSuccess()) {
return AjaxResult.success("保存成功");
}
return AjaxResult.error(resp.getMessage());
}
/**
* 解除关联
*/
@PostMapping("unbind")
@ResponseBody
@ApiOperation("解除演出与商品关联")
@ApiImplicitParams({
@ApiImplicitParam(type = "form", required = true, dataType = "String", name = "performancesId", value = "演出ID"),
@ApiImplicitParam(type = "form", required = true, dataType = "String", name = "skuId", value = "SKU ID"),
})
public AjaxResult unbind(@RequestParam("performancesId") String performancesId,
@RequestParam("skuId") String skuId) {
ResponseDto<Boolean> resp = sqbPerformanceGoodsService.unbind(performancesId, skuId);
if (resp.isSuccess()) {
return AjaxResult.success("已取消关联");
}
return AjaxResult.error(resp.getMessage());
}
/**
* 查询演出已关联商品列表
*/
@GetMapping("list")
@ResponseBody
@ApiOperation("查询演出关联商品列表(含全局配置)")
@ApiImplicitParams({
@ApiImplicitParam(type = "query", required = true, dataType = "String", name = "performancesId", value = "演出ID"),
})
public AjaxResult list(@RequestParam("performancesId") String performancesId) {
ResponseDto<GoblinSqbPerfListRespVo> resp = sqbPerformanceGoodsService.list(performancesId);
if (resp.isSuccess()) {
return AjaxResult.success(resp.getData());
}
return AjaxResult.error(resp.getMessage());
}
}
...@@ -111,6 +111,41 @@ ...@@ -111,6 +111,41 @@
var removeFlag = [[${@permission.hasPermi('kylin:tickets:remove')}]]; var removeFlag = [[${@permission.hasPermi('kylin:tickets:remove')}]];
var prefix = ctx + "kylin/tickets"; var prefix = ctx + "kylin/tickets";
function formatPaymentType(value) {
if (!value) {
return '';
}
var pt = value;
if (pt.indexOf('UNIONPAY') >= 0) {
return '银联云闪付';
}
if (pt.indexOf('DOUYIN') >= 0) {
return '抖音支付';
}
if (pt.indexOf('ALIPAY') >= 0 || pt.toLowerCase() === 'alipay') {
return '支付宝';
}
if (pt.indexOf('APPLET') >= 0 && pt.lastIndexOf('WEPAY') === pt.length - 5) {
if (pt.indexOf('DOUDOU') >= 0) {
return '微信(DouDou)';
}
if (pt.indexOf('MOOTOO') >= 0) {
return '微信(mootoo)';
}
if (pt.indexOf('WENQUE') >= 0) {
return '微信(wenque)';
}
if (pt.indexOf('APPLETB') >= 0) {
return '微信(摩登)';
}
return '微信小程序';
}
if (pt.indexOf('WEPAY') >= 0 || pt.toLowerCase() === 'wepay') {
return '微信';
}
return pt;
}
$(function() { $(function() {
var options = { var options = {
url: prefix + "/list", url: prefix + "/list",
...@@ -144,7 +179,10 @@ ...@@ -144,7 +179,10 @@
}, },
{ {
field: 'paymentType', field: 'paymentType',
title: '支付方式' title: '支付方式',
formatter: function(value) {
return formatPaymentType(value);
}
}, },
{ {
field: 'userId', field: 'userId',
......
...@@ -45,6 +45,8 @@ ...@@ -45,6 +45,8 @@
</li> </li>
<li id="li-tab-12"><a data-toggle="tab" href="#tab-12" aria-expanded="false" onclick="artistLineupInfo()">演出阵容</a> <li id="li-tab-12"><a data-toggle="tab" href="#tab-12" aria-expanded="false" onclick="artistLineupInfo()">演出阵容</a>
</li> </li>
<li id="li-tab-13"><a data-toggle="tab" href="#tab-13" aria-expanded="false" onclick="sqbGoodsInfo()">关联推荐商品</a>
</li>
</ul> </ul>
<div class="tab-content"> <div class="tab-content">
<div id="tab-1" class="tab-pane"> <div id="tab-1" class="tab-pane">
...@@ -373,6 +375,13 @@ ...@@ -373,6 +375,13 @@
height=800px frameborder=0></iframe> height=800px frameborder=0></iframe>
</div> </div>
</div> </div>
<div id="tab-13" class="tab-pane">
<div class="panel-body">
<iframe id="sqb_goods_iframe" name="sqb_goods_iframe" marginwidth=0 marginheight=0
width=100%
height=800px frameborder=0></iframe>
</div>
</div>
</div> </div>
</div> </div>
</div> </div>
...@@ -578,6 +587,11 @@ ...@@ -578,6 +587,11 @@
document.getElementById("artist_lineup_iframe").src = "../artistLineup/" + '[[${kylinPerformanceMisVo.performancesId}]]'.replaceAll("\"", ""); document.getElementById("artist_lineup_iframe").src = "../artistLineup/" + '[[${kylinPerformanceMisVo.performancesId}]]'.replaceAll("\"", "");
} }
//关联推荐商品
function sqbGoodsInfo() {
document.getElementById("sqb_goods_iframe").src = ctx + "sqb/performance/goods/page/" + '[[${kylinPerformanceMisVo.performancesId}]]'.replaceAll("\"", "");
}
$("#tab-nav-1").bind("click", function () { $("#tab-nav-1").bind("click", function () {
$("#tab_iframe_1").attr("src", prefix + "/performanceStatic/" + '[[${kylinPerformanceMisVo.performancesId}]]'.replaceAll("\"", "")); $("#tab_iframe_1").attr("src", prefix + "/performanceStatic/" + '[[${kylinPerformanceMisVo.performancesId}]]'.replaceAll("\"", ""));
}); });
......
...@@ -28,6 +28,11 @@ ...@@ -28,6 +28,11 @@
<artifactId>liquidnet-service-kylin-api</artifactId> <artifactId>liquidnet-service-kylin-api</artifactId>
<version>1.0-SNAPSHOT</version> <version>1.0-SNAPSHOT</version>
</dependency> </dependency>
<dependency>
<groupId>com.liquidnet</groupId>
<artifactId>liquidnet-service-dragon-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency> <dependency>
<groupId>com.liquidnet</groupId> <groupId>com.liquidnet</groupId>
<artifactId>liquidnet-service-adam-api</artifactId> <artifactId>liquidnet-service-adam-api</artifactId>
......
package com.liquidnet.client.admin.zhengzai.goblin.dto;
import lombok.Data;
import java.io.Serializable;
import java.math.BigDecimal;
/**
* 演出-商品关联绑定请求 DTO
*/
@Data
public class SqbPerfGoodsBindItemParam implements Serializable {
private static final long serialVersionUID = 1L;
/** SKU ID */
private String skuId;
/** 排序权重 */
private Integer sort;
/** 换购价格(null 表示不设置换购价,按原价售卖) */
private BigDecimal settlementPrice;
}
package com.liquidnet.client.admin.zhengzai.goblin.service;
import com.liquidnet.client.admin.zhengzai.goblin.dto.SqbPerfGoodsBindItemParam;
import com.liquidnet.service.base.ResponseDto;
import com.liquidnet.service.goblin.dto.vo.GoblinAdminSqbGoodsVo;
import com.liquidnet.service.goblin.dto.vo.GoblinSqbPerfGoodsVo;
import com.liquidnet.service.goblin.dto.vo.GoblinSqbPerfListRespVo;
import java.util.List;
/**
* 演出-收钱吧商品关联 服务接口
*/
public interface ISqbPerformanceGoodsService {
/**
* 关联演出与商品(批量,支持换购价/演出级自动下架全局配置)
*
* @param performancesId 演出ID
* @param items 绑定项列表(仅含 SKU ID、排序、换购价)
* @param autoOffline 演出结束后不在前台列表展示 0-否 1-是(全局配置,仅列表隐藏)
* @return 操作结果
*/
ResponseDto<Boolean> bind(String performancesId, List<SqbPerfGoodsBindItemParam> items, Integer autoOffline);
/**
* 解除演出与商品关联
*
* @param performancesId 演出ID
* @param skuId SKU ID
* @return 操作结果
*/
ResponseDto<Boolean> unbind(String performancesId, String skuId);
/**
* 查询演出关联的收钱吧商品列表(包含全局配置)
*
* @param performancesId 演出ID
* @return 商品列表及配置
*/
ResponseDto<GoblinSqbPerfListRespVo> list(String performancesId);
/**
* 搜索收钱吧商品(skuType=33);有关键词时按 SPU 商品名称模糊匹配;无关键词时返回少量候选 SKU。
*
* @param keyword 商品(SPU)名称关键词,可为空
* @return 列表项含 spuTitle、skuTitle、title(一般为「商品名-规格名」)
*/
ResponseDto<List<GoblinAdminSqbGoodsVo>> searchGoods(String keyword);
}
...@@ -224,6 +224,21 @@ public class GoblinRedisUtils { ...@@ -224,6 +224,21 @@ public class GoblinRedisUtils {
return vo; return vo;
} }
/**
* 与 goblin 服务一致:SPU 基础缓存(用于后台与 C 端上下架状态对齐)
*/
public GoblinGoodsInfoVo getGoodsInfoVo(String spuId) {
if (spuId == null || spuId.isEmpty()) {
return null;
}
String rk = GoblinRedisConst.BASIC_GOODS.concat(spuId);
GoblinGoodsInfoVo vo = (GoblinGoodsInfoVo) redisDataSourceUtil.getRedisGoblinUtil().get(rk);
if (null == vo) {
return null;
}
return vo;
}
//覆盖 站位宾哥要dto //覆盖 站位宾哥要dto
public void setNftNumDetails(String num, String skuId, GalaxyNftPublishAndBuyReqDto dto) { public void setNftNumDetails(String num, String skuId, GalaxyNftPublishAndBuyReqDto dto) {
String redisKey = GoblinRedisConst.GOBLIN_NUM_DETAILS.concat(num).concat(skuId); String redisKey = GoblinRedisConst.GOBLIN_NUM_DETAILS.concat(num).concat(skuId);
...@@ -249,4 +264,14 @@ public class GoblinRedisUtils { ...@@ -249,4 +264,14 @@ public class GoblinRedisUtils {
rk = rk.concat(skuId); rk = rk.concat(skuId);
return (int) redisDataSourceUtil.getRedisGoblinUtil().incr(rk, stock); return (int) redisDataSourceUtil.getRedisGoblinUtil().incr(rk, stock);
} }
/**
* 清除演出关联收钱吧商品缓存
*
* @param performancesId 演出ID
*/
public void delPerformanceGoodsCache(String performancesId) {
String redisKey = GoblinRedisConst.SQB_PERFORMANCE_GOODS.concat(performancesId);
redisDataSourceUtil.getRedisGoblinUtil().del(redisKey);
}
} }
...@@ -21,6 +21,7 @@ import com.liquidnet.service.kylin.mapper.KylinOrderRefundBatchesMapper; ...@@ -21,6 +21,7 @@ import com.liquidnet.service.kylin.mapper.KylinOrderRefundBatchesMapper;
import com.liquidnet.service.kylin.mapper.KylinOrderRefundsMapper; import com.liquidnet.service.kylin.mapper.KylinOrderRefundsMapper;
import com.liquidnet.service.kylin.mapper.KylinOrderTicketsMapper; import com.liquidnet.service.kylin.mapper.KylinOrderTicketsMapper;
import com.liquidnet.service.kylin.mapper.KylinPerformancesMapper; import com.liquidnet.service.kylin.mapper.KylinPerformancesMapper;
import com.liquidnet.service.dragon.support.WepayAppletPaySupport;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils; import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
...@@ -67,9 +68,9 @@ public class KylinRefundPerformancesAdminServiceImpl { ...@@ -67,9 +68,9 @@ public class KylinRefundPerformancesAdminServiceImpl {
public ResponseDto refundBatchApply(RefundBatchApplyParam refundBatchApplyParam) { public ResponseDto refundBatchApply(RefundBatchApplyParam refundBatchApplyParam) {
String targetId = refundBatchApplyParam.getTargetId(); String targetId = refundBatchApplyParam.getTargetId();
// 查询需要退的金额和数量 // 查询需要退的金额和数量
String[] paymentTypeAlipay = {"APPALIPAY", "WAPALIPAY", "alipay"}; String[] paymentTypeAlipay = WepayAppletPaySupport.alipayPaymentTypesForRefundStatis();
HashMap<String, Object> orderStatisAlipay = kylinOrderTicketsMapper.getPerformanceRefundOrderStatis(targetId, paymentTypeAlipay); HashMap<String, Object> orderStatisAlipay = kylinOrderTicketsMapper.getPerformanceRefundOrderStatis(targetId, paymentTypeAlipay);
String[] paymentTypeWepay = {"APPWEPAY", "APPLETWEPAY", "WAPWEPAY", "JSWEPAY", "wepay"}; String[] paymentTypeWepay = WepayAppletPaySupport.wechatPaymentTypesForRefundStatis();
HashMap<String, Object> orderStatisWepay = kylinOrderTicketsMapper.getPerformanceRefundOrderStatis(targetId, paymentTypeWepay); HashMap<String, Object> orderStatisWepay = kylinOrderTicketsMapper.getPerformanceRefundOrderStatis(targetId, paymentTypeWepay);
BigDecimal totalPriceRefundAlipay = new BigDecimal(0.0); BigDecimal totalPriceRefundAlipay = new BigDecimal(0.0);
Integer totalRefundNumberAlipay = 0; Integer totalRefundNumberAlipay = 0;
......
...@@ -123,7 +123,8 @@ public class LnsRegex { ...@@ -123,7 +123,8 @@ public class LnsRegex {
/** /**
* 支持的支付终端 * 支持的支付终端
*/ */
public static final String TRIPLE_PF_FOR_PAY_TERMINAL = "\\b(app|wap|js|applet)\\b"; public static final String TRIPLE_PF_FOR_PAY_TERMINAL =
"\\b(app|wap|js|applet|appletb|appletdoudou|appletmootoo|appletwenque|web|wappage|micropay)\\b";
/** /**
* 支持的支付方式 * 支持的支付方式
*/ */
......
...@@ -12,12 +12,17 @@ import javax.crypto.SecretKey; ...@@ -12,12 +12,17 @@ import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec; import javax.crypto.spec.SecretKeySpec;
import java.util.Date; import java.util.Date;
import java.util.Map; import java.util.Map;
import java.util.UUID;
@Data @Data
@Component("jwtValidator") @Component("jwtValidator")
@ConfigurationProperties(prefix = "jwt") @ConfigurationProperties(prefix = "jwt")
public class JwtValidator { public class JwtValidator {
private String ssoRedisKey = "adam:identity:sso:"; private String ssoRedisKey = "adam:identity:sso:";
/** 用户会话:adam:session:{jti} = uid */
private String sessionRedisKey = "adam:session:";
/** 用户下活跃 jti 集合:adam:session:user:{uid} = {jti,...},用于按人踢线 */
private String userSessionsRedisKey = "adam:session:user:";
private String msoRedisKey = "adam:identity:mso:"; private String msoRedisKey = "adam:identity:mso:";
private String secret; private String secret;
// 分钟 // 分钟
...@@ -45,15 +50,32 @@ public class JwtValidator { ...@@ -45,15 +50,32 @@ public class JwtValidator {
* @return token字符串 * @return token字符串
*/ */
public String create(Map<String, Object> claimsMap) { public String create(Map<String, Object> claimsMap) {
return create(claimsMap, generateJti());
}
public String create(Map<String, Object> claimsMap, String jti) {
long nowMillis = System.currentTimeMillis(); long nowMillis = System.currentTimeMillis();
long expMillis = System.currentTimeMillis() + expireTtl * 60000; long expMillis = nowMillis + expireTtl * 60000;
JwtBuilder builder = Jwts.builder() return Jwts.builder()
.setClaims(claimsMap) .setClaims(claimsMap)
.setId(jti)
.setIssuedAt(new Date(nowMillis)) .setIssuedAt(new Date(nowMillis))
.setExpiration(new Date(expMillis)) .setExpiration(new Date(expMillis))
.signWith(SignatureAlgorithm.HS256, this.initSecretKey(this.secret)); .signWith(SignatureAlgorithm.HS256, this.initSecretKey(this.secret))
return builder.compact(); .compact();
}
public String generateJti() {
return UUID.randomUUID().toString().replace("-", "");
}
public String sessionKey(String jti) {
return sessionRedisKey.concat(jti);
}
public String userSessionsKey(String uid) {
return userSessionsRedisKey.concat(uid);
} }
/** /**
......
...@@ -18,6 +18,7 @@ public class CurrentUtil { ...@@ -18,6 +18,7 @@ public class CurrentUtil {
public static final String TOKEN_NICKNAME = "nickname"; public static final String TOKEN_NICKNAME = "nickname";
public static final String TOKEN_TYPE = "type"; public static final String TOKEN_TYPE = "type";
public static final String TOKEN_UCREATED = "c_at"; public static final String TOKEN_UCREATED = "c_at";
public static final String TOKEN_JTI = "jti";
public static final String TOKEN_TYPE_VAL_USER = "user"; public static final String TOKEN_TYPE_VAL_USER = "user";
public static final String TOKEN_TYPE_VAL_STATION = "station"; public static final String TOKEN_TYPE_VAL_STATION = "station";
......
package com.liquidnet.commons.lang.util; package com.liquidnet.commons.lang.util;
import java.math.BigInteger;
import java.nio.charset.Charset; import java.nio.charset.Charset;
import java.security.MessageDigest; import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
...@@ -20,20 +19,13 @@ public class MD5Utils { ...@@ -20,20 +19,13 @@ public class MD5Utils {
* 使用md5的算法进行加密 * 使用md5的算法进行加密
*/ */
public static String md5(String plainText) { public static String md5(String plainText) {
byte[] secretBytes = null;
try { try {
secretBytes = MessageDigest.getInstance("md5").digest(plainText.getBytes(Charset.defaultCharset())); byte[] secretBytes = MessageDigest.getInstance("md5").digest(plainText.getBytes(Charset.defaultCharset()));
// 不可使用 BigInteger.toString(16):会吞掉高位为 0 的半字节/整字节,导致 MD5 非固定 32 位十六进制(微信二次签名会偶发失败)
return bufferToHex(secretBytes);
} catch (NoSuchAlgorithmException e) { } catch (NoSuchAlgorithmException e) {
throw new RuntimeException("没有md5这个算法!"); throw new RuntimeException("没有md5这个算法!");
} }
String md5code = new BigInteger(1, secretBytes).toString(16);// 16进制数字
// 如果生成数字未满32位,需要前面补0
if (md5code.length() < 32) {
for (int i = 0; i <= 32 - md5code.length(); i++) {
md5code = "0" + md5code;
}
}
return md5code;
} }
protected static MessageDigest messagedigest = null; protected static MessageDigest messagedigest = null;
......
...@@ -57,6 +57,16 @@ public class RedisKeyExpireConst { ...@@ -57,6 +57,16 @@ public class RedisKeyExpireConst {
// 演出关联阵容缓存过期时间 // 演出关联阵容缓存过期时间
public static final long PERFORMANCES_ARTISTS_EXPIRE = 30 * 24 * 60 * 60; public static final long PERFORMANCES_ARTISTS_EXPIRE = 30 * 24 * 60 * 60;
/**
* 演出关联收钱吧商品缓存过期时间 (30天)
*/
public static final long SQB_PERFORMANCE_GOODS_EXPIRE = 30 * 24 * 60 * 60;
/**
* 收钱吧下单防重锁过期时间 (10秒)
*/
public static final long SQB_ORDER_LOCK_EXPIRE = 10;
// 已发布状态徽章过期时间:30天 // 已发布状态徽章过期时间:30天
public static final long CAOMEI_BADGE_PUBLISHED_EXPIRE = 30 * 24 * 60 * 60; public static final long CAOMEI_BADGE_PUBLISHED_EXPIRE = 30 * 24 * 60 * 60;
} }
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>com.liquidnet</groupId>
<artifactId>liquidnet-common-third</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>liquidnet-common-third-sqb</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>com.liquidnet</groupId>
<artifactId>liquidnet-common-base</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
package com.liquidnet.common.third.sqb.config;
import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@ConfigurationProperties(prefix = "liquidnet.sqb")
@Component
@Setter
@Getter
public class SqbConfig {
private String appId;
private String appKey;
private String appCode;
/**
* 商户ID
*/
private String merchantId;
/**
* 商户UserID
*/
private String merchantUserId;
/**
* 角色
*/
private String role;
/**
* 公钥
*/
private String publicKey;
private String baseApi;
}
package com.liquidnet.common.third.sqb.param.callback;
import lombok.Data;
@Data
/**
* CallbackParams
*/
public class CallbackParams {
/** 推送事件ID,全局唯一 */
private Long eventId;
/** 推送时间戳,当前时间毫秒值 */
private Long timestamp;
/** 随机字串,用于签名 */
private String nonce;
/** 订单数据 JSON字符串 (详见 SqbOrderContentDTO) */
private String content;
/** 报文签名 */
private String signature;
}
package com.liquidnet.common.third.sqb.param.callback;
import lombok.Data;
import java.math.BigDecimal;
import java.util.List;
@Data
/**
* SqbVoucherStatusDTO
*/
public class CouponCallbackContent {
/** 订单Sn */
private String orderSn;
/** 商城Sn */
private String mallSn;
/** 商户Sn */
private String merchantSn;
/** 门店id */
private String storeId;
/**
* 券列表(收钱吧字段名为 orderVoucherList;单 SKU 场景取首条即可,多券需后续扩展结构)
*/
private List<VoucherItem> orderVoucherList;
@Data
/**
* VoucherItem
*/
public static class VoucherItem {
/** 券号 */
private String voucherNo;
/** 类型 */
private Integer type;
/** 券状态 (0未核销, 1已核销, 2未核销退款, 3已核销退款中, 4未核销退款完成, 5已核销退款完成, 6已失效) */
private Byte targetState;
/** 券原状态 */
private Byte sourceState;
/** 券名称 */
private String voucherName;
/** 操作时间 (yyyy-MM-dd HH:mm:ss) */
private String operationTime;
/** 券对应的商品信息 */
private VoucherProductInfo item;
/** 券二维码地址 */
private String qrCodeUrl;
/** 券二维码内容 */
private String qrCodeContent;
/** 原金额 (单位:分) */
private Long oriAmount;
/** 实收金额 (单位:分) */
private Long receivedAmount;
/** 核销信息 (已核销会有这部分) */
private RedeemInfo redeemInfo;
}
@Data
/**
* VoucherProductInfo
*/
public static class VoucherProductInfo {
/** spuId(回调里可能是字符串数字) */
private String spuId;
/** skuId */
private String skuId;
/** 商品标题 */
private String title;
/** 商品图片 */
private String image;
private String qrCodeUrl;
private String qrCodeContent;
private BigDecimal oriAmount;
private BigDecimal receivedAmount;
}
@Data
/**
* RedeemInfo
*/
public static class RedeemInfo {
/** 操作来源 (如: EXTERN) */
private String redeemSource;
/** 操作appId */
private String redeemAppId;
/** 客户端编码 */
private String redeemClientSn;
/** 外部编码 (appId + 请求号) */
private String redeemExternalOrderSn;
/** 操作商户 (userId) */
private String operatorMerchantId;
}
}
package com.liquidnet.common.third.sqb.param.callback;
import lombok.Data;
import java.math.BigDecimal;
import java.util.List;
@Data
/**
* OrderCallbackContent
*/
public class OrderCallbackContent {
/**
* 订单号
*/
private String orderSn;
/**
* 支付流水号列表
*/
private List<String> payTsnList;
/**
* 终端号
*/
private String terminalSn;
/**
* 门店号
*/
private String storeSn;
/**
* 商城名称
*/
private String mallName;
/**
* 订单金额
*/
private BigDecimal orderAmount;
/**
* 创建时间
*/
private String createdAt;
/**
* 订单状态码 0:已创建 10:已支付 35:已完成 40:已取消
*/
private Integer orderStateCode;
/**
* 商品明细列表
*/
private List<Item> items;
/**
* 收集的信息 JSON字符串
*/
private String collectedInfo;
/**
* 预订单编码
*/
private List<String> preOrderSns;
/**
* 订单签名
*/
private String orderSignature;
/**
* 支付的代客下单数据
*/
private List<PreOrder> preOrderList;
/**
* 商品明细
*/
@Data
public static class Item {
/**
* 商品标题
*/
private String title;
/**
* 规格描述
*/
private String skuDesc;
/**
* 数量
*/
private String quantity;
/**
* 单位
*/
private String unit;
}
/**
* 采集数据
*/
@Data
public static class CollectedInfo {
/**
* 控件类型
*/
private String type;
/**
* 控件格式
*/
private String form;
/**
* 字段名
*/
private String fieldName;
/**
* 采集数据内容
*/
private String content;
}
/**
* 支付的代客下单数据
*/
@Data
public static class PreOrder {
/**
* 预订单id
*/
private String preOrderId;
/**
* 预订单编号
*/
private String preOrderSn;
/**
* 请求号
*/
private String requestId;
}
}
package com.liquidnet.common.third.sqb.param.callback;
import lombok.Data;
import java.util.List;
@Data
/**
* SqbRefundContentDTO
*/
public class RefundCallbackContent {
/** 售后单号 (全局唯一) */
private String ticketSn;
/** 订单号 */
private String orderSn;
/** 原状态 */
private Integer sourceState;
/** 目标状态 (20:完成, 15:退款完成, 0:创建, 10:退款中, 30:取消退款) */
private Integer targetState;
/** 下单金额 (单位:分) */
private Long amount;
/** 申请金额 (单位:分) */
private Long applyAmount;
/** 请求号 */
private String requestId;
/** 来源 (如: EXTERN) */
private String requestSource;
/** 退款的商品信息 */
private SqbRefundItemContainer item;
@Data
/**
* SqbRefundItemContainer
*/
public static class SqbRefundItemContainer {
/** 退款类型 (1:商品, 2:金额) */
private Byte type;
/** 商品明细列表 */
private List<SqbRefundItemDetail> items;
}
@Data
/**
* SqbRefundItemDetail
*/
public static class SqbRefundItemDetail {
/** spu id */
private String spuId;
/** sku id */
private String skuId;
/** 标题 */
private String title;
/** 数量 */
private String quantity;
/** 退款类型 (0:正常商品, 1:自定义商品) */
private Byte type;
}
}
package com.liquidnet.common.third.sqb.param.request;
import lombok.Data;
/**
* 创建收单请求
*/
@Data
public class AcquiringCreateRequest {
/**
* 应用id
*/
private String appid;
/**
* 卖家信息
*/
private CommonRequest.Seller seller;
/**
* 卖家信息
*/
private Order orderID;
/**
* 订单信息
*/
@Data
public static class Order {
/**
* 订单ID
*/
private String sn;
/**
* 订单密码
*/
private String signature;
}
}
package com.liquidnet.common.third.sqb.param.request;
import lombok.Data;
/**
* 收银台查询请求
*/
@Data
public class CashierQueryRequest {
/** 应用id */
private String appid;
/** 商户信息 */
private CommonRequest.Seller seller;
/** 支付模式代码 */
private Integer paymentMode;
/** 支付环境 */
private PaymentEnv paymentEnv;
/** 付款人信息 */
private CommonRequest.Payer payer;
/** 收单信息 */
private CommonRequest.Acquiring acquiringInfo;
@Data
/**
* 支付环境信息
*/
public static class PaymentEnv {
/** ip地址 最大40位 */
private String ip;
/** 支付客户端 最大32位 */
private String client;
/** 设备号 最大64位 */
private String device;
/** 版本号 */
private String version;
}
}
package com.liquidnet.common.third.sqb.param.request;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
@Data
public class CommonRequest {
/**
* 商城信息
*/
@Data
@JsonIgnoreProperties(ignoreUnknown = true)
@AllArgsConstructor
@NoArgsConstructor
public static class Mall {
/**
* 商城ID
*/
private String mallSn;
/**
* 商城密码
*/
private String signature;
}
/**
* 卖家信息/商户信息
*/
@Data
@JsonIgnoreProperties(ignoreUnknown = true)
@AllArgsConstructor
@NoArgsConstructor
public static class Seller {
/**
* 商户ID
*/
private String merchantId;
/**
* 商户userID
*/
private String merchantUserId;
/**
* 角色 固定值(super_admin)
*/
private String role;
}
/**
* 买家信息
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
public static class Buyer {
/**
* 买家ID(用户唯一标识)
*/
private String buyerId;
}
/**
* 付款人信息
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
public static class Payer {
/**
* 付款人ID
*/
private String userId;
}
/**
* 收单信息
*/
@Data
@JsonIgnoreProperties(ignoreUnknown = true)
@AllArgsConstructor
@NoArgsConstructor
public static class Acquiring {
/**
* 收单号
*/
private String acquiringSn;
/**
* 收单密钥
*/
private String signature;
}
/**
* 金额构成信息
*/
@Data
@JsonIgnoreProperties(ignoreUnknown = true)
public static class AmountComposition {
/**
* 金额构成项列表
*/
private List<CompositionItem> compositionItems;
}
/**
* 金额构成项详情
*/
@Data
@JsonIgnoreProperties(ignoreUnknown = true)
public static class CompositionItem {
/**
* 构成项类目
*/
private String category;
/**
* 构成项金额
*/
private Long amount;
}
/**
* 订单信息
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public static class OrderInfo {
/**
* 订单ID
*/
private String sn;
/**
* 订单密码
*/
private String signature;
}
}
package com.liquidnet.common.third.sqb.param.request;
import lombok.Data;
/**
* 查询券码请求
*/
@Data
public class CouponQueryRequest {
/** 应用id */
private String appid;
/** 订单信息 */
private CommonRequest.OrderInfo orderID;
/** 卖家信息 */
private CommonRequest.Seller seller;
}
package com.liquidnet.common.third.sqb.param.request;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
/**
* 券退款请求参数
*/
@Data
public class CouponRefundRequest {
/**
* 应用ID(收钱吧分配的应用id)
*/
private String appid;
/**
* 卖家信息
*/
private CommonRequest.Seller seller;
/**
* 订单信息
*/
private CommonRequest.OrderInfo orderID;
/**
* 申请退款信息不能为空
*/
private RefundInfo refundInfo;
/**
* 退款请求id(${AppCode}+id)
*/
private String requestId;
/**
* 退款来源(固定值:EXTERN)
*/
private String requestSource;
/**
* 退款信息
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public static class RefundInfo {
/**
* 申请退款金额(单位:分)
*/
private Long applyAmount;
/**
* 退款类型(1商品 2金额)
*/
private Byte type;
/**
* 退款明细(商品必填)
*/
private List<RefundItem> items;
/**
* 退款原因
*/
private String refundReason;
}
/**
* 退款明细商品
*/
@Data
public static class RefundItem {
/**
* spu
*/
private String spuId;
/**
* sku
*/
private String skuId;
/**
* 标题
*/
private String title;
/**
* 商品图片
*/
private String img;
/**
* 数量
*/
private String quantity;
/**
* 退款类型(0正常商品 1自定义商品)
*/
private Byte type;
}
}
package com.liquidnet.common.third.sqb.param.request;
import lombok.Data;
import java.util.List;
/**
* 券码状态同步
*/
@Data
public class CouponStatusSyncRequest {
/** 应用ID(聚合收单唯一ID,需申请) */
private String appid;
/** 卖家/商户信息(与 queryCoupon、refund 等接口一致,收钱吧侧必填) */
private CommonRequest.Seller seller;
/** 券号 */
private List<String> voucherNos;
/** 用户ID(自定义,核销用户id) */
private String redeemMerchantId;
/** 外部单号(${AppCode}+id,AppCode需要分配) */
private String redeemExternalOrderSn;
/** 来源(固定值:EXTERN) */
private String redeemSource;
/** 核销终端号(自定义) */
private String clientSn;
/** 券使用状态(0未核销,1已核销) */
private Byte status;
}
package com.liquidnet.common.third.sqb.param.request;
import lombok.Data;
import java.util.List;
import java.util.Map;
/**
* 创建微信预支付订单请求
*/
@Data
public class CreateWechatPrepayOrderRequest {
/** 应用id */
private String appid;
/** 商户信息 */
private CommonRequest.Seller seller;
/** 收单号 */
private String acquiringSn;
/** 收单签名 */
private String signature;
/** 支付工具 */
private List<UsingPayTool> usingPayTools;
/** 支付环境 */
private PaymentEnv paymentEnv;
/** 支付工具签名 */
private String selectedSignature;
/** 序列号 */
private String seq;
@Data
/**
* 支付工具使用详情
*/
public static class UsingPayTool {
/** 支付工具ID */
private Long id;
/** 支付工具代码 */
private Integer payTool;
/** 支付模式 */
private Integer payMode;
/** 支付金额 */
private String amount;
/** 金额构成 */
private CommonRequest.AmountComposition amountComposition;
/** 用户身份信息 */
private String identity;
/** 支付请求号 */
private String requestSn;
/** 通道扩展参数 */
private Map<String, Object> channelExt;
}
@Data
/**
* 支付环境信息
*/
public static class PaymentEnv {
/** 付款终端ip */
private String clientIp;
/** 付款经纬度 */
private ClientPoi clientPoi;
/** 支付入口 */
private String paymentEntry;
}
@Data
/**
* 地理位置信息
*/
public static class ClientPoi {
/** 经度信息 */
private String longitude;
/** 纬度信息 */
private String latitude;
}
}
package com.liquidnet.common.third.sqb.param.request;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
/**
* 商城列表接口
*/
@Data
public class MallListQueryRequest implements Serializable {
private static final long serialVersionUID = 1L;
/** 应用ID */
private String appid;
/** 过滤条件 */
private Filter filter;
/** 分页游标 */
private Cursor cursor;
/** 排序条件 */
private Sort sort;
@Data
/**
* 查询过滤条件
*/
public static class Filter {
/** 商户信息 */
private CommonRequest.Seller seller;
/** 商城行业筛选 */
private List<String> industryCodes;
/** 商城状态筛选 */
private List<Byte> states;
/** 商城状态筛选 */
private Byte state;
/** 创建时间起始 */
private String beginDateTime;
/** 创建时间截止 */
private String endDateTime;
}
@Data
/**
* 排序规则
*/
public static class Sort {
/** 排序方式: DESC/ASC */
private String sort;
/** 排序字段 */
private String sortField;
}
@Data
/**
* 分页游标
*/
public static class Cursor {
/** 游标字段 分页依据的字段(固定为id) */
private String cursorField;
/** 结束游标 上一页的结束游标(首次查询传 null) */
private String endCursor;
/** 查询数量 每页返回的最大订单数 */
private Integer count;
}
}
package com.liquidnet.common.third.sqb.param.request;
import lombok.Data;
/**
* 商城列表查询响应数据
*/
@Data
public class MallProductsQueryRequest {
/** 应用ID */
private String appid;
/** 商户信息 */
private CommonRequest.Seller seller;
/** 商城标识 */
private CommonRequest.Mall mallID;
}
package com.liquidnet.common.third.sqb.param.request;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
import java.util.List;
/**
* 收钱吧 - 订单创建 请求参数
*
* @author liquidnet
* @since 2026-03-16
*/
@Data
public class OrderCreateRequest implements Serializable {
private static final long serialVersionUID = 1L;
/** 应用ID(聚合收单唯一ID,需申请) */
private String appid;
/** 商城信息 */
private CommonRequest.Mall mallID;
/** 商户信息 */
private CommonRequest.Seller seller;
/** 结算项ID */
private String checkoutItemsId;
/** 买家信息 */
private CommonRequest.Buyer buyer;
/** 请求ID 不超过40位 */
private String requestId;
/** 标题 不超过32 */
private String subject;
}
package com.liquidnet.common.third.sqb.param.request;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
/**
* 收钱吧 - 创建结算明细 请求参数
*
* @author liquidnet
* @since 2026-03-16
*/
@Data
public class SettlementCreateRequest implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 应用ID(聚合收单唯一ID,需申请)
*/
private String appid;
/**
* 商城信息
*/
private CommonRequest.Mall mallID;
/**
* 商户信息
*/
private CommonRequest.Seller seller;
/**
* 买家信息
*/
private CommonRequest.Buyer buyer;
/**
* 结算明细组(结算条目列表)
*/
private List<CheckoutItem> checkoutItems;
/**
* 结算总金额(单位:分);纯金额结算时必填。商品结算走 checkoutItems 且 type=1 时不要传
*/
private Long amount;
/**
* 结算明细条目
*/
@Data
public static class CheckoutItem {
/**
* sqb 商品识别号(商品唯一标识,如 spuId)
*/
private String spuId;
/**
* sqb 规格识别号(SKU唯一标识,如 skuId)
*/
private String skuId;
/**
* 单价(单位:分)
*/
private Long price;
/**
* 购买数量
*/
private String quantity;
/**
* 商品类型(0 正常商品 1 自定义商品)
*/
private Byte type;
/**
* 商品标题
*/
private String title;
/**
* 商品图片链接
*/
private String image;
}
}
package com.liquidnet.common.third.sqb.param.response;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.liquidnet.common.third.sqb.param.response.data.AcquiringCreateData;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* 创建收单响应参数
*/
@EqualsAndHashCode(callSuper = true)
@Data
@JsonIgnoreProperties(ignoreUnknown = true)
public class AcquiringCreateResponse extends BaseResponse<AcquiringCreateData> {
}
package com.liquidnet.common.third.sqb.param.response;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.liquidnet.common.third.sqb.param.response.data.CashierQueryData;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* 自助收银查询响应
*/
@EqualsAndHashCode(callSuper = true)
@Data
@JsonIgnoreProperties(ignoreUnknown = true)
public class CashierQueryResponse extends BaseResponse<CashierQueryData>{
}
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