diff --git a/src/main/java/com/budwk/app/zhgh/pointsmall/h5/loveaid/PointsMallH5LoveAidController.java b/src/main/java/com/budwk/app/zhgh/pointsmall/h5/loveaid/PointsMallH5LoveAidController.java deleted file mode 100644 index 3ba88396..00000000 --- a/src/main/java/com/budwk/app/zhgh/pointsmall/h5/loveaid/PointsMallH5LoveAidController.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.budwk.app.zhgh.pointsmall.h5.loveaid; - -import cn.dev33.satoken.annotation.SaCheckPermission; -import org.nutz.ioc.loader.annotation.IocBean; -import org.nutz.mvc.annotation.At; -import org.nutz.mvc.annotation.Ok; - -@IocBean -@Ok("json:full") -@At("/platform/h5/points-mall/loveAid") -public class PointsMallH5LoveAidController { - - @At("") - @Ok("beetl:/platform/zhghh5/points-mall/loveAid/index.html") - @SaCheckPermission("h5.points.mall") - public void index() { - } -} diff --git a/src/main/java/com/budwk/app/zhgh/pointsmall/h5/me/PointsMallH5MeController.java b/src/main/java/com/budwk/app/zhgh/pointsmall/h5/me/PointsMallH5MeController.java deleted file mode 100644 index 1143aea0..00000000 --- a/src/main/java/com/budwk/app/zhgh/pointsmall/h5/me/PointsMallH5MeController.java +++ /dev/null @@ -1,50 +0,0 @@ -package com.budwk.app.zhgh.pointsmall.h5.me; - -import cn.dev33.satoken.annotation.SaCheckPermission; -import cn.dev33.satoken.stp.StpUtil; -import cn.hutool.core.util.StrUtil; -import com.budwk.app.base.result.Result; -import com.budwk.app.zhgh.pointsmall.points.service.PointsMallUserPointsService; -import org.nutz.ioc.loader.annotation.Inject; -import org.nutz.ioc.loader.annotation.IocBean; -import org.nutz.mvc.annotation.At; -import org.nutz.mvc.annotation.Ok; -import org.nutz.mvc.annotation.Param; - -@IocBean -@Ok("json:full") -@At("/platform/h5/points-mall/me") -public class PointsMallH5MeController { - - @Inject - private PointsMallUserPointsService pointsMallUserPointsService; - - @At("") - @Ok("beetl:/platform/zhghh5/points-mall/me/index.html") - @SaCheckPermission("h5.points.mall") - public void index() { - } - - @At("/points") - @SaCheckPermission("h5.points.mall") - public Result points(@Param("userId") String userId) { - return Result.success(pointsMallUserPointsService.availablePoints(currentUserId(userId))); - } - - @At("/userInfo") - @SaCheckPermission("h5.points.mall") - public Result userInfo(@Param("userId") String userId) { - return Result.success(pointsMallUserPointsService.userInfo(currentUserId(userId))); - } - - private String currentUserId(String userId) { - if (StrUtil.isNotBlank(userId)) { - return userId; - } - try { - return StpUtil.getLoginIdAsString(); - } catch (Exception e) { - return ""; - } - } -} diff --git a/src/main/java/com/budwk/app/zhgh/pointsmall/h5/movies/PointsMallH5MoviesController.java b/src/main/java/com/budwk/app/zhgh/pointsmall/h5/movies/PointsMallH5MoviesController.java deleted file mode 100644 index 488d3b43..00000000 --- a/src/main/java/com/budwk/app/zhgh/pointsmall/h5/movies/PointsMallH5MoviesController.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.budwk.app.zhgh.pointsmall.h5.movies; - -import cn.dev33.satoken.annotation.SaCheckPermission; -import org.nutz.ioc.loader.annotation.IocBean; -import org.nutz.mvc.annotation.At; -import org.nutz.mvc.annotation.Ok; - -@IocBean -@Ok("json:full") -@At("/platform/h5/points-mall/movies") -public class PointsMallH5MoviesController { - - @At("") - @Ok("beetl:/platform/zhghh5/points-mall/movies/index.html") - @SaCheckPermission("h5.points.mall") - public void index() { - } -} diff --git a/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/controller/PointsMallBridgeController.java b/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/controller/PointsMallBridgeController.java new file mode 100644 index 00000000..b2149d14 --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/controller/PointsMallBridgeController.java @@ -0,0 +1,113 @@ +package com.budwk.app.zhgh.pointsmall.mallbridge.controller; + +import com.budwk.app.zhgh.pointsmall.mallbridge.dto.*; +import com.budwk.app.zhgh.pointsmall.mallbridge.model.MallInboundPointsResult; +import com.budwk.app.zhgh.pointsmall.mallbridge.model.MallInboundResult; +import com.budwk.app.zhgh.pointsmall.mallbridge.model.MallOutboundResult; +import com.budwk.app.zhgh.pointsmall.mallbridge.service.PointsMallBridgeService; +import org.nutz.ioc.loader.annotation.Inject; +import org.nutz.ioc.loader.annotation.IocBean; +import org.nutz.json.Json; +import org.nutz.mvc.annotation.At; +import org.nutz.mvc.annotation.Ok; +import org.nutz.mvc.annotation.POST; + +import javax.servlet.http.HttpServletRequest; +import java.io.BufferedReader; +import java.io.IOException; + +@IocBean +@Ok("json:full") +@At("/open") +public class PointsMallBridgeController { + + @Inject + private PointsMallBridgeService pointsMallBridgeService; + + @POST + @At("/connect/token") + public MallInboundResult getToken(HttpServletRequest request) { + try { + return pointsMallBridgeService.getToken(readBody(request, MallTokenDTO.class)); + } catch (Exception e) { + return MallInboundResult.fail(401, e.getMessage()); + } + } + + @POST + @At("/connect/refreshToken") + public MallInboundResult refreshToken(HttpServletRequest request) { + try { + return pointsMallBridgeService.refreshToken(readBody(request, MallTokenRefreshDTO.class)); + } catch (Exception e) { + return MallInboundResult.fail(401, e.getMessage()); + } + } + + @POST + @At("/pointOrder/queryPoints") + public MallInboundPointsResult queryPoints(HttpServletRequest request) { + try { + return pointsMallBridgeService.queryPoints(readBody(request, MallPointQueryDTO.class)); + } catch (Exception e) { + return MallInboundPointsResult.fail(401, e.getMessage()); + } + } + + @POST + @At("/pointOrder/pendingOrderInfo") + public MallInboundResult receivePending(HttpServletRequest request) { + return inbound(() -> pointsMallBridgeService.receivePending(readBody(request, MallPendingOrderDTO.class))); + } + + @POST + @At("/pointOrder/confirmPurchase") + public MallInboundResult confirmPurchase(HttpServletRequest request) { + return inbound(() -> pointsMallBridgeService.confirmPurchase(readBody(request, MallPurchaseConfirmDTO.class))); + } + + @POST + @At("/pointOrder/purchaseResult") + public MallInboundResult purchaseResult(HttpServletRequest request) { + return inbound(() -> pointsMallBridgeService.purchaseResult(readBody(request, MallPurchaseResultDTO.class))); + } + + @POST + @At("/pointOrder/pushOrderInfoMsg") + public MallInboundResult receiveEvent(HttpServletRequest request) { + return inbound(() -> pointsMallBridgeService.receiveEvent(readBody(request, MallOrderEventDTO.class))); + } + + @POST + @At("/pointOrder/queryOrderInfo") + public MallOutboundResult queryOrderInfo(HttpServletRequest request) { + try { + return pointsMallBridgeService.queryOrderInfo(readBody(request, MallOrderQueryDTO.class)); + } catch (Exception e) { + return MallOutboundResult.fail(401, e.getMessage()); + } + } + + private MallInboundResult inbound(InboundCall call) { + try { + return call.get(); + } catch (Exception e) { + return MallInboundResult.fail(401, e.getMessage()); + } + } + + private T readBody(HttpServletRequest request, Class type) throws IOException { + StringBuilder body = new StringBuilder(); + try (BufferedReader reader = request.getReader()) { + String line; + while ((line = reader.readLine()) != null) { + body.append(line); + } + } + return Json.fromJson(type, body.toString()); + } + + private interface InboundCall { + MallInboundResult get() throws Exception; + } +} diff --git a/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/dto/MallOrderEventDTO.java b/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/dto/MallOrderEventDTO.java new file mode 100644 index 00000000..35a0ecf8 --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/dto/MallOrderEventDTO.java @@ -0,0 +1,14 @@ +package com.budwk.app.zhgh.pointsmall.mallbridge.dto; + +import lombok.Data; + +@Data +public class MallOrderEventDTO { + private String supplierId; + private String token; + private Integer orderType; + private String orderId; + private String mainOrderId; + private String userId; + private Long time; +} diff --git a/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/dto/MallOrderQueryDTO.java b/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/dto/MallOrderQueryDTO.java new file mode 100644 index 00000000..f9a1f976 --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/dto/MallOrderQueryDTO.java @@ -0,0 +1,12 @@ +package com.budwk.app.zhgh.pointsmall.mallbridge.dto; + +import lombok.Data; + +@Data +public class MallOrderQueryDTO { + private String supplierId; + private String token; + private Integer orderType; + private String orderId; + private Long timestamp; +} diff --git a/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/dto/MallPendingOrderDTO.java b/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/dto/MallPendingOrderDTO.java new file mode 100644 index 00000000..7e82d0f0 --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/dto/MallPendingOrderDTO.java @@ -0,0 +1,11 @@ +package com.budwk.app.zhgh.pointsmall.mallbridge.dto; + +import lombok.Data; + +@Data +public class MallPendingOrderDTO { + private String supplierId; + private String token; + private String userId; + private OrderInfoDTO orderInfo; +} diff --git a/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/dto/MallPointQueryDTO.java b/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/dto/MallPointQueryDTO.java new file mode 100644 index 00000000..35d89485 --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/dto/MallPointQueryDTO.java @@ -0,0 +1,10 @@ +package com.budwk.app.zhgh.pointsmall.mallbridge.dto; + +import lombok.Data; + +@Data +public class MallPointQueryDTO { + private String supplierId; + private String token; + private String userId; +} diff --git a/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/dto/MallPurchaseConfirmDTO.java b/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/dto/MallPurchaseConfirmDTO.java new file mode 100644 index 00000000..0fa062b9 --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/dto/MallPurchaseConfirmDTO.java @@ -0,0 +1,15 @@ +package com.budwk.app.zhgh.pointsmall.mallbridge.dto; + +import lombok.Data; + +import java.math.BigDecimal; + +@Data +public class MallPurchaseConfirmDTO { + private String supplierId; + private String token; + private String orderId; + private BigDecimal totalPrice; + private BigDecimal wPayOrAPay; + private BigDecimal pointsPrice; +} diff --git a/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/dto/MallPurchaseResultDTO.java b/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/dto/MallPurchaseResultDTO.java new file mode 100644 index 00000000..4336d829 --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/dto/MallPurchaseResultDTO.java @@ -0,0 +1,17 @@ +package com.budwk.app.zhgh.pointsmall.mallbridge.dto; + +import lombok.Data; + +import java.math.BigDecimal; + +@Data +public class MallPurchaseResultDTO { + private String supplierId; + private String token; + private String orderId; + private BigDecimal totalPrice; + private BigDecimal wPayOrAPay; + private BigDecimal pointsPrice; + private Boolean purchaseResult; + private String message; +} diff --git a/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/dto/MallTokenDTO.java b/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/dto/MallTokenDTO.java new file mode 100644 index 00000000..9dbaee8a --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/dto/MallTokenDTO.java @@ -0,0 +1,12 @@ +package com.budwk.app.zhgh.pointsmall.mallbridge.dto; + +import lombok.Data; + +@Data +public class MallTokenDTO { + private String supplierId; + private String clientId; + private String clientSecret; + private String code; + private String timestamp; +} diff --git a/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/dto/MallTokenRefreshDTO.java b/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/dto/MallTokenRefreshDTO.java new file mode 100644 index 00000000..da2768d6 --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/dto/MallTokenRefreshDTO.java @@ -0,0 +1,12 @@ +package com.budwk.app.zhgh.pointsmall.mallbridge.dto; + +import lombok.Data; + +@Data +public class MallTokenRefreshDTO { + private String supplierId; + private String refreshToken; + private String clientId; + private String clientSecret; + private String timestamp; +} diff --git a/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/dto/MallTokenResDTO.java b/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/dto/MallTokenResDTO.java new file mode 100644 index 00000000..a5a2aefc --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/dto/MallTokenResDTO.java @@ -0,0 +1,14 @@ +package com.budwk.app.zhgh.pointsmall.mallbridge.dto; + +import lombok.Builder; +import lombok.Data; + +@Data +@Builder +public class MallTokenResDTO { + private String time; + private String accessToken; + private String refreshToken; + private long expire; + private long refreshExpire; +} diff --git a/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/dto/OrderInfoDTO.java b/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/dto/OrderInfoDTO.java new file mode 100644 index 00000000..d9293b57 --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/dto/OrderInfoDTO.java @@ -0,0 +1,33 @@ +package com.budwk.app.zhgh.pointsmall.mallbridge.dto; + +import lombok.Data; + +import java.math.BigDecimal; +import java.util.List; + +@Data +public class OrderInfoDTO { + private String orderId; + private String orderNumberId; + private String supplierId; + private String token; + private String aplName; + private String createTime; + private String updateTime; + private String deliveryTime; + private String orderFinishTime; + private String completeTime; + private String deliveryStatus; + private BigDecimal freightCost; + private BigDecimal wPayOrAPayFreightCost; + private BigDecimal refund; + private BigDecimal wPayOrAPayRefund; + private String logisticsOrderId; + private String crrgBsnNm; + private Integer orderState; + private BigDecimal totalPrice; + private BigDecimal wPayOrAPay; + private BigDecimal pointsPrice; + private String invoiceCode; + private List orderProInfos; +} diff --git a/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/dto/OrderProInfoDTO.java b/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/dto/OrderProInfoDTO.java new file mode 100644 index 00000000..5396c5dd --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/dto/OrderProInfoDTO.java @@ -0,0 +1,18 @@ +package com.budwk.app.zhgh.pointsmall.mallbridge.dto; + +import lombok.Data; + +import java.math.BigDecimal; +import java.util.List; + +@Data +public class OrderProInfoDTO { + private String sku; + private Integer number; + private BigDecimal price; + private String name; + private BigDecimal taxRate; + private List picInfo; + private String fileId; + private String filePath; +} diff --git a/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/model/MallInboundPointsResult.java b/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/model/MallInboundPointsResult.java new file mode 100644 index 00000000..6df11f82 --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/model/MallInboundPointsResult.java @@ -0,0 +1,27 @@ +package com.budwk.app.zhgh.pointsmall.mallbridge.model; + +import lombok.Data; + +import java.math.BigDecimal; + +@Data +public class MallInboundPointsResult { + private int resultCode; + private String message; + private BigDecimal userPoints; + + public static MallInboundPointsResult success(BigDecimal points) { + MallInboundPointsResult result = new MallInboundPointsResult(); + result.setResultCode(0); + result.setMessage("成功"); + result.setUserPoints(points); + return result; + } + + public static MallInboundPointsResult fail(int code, String message) { + MallInboundPointsResult result = new MallInboundPointsResult(); + result.setResultCode(code); + result.setMessage(message); + return result; + } +} diff --git a/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/model/MallInboundResult.java b/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/model/MallInboundResult.java new file mode 100644 index 00000000..0376cdd2 --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/model/MallInboundResult.java @@ -0,0 +1,23 @@ +package com.budwk.app.zhgh.pointsmall.mallbridge.model; + +import lombok.Data; + +@Data +public class MallInboundResult { + private int resultCode; + private String message; + + public static MallInboundResult success() { + MallInboundResult result = new MallInboundResult(); + result.setResultCode(0); + result.setMessage("成功"); + return result; + } + + public static MallInboundResult fail(int code, String message) { + MallInboundResult result = new MallInboundResult(); + result.setResultCode(code); + result.setMessage(message); + return result; + } +} diff --git a/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/model/MallInboundTokenResult.java b/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/model/MallInboundTokenResult.java new file mode 100644 index 00000000..271a6993 --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/model/MallInboundTokenResult.java @@ -0,0 +1,26 @@ +package com.budwk.app.zhgh.pointsmall.mallbridge.model; + +import lombok.Data; +import lombok.EqualsAndHashCode; + +@Data +@EqualsAndHashCode(callSuper = true) +public class MallInboundTokenResult extends MallInboundResult { + private String time; + private String accessToken; + private String refreshToken; + private Long expire; + private Long refreshExpire; + + public static MallInboundTokenResult success(String time, String accessToken, String refreshToken, long expire, long refreshExpire) { + MallInboundTokenResult result = new MallInboundTokenResult(); + result.setResultCode(0); + result.setMessage("成功"); + result.setTime(time); + result.setAccessToken(accessToken); + result.setRefreshToken(refreshToken); + result.setExpire(expire); + result.setRefreshExpire(refreshExpire); + return result; + } +} diff --git a/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/model/MallOutboundResult.java b/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/model/MallOutboundResult.java new file mode 100644 index 00000000..cad2758b --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/model/MallOutboundResult.java @@ -0,0 +1,28 @@ +package com.budwk.app.zhgh.pointsmall.mallbridge.model; + +import com.budwk.app.zhgh.pointsmall.mallbridge.dto.OrderInfoDTO; +import lombok.Data; + +import java.util.List; + +@Data +public class MallOutboundResult { + private int resultCode; + private String message; + private List orderInfo; + + public static MallOutboundResult success(List orderInfo) { + MallOutboundResult result = new MallOutboundResult(); + result.setResultCode(0); + result.setMessage("成功"); + result.setOrderInfo(orderInfo); + return result; + } + + public static MallOutboundResult fail(int code, String message) { + MallOutboundResult result = new MallOutboundResult(); + result.setResultCode(code); + result.setMessage(message); + return result; + } +} diff --git a/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/models/PointsMallSupplierTokenStore.java b/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/models/PointsMallSupplierTokenStore.java new file mode 100644 index 00000000..d3126065 --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/models/PointsMallSupplierTokenStore.java @@ -0,0 +1,49 @@ +package com.budwk.app.zhgh.pointsmall.mallbridge.models; + +import com.budwk.app.base.model.BaseModel; +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.nutz.dao.entity.annotation.*; +import org.nutz.dao.interceptor.annotation.PrevInsert; + +import java.io.Serializable; +import java.util.Date; + +@Data +@EqualsAndHashCode(callSuper = true) +@Table("points_mall_supplier_token_store") +@Comment("积分商城供应商Token") +public class PointsMallSupplierTokenStore extends BaseModel implements Serializable { + + @Name + @Column + @Comment("ID") + @ColDefine(type = ColType.VARCHAR, width = 32) + @PrevInsert(uu32 = true) + private String id; + + @Column + @ColDefine(type = ColType.VARCHAR, width = 64) + private String supplierId; + + @Column + @ColDefine(type = ColType.VARCHAR, width = 128) + private String clientId; + + @Column + @ColDefine(type = ColType.VARCHAR, width = 1000) + private String accessToken; + + @Column + @ColDefine(type = ColType.VARCHAR, width = 1000) + private String refreshToken; + + @Column + private Date accessExpireTime; + + @Column + private Date refreshExpireTime; + + @Column + private Boolean isValid; +} diff --git a/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/service/PointsMallBridgeService.java b/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/service/PointsMallBridgeService.java new file mode 100644 index 00000000..c655d91e --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/service/PointsMallBridgeService.java @@ -0,0 +1,25 @@ +package com.budwk.app.zhgh.pointsmall.mallbridge.service; + +import com.budwk.app.zhgh.pointsmall.mallbridge.dto.*; +import com.budwk.app.zhgh.pointsmall.mallbridge.model.MallInboundPointsResult; +import com.budwk.app.zhgh.pointsmall.mallbridge.model.MallInboundResult; +import com.budwk.app.zhgh.pointsmall.mallbridge.model.MallInboundTokenResult; +import com.budwk.app.zhgh.pointsmall.mallbridge.model.MallOutboundResult; + +public interface PointsMallBridgeService { + MallInboundTokenResult getToken(MallTokenDTO dto); + + MallInboundTokenResult refreshToken(MallTokenRefreshDTO dto); + + MallInboundPointsResult queryPoints(MallPointQueryDTO dto); + + MallInboundResult receivePending(MallPendingOrderDTO dto); + + MallInboundResult confirmPurchase(MallPurchaseConfirmDTO dto); + + MallInboundResult purchaseResult(MallPurchaseResultDTO dto); + + MallInboundResult receiveEvent(MallOrderEventDTO dto); + + MallOutboundResult queryOrderInfo(MallOrderQueryDTO dto); +} diff --git a/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/service/impl/PointsMallBridgeServiceImpl.java b/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/service/impl/PointsMallBridgeServiceImpl.java new file mode 100644 index 00000000..68fac3fe --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/service/impl/PointsMallBridgeServiceImpl.java @@ -0,0 +1,358 @@ +package com.budwk.app.zhgh.pointsmall.mallbridge.service.impl; + +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.convert.Convert; +import cn.hutool.core.util.StrUtil; +import cn.hutool.crypto.SecureUtil; +import cn.hutool.json.JSONUtil; +import com.budwk.app.zhgh.pointsmall.mallbridge.dto.*; +import com.budwk.app.zhgh.pointsmall.mallbridge.model.MallInboundPointsResult; +import com.budwk.app.zhgh.pointsmall.mallbridge.model.MallInboundResult; +import com.budwk.app.zhgh.pointsmall.mallbridge.model.MallInboundTokenResult; +import com.budwk.app.zhgh.pointsmall.mallbridge.model.MallOutboundResult; +import com.budwk.app.zhgh.pointsmall.mallbridge.models.PointsMallSupplierTokenStore; +import com.budwk.app.zhgh.pointsmall.mallbridge.service.PointsMallBridgeService; +import com.budwk.app.zhgh.pointsmall.order.models.PointsMallOrderMain; +import com.budwk.app.zhgh.pointsmall.order.models.PointsMallOrderSub; +import com.budwk.app.zhgh.pointsmall.order.models.PointsMallOrderSubProduct; +import com.budwk.app.zhgh.pointsmall.points.service.PointsMallUserPointsService; +import com.budwk.app.zhgh.pointsmall.supplier.models.PointsMallSupplier; +import org.nutz.dao.Cnd; +import org.nutz.dao.Dao; +import org.nutz.dao.Sqls; +import org.nutz.dao.entity.Record; +import org.nutz.dao.sql.Sql; +import org.nutz.ioc.loader.annotation.Inject; +import org.nutz.ioc.loader.annotation.IocBean; +import org.nutz.trans.Atom; +import org.nutz.trans.Trans; + +import java.math.BigDecimal; +import java.util.*; +import java.util.stream.Collectors; + +@IocBean(args = {"refer:dao"}) +public class PointsMallBridgeServiceImpl implements PointsMallBridgeService { + private static final long ACCESS_EXPIRE_SECONDS = 3600; + private static final long REFRESH_EXPIRE_SECONDS = 86400L * 7; + + private final Dao dao; + + @Inject + private PointsMallUserPointsService pointsMallUserPointsService; + + public PointsMallBridgeServiceImpl(Dao dao) { + this.dao = dao; + } + + @Override + public MallInboundTokenResult getToken(MallTokenDTO dto) { + PointsMallSupplier supplier = checkedSupplier(dto.getSupplierId(), dto.getClientId(), dto.getClientSecret(), dto.getTimestamp()); + invalidateOldToken(supplier.getSupplierId(), supplier.getClientId()); + return createToken(supplier); + } + + @Override + public MallInboundTokenResult refreshToken(MallTokenRefreshDTO dto) { + PointsMallSupplier supplier = checkedSupplier(dto.getSupplierId(), dto.getClientId(), dto.getClientSecret(), dto.getTimestamp()); + PointsMallSupplierTokenStore store = dao.fetch(PointsMallSupplierTokenStore.class, Cnd.where("supplierId", "=", supplier.getSupplierId()) + .and("refreshToken", "=", dto.getRefreshToken()).and("isValid", "=", true)); + if (store == null || store.getRefreshExpireTime() == null || new Date().after(store.getRefreshExpireTime())) { + throw new IllegalArgumentException("刷新令牌无效或已过期"); + } + invalidateOldToken(supplier.getSupplierId(), supplier.getClientId()); + return createToken(supplier); + } + + @Override + public MallInboundPointsResult queryPoints(MallPointQueryDTO dto) { + validateToken(dto.getSupplierId(), dto.getToken()); + return MallInboundPointsResult.success(pointsMallUserPointsService.availablePoints(dto.getUserId())); + } + + @Override + public MallInboundResult receivePending(MallPendingOrderDTO dto) { + validateToken(dto.getSupplierId(), dto.getToken()); + if (dto.getOrderInfo() == null || StrUtil.isBlank(dto.getOrderInfo().getOrderId())) { + return MallInboundResult.fail(400, "订单信息不能为空"); + } + if (dao.count(PointsMallOrderMain.class, Cnd.where("orderId", "=", dto.getOrderInfo().getOrderId()).and("supplierId", "=", dto.getSupplierId()).and("delFlag", "=", false)) > 0) { + return MallInboundResult.fail(-1, "订单已存在"); + } + Trans.exec((Atom) () -> dao.insert(toMain(dto.getSupplierId(), dto.getUserId(), dto.getOrderInfo(), 0))); + return MallInboundResult.success(); + } + + @Override + public MallInboundResult confirmPurchase(MallPurchaseConfirmDTO dto) { + validateToken(dto.getSupplierId(), dto.getToken()); + return updateMainOrderPay(dto.getSupplierId(), dto.getOrderId(), 1, dto.getTotalPrice(), dto.getWPayOrAPay(), dto.getPointsPrice()); + } + + @Override + public MallInboundResult purchaseResult(MallPurchaseResultDTO dto) { + validateToken(dto.getSupplierId(), dto.getToken()); + int state = Boolean.TRUE.equals(dto.getPurchaseResult()) ? 1 : 0; + return updateMainOrderPay(dto.getSupplierId(), dto.getOrderId(), state, dto.getTotalPrice(), dto.getWPayOrAPay(), dto.getPointsPrice()); + } + + @Override + public MallInboundResult receiveEvent(MallOrderEventDTO dto) { + validateToken(dto.getSupplierId(), dto.getToken()); + Integer type = dto.getOrderType(); + if (type == null) { + return MallInboundResult.fail(400, "订单事件类型不能为空"); + } + if (type == 2) { + return splitSubOrder(dto); + } + if (type == 3) { + return updateSubState(dto, 3); + } + if (type == 4) { + return updateSubState(dto, 4); + } + if (type == 5) { + return updateSubState(dto, 5); + } + if (type == 6) { + return updateSubState(dto, 6); + } + if (type == 7) { + return updateSubState(dto, 7); + } + return MallInboundResult.success(); + } + + @Override + public MallOutboundResult queryOrderInfo(MallOrderQueryDTO dto) { + validateToken(dto.getSupplierId(), dto.getToken()); + Sql sql = Sqls.create("select * from points_mall_order_main where supplierId=@supplierId and orderId=@orderId and delFlag=0"); + sql.params().set("supplierId", dto.getSupplierId()); + sql.params().set("orderId", dto.getOrderId()); + sql.setCallback(Sqls.callback.records()); + dao.execute(sql); + List list = sql.getList(Record.class).stream().map(this::toOrderInfo).collect(Collectors.toList()); + return MallOutboundResult.success(list); + } + + private PointsMallSupplier checkedSupplier(String supplierId, String clientId, String clientSecret, String timestamp) { + if (StrUtil.hasBlank(supplierId, clientId, clientSecret, timestamp)) { + throw new IllegalArgumentException("供应商认证参数不能为空"); + } + PointsMallSupplier supplier = dao.fetch(PointsMallSupplier.class, Cnd.where("supplierId", "=", supplierId) + .and("clientId", "=", clientId).and("delFlag", "=", false)); + if (supplier == null) { + throw new IllegalArgumentException("供应商和客户端信息不匹配"); + } + String serverSha256 = SecureUtil.sha256(supplier.getClientId() + supplier.getClientSecret() + timestamp + clientSecret); + if (!Objects.equals(clientSecret, serverSha256)) { + throw new IllegalArgumentException("签名验证信息错误"); + } + return supplier; + } + + private void validateToken(String supplierId, String token) { + if (StrUtil.hasBlank(supplierId, token)) { + throw new IllegalArgumentException("供应商ID和token不能为空"); + } + PointsMallSupplierTokenStore store = dao.fetch(PointsMallSupplierTokenStore.class, Cnd.where("supplierId", "=", supplierId) + .and("accessToken", "=", token).and("isValid", "=", true)); + if (store == null || store.getAccessExpireTime() == null || new Date().after(store.getAccessExpireTime())) { + throw new IllegalArgumentException("token无效或已过期"); + } + } + + private MallInboundTokenResult createToken(PointsMallSupplier supplier) { + String accessToken = UUID.randomUUID().toString().replace("-", ""); + String refreshToken = UUID.randomUUID().toString().replace("-", ""); + Date now = new Date(); + PointsMallSupplierTokenStore store = new PointsMallSupplierTokenStore(); + store.setSupplierId(supplier.getSupplierId()); + store.setClientId(supplier.getClientId()); + store.setAccessToken(accessToken); + store.setRefreshToken(refreshToken); + store.setAccessExpireTime(DateUtil.offsetSecond(now, (int) ACCESS_EXPIRE_SECONDS)); + store.setRefreshExpireTime(DateUtil.offsetSecond(now, (int) REFRESH_EXPIRE_SECONDS)); + store.setIsValid(true); + dao.insert(store); + return MallInboundTokenResult.success(DateUtil.format(now, "yyyyMMddHHmmss"), accessToken, refreshToken, ACCESS_EXPIRE_SECONDS, REFRESH_EXPIRE_SECONDS); + } + + private void invalidateOldToken(String supplierId, String clientId) { + dao.clear(PointsMallSupplierTokenStore.class, Cnd.where("supplierId", "=", supplierId).and("clientId", "=", clientId)); + } + + private MallInboundResult updateMainOrderPay(String supplierId, String orderId, Integer cashPaid, BigDecimal totalPrice, BigDecimal cash, BigDecimal points) { + PointsMallOrderMain main = dao.fetch(PointsMallOrderMain.class, Cnd.where("supplierId", "=", supplierId).and("orderId", "=", orderId).and("delFlag", "=", false)); + if (main == null) { + return MallInboundResult.fail(404, "订单不存在"); + } + main.setCashPaid(cashPaid); + main.setTotalPrice(nvl(totalPrice, main.getTotalPrice())); + main.setWPayOrAPay(nvl(cash, main.getWPayOrAPay())); + main.setPointsPrice(nvl(points, main.getPointsPrice())); + main.setOrderState(cashPaid == 1 ? 1 : main.getOrderState()); + main.setOrderUpdateTime(new Date()); + dao.updateIgnoreNull(main); + return MallInboundResult.success(); + } + + private MallInboundResult splitSubOrder(MallOrderEventDTO dto) { + PointsMallOrderMain main = dao.fetch(PointsMallOrderMain.class, Cnd.where("supplierId", "=", dto.getSupplierId()) + .and("orderId", "=", dto.getMainOrderId()).and("delFlag", "=", false)); + if (main == null) { + return MallInboundResult.fail(404, "主订单不存在"); + } + if (dao.count(PointsMallOrderSub.class, Cnd.where("orderId", "=", dto.getOrderId()).and("supplierId", "=", dto.getSupplierId()).and("delFlag", "=", false)) > 0) { + return MallInboundResult.fail(-1, "子订单已存在"); + } + Trans.exec((Atom) () -> { + PointsMallOrderSub sub = toSub(main, dto.getOrderId()); + dao.insert(sub); + List products = StrUtil.isBlank(main.getExtJson()) || "null".equalsIgnoreCase(main.getExtJson()) ? Collections.emptyList() : JSONUtil.toList(main.getExtJson(), OrderProInfoDTO.class); + insertProducts(dto.getOrderId(), products); + }); + return MallInboundResult.success(); + } + + private MallInboundResult updateSubState(MallOrderEventDTO dto, int state) { + PointsMallOrderSub sub = dao.fetch(PointsMallOrderSub.class, Cnd.where("supplierId", "=", dto.getSupplierId()) + .and("orderId", "=", dto.getOrderId()).and("delFlag", "=", false)); + if (sub == null) { + return MallInboundResult.fail(404, "订单不存在"); + } + sub.setOrderState(state); + sub.setOrderUpdateTime(new Date()); + if (state == 4) { + sub.setOrderFinishTime(new Date()); + } + if (state == 5) { + sub.setOrderCompleteTime(new Date()); + } + dao.updateIgnoreNull(sub); + return MallInboundResult.success(); + } + + private PointsMallOrderMain toMain(String supplierId, String userId, OrderInfoDTO orderInfo, Integer state) { + PointsMallOrderMain main = new PointsMallOrderMain(); + main.setOrderId(orderInfo.getOrderId()); + main.setSupplierId(supplierId); + main.setOrderNumberId(orderInfo.getOrderNumberId()); + main.setUserId(userId); + main.setAplName(orderInfo.getAplName()); + main.setOrderCreateTime(parseDate(orderInfo.getCreateTime())); + main.setOrderUpdateTime(parseDate(orderInfo.getUpdateTime())); + main.setDeliveryTime(parseDate(orderInfo.getDeliveryTime())); + main.setOrderFinishTime(parseDate(orderInfo.getOrderFinishTime())); + main.setOrderCompleteTime(parseDate(orderInfo.getCompleteTime())); + main.setDeliveryStatus(orderInfo.getDeliveryStatus()); + main.setFreightCost(nvl(orderInfo.getFreightCost())); + main.setRefund(nvl(orderInfo.getRefund())); + main.setLogisticsOrderId(orderInfo.getLogisticsOrderId()); + main.setCrrgBsnNm(orderInfo.getCrrgBsnNm()); + main.setOrderState(state); + main.setTotalPrice(nvl(orderInfo.getTotalPrice())); + main.setWPayOrAPay(nvl(orderInfo.getWPayOrAPay())); + main.setPointsPrice(nvl(orderInfo.getPointsPrice())); + main.setInvoiceCode(orderInfo.getInvoiceCode()); + main.setExtJson(JSONUtil.toJsonStr(orderInfo.getOrderProInfos() == null ? Collections.emptyList() : orderInfo.getOrderProInfos())); + main.setCashPaid(0); + return main; + } + + private PointsMallOrderSub toSub(PointsMallOrderMain main, String subOrderId) { + PointsMallOrderSub sub = new PointsMallOrderSub(); + sub.setOrderId(StrUtil.blankToDefault(subOrderId, main.getOrderId())); + sub.setOrderNumberId(main.getOrderNumberId()); + sub.setMainOrderId(main.getOrderId()); + sub.setSupplierId(main.getSupplierId()); + sub.setUserId(main.getUserId()); + sub.setAplName(main.getAplName()); + sub.setOrderCreateTime(main.getOrderCreateTime()); + sub.setOrderUpdateTime(new Date()); + sub.setDeliveryTime(main.getDeliveryTime()); + sub.setOrderFinishTime(main.getOrderFinishTime()); + sub.setOrderCompleteTime(main.getOrderCompleteTime()); + sub.setDeliveryStatus(parseInteger(main.getDeliveryStatus())); + sub.setFreightCost(main.getFreightCost()); + sub.setRefund(main.getRefund()); + sub.setLogisticsOrderId(main.getLogisticsOrderId()); + sub.setCrrgBsnNm(main.getCrrgBsnNm()); + sub.setOrderState(main.getOrderState()); + sub.setTotalPrice(main.getTotalPrice()); + sub.setWPayOrAPay(main.getWPayOrAPay()); + sub.setPointsPrice(main.getPointsPrice()); + sub.setInvoiceCode(main.getInvoiceCode()); + sub.setExtJson(main.getExtJson()); + sub.setReconciliationStatus(0); + sub.setInvoiceStatus(0); + return sub; + } + + private void insertProducts(String orderSubId, List products) { + if (products == null) { + return; + } + for (OrderProInfoDTO item : products) { + PointsMallOrderSubProduct product = new PointsMallOrderSubProduct(); + product.setOrderSubId(orderSubId); + product.setSku(item.getSku()); + product.setNumber(item.getNumber()); + product.setPrice(item.getPrice()); + product.setName(item.getName()); + product.setTaxRate(item.getTaxRate()); + product.setPicInfo(item.getPicInfo() == null || item.getPicInfo().isEmpty() ? null : item.getPicInfo().get(0)); + dao.insert(product); + } + } + + private OrderInfoDTO toOrderInfo(Record record) { + OrderInfoDTO dto = new OrderInfoDTO(); + dto.setOrderId(record.getString("orderId")); + dto.setOrderNumberId(record.getString("orderNumberId")); + dto.setSupplierId(record.getString("supplierId")); + dto.setAplName(record.getString("aplName")); + dto.setDeliveryStatus(record.getString("deliveryStatus")); + dto.setFreightCost(decimal(record.get("freightCost"))); + dto.setRefund(decimal(record.get("refund"))); + dto.setLogisticsOrderId(record.getString("logisticsOrderId")); + dto.setCrrgBsnNm(record.getString("crrgBsnNm")); + dto.setOrderState(record.getInt("orderState")); + dto.setTotalPrice(decimal(record.get("totalPrice"))); + dto.setWPayOrAPay(decimal(record.get("wPayOrAPay"))); + dto.setPointsPrice(decimal(record.get("pointsPrice"))); + dto.setInvoiceCode(record.getString("invoiceCode")); + return dto; + } + + private Date parseDate(String value) { + if (StrUtil.isBlank(value)) { + return null; + } + return DateUtil.parse(value.replace("T", " ")); + } + + private BigDecimal nvl(BigDecimal value) { + return value == null ? BigDecimal.ZERO : value; + } + + private BigDecimal nvl(BigDecimal value, BigDecimal defaultValue) { + return value == null ? defaultValue : value; + } + + private BigDecimal decimal(Object value) { + return Convert.toBigDecimal(value, BigDecimal.ZERO); + } + + private Integer parseInteger(String value) { + if (StrUtil.isBlank(value)) { + return null; + } + try { + return Integer.valueOf(value); + } catch (NumberFormatException e) { + return null; + } + } +}