feat: 积分商城-补充

This commit is contained in:
2026-07-29 10:11:25 +08:00
parent 0eefc705a1
commit 51a951d863
22 changed files with 923 additions and 93 deletions
@@ -1,7 +1,9 @@
package com.budwk.app.zhgh.pointsmall.h5.index;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.stp.StpUtil;
import com.budwk.app.base.result.Result;
import com.budwk.app.zhgh.pointsmall.points.service.PointsMallUserPointsService;
import com.budwk.app.zhgh.pointsmall.supplier.service.PointsMallSupplierService;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
@@ -13,10 +15,12 @@ import org.nutz.mvc.annotation.Param;
@Ok("json:full")
@At("/platform/h5/points-mall")
public class PointsMallH5IndexController {
@Inject
private PointsMallSupplierService pointsMallSupplierService;
@Inject
private PointsMallUserPointsService pointsMallUserPointsService;
@At("")
@Ok("beetl:/platform/zhghh5/points-mall/index.html")
@SaCheckPermission("h5.points.mall")
@@ -28,4 +32,18 @@ public class PointsMallH5IndexController {
public Result supplierList(@Param("mallType") Integer mallType) {
return Result.success(pointsMallSupplierService.listByMallType(mallType));
}
@At("/me/points")
@SaCheckPermission("h5.points.mall")
public Result points() {
return Result.success(pointsMallUserPointsService.availablePoints(currentUserId()));
}
private String currentUserId() {
try {
return StpUtil.getLoginIdAsString();
} catch (Exception e) {
return "";
}
}
}
@@ -0,0 +1,11 @@
package com.budwk.app.zhgh.pointsmall.mallbridge.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MallTokenRequired {
}
@@ -1,24 +1,29 @@
package com.budwk.app.zhgh.pointsmall.mallbridge.controller;
import com.budwk.app.base.result.Result;
import com.budwk.app.zhgh.pointsmall.mallbridge.annotation.MallTokenRequired;
import com.budwk.app.zhgh.pointsmall.mallbridge.dto.*;
import com.budwk.app.zhgh.pointsmall.mallbridge.interceptor.MallTokenInterceptor;
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.model.MallPictureOutboundResult;
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.adaptor.JsonAdaptor;
import org.nutz.mvc.annotation.AdaptBy;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.By;
import org.nutz.mvc.annotation.Filters;
import org.nutz.mvc.annotation.Ok;
import org.nutz.mvc.annotation.Param;
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")
@AdaptBy(type = JsonAdaptor.class)
public class PointsMallBridgeController {
@Inject
@@ -26,9 +31,9 @@ public class PointsMallBridgeController {
@POST
@At("/connect/token")
public MallInboundResult getToken(HttpServletRequest request) {
public MallInboundResult getToken(@Param("..") MallTokenDTO dto) {
try {
return pointsMallBridgeService.getToken(readBody(request, MallTokenDTO.class));
return pointsMallBridgeService.getToken(dto);
} catch (Exception e) {
return MallInboundResult.fail(401, e.getMessage());
}
@@ -36,9 +41,9 @@ public class PointsMallBridgeController {
@POST
@At("/connect/refreshToken")
public MallInboundResult refreshToken(HttpServletRequest request) {
public MallInboundResult refreshToken(@Param("..") MallTokenRefreshDTO dto) {
try {
return pointsMallBridgeService.refreshToken(readBody(request, MallTokenRefreshDTO.class));
return pointsMallBridgeService.refreshToken(dto);
} catch (Exception e) {
return MallInboundResult.fail(401, e.getMessage());
}
@@ -46,9 +51,11 @@ public class PointsMallBridgeController {
@POST
@At("/pointOrder/queryPoints")
public MallInboundPointsResult queryPoints(HttpServletRequest request) {
@MallTokenRequired
@Filters(@By(type = MallTokenInterceptor.class))
public MallInboundPointsResult queryPoints(@Param("..") MallPointQueryDTO dto) {
try {
return pointsMallBridgeService.queryPoints(readBody(request, MallPointQueryDTO.class));
return pointsMallBridgeService.queryPoints(dto);
} catch (Exception e) {
return MallInboundPointsResult.fail(401, e.getMessage());
}
@@ -56,38 +63,88 @@ public class PointsMallBridgeController {
@POST
@At("/pointOrder/pendingOrderInfo")
public MallInboundResult receivePending(HttpServletRequest request) {
return inbound(() -> pointsMallBridgeService.receivePending(readBody(request, MallPendingOrderDTO.class)));
@MallTokenRequired
@Filters(@By(type = MallTokenInterceptor.class))
public MallInboundResult receivePending(@Param("..") MallPendingOrderDTO dto) {
return inbound(() -> pointsMallBridgeService.receivePending(dto));
}
@POST
@At("/pointOrder/confirmPurchase")
public MallInboundResult confirmPurchase(HttpServletRequest request) {
return inbound(() -> pointsMallBridgeService.confirmPurchase(readBody(request, MallPurchaseConfirmDTO.class)));
@MallTokenRequired
@Filters(@By(type = MallTokenInterceptor.class))
public MallInboundResult confirmPurchase(@Param("..") MallPurchaseConfirmDTO dto) {
return inbound(() -> pointsMallBridgeService.confirmPurchase(dto));
}
@POST
@At("/pointOrder/purchaseResult")
public MallInboundResult purchaseResult(HttpServletRequest request) {
return inbound(() -> pointsMallBridgeService.purchaseResult(readBody(request, MallPurchaseResultDTO.class)));
@MallTokenRequired
@Filters(@By(type = MallTokenInterceptor.class))
public MallInboundResult purchaseResult(@Param("..") MallPurchaseResultDTO dto) {
return inbound(() -> pointsMallBridgeService.purchaseResult(dto));
}
@POST
@At("/pointOrder/pushOrderInfoMsg")
public MallInboundResult receiveEvent(HttpServletRequest request) {
return inbound(() -> pointsMallBridgeService.receiveEvent(readBody(request, MallOrderEventDTO.class)));
@MallTokenRequired
@Filters(@By(type = MallTokenInterceptor.class))
public MallInboundResult receiveEvent(@Param("..") MallOrderEventDTO dto) {
return inbound(() -> pointsMallBridgeService.receiveEvent(dto));
}
@POST
@At("/pointOrder/queryOrderInfo")
public MallOutboundResult queryOrderInfo(HttpServletRequest request) {
public MallOutboundResult queryOrderInfo(@Param("..") MallOrderQueryDTO dto) {
try {
return pointsMallBridgeService.queryOrderInfo(readBody(request, MallOrderQueryDTO.class));
return pointsMallBridgeService.queryOrderInfo(dto);
} catch (Exception e) {
return MallOutboundResult.fail(401, e.getMessage());
}
}
@POST
@At("/pointOrder/applyForInvoices")
public MallOutboundResult applyInvoice(@Param("..") MallInvoiceApplyDTO dto) {
try {
return pointsMallBridgeService.applyInvoice(dto);
} catch (Exception e) {
return MallOutboundResult.fail(401, e.getMessage());
}
}
@POST
@At("/pointOrder/queryInvoicesInfo")
public Result queryInvoicesInfo(@Param("..") QueryInvoiceInfoDTO dto) {
try {
return Result.success(pointsMallBridgeService.queryInvoicesInfo(dto));
} catch (Exception e) {
return Result.error(401, e.getMessage());
}
}
@POST
@At("/pointOrder/queryFileBase64Info")
public MallPictureOutboundResult queryFileBase64Info(@Param("..") PictureQueryDTO dto) {
try {
return pointsMallBridgeService.queryFileBase64Info(dto);
} catch (Exception e) {
return MallPictureOutboundResult.fail(401, e.getMessage());
}
}
@POST
@At("/pointOrder/unReconciledMsg")
public MallInboundResult unReconciledMsg(@Param("..") UnReconciledMsgNoticeDTO dto) {
return inbound(() -> pointsMallBridgeService.unReconciledMsg(dto));
}
@POST
@At("/pointOrder/payCompletion")
public MallInboundResult payCompletion(@Param("..") OrderPayFinishNoticeDTO dto) {
return inbound(() -> pointsMallBridgeService.payCompletion(dto));
}
private MallInboundResult inbound(InboundCall call) {
try {
return call.get();
@@ -96,17 +153,6 @@ public class PointsMallBridgeController {
}
}
private <T> T readBody(HttpServletRequest request, Class<T> 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;
}
@@ -0,0 +1,14 @@
package com.budwk.app.zhgh.pointsmall.mallbridge.dto;
import lombok.Data;
import java.math.BigDecimal;
@Data
public class FinalStatementDTO {
private String settlementId;
private String invoiceIds;
private String orderIds;
private String payDate;
private BigDecimal totalFee;
}
@@ -0,0 +1,15 @@
package com.budwk.app.zhgh.pointsmall.mallbridge.dto;
import lombok.Data;
import java.util.List;
@Data
public class GetInvoiceInfoDTO {
private Integer bSuccess;
private String settlementId;
private String sucOrderIds;
private String failOrderIds;
private String failMsg;
private List<InvoiceInfoDTO> invoiceInfos;
}
@@ -0,0 +1,23 @@
package com.budwk.app.zhgh.pointsmall.mallbridge.dto;
import lombok.Data;
import java.math.BigDecimal;
import java.time.LocalDate;
@Data
public class InvoiceInfoDTO {
private String invoiceId;
private String invoiceCode;
private LocalDate invoiceDate;
private BigDecimal invoiceNakeAmount;
private BigDecimal invoiceTaxRate;
private BigDecimal invoiceTaxAmount;
private BigDecimal invoiceAmount;
private Integer invoiceType;
private String url;
private String imageEncode;
private String fileType;
private String checkCode;
private String invoiceAddress;
}
@@ -0,0 +1,29 @@
package com.budwk.app.zhgh.pointsmall.mallbridge.dto;
import lombok.Data;
import java.math.BigDecimal;
@Data
public class MallInvoiceApplyDTO {
private String supplierId;
private String token;
private String settlementId;
private String orderIds;
private Integer orderNum;
private BigDecimal orderTotalPrice;
private String invoiceDate;
private String invoiceTitle;
private String invoiceCode;
private String invoiceAddress;
private String invoiceContact;
private BigDecimal invoiceNakedPrice;
private BigDecimal invoiceTaxPrice;
private String invoiceType;
private String invoiceContent;
private String remark;
private String bankAccount;
private String registeredAddress;
private String bankName;
private Long timestamp;
}
@@ -7,6 +7,7 @@ public class MallTokenDTO {
private String supplierId;
private String clientId;
private String clientSecret;
private String sendSha256;
private String code;
private String timestamp;
}
@@ -8,5 +8,6 @@ public class MallTokenRefreshDTO {
private String refreshToken;
private String clientId;
private String clientSecret;
private String sendSha256;
private String timestamp;
}
@@ -0,0 +1,14 @@
package com.budwk.app.zhgh.pointsmall.mallbridge.dto;
import lombok.Data;
import java.util.List;
@Data
public class OrderPayFinishNoticeDTO {
private String supplierId;
private String token;
private String expReportNumber;
private List<FinalStatementDTO> expFinalInfos;
private Long timestamp;
}
@@ -0,0 +1,15 @@
package com.budwk.app.zhgh.pointsmall.mallbridge.dto;
import lombok.Data;
import java.util.List;
@Data
public class PictureQueryDTO {
private String supplierId;
private String token;
private String queryType;
private String idNumber;
private List<String> fileIdList;
private Long timestamp;
}
@@ -0,0 +1,11 @@
package com.budwk.app.zhgh.pointsmall.mallbridge.dto;
import lombok.Data;
@Data
public class QueryInvoiceInfoDTO {
private String supplierId;
private String token;
private String settlementId;
private Long timestamp;
}
@@ -0,0 +1,15 @@
package com.budwk.app.zhgh.pointsmall.mallbridge.dto;
import lombok.Data;
@Data
public class UnReconciledMsgNoticeDTO {
private String uniqueSeqNo;
private String supplierId;
private String token;
private String orderIds;
private String unReconciledMsg;
private String unReconciledType;
private String startDate;
private String endDate;
}
@@ -0,0 +1,52 @@
package com.budwk.app.zhgh.pointsmall.mallbridge.interceptor;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.zhgh.pointsmall.mallbridge.annotation.MallTokenRequired;
import com.budwk.app.zhgh.pointsmall.mallbridge.model.MallInboundResult;
import com.budwk.app.zhgh.pointsmall.mallbridge.models.PointsMallSupplierTokenStore;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.json.JsonFormat;
import org.nutz.mvc.ActionContext;
import org.nutz.mvc.ActionFilter;
import org.nutz.mvc.Mvcs;
import org.nutz.mvc.View;
import org.nutz.mvc.view.UTF8JsonView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Date;
public class MallTokenInterceptor implements ActionFilter {
@Override
public View match(ActionContext actionContext) {
if (actionContext.getMethod() == null || !actionContext.getMethod().isAnnotationPresent(MallTokenRequired.class)) {
return null;
}
String accessToken = actionContext.getRequest().getHeader("token");
if (StrUtil.isBlank(accessToken)) {
return fail(401, "缺少accessToken参数");
}
Dao dao = Mvcs.getIoc().get(Dao.class);
PointsMallSupplierTokenStore tokenStore = dao.fetch(PointsMallSupplierTokenStore.class,
Cnd.where("accessToken", "=", accessToken).and("isValid", "=", true));
if (tokenStore == null || tokenStore.getAccessExpireTime() == null || tokenStore.getAccessExpireTime().before(new Date())) {
return fail(401, "无效的accessToken");
}
return null;
}
private View fail(int code, String message) {
return new View() {
@Override
public void render(HttpServletRequest req, HttpServletResponse resp, Object obj) throws Throwable {
resp.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
new UTF8JsonView(JsonFormat.compact()).render(req, resp, MallInboundResult.fail(code, message));
}
};
}
}
@@ -11,6 +11,10 @@ public class MallOutboundResult {
private String message;
private List<OrderInfoDTO> orderInfo;
public static MallOutboundResult success() {
return success(null);
}
public static MallOutboundResult success(List<OrderInfoDTO> orderInfo) {
MallOutboundResult result = new MallOutboundResult();
result.setResultCode(0);
@@ -0,0 +1,57 @@
package com.budwk.app.zhgh.pointsmall.mallbridge.model;
import java.util.Map;
public class MallPictureOutboundResult {
private int resultCode;
private String message;
private String fileType;
private Map<String, String> imageEncodeMap;
public static MallPictureOutboundResult success(Map<String, String> imageEncodeMap) {
MallPictureOutboundResult result = new MallPictureOutboundResult();
result.resultCode = 0;
result.message = "成功";
result.imageEncodeMap = imageEncodeMap;
return result;
}
public static MallPictureOutboundResult fail(int code, String message) {
MallPictureOutboundResult result = new MallPictureOutboundResult();
result.resultCode = code;
result.message = message;
return result;
}
public int getResultCode() {
return resultCode;
}
public void setResultCode(int resultCode) {
this.resultCode = resultCode;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public String getFileType() {
return fileType;
}
public void setFileType(String fileType) {
this.fileType = fileType;
}
public Map<String, String> getImageEncodeMap() {
return imageEncodeMap;
}
public void setImageEncodeMap(Map<String, String> imageEncodeMap) {
this.imageEncodeMap = imageEncodeMap;
}
}
@@ -5,6 +5,7 @@ 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.model.MallPictureOutboundResult;
public interface PointsMallBridgeService {
MallInboundTokenResult getToken(MallTokenDTO dto);
@@ -22,4 +23,14 @@ public interface PointsMallBridgeService {
MallInboundResult receiveEvent(MallOrderEventDTO dto);
MallOutboundResult queryOrderInfo(MallOrderQueryDTO dto);
MallOutboundResult applyInvoice(MallInvoiceApplyDTO dto);
GetInvoiceInfoDTO queryInvoicesInfo(QueryInvoiceInfoDTO dto);
MallPictureOutboundResult queryFileBase64Info(PictureQueryDTO dto);
MallInboundResult unReconciledMsg(UnReconciledMsgNoticeDTO dto);
MallInboundResult payCompletion(OrderPayFinishNoticeDTO dto);
}
@@ -1,22 +1,44 @@
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.date.DateUtil;
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.invoice.models.PointsMallInvoiceInfo;
import com.budwk.app.zhgh.pointsmall.invoice.models.PointsMallInvoiceMain;
import com.budwk.app.zhgh.pointsmall.mallbridge.dto.FinalStatementDTO;
import com.budwk.app.zhgh.pointsmall.mallbridge.dto.GetInvoiceInfoDTO;
import com.budwk.app.zhgh.pointsmall.mallbridge.dto.InvoiceInfoDTO;
import com.budwk.app.zhgh.pointsmall.mallbridge.dto.MallInvoiceApplyDTO;
import com.budwk.app.zhgh.pointsmall.mallbridge.dto.MallOrderEventDTO;
import com.budwk.app.zhgh.pointsmall.mallbridge.dto.MallOrderQueryDTO;
import com.budwk.app.zhgh.pointsmall.mallbridge.dto.MallPendingOrderDTO;
import com.budwk.app.zhgh.pointsmall.mallbridge.dto.MallPointQueryDTO;
import com.budwk.app.zhgh.pointsmall.mallbridge.dto.MallPurchaseConfirmDTO;
import com.budwk.app.zhgh.pointsmall.mallbridge.dto.MallPurchaseResultDTO;
import com.budwk.app.zhgh.pointsmall.mallbridge.dto.MallTokenDTO;
import com.budwk.app.zhgh.pointsmall.mallbridge.dto.MallTokenRefreshDTO;
import com.budwk.app.zhgh.pointsmall.mallbridge.dto.OrderInfoDTO;
import com.budwk.app.zhgh.pointsmall.mallbridge.dto.OrderPayFinishNoticeDTO;
import com.budwk.app.zhgh.pointsmall.mallbridge.dto.OrderProInfoDTO;
import com.budwk.app.zhgh.pointsmall.mallbridge.dto.PictureQueryDTO;
import com.budwk.app.zhgh.pointsmall.mallbridge.dto.QueryInvoiceInfoDTO;
import com.budwk.app.zhgh.pointsmall.mallbridge.dto.UnReconciledMsgNoticeDTO;
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.model.MallPictureOutboundResult;
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.reconciliation.models.PointsMallReconciliationRecord;
import com.budwk.app.zhgh.pointsmall.supplier.models.PointsMallSupplier;
import org.nutz.dao.Chain;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.dao.Sqls;
@@ -28,7 +50,16 @@ import org.nutz.trans.Atom;
import org.nutz.trans.Trans;
import java.math.BigDecimal;
import java.util.*;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.UUID;
import java.util.stream.Collectors;
@IocBean(args = {"refer:dao"})
@@ -36,6 +67,16 @@ public class PointsMallBridgeServiceImpl implements PointsMallBridgeService {
private static final long ACCESS_EXPIRE_SECONDS = 3600;
private static final long REFRESH_EXPIRE_SECONDS = 86400L * 7;
private static final int ORDER_PENDING_PAY = 0;
private static final int ORDER_FINISH_PAY = 1;
private static final int ORDER_IN_PROGRESS = 2;
private static final int ORDER_CANCELLED = 3;
private static final int ORDER_RECEIVED = 4;
private static final int ORDER_COMPLETED = 5;
private static final int ORDER_EXCHANGE = 6;
private static final int ORDER_REFUNDED = 7;
private static final int ORDER_ABOLISH = 8;
private final Dao dao;
@Inject
@@ -47,18 +88,18 @@ public class PointsMallBridgeServiceImpl implements PointsMallBridgeService {
@Override
public MallInboundTokenResult getToken(MallTokenDTO dto) {
PointsMallSupplier supplier = checkedSupplier(dto.getSupplierId(), dto.getClientId(), dto.getClientSecret(), dto.getTimestamp());
PointsMallSupplier supplier = checkedSupplier(dto.getSupplierId(), dto.getClientId(), dto.getClientSecret(), dto.getSendSha256(), 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());
PointsMallSupplier supplier = checkedSupplier(dto.getSupplierId(), dto.getClientId(), dto.getClientSecret(), dto.getSendSha256(), 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("刷新令牌无效或已过期");
throw new IllegalArgumentException("刷新令牌已失效,请重新获取授权");
}
invalidateOldToken(supplier.getSupplierId(), supplier.getClientId());
return createToken(supplier);
@@ -66,68 +107,73 @@ public class PointsMallBridgeServiceImpl implements PointsMallBridgeService {
@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) {
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)));
Trans.exec((Atom) () -> dao.insert(toMain(dto.getSupplierId(), dto.getUserId(), dto.getOrderInfo(), ORDER_PENDING_PAY)));
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());
int cashPaid = Boolean.TRUE.equals(dto.getPurchaseResult()) ? 1 : 0;
return updateMainOrderPay(dto.getSupplierId(), dto.getOrderId(), cashPaid, 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 == 1) {
return cancelMainOrder(dto, false);
}
if (type == 2) {
return splitSubOrder(dto);
}
if (type == 3) {
return updateSubState(dto, 3);
return updateSubState(dto, ORDER_CANCELLED);
}
if (type == 4) {
return updateSubState(dto, 4);
return updateSubState(dto, ORDER_REFUNDED);
}
if (type == 5) {
return updateSubState(dto, 5);
return updateSubState(dto, ORDER_EXCHANGE);
}
if (type == 6) {
return updateSubState(dto, 6);
return updateSubState(dto, ORDER_COMPLETED);
}
if (type == 7) {
return updateSubState(dto, 7);
return cancelMainOrder(dto, true);
}
if (type == 8) {
return updateSubState(dto, ORDER_ABOLISH);
}
if (type == 11) {
return markInvoiceNotice(dto);
}
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");
String table = Integer.valueOf(2).equals(dto.getOrderType()) ? "points_mall_order_sub" : "points_mall_order_main";
Sql sql = Sqls.create("select * from " + table + " 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());
@@ -136,33 +182,126 @@ public class PointsMallBridgeServiceImpl implements PointsMallBridgeService {
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("供应商认证参数不能为空");
@Override
public MallOutboundResult applyInvoice(MallInvoiceApplyDTO dto) {
if (dto == null || StrUtil.hasBlank(dto.getSupplierId(), dto.getSettlementId(), dto.getOrderIds())) {
return MallOutboundResult.fail(400, "开票申请参数不能为空");
}
List<String> orderIds = splitIds(dto.getOrderIds());
List<PointsMallOrderSub> orders = dao.query(PointsMallOrderSub.class, Cnd.where("supplierId", "=", dto.getSupplierId())
.and("orderId", "in", orderIds).and("delFlag", "=", false));
if (orders.isEmpty()) {
return MallOutboundResult.fail(404, "未找到可开票订单");
}
if (dto.getOrderNum() != null && dto.getOrderNum() != orders.size()) {
return MallOutboundResult.fail(400, "订单数量与开票申请不一致");
}
BigDecimal total = orders.stream().map(PointsMallOrderSub::getTotalPrice).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add);
if (dto.getOrderTotalPrice() != null && total.compareTo(dto.getOrderTotalPrice()) != 0) {
return MallOutboundResult.fail(400, "订单金额与开票申请不一致");
}
Trans.exec((Atom) () -> saveInvoiceApply(dto, orderIds, total));
return MallOutboundResult.success();
}
@Override
public GetInvoiceInfoDTO queryInvoicesInfo(QueryInvoiceInfoDTO dto) {
if (dto == null || StrUtil.hasBlank(dto.getSupplierId(), dto.getSettlementId())) {
throw new IllegalArgumentException("发票查询参数不能为空");
}
PointsMallInvoiceMain main = dao.fetch(PointsMallInvoiceMain.class, Cnd.where("settlementId", "=", dto.getSettlementId())
.and("delFlag", "=", false));
if (main == null) {
throw new IllegalArgumentException("发票信息不存在");
}
List<InvoiceInfoDTO> invoiceInfos = dao.query(PointsMallInvoiceInfo.class, Cnd.where("mainId", "=", main.getId()).and("delFlag", "=", false))
.stream().map(this::toInvoiceInfoDTO).collect(Collectors.toList());
GetInvoiceInfoDTO result = new GetInvoiceInfoDTO();
result.setBSuccess(main.getBSuccess());
result.setSettlementId(main.getSettlementId());
result.setSucOrderIds(main.getSucOrderIds());
result.setFailOrderIds(main.getFailOrderIds());
result.setFailMsg(main.getFailMsg());
result.setInvoiceInfos(invoiceInfos);
return result;
}
@Override
public MallPictureOutboundResult queryFileBase64Info(PictureQueryDTO dto) {
if (dto == null || StrUtil.hasBlank(dto.getSupplierId(), dto.getQueryType(), dto.getIdNumber())) {
return MallPictureOutboundResult.fail(400, "图片查询参数不能为空");
}
Map<String, String> map = "2".equals(dto.getQueryType()) ? queryInvoiceFiles(dto) : queryProductPictures(dto);
MallPictureOutboundResult result = MallPictureOutboundResult.success(map);
if ("2".equals(dto.getQueryType())) {
result.setFileType(firstInvoiceFileType(dto));
}
return result;
}
@Override
public MallInboundResult unReconciledMsg(UnReconciledMsgNoticeDTO dto) {
if (dto == null || StrUtil.hasBlank(dto.getSupplierId(), dto.getOrderIds())) {
return MallInboundResult.fail(400, "对账异常通知参数不能为空");
}
List<String> orderIds = splitIds(dto.getOrderIds());
Trans.exec((Atom) () -> {
for (String orderId : orderIds) {
PointsMallReconciliationRecord record = new PointsMallReconciliationRecord();
record.setSupplierId(dto.getSupplierId());
record.setOrderId(orderId);
record.setDiffReason(dto.getUnReconciledMsg());
record.setDiffType(Convert.toInt(dto.getUnReconciledType(), null));
record.setBatchNo(StrUtil.blankToDefault(dto.getUniqueSeqNo(), dto.getStartDate() + "_" + dto.getEndDate()));
record.setNoticeStatus(1);
record.setPushTime(1);
dao.insert(record);
}
});
return MallInboundResult.success();
}
@Override
public MallInboundResult payCompletion(OrderPayFinishNoticeDTO dto) {
if (dto == null || StrUtil.isBlank(dto.getSupplierId()) || dto.getExpFinalInfos() == null) {
return MallInboundResult.fail(400, "支付完成通知参数不能为空");
}
Trans.exec((Atom) () -> {
for (FinalStatementDTO item : dto.getExpFinalInfos()) {
if (item == null || StrUtil.isBlank(item.getSettlementId())) {
continue;
}
PointsMallInvoiceMain main = dao.fetch(PointsMallInvoiceMain.class, Cnd.where("settlementId", "=", item.getSettlementId())
.and("delFlag", "=", false));
if (main != null) {
main.setBSuccess(1);
dao.updateIgnoreNull(main);
}
List<String> orderIds = splitIds(item.getOrderIds());
if (!orderIds.isEmpty()) {
dao.update(PointsMallOrderSub.class, Chain.make("invoiceStatus", 1), Cnd.where("supplierId", "=", dto.getSupplierId()).and("orderId", "in", orderIds));
}
}
});
return MallInboundResult.success();
}
private PointsMallSupplier checkedSupplier(String supplierId, String clientId, String clientSecret, String sendSha256, String timestamp) {
if (StrUtil.hasBlank(supplierId, clientId, clientSecret, sendSha256, 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("供应商和客户端信息不匹配");
throw new IllegalArgumentException("供应商不存在或已停用");
}
String serverSha256 = SecureUtil.sha256(supplier.getClientId() + supplier.getClientSecret() + timestamp + clientSecret);
if (!Objects.equals(clientSecret, serverSha256)) {
String serverSha256 = SecureUtil.sha256(supplier.getClientId() + supplier.getClientSecret() + timestamp);
if (!Objects.equals(sendSha256, 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("-", "");
@@ -184,7 +323,8 @@ public class PointsMallBridgeServiceImpl implements PointsMallBridgeService {
}
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));
PointsMallOrderMain main = dao.fetch(PointsMallOrderMain.class, Cnd.where("supplierId", "=", supplierId)
.and("orderId", "=", orderId).and("delFlag", "=", false));
if (main == null) {
return MallInboundResult.fail(404, "订单不存在");
}
@@ -192,26 +332,61 @@ public class PointsMallBridgeServiceImpl implements PointsMallBridgeService {
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.setOrderState(cashPaid == 1 ? ORDER_FINISH_PAY : main.getOrderState());
main.setOrderUpdateTime(new Date());
dao.updateIgnoreNull(main);
return MallInboundResult.success();
}
private MallInboundResult cancelMainOrder(MallOrderEventDTO dto, boolean paidNotSplit) {
String mainOrderId = StrUtil.blankToDefault(dto.getMainOrderId(), dto.getOrderId());
if (StrUtil.isBlank(mainOrderId)) {
return MallInboundResult.fail(400, "主订单信息不能为空");
}
PointsMallOrderMain main = dao.fetch(PointsMallOrderMain.class, Cnd.where("supplierId", "=", dto.getSupplierId())
.and("orderId", "=", mainOrderId).and("delFlag", "=", false));
if (main == null) {
return MallInboundResult.fail(404, "主订单不存在");
}
if (!paidNotSplit && !Integer.valueOf(ORDER_PENDING_PAY).equals(main.getOrderState())) {
return MallInboundResult.fail(400, "只能取消未支付主单");
}
main.setOrderState(ORDER_CANCELLED);
main.setOrderUpdateTime(new Date());
dao.updateIgnoreNull(main);
dao.update(PointsMallOrderSub.class, Chain.make("orderState", ORDER_CANCELLED).add("orderUpdateTime", new Date()),
Cnd.where("supplierId", "=", dto.getSupplierId()).and("mainOrderId", "=", mainOrderId).and("delFlag", "=", false));
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, "子订单已存在");
List<String> subOrderIds = splitIds(dto.getOrderId());
if (subOrderIds.isEmpty()) {
return MallInboundResult.fail(400, "子订单信息不能为空");
}
List<OrderProInfoDTO> products = StrUtil.isBlank(main.getExtJson()) || "null".equalsIgnoreCase(main.getExtJson())
? Collections.emptyList()
: JSONUtil.toList(main.getExtJson(), OrderProInfoDTO.class);
Trans.exec((Atom) () -> {
PointsMallOrderSub sub = toSub(main, dto.getOrderId());
dao.insert(sub);
List<OrderProInfoDTO> products = StrUtil.isBlank(main.getExtJson()) || "null".equalsIgnoreCase(main.getExtJson()) ? Collections.emptyList() : JSONUtil.toList(main.getExtJson(), OrderProInfoDTO.class);
insertProducts(dto.getOrderId(), products);
for (String subOrderId : subOrderIds) {
PointsMallOrderSub sub = dao.fetch(PointsMallOrderSub.class, Cnd.where("orderId", "=", subOrderId)
.and("supplierId", "=", dto.getSupplierId()).and("delFlag", "=", false));
if (sub == null) {
sub = toSub(main, subOrderId);
sub.setOrderState(ORDER_IN_PROGRESS);
dao.insert(sub);
insertProducts(subOrderId, products);
} else {
sub.setOrderState(ORDER_IN_PROGRESS);
sub.setOrderUpdateTime(new Date());
dao.updateIgnoreNull(sub);
}
}
});
return MallInboundResult.success();
}
@@ -224,16 +399,105 @@ public class PointsMallBridgeServiceImpl implements PointsMallBridgeService {
}
sub.setOrderState(state);
sub.setOrderUpdateTime(new Date());
if (state == 4) {
if (state == ORDER_RECEIVED) {
sub.setOrderFinishTime(new Date());
}
if (state == 5) {
if (state == ORDER_COMPLETED) {
sub.setOrderCompleteTime(new Date());
}
dao.updateIgnoreNull(sub);
return MallInboundResult.success();
}
private MallInboundResult markInvoiceNotice(MallOrderEventDTO dto) {
String mainOrderId = StrUtil.blankToDefault(dto.getMainOrderId(), dto.getOrderId());
if (StrUtil.isBlank(mainOrderId)) {
return MallInboundResult.fail(400, "主订单信息不能为空");
}
dao.update(PointsMallOrderSub.class, Chain.make("invoiceStatus", 1), Cnd.where("supplierId", "=", dto.getSupplierId())
.and("mainOrderId", "=", mainOrderId).and("delFlag", "=", false));
return MallInboundResult.success();
}
private void saveInvoiceApply(MallInvoiceApplyDTO dto, List<String> orderIds, BigDecimal total) {
PointsMallInvoiceMain main = dao.fetch(PointsMallInvoiceMain.class, Cnd.where("settlementId", "=", dto.getSettlementId()).and("delFlag", "=", false));
if (main == null) {
main = new PointsMallInvoiceMain();
main.setSettlementId(dto.getSettlementId());
main.setBSuccess(0);
main.setSucOrderIds(String.join(",", orderIds));
main.setFailOrderIds("");
main.setFailMsg("");
dao.insert(main);
} else {
main.setBSuccess(0);
main.setSucOrderIds(String.join(",", orderIds));
main.setFailOrderIds("");
main.setFailMsg("");
dao.updateIgnoreNull(main);
}
PointsMallInvoiceInfo info = new PointsMallInvoiceInfo();
info.setMainId(main.getId());
info.setInvoiceId(dto.getSettlementId());
info.setInvoiceCode(dto.getInvoiceCode());
info.setInvoiceDate(parseDate(dto.getInvoiceDate()));
info.setInvoiceNakeAmount(nvl(dto.getInvoiceNakedPrice(), total));
info.setInvoiceTaxAmount(nvl(dto.getInvoiceTaxPrice(), BigDecimal.ZERO));
info.setInvoiceAmount(total);
info.setInvoiceType(Convert.toInt(dto.getInvoiceType(), null));
info.setInvoiceAddress(dto.getInvoiceAddress());
info.setInvoiceContact(dto.getInvoiceContact());
info.setInvoiceContent(dto.getInvoiceContent());
info.setInvoiceBank(dto.getBankName());
info.setInvoiceAccount(dto.getBankAccount());
info.setTaxIdNumber(dto.getInvoiceCode());
info.setRemark(dto.getRemark());
dao.insert(info);
dao.update(PointsMallOrderSub.class, Chain.make("invoiceStatus", 2).add("invoiceCode", dto.getSettlementId()),
Cnd.where("supplierId", "=", dto.getSupplierId()).and("orderId", "in", orderIds));
}
private Map<String, String> queryProductPictures(PictureQueryDTO dto) {
Cnd cnd = Cnd.where("orderSubId", "=", dto.getIdNumber()).and("delFlag", "=", false);
if (dto.getFileIdList() != null && !dto.getFileIdList().isEmpty()) {
cnd.and("sku", "in", dto.getFileIdList());
}
List<PointsMallOrderSubProduct> products = dao.query(PointsMallOrderSubProduct.class, cnd);
Map<String, String> map = new LinkedHashMap<>();
for (PointsMallOrderSubProduct product : products) {
map.put(product.getSku(), product.getPicInfo());
}
return map;
}
private Map<String, String> queryInvoiceFiles(PictureQueryDTO dto) {
PointsMallInvoiceMain main = dao.fetch(PointsMallInvoiceMain.class, Cnd.where("settlementId", "=", dto.getIdNumber()).and("delFlag", "=", false));
if (main == null) {
return Collections.emptyMap();
}
Cnd cnd = Cnd.where("mainId", "=", main.getId()).and("delFlag", "=", false);
if (dto.getFileIdList() != null && !dto.getFileIdList().isEmpty()) {
cnd.and("invoiceId", "in", dto.getFileIdList());
}
List<PointsMallInvoiceInfo> invoices = dao.query(PointsMallInvoiceInfo.class, cnd);
Map<String, String> map = new LinkedHashMap<>();
for (PointsMallInvoiceInfo invoice : invoices) {
map.put(invoice.getInvoiceId(), invoice.getImageEncode());
}
return map;
}
private String firstInvoiceFileType(PictureQueryDTO dto) {
PointsMallInvoiceMain main = dao.fetch(PointsMallInvoiceMain.class, Cnd.where("settlementId", "=", dto.getIdNumber()).and("delFlag", "=", false));
if (main == null) {
return null;
}
PointsMallInvoiceInfo info = dao.fetch(PointsMallInvoiceInfo.class, Cnd.where("mainId", "=", main.getId()).and("delFlag", "=", false));
return info == null ? null : info.getFileType();
}
private PointsMallOrderMain toMain(String supplierId, String userId, OrderInfoDTO orderInfo, Integer state) {
PointsMallOrderMain main = new PointsMallOrderMain();
main.setOrderId(orderInfo.getOrderId());
@@ -313,9 +577,16 @@ public class PointsMallBridgeServiceImpl implements PointsMallBridgeService {
dto.setOrderNumberId(record.getString("orderNumberId"));
dto.setSupplierId(record.getString("supplierId"));
dto.setAplName(record.getString("aplName"));
dto.setCreateTime(formatDate(record.get("orderCreateTime")));
dto.setUpdateTime(formatDate(record.get("orderUpdateTime")));
dto.setDeliveryTime(formatDate(record.get("deliveryTime")));
dto.setOrderFinishTime(formatDate(record.get("orderFinishTime")));
dto.setCompleteTime(formatDate(record.get("orderCompleteTime")));
dto.setDeliveryStatus(record.getString("deliveryStatus"));
dto.setFreightCost(decimal(record.get("freightCost")));
dto.setWPayOrAPayFreightCost(decimal(record.get("wPayOrAPayFreightCost")));
dto.setRefund(decimal(record.get("refund")));
dto.setWPayOrAPayRefund(decimal(record.get("wPayOrAPayRefund")));
dto.setLogisticsOrderId(record.getString("logisticsOrderId"));
dto.setCrrgBsnNm(record.getString("crrgBsnNm"));
dto.setOrderState(record.getInt("orderState"));
@@ -323,6 +594,49 @@ public class PointsMallBridgeServiceImpl implements PointsMallBridgeService {
dto.setWPayOrAPay(decimal(record.get("wPayOrAPay")));
dto.setPointsPrice(decimal(record.get("pointsPrice")));
dto.setInvoiceCode(record.getString("invoiceCode"));
dto.setOrderProInfos(readProducts(dto.getOrderId(), record.getString("extJson")));
return dto;
}
private List<OrderProInfoDTO> readProducts(String orderId, String extJson) {
List<PointsMallOrderSubProduct> products = dao.query(PointsMallOrderSubProduct.class, Cnd.where("orderSubId", "=", orderId).and("delFlag", "=", false));
if (!products.isEmpty()) {
return products.stream().map(this::toProductDTO).collect(Collectors.toList());
}
if (StrUtil.isBlank(extJson) || "null".equalsIgnoreCase(extJson)) {
return Collections.emptyList();
}
return JSONUtil.toList(extJson, OrderProInfoDTO.class);
}
private OrderProInfoDTO toProductDTO(PointsMallOrderSubProduct product) {
OrderProInfoDTO dto = new OrderProInfoDTO();
dto.setSku(product.getSku());
dto.setNumber(product.getNumber());
dto.setPrice(product.getPrice());
dto.setName(product.getName());
dto.setTaxRate(product.getTaxRate());
dto.setPicInfo(StrUtil.isBlank(product.getPicInfo()) ? Collections.emptyList() : Collections.singletonList(product.getPicInfo()));
dto.setFileId(product.getSku());
dto.setFilePath(product.getPicInfo());
return dto;
}
private InvoiceInfoDTO toInvoiceInfoDTO(PointsMallInvoiceInfo info) {
InvoiceInfoDTO dto = new InvoiceInfoDTO();
dto.setInvoiceId(info.getInvoiceId());
dto.setInvoiceCode(info.getInvoiceCode());
dto.setInvoiceDate(toLocalDate(info.getInvoiceDate()));
dto.setInvoiceNakeAmount(info.getInvoiceNakeAmount());
dto.setInvoiceTaxRate(info.getInvoiceTaxRate());
dto.setInvoiceTaxAmount(info.getInvoiceTaxAmount());
dto.setInvoiceAmount(info.getInvoiceAmount());
dto.setInvoiceType(info.getInvoiceType());
dto.setUrl(info.getUrl());
dto.setImageEncode(info.getImageEncode());
dto.setFileType(info.getFileType());
dto.setCheckCode(info.getCheckCode());
dto.setInvoiceAddress(info.getInvoiceAddress());
return dto;
}
@@ -333,6 +647,28 @@ public class PointsMallBridgeServiceImpl implements PointsMallBridgeService {
return DateUtil.parse(value.replace("T", " "));
}
private String formatDate(Object value) {
if (value == null) {
return null;
}
return DateUtil.format(Convert.toDate(value), "yyyy-MM-dd HH:mm:ss");
}
private LocalDate toLocalDate(Date date) {
return date == null ? null : date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
}
private List<String> splitIds(String value) {
if (StrUtil.isBlank(value)) {
return Collections.emptyList();
}
return Arrays.stream(value.split(","))
.map(String::trim)
.filter(StrUtil::isNotBlank)
.distinct()
.collect(Collectors.toList());
}
private BigDecimal nvl(BigDecimal value) {
return value == null ? BigDecimal.ZERO : value;
}
@@ -349,10 +685,6 @@ public class PointsMallBridgeServiceImpl implements PointsMallBridgeService {
if (StrUtil.isBlank(value)) {
return null;
}
try {
return Integer.valueOf(value);
} catch (NumberFormatException e) {
return null;
}
return Convert.toInt(value, null);
}
}
@@ -0,0 +1,86 @@
package com.budwk.app.zhgh.pointsmall.order.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import com.budwk.app.base.result.Result;
import com.budwk.app.zhgh.pointsmall.order.models.PointsMallOrderExchange;
import com.budwk.app.zhgh.pointsmall.order.models.PointsMallOrderSub;
import com.budwk.app.zhgh.pointsmall.order.param.PointsMallOrderPageParam;
import com.budwk.app.zhgh.pointsmall.order.service.PointsMallOrderService;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.mvc.adaptor.JsonAdaptor;
import org.nutz.mvc.annotation.AdaptBy;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import org.nutz.mvc.annotation.Param;
import org.nutz.mvc.annotation.POST;
@IocBean
@Ok("json:full")
@At("/platform/zhgh/points-mall/order/sub")
@AdaptBy(type = JsonAdaptor.class)
public class PointsMallOrderSubController {
@Inject
private PointsMallOrderService pointsMallOrderService;
@POST
@At("/page")
@SaCheckPermission("points.mall.order")
public Result pageData(@Param("..") PointsMallOrderPageParam param) {
return Result.success(pointsMallOrderService.pageSub(param));
}
@POST
@At("/product")
@SaCheckPermission("points.mall.order")
public Result productList(@Param("orderId") String orderId) {
return Result.success(pointsMallOrderService.listSubProducts(orderId));
}
@POST
@At("/exchange/list")
@SaCheckPermission("points.mall.order")
public Result exchangeList(@Param("mainOrderId") String mainOrderId) {
return Result.success(pointsMallOrderService.listExchange(mainOrderId));
}
@POST
@At("/exchange/product")
@SaCheckPermission("points.mall.order")
public Result exchangeProductList(@Param("orderId") String orderId) {
return Result.success(pointsMallOrderService.listExchangeProducts(orderId));
}
@POST
@At("/update")
@SaCheckPermission("points.mall.order")
public Result update(@Param("..") PointsMallOrderSub orderSub) {
return result(pointsMallOrderService.updateSub(orderSub));
}
@POST
@At("/delete")
@SaCheckPermission("points.mall.order")
public Result delete(@Param("id") String id) {
return result(pointsMallOrderService.deleteSub(id));
}
@POST
@At("/exchange/update")
@SaCheckPermission("points.mall.order")
public Result updateExchange(@Param("..") PointsMallOrderExchange exchange) {
return result(pointsMallOrderService.updateExchange(exchange));
}
@POST
@At("/exchange/delete")
@SaCheckPermission("points.mall.order")
public Result deleteExchange(@Param("id") String id) {
return result(pointsMallOrderService.deleteExchange(id));
}
private Result result(boolean success) {
return success ? Result.success("操作成功") : Result.error("操作失败");
}
}
@@ -3,6 +3,8 @@ package com.budwk.app.zhgh.pointsmall.order.service;
import com.budwk.app.base.page.Pagination;
import com.budwk.app.base.service.BaseService;
import com.budwk.app.zhgh.pointsmall.order.models.PointsMallOrderMain;
import com.budwk.app.zhgh.pointsmall.order.models.PointsMallOrderExchange;
import com.budwk.app.zhgh.pointsmall.order.models.PointsMallOrderSub;
import com.budwk.app.zhgh.pointsmall.order.param.PointsMallMobileOrderPageParam;
import com.budwk.app.zhgh.pointsmall.supplier.models.PointsMallSupplier;
import com.budwk.app.zhgh.pointsmall.order.param.PointsMallOrderPageParam;
@@ -28,5 +30,13 @@ public interface PointsMallOrderService extends BaseService<PointsMallOrderMain>
List<Record> listExchangeProducts(String orderId);
boolean updateSub(PointsMallOrderSub orderSub);
boolean deleteSub(String id);
boolean updateExchange(PointsMallOrderExchange exchange);
boolean deleteExchange(String id);
List<PointsMallSupplier> listSuppliers();
}
@@ -3,19 +3,23 @@ package com.budwk.app.zhgh.pointsmall.order.service.impl;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.page.Pagination;
import com.budwk.app.base.service.impl.BaseServiceImpl;
import com.budwk.app.zhgh.pointsmall.order.models.PointsMallOrderExchange;
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.param.PointsMallMobileOrderPageParam;
import com.budwk.app.zhgh.pointsmall.supplier.models.PointsMallSupplier;
import com.budwk.app.zhgh.pointsmall.order.param.PointsMallOrderPageParam;
import com.budwk.app.zhgh.pointsmall.order.service.PointsMallOrderService;
import com.budwk.app.zhgh.pointsmall.supplier.models.PointsMallSupplier;
import org.nutz.dao.Chain;
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.dao.Sqls;
import org.nutz.ioc.loader.annotation.IocBean;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
@IocBean(args = {"refer:dao"})
@@ -97,10 +101,12 @@ public class PointsMallOrderServiceImpl extends BaseServiceImpl<PointsMallOrderM
state(0, "待付款"),
state(1, "已支付"),
state(2, "进行中"),
state(4, "签收"),
state(3, "取消"),
state(4, "已妥投"),
state(5, "已完成"),
state(6, "换货"),
state(7, "退货")
state(7, "退货"),
state(8, "已废除")
);
}
@@ -145,6 +151,40 @@ public class PointsMallOrderServiceImpl extends BaseServiceImpl<PointsMallOrderM
return listSubProducts(orderId);
}
@Override
public boolean updateSub(PointsMallOrderSub orderSub) {
if (orderSub == null || StrUtil.isBlank(orderSub.getId())) {
return false;
}
orderSub.setOrderUpdateTime(new Date());
return dao().updateIgnoreNull(orderSub) > 0;
}
@Override
public boolean deleteSub(String id) {
if (StrUtil.isBlank(id)) {
return false;
}
return dao().update(PointsMallOrderSub.class, Chain.make("delFlag", true), Cnd.where("id", "=", id)) > 0;
}
@Override
public boolean updateExchange(PointsMallOrderExchange exchange) {
if (exchange == null || StrUtil.isBlank(exchange.getId())) {
return false;
}
exchange.setOrderUpdateTime(new Date());
return dao().updateIgnoreNull(exchange) > 0;
}
@Override
public boolean deleteExchange(String id) {
if (StrUtil.isBlank(id)) {
return false;
}
return dao().update(PointsMallOrderExchange.class, Chain.make("delFlag", true), Cnd.where("id", "=", id)) > 0;
}
@Override
public List<PointsMallSupplier> listSuppliers() {
return dao().query(PointsMallSupplier.class, Cnd.where("delFlag", "=", false).asc("sortCode"));
@@ -84,6 +84,7 @@ layout("/layouts/platform_h5.html"){
<script nonce="${cspNonce!}">
new Vue({
el: "#app",
store,
data() {
return {
keyword: "",
@@ -145,12 +146,36 @@ layout("/layouts/platform_h5.html"){
this.userPoints = resp.data || 0
}
},
openSupplier(item) {
async openSupplier(item) {
if (!item.supplierUrl) {
this.$toast("暂无跳转地址")
return
}
window.location.href = item.supplierUrl
const userId = this.$store && this.$store.state.user ? this.$store.state.user.id : ""
if (!userId) {
this.$toast("获取用户信息失败,请重新登录后再试")
return
}
window.location.href = this.withSupplierQuery(item.supplierUrl, {
userId: userId
})
},
withSupplierQuery(url, params) {
const query = Object.keys(params)
.filter((key) => params[key] !== undefined && params[key] !== null && params[key] !== "")
.map((key) => encodeURIComponent(key) + "=" + encodeURIComponent(params[key]))
.join("&")
if (!query) {
return url
}
const hashIndex = url.indexOf("#")
if (hashIndex > -1) {
const base = url.slice(0, hashIndex)
const hash = url.slice(hashIndex)
const joiner = hash.indexOf("?") > -1 ? "&" : "?"
return base + hash + joiner + query
}
return url + (url.indexOf("?") > -1 ? "&" : "?") + query
},
onImgError(e) {
e.target.src = this.defaultLogo