Commit d982a95fdd987879380f220ee8cc83bb4a8757ae
Merge branch 'feature/mall_product' of https://gitee.com/zhijiantianya/ruoyi-vue-pro
Showing
114 changed files
with
1486 additions
and
569 deletions
Too many changes.
To preserve performance only 100 of 114 files are displayed.
sql/mysql/optional/mall_trade_log.sql
0 → 100644
sql/mysql/pay_wallet.sql
| ... | ... | @@ -5,11 +5,11 @@ DROP TABLE IF EXISTS `pay_wallet`; |
| 5 | 5 | CREATE TABLE `pay_wallet` |
| 6 | 6 | ( |
| 7 | 7 | `id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号', |
| 8 | - `user_id` bigint NOT NULL COMMENT '用户 id', | |
| 8 | + `user_id` bigint NOT NULL COMMENT '用户编号', | |
| 9 | 9 | `user_type` tinyint NOT NULL DEFAULT 0 COMMENT '用户类型', |
| 10 | - `balance` int NOT NULL DEFAULT 0 COMMENT '余额, 单位分', | |
| 11 | - `total_expense` bigint NOT NULL DEFAULT 0 COMMENT '累计支出, 单位分', | |
| 12 | - `total_recharge` bigint NOT NULL DEFAULT 0 COMMENT '累计充值, 单位分', | |
| 10 | + `balance` int NOT NULL DEFAULT 0 COMMENT '余额,单位分', | |
| 11 | + `total_expense` bigint NOT NULL DEFAULT 0 COMMENT '累计支出,单位分', | |
| 12 | + `total_recharge` bigint NOT NULL DEFAULT 0 COMMENT '累计充值,单位分', | |
| 13 | 13 | `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '创建者', |
| 14 | 14 | `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', |
| 15 | 15 | `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '更新者', |
| ... | ... | @@ -41,4 +41,4 @@ CREATE TABLE `pay_wallet_transaction` |
| 41 | 41 | `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', |
| 42 | 42 | `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号', |
| 43 | 43 | PRIMARY KEY (`id`) USING BTREE |
| 44 | -) ENGINE=InnoDB COMMENT='支付钱包余额明细表'; | |
| 45 | 44 | \ No newline at end of file |
| 45 | +) ENGINE=InnoDB COMMENT='支付钱包余额明细表'; | ... | ... |
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/PayClientFactory.java
| 1 | 1 | package cn.iocoder.yudao.framework.pay.core.client; |
| 2 | 2 | |
| 3 | +import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum; | |
| 4 | + | |
| 3 | 5 | /** |
| 4 | 6 | * 支付客户端的工厂接口 |
| 5 | 7 | * |
| ... | ... | @@ -25,4 +27,12 @@ public interface PayClientFactory { |
| 25 | 27 | <Config extends PayClientConfig> void createOrUpdatePayClient(Long channelId, String channelCode, |
| 26 | 28 | Config config); |
| 27 | 29 | |
| 30 | + /** | |
| 31 | + * 注册支付客户端 Class,用于模块中实现的 PayClient | |
| 32 | + * | |
| 33 | + * @param channel 支付渠道的编码的枚举 | |
| 34 | + * @param payClientClass 支付客户端 class | |
| 35 | + */ | |
| 36 | + void registerPayClientClass(PayChannelEnum channel, Class<?> payClientClass); | |
| 37 | + | |
| 28 | 38 | } | ... | ... |
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/NonePayClientConfig.java
0 → 100644
| 1 | +package cn.iocoder.yudao.framework.pay.core.client.impl; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.framework.pay.core.client.PayClientConfig; | |
| 4 | +import lombok.Data; | |
| 5 | + | |
| 6 | +import javax.validation.Validator; | |
| 7 | + | |
| 8 | +/** | |
| 9 | + * 无需任何配置 PayClientConfig 实现类 | |
| 10 | + * | |
| 11 | + * @author jason | |
| 12 | + */ | |
| 13 | +@Data | |
| 14 | +public class NonePayClientConfig implements PayClientConfig { | |
| 15 | + | |
| 16 | + /** | |
| 17 | + * 配置名称 | |
| 18 | + * <p> | |
| 19 | + * 如果不加任何属性,JsonUtils.parseObject2 解析会报错,所以暂时加个名称 | |
| 20 | + */ | |
| 21 | + private String name; | |
| 22 | + | |
| 23 | + public NonePayClientConfig(){ | |
| 24 | + this.name = "none-config"; | |
| 25 | + } | |
| 26 | + | |
| 27 | + @Override | |
| 28 | + public void validate(Validator validator) { | |
| 29 | + // 无任何配置不需要校验 | |
| 30 | + } | |
| 31 | +} | ... | ... |
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/PayClientFactoryImpl.java
| 1 | 1 | package cn.iocoder.yudao.framework.pay.core.client.impl; |
| 2 | 2 | |
| 3 | 3 | import cn.hutool.core.lang.Assert; |
| 4 | +import cn.hutool.core.util.ReflectUtil; | |
| 4 | 5 | import cn.iocoder.yudao.framework.pay.core.client.PayClient; |
| 5 | 6 | import cn.iocoder.yudao.framework.pay.core.client.PayClientConfig; |
| 6 | 7 | import cn.iocoder.yudao.framework.pay.core.client.PayClientFactory; |
| 7 | 8 | import cn.iocoder.yudao.framework.pay.core.client.impl.alipay.*; |
| 8 | 9 | import cn.iocoder.yudao.framework.pay.core.client.impl.mock.MockPayClient; |
| 9 | -import cn.iocoder.yudao.framework.pay.core.client.impl.mock.MockPayClientConfig; | |
| 10 | 10 | import cn.iocoder.yudao.framework.pay.core.client.impl.weixin.*; |
| 11 | 11 | import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum; |
| 12 | 12 | import lombok.extern.slf4j.Slf4j; |
| 13 | 13 | |
| 14 | +import java.util.Map; | |
| 14 | 15 | import java.util.concurrent.ConcurrentHashMap; |
| 15 | 16 | import java.util.concurrent.ConcurrentMap; |
| 16 | 17 | |
| 18 | +import static cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum.*; | |
| 19 | + | |
| 17 | 20 | /** |
| 18 | 21 | * 支付客户端的工厂实现类 |
| 19 | 22 | * |
| ... | ... | @@ -24,10 +27,38 @@ public class PayClientFactoryImpl implements PayClientFactory { |
| 24 | 27 | |
| 25 | 28 | /** |
| 26 | 29 | * 支付客户端 Map |
| 30 | + * | |
| 27 | 31 | * key:渠道编号 |
| 28 | 32 | */ |
| 29 | 33 | private final ConcurrentMap<Long, AbstractPayClient<?>> clients = new ConcurrentHashMap<>(); |
| 30 | 34 | |
| 35 | + /** | |
| 36 | + * 支付客户端 Class Map | |
| 37 | + */ | |
| 38 | + private final Map<PayChannelEnum, Class<?>> clientClass = new ConcurrentHashMap<>(); | |
| 39 | + | |
| 40 | + public PayClientFactoryImpl() { | |
| 41 | + // 微信支付客户端 | |
| 42 | + clientClass.put(WX_PUB, WxPubPayClient.class); | |
| 43 | + clientClass.put(WX_LITE, WxLitePayClient.class); | |
| 44 | + clientClass.put(WX_APP, WxAppPayClient.class); | |
| 45 | + clientClass.put(WX_BAR, WxBarPayClient.class); | |
| 46 | + clientClass.put(WX_NATIVE, WxNativePayClient.class); | |
| 47 | + // 支付包支付客户端 | |
| 48 | + clientClass.put(ALIPAY_WAP, AlipayWapPayClient.class); | |
| 49 | + clientClass.put(ALIPAY_QR, AlipayQrPayClient.class); | |
| 50 | + clientClass.put(ALIPAY_APP, AlipayAppPayClient.class); | |
| 51 | + clientClass.put(ALIPAY_PC, AlipayPcPayClient.class); | |
| 52 | + clientClass.put(ALIPAY_BAR, AlipayBarPayClient.class); | |
| 53 | + // Mock 支付客户端 | |
| 54 | + clientClass.put(MOCK, MockPayClient.class); | |
| 55 | + } | |
| 56 | + | |
| 57 | + @Override | |
| 58 | + public void registerPayClientClass(PayChannelEnum channel, Class<?> payClientClass) { | |
| 59 | + clientClass.put(channel, payClientClass); | |
| 60 | + } | |
| 61 | + | |
| 31 | 62 | @Override |
| 32 | 63 | public PayClient getPayClient(Long channelId) { |
| 33 | 64 | AbstractPayClient<?> client = clients.get(channelId); |
| ... | ... | @@ -52,30 +83,13 @@ public class PayClientFactoryImpl implements PayClientFactory { |
| 52 | 83 | } |
| 53 | 84 | |
| 54 | 85 | @SuppressWarnings("unchecked") |
| 55 | - private <Config extends PayClientConfig> AbstractPayClient<Config> createPayClient( | |
| 56 | - Long channelId, String channelCode, Config config) { | |
| 86 | + private <Config extends PayClientConfig> AbstractPayClient<Config> createPayClient(Long channelId, String channelCode, | |
| 87 | + Config config) { | |
| 57 | 88 | PayChannelEnum channelEnum = PayChannelEnum.getByCode(channelCode); |
| 58 | - Assert.notNull(channelEnum, String.format("支付渠道(%s) 为空", channelEnum)); | |
| 59 | - // 创建客户端 | |
| 60 | - switch (channelEnum) { | |
| 61 | - // 微信支付 | |
| 62 | - case WX_PUB: return (AbstractPayClient<Config>) new WxPubPayClient(channelId, (WxPayClientConfig) config); | |
| 63 | - case WX_LITE: return (AbstractPayClient<Config>) new WxLitePayClient(channelId, (WxPayClientConfig) config); | |
| 64 | - case WX_APP: return (AbstractPayClient<Config>) new WxAppPayClient(channelId, (WxPayClientConfig) config); | |
| 65 | - case WX_BAR: return (AbstractPayClient<Config>) new WxBarPayClient(channelId, (WxPayClientConfig) config); | |
| 66 | - case WX_NATIVE: return (AbstractPayClient<Config>) new WxNativePayClient(channelId, (WxPayClientConfig) config); | |
| 67 | - // 支付宝支付 | |
| 68 | - case ALIPAY_WAP: return (AbstractPayClient<Config>) new AlipayWapPayClient(channelId, (AlipayPayClientConfig) config); | |
| 69 | - case ALIPAY_QR: return (AbstractPayClient<Config>) new AlipayQrPayClient(channelId, (AlipayPayClientConfig) config); | |
| 70 | - case ALIPAY_APP: return (AbstractPayClient<Config>) new AlipayAppPayClient(channelId, (AlipayPayClientConfig) config); | |
| 71 | - case ALIPAY_PC: return (AbstractPayClient<Config>) new AlipayPcPayClient(channelId, (AlipayPayClientConfig) config); | |
| 72 | - case ALIPAY_BAR: return (AbstractPayClient<Config>) new AlipayBarPayClient(channelId, (AlipayPayClientConfig) config); | |
| 73 | - // 其它支付 | |
| 74 | - case MOCK: return (AbstractPayClient<Config>) new MockPayClient(channelId, (MockPayClientConfig) config); | |
| 75 | - } | |
| 76 | - // 创建失败,错误日志 + 抛出异常 | |
| 77 | - log.error("[createPayClient][配置({}) 找不到合适的客户端实现]", config); | |
| 78 | - throw new IllegalArgumentException(String.format("配置(%s) 找不到合适的客户端实现", config)); | |
| 89 | + Assert.notNull(channelEnum, String.format("支付渠道(%s) 为空", channelCode)); | |
| 90 | + Class<?> payClientClass = clientClass.get(channelEnum); | |
| 91 | + Assert.notNull(payClientClass, String.format("支付渠道(%s) Class 为空", channelCode)); | |
| 92 | + return (AbstractPayClient<Config>) ReflectUtil.newInstance(payClientClass, channelId, config); | |
| 79 | 93 | } |
| 80 | 94 | |
| 81 | 95 | } | ... | ... |
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/delegate/DelegatePayClient.java
0 → 100644
| 1 | +package cn.iocoder.yudao.framework.pay.core.client.impl.delegate; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.framework.pay.core.client.PayClientConfig; | |
| 4 | +import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO; | |
| 5 | +import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO; | |
| 6 | +import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundRespDTO; | |
| 7 | +import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundUnifiedReqDTO; | |
| 8 | +import cn.iocoder.yudao.framework.pay.core.client.impl.AbstractPayClient; | |
| 9 | + | |
| 10 | +import java.util.Map; | |
| 11 | + | |
| 12 | +// TODO @jason:其它模块,主要是无法 pay client 初始化存在问题,所以我感觉,是不是可以搞个 PayClientInitializer 接口。这样,PayClientFactory 去 get 这个支付模式对应的 PayClientInitializer,通过它来创建。具体注入的地方,可以在 PayChannel init 方法那; | |
| 13 | +/** | |
| 14 | + * 代理支付 Client 的抽象类。 | |
| 15 | + * | |
| 16 | + * 用于支付 Client 由其它模块实现,例如钱包支付 | |
| 17 | + * | |
| 18 | + * @author jason | |
| 19 | + */ | |
| 20 | +public abstract class DelegatePayClient<Config extends PayClientConfig> extends AbstractPayClient<PayClientConfig> { | |
| 21 | + | |
| 22 | + private final DelegatePayClient<Config> delegate; | |
| 23 | + | |
| 24 | + public DelegatePayClient(Long channelId, String channelCode, PayClientConfig config) { | |
| 25 | + super(channelId, channelCode, config); | |
| 26 | + delegate = this; | |
| 27 | + } | |
| 28 | + | |
| 29 | + @Override | |
| 30 | + protected void doInit() { | |
| 31 | + delegate.doInit(); | |
| 32 | + } | |
| 33 | + | |
| 34 | + @Override | |
| 35 | + protected PayOrderRespDTO doUnifiedOrder(PayOrderUnifiedReqDTO reqDTO) { | |
| 36 | + return delegate.doUnifiedOrder(reqDTO); | |
| 37 | + } | |
| 38 | + | |
| 39 | + @Override | |
| 40 | + protected PayOrderRespDTO doGetOrder(String outTradeNo) { | |
| 41 | + return delegate.doGetOrder(outTradeNo); | |
| 42 | + } | |
| 43 | + | |
| 44 | + @Override | |
| 45 | + protected PayRefundRespDTO doUnifiedRefund(PayRefundUnifiedReqDTO reqDTO) { | |
| 46 | + return delegate.doUnifiedRefund(reqDTO); | |
| 47 | + } | |
| 48 | + | |
| 49 | + @Override | |
| 50 | + protected PayRefundRespDTO doGetRefund(String outTradeNo, String outRefundNo) { | |
| 51 | + return delegate.doGetRefund(outTradeNo, outRefundNo); | |
| 52 | + } | |
| 53 | + | |
| 54 | + @Override | |
| 55 | + protected PayRefundRespDTO doParseRefundNotify(Map<String,String> params, String body) { | |
| 56 | + return delegate.doParseRefundNotify(params, body); | |
| 57 | + } | |
| 58 | + | |
| 59 | + @Override | |
| 60 | + protected PayOrderRespDTO doParseOrderNotify(Map<String,String> params, String body) { | |
| 61 | + return delegate.doParseOrderNotify(params, body); | |
| 62 | + } | |
| 63 | +} | ... | ... |
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/enums/channel/PayChannelEnum.java
| 1 | 1 | package cn.iocoder.yudao.framework.pay.core.enums.channel; |
| 2 | 2 | |
| 3 | 3 | import cn.hutool.core.util.ArrayUtil; |
| 4 | +import cn.iocoder.yudao.framework.pay.core.client.impl.NonePayClientConfig; | |
| 4 | 5 | import cn.iocoder.yudao.framework.pay.core.client.PayClientConfig; |
| 5 | 6 | import cn.iocoder.yudao.framework.pay.core.client.impl.alipay.AlipayPayClientConfig; |
| 6 | 7 | import cn.iocoder.yudao.framework.pay.core.client.impl.mock.MockPayClientConfig; |
| ... | ... | @@ -29,7 +30,9 @@ public enum PayChannelEnum { |
| 29 | 30 | ALIPAY_QR("alipay_qr", "支付宝扫码支付", AlipayPayClientConfig.class), |
| 30 | 31 | ALIPAY_BAR("alipay_bar", "支付宝条码支付", AlipayPayClientConfig.class), |
| 31 | 32 | |
| 32 | - MOCK("mock", "模拟支付", MockPayClientConfig.class); | |
| 33 | + MOCK("mock", "模拟支付", MockPayClientConfig.class), | |
| 34 | + | |
| 35 | + WALLET("wallet", "钱包支付", NonePayClientConfig.class); | |
| 33 | 36 | |
| 34 | 37 | /** |
| 35 | 38 | * 编码 | ... | ... |
yudao-framework/yudao-spring-boot-starter-biz-pay/src/test/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AbstractAlipayClientTest.java
| ... | ... | @@ -168,7 +168,7 @@ public abstract class AbstractAlipayClientTest extends BaseMockitoUnitTest { |
| 168 | 168 | @Test |
| 169 | 169 | @DisplayName("支付宝 Client 统一退款:抛出业务异常") |
| 170 | 170 | public void testUnifiedRefund_throwServiceException() throws AlipayApiException { |
| 171 | - // mock | |
| 171 | + // mock 方法 | |
| 172 | 172 | when(defaultAlipayClient.execute(argThat((ArgumentMatcher<AlipayTradeRefundRequest>) request -> true))) |
| 173 | 173 | .thenThrow(ServiceExceptionUtil.exception(GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR)); |
| 174 | 174 | // 准备请求参数 |
| ... | ... | @@ -182,7 +182,7 @@ public abstract class AbstractAlipayClientTest extends BaseMockitoUnitTest { |
| 182 | 182 | @Test |
| 183 | 183 | @DisplayName("支付宝 Client 统一退款:抛出系统异常") |
| 184 | 184 | public void testUnifiedRefund_throwPayException() throws AlipayApiException { |
| 185 | - // mock | |
| 185 | + // mock 方法 | |
| 186 | 186 | when(defaultAlipayClient.execute(argThat((ArgumentMatcher<AlipayTradeRefundRequest>) request -> true))) |
| 187 | 187 | .thenThrow(new RuntimeException("系统异常")); |
| 188 | 188 | // 准备请求参数 | ... | ... |
yudao-framework/yudao-spring-boot-starter-biz-pay/src/test/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayPcPayClientTest.java
| ... | ... | @@ -70,7 +70,7 @@ public class AlipayPcPayClientTest extends AbstractAlipayClientTest { |
| 70 | 70 | @Test |
| 71 | 71 | @DisplayName("支付宝 PC 网站支付:Form Display Mode 下单成功") |
| 72 | 72 | public void testUnifiedOrder_formSuccess() throws AlipayApiException { |
| 73 | - // mock | |
| 73 | + // mock 方法 | |
| 74 | 74 | String notifyUrl = randomURL(); |
| 75 | 75 | AlipayTradePagePayResponse response = randomPojo(AlipayTradePagePayResponse.class, o -> o.setSubCode("")); |
| 76 | 76 | when(defaultAlipayClient.pageExecute(argThat((ArgumentMatcher<AlipayTradePagePayRequest>) request -> true), |
| ... | ... | @@ -99,7 +99,7 @@ public class AlipayPcPayClientTest extends AbstractAlipayClientTest { |
| 99 | 99 | @Test |
| 100 | 100 | @DisplayName("支付宝 PC 网站支付:渠道返回失败") |
| 101 | 101 | public void testUnifiedOrder_channelFailed() throws AlipayApiException { |
| 102 | - // mock | |
| 102 | + // mock 方法 | |
| 103 | 103 | String subCode = randomString(); |
| 104 | 104 | String subMsg = randomString(); |
| 105 | 105 | AlipayTradePagePayResponse response = randomPojo(AlipayTradePagePayResponse.class, o -> { | ... | ... |
yudao-framework/yudao-spring-boot-starter-biz-pay/src/test/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayQrPayClientTest.java
| ... | ... | @@ -39,9 +39,9 @@ public class AlipayQrPayClientTest extends AbstractAlipayClientTest { |
| 39 | 39 | } |
| 40 | 40 | |
| 41 | 41 | @Test |
| 42 | - @DisplayName("支付宝扫描支付下单成功") | |
| 43 | - public void test_unified_order_success() throws AlipayApiException { | |
| 44 | - // 准备返回对象 | |
| 42 | + @DisplayName("支付宝扫描支付:下单成功") | |
| 43 | + public void testUnifiedOrder_success() throws AlipayApiException { | |
| 44 | + // mock 方法 | |
| 45 | 45 | String notifyUrl = randomURL(); |
| 46 | 46 | String qrCode = randomString(); |
| 47 | 47 | Integer price = randomInteger(); |
| ... | ... | @@ -49,7 +49,6 @@ public class AlipayQrPayClientTest extends AbstractAlipayClientTest { |
| 49 | 49 | o.setQrCode(qrCode); |
| 50 | 50 | o.setSubCode(""); |
| 51 | 51 | }); |
| 52 | - // mock | |
| 53 | 52 | when(defaultAlipayClient.execute(argThat((ArgumentMatcher<AlipayTradePrecreateRequest>) request -> { |
| 54 | 53 | assertEquals(notifyUrl, request.getNotifyUrl()); |
| 55 | 54 | return true; |
| ... | ... | @@ -58,18 +57,25 @@ public class AlipayQrPayClientTest extends AbstractAlipayClientTest { |
| 58 | 57 | String outTradeNo = randomString(); |
| 59 | 58 | PayOrderUnifiedReqDTO reqDTO = buildOrderUnifiedReqDTO(notifyUrl, outTradeNo, price); |
| 60 | 59 | |
| 60 | + // 调用 | |
| 61 | 61 | PayOrderRespDTO resp = client.unifiedOrder(reqDTO); |
| 62 | 62 | // 断言 |
| 63 | 63 | assertEquals(WAITING.getStatus(), resp.getStatus()); |
| 64 | - assertEquals(PayOrderDisplayModeEnum.QR_CODE.getMode(), resp.getDisplayMode()); | |
| 65 | 64 | assertEquals(outTradeNo, resp.getOutTradeNo()); |
| 66 | - assertEquals(qrCode, resp.getDisplayContent()); | |
| 65 | + assertNull(resp.getChannelOrderNo()); | |
| 66 | + assertNull(resp.getChannelUserId()); | |
| 67 | + assertNull(resp.getSuccessTime()); | |
| 68 | + assertEquals(PayOrderDisplayModeEnum.QR_CODE.getMode(), resp.getDisplayMode()); | |
| 69 | + assertEquals(response.getQrCode(), resp.getDisplayContent()); | |
| 67 | 70 | assertSame(response, resp.getRawData()); |
| 71 | + assertNull(resp.getChannelErrorCode()); | |
| 72 | + assertNull(resp.getChannelErrorMsg()); | |
| 68 | 73 | } |
| 69 | 74 | |
| 70 | 75 | @Test |
| 71 | - @DisplayName("支付宝扫描支付,渠道返回失败") | |
| 72 | - public void test_unified_order_channel_failed() throws AlipayApiException { | |
| 76 | + @DisplayName("支付宝扫描支付:渠道返回失败") | |
| 77 | + public void testUnifiedOrder_channelFailed() throws AlipayApiException { | |
| 78 | + // mock 方法 | |
| 73 | 79 | String notifyUrl = randomURL(); |
| 74 | 80 | String subCode = randomString(); |
| 75 | 81 | String subMsg = randomString(); |
| ... | ... | @@ -87,47 +93,55 @@ public class AlipayQrPayClientTest extends AbstractAlipayClientTest { |
| 87 | 93 | String outTradeNo = randomString(); |
| 88 | 94 | PayOrderUnifiedReqDTO reqDTO = buildOrderUnifiedReqDTO(notifyUrl, outTradeNo, price); |
| 89 | 95 | |
| 96 | + // 调用 | |
| 90 | 97 | PayOrderRespDTO resp = client.unifiedOrder(reqDTO); |
| 91 | 98 | // 断言 |
| 92 | 99 | assertEquals(CLOSED.getStatus(), resp.getStatus()); |
| 100 | + assertEquals(outTradeNo, resp.getOutTradeNo()); | |
| 101 | + assertNull(resp.getChannelOrderNo()); | |
| 102 | + assertNull(resp.getChannelUserId()); | |
| 103 | + assertNull(resp.getSuccessTime()); | |
| 104 | + assertNull(resp.getDisplayMode()); | |
| 105 | + assertNull(resp.getDisplayContent()); | |
| 106 | + assertSame(response, resp.getRawData()); | |
| 93 | 107 | assertEquals(subCode, resp.getChannelErrorCode()); |
| 94 | 108 | assertEquals(subMsg, resp.getChannelErrorMsg()); |
| 95 | - assertSame(response, resp.getRawData()); | |
| 96 | 109 | } |
| 97 | 110 | |
| 98 | 111 | @Test |
| 99 | 112 | @DisplayName("支付宝扫描支付, 抛出系统异常") |
| 100 | - public void test_unified_order_throw_pay_exception() throws AlipayApiException { | |
| 101 | - // 准备请求参数 | |
| 113 | + public void testUnifiedOrder_throwPayException() throws AlipayApiException { | |
| 114 | + // mock 方法 | |
| 102 | 115 | String outTradeNo = randomString(); |
| 103 | 116 | String notifyUrl = randomURL(); |
| 104 | 117 | Integer price = randomInteger(); |
| 105 | - // mock | |
| 106 | 118 | when(defaultAlipayClient.execute(argThat((ArgumentMatcher<AlipayTradePrecreateRequest>) request -> { |
| 107 | 119 | assertEquals(notifyUrl, request.getNotifyUrl()); |
| 108 | 120 | return true; |
| 109 | 121 | }))).thenThrow(new RuntimeException("系统异常")); |
| 110 | 122 | // 准备请求参数 |
| 111 | 123 | PayOrderUnifiedReqDTO reqDTO = buildOrderUnifiedReqDTO(notifyUrl, outTradeNo,price); |
| 112 | - // 断言 | |
| 124 | + | |
| 125 | + // 调用,并断言 | |
| 113 | 126 | assertThrows(PayException.class, () -> client.unifiedOrder(reqDTO)); |
| 114 | 127 | } |
| 115 | 128 | |
| 116 | 129 | @Test |
| 117 | - @DisplayName("支付宝 Client 统一下单,抛出业务异常") | |
| 118 | - public void test_unified_order_throw_service_exception() throws AlipayApiException { | |
| 119 | - // 准备请求参数 | |
| 130 | + @DisplayName("支付宝 Client 统一下单:抛出业务异常") | |
| 131 | + public void testUnifiedOrder_throwServiceException() throws AlipayApiException { | |
| 132 | + // mock 方法 | |
| 120 | 133 | String outTradeNo = randomString(); |
| 121 | 134 | String notifyUrl = randomURL(); |
| 122 | 135 | Integer price = randomInteger(); |
| 123 | - // mock | |
| 124 | 136 | when(defaultAlipayClient.execute(argThat((ArgumentMatcher<AlipayTradePrecreateRequest>) request -> { |
| 125 | 137 | assertEquals(notifyUrl, request.getNotifyUrl()); |
| 126 | 138 | return true; |
| 127 | 139 | }))).thenThrow(ServiceExceptionUtil.exception(GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR)); |
| 128 | 140 | // 准备请求参数 |
| 129 | 141 | PayOrderUnifiedReqDTO reqDTO = buildOrderUnifiedReqDTO(notifyUrl, outTradeNo, price); |
| 130 | - // 断言 | |
| 142 | + | |
| 143 | + // 调用,并断言 | |
| 131 | 144 | assertThrows(ServiceException.class, () -> client.unifiedOrder(reqDTO)); |
| 132 | 145 | } |
| 146 | + | |
| 133 | 147 | } | ... | ... |
yudao-framework/yudao-spring-boot-starter-biz-pay/src/test/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayWapPayClientTest.java
| ... | ... | @@ -42,9 +42,9 @@ public class AlipayWapPayClientTest extends AbstractAlipayClientTest { |
| 42 | 42 | } |
| 43 | 43 | |
| 44 | 44 | @Test |
| 45 | - @DisplayName("支付宝 H5 支付下单成功") | |
| 46 | - public void test_unified_order_success() throws AlipayApiException { | |
| 47 | - // 准备响应对象 | |
| 45 | + @DisplayName("支付宝 H5 支付:下单成功") | |
| 46 | + public void testUnifiedOrder_success() throws AlipayApiException { | |
| 47 | + // mock 方法 | |
| 48 | 48 | String h5Body = randomString(); |
| 49 | 49 | Integer price = randomInteger(); |
| 50 | 50 | AlipayTradeWapPayResponse response = randomPojo(AlipayTradeWapPayResponse.class, o -> { |
| ... | ... | @@ -52,7 +52,6 @@ public class AlipayWapPayClientTest extends AbstractAlipayClientTest { |
| 52 | 52 | o.setBody(h5Body); |
| 53 | 53 | }); |
| 54 | 54 | String notifyUrl = randomURL(); |
| 55 | - // mock | |
| 56 | 55 | when(defaultAlipayClient.pageExecute(argThat((ArgumentMatcher<AlipayTradeWapPayRequest>) request -> { |
| 57 | 56 | assertInstanceOf(AlipayTradeWapPayModel.class, request.getBizModel()); |
| 58 | 57 | AlipayTradeWapPayModel bizModel = (AlipayTradeWapPayModel) request.getBizModel(); |
| ... | ... | @@ -60,37 +59,53 @@ public class AlipayWapPayClientTest extends AbstractAlipayClientTest { |
| 60 | 59 | assertEquals(notifyUrl, request.getNotifyUrl()); |
| 61 | 60 | return true; |
| 62 | 61 | }), eq(Method.GET.name()))).thenReturn(response); |
| 63 | - | |
| 62 | + // 准备请求参数 | |
| 64 | 63 | String outTradeNo = randomString(); |
| 65 | 64 | PayOrderUnifiedReqDTO reqDTO = buildOrderUnifiedReqDTO(notifyUrl, outTradeNo, price); |
| 65 | + | |
| 66 | + // 调用 | |
| 66 | 67 | PayOrderRespDTO resp = client.unifiedOrder(reqDTO); |
| 68 | + // 断言 | |
| 67 | 69 | assertEquals(WAITING.getStatus(), resp.getStatus()); |
| 68 | - assertEquals(PayOrderDisplayModeEnum.URL.getMode(), resp.getDisplayMode()); | |
| 69 | 70 | assertEquals(outTradeNo, resp.getOutTradeNo()); |
| 70 | - assertEquals(h5Body, resp.getDisplayContent()); | |
| 71 | + assertNull(resp.getChannelOrderNo()); | |
| 72 | + assertNull(resp.getChannelUserId()); | |
| 73 | + assertNull(resp.getSuccessTime()); | |
| 74 | + assertEquals(PayOrderDisplayModeEnum.URL.getMode(), resp.getDisplayMode()); | |
| 75 | + assertEquals(response.getBody(), resp.getDisplayContent()); | |
| 71 | 76 | assertSame(response, resp.getRawData()); |
| 77 | + assertNull(resp.getChannelErrorCode()); | |
| 78 | + assertNull(resp.getChannelErrorMsg()); | |
| 72 | 79 | } |
| 73 | 80 | |
| 74 | 81 | @Test |
| 75 | - @DisplayName("支付宝 H5 支付,渠道返回失败") | |
| 82 | + @DisplayName("支付宝 H5 支付:渠道返回失败") | |
| 76 | 83 | public void test_unified_order_channel_failed() throws AlipayApiException { |
| 77 | - // 准备响应对象 | |
| 84 | + // mock 方法 | |
| 78 | 85 | String subCode = randomString(); |
| 79 | 86 | String subMsg = randomString(); |
| 80 | 87 | AlipayTradeWapPayResponse response = randomPojo(AlipayTradeWapPayResponse.class, o -> { |
| 81 | 88 | o.setSubCode(subCode); |
| 82 | 89 | o.setSubMsg(subMsg); |
| 83 | 90 | }); |
| 84 | - // mock | |
| 85 | 91 | when(defaultAlipayClient.pageExecute(argThat((ArgumentMatcher<AlipayTradeWapPayRequest>) request -> true), |
| 86 | 92 | eq(Method.GET.name()))).thenReturn(response); |
| 87 | - PayOrderUnifiedReqDTO reqDTO = buildOrderUnifiedReqDTO(randomURL(), randomString(), randomInteger()); | |
| 93 | + String outTradeNo = randomString(); | |
| 94 | + PayOrderUnifiedReqDTO reqDTO = buildOrderUnifiedReqDTO(randomURL(), outTradeNo, randomInteger()); | |
| 88 | 95 | |
| 96 | + // 调用 | |
| 89 | 97 | PayOrderRespDTO resp = client.unifiedOrder(reqDTO); |
| 90 | 98 | // 断言 |
| 91 | 99 | assertEquals(CLOSED.getStatus(), resp.getStatus()); |
| 100 | + assertEquals(outTradeNo, resp.getOutTradeNo()); | |
| 101 | + assertNull(resp.getChannelOrderNo()); | |
| 102 | + assertNull(resp.getChannelUserId()); | |
| 103 | + assertNull(resp.getSuccessTime()); | |
| 104 | + assertNull(resp.getDisplayMode()); | |
| 105 | + assertNull(resp.getDisplayContent()); | |
| 106 | + assertSame(response, resp.getRawData()); | |
| 92 | 107 | assertEquals(subCode, resp.getChannelErrorCode()); |
| 93 | 108 | assertEquals(subMsg, resp.getChannelErrorMsg()); |
| 94 | - assertSame(response, resp.getRawData()); | |
| 95 | 109 | } |
| 110 | + | |
| 96 | 111 | } | ... | ... |
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/job/JobLogController.java
| ... | ... | @@ -4,6 +4,7 @@ import cn.iocoder.yudao.framework.common.pojo.CommonResult; |
| 4 | 4 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 5 | 5 | import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; |
| 6 | 6 | import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; |
| 7 | +import cn.iocoder.yudao.framework.operatelog.core.util.OperateLogUtils; | |
| 7 | 8 | import cn.iocoder.yudao.module.infra.controller.admin.job.vo.log.JobLogExcelVO; |
| 8 | 9 | import cn.iocoder.yudao.module.infra.controller.admin.job.vo.log.JobLogExportReqVO; |
| 9 | 10 | import cn.iocoder.yudao.module.infra.controller.admin.job.vo.log.JobLogPageReqVO; | ... | ... |
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/AppFavoriteController.java
| ... | ... | @@ -42,6 +42,14 @@ public class AppFavoriteController { |
| 42 | 42 | return success(productFavoriteService.createFavorite(getLoginUserId(), reqVO.getSpuId())); |
| 43 | 43 | } |
| 44 | 44 | |
| 45 | + @PostMapping(value = "/create-list") | |
| 46 | + @Operation(summary = "添加多个商品收藏") | |
| 47 | + @PreAuthenticated | |
| 48 | + public CommonResult<Boolean> createFavoriteList(@RequestBody @Valid AppFavoriteBatchReqVO reqVO) { | |
| 49 | + // todo @jason:待实现;如果有已经收藏的,不用报错,忽略即可; | |
| 50 | + return success(true); | |
| 51 | + } | |
| 52 | + | |
| 45 | 53 | @DeleteMapping(value = "/delete") |
| 46 | 54 | @Operation(summary = "取消单个商品收藏") |
| 47 | 55 | @PreAuthenticated | ... | ... |
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java
| ... | ... | @@ -110,8 +110,9 @@ public class ProductSpuServiceImpl implements ProductSpuService { |
| 110 | 110 | spu.setMarketPrice(getMinValue(skus, ProductSkuCreateOrUpdateReqVO::getMarketPrice)); |
| 111 | 111 | // sku 单价最低的商品的成本价格 |
| 112 | 112 | spu.setCostPrice(getMinValue(skus, ProductSkuCreateOrUpdateReqVO::getCostPrice)); |
| 113 | - // sku 单价最低的商品的条形码 | |
| 114 | - spu.setBarCode(getMinValue(skus, ProductSkuCreateOrUpdateReqVO::getBarCode)); | |
| 113 | + // sku 单价最低的商品的条形码 TODO 芋艿:条形码字段,是不是可以删除 | |
| 114 | + spu.setBarCode(""); | |
| 115 | +// spu.setBarCode(getMinValue(skus, ProductSkuCreateOrUpdateReqVO::getBarCode)); | |
| 115 | 116 | // skus 库存总数 |
| 116 | 117 | spu.setStock(getSumValue(skus, ProductSkuCreateOrUpdateReqVO::getStock, Integer::sum)); |
| 117 | 118 | // 若是 spu 已有状态则不处理 | ... | ... |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/SeckillConfigController.java
| ... | ... | @@ -81,12 +81,13 @@ public class SeckillConfigController { |
| 81 | 81 | @GetMapping("/list-all-simple") |
| 82 | 82 | @Operation(summary = "获得所有开启状态的秒杀时段精简列表", description = "主要用于前端的下拉选项") |
| 83 | 83 | public CommonResult<List<SeckillConfigSimpleRespVO>> getListAllSimple() { |
| 84 | - List<SeckillConfigDO> list = seckillConfigService.getSeckillConfigListByStatus(CommonStatusEnum.ENABLE.getStatus()); | |
| 84 | + List<SeckillConfigDO> list = seckillConfigService.getSeckillConfigListByStatus( | |
| 85 | + CommonStatusEnum.ENABLE.getStatus()); | |
| 85 | 86 | return success(SeckillConfigConvert.INSTANCE.convertList1(list)); |
| 86 | 87 | } |
| 87 | 88 | |
| 88 | 89 | @GetMapping("/page") |
| 89 | - @Operation(summary = "获得秒杀活动分页") | |
| 90 | + @Operation(summary = "获得秒杀时间段分页") | |
| 90 | 91 | @PreAuthorize("@ss.hasPermission('promotion:seckill-config:query')") |
| 91 | 92 | public CommonResult<PageResult<SeckillConfigRespVO>> getSeckillActivityPage(@Valid SeckillConfigPageReqVO pageVO) { |
| 92 | 93 | PageResult<SeckillConfigDO> pageResult = seckillConfigService.getSeckillConfigPage(pageVO); | ... | ... |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/bargain/AppBargainActivityController.java
| ... | ... | @@ -35,7 +35,7 @@ public class AppBargainActivityController { |
| 35 | 35 | activity1.setId(1L); |
| 36 | 36 | activity1.setName("618 大砍价"); |
| 37 | 37 | activity1.setSpuId(2048L); |
| 38 | - activity1.setPicUrl("https://demo26.crmeb.net/uploads/attach/2021/11/15/a79f5d2ea6bf0c3c11b2127332dfe2df.jpg"); | |
| 38 | + activity1.setPicUrl("https://static.iocoder.cn/mall/a79f5d2ea6bf0c3c11b2127332dfe2df.jpg"); | |
| 39 | 39 | activity1.setMarketPrice(50); |
| 40 | 40 | activity1.setBargainPrice(100); |
| 41 | 41 | activity1.setStartTime(LocalDateTimeUtils.addTime(Duration.ofDays(-2))); |
| ... | ... | @@ -47,7 +47,7 @@ public class AppBargainActivityController { |
| 47 | 47 | activity2.setId(2L); |
| 48 | 48 | activity2.setName("双十一砍价"); |
| 49 | 49 | activity2.setSpuId(4096L); |
| 50 | - activity2.setPicUrl("https://thirdwx.qlogo.cn/mmopen/vi_32/Q0j4TwGTfTKXMYJOomfp7cebz3cIeb8sHk3GGSIJtWEgREe3j7J1WoAbTvIOicpcNdFkWAziatBSMod8b5RyS4CQ/132"); | |
| 50 | + activity2.setPicUrl("https://static.iocoder.cn/mall/132.jpeg"); | |
| 51 | 51 | activity2.setMarketPrice(100); |
| 52 | 52 | activity2.setBargainPrice(200); |
| 53 | 53 | activity2.setStartTime(LocalDateTimeUtils.addTime(Duration.ofDays(-2))); |
| ... | ... | @@ -69,7 +69,7 @@ public class AppBargainActivityController { |
| 69 | 69 | activity1.setId(1L); |
| 70 | 70 | activity1.setName("618 大砍价"); |
| 71 | 71 | activity1.setSpuId(2048L); |
| 72 | - activity1.setPicUrl("https://demo26.crmeb.net/uploads/attach/2021/11/15/a79f5d2ea6bf0c3c11b2127332dfe2df.jpg"); | |
| 72 | + activity1.setPicUrl("https://static.iocoder.cn/mall/a79f5d2ea6bf0c3c11b2127332dfe2df.jpg"); | |
| 73 | 73 | activity1.setMarketPrice(50); |
| 74 | 74 | activity1.setBargainPrice(100); |
| 75 | 75 | activityList.add(activity1); |
| ... | ... | @@ -78,7 +78,7 @@ public class AppBargainActivityController { |
| 78 | 78 | activity2.setId(2L); |
| 79 | 79 | activity2.setName("双十一砍价"); |
| 80 | 80 | activity2.setSpuId(4096L); |
| 81 | - activity2.setPicUrl("https://thirdwx.qlogo.cn/mmopen/vi_32/Q0j4TwGTfTKXMYJOomfp7cebz3cIeb8sHk3GGSIJtWEgREe3j7J1WoAbTvIOicpcNdFkWAziatBSMod8b5RyS4CQ/132"); | |
| 81 | + activity2.setPicUrl("https://static.iocoder.cn/mall/132.jpeg"); | |
| 82 | 82 | activity2.setMarketPrice(100); |
| 83 | 83 | activity2.setBargainPrice(200); |
| 84 | 84 | activityList.add(activity2); |
| ... | ... | @@ -94,7 +94,7 @@ public class AppBargainActivityController { |
| 94 | 94 | activity.setId(2L); |
| 95 | 95 | activity.setName("618 大砍价"); |
| 96 | 96 | activity.setSpuId(2048L); |
| 97 | - activity.setPicUrl("https://demo26.crmeb.net/uploads/attach/2021/11/15/a79f5d2ea6bf0c3c11b2127332dfe2df.jpg"); | |
| 97 | + activity.setPicUrl("https://static.iocoder.cn/mall/a79f5d2ea6bf0c3c11b2127332dfe2df.jpg"); | |
| 98 | 98 | activity.setMarketPrice(50); |
| 99 | 99 | activity.setBargainPrice(100); |
| 100 | 100 | activity.setStock(10); | ... | ... |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/bargain/AppBargainRecordController.java
| ... | ... | @@ -81,7 +81,7 @@ public class AppBargainRecordController { |
| 81 | 81 | record1.setPrice(200); |
| 82 | 82 | record1.setPayPrice(180); |
| 83 | 83 | record1.setStatus(1); |
| 84 | - record1.setPicUrl("https://demo26.crmeb.net/uploads/attach/2021/11/15/a79f5d2ea6bf0c3c11b2127332dfe2df.jpg"); | |
| 84 | + record1.setPicUrl("https://static.iocoder.cn/mall/a79f5d2ea6bf0c3c11b2127332dfe2df.jpg"); | |
| 85 | 85 | record1.setExpireTime(LocalDateTimeUtils.addTime(Duration.ofDays(2))); |
| 86 | 86 | page.getList().add(record1); |
| 87 | 87 | |
| ... | ... | @@ -96,7 +96,7 @@ public class AppBargainRecordController { |
| 96 | 96 | record2.setPrice(200); |
| 97 | 97 | record2.setPayPrice(280); |
| 98 | 98 | record2.setStatus(2); |
| 99 | - record2.setPicUrl("https://demo26.crmeb.net/uploads/attach/2021/11/15/a79f5d2ea6bf0c3c11b2127332dfe2df.jpg"); | |
| 99 | + record2.setPicUrl("https://static.iocoder.cn/mall/a79f5d2ea6bf0c3c11b2127332dfe2df.jpg"); | |
| 100 | 100 | record2.setExpireTime(LocalDateTimeUtils.addTime(Duration.ofDays(2))); |
| 101 | 101 | page.getList().add(record2); |
| 102 | 102 | |
| ... | ... | @@ -111,7 +111,7 @@ public class AppBargainRecordController { |
| 111 | 111 | record3.setPrice(200); |
| 112 | 112 | record3.setPayPrice(380); |
| 113 | 113 | record3.setStatus(2); |
| 114 | - record3.setPicUrl("https://demo26.crmeb.net/uploads/attach/2021/11/15/a79f5d2ea6bf0c3c11b2127332dfe2df.jpg"); | |
| 114 | + record3.setPicUrl("https://static.iocoder.cn/mall/a79f5d2ea6bf0c3c11b2127332dfe2df.jpg"); | |
| 115 | 115 | record3.setExpireTime(LocalDateTimeUtils.addTime(Duration.ofDays(2))); |
| 116 | 116 | record3.setOrderId(100L); |
| 117 | 117 | page.getList().add(record3); |
| ... | ... | @@ -127,7 +127,7 @@ public class AppBargainRecordController { |
| 127 | 127 | record4.setPrice(200); |
| 128 | 128 | record4.setPayPrice(380); |
| 129 | 129 | record4.setStatus(3); |
| 130 | - record4.setPicUrl("https://demo26.crmeb.net/uploads/attach/2021/11/15/a79f5d2ea6bf0c3c11b2127332dfe2df.jpg"); | |
| 130 | + record4.setPicUrl("https://static.iocoder.cn/mall/a79f5d2ea6bf0c3c11b2127332dfe2df.jpg"); | |
| 131 | 131 | record4.setExpireTime(LocalDateTimeUtils.addTime(Duration.ofDays(2))); |
| 132 | 132 | record4.setOrderId(100L); |
| 133 | 133 | page.getList().add(record4); | ... | ... |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/combination/AppCombinationActivityController.java
| ... | ... | @@ -38,7 +38,7 @@ public class AppCombinationActivityController { |
| 38 | 38 | activity1.setName("618 大拼团"); |
| 39 | 39 | activity1.setUserSize(3); |
| 40 | 40 | activity1.setSpuId(2048L); |
| 41 | - activity1.setPicUrl("https://demo26.crmeb.net/uploads/attach/2021/11/15/a79f5d2ea6bf0c3c11b2127332dfe2df.jpg"); | |
| 41 | + activity1.setPicUrl("https://static.iocoder.cn/mall/a79f5d2ea6bf0c3c11b2127332dfe2df.jpg"); | |
| 42 | 42 | activity1.setMarketPrice(50); |
| 43 | 43 | activity1.setCombinationPrice(100); |
| 44 | 44 | activityList.add(activity1); |
| ... | ... | @@ -48,7 +48,7 @@ public class AppCombinationActivityController { |
| 48 | 48 | activity2.setName("双十一拼团"); |
| 49 | 49 | activity2.setUserSize(5); |
| 50 | 50 | activity2.setSpuId(4096L); |
| 51 | - activity2.setPicUrl("https://thirdwx.qlogo.cn/mmopen/vi_32/Q0j4TwGTfTKXMYJOomfp7cebz3cIeb8sHk3GGSIJtWEgREe3j7J1WoAbTvIOicpcNdFkWAziatBSMod8b5RyS4CQ/132"); | |
| 51 | + activity2.setPicUrl("https://static.iocoder.cn/mall/132.jpeg"); | |
| 52 | 52 | activity2.setMarketPrice(100); |
| 53 | 53 | activity2.setCombinationPrice(200); |
| 54 | 54 | activityList.add(activity2); | ... | ... |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/combination/AppCombinationRecordController.java
| ... | ... | @@ -41,7 +41,7 @@ public class AppCombinationRecordController { |
| 41 | 41 | summary.getAvatars().add("https://thirdwx.qlogo.cn/mmopen/vi_32/ouwtwJycbic2JrCoZjETict0klxd1uRuicRneKk00ewMcCClxVcVHQT91Sh9MJGtwibf1fOicD1WpwSP4icJM6eQq1AA/132"); |
| 42 | 42 | summary.getAvatars().add("https://thirdwx.qlogo.cn/mmopen/vi_32/RpUrhwens58qc99OcGs993xL4M5QPOe05ekqF9Eia440kRicAlicicIdQWicHBmy2bzLgHzHguWEzHHxnIgeictL7bLA/132"); |
| 43 | 43 | summary.getAvatars().add("https://thirdwx.qlogo.cn/mmopen/vi_32/S4tfqmxc8GZGsKc1K4mnhpvtG16gtMrLnTQfDibhr7jJich9LRI5RQKZDoqEjZM3azMib5nic7F4ZXKMEgYyLO08KA/132"); |
| 44 | - summary.getAvatars().add("https://thirdwx.qlogo.cn/mmopen/vi_32/Q0j4TwGTfTKXMYJOomfp7cebz3cIeb8sHk3GGSIJtWEgREe3j7J1WoAbTvIOicpcNdFkWAziatBSMod8b5RyS4CQ/132"); | |
| 44 | + summary.getAvatars().add("https://static.iocoder.cn/mall/132.jpeg"); | |
| 45 | 45 | return success(summary); |
| 46 | 46 | } |
| 47 | 47 | |
| ... | ... | @@ -61,7 +61,7 @@ public class AppCombinationRecordController { |
| 61 | 61 | record.setExpireTime(new Date()); |
| 62 | 62 | record.setUserSize(10); |
| 63 | 63 | record.setUserCount(i); |
| 64 | - record.setPicUrl("https://demo26.crmeb.net/uploads/attach/2021/11/15/a79f5d2ea6bf0c3c11b2127332dfe2df.jpg"); | |
| 64 | + record.setPicUrl("https://static.iocoder.cn/mall/a79f5d2ea6bf0c3c11b2127332dfe2df.jpg"); | |
| 65 | 65 | record.setActivityId(1L); |
| 66 | 66 | record.setSpuName("活动:" + i); |
| 67 | 67 | list.add(record); |
| ... | ... | @@ -84,7 +84,7 @@ public class AppCombinationRecordController { |
| 84 | 84 | headRecord.setUserCount(3); |
| 85 | 85 | headRecord.setStatus(1); |
| 86 | 86 | headRecord.setActivityId(10L); |
| 87 | - headRecord.setPicUrl("https://demo26.crmeb.net/uploads/attach/2021/11/15/a79f5d2ea6bf0c3c11b2127332dfe2df.jpg"); | |
| 87 | + headRecord.setPicUrl("https://static.iocoder.cn/mall/a79f5d2ea6bf0c3c11b2127332dfe2df.jpg"); | |
| 88 | 88 | headRecord.setCombinationPrice(100); |
| 89 | 89 | detail.setHeadRecord(headRecord); |
| 90 | 90 | // 团员 | ... | ... |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/seckill/AppSeckillActivityController.java
| ... | ... | @@ -39,7 +39,7 @@ public class AppSeckillActivityController { |
| 39 | 39 | activity1.setId(1L); |
| 40 | 40 | activity1.setName("618 大秒杀"); |
| 41 | 41 | activity1.setSpuId(2048L); |
| 42 | - activity1.setPicUrl("https://demo26.crmeb.net/uploads/attach/2021/11/15/a79f5d2ea6bf0c3c11b2127332dfe2df.jpg"); | |
| 42 | + activity1.setPicUrl("https://static.iocoder.cn/mall/a79f5d2ea6bf0c3c11b2127332dfe2df.jpg"); | |
| 43 | 43 | activity1.setMarketPrice(50); |
| 44 | 44 | activity1.setSeckillPrice(100); |
| 45 | 45 | activityList.add(activity1); |
| ... | ... | @@ -48,7 +48,7 @@ public class AppSeckillActivityController { |
| 48 | 48 | activity2.setId(2L); |
| 49 | 49 | activity2.setName("双十一大秒杀"); |
| 50 | 50 | activity2.setSpuId(4096L); |
| 51 | - activity2.setPicUrl("https://thirdwx.qlogo.cn/mmopen/vi_32/Q0j4TwGTfTKXMYJOomfp7cebz3cIeb8sHk3GGSIJtWEgREe3j7J1WoAbTvIOicpcNdFkWAziatBSMod8b5RyS4CQ/132"); | |
| 51 | + activity2.setPicUrl("https://static.iocoder.cn/mall/132.jpeg"); | |
| 52 | 52 | activity2.setMarketPrice(100); |
| 53 | 53 | activity2.setSeckillPrice(200); |
| 54 | 54 | activityList.add(activity2); |
| ... | ... | @@ -65,7 +65,7 @@ public class AppSeckillActivityController { |
| 65 | 65 | activity1.setId(1L); |
| 66 | 66 | activity1.setName("618 大秒杀"); |
| 67 | 67 | activity1.setSpuId(2048L); |
| 68 | - activity1.setPicUrl("https://demo26.crmeb.net/uploads/attach/2021/11/15/a79f5d2ea6bf0c3c11b2127332dfe2df.jpg"); | |
| 68 | + activity1.setPicUrl("https://static.iocoder.cn/mall/a79f5d2ea6bf0c3c11b2127332dfe2df.jpg"); | |
| 69 | 69 | activity1.setMarketPrice(50); |
| 70 | 70 | activity1.setSeckillPrice(100); |
| 71 | 71 | activity1.setUnitName("个"); |
| ... | ... | @@ -77,7 +77,7 @@ public class AppSeckillActivityController { |
| 77 | 77 | activity2.setId(2L); |
| 78 | 78 | activity2.setName("双十一大秒杀"); |
| 79 | 79 | activity2.setSpuId(4096L); |
| 80 | - activity2.setPicUrl("https://thirdwx.qlogo.cn/mmopen/vi_32/Q0j4TwGTfTKXMYJOomfp7cebz3cIeb8sHk3GGSIJtWEgREe3j7J1WoAbTvIOicpcNdFkWAziatBSMod8b5RyS4CQ/132"); | |
| 80 | + activity2.setPicUrl("https://static.iocoder.cn/mall/132.jpeg"); | |
| 81 | 81 | activity2.setMarketPrice(100); |
| 82 | 82 | activity2.setSeckillPrice(200); |
| 83 | 83 | activity2.setUnitName("套"); | ... | ... |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/seckill/AppSeckillConfigController.java
| ... | ... | @@ -25,8 +25,8 @@ public class AppSeckillConfigController { |
| 25 | 25 | public CommonResult<List<AppSeckillConfigRespVO>> getSeckillConfigList() { |
| 26 | 26 | return success(Arrays.asList( |
| 27 | 27 | new AppSeckillConfigRespVO().setId(1L).setStartTime("00:00").setEndTime("09:59") |
| 28 | - .setSliderPicUrls(Arrays.asList("https://demo26.crmeb.net/uploads/attach/2021/11/15/a79f5d2ea6bf0c3c11b2127332dfe2df.jpg", | |
| 29 | - "https://thirdwx.qlogo.cn/mmopen/vi_32/Q0j4TwGTfTKXMYJOomfp7cebz3cIeb8sHk3GGSIJtWEgREe3j7J1WoAbTvIOicpcNdFkWAziatBSMod8b5RyS4CQ/132")), | |
| 28 | + .setSliderPicUrls(Arrays.asList("https://static.iocoder.cn/mall/a79f5d2ea6bf0c3c11b2127332dfe2df.jpg", | |
| 29 | + "https://static.iocoder.cn/mall/132.jpeg")), | |
| 30 | 30 | new AppSeckillConfigRespVO().setId(2L).setStartTime("10:00").setEndTime("12:59"), |
| 31 | 31 | new AppSeckillConfigRespVO().setId(2L).setStartTime("13:00").setEndTime("22:59"), |
| 32 | 32 | new AppSeckillConfigRespVO().setId(2L).setStartTime("23:00").setEndTime("23:59") | ... | ... |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/seckill/seckillconfig/SeckillConfigMapper.java
| ... | ... | @@ -16,7 +16,7 @@ public interface SeckillConfigMapper extends BaseMapperX<SeckillConfigDO> { |
| 16 | 16 | return selectPage(reqVO, new LambdaQueryWrapperX<SeckillConfigDO>() |
| 17 | 17 | .likeIfPresent(SeckillConfigDO::getName, reqVO.getName()) |
| 18 | 18 | .eqIfPresent(SeckillConfigDO::getStatus, reqVO.getStatus()) |
| 19 | - .orderByDesc(SeckillConfigDO::getId)); | |
| 19 | + .orderByAsc(SeckillConfigDO::getStartTime)); | |
| 20 | 20 | } |
| 21 | 21 | |
| 22 | 22 | default List<SeckillConfigDO> selectListByStatus(Integer status) { | ... | ... |
yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java
| ... | ... | @@ -32,6 +32,7 @@ public interface ErrorCodeConstants { |
| 32 | 32 | ErrorCode ORDER_DELIVERY_FAIL_REFUND_STATUS_NOT_NONE = new ErrorCode(1011000021, "交易订单发货失败,订单已退款或部分退款"); |
| 33 | 33 | ErrorCode ORDER_DELIVERY_FAIL_COMBINATION_RECORD_STATUS_NOT_SUCCESS = new ErrorCode(1011000022, "交易订单发货失败,拼团未成功"); |
| 34 | 34 | ErrorCode ORDER_DELIVERY_FAIL_BARGAIN_RECORD_STATUS_NOT_SUCCESS = new ErrorCode(1011000023, "交易订单发货失败,砍价未成功"); |
| 35 | + ErrorCode ORDER_DELIVERY_FAIL_DELIVERY_TYPE_NOT_EXPRESS = new ErrorCode(1011000024, "交易订单发货失败,发货类型不是快递"); | |
| 35 | 36 | |
| 36 | 37 | // ========== After Sale 模块 1011000100 ========== |
| 37 | 38 | ErrorCode AFTER_SALE_NOT_FOUND = new ErrorCode(1011000100, "售后单不存在"); | ... | ... |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/TradeAfterSaleController.java
| ... | ... | @@ -7,13 +7,15 @@ import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; |
| 7 | 7 | import cn.iocoder.yudao.module.member.api.user.MemberUserApi; |
| 8 | 8 | import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; |
| 9 | 9 | import cn.iocoder.yudao.module.pay.api.notify.dto.PayRefundNotifyReqDTO; |
| 10 | -import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.TradeAfterSaleDisagreeReqVO; | |
| 11 | -import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.TradeAfterSalePageReqVO; | |
| 12 | -import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.TradeAfterSaleRefuseReqVO; | |
| 13 | -import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.TradeAfterSaleRespPageItemVO; | |
| 10 | +import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.*; | |
| 14 | 11 | import cn.iocoder.yudao.module.trade.convert.aftersale.TradeAfterSaleConvert; |
| 15 | 12 | import cn.iocoder.yudao.module.trade.dal.dataobject.aftersale.TradeAfterSaleDO; |
| 13 | +import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO; | |
| 14 | +import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO; | |
| 15 | +import cn.iocoder.yudao.module.trade.framework.aftersalelog.core.dto.TradeAfterSaleLogRespDTO; | |
| 16 | +import cn.iocoder.yudao.module.trade.framework.aftersalelog.core.service.AfterSaleLogService; | |
| 16 | 17 | import cn.iocoder.yudao.module.trade.service.aftersale.TradeAfterSaleService; |
| 18 | +import cn.iocoder.yudao.module.trade.service.order.TradeOrderQueryService; | |
| 17 | 19 | import io.swagger.v3.oas.annotations.Operation; |
| 18 | 20 | import io.swagger.v3.oas.annotations.Parameter; |
| 19 | 21 | import io.swagger.v3.oas.annotations.tags.Tag; |
| ... | ... | @@ -25,6 +27,7 @@ import org.springframework.web.bind.annotation.*; |
| 25 | 27 | import javax.annotation.Resource; |
| 26 | 28 | import javax.annotation.security.PermitAll; |
| 27 | 29 | import javax.validation.Valid; |
| 30 | +import java.util.List; | |
| 28 | 31 | import java.util.Map; |
| 29 | 32 | |
| 30 | 33 | import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; |
| ... | ... | @@ -41,7 +44,10 @@ public class TradeAfterSaleController { |
| 41 | 44 | |
| 42 | 45 | @Resource |
| 43 | 46 | private TradeAfterSaleService afterSaleService; |
| 44 | - | |
| 47 | + @Resource | |
| 48 | + private TradeOrderQueryService tradeOrderQueryService; | |
| 49 | + @Resource | |
| 50 | + private AfterSaleLogService afterSaleLogService; | |
| 45 | 51 | @Resource |
| 46 | 52 | private MemberUserApi memberUserApi; |
| 47 | 53 | |
| ... | ... | @@ -61,6 +67,24 @@ public class TradeAfterSaleController { |
| 61 | 67 | return success(TradeAfterSaleConvert.INSTANCE.convertPage(pageResult, memberUsers)); |
| 62 | 68 | } |
| 63 | 69 | |
| 70 | + @GetMapping("/get-detail") | |
| 71 | + @Operation(summary = "获得售后订单详情") | |
| 72 | + @Parameter(name = "id", description = "售后编号", required = true, example = "1") | |
| 73 | + @PreAuthorize("@ss.hasPermission('trade:after-sale:query')") | |
| 74 | + public CommonResult<TradeAfterSaleDetailRespVO> getOrderDetail(@RequestParam("id") Long id) { | |
| 75 | + // 查询订单 | |
| 76 | + TradeAfterSaleDO afterSale = afterSaleService.getAfterSale(id); | |
| 77 | + // 查询订单 | |
| 78 | + TradeOrderDO order = tradeOrderQueryService.getOrder(afterSale.getOrderId()); | |
| 79 | + // 查询订单项 | |
| 80 | + List<TradeOrderItemDO> orderItems = tradeOrderQueryService.getOrderItemListByOrderId(id); | |
| 81 | + // 拼接数据 | |
| 82 | + MemberUserRespDTO user = memberUserApi.getUser(afterSale.getUserId()); | |
| 83 | + // 获取售后日志 | |
| 84 | + List<TradeAfterSaleLogRespDTO> logs = afterSaleLogService.getLog(afterSale.getId()); | |
| 85 | + return success(TradeAfterSaleConvert.INSTANCE.convert(afterSale, order, orderItems, user, logs)); | |
| 86 | + } | |
| 87 | + | |
| 64 | 88 | @PutMapping("/agree") |
| 65 | 89 | @Operation(summary = "同意售后") |
| 66 | 90 | @Parameter(name = "id", description = "售后编号", required = true, example = "1") |
| ... | ... | @@ -88,7 +112,7 @@ public class TradeAfterSaleController { |
| 88 | 112 | } |
| 89 | 113 | |
| 90 | 114 | @PutMapping("/refuse") |
| 91 | - @Operation(summary = "确认收货") | |
| 115 | + @Operation(summary = "拒绝收货") | |
| 92 | 116 | @Parameter(name = "id", description = "售后编号", required = true, example = "1") |
| 93 | 117 | @PreAuthorize("@ss.hasPermission('trade:after-sale:receive')") |
| 94 | 118 | public CommonResult<Boolean> refuseAfterSale(TradeAfterSaleRefuseReqVO refuseReqVO) { | ... | ... |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/vo/TradeAfterSaleDetailRespVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.log.TradeAfterSaleLogRespVO; | |
| 4 | +import cn.iocoder.yudao.module.trade.controller.admin.base.member.user.MemberUserRespVO; | |
| 5 | +import cn.iocoder.yudao.module.trade.controller.admin.base.product.property.ProductPropertyValueDetailRespVO; | |
| 6 | +import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderBaseVO; | |
| 7 | +import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderItemBaseVO; | |
| 8 | +import io.swagger.v3.oas.annotations.media.Schema; | |
| 9 | +import lombok.Data; | |
| 10 | + | |
| 11 | +import java.util.List; | |
| 12 | + | |
| 13 | +@Schema(description = "管理后台 - 售后订单的详情 Response VO") | |
| 14 | +@Data | |
| 15 | +public class TradeAfterSaleDetailRespVO extends TradeAfterSaleBaseVO { | |
| 16 | + | |
| 17 | + @Schema(description = "售后编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") | |
| 18 | + private Long id; | |
| 19 | + | |
| 20 | + /** | |
| 21 | + * 订单项列表 | |
| 22 | + */ | |
| 23 | + private List<Item> items; | |
| 24 | + | |
| 25 | + /** | |
| 26 | + * 订单基本信息 | |
| 27 | + */ | |
| 28 | + private TradeOrderBaseVO order; | |
| 29 | + | |
| 30 | + /** | |
| 31 | + * 用户信息 | |
| 32 | + */ | |
| 33 | + private MemberUserRespVO user; | |
| 34 | + | |
| 35 | + /** | |
| 36 | + * 售后日志 | |
| 37 | + */ | |
| 38 | + private List<TradeAfterSaleLogRespVO> afterSaleLog; | |
| 39 | + | |
| 40 | + @Schema(description = "管理后台 - 交易订单的详情的订单项目") | |
| 41 | + @Data | |
| 42 | + public static class Item extends TradeOrderItemBaseVO { | |
| 43 | + | |
| 44 | + /** | |
| 45 | + * 属性数组 | |
| 46 | + */ | |
| 47 | + private List<ProductPropertyValueDetailRespVO> properties; | |
| 48 | + | |
| 49 | + } | |
| 50 | + | |
| 51 | +} | ... | ... |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/DeliveryPickUpStoreController.java
| ... | ... | @@ -64,9 +64,10 @@ public class DeliveryPickUpStoreController { |
| 64 | 64 | } |
| 65 | 65 | |
| 66 | 66 | @GetMapping("/list-all-simple") |
| 67 | - @Operation(summary = "获取快递公司精简信息列表") | |
| 67 | + @Operation(summary = "获得自提门店精简信息列表") | |
| 68 | 68 | public CommonResult<List<DeliveryPickUpStoreSimpleRespVO>> getSimpleDeliveryPickUpStoreList() { |
| 69 | - List<DeliveryPickUpStoreDO> list = deliveryPickUpStoreService.getDeliveryPickUpStoreListByStatus(CommonStatusEnum.ENABLE.getStatus()); | |
| 69 | + List<DeliveryPickUpStoreDO> list = deliveryPickUpStoreService.getDeliveryPickUpStoreListByStatus( | |
| 70 | + CommonStatusEnum.ENABLE.getStatus()); | |
| 70 | 71 | return success(DeliveryPickUpStoreConvert.INSTANCE.convertList1(list)); |
| 71 | 72 | } |
| 72 | 73 | ... | ... |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/pickup/DeliveryPickUpStoreSimpleRespVO.java
| ... | ... | @@ -23,7 +23,8 @@ public class DeliveryPickUpStoreSimpleRespVO { |
| 23 | 23 | @Schema(description = "区域编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "18733") |
| 24 | 24 | private Integer areaId; |
| 25 | 25 | |
| 26 | - // TODO @puhui999:要把 areaName 也返回哈 | |
| 26 | + @Schema(description = "区域名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "xx市") | |
| 27 | + private String areaName; | |
| 27 | 28 | |
| 28 | 29 | @Schema(description = "门店详细地址", requiredMode = Schema.RequiredMode.REQUIRED, example = "复旦大学路 188 号") |
| 29 | 30 | private String detailAddress; | ... | ... |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/TradeOrderController.java
| ... | ... | @@ -85,8 +85,7 @@ public class TradeOrderController { |
| 85 | 85 | tradeOrderQueryService.getExpressTrackList(id, getLoginUserId()))); |
| 86 | 86 | } |
| 87 | 87 | |
| 88 | - // TODO @puhui999:put 请求哈 | |
| 89 | - @PostMapping("/delivery") | |
| 88 | + @PutMapping("/delivery") | |
| 90 | 89 | @Operation(summary = "订单发货") |
| 91 | 90 | @PreAuthorize("@ss.hasPermission('trade:order:update')") |
| 92 | 91 | public CommonResult<Boolean> deliveryOrder(@RequestBody TradeOrderDeliveryReqVO deliveryReqVO) { |
| ... | ... | @@ -94,8 +93,7 @@ public class TradeOrderController { |
| 94 | 93 | return success(true); |
| 95 | 94 | } |
| 96 | 95 | |
| 97 | - // TODO @puhui999:put 请求哈,update-remark; | |
| 98 | - @PostMapping("/remark") | |
| 96 | + @PutMapping("/update-remark") | |
| 99 | 97 | @Operation(summary = "订单备注") |
| 100 | 98 | @PreAuthorize("@ss.hasPermission('trade:order:update')") |
| 101 | 99 | public CommonResult<Boolean> updateOrderRemark(@RequestBody TradeOrderRemarkReqVO reqVO) { |
| ... | ... | @@ -103,8 +101,7 @@ public class TradeOrderController { |
| 103 | 101 | return success(true); |
| 104 | 102 | } |
| 105 | 103 | |
| 106 | - // TODO @puhui999:put 请求哈,update-price; | |
| 107 | - @PostMapping("/adjust-price") | |
| 104 | + @PutMapping("/update-price") | |
| 108 | 105 | @Operation(summary = "订单调价") |
| 109 | 106 | @PreAuthorize("@ss.hasPermission('trade:order:update')") |
| 110 | 107 | public CommonResult<Boolean> updateOrderPrice(@RequestBody TradeOrderUpdatePriceReqVO reqVO) { |
| ... | ... | @@ -112,8 +109,7 @@ public class TradeOrderController { |
| 112 | 109 | return success(true); |
| 113 | 110 | } |
| 114 | 111 | |
| 115 | - // TODO @puhui999:put 请求哈,update-address; | |
| 116 | - @PostMapping("/adjust-address") | |
| 112 | + @PutMapping("/update-address") | |
| 117 | 113 | @Operation(summary = "修改订单收货地址") |
| 118 | 114 | @PreAuthorize("@ss.hasPermission('trade:order:update')") |
| 119 | 115 | public CommonResult<Boolean> updateOrderAddress(@RequestBody TradeOrderUpdateAddressReqVO reqVO) { | ... | ... |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/aftersale/AppTradeAfterSaleController.java
| ... | ... | @@ -8,8 +8,10 @@ import cn.iocoder.yudao.module.trade.controller.app.aftersale.vo.AppTradeAfterSa |
| 8 | 8 | import cn.iocoder.yudao.module.trade.controller.app.aftersale.vo.AppTradeAfterSaleRespVO; |
| 9 | 9 | import cn.iocoder.yudao.module.trade.convert.aftersale.TradeAfterSaleConvert; |
| 10 | 10 | import cn.iocoder.yudao.module.trade.enums.aftersale.AfterSaleOperateTypeEnum; |
| 11 | +import cn.iocoder.yudao.module.trade.enums.aftersale.TradeAfterSaleStatusEnum; | |
| 11 | 12 | import cn.iocoder.yudao.module.trade.enums.aftersale.TradeAfterSaleWayEnum; |
| 12 | 13 | import cn.iocoder.yudao.module.trade.framework.aftersalelog.core.annotations.AfterSaleLog; |
| 14 | +import cn.iocoder.yudao.module.trade.framework.aftersalelog.core.util.AfterSaleLogUtils; | |
| 13 | 15 | import cn.iocoder.yudao.module.trade.service.aftersale.TradeAfterSaleService; |
| 14 | 16 | import io.swagger.v3.oas.annotations.Operation; |
| 15 | 17 | import io.swagger.v3.oas.annotations.Parameter; |
| ... | ... | @@ -71,6 +73,8 @@ public class AppTradeAfterSaleController { |
| 71 | 73 | @Operation(summary = "申请售后") |
| 72 | 74 | @AfterSaleLog(id = "#info.data", content = "'申请售后:售后编号['+#info.data+'],订单编号['+#createReqVO.orderItemId+'], '", operateType = AfterSaleOperateTypeEnum.APPLY) |
| 73 | 75 | public CommonResult<Long> createAfterSale(@RequestBody AppTradeAfterSaleCreateReqVO createReqVO) { |
| 76 | + AfterSaleLogUtils.setBeforeStatus(0); | |
| 77 | + AfterSaleLogUtils.setAfterStatus(TradeAfterSaleStatusEnum.APPLY.getStatus()); | |
| 74 | 78 | return success(afterSaleService.createAfterSale(getLoginUserId(), createReqVO)); |
| 75 | 79 | } |
| 76 | 80 | ... | ... |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/TradeCartController.http renamed to yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/AppCartController.http
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/TradeCartController.java renamed to yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/AppCartController.java
| ... | ... | @@ -2,11 +2,8 @@ package cn.iocoder.yudao.module.trade.controller.app.cart; |
| 2 | 2 | |
| 3 | 3 | import cn.iocoder.yudao.framework.common.pojo.CommonResult; |
| 4 | 4 | import cn.iocoder.yudao.framework.security.core.annotations.PreAuthenticated; |
| 5 | -import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartAddReqVO; | |
| 6 | -import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartListRespVO; | |
| 7 | -import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartResetReqVO; | |
| 8 | -import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartUpdateReqVO; | |
| 9 | -import cn.iocoder.yudao.module.trade.service.cart.TradeCartService; | |
| 5 | +import cn.iocoder.yudao.module.trade.controller.app.cart.vo.*; | |
| 6 | +import cn.iocoder.yudao.module.trade.service.cart.CartService; | |
| 10 | 7 | import io.swagger.v3.oas.annotations.Operation; |
| 11 | 8 | import io.swagger.v3.oas.annotations.Parameter; |
| 12 | 9 | import io.swagger.v3.oas.annotations.tags.Tag; |
| ... | ... | @@ -18,7 +15,6 @@ import org.springframework.web.bind.annotation.*; |
| 18 | 15 | import javax.annotation.Resource; |
| 19 | 16 | import javax.validation.Valid; |
| 20 | 17 | import java.util.List; |
| 21 | -import java.util.Map; | |
| 22 | 18 | |
| 23 | 19 | import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; |
| 24 | 20 | import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; |
| ... | ... | @@ -29,30 +25,38 @@ import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUti |
| 29 | 25 | @RequiredArgsConstructor |
| 30 | 26 | @Validated |
| 31 | 27 | @Slf4j |
| 32 | -public class TradeCartController { | |
| 28 | +public class AppCartController { | |
| 33 | 29 | |
| 34 | 30 | @Resource |
| 35 | - private TradeCartService cartService; | |
| 31 | + private CartService cartService; | |
| 36 | 32 | |
| 37 | 33 | @PostMapping("/add") |
| 38 | 34 | @Operation(summary = "添加购物车商品") |
| 39 | 35 | @PreAuthenticated |
| 40 | - public CommonResult<Long> addCart(@Valid @RequestBody AppTradeCartAddReqVO addCountReqVO) { | |
| 36 | + public CommonResult<Long> addCart(@Valid @RequestBody AppCartAddReqVO addCountReqVO) { | |
| 41 | 37 | return success(cartService.addCart(getLoginUserId(), addCountReqVO)); |
| 42 | 38 | } |
| 43 | 39 | |
| 44 | - @PutMapping("/update") | |
| 45 | - @Operation(summary = "更新购物车商品") | |
| 40 | + @PutMapping("/update-count") | |
| 41 | + @Operation(summary = "更新购物车商品数量") | |
| 46 | 42 | @PreAuthenticated |
| 47 | - public CommonResult<Boolean> updateCart(@Valid @RequestBody AppTradeCartUpdateReqVO updateReqVO) { | |
| 48 | - cartService.updateCart(getLoginUserId(), updateReqVO); | |
| 43 | + public CommonResult<Boolean> updateCartCount(@Valid @RequestBody AppCartUpdateCountReqVO updateReqVO) { | |
| 44 | + cartService.updateCartCount(getLoginUserId(), updateReqVO); | |
| 45 | + return success(true); | |
| 46 | + } | |
| 47 | + | |
| 48 | + @PutMapping("/update-selected") | |
| 49 | + @Operation(summary = "更新购物车商品选中") | |
| 50 | + @PreAuthenticated | |
| 51 | + public CommonResult<Boolean> updateCartSelected(@Valid @RequestBody AppCartUpdateSelectedReqVO updateReqVO) { | |
| 52 | + cartService.updateCartSelected(getLoginUserId(), updateReqVO); | |
| 49 | 53 | return success(true); |
| 50 | 54 | } |
| 51 | 55 | |
| 52 | 56 | @PutMapping("/reset") |
| 53 | 57 | @Operation(summary = "重置购物车商品") |
| 54 | 58 | @PreAuthenticated |
| 55 | - public CommonResult<Boolean> resetCart(@Valid @RequestBody AppTradeCartResetReqVO updateReqVO) { | |
| 59 | + public CommonResult<Boolean> resetCart(@Valid @RequestBody AppCartResetReqVO updateReqVO) { | |
| 56 | 60 | cartService.resetCart(getLoginUserId(), updateReqVO); |
| 57 | 61 | return success(true); |
| 58 | 62 | } |
| ... | ... | @@ -73,17 +77,10 @@ public class TradeCartController { |
| 73 | 77 | return success(cartService.getCartCount(getLoginUserId())); |
| 74 | 78 | } |
| 75 | 79 | |
| 76 | - @GetMapping("get-count-map") | |
| 77 | - @Operation(summary = "查询用户在购物车中的商品 SPU 数量 Map") | |
| 78 | - @PreAuthenticated | |
| 79 | - public CommonResult<Map<Long, Integer>> getCartCountMap() { | |
| 80 | - return success(cartService.getCartCountMap(getLoginUserId())); | |
| 81 | - } | |
| 82 | - | |
| 83 | 80 | @GetMapping("/list") |
| 84 | 81 | @Operation(summary = "查询用户的购物车列表") |
| 85 | 82 | @PreAuthenticated |
| 86 | - public CommonResult<AppTradeCartListRespVO> getCartList() { | |
| 83 | + public CommonResult<AppCartListRespVO> getCartList() { | |
| 87 | 84 | return success(cartService.getCartList(getLoginUserId())); |
| 88 | 85 | } |
| 89 | 86 | ... | ... |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppTradeCartAddReqVO.java renamed to yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppCartAddReqVO.java
| ... | ... | @@ -7,7 +7,7 @@ import javax.validation.constraints.NotNull; |
| 7 | 7 | |
| 8 | 8 | @Schema(description = "用户 App - 购物车添加购物项 Request VO") |
| 9 | 9 | @Data |
| 10 | -public class AppTradeCartAddReqVO { | |
| 10 | +public class AppCartAddReqVO { | |
| 11 | 11 | |
| 12 | 12 | @Schema(description = "商品 SKU 编号", requiredMode = Schema.RequiredMode.REQUIRED,example = "1024") |
| 13 | 13 | @NotNull(message = "商品 SKU 编号不能为空") |
| ... | ... | @@ -17,8 +17,4 @@ public class AppTradeCartAddReqVO { |
| 17 | 17 | @NotNull(message = "数量不能为空") |
| 18 | 18 | private Integer count; |
| 19 | 19 | |
| 20 | - @Schema(description = "是否添加到购物车", requiredMode = Schema.RequiredMode.REQUIRED, example = "true") | |
| 21 | - @NotNull(message = "是否添加购物车不能为空") | |
| 22 | - private Boolean addStatus; | |
| 23 | - | |
| 24 | 20 | } | ... | ... |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppTradeCartDetailRespVO.java renamed to yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppCartDetailRespVO.java
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppTradeCartListRespVO.java renamed to yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppCartListRespVO.java
| ... | ... | @@ -9,7 +9,7 @@ import java.util.List; |
| 9 | 9 | |
| 10 | 10 | @Schema(description = "用户 App - 用户的购物列表 Response VO") |
| 11 | 11 | @Data |
| 12 | -public class AppTradeCartListRespVO { | |
| 12 | +public class AppCartListRespVO { | |
| 13 | 13 | |
| 14 | 14 | /** |
| 15 | 15 | * 有效的购物项数组 |
| ... | ... | @@ -31,6 +31,9 @@ public class AppTradeCartListRespVO { |
| 31 | 31 | @Schema(description = "商品数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") |
| 32 | 32 | private Integer count; |
| 33 | 33 | |
| 34 | + @Schema(description = "是否选中", requiredMode = Schema.RequiredMode.REQUIRED, example = "true") | |
| 35 | + private Boolean selected; | |
| 36 | + | |
| 34 | 37 | /** |
| 35 | 38 | * 商品 SPU |
| 36 | 39 | */ | ... | ... |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppTradeCartResetReqVO.java renamed to yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppCartResetReqVO.java
| ... | ... | @@ -8,7 +8,7 @@ import javax.validation.constraints.NotNull; |
| 8 | 8 | |
| 9 | 9 | @Schema(description = "用户 App - 购物车重置 Request VO") |
| 10 | 10 | @Data |
| 11 | -public class AppTradeCartResetReqVO { | |
| 11 | +public class AppCartResetReqVO { | |
| 12 | 12 | |
| 13 | 13 | @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") |
| 14 | 14 | @NotNull(message = "编号不能为空") | ... | ... |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppTradeCartUpdateReqVO.java renamed to yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppCartUpdateCountReqVO.java
| ... | ... | @@ -6,9 +6,9 @@ import lombok.Data; |
| 6 | 6 | import javax.validation.constraints.Min; |
| 7 | 7 | import javax.validation.constraints.NotNull; |
| 8 | 8 | |
| 9 | -@Schema(description = "用户 App - 购物车更新 Request VO") | |
| 9 | +@Schema(description = "用户 App - 购物车更新数量 Request VO") | |
| 10 | 10 | @Data |
| 11 | -public class AppTradeCartUpdateReqVO { | |
| 11 | +public class AppCartUpdateCountReqVO { | |
| 12 | 12 | |
| 13 | 13 | @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") |
| 14 | 14 | @NotNull(message = "编号不能为空") | ... | ... |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppTradeCartItemUpdateSelectedReqVO.java renamed to yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppCartUpdateSelectedReqVO.java
| ... | ... | @@ -8,11 +8,11 @@ import java.util.Collection; |
| 8 | 8 | |
| 9 | 9 | @Schema(description = "用户 App - 购物车更新是否选中 Request VO") |
| 10 | 10 | @Data |
| 11 | -public class AppTradeCartItemUpdateSelectedReqVO { | |
| 11 | +public class AppCartUpdateSelectedReqVO { | |
| 12 | 12 | |
| 13 | - @Schema(description = "商品 SKU 编号列表", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024,2048") | |
| 14 | - @NotNull(message = "商品 SKU 编号列表不能为空") | |
| 15 | - private Collection<Long> skuIds; | |
| 13 | + @Schema(description = "编号列表", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024,2048") | |
| 14 | + @NotNull(message = "编号列表不能为空") | |
| 15 | + private Collection<Long> ids; | |
| 16 | 16 | |
| 17 | 17 | @Schema(description = "是否选中", requiredMode = Schema.RequiredMode.REQUIRED, example = "true") |
| 18 | 18 | @NotNull(message = "是否选中不能为空") | ... | ... |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java
| ... | ... | @@ -5,7 +5,6 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 5 | 5 | import cn.iocoder.yudao.framework.security.core.annotations.PreAuthenticated; |
| 6 | 6 | import cn.iocoder.yudao.module.pay.api.notify.dto.PayOrderNotifyReqDTO; |
| 7 | 7 | import cn.iocoder.yudao.module.product.api.property.ProductPropertyValueApi; |
| 8 | -import cn.iocoder.yudao.module.product.api.property.dto.ProductPropertyValueDetailRespDTO; | |
| 9 | 8 | import cn.iocoder.yudao.module.trade.controller.app.order.vo.*; |
| 10 | 9 | import cn.iocoder.yudao.module.trade.controller.app.order.vo.item.AppTradeOrderItemCommentCreateReqVO; |
| 11 | 10 | import cn.iocoder.yudao.module.trade.controller.app.order.vo.item.AppTradeOrderItemRespVO; |
| ... | ... | @@ -91,15 +90,11 @@ public class AppTradeOrderController { |
| 91 | 90 | |
| 92 | 91 | // 查询订单项 |
| 93 | 92 | List<TradeOrderItemDO> orderItems = tradeOrderQueryService.getOrderItemListByOrderId(order.getId()); |
| 94 | - // 查询商品属性 | |
| 95 | - List<ProductPropertyValueDetailRespDTO> propertyValueDetails = productPropertyValueApi | |
| 96 | - .getPropertyValueDetailList(TradeOrderConvert.INSTANCE.convertPropertyValueIds(orderItems)); | |
| 97 | 93 | // 查询物流公司 |
| 98 | 94 | DeliveryExpressDO express = order.getLogisticsId() != null && order.getLogisticsId() > 0 ? |
| 99 | 95 | deliveryExpressService.getDeliveryExpress(order.getLogisticsId()) : null; |
| 100 | 96 | // 最终组合 |
| 101 | - return success(TradeOrderConvert.INSTANCE.convert02(order, orderItems, | |
| 102 | - propertyValueDetails, tradeOrderProperties, express)); | |
| 97 | + return success(TradeOrderConvert.INSTANCE.convert02(order, orderItems, tradeOrderProperties, express)); | |
| 103 | 98 | } |
| 104 | 99 | |
| 105 | 100 | @GetMapping("/get-express-track-list") | ... | ... |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/aftersale/TradeAfterSaleConvert.java
| ... | ... | @@ -4,19 +4,26 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 4 | 4 | import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; |
| 5 | 5 | import cn.iocoder.yudao.module.pay.api.refund.dto.PayRefundCreateReqDTO; |
| 6 | 6 | import cn.iocoder.yudao.module.product.api.property.dto.ProductPropertyValueDetailRespDTO; |
| 7 | +import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.TradeAfterSaleDetailRespVO; | |
| 7 | 8 | import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.TradeAfterSaleRespPageItemVO; |
| 9 | +import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.log.TradeAfterSaleLogRespVO; | |
| 8 | 10 | import cn.iocoder.yudao.module.trade.controller.admin.base.member.user.MemberUserRespVO; |
| 9 | 11 | import cn.iocoder.yudao.module.trade.controller.admin.base.product.property.ProductPropertyValueDetailRespVO; |
| 12 | +import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderBaseVO; | |
| 10 | 13 | import cn.iocoder.yudao.module.trade.controller.app.aftersale.vo.AppTradeAfterSaleCreateReqVO; |
| 11 | 14 | import cn.iocoder.yudao.module.trade.controller.app.aftersale.vo.AppTradeAfterSaleRespVO; |
| 12 | 15 | import cn.iocoder.yudao.module.trade.dal.dataobject.aftersale.TradeAfterSaleDO; |
| 16 | +import cn.iocoder.yudao.module.trade.dal.dataobject.aftersale.TradeAfterSaleLogDO; | |
| 17 | +import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO; | |
| 13 | 18 | import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO; |
| 19 | +import cn.iocoder.yudao.module.trade.framework.aftersalelog.core.dto.TradeAfterSaleLogRespDTO; | |
| 14 | 20 | import cn.iocoder.yudao.module.trade.framework.order.config.TradeOrderProperties; |
| 15 | 21 | import org.mapstruct.Mapper; |
| 16 | 22 | import org.mapstruct.Mapping; |
| 17 | 23 | import org.mapstruct.Mappings; |
| 18 | 24 | import org.mapstruct.factory.Mappers; |
| 19 | 25 | |
| 26 | +import java.util.List; | |
| 20 | 27 | import java.util.Map; |
| 21 | 28 | |
| 22 | 29 | @Mapper |
| ... | ... | @@ -61,4 +68,20 @@ public interface TradeAfterSaleConvert { |
| 61 | 68 | |
| 62 | 69 | PageResult<AppTradeAfterSaleRespVO> convertPage02(PageResult<TradeAfterSaleDO> page); |
| 63 | 70 | |
| 71 | + List<TradeAfterSaleLogRespDTO> convertList(List<TradeAfterSaleLogDO> list); | |
| 72 | + | |
| 73 | + default TradeAfterSaleDetailRespVO convert(TradeAfterSaleDO afterSale, TradeOrderDO order, List<TradeOrderItemDO> orderItems, | |
| 74 | + MemberUserRespDTO user, List<TradeAfterSaleLogRespDTO> logs) { | |
| 75 | + TradeAfterSaleDetailRespVO respVO = convert(afterSale, orderItems, convertList1(logs)); | |
| 76 | + // 处理用户信息 | |
| 77 | + respVO.setUser(convert(user)); | |
| 78 | + // 处理订单信息 | |
| 79 | + respVO.setOrder(convert(order)); | |
| 80 | + return respVO; | |
| 81 | + } | |
| 82 | + List<TradeAfterSaleLogRespVO> convertList1(List<TradeAfterSaleLogRespDTO> list); | |
| 83 | + @Mapping(target = "id", source = "afterSale.id") | |
| 84 | + TradeAfterSaleDetailRespVO convert(TradeAfterSaleDO afterSale, List<TradeOrderItemDO> orderItems, List<TradeAfterSaleLogRespVO> logs); | |
| 85 | + TradeOrderBaseVO convert(TradeOrderDO order); | |
| 86 | + | |
| 64 | 87 | } | ... | ... |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/cart/TradeCartConvert.java
| ... | ... | @@ -5,8 +5,8 @@ import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO; |
| 5 | 5 | import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum; |
| 6 | 6 | import cn.iocoder.yudao.module.trade.controller.app.base.sku.AppProductSkuBaseRespVO; |
| 7 | 7 | import cn.iocoder.yudao.module.trade.controller.app.base.spu.AppProductSpuBaseRespVO; |
| 8 | -import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartListRespVO; | |
| 9 | -import cn.iocoder.yudao.module.trade.dal.dataobject.cart.TradeCartDO; | |
| 8 | +import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppCartListRespVO; | |
| 9 | +import cn.iocoder.yudao.module.trade.dal.dataobject.cart.CartDO; | |
| 10 | 10 | import org.mapstruct.Mapper; |
| 11 | 11 | import org.mapstruct.factory.Mappers; |
| 12 | 12 | |
| ... | ... | @@ -21,16 +21,16 @@ public interface TradeCartConvert { |
| 21 | 21 | |
| 22 | 22 | TradeCartConvert INSTANCE = Mappers.getMapper(TradeCartConvert.class); |
| 23 | 23 | |
| 24 | - default AppTradeCartListRespVO convertList(List<TradeCartDO> carts, | |
| 25 | - List<ProductSpuRespDTO> spus, List<ProductSkuRespDTO> skus) { | |
| 24 | + default AppCartListRespVO convertList(List<CartDO> carts, | |
| 25 | + List<ProductSpuRespDTO> spus, List<ProductSkuRespDTO> skus) { | |
| 26 | 26 | Map<Long, ProductSpuRespDTO> spuMap = convertMap(spus, ProductSpuRespDTO::getId); |
| 27 | 27 | Map<Long, ProductSkuRespDTO> skuMap = convertMap(skus, ProductSkuRespDTO::getId); |
| 28 | 28 | // 遍历,开始转换 |
| 29 | - List<AppTradeCartListRespVO.Cart> validList = new ArrayList<>(carts.size()); | |
| 30 | - List<AppTradeCartListRespVO.Cart> invalidList = new ArrayList<>(); | |
| 29 | + List<AppCartListRespVO.Cart> validList = new ArrayList<>(carts.size()); | |
| 30 | + List<AppCartListRespVO.Cart> invalidList = new ArrayList<>(); | |
| 31 | 31 | carts.forEach(cart -> { |
| 32 | - AppTradeCartListRespVO.Cart cartVO = new AppTradeCartListRespVO.Cart(); | |
| 33 | - cartVO.setId(cart.getId()).setCount(cart.getCount()); | |
| 32 | + AppCartListRespVO.Cart cartVO = new AppCartListRespVO.Cart(); | |
| 33 | + cartVO.setId(cart.getId()).setCount(cart.getCount()).setSelected(cart.getSelected()); | |
| 34 | 34 | ProductSpuRespDTO spu = spuMap.get(cart.getSpuId()); |
| 35 | 35 | ProductSkuRespDTO sku = skuMap.get(cart.getSkuId()); |
| 36 | 36 | cartVO.setSpu(convert(spu)).setSku(convert(sku)); |
| ... | ... | @@ -38,13 +38,14 @@ public interface TradeCartConvert { |
| 38 | 38 | if (spu == null |
| 39 | 39 | || !ProductSpuStatusEnum.isEnable(spu.getStatus()) |
| 40 | 40 | || spu.getStock() <= 0) { |
| 41 | + cartVO.setSelected(false); // 强制设置成不可选中 | |
| 41 | 42 | invalidList.add(cartVO); |
| 42 | 43 | } else { |
| 43 | 44 | // 虽然 SKU 可能也会不存在,但是可以通过购物车重新选择 |
| 44 | 45 | validList.add(cartVO); |
| 45 | 46 | } |
| 46 | 47 | }); |
| 47 | - return new AppTradeCartListRespVO().setValidList(validList).setInvalidList(invalidList); | |
| 48 | + return new AppCartListRespVO().setValidList(validList).setInvalidList(invalidList); | |
| 48 | 49 | } |
| 49 | 50 | AppProductSpuBaseRespVO convert(ProductSpuRespDTO spu); |
| 50 | 51 | AppProductSkuBaseRespVO convert(ProductSkuRespDTO sku); | ... | ... |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/delivery/DeliveryPickUpStoreConvert.java
| ... | ... | @@ -8,6 +8,7 @@ import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.pickup.Deliver |
| 8 | 8 | import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.pickup.DeliveryPickUpStoreUpdateReqVO; |
| 9 | 9 | import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryPickUpStoreDO; |
| 10 | 10 | import org.mapstruct.Mapper; |
| 11 | +import org.mapstruct.Mapping; | |
| 11 | 12 | import org.mapstruct.Named; |
| 12 | 13 | import org.mapstruct.factory.Mappers; |
| 13 | 14 | |
| ... | ... | @@ -28,10 +29,13 @@ public interface DeliveryPickUpStoreConvert { |
| 28 | 29 | |
| 29 | 30 | PageResult<DeliveryPickUpStoreRespVO> convertPage(PageResult<DeliveryPickUpStoreDO> page); |
| 30 | 31 | |
| 31 | - @Named("convertAreaIdToName") | |
| 32 | - default String convertAreaIdToName(Integer areaId) { | |
| 32 | + List<DeliveryPickUpStoreSimpleRespVO> convertList1(List<DeliveryPickUpStoreDO> list); | |
| 33 | + @Mapping(source = "areaId", target = "areaName", qualifiedByName = "convertAreaIdToAreaName") | |
| 34 | + DeliveryPickUpStoreSimpleRespVO convert02(DeliveryPickUpStoreDO bean); | |
| 35 | + | |
| 36 | + @Named("convertAreaIdToAreaName") | |
| 37 | + default String convertAreaIdToAreaName(Integer areaId) { | |
| 33 | 38 | return AreaUtils.format(areaId); |
| 34 | 39 | } |
| 35 | 40 | |
| 36 | - List<DeliveryPickUpStoreSimpleRespVO> convertList1(List<DeliveryPickUpStoreDO> list); | |
| 37 | 41 | } | ... | ... |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java
| ... | ... | @@ -4,6 +4,7 @@ import cn.hutool.core.collection.CollUtil; |
| 4 | 4 | import cn.hutool.core.util.StrUtil; |
| 5 | 5 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 6 | 6 | import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; |
| 7 | +import cn.iocoder.yudao.framework.common.util.string.StrUtils; | |
| 7 | 8 | import cn.iocoder.yudao.framework.dict.core.util.DictFrameworkUtils; |
| 8 | 9 | import cn.iocoder.yudao.framework.ip.core.utils.AreaUtils; |
| 9 | 10 | import cn.iocoder.yudao.module.member.api.address.dto.AddressRespDTO; |
| ... | ... | @@ -22,7 +23,7 @@ import cn.iocoder.yudao.module.trade.controller.app.base.property.AppProductProp |
| 22 | 23 | import cn.iocoder.yudao.module.trade.controller.app.order.vo.*; |
| 23 | 24 | import cn.iocoder.yudao.module.trade.controller.app.order.vo.item.AppTradeOrderItemCommentCreateReqVO; |
| 24 | 25 | import cn.iocoder.yudao.module.trade.controller.app.order.vo.item.AppTradeOrderItemRespVO; |
| 25 | -import cn.iocoder.yudao.module.trade.dal.dataobject.cart.TradeCartDO; | |
| 26 | +import cn.iocoder.yudao.module.trade.dal.dataobject.cart.CartDO; | |
| 26 | 27 | import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressDO; |
| 27 | 28 | import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO; |
| 28 | 29 | import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO; |
| ... | ... | @@ -82,14 +83,16 @@ public interface TradeOrderConvert { |
| 82 | 83 | |
| 83 | 84 | TradeOrderItemDO convert(TradePriceCalculateRespBO.OrderItem item); |
| 84 | 85 | |
| 86 | + default ProductSkuUpdateStockReqDTO convert(List<TradeOrderItemDO> list) { | |
| 87 | + return new ProductSkuUpdateStockReqDTO(TradeOrderConvert.INSTANCE.convertList(list)); | |
| 88 | + } | |
| 89 | + List<ProductSkuUpdateStockReqDTO.Item> convertList(List<TradeOrderItemDO> list); | |
| 85 | 90 | @Mappings({ |
| 86 | 91 | @Mapping(source = "skuId", target = "id"), |
| 87 | 92 | @Mapping(source = "count", target = "incrCount"), |
| 88 | 93 | }) |
| 89 | 94 | ProductSkuUpdateStockReqDTO.Item convert(TradeOrderItemDO bean); |
| 90 | 95 | |
| 91 | - List<ProductSkuUpdateStockReqDTO.Item> convertList(List<TradeOrderItemDO> list); | |
| 92 | - | |
| 93 | 96 | default PayOrderCreateReqDTO convert(TradeOrderDO order, List<TradeOrderItemDO> orderItems, |
| 94 | 97 | TradePriceCalculateRespBO calculateRespBO, TradeOrderProperties orderProperties) { |
| 95 | 98 | PayOrderCreateReqDTO createReqDTO = new PayOrderCreateReqDTO() |
| ... | ... | @@ -97,9 +100,7 @@ public interface TradeOrderConvert { |
| 97 | 100 | // 商户相关字段 |
| 98 | 101 | createReqDTO.setMerchantOrderId(String.valueOf(order.getId())); |
| 99 | 102 | String subject = calculateRespBO.getItems().get(0).getSpuName(); |
| 100 | - if (calculateRespBO.getItems().size() > 1) { | |
| 101 | - subject += " 等多件"; | |
| 102 | - } | |
| 103 | + subject = StrUtils.maxLength(subject, PayOrderCreateReqDTO.SUBJECT_MAX_LENGTH); // 避免超过 32 位 | |
| 103 | 104 | createReqDTO.setSubject(subject); |
| 104 | 105 | createReqDTO.setBody(subject); // TODO 芋艿:临时写死 |
| 105 | 106 | // 订单相关字段 |
| ... | ... | @@ -107,16 +108,6 @@ public interface TradeOrderConvert { |
| 107 | 108 | return createReqDTO; |
| 108 | 109 | } |
| 109 | 110 | |
| 110 | - default Set<Long> convertPropertyValueIds(List<TradeOrderItemDO> list) { | |
| 111 | - if (CollUtil.isEmpty(list)) { | |
| 112 | - return new HashSet<>(); | |
| 113 | - } | |
| 114 | - return list.stream().filter(item -> item.getProperties() != null) | |
| 115 | - .flatMap(p -> p.getProperties().stream()) // 遍历多个 Property 属性 | |
| 116 | - .map(TradeOrderItemDO.Property::getValueId) // 将每个 Property 转换成对应的 propertyId,最后形成集合 | |
| 117 | - .collect(Collectors.toSet()); | |
| 118 | - } | |
| 119 | - | |
| 120 | 111 | // TODO 芋艿:可简化 |
| 121 | 112 | default PageResult<TradeOrderPageItemRespVO> convertPage(PageResult<TradeOrderDO> pageResult, |
| 122 | 113 | List<TradeOrderItemDO> orderItems, |
| ... | ... | @@ -170,31 +161,13 @@ public interface TradeOrderConvert { |
| 170 | 161 | |
| 171 | 162 | // TODO 芋艿:可简化 |
| 172 | 163 | default AppTradeOrderDetailRespVO convert02(TradeOrderDO order, List<TradeOrderItemDO> orderItems, |
| 173 | - List<ProductPropertyValueDetailRespDTO> propertyValueDetails, TradeOrderProperties tradeOrderProperties, | |
| 164 | + TradeOrderProperties tradeOrderProperties, | |
| 174 | 165 | DeliveryExpressDO express) { |
| 175 | 166 | AppTradeOrderDetailRespVO orderVO = convert3(order, orderItems); |
| 176 | 167 | orderVO.setPayExpireTime(addTime(tradeOrderProperties.getExpireTime())); |
| 177 | 168 | if (StrUtil.isNotEmpty(order.getPayChannelCode())) { |
| 178 | 169 | orderVO.setPayChannelName(DictFrameworkUtils.getDictDataLabel(DictTypeConstants.CHANNEL_CODE, order.getPayChannelCode())); |
| 179 | 170 | } |
| 180 | - // 处理商品属性 | |
| 181 | - Map<Long, ProductPropertyValueDetailRespDTO> propertyValueDetailMap = convertMap(propertyValueDetails, ProductPropertyValueDetailRespDTO::getValueId); | |
| 182 | - for (int i = 0; i < orderItems.size(); i++) { | |
| 183 | - List<TradeOrderItemDO.Property> properties = orderItems.get(i).getProperties(); | |
| 184 | - if (CollUtil.isEmpty(properties)) { | |
| 185 | - continue; | |
| 186 | - } | |
| 187 | - AppTradeOrderItemRespVO item = orderVO.getItems().get(i); | |
| 188 | - item.setProperties(new ArrayList<>(properties.size())); | |
| 189 | - // 遍历每个 properties,设置到 TradeOrderPageItemRespVO.Item 中 | |
| 190 | - properties.forEach(property -> { | |
| 191 | - ProductPropertyValueDetailRespDTO propertyValueDetail = propertyValueDetailMap.get(property.getValueId()); | |
| 192 | - if (propertyValueDetail == null) { | |
| 193 | - return; | |
| 194 | - } | |
| 195 | - item.getProperties().add(convert02(propertyValueDetail)); | |
| 196 | - }); | |
| 197 | - } | |
| 198 | 171 | // 处理收货地址 |
| 199 | 172 | orderVO.setReceiverAreaName(AreaUtils.format(order.getReceiverAreaId())); |
| 200 | 173 | if (express != null) { |
| ... | ... | @@ -221,12 +194,12 @@ public interface TradeOrderConvert { |
| 221 | 194 | ProductCommentCreateReqDTO convert04(AppTradeOrderItemCommentCreateReqVO createReqVO, TradeOrderItemDO tradeOrderItemDO); |
| 222 | 195 | |
| 223 | 196 | default TradePriceCalculateReqBO convert(Long userId, AppTradeOrderSettlementReqVO settlementReqVO, |
| 224 | - List<TradeCartDO> cartList) { | |
| 197 | + List<CartDO> cartList) { | |
| 225 | 198 | TradePriceCalculateReqBO reqBO = new TradePriceCalculateReqBO(); |
| 226 | 199 | reqBO.setUserId(userId).setCouponId(settlementReqVO.getCouponId()).setAddressId(settlementReqVO.getAddressId()) |
| 227 | 200 | .setItems(new ArrayList<>(settlementReqVO.getItems().size())); |
| 228 | 201 | // 商品项的构建 |
| 229 | - Map<Long, TradeCartDO> cartMap = convertMap(cartList, TradeCartDO::getId); | |
| 202 | + Map<Long, CartDO> cartMap = convertMap(cartList, CartDO::getId); | |
| 230 | 203 | for (AppTradeOrderSettlementReqVO.Item item : settlementReqVO.getItems()) { |
| 231 | 204 | // 情况一:skuId + count |
| 232 | 205 | if (item.getSkuId() != null) { |
| ... | ... | @@ -235,7 +208,7 @@ public interface TradeOrderConvert { |
| 235 | 208 | continue; |
| 236 | 209 | } |
| 237 | 210 | // 情况二:cartId |
| 238 | - TradeCartDO cart = cartMap.get(item.getCartId()); | |
| 211 | + CartDO cart = cartMap.get(item.getCartId()); | |
| 239 | 212 | if (cart == null) { |
| 240 | 213 | continue; |
| 241 | 214 | } | ... | ... |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/cart/TradeCartDO.java renamed to yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/cart/CartDO.java
| ... | ... | @@ -17,7 +17,7 @@ import lombok.experimental.Accessors; |
| 17 | 17 | @Data |
| 18 | 18 | @EqualsAndHashCode(callSuper = true) |
| 19 | 19 | @Accessors(chain = true) |
| 20 | -public class TradeCartDO extends BaseDO { | |
| 20 | +public class CartDO extends BaseDO { | |
| 21 | 21 | |
| 22 | 22 | // ========= 基础字段 BEGIN ========= |
| 23 | 23 | |
| ... | ... | @@ -33,27 +33,7 @@ public class TradeCartDO extends BaseDO { |
| 33 | 33 | */ |
| 34 | 34 | private Long userId; |
| 35 | 35 | |
| 36 | - /** | |
| 37 | - * 是否添加到购物车 | |
| 38 | - * | |
| 39 | - * false - 未添加:用户点击【立即购买】 | |
| 40 | - * true - 已添加:用户点击【添加购物车】 | |
| 41 | - * | |
| 42 | - * 为什么要设计这个字段? | |
| 43 | - * 配合 orderStatus 字段,可以知道有多少商品,用户点击了【立即购买】,最终多少【确认下单】 | |
| 44 | - */ | |
| 45 | - private Boolean addStatus; | |
| 46 | - /** | |
| 47 | - * 是否提交订单 | |
| 48 | - * | |
| 49 | - * false - 未下单:立即购买,或者添加到购物车,此时设置为 false | |
| 50 | - * true - 已下单:确认下单,此时设置为 true | |
| 51 | - */ | |
| 52 | - private Boolean orderStatus; | |
| 53 | - | |
| 54 | - // ========= 基础字段 END ========= | |
| 55 | - | |
| 56 | - // ========= 商品信息 BEGIN ========= | |
| 36 | + // ========= 商品信息 ========= | |
| 57 | 37 | |
| 58 | 38 | /** |
| 59 | 39 | * 商品 SPU 编号 |
| ... | ... | @@ -71,16 +51,9 @@ public class TradeCartDO extends BaseDO { |
| 71 | 51 | * 商品购买数量 |
| 72 | 52 | */ |
| 73 | 53 | private Integer count; |
| 74 | - | |
| 75 | - // ========= 商品信息 END ========= | |
| 76 | - | |
| 77 | - // ========= 优惠信息 BEGIN ========= | |
| 78 | - | |
| 79 | - // TODO 芋艿:combination_id 拼团 ID | |
| 80 | - // TODO 芋艿:seckill_id 秒杀产品 ID | |
| 81 | - // TODO 芋艿:bargain_id 砍价 ID | |
| 82 | - // TODO 芋艿:pinkId 团长拼团 ID | |
| 83 | - | |
| 84 | - // ========= 优惠信息 END ========= | |
| 54 | + /** | |
| 55 | + * 是否选中 | |
| 56 | + */ | |
| 57 | + private Boolean selected; | |
| 85 | 58 | |
| 86 | 59 | } | ... | ... |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderDO.java
| ... | ... | @@ -27,6 +27,11 @@ import java.time.LocalDateTime; |
| 27 | 27 | @AllArgsConstructor |
| 28 | 28 | public class TradeOrderDO extends BaseDO { |
| 29 | 29 | |
| 30 | + /** | |
| 31 | + * 发货物流公司编号 - 空(无需发货) | |
| 32 | + */ | |
| 33 | + public static final Long LOGISTICS_ID_NULL = 0L; | |
| 34 | + | |
| 30 | 35 | // ========== 订单基本信息 ========== |
| 31 | 36 | /** |
| 32 | 37 | * 订单编号,主键自增 | ... | ... |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderItemDO.java
| ... | ... | @@ -3,7 +3,7 @@ package cn.iocoder.yudao.module.trade.dal.dataobject.order; |
| 3 | 3 | import cn.iocoder.yudao.framework.common.util.json.JsonUtils; |
| 4 | 4 | import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; |
| 5 | 5 | import cn.iocoder.yudao.module.trade.dal.dataobject.aftersale.TradeAfterSaleDO; |
| 6 | -import cn.iocoder.yudao.module.trade.dal.dataobject.cart.TradeCartDO; | |
| 6 | +import cn.iocoder.yudao.module.trade.dal.dataobject.cart.CartDO; | |
| 7 | 7 | import cn.iocoder.yudao.module.trade.enums.order.TradeOrderItemAfterSaleStatusEnum; |
| 8 | 8 | import com.baomidou.mybatisplus.annotation.TableField; |
| 9 | 9 | import com.baomidou.mybatisplus.annotation.TableName; |
| ... | ... | @@ -46,7 +46,7 @@ public class TradeOrderItemDO extends BaseDO { |
| 46 | 46 | /** |
| 47 | 47 | * 购物车项编号 |
| 48 | 48 | * |
| 49 | - * 关联 {@link TradeCartDO#getId()} | |
| 49 | + * 关联 {@link CartDO#getId()} | |
| 50 | 50 | */ |
| 51 | 51 | private Long cartId; |
| 52 | 52 | ... | ... |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/cart/CartMapper.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.trade.dal.mysql.cart; | |
| 2 | + | |
| 3 | +import cn.hutool.core.collection.CollUtil; | |
| 4 | +import cn.hutool.core.map.MapUtil; | |
| 5 | +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; | |
| 6 | +import cn.iocoder.yudao.module.trade.dal.dataobject.cart.CartDO; | |
| 7 | +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; | |
| 8 | +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; | |
| 9 | +import org.apache.ibatis.annotations.Mapper; | |
| 10 | + | |
| 11 | +import java.util.Collection; | |
| 12 | +import java.util.List; | |
| 13 | +import java.util.Map; | |
| 14 | +import java.util.Set; | |
| 15 | + | |
| 16 | +@Mapper | |
| 17 | +public interface CartMapper extends BaseMapperX<CartDO> { | |
| 18 | + | |
| 19 | + default CartDO selectByUserIdAndSkuId(Long userId, Long skuId) { | |
| 20 | + return selectOne(CartDO::getUserId, userId, | |
| 21 | + CartDO::getSkuId, skuId); | |
| 22 | + } | |
| 23 | + | |
| 24 | + default Integer selectSumByUserId(Long userId) { | |
| 25 | + // SQL sum 查询 | |
| 26 | + List<Map<String, Object>> result = selectMaps(new QueryWrapper<CartDO>() | |
| 27 | + .select("SUM(count) AS sumCount") | |
| 28 | + .eq("user_id", userId) | |
| 29 | + .eq("selected", true)); // 只计算选中的 | |
| 30 | + // 获得数量 | |
| 31 | + return CollUtil.getFirst(result) != null ? MapUtil.getInt(result.get(0), "sumCount") : 0; | |
| 32 | + } | |
| 33 | + | |
| 34 | + default CartDO selectById(Long id, Long userId) { | |
| 35 | + return selectOne(CartDO::getId, id, | |
| 36 | + CartDO::getUserId, userId); | |
| 37 | + } | |
| 38 | + | |
| 39 | + default List<CartDO> selectListByIds(Collection<Long> ids, Long userId) { | |
| 40 | + return selectList(new LambdaQueryWrapper<CartDO>() | |
| 41 | + .in(CartDO::getId, ids) | |
| 42 | + .eq(CartDO::getUserId, userId)); | |
| 43 | + } | |
| 44 | + | |
| 45 | + default List<CartDO> selectListByUserId(Long userId) { | |
| 46 | + return selectList(new LambdaQueryWrapper<CartDO>() | |
| 47 | + .eq(CartDO::getUserId, userId)); | |
| 48 | + } | |
| 49 | + | |
| 50 | + default List<CartDO> selectListByUserId(Long userId, Set<Long> ids) { | |
| 51 | + return selectList(new LambdaQueryWrapper<CartDO>() | |
| 52 | + .eq(CartDO::getUserId, userId) | |
| 53 | + .in(CartDO::getId, ids)); | |
| 54 | + } | |
| 55 | + | |
| 56 | + default void updateByIds(Collection<Long> ids, Long userId, CartDO updateObj) { | |
| 57 | + update(updateObj, new LambdaQueryWrapper<CartDO>() | |
| 58 | + .in(CartDO::getId, ids) | |
| 59 | + .eq(CartDO::getUserId, userId)); | |
| 60 | + } | |
| 61 | + | |
| 62 | +} | ... | ... |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/cart/TradeCartMapper.java deleted
| 1 | -package cn.iocoder.yudao.module.trade.dal.mysql.cart; | |
| 2 | - | |
| 3 | -import cn.hutool.core.collection.CollUtil; | |
| 4 | -import cn.hutool.core.map.MapUtil; | |
| 5 | -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; | |
| 6 | -import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; | |
| 7 | -import cn.iocoder.yudao.module.trade.dal.dataobject.cart.TradeCartDO; | |
| 8 | -import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; | |
| 9 | -import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; | |
| 10 | -import org.apache.ibatis.annotations.Mapper; | |
| 11 | - | |
| 12 | -import java.util.Collection; | |
| 13 | -import java.util.List; | |
| 14 | -import java.util.Map; | |
| 15 | -import java.util.Set; | |
| 16 | - | |
| 17 | -@Mapper | |
| 18 | -public interface TradeCartMapper extends BaseMapperX<TradeCartDO> { | |
| 19 | - | |
| 20 | - default TradeCartDO selectByUserIdAndSkuId(Long userId, Long skuId, | |
| 21 | - Boolean addStatus, Boolean orderStatus) { | |
| 22 | - return selectOne(new LambdaQueryWrapper<TradeCartDO>().eq(TradeCartDO::getUserId, userId) | |
| 23 | - .eq(TradeCartDO::getSkuId, skuId) | |
| 24 | - .eq(TradeCartDO::getAddStatus, addStatus) | |
| 25 | - .eq(TradeCartDO::getOrderStatus, orderStatus)); | |
| 26 | - } | |
| 27 | - | |
| 28 | - default Integer selectSumByUserId(Long userId) { | |
| 29 | - // SQL sum 查询 | |
| 30 | - List<Map<String, Object>> result = selectMaps(new QueryWrapper<TradeCartDO>() | |
| 31 | - .select("SUM(count) AS sumCount") | |
| 32 | - .eq("user_id", userId) | |
| 33 | - .eq("add_status", true) // 只计算添加到购物车中的 | |
| 34 | - .eq("order_status", false)); // 必须未下单 | |
| 35 | - // 获得数量 | |
| 36 | - return CollUtil.getFirst(result) != null ? MapUtil.getInt(result.get(0), "sumCount") : 0; | |
| 37 | - } | |
| 38 | - | |
| 39 | - default Map<Long, Integer> selectSumMapByUserId(Long userId) { | |
| 40 | - // SQL sum 查询 | |
| 41 | - List<Map<String, Object>> result = selectMaps(new QueryWrapper<TradeCartDO>() | |
| 42 | - .select("spu_id, SUM(count) AS sumCount") | |
| 43 | - .eq("user_id", userId) | |
| 44 | - .eq("add_status", true) // 只计算添加到购物车中的 | |
| 45 | - .eq("order_status", false) // 必须未下单 | |
| 46 | - .groupBy("spu_id")); | |
| 47 | - // 获得数量 | |
| 48 | - return CollectionUtils.convertMap(result, item -> MapUtil.getLong(item, "spu_id"), | |
| 49 | - item -> MapUtil.getInt(item, "sumCount")); | |
| 50 | - } | |
| 51 | - | |
| 52 | - default TradeCartDO selectById(Long id, Long userId) { | |
| 53 | - return selectOne(TradeCartDO::getId, id, | |
| 54 | - TradeCartDO::getUserId, userId); | |
| 55 | - } | |
| 56 | - | |
| 57 | - default List<TradeCartDO> selectListByIds(Collection<Long> ids, Long userId) { | |
| 58 | - return selectList(new LambdaQueryWrapper<TradeCartDO>() | |
| 59 | - .in(TradeCartDO::getId, ids) | |
| 60 | - .eq(TradeCartDO::getUserId, userId)); | |
| 61 | - } | |
| 62 | - | |
| 63 | - default List<TradeCartDO> selectListByUserId(Long userId, Boolean addStatus, Boolean orderStatus) { | |
| 64 | - return selectList(new LambdaQueryWrapper<TradeCartDO>() | |
| 65 | - .eq(TradeCartDO::getUserId, userId) | |
| 66 | - .eq(TradeCartDO::getAddStatus, addStatus) | |
| 67 | - .eq(TradeCartDO::getOrderStatus, orderStatus)); | |
| 68 | - } | |
| 69 | - | |
| 70 | - default void updateByIds(Collection<Long> ids, TradeCartDO updateObject) { | |
| 71 | - update(updateObject, new LambdaQueryWrapper<TradeCartDO>().in(TradeCartDO::getId, ids)); | |
| 72 | - } | |
| 73 | - | |
| 74 | - default List<TradeCartDO> selectListByUserId(Long userId, Set<Long> ids) { | |
| 75 | - return selectList(new LambdaQueryWrapper<TradeCartDO>() | |
| 76 | - .eq(TradeCartDO::getUserId, userId) | |
| 77 | - .in(TradeCartDO::getId, ids)); | |
| 78 | - } | |
| 79 | - | |
| 80 | -} |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/aftersalelog/core/aop/AfterSaleLogAspect.java
| ... | ... | @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.trade.framework.aftersalelog.core.aop; |
| 3 | 3 | import cn.hutool.core.map.MapUtil; |
| 4 | 4 | import cn.hutool.core.util.ObjectUtil; |
| 5 | 5 | import cn.iocoder.yudao.framework.common.util.spring.SpringExpressionUtils; |
| 6 | +import cn.iocoder.yudao.framework.operatelog.core.service.OperateLog; | |
| 6 | 7 | import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils; |
| 7 | 8 | import cn.iocoder.yudao.module.trade.framework.aftersalelog.core.annotations.AfterSaleLog; |
| 8 | 9 | import cn.iocoder.yudao.module.trade.framework.aftersalelog.core.dto.TradeAfterSaleLogCreateReqDTO; |
| ... | ... | @@ -33,9 +34,26 @@ public class AfterSaleLogAspect { |
| 33 | 34 | |
| 34 | 35 | @Resource |
| 35 | 36 | private AfterSaleLogService afterSaleLogService; |
| 36 | - | |
| 37 | - // TODO chenchen: 这个分 3 行把; | |
| 38 | - private final static String OPERATE_TYPE = "operateType", ID = "id", CONTENT = "content"; | |
| 37 | + /** | |
| 38 | + * 售前状态 | |
| 39 | + */ | |
| 40 | + private static final ThreadLocal<Integer> BEFORE_STATUS = new ThreadLocal<>(); | |
| 41 | + /** | |
| 42 | + * 售后状态 | |
| 43 | + */ | |
| 44 | + private static final ThreadLocal<Integer> AFTER_STATUS = new ThreadLocal<>(); | |
| 45 | + /** | |
| 46 | + * 操作类型 | |
| 47 | + */ | |
| 48 | + private final static String OPERATE_TYPE = "operateType"; | |
| 49 | + /** | |
| 50 | + * ID | |
| 51 | + */ | |
| 52 | + private final static String ID = "id"; | |
| 53 | + /** | |
| 54 | + * 操作明细 | |
| 55 | + */ | |
| 56 | + private final static String CONTENT = "content"; | |
| 39 | 57 | |
| 40 | 58 | /** |
| 41 | 59 | * 切面存入日志 |
| ... | ... | @@ -52,11 +70,15 @@ public class AfterSaleLogAspect { |
| 52 | 70 | .setUserType(userType) |
| 53 | 71 | .setAfterSaleId(MapUtil.getLong(formatObj, ID)) |
| 54 | 72 | .setOperateType(MapUtil.getStr(formatObj, OPERATE_TYPE)) |
| 73 | + .setBeforeStatus(BEFORE_STATUS.get()) | |
| 74 | + .setAfterStatus(AFTER_STATUS.get()) | |
| 55 | 75 | .setContent(MapUtil.getStr(formatObj, CONTENT)); |
| 56 | 76 | // 异步存入数据库 |
| 57 | 77 | afterSaleLogService.createLog(dto); |
| 58 | 78 | } catch (Exception exception) { |
| 59 | 79 | log.error("[doAfterReturning][afterSaleLog({}) 日志记录错误]", toJsonString(afterSaleLog), exception); |
| 80 | + }finally { | |
| 81 | + clearThreadLocal(); | |
| 60 | 82 | } |
| 61 | 83 | } |
| 62 | 84 | |
| ... | ... | @@ -85,4 +107,17 @@ public class AfterSaleLogAspect { |
| 85 | 107 | return result; |
| 86 | 108 | } |
| 87 | 109 | |
| 110 | + public static void setBeforeStatus(Integer beforestatus) { | |
| 111 | + BEFORE_STATUS.set(beforestatus); | |
| 112 | + } | |
| 113 | + | |
| 114 | + public static void setAfterStatus(Integer afterStatus) { | |
| 115 | + AFTER_STATUS.set(afterStatus); | |
| 116 | + } | |
| 117 | + | |
| 118 | + private static void clearThreadLocal() { | |
| 119 | + AFTER_STATUS.remove(); | |
| 120 | + BEFORE_STATUS.remove(); | |
| 121 | + } | |
| 122 | + | |
| 88 | 123 | } | ... | ... |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/aftersalelog/core/dto/TradeAfterSaleLogCreateReqDTO.java
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/aftersalelog/core/dto/TradeAfterSaleLogRespDTO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.trade.framework.aftersalelog.core.dto; | |
| 2 | + | |
| 3 | +import io.swagger.v3.oas.annotations.media.Schema; | |
| 4 | +import lombok.AllArgsConstructor; | |
| 5 | +import lombok.Data; | |
| 6 | +import lombok.NoArgsConstructor; | |
| 7 | + | |
| 8 | +import javax.validation.constraints.NotNull; | |
| 9 | +import java.time.LocalDateTime; | |
| 10 | + | |
| 11 | +// TODO @puhui999:这个是不是应该搞成 vo 啊? | |
| 12 | +/** | |
| 13 | + * 贸易售后日志详情 DTO | |
| 14 | + * | |
| 15 | + * @author HUIHUI | |
| 16 | + */ | |
| 17 | +@Data | |
| 18 | +@NoArgsConstructor | |
| 19 | +@AllArgsConstructor | |
| 20 | +public class TradeAfterSaleLogRespDTO { | |
| 21 | + | |
| 22 | + @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "20669") | |
| 23 | + private Long id; | |
| 24 | + | |
| 25 | + @Schema(description = "用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "22634") | |
| 26 | + @NotNull(message = "用户编号不能为空") | |
| 27 | + private Long userId; | |
| 28 | + | |
| 29 | + @Schema(description = "用户类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") | |
| 30 | + @NotNull(message = "用户类型不能为空") | |
| 31 | + private Integer userType; | |
| 32 | + | |
| 33 | + @Schema(description = "售后编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "3023") | |
| 34 | + @NotNull(message = "售后编号不能为空") | |
| 35 | + private Long afterSaleId; | |
| 36 | + | |
| 37 | + @Schema(description = "订单编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "25870") | |
| 38 | + @NotNull(message = "订单编号不能为空") | |
| 39 | + private Long orderId; | |
| 40 | + | |
| 41 | + @Schema(description = "订单项编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "23154") | |
| 42 | + @NotNull(message = "订单项编号不能为空") | |
| 43 | + private Long orderItemId; | |
| 44 | + | |
| 45 | + @Schema(description = "售后状态(之前)", example = "2") | |
| 46 | + private Integer beforeStatus; | |
| 47 | + | |
| 48 | + @Schema(description = "售后状态(之后)", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") | |
| 49 | + @NotNull(message = "售后状态(之后)不能为空") | |
| 50 | + private Integer afterStatus; | |
| 51 | + | |
| 52 | + @Schema(description = "操作明细", requiredMode = Schema.RequiredMode.REQUIRED, example = "维权完成,退款金额:¥37776.00") | |
| 53 | + @NotNull(message = "操作明细不能为空") | |
| 54 | + private String content; | |
| 55 | + | |
| 56 | + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) | |
| 57 | + private LocalDateTime createTime; | |
| 58 | + | |
| 59 | +} | ... | ... |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/aftersalelog/core/service/AfterSaleLogService.java
| ... | ... | @@ -2,6 +2,9 @@ package cn.iocoder.yudao.module.trade.framework.aftersalelog.core.service; |
| 2 | 2 | |
| 3 | 3 | |
| 4 | 4 | import cn.iocoder.yudao.module.trade.framework.aftersalelog.core.dto.TradeAfterSaleLogCreateReqDTO; |
| 5 | +import cn.iocoder.yudao.module.trade.framework.aftersalelog.core.dto.TradeAfterSaleLogRespDTO; | |
| 6 | + | |
| 7 | +import java.util.List; | |
| 5 | 8 | |
| 6 | 9 | /** |
| 7 | 10 | * 交易售后日志 Service 接口 |
| ... | ... | @@ -20,4 +23,12 @@ public interface AfterSaleLogService { |
| 20 | 23 | */ |
| 21 | 24 | void createLog(TradeAfterSaleLogCreateReqDTO logDTO); |
| 22 | 25 | |
| 26 | + /** | |
| 27 | + * 获取售后日志 | |
| 28 | + * | |
| 29 | + * @param afterSaleId 售后编号 | |
| 30 | + * @return 售后日志 | |
| 31 | + */ | |
| 32 | + List<TradeAfterSaleLogRespDTO> getLog(Long afterSaleId); | |
| 33 | + | |
| 23 | 34 | } | ... | ... |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/aftersalelog/core/util/AfterSaleLogUtils.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.trade.framework.aftersalelog.core.util; | |
| 2 | + | |
| 3 | + | |
| 4 | +import cn.iocoder.yudao.module.trade.framework.aftersalelog.core.aop.AfterSaleLogAspect; | |
| 5 | + | |
| 6 | +/** | |
| 7 | + * 操作日志工具类 | |
| 8 | + * 目前主要的作用,是提供给业务代码,记录操作明细和拓展字段 | |
| 9 | + * | |
| 10 | + * @author 芋道源码 | |
| 11 | + */ | |
| 12 | +public class AfterSaleLogUtils { | |
| 13 | + | |
| 14 | + public static void setBeforeStatus(Integer status) { | |
| 15 | + AfterSaleLogAspect.setBeforeStatus(status); | |
| 16 | + } | |
| 17 | + | |
| 18 | + public static void setAfterStatus(Integer status) { | |
| 19 | + AfterSaleLogAspect.setAfterStatus(status); | |
| 20 | + } | |
| 21 | + | |
| 22 | +} | ... | ... |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/aftersale/TradeAfterSaleService.java
| ... | ... | @@ -43,6 +43,14 @@ public interface TradeAfterSaleService { |
| 43 | 43 | TradeAfterSaleDO getAfterSale(Long userId, Long id); |
| 44 | 44 | |
| 45 | 45 | /** |
| 46 | + * 【管理员】获得售后单 | |
| 47 | + * | |
| 48 | + * @param id 售后编号 | |
| 49 | + * @return 售后订单 | |
| 50 | + */ | |
| 51 | + TradeAfterSaleDO getAfterSale(Long id); | |
| 52 | + | |
| 53 | + /** | |
| 46 | 54 | * 【会员】创建售后订单 |
| 47 | 55 | * |
| 48 | 56 | * @param userId 会员用户编号 | ... | ... |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/aftersale/TradeAfterSaleServiceImpl.java
| ... | ... | @@ -26,6 +26,7 @@ import cn.iocoder.yudao.module.trade.enums.aftersale.TradeAfterSaleWayEnum; |
| 26 | 26 | import cn.iocoder.yudao.module.trade.enums.order.TradeOrderItemAfterSaleStatusEnum; |
| 27 | 27 | import cn.iocoder.yudao.module.trade.enums.order.TradeOrderStatusEnum; |
| 28 | 28 | import cn.iocoder.yudao.module.trade.framework.aftersalelog.core.dto.TradeAfterSaleLogCreateReqDTO; |
| 29 | +import cn.iocoder.yudao.module.trade.framework.aftersalelog.core.dto.TradeAfterSaleLogRespDTO; | |
| 29 | 30 | import cn.iocoder.yudao.module.trade.framework.aftersalelog.core.service.AfterSaleLogService; |
| 30 | 31 | import cn.iocoder.yudao.module.trade.framework.order.config.TradeOrderProperties; |
| 31 | 32 | import cn.iocoder.yudao.module.trade.service.order.TradeOrderQueryService; |
| ... | ... | @@ -40,6 +41,7 @@ import org.springframework.validation.annotation.Validated; |
| 40 | 41 | |
| 41 | 42 | import javax.annotation.Resource; |
| 42 | 43 | import java.time.LocalDateTime; |
| 44 | +import java.util.List; | |
| 43 | 45 | |
| 44 | 46 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| 45 | 47 | import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString; |
| ... | ... | @@ -87,6 +89,16 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService, AfterSa |
| 87 | 89 | } |
| 88 | 90 | |
| 89 | 91 | @Override |
| 92 | + public TradeAfterSaleDO getAfterSale(Long id) { | |
| 93 | + TradeAfterSaleDO afterSale = tradeAfterSaleMapper.selectById(id); | |
| 94 | + // TODO @puhui999;读不到,不要这里报错哈;交给前端报错;一般是读取信息不到,message 提示,然后 close tab; | |
| 95 | + if (afterSale == null) { | |
| 96 | + throw exception(AFTER_SALE_NOT_FOUND); | |
| 97 | + } | |
| 98 | + return afterSale; | |
| 99 | + } | |
| 100 | + | |
| 101 | + @Override | |
| 90 | 102 | @Transactional(rollbackFor = Exception.class) |
| 91 | 103 | public Long createAfterSale(Long userId, AppTradeAfterSaleCreateReqVO createReqVO) { |
| 92 | 104 | // 第一步,前置校验 |
| ... | ... | @@ -439,4 +451,12 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService, AfterSa |
| 439 | 451 | log.error("[createLog][request({}) 日志记录错误]", toJsonString(logDTO), exception); |
| 440 | 452 | } |
| 441 | 453 | } |
| 454 | + | |
| 455 | + @Override | |
| 456 | + public List<TradeAfterSaleLogRespDTO> getLog(Long afterSaleId) { | |
| 457 | + // TODO 不熟悉流程先这么滴 | |
| 458 | + List<TradeAfterSaleLogDO> saleLogDOs = tradeAfterSaleLogMapper.selectList(TradeAfterSaleLogDO::getAfterSaleId, afterSaleId); | |
| 459 | + return TradeAfterSaleConvert.INSTANCE.convertList(saleLogDOs); | |
| 460 | + } | |
| 461 | + | |
| 442 | 462 | } | ... | ... |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/cart/TradeCartService.java renamed to yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/cart/CartService.java
| 1 | 1 | package cn.iocoder.yudao.module.trade.service.cart; |
| 2 | 2 | |
| 3 | -import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartAddReqVO; | |
| 4 | -import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartListRespVO; | |
| 5 | -import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartResetReqVO; | |
| 6 | -import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartUpdateReqVO; | |
| 7 | -import cn.iocoder.yudao.module.trade.dal.dataobject.cart.TradeCartDO; | |
| 3 | +import cn.iocoder.yudao.module.trade.controller.app.cart.vo.*; | |
| 4 | +import cn.iocoder.yudao.module.trade.dal.dataobject.cart.CartDO; | |
| 8 | 5 | |
| 9 | 6 | import javax.validation.Valid; |
| 10 | 7 | import java.util.Collection; |
| 11 | 8 | import java.util.List; |
| 12 | -import java.util.Map; | |
| 13 | 9 | import java.util.Set; |
| 14 | 10 | |
| 15 | 11 | /** |
| ... | ... | @@ -17,7 +13,7 @@ import java.util.Set; |
| 17 | 13 | * |
| 18 | 14 | * @author 芋道源码 |
| 19 | 15 | */ |
| 20 | -public interface TradeCartService { | |
| 16 | +public interface CartService { | |
| 21 | 17 | |
| 22 | 18 | /** |
| 23 | 19 | * 添加商品到购物车 |
| ... | ... | @@ -26,7 +22,7 @@ public interface TradeCartService { |
| 26 | 22 | * @param addReqVO 添加信息 |
| 27 | 23 | * @return 购物项的编号 |
| 28 | 24 | */ |
| 29 | - Long addCart(Long userId, @Valid AppTradeCartAddReqVO addReqVO); | |
| 25 | + Long addCart(Long userId, @Valid AppCartAddReqVO addReqVO); | |
| 30 | 26 | |
| 31 | 27 | /** |
| 32 | 28 | * 更新购物车商品数量 |
| ... | ... | @@ -34,7 +30,15 @@ public interface TradeCartService { |
| 34 | 30 | * @param userId 用户编号 |
| 35 | 31 | * @param updateCountReqVO 更新信息 |
| 36 | 32 | */ |
| 37 | - void updateCart(Long userId, AppTradeCartUpdateReqVO updateCountReqVO); | |
| 33 | + void updateCartCount(Long userId, AppCartUpdateCountReqVO updateCountReqVO); | |
| 34 | + | |
| 35 | + /** | |
| 36 | + * 更新购物车选中状态 | |
| 37 | + * | |
| 38 | + * @param userId 用户编号 | |
| 39 | + * @param updateSelectedReqVO 更新信息 | |
| 40 | + */ | |
| 41 | + void updateCartSelected(Long userId, @Valid AppCartUpdateSelectedReqVO updateSelectedReqVO); | |
| 38 | 42 | |
| 39 | 43 | /** |
| 40 | 44 | * 重置购物车商品 |
| ... | ... | @@ -44,7 +48,7 @@ public interface TradeCartService { |
| 44 | 48 | * @param userId 用户编号 |
| 45 | 49 | * @param updateReqVO 重置信息 |
| 46 | 50 | */ |
| 47 | - void resetCart(Long userId, AppTradeCartResetReqVO updateReqVO); | |
| 51 | + void resetCart(Long userId, AppCartResetReqVO updateReqVO); | |
| 48 | 52 | |
| 49 | 53 | /** |
| 50 | 54 | * 删除购物车商品 |
| ... | ... | @@ -68,7 +72,7 @@ public interface TradeCartService { |
| 68 | 72 | * @param userId 用户编号 |
| 69 | 73 | * @return 购物车列表 |
| 70 | 74 | */ |
| 71 | - AppTradeCartListRespVO getCartList(Long userId); | |
| 75 | + AppCartListRespVO getCartList(Long userId); | |
| 72 | 76 | |
| 73 | 77 | /** |
| 74 | 78 | * 查询用户的购物车列表 |
| ... | ... | @@ -77,14 +81,6 @@ public interface TradeCartService { |
| 77 | 81 | * @param ids 购物项的编号 |
| 78 | 82 | * @return 购物车列表 |
| 79 | 83 | */ |
| 80 | - List<TradeCartDO> getCartList(Long userId, Set<Long> ids); | |
| 81 | - | |
| 82 | - /** | |
| 83 | - * 获得用户的购物车商品 SPU 数量的 Map | |
| 84 | - * | |
| 85 | - * @param userId 用户编号 | |
| 86 | - * @return 购物车商品 SPU 数量的 Map | |
| 87 | - */ | |
| 88 | - Map<Long, Integer> getCartCountMap(Long userId); | |
| 84 | + List<CartDO> getCartList(Long userId, Set<Long> ids); | |
| 89 | 85 | |
| 90 | 86 | } | ... | ... |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/cart/TradeCartServiceImpl.java renamed to yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/cart/CartServiceImpl.java
| ... | ... | @@ -5,13 +5,10 @@ import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi; |
| 5 | 5 | import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; |
| 6 | 6 | import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi; |
| 7 | 7 | import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO; |
| 8 | -import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartAddReqVO; | |
| 9 | -import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartListRespVO; | |
| 10 | -import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartResetReqVO; | |
| 11 | -import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartUpdateReqVO; | |
| 8 | +import cn.iocoder.yudao.module.trade.controller.app.cart.vo.*; | |
| 12 | 9 | import cn.iocoder.yudao.module.trade.convert.cart.TradeCartConvert; |
| 13 | -import cn.iocoder.yudao.module.trade.dal.dataobject.cart.TradeCartDO; | |
| 14 | -import cn.iocoder.yudao.module.trade.dal.mysql.cart.TradeCartMapper; | |
| 10 | +import cn.iocoder.yudao.module.trade.dal.dataobject.cart.CartDO; | |
| 11 | +import cn.iocoder.yudao.module.trade.dal.mysql.cart.CartMapper; | |
| 15 | 12 | import org.springframework.stereotype.Service; |
| 16 | 13 | import org.springframework.transaction.annotation.Transactional; |
| 17 | 14 | import org.springframework.validation.annotation.Validated; |
| ... | ... | @@ -29,17 +26,16 @@ import static java.util.Collections.emptyList; |
| 29 | 26 | /** |
| 30 | 27 | * 购物车 Service 实现类 |
| 31 | 28 | * |
| 32 | - * // TODO 芋艿:秒杀、拼团、砍价对购物车的影响 | |
| 33 | - * // TODO 芋艿:未来优化:购物车的价格计算,支持营销信息 | |
| 29 | + * // TODO 芋艿:未来优化:购物车的价格计算,支持营销信息;目前不支持的原因,前端界面需要前端 pr 支持下; | |
| 34 | 30 | * |
| 35 | 31 | * @author 芋道源码 |
| 36 | 32 | */ |
| 37 | 33 | @Service |
| 38 | 34 | @Validated |
| 39 | -public class TradeCartServiceImpl implements TradeCartService { | |
| 35 | +public class CartServiceImpl implements CartService { | |
| 40 | 36 | |
| 41 | 37 | @Resource |
| 42 | - private TradeCartMapper cartMapper; | |
| 38 | + private CartMapper cartMapper; | |
| 43 | 39 | |
| 44 | 40 | @Resource |
| 45 | 41 | private ProductSpuApi productSpuApi; |
| ... | ... | @@ -47,39 +43,31 @@ public class TradeCartServiceImpl implements TradeCartService { |
| 47 | 43 | private ProductSkuApi productSkuApi; |
| 48 | 44 | |
| 49 | 45 | @Override |
| 50 | - public Long addCart(Long userId, AppTradeCartAddReqVO addReqVO) { | |
| 46 | + public Long addCart(Long userId, AppCartAddReqVO addReqVO) { | |
| 51 | 47 | // 查询 TradeCartDO |
| 52 | - TradeCartDO cart = cartMapper.selectByUserIdAndSkuId(userId, addReqVO.getSkuId(), | |
| 53 | - addReqVO.getAddStatus(), false); | |
| 48 | + CartDO cart = cartMapper.selectByUserIdAndSkuId(userId, addReqVO.getSkuId()); | |
| 54 | 49 | // 校验 SKU |
| 55 | - Integer count = cart != null && addReqVO.getAddStatus() ? | |
| 56 | - cart.getCount() + addReqVO.getCount() : addReqVO.getCount(); | |
| 50 | + Integer count = addReqVO.getCount(); | |
| 57 | 51 | ProductSkuRespDTO sku = checkProductSku(addReqVO.getSkuId(), count); |
| 58 | 52 | |
| 59 | - // 情况零:特殊,count 小于等于 0,说明前端项目删除 | |
| 60 | 53 | // 情况一:存在,则进行数量更新 |
| 61 | 54 | if (cart != null) { |
| 62 | - // 特殊情况,如果 count 小于等于 0,说明前端想要删除 | |
| 63 | - if (count <= 0) { | |
| 64 | - cartMapper.deleteById(cart.getId()); | |
| 65 | - } else { | |
| 66 | - cartMapper.updateById(new TradeCartDO().setId(cart.getId()).setCount(count)); | |
| 67 | - } | |
| 55 | + cartMapper.updateById(new CartDO().setId(cart.getId()).setSelected(true) | |
| 56 | + .setCount(cart.getCount() + count)); | |
| 68 | 57 | return cart.getId(); |
| 69 | 58 | // 情况二:不存在,则进行插入 |
| 70 | 59 | } else { |
| 71 | - cart = new TradeCartDO().setUserId(userId) | |
| 72 | - .setSpuId(sku.getSpuId()).setSkuId(sku.getId()).setCount(count) | |
| 73 | - .setAddStatus(addReqVO.getAddStatus()).setOrderStatus(false); | |
| 60 | + cart = new CartDO().setUserId(userId).setSelected(true) | |
| 61 | + .setSpuId(sku.getSpuId()).setSkuId(sku.getId()).setCount(count); | |
| 74 | 62 | cartMapper.insert(cart); |
| 75 | 63 | } |
| 76 | 64 | return cart.getId(); |
| 77 | 65 | } |
| 78 | 66 | |
| 79 | 67 | @Override |
| 80 | - public void updateCart(Long userId, AppTradeCartUpdateReqVO updateReqVO) { | |
| 68 | + public void updateCartCount(Long userId, AppCartUpdateCountReqVO updateReqVO) { | |
| 81 | 69 | // 校验 TradeCartDO 存在 |
| 82 | - TradeCartDO cart = cartMapper.selectById(updateReqVO.getId(), userId); | |
| 70 | + CartDO cart = cartMapper.selectById(updateReqVO.getId(), userId); | |
| 83 | 71 | if (cart == null) { |
| 84 | 72 | throw exception(CARD_ITEM_NOT_FOUND); |
| 85 | 73 | } |
| ... | ... | @@ -87,29 +75,34 @@ public class TradeCartServiceImpl implements TradeCartService { |
| 87 | 75 | checkProductSku(cart.getSkuId(), updateReqVO.getCount()); |
| 88 | 76 | |
| 89 | 77 | // 更新数量 |
| 90 | - cartMapper.updateById(new TradeCartDO().setId(cart.getId()) | |
| 78 | + cartMapper.updateById(new CartDO().setId(cart.getId()) | |
| 91 | 79 | .setCount(updateReqVO.getCount())); |
| 92 | 80 | } |
| 93 | 81 | |
| 94 | 82 | @Override |
| 83 | + public void updateCartSelected(Long userId, AppCartUpdateSelectedReqVO updateSelectedReqVO) { | |
| 84 | + cartMapper.updateByIds(updateSelectedReqVO.getIds(), userId, | |
| 85 | + new CartDO().setSelected(updateSelectedReqVO.getSelected())); | |
| 86 | + } | |
| 87 | + | |
| 88 | + @Override | |
| 95 | 89 | @Transactional(rollbackFor = Exception.class) |
| 96 | - public void resetCart(Long userId, AppTradeCartResetReqVO resetReqVO) { | |
| 90 | + public void resetCart(Long userId, AppCartResetReqVO resetReqVO) { | |
| 97 | 91 | // 第一步:删除原本的购物项 |
| 98 | - TradeCartDO oldCart = cartMapper.selectById(resetReqVO.getId(), userId); | |
| 92 | + CartDO oldCart = cartMapper.selectById(resetReqVO.getId(), userId); | |
| 99 | 93 | if (oldCart == null) { |
| 100 | 94 | throw exception(CARD_ITEM_NOT_FOUND); |
| 101 | 95 | } |
| 102 | 96 | cartMapper.deleteById(oldCart.getId()); |
| 103 | 97 | |
| 104 | 98 | // 第二步:添加新的购物项 |
| 105 | - TradeCartDO newCart = cartMapper.selectByUserIdAndSkuId(userId, resetReqVO.getSkuId(), | |
| 106 | - true, false); | |
| 99 | + CartDO newCart = cartMapper.selectByUserIdAndSkuId(userId, resetReqVO.getSkuId()); | |
| 107 | 100 | if (newCart != null) { |
| 108 | - updateCart(userId, new AppTradeCartUpdateReqVO() | |
| 101 | + updateCartCount(userId, new AppCartUpdateCountReqVO() | |
| 109 | 102 | .setId(newCart.getId()).setCount(resetReqVO.getCount())); |
| 110 | 103 | } else { |
| 111 | - addCart(userId, new AppTradeCartAddReqVO().setAddStatus(true) | |
| 112 | - .setSkuId(resetReqVO.getSkuId()).setCount(resetReqVO.getCount())); | |
| 104 | + addCart(userId, new AppCartAddReqVO().setSkuId(resetReqVO.getSkuId()) | |
| 105 | + .setCount(resetReqVO.getCount())); | |
| 113 | 106 | } |
| 114 | 107 | } |
| 115 | 108 | |
| ... | ... | @@ -122,7 +115,7 @@ public class TradeCartServiceImpl implements TradeCartService { |
| 122 | 115 | @Override |
| 123 | 116 | public void deleteCart(Long userId, Collection<Long> ids) { |
| 124 | 117 | // 查询 TradeCartDO 列表 |
| 125 | - List<TradeCartDO> carts = cartMapper.selectListByIds(ids, userId); | |
| 118 | + List<CartDO> carts = cartMapper.selectListByIds(ids, userId); | |
| 126 | 119 | if (CollUtil.isEmpty(carts)) { |
| 127 | 120 | return; |
| 128 | 121 | } |
| ... | ... | @@ -133,30 +126,27 @@ public class TradeCartServiceImpl implements TradeCartService { |
| 133 | 126 | |
| 134 | 127 | @Override |
| 135 | 128 | public Integer getCartCount(Long userId) { |
| 129 | + // TODO 芋艿:需要算上 selected | |
| 136 | 130 | return cartMapper.selectSumByUserId(userId); |
| 137 | 131 | } |
| 138 | 132 | |
| 139 | 133 | @Override |
| 140 | - public Map<Long, Integer> getCartCountMap(Long userId) { | |
| 141 | - return cartMapper.selectSumMapByUserId(userId); | |
| 142 | - } | |
| 143 | - | |
| 144 | - @Override | |
| 145 | - public AppTradeCartListRespVO getCartList(Long userId) { | |
| 146 | - // 获得购物车的商品,只查询未下单的 | |
| 147 | - List<TradeCartDO> carts = cartMapper.selectListByUserId(userId, true, false); | |
| 148 | - carts.sort(Comparator.comparing(TradeCartDO::getId).reversed()); | |
| 134 | + public AppCartListRespVO getCartList(Long userId) { | |
| 135 | + // 获得购物车的商品 | |
| 136 | + List<CartDO> carts = cartMapper.selectListByUserId(userId); | |
| 137 | + carts.sort(Comparator.comparing(CartDO::getId).reversed()); | |
| 149 | 138 | // 如果未空,则返回空结果 |
| 150 | 139 | if (CollUtil.isEmpty(carts)) { |
| 151 | - return new AppTradeCartListRespVO().setValidList(emptyList()) | |
| 140 | + return new AppCartListRespVO().setValidList(emptyList()) | |
| 152 | 141 | .setInvalidList(emptyList()); |
| 153 | 142 | } |
| 154 | 143 | |
| 155 | 144 | // 查询 SPU、SKU 列表 |
| 156 | - List<ProductSpuRespDTO> spus = productSpuApi.getSpuList(convertSet(carts, TradeCartDO::getSpuId)); | |
| 157 | - List<ProductSkuRespDTO> skus = productSkuApi.getSkuList(convertSet(carts, TradeCartDO::getSkuId)); | |
| 145 | + List<ProductSpuRespDTO> spus = productSpuApi.getSpuList(convertSet(carts, CartDO::getSpuId)); | |
| 146 | + List<ProductSkuRespDTO> skus = productSkuApi.getSkuList(convertSet(carts, CartDO::getSkuId)); | |
| 158 | 147 | |
| 159 | 148 | // 如果 SPU 被删除,则删除购物车对应的商品。延迟删除 |
| 149 | + // 为什么不是 SKU 被删除呢?因为 SKU 被删除时,还可以通过 SPU 选择其它 SKU | |
| 160 | 150 | deleteCartIfSpuDeleted(carts, spus); |
| 161 | 151 | |
| 162 | 152 | // 拼接数据 |
| ... | ... | @@ -164,14 +154,14 @@ public class TradeCartServiceImpl implements TradeCartService { |
| 164 | 154 | } |
| 165 | 155 | |
| 166 | 156 | @Override |
| 167 | - public List<TradeCartDO> getCartList(Long userId, Set<Long> ids) { | |
| 157 | + public List<CartDO> getCartList(Long userId, Set<Long> ids) { | |
| 168 | 158 | if (CollUtil.isEmpty(ids)) { |
| 169 | 159 | return Collections.emptyList(); |
| 170 | 160 | } |
| 171 | 161 | return cartMapper.selectListByUserId(userId, ids); |
| 172 | 162 | } |
| 173 | 163 | |
| 174 | - private void deleteCartIfSpuDeleted(List<TradeCartDO> carts, List<ProductSpuRespDTO> spus) { | |
| 164 | + private void deleteCartIfSpuDeleted(List<CartDO> carts, List<ProductSpuRespDTO> spus) { | |
| 175 | 165 | // 如果 SPU 被删除,则删除购物车对应的商品。延迟删除 |
| 176 | 166 | carts.removeIf(cart -> { |
| 177 | 167 | if (spus.stream().noneMatch(spu -> spu.getId().equals(cart.getSpuId()))) { | ... | ... |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressService.java
| ... | ... | @@ -48,6 +48,14 @@ public interface DeliveryExpressService { |
| 48 | 48 | DeliveryExpressDO getDeliveryExpress(Long id); |
| 49 | 49 | |
| 50 | 50 | /** |
| 51 | + * 校验快递公司是否合法 | |
| 52 | + * | |
| 53 | + * @param id 编号 | |
| 54 | + * @return 快递公司 | |
| 55 | + */ | |
| 56 | + DeliveryExpressDO validateDeliveryExpress(Long id); | |
| 57 | + | |
| 58 | + /** | |
| 51 | 59 | * 获得快递公司分页 |
| 52 | 60 | * |
| 53 | 61 | * @param pageReqVO 分页查询 |
| ... | ... | @@ -70,4 +78,5 @@ public interface DeliveryExpressService { |
| 70 | 78 | * @return 快递公司列表 |
| 71 | 79 | */ |
| 72 | 80 | List<DeliveryExpressDO> getDeliveryExpressListByStatus(Integer status); |
| 81 | + | |
| 73 | 82 | } | ... | ... |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/DeliveryExpressServiceImpl.java
| 1 | 1 | package cn.iocoder.yudao.module.trade.service.delivery; |
| 2 | 2 | |
| 3 | +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; | |
| 3 | 4 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 4 | 5 | import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.express.DeliveryExpressCreateReqVO; |
| 5 | 6 | import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.express.DeliveryExpressExportReqVO; |
| ... | ... | @@ -12,12 +13,10 @@ import org.springframework.stereotype.Service; |
| 12 | 13 | import org.springframework.validation.annotation.Validated; |
| 13 | 14 | |
| 14 | 15 | import javax.annotation.Resource; |
| 15 | -import java.util.Collection; | |
| 16 | 16 | import java.util.List; |
| 17 | 17 | |
| 18 | 18 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| 19 | -import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.EXPRESS_CODE_DUPLICATE; | |
| 20 | -import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.EXPRESS_NOT_EXISTS; | |
| 19 | +import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.*; | |
| 21 | 20 | |
| 22 | 21 | /** |
| 23 | 22 | * 快递公司 Service 实现类 |
| ... | ... | @@ -86,6 +85,18 @@ public class DeliveryExpressServiceImpl implements DeliveryExpressService { |
| 86 | 85 | } |
| 87 | 86 | |
| 88 | 87 | @Override |
| 88 | + public DeliveryExpressDO validateDeliveryExpress(Long id) { | |
| 89 | + DeliveryExpressDO deliveryExpress = deliveryExpressMapper.selectById(id); | |
| 90 | + if (deliveryExpress == null) { | |
| 91 | + throw exception(EXPRESS_NOT_EXISTS); | |
| 92 | + } | |
| 93 | + if (deliveryExpress.getStatus().equals(CommonStatusEnum.DISABLE.getStatus())) { | |
| 94 | + throw exception(EXPRESS_STATUS_NOT_ENABLE); | |
| 95 | + } | |
| 96 | + return deliveryExpress; | |
| 97 | + } | |
| 98 | + | |
| 99 | + @Override | |
| 89 | 100 | public PageResult<DeliveryExpressDO> getDeliveryExpressPage(DeliveryExpressPageReqVO pageReqVO) { |
| 90 | 101 | return deliveryExpressMapper.selectPage(pageReqVO); |
| 91 | 102 | } | ... | ... |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateServiceImpl.java
| ... | ... | @@ -7,7 +7,6 @@ import cn.hutool.core.util.ObjectUtil; |
| 7 | 7 | import cn.hutool.core.util.StrUtil; |
| 8 | 8 | import cn.hutool.extra.spring.SpringUtil; |
| 9 | 9 | import cn.iocoder.yudao.framework.common.core.KeyValue; |
| 10 | -import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; | |
| 11 | 10 | import cn.iocoder.yudao.framework.common.enums.TerminalEnum; |
| 12 | 11 | import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; |
| 13 | 12 | import cn.iocoder.yudao.framework.common.util.json.JsonUtils; |
| ... | ... | @@ -26,7 +25,6 @@ import cn.iocoder.yudao.module.pay.enums.order.PayOrderStatusEnum; |
| 26 | 25 | import cn.iocoder.yudao.module.product.api.comment.ProductCommentApi; |
| 27 | 26 | import cn.iocoder.yudao.module.product.api.comment.dto.ProductCommentCreateReqDTO; |
| 28 | 27 | import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi; |
| 29 | -import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuUpdateStockReqDTO; | |
| 30 | 28 | import cn.iocoder.yudao.module.promotion.api.bargain.BargainRecordApi; |
| 31 | 29 | import cn.iocoder.yudao.module.promotion.api.combination.CombinationRecordApi; |
| 32 | 30 | import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordRespDTO; |
| ... | ... | @@ -43,8 +41,7 @@ import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderSettle |
| 43 | 41 | import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderSettlementRespVO; |
| 44 | 42 | import cn.iocoder.yudao.module.trade.controller.app.order.vo.item.AppTradeOrderItemCommentCreateReqVO; |
| 45 | 43 | import cn.iocoder.yudao.module.trade.convert.order.TradeOrderConvert; |
| 46 | -import cn.iocoder.yudao.module.trade.dal.dataobject.cart.TradeCartDO; | |
| 47 | -import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressDO; | |
| 44 | +import cn.iocoder.yudao.module.trade.dal.dataobject.cart.CartDO; | |
| 48 | 45 | import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO; |
| 49 | 46 | import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO; |
| 50 | 47 | import cn.iocoder.yudao.module.trade.dal.mysql.order.TradeOrderItemMapper; |
| ... | ... | @@ -53,7 +50,7 @@ import cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants; |
| 53 | 50 | import cn.iocoder.yudao.module.trade.enums.delivery.DeliveryTypeEnum; |
| 54 | 51 | import cn.iocoder.yudao.module.trade.enums.order.*; |
| 55 | 52 | import cn.iocoder.yudao.module.trade.framework.order.config.TradeOrderProperties; |
| 56 | -import cn.iocoder.yudao.module.trade.service.cart.TradeCartService; | |
| 53 | +import cn.iocoder.yudao.module.trade.service.cart.CartService; | |
| 57 | 54 | import cn.iocoder.yudao.module.trade.service.delivery.DeliveryExpressService; |
| 58 | 55 | import cn.iocoder.yudao.module.trade.service.message.TradeMessageService; |
| 59 | 56 | import cn.iocoder.yudao.module.trade.service.message.bo.TradeOrderMessageWhenDeliveryOrderReqBO; |
| ... | ... | @@ -70,6 +67,7 @@ import javax.annotation.Resource; |
| 70 | 67 | import java.time.LocalDateTime; |
| 71 | 68 | import java.util.List; |
| 72 | 69 | import java.util.Objects; |
| 70 | +import java.util.Set; | |
| 73 | 71 | |
| 74 | 72 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| 75 | 73 | import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*; |
| ... | ... | @@ -93,7 +91,7 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { |
| 93 | 91 | private TradeOrderItemMapper tradeOrderItemMapper; |
| 94 | 92 | |
| 95 | 93 | @Resource |
| 96 | - private TradeCartService tradeCartService; | |
| 94 | + private CartService cartService; | |
| 97 | 95 | @Resource |
| 98 | 96 | private TradePriceService tradePriceService; |
| 99 | 97 | @Resource |
| ... | ... | @@ -168,7 +166,7 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { |
| 168 | 166 | */ |
| 169 | 167 | private TradePriceCalculateRespBO calculatePrice(Long userId, AppTradeOrderSettlementReqVO settlementReqVO) { |
| 170 | 168 | // 1. 如果来自购物车,则获得购物车的商品 |
| 171 | - List<TradeCartDO> cartList = tradeCartService.getCartList(userId, | |
| 169 | + List<CartDO> cartList = cartService.getCartList(userId, | |
| 172 | 170 | convertSet(settlementReqVO.getItems(), AppTradeOrderSettlementReqVO.Item::getCartId)); |
| 173 | 171 | |
| 174 | 172 | // 2. 计算价格 |
| ... | ... | @@ -190,6 +188,7 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { |
| 190 | 188 | // 订单创建完后的逻辑 |
| 191 | 189 | afterCreateTradeOrder(userId, createReqVO, order, orderItems, calculateRespBO); |
| 192 | 190 | // 3.3 校验订单类型 |
| 191 | + // TODO @puhui999:这个逻辑,先抽个小方法;未来要通过设计模式,把这些拼团之类的逻辑,抽象出去 | |
| 193 | 192 | // 拼团 |
| 194 | 193 | if (Objects.equals(TradeOrderTypeEnum.COMBINATION.getType(), order.getType())) { |
| 195 | 194 | MemberUserRespDTO user = memberUserApi.getUser(userId); |
| ... | ... | @@ -292,11 +291,15 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { |
| 292 | 291 | TradeOrderDO tradeOrderDO, List<TradeOrderItemDO> orderItems, |
| 293 | 292 | TradePriceCalculateRespBO calculateRespBO) { |
| 294 | 293 | // 下单时扣减商品库存 |
| 295 | - productSkuApi.updateSkuStock(new ProductSkuUpdateStockReqDTO(TradeOrderConvert.INSTANCE.convertList(orderItems))); | |
| 294 | + productSkuApi.updateSkuStock(TradeOrderConvert.INSTANCE.convert(orderItems)); | |
| 296 | 295 | |
| 297 | - // 删除购物车商品 TODO 芋艿:待实现 | |
| 296 | + // 删除购物车商品 | |
| 297 | + Set<Long> cartIds = convertSet(createReqVO.getItems(), AppTradeOrderSettlementReqVO.Item::getCartId); | |
| 298 | + if (CollUtil.isNotEmpty(cartIds)) { | |
| 299 | + cartService.deleteCart(userId, cartIds); | |
| 300 | + } | |
| 298 | 301 | |
| 299 | - // 扣减积分,抵扣金额 TODO 芋艿:待实现 | |
| 302 | + // 扣减积分 TODO 芋艿:待实现 | |
| 300 | 303 | |
| 301 | 304 | // 有使用优惠券时更新 |
| 302 | 305 | if (createReqVO.getCouponId() != null) { |
| ... | ... | @@ -411,29 +414,24 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { |
| 411 | 414 | @Override |
| 412 | 415 | @Transactional(rollbackFor = Exception.class) |
| 413 | 416 | public void deliveryOrder(TradeOrderDeliveryReqVO deliveryReqVO) { |
| 414 | - // TODO @puhui999:只有选择快递的,才可以发货 | |
| 415 | 417 | // 1.1 校验并获得交易订单(可发货) |
| 416 | 418 | TradeOrderDO order = validateOrderDeliverable(deliveryReqVO.getId()); |
| 419 | + // 1.2 校验 deliveryType 是否为快递,是快递才可以发货 | |
| 420 | + if (ObjectUtil.notEqual(order.getDeliveryType(), DeliveryTypeEnum.EXPRESS.getMode())) { | |
| 421 | + throw exception(ORDER_DELIVERY_FAIL_DELIVERY_TYPE_NOT_EXPRESS); | |
| 422 | + } | |
| 417 | 423 | |
| 418 | - // TODO @puhui999:下面不修改 deliveryType,直接校验 deliveryType 是否为快递,是快递才可以发货;先做严格的方式哈。 | |
| 419 | - // 判断发货类型 | |
| 424 | + // 2. 更新订单为已发货 | |
| 420 | 425 | TradeOrderDO updateOrderObj = new TradeOrderDO(); |
| 421 | 426 | // 2.1 快递发货 |
| 422 | - if (ObjectUtil.notEqual(deliveryReqVO.getLogisticsId(), 0L)) { | |
| 423 | - // 校验快递公司 | |
| 424 | - DeliveryExpressDO deliveryExpress = deliveryExpressService.getDeliveryExpress(deliveryReqVO.getLogisticsId()); | |
| 425 | - if (deliveryExpress == null) { | |
| 426 | - throw exception(EXPRESS_NOT_EXISTS); | |
| 427 | - } | |
| 428 | - if (deliveryExpress.getStatus().equals(CommonStatusEnum.DISABLE.getStatus())) { | |
| 429 | - throw exception(EXPRESS_STATUS_NOT_ENABLE); | |
| 430 | - } | |
| 431 | - updateOrderObj.setLogisticsId(deliveryReqVO.getLogisticsId()).setLogisticsNo(deliveryReqVO.getLogisticsNo()).setDeliveryType(DeliveryTypeEnum.EXPRESS.getMode()); | |
| 427 | + if (ObjectUtil.notEqual(deliveryReqVO.getLogisticsId(), TradeOrderDO.LOGISTICS_ID_NULL)) { | |
| 428 | + deliveryExpressService.validateDeliveryExpress(deliveryReqVO.getLogisticsId()); | |
| 429 | + updateOrderObj.setLogisticsId(deliveryReqVO.getLogisticsId()).setLogisticsNo(deliveryReqVO.getLogisticsNo()); | |
| 432 | 430 | } else { |
| 433 | 431 | // 2.2 无需发货 |
| 434 | - updateOrderObj.setLogisticsId(0L).setLogisticsNo("").setDeliveryType(DeliveryTypeEnum.NULL.getMode()); | |
| 432 | + updateOrderObj.setLogisticsId(0L).setLogisticsNo(""); | |
| 435 | 433 | } |
| 436 | - // 更新 TradeOrderDO 状态为已发货,等待收货 | |
| 434 | + // 执行更新 | |
| 437 | 435 | updateOrderObj.setStatus(TradeOrderStatusEnum.DELIVERED.getStatus()).setDeliveryTime(LocalDateTime.now()); |
| 438 | 436 | int updateCount = tradeOrderMapper.updateByIdAndStatus(order.getId(), order.getStatus(), updateOrderObj); |
| 439 | 437 | if (updateCount == 0) { |
| ... | ... | @@ -471,16 +469,14 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { |
| 471 | 469 | // 订单类型:拼团 |
| 472 | 470 | if (Objects.equals(TradeOrderTypeEnum.COMBINATION.getType(), order.getType())) { |
| 473 | 471 | // 校验订单拼团是否成功 |
| 474 | - // TODO @puhui999:是不是取反? | |
| 475 | - if (combinationRecordApi.isCombinationRecordSuccess(order.getUserId(), order.getId())) { | |
| 472 | + if (!combinationRecordApi.isCombinationRecordSuccess(order.getUserId(), order.getId())) { | |
| 476 | 473 | throw exception(ORDER_DELIVERY_FAIL_COMBINATION_RECORD_STATUS_NOT_SUCCESS); |
| 477 | 474 | } |
| 478 | 475 | } |
| 479 | 476 | // 订单类类型:砍价 |
| 480 | 477 | if (Objects.equals(TradeOrderTypeEnum.BARGAIN.getType(), order.getType())) { |
| 481 | 478 | // 校验订单砍价是否成功 |
| 482 | - // TODO @puhui999:是不是取反? | |
| 483 | - if (bargainRecordApi.isBargainRecordSuccess(order.getUserId(), order.getId())) { | |
| 479 | + if (!bargainRecordApi.isBargainRecordSuccess(order.getUserId(), order.getId())) { | |
| 484 | 480 | throw exception(ORDER_DELIVERY_FAIL_BARGAIN_RECORD_STATUS_NOT_SUCCESS); |
| 485 | 481 | } |
| 486 | 482 | } | ... | ... |
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/level/MemberLevelController.java
| ... | ... | @@ -72,8 +72,8 @@ public class MemberLevelController { |
| 72 | 72 | @GetMapping("/list") |
| 73 | 73 | @Operation(summary = "获得会员等级列表") |
| 74 | 74 | @PreAuthorize("@ss.hasPermission('member:level:query')") |
| 75 | - public CommonResult<List<MemberLevelRespVO>> getLevelList(@Valid MemberLevelListReqVO pageVO) { | |
| 76 | - List<MemberLevelDO> result = levelService.getLevelList(pageVO); | |
| 75 | + public CommonResult<List<MemberLevelRespVO>> getLevelList(@Valid MemberLevelListReqVO listReqVO) { | |
| 76 | + List<MemberLevelDO> result = levelService.getLevelList(listReqVO); | |
| 77 | 77 | return success(MemberLevelConvert.INSTANCE.convertList(result)); |
| 78 | 78 | } |
| 79 | 79 | ... | ... |
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/level/MemberLevelRecordController.java
| ... | ... | @@ -2,8 +2,8 @@ package cn.iocoder.yudao.module.member.controller.admin.level; |
| 2 | 2 | |
| 3 | 3 | import cn.iocoder.yudao.framework.common.pojo.CommonResult; |
| 4 | 4 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 5 | -import cn.iocoder.yudao.module.member.controller.admin.level.vo.log.MemberLevelRecordPageReqVO; | |
| 6 | -import cn.iocoder.yudao.module.member.controller.admin.level.vo.log.MemberLevelRecordRespVO; | |
| 5 | +import cn.iocoder.yudao.module.member.controller.admin.level.vo.record.MemberLevelRecordPageReqVO; | |
| 6 | +import cn.iocoder.yudao.module.member.controller.admin.level.vo.record.MemberLevelRecordRespVO; | |
| 7 | 7 | import cn.iocoder.yudao.module.member.convert.level.MemberLevelRecordConvert; |
| 8 | 8 | import cn.iocoder.yudao.module.member.dal.dataobject.level.MemberLevelRecordDO; |
| 9 | 9 | import cn.iocoder.yudao.module.member.service.level.MemberLevelRecordService; | ... | ... |
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/level/vo/log/MemberLevelRecordBaseVO.java renamed to yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/level/vo/record/MemberLevelRecordBaseVO.java
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/level/vo/log/MemberLevelRecordPageReqVO.java renamed to yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/level/vo/record/MemberLevelRecordPageReqVO.java
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/level/vo/log/MemberLevelRecordRespVO.java renamed to yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/level/vo/record/MemberLevelRecordRespVO.java
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/address/AppAddressController.java
| 1 | 1 | package cn.iocoder.yudao.module.member.controller.app.address; |
| 2 | 2 | |
| 3 | 3 | import cn.iocoder.yudao.framework.common.pojo.CommonResult; |
| 4 | +import cn.iocoder.yudao.framework.security.core.annotations.PreAuthenticated; | |
| 4 | 5 | import cn.iocoder.yudao.module.member.controller.app.address.vo.AppAddressCreateReqVO; |
| 5 | 6 | import cn.iocoder.yudao.module.member.controller.app.address.vo.AppAddressRespVO; |
| 6 | 7 | import cn.iocoder.yudao.module.member.controller.app.address.vo.AppAddressUpdateReqVO; |
| ... | ... | @@ -31,12 +32,14 @@ public class AppAddressController { |
| 31 | 32 | |
| 32 | 33 | @PostMapping("/create") |
| 33 | 34 | @Operation(summary = "创建用户收件地址") |
| 35 | + @PreAuthenticated | |
| 34 | 36 | public CommonResult<Long> createAddress(@Valid @RequestBody AppAddressCreateReqVO createReqVO) { |
| 35 | 37 | return success(addressService.createAddress(getLoginUserId(), createReqVO)); |
| 36 | 38 | } |
| 37 | 39 | |
| 38 | 40 | @PutMapping("/update") |
| 39 | 41 | @Operation(summary = "更新用户收件地址") |
| 42 | + @PreAuthenticated | |
| 40 | 43 | public CommonResult<Boolean> updateAddress(@Valid @RequestBody AppAddressUpdateReqVO updateReqVO) { |
| 41 | 44 | addressService.updateAddress(getLoginUserId(), updateReqVO); |
| 42 | 45 | return success(true); |
| ... | ... | @@ -45,6 +48,7 @@ public class AppAddressController { |
| 45 | 48 | @DeleteMapping("/delete") |
| 46 | 49 | @Operation(summary = "删除用户收件地址") |
| 47 | 50 | @Parameter(name = "id", description = "编号", required = true) |
| 51 | + @PreAuthenticated | |
| 48 | 52 | public CommonResult<Boolean> deleteAddress(@RequestParam("id") Long id) { |
| 49 | 53 | addressService.deleteAddress(getLoginUserId(), id); |
| 50 | 54 | return success(true); |
| ... | ... | @@ -53,6 +57,7 @@ public class AppAddressController { |
| 53 | 57 | @GetMapping("/get") |
| 54 | 58 | @Operation(summary = "获得用户收件地址") |
| 55 | 59 | @Parameter(name = "id", description = "编号", required = true, example = "1024") |
| 60 | + @PreAuthenticated | |
| 56 | 61 | public CommonResult<AppAddressRespVO> getAddress(@RequestParam("id") Long id) { |
| 57 | 62 | MemberAddressDO address = addressService.getAddress(getLoginUserId(), id); |
| 58 | 63 | return success(AddressConvert.INSTANCE.convert(address)); |
| ... | ... | @@ -60,6 +65,7 @@ public class AppAddressController { |
| 60 | 65 | |
| 61 | 66 | @GetMapping("/get-default") |
| 62 | 67 | @Operation(summary = "获得默认的用户收件地址") |
| 68 | + @PreAuthenticated | |
| 63 | 69 | public CommonResult<AppAddressRespVO> getDefaultUserAddress() { |
| 64 | 70 | MemberAddressDO address = addressService.getDefaultUserAddress(getLoginUserId()); |
| 65 | 71 | return success(AddressConvert.INSTANCE.convert(address)); |
| ... | ... | @@ -67,6 +73,7 @@ public class AppAddressController { |
| 67 | 73 | |
| 68 | 74 | @GetMapping("/list") |
| 69 | 75 | @Operation(summary = "获得用户收件地址列表") |
| 76 | + @PreAuthenticated | |
| 70 | 77 | public CommonResult<List<AppAddressRespVO>> getAddressList() { |
| 71 | 78 | List<MemberAddressDO> list = addressService.getAddressList(getLoginUserId()); |
| 72 | 79 | return success(AddressConvert.INSTANCE.convertList(list)); | ... | ... |
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/level/AppMemberExperienceRecordController.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.member.controller.app.level; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.framework.common.pojo.CommonResult; | |
| 4 | +import cn.iocoder.yudao.framework.common.pojo.PageParam; | |
| 5 | +import cn.iocoder.yudao.framework.common.pojo.PageResult; | |
| 6 | +import cn.iocoder.yudao.framework.security.core.annotations.PreAuthenticated; | |
| 7 | +import cn.iocoder.yudao.module.member.controller.app.level.vo.experience.AppMemberExperienceRecordRespVO; | |
| 8 | +import cn.iocoder.yudao.module.member.convert.level.MemberExperienceRecordConvert; | |
| 9 | +import cn.iocoder.yudao.module.member.dal.dataobject.level.MemberExperienceRecordDO; | |
| 10 | +import cn.iocoder.yudao.module.member.service.level.MemberExperienceRecordService; | |
| 11 | +import io.swagger.v3.oas.annotations.Operation; | |
| 12 | +import io.swagger.v3.oas.annotations.tags.Tag; | |
| 13 | +import org.springframework.validation.annotation.Validated; | |
| 14 | +import org.springframework.web.bind.annotation.GetMapping; | |
| 15 | +import org.springframework.web.bind.annotation.RequestMapping; | |
| 16 | +import org.springframework.web.bind.annotation.RestController; | |
| 17 | + | |
| 18 | +import javax.annotation.Resource; | |
| 19 | +import javax.validation.Valid; | |
| 20 | + | |
| 21 | +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; | |
| 22 | +import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; | |
| 23 | + | |
| 24 | +@Tag(name = "用户 App - 会员经验记录") | |
| 25 | +@RestController | |
| 26 | +@RequestMapping("/member/experience-record") | |
| 27 | +@Validated | |
| 28 | +public class AppMemberExperienceRecordController { | |
| 29 | + | |
| 30 | + @Resource | |
| 31 | + private MemberExperienceRecordService experienceLogService; | |
| 32 | + | |
| 33 | + @GetMapping("/page") | |
| 34 | + @Operation(summary = "获得会员经验记录分页") | |
| 35 | + @PreAuthenticated | |
| 36 | + public CommonResult<PageResult<AppMemberExperienceRecordRespVO>> getExperienceRecordPage( | |
| 37 | + @Valid PageParam pageParam) { | |
| 38 | + PageResult<MemberExperienceRecordDO> pageResult = experienceLogService.getExperienceRecordPage( | |
| 39 | + getLoginUserId(), pageParam); | |
| 40 | + return success(MemberExperienceRecordConvert.INSTANCE.convertPage02(pageResult)); | |
| 41 | + } | |
| 42 | + | |
| 43 | +} | ... | ... |
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/level/AppMemberLevelController.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.member.controller.app.level; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.framework.common.pojo.CommonResult; | |
| 4 | +import cn.iocoder.yudao.module.member.controller.app.level.vo.level.AppMemberLevelRespVO; | |
| 5 | +import cn.iocoder.yudao.module.member.convert.level.MemberLevelConvert; | |
| 6 | +import cn.iocoder.yudao.module.member.dal.dataobject.level.MemberLevelDO; | |
| 7 | +import cn.iocoder.yudao.module.member.service.level.MemberLevelService; | |
| 8 | +import io.swagger.v3.oas.annotations.Operation; | |
| 9 | +import io.swagger.v3.oas.annotations.tags.Tag; | |
| 10 | +import org.springframework.validation.annotation.Validated; | |
| 11 | +import org.springframework.web.bind.annotation.GetMapping; | |
| 12 | +import org.springframework.web.bind.annotation.RequestMapping; | |
| 13 | +import org.springframework.web.bind.annotation.RestController; | |
| 14 | + | |
| 15 | +import javax.annotation.Resource; | |
| 16 | +import java.util.List; | |
| 17 | + | |
| 18 | +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; | |
| 19 | + | |
| 20 | +@Tag(name = "用户 App - 会员等级") | |
| 21 | +@RestController | |
| 22 | +@RequestMapping("/member/level") | |
| 23 | +@Validated | |
| 24 | +public class AppMemberLevelController { | |
| 25 | + | |
| 26 | + @Resource | |
| 27 | + private MemberLevelService levelService; | |
| 28 | + | |
| 29 | + @GetMapping("/list") | |
| 30 | + @Operation(summary = "获得会员等级列表") | |
| 31 | + public CommonResult<List<AppMemberLevelRespVO>> getLevelList() { | |
| 32 | + List<MemberLevelDO> result = levelService.getEnableLevelList(); | |
| 33 | + return success(MemberLevelConvert.INSTANCE.convertList02(result)); | |
| 34 | + } | |
| 35 | + | |
| 36 | +} | ... | ... |
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/level/vo/experience/AppMemberExperienceRecordRespVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.member.controller.app.level.vo.experience; | |
| 2 | + | |
| 3 | +import io.swagger.v3.oas.annotations.media.Schema; | |
| 4 | +import lombok.Data; | |
| 5 | + | |
| 6 | +import java.time.LocalDateTime; | |
| 7 | + | |
| 8 | +@Schema(description = "用户 App - 会员经验记录 Response VO") | |
| 9 | +@Data | |
| 10 | +public class AppMemberExperienceRecordRespVO { | |
| 11 | + | |
| 12 | + @Schema(description = "标题", requiredMode = Schema.RequiredMode.REQUIRED, example = "增加经验") | |
| 13 | + private String title; | |
| 14 | + | |
| 15 | + @Schema(description = "经验", requiredMode = Schema.RequiredMode.REQUIRED, example = "100") | |
| 16 | + private Integer experience; | |
| 17 | + | |
| 18 | + @Schema(description = "描述", requiredMode = Schema.RequiredMode.REQUIRED, example = "下单增加 100 经验") | |
| 19 | + private String description; | |
| 20 | + | |
| 21 | + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) | |
| 22 | + private LocalDateTime createTime; | |
| 23 | + | |
| 24 | +} | ... | ... |
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/level/vo/level/AppMemberLevelRespVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.member.controller.app.level.vo.level; | |
| 2 | + | |
| 3 | +import io.swagger.v3.oas.annotations.media.Schema; | |
| 4 | +import lombok.Data; | |
| 5 | + | |
| 6 | +@Schema(description = "用户 App - 会员等级 Response VO") | |
| 7 | +@Data | |
| 8 | +public class AppMemberLevelRespVO { | |
| 9 | + | |
| 10 | + @Schema(description = "等级名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋艿") | |
| 11 | + private String name; | |
| 12 | + | |
| 13 | + @Schema(description = "等级", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") | |
| 14 | + private Integer level; | |
| 15 | + | |
| 16 | + @Schema(description = "升级经验", requiredMode = Schema.RequiredMode.REQUIRED, example = "100") | |
| 17 | + private Integer experience; | |
| 18 | + | |
| 19 | + @Schema(description = "享受折扣", requiredMode = Schema.RequiredMode.REQUIRED, example = "98") | |
| 20 | + private Integer discountPercent; | |
| 21 | + | |
| 22 | + @Schema(description = "等级图标", example = "https://www.iocoder.cn/yudao.jpg") | |
| 23 | + private String icon; | |
| 24 | + | |
| 25 | + @Schema(description = "等级背景图", example = "https://www.iocoder.cn/yudao.jpg") | |
| 26 | + private String backgroundUrl; | |
| 27 | + | |
| 28 | +} | ... | ... |
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/point/AppMemberPointRecordController.java
| ... | ... | @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.member.controller.app.point; |
| 3 | 3 | import cn.iocoder.yudao.framework.common.pojo.CommonResult; |
| 4 | 4 | import cn.iocoder.yudao.framework.common.pojo.PageParam; |
| 5 | 5 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 6 | +import cn.iocoder.yudao.framework.security.core.annotations.PreAuthenticated; | |
| 6 | 7 | import cn.iocoder.yudao.module.member.controller.app.point.vo.AppMemberPointRecordRespVO; |
| 7 | 8 | import cn.iocoder.yudao.module.member.convert.point.MemberPointRecordConvert; |
| 8 | 9 | import cn.iocoder.yudao.module.member.dal.dataobject.point.MemberPointRecordDO; |
| ... | ... | @@ -31,6 +32,7 @@ public class AppMemberPointRecordController { |
| 31 | 32 | |
| 32 | 33 | @GetMapping("/page") |
| 33 | 34 | @Operation(summary = "获得用户积分记录分页") |
| 35 | + @PreAuthenticated | |
| 34 | 36 | public CommonResult<PageResult<AppMemberPointRecordRespVO>> getPointRecordPage(@Valid PageParam pageVO) { |
| 35 | 37 | PageResult<MemberPointRecordDO> pageResult = pointRecordService.getPointRecordPage(getLoginUserId(), pageVO); |
| 36 | 38 | return success(MemberPointRecordConvert.INSTANCE.convertPage02(pageResult)); | ... | ... |
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/signin/AppMemberSignInRecordController.java
| ... | ... | @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.member.controller.app.signin; |
| 3 | 3 | import cn.iocoder.yudao.framework.common.pojo.CommonResult; |
| 4 | 4 | import cn.iocoder.yudao.framework.common.pojo.PageParam; |
| 5 | 5 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 6 | +import cn.iocoder.yudao.framework.security.core.annotations.PreAuthenticated; | |
| 6 | 7 | import cn.iocoder.yudao.module.member.controller.app.signin.vo.record.AppMemberSignInRecordRespVO; |
| 7 | 8 | import cn.iocoder.yudao.module.member.controller.app.signin.vo.record.AppMemberSignInRecordSummaryRespVO; |
| 8 | 9 | import cn.iocoder.yudao.module.member.convert.signin.MemberSignInRecordConvert; |
| ... | ... | @@ -34,6 +35,7 @@ public class AppMemberSignInRecordController { |
| 34 | 35 | // TODO 芋艿:临时 mock => UserSignController.getUserInfo |
| 35 | 36 | @GetMapping("/get-summary") |
| 36 | 37 | @Operation(summary = "获得个人签到统计") |
| 38 | + @PreAuthenticated | |
| 37 | 39 | public CommonResult<AppMemberSignInRecordSummaryRespVO> getSignInRecordSummary() { |
| 38 | 40 | AppMemberSignInRecordSummaryRespVO respVO = new AppMemberSignInRecordSummaryRespVO(); |
| 39 | 41 | if (false) { |
| ... | ... | @@ -51,6 +53,7 @@ public class AppMemberSignInRecordController { |
| 51 | 53 | // TODO 芋艿:临时 mock => UserSignController.info |
| 52 | 54 | @PostMapping("/create") |
| 53 | 55 | @Operation(summary = "签到") |
| 56 | + @PreAuthenticated | |
| 54 | 57 | public CommonResult<AppMemberSignInRecordRespVO> createSignInRecord() { |
| 55 | 58 | AppMemberSignInRecordRespVO respVO = new AppMemberSignInRecordRespVO() |
| 56 | 59 | .setPoint(10) |
| ... | ... | @@ -61,6 +64,7 @@ public class AppMemberSignInRecordController { |
| 61 | 64 | |
| 62 | 65 | @GetMapping("/page") |
| 63 | 66 | @Operation(summary = "获得签到记录分页") |
| 67 | + @PreAuthenticated | |
| 64 | 68 | public CommonResult<PageResult<AppMemberSignInRecordRespVO>> getSignRecordPage(PageParam pageParam) { |
| 65 | 69 | PageResult<MemberSignInRecordDO> pageResult = signInRecordService.getSignRecordPage(getLoginUserId(), pageParam); |
| 66 | 70 | return success(MemberSignInRecordConvert.INSTANCE.convertPage02(pageResult)); | ... | ... |
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/social/AppSocialUserController.java
| ... | ... | @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.member.controller.app.social; |
| 2 | 2 | |
| 3 | 3 | import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; |
| 4 | 4 | import cn.iocoder.yudao.framework.common.pojo.CommonResult; |
| 5 | +import cn.iocoder.yudao.framework.security.core.annotations.PreAuthenticated; | |
| 5 | 6 | import cn.iocoder.yudao.module.member.controller.app.social.vo.AppSocialUserBindReqVO; |
| 6 | 7 | import cn.iocoder.yudao.module.member.controller.app.social.vo.AppSocialUserUnbindReqVO; |
| 7 | 8 | import cn.iocoder.yudao.module.member.convert.social.SocialUserConvert; |
| ... | ... | @@ -34,6 +35,7 @@ public class AppSocialUserController { |
| 34 | 35 | |
| 35 | 36 | @DeleteMapping("/unbind") |
| 36 | 37 | @Operation(summary = "取消社交绑定") |
| 38 | + @PreAuthenticated | |
| 37 | 39 | public CommonResult<Boolean> socialUnbind(@RequestBody AppSocialUserUnbindReqVO reqVO) { |
| 38 | 40 | socialUserApi.unbindSocialUser(SocialUserConvert.INSTANCE.convert(getLoginUserId(), UserTypeEnum.MEMBER.getValue(), reqVO)); |
| 39 | 41 | return CommonResult.success(true); | ... | ... |
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/user/AppMemberUserController.java
| ... | ... | @@ -4,7 +4,9 @@ import cn.iocoder.yudao.framework.common.pojo.CommonResult; |
| 4 | 4 | import cn.iocoder.yudao.framework.security.core.annotations.PreAuthenticated; |
| 5 | 5 | import cn.iocoder.yudao.module.member.controller.app.user.vo.*; |
| 6 | 6 | import cn.iocoder.yudao.module.member.convert.user.MemberUserConvert; |
| 7 | +import cn.iocoder.yudao.module.member.dal.dataobject.level.MemberLevelDO; | |
| 7 | 8 | import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO; |
| 9 | +import cn.iocoder.yudao.module.member.service.level.MemberLevelService; | |
| 8 | 10 | import cn.iocoder.yudao.module.member.service.user.MemberUserService; |
| 9 | 11 | import io.swagger.v3.oas.annotations.Operation; |
| 10 | 12 | import io.swagger.v3.oas.annotations.tags.Tag; |
| ... | ... | @@ -28,12 +30,16 @@ public class AppMemberUserController { |
| 28 | 30 | @Resource |
| 29 | 31 | private MemberUserService userService; |
| 30 | 32 | |
| 33 | + @Resource | |
| 34 | + private MemberLevelService levelService; | |
| 35 | + | |
| 31 | 36 | @GetMapping("/get") |
| 32 | 37 | @Operation(summary = "获得基本信息") |
| 33 | 38 | @PreAuthenticated |
| 34 | 39 | public CommonResult<AppMemberUserInfoRespVO> getUserInfo() { |
| 35 | 40 | MemberUserDO user = userService.getUser(getLoginUserId()); |
| 36 | - return success(MemberUserConvert.INSTANCE.convert(user)); | |
| 41 | + MemberLevelDO level = levelService.getLevel(user.getLevelId()); | |
| 42 | + return success(MemberUserConvert.INSTANCE.convert(user, level)); | |
| 37 | 43 | } |
| 38 | 44 | |
| 39 | 45 | @PutMapping("/update") | ... | ... |
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/user/vo/AppMemberUserInfoRespVO.java
| ... | ... | @@ -23,4 +23,28 @@ public class AppMemberUserInfoRespVO { |
| 23 | 23 | @Schema(description = "积分", requiredMode = Schema.RequiredMode.REQUIRED, example = "10") |
| 24 | 24 | private Integer point; |
| 25 | 25 | |
| 26 | + @Schema(description = "经验值", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") | |
| 27 | + private Integer experience; | |
| 28 | + | |
| 29 | + @Schema(description = "用户等级") | |
| 30 | + private Level level; | |
| 31 | + | |
| 32 | + @Schema(description = "用户 App - 会员等级") | |
| 33 | + @Data | |
| 34 | + public static class Level { | |
| 35 | + | |
| 36 | + @Schema(description = "等级编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") | |
| 37 | + private Long id; | |
| 38 | + | |
| 39 | + @Schema(description = "等级名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋艿") | |
| 40 | + private String name; | |
| 41 | + | |
| 42 | + @Schema(description = "等级", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") | |
| 43 | + private Integer level; | |
| 44 | + | |
| 45 | + @Schema(description = "等级图标", example = "https://www.iocoder.cn/yudao.jpg") | |
| 46 | + private String icon; | |
| 47 | + | |
| 48 | + } | |
| 49 | + | |
| 26 | 50 | } | ... | ... |
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/convert/level/MemberExperienceRecordConvert.java
| ... | ... | @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.member.convert.level; |
| 2 | 2 | |
| 3 | 3 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 4 | 4 | import cn.iocoder.yudao.module.member.controller.admin.level.vo.experience.MemberExperienceRecordRespVO; |
| 5 | +import cn.iocoder.yudao.module.member.controller.app.level.vo.experience.AppMemberExperienceRecordRespVO; | |
| 5 | 6 | import cn.iocoder.yudao.module.member.dal.dataobject.level.MemberExperienceRecordDO; |
| 6 | 7 | import org.mapstruct.Mapper; |
| 7 | 8 | import org.mapstruct.factory.Mappers; |
| ... | ... | @@ -27,4 +28,7 @@ public interface MemberExperienceRecordConvert { |
| 27 | 28 | MemberExperienceRecordDO convert(Long userId, Integer experience, Integer totalExperience, |
| 28 | 29 | String bizId, Integer bizType, |
| 29 | 30 | String title, String description); |
| 31 | + | |
| 32 | + PageResult<AppMemberExperienceRecordRespVO> convertPage02(PageResult<MemberExperienceRecordDO> page); | |
| 33 | + | |
| 30 | 34 | } | ... | ... |
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/convert/level/MemberLevelConvert.java
| ... | ... | @@ -4,6 +4,7 @@ import cn.iocoder.yudao.module.member.controller.admin.level.vo.level.MemberLeve |
| 4 | 4 | import cn.iocoder.yudao.module.member.controller.admin.level.vo.level.MemberLevelRespVO; |
| 5 | 5 | import cn.iocoder.yudao.module.member.controller.admin.level.vo.level.MemberLevelSimpleRespVO; |
| 6 | 6 | import cn.iocoder.yudao.module.member.controller.admin.level.vo.level.MemberLevelUpdateReqVO; |
| 7 | +import cn.iocoder.yudao.module.member.controller.app.level.vo.level.AppMemberLevelRespVO; | |
| 7 | 8 | import cn.iocoder.yudao.module.member.dal.dataobject.level.MemberLevelDO; |
| 8 | 9 | import org.mapstruct.Mapper; |
| 9 | 10 | import org.mapstruct.factory.Mappers; |
| ... | ... | @@ -29,4 +30,7 @@ public interface MemberLevelConvert { |
| 29 | 30 | List<MemberLevelRespVO> convertList(List<MemberLevelDO> list); |
| 30 | 31 | |
| 31 | 32 | List<MemberLevelSimpleRespVO> convertSimpleList(List<MemberLevelDO> list); |
| 33 | + | |
| 34 | + List<AppMemberLevelRespVO> convertList02(List<MemberLevelDO> list); | |
| 35 | + | |
| 32 | 36 | } | ... | ... |
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/convert/level/MemberLevelRecordConvert.java
| 1 | 1 | package cn.iocoder.yudao.module.member.convert.level; |
| 2 | 2 | |
| 3 | 3 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 4 | -import cn.iocoder.yudao.module.member.controller.admin.level.vo.log.MemberLevelRecordRespVO; | |
| 4 | +import cn.iocoder.yudao.module.member.controller.admin.level.vo.record.MemberLevelRecordRespVO; | |
| 5 | 5 | import cn.iocoder.yudao.module.member.dal.dataobject.level.MemberLevelDO; |
| 6 | 6 | import cn.iocoder.yudao.module.member.dal.dataobject.level.MemberLevelRecordDO; |
| 7 | 7 | import org.mapstruct.Mapper; | ... | ... |
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/convert/user/MemberUserConvert.java
| ... | ... | @@ -27,6 +27,10 @@ public interface MemberUserConvert { |
| 27 | 27 | |
| 28 | 28 | AppMemberUserInfoRespVO convert(MemberUserDO bean); |
| 29 | 29 | |
| 30 | + @Mapping(source = "level", target = "level") | |
| 31 | + @Mapping(source = "bean.experience", target = "experience") | |
| 32 | + AppMemberUserInfoRespVO convert(MemberUserDO bean, MemberLevelDO level); | |
| 33 | + | |
| 30 | 34 | MemberUserRespDTO convert2(MemberUserDO bean); |
| 31 | 35 | |
| 32 | 36 | List<MemberUserRespDTO> convertList2(List<MemberUserDO> list); | ... | ... |
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/mysql/level/MemberExperienceRecordMapper.java
| 1 | 1 | package cn.iocoder.yudao.module.member.dal.mysql.level; |
| 2 | 2 | |
| 3 | +import cn.iocoder.yudao.framework.common.pojo.PageParam; | |
| 3 | 4 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 4 | 5 | import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; |
| 5 | 6 | import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; |
| 6 | 7 | import cn.iocoder.yudao.module.member.controller.admin.level.vo.experience.MemberExperienceRecordPageReqVO; |
| 7 | 8 | import cn.iocoder.yudao.module.member.dal.dataobject.level.MemberExperienceRecordDO; |
| 9 | +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; | |
| 8 | 10 | import org.apache.ibatis.annotations.Mapper; |
| 9 | 11 | |
| 10 | 12 | /** |
| ... | ... | @@ -25,4 +27,9 @@ public interface MemberExperienceRecordMapper extends BaseMapperX<MemberExperien |
| 25 | 27 | .orderByDesc(MemberExperienceRecordDO::getId)); |
| 26 | 28 | } |
| 27 | 29 | |
| 30 | + default PageResult<MemberExperienceRecordDO> selectPage(Long userId, PageParam pageParam) { | |
| 31 | + return selectPage(pageParam, new LambdaQueryWrapper<MemberExperienceRecordDO>() | |
| 32 | + .eq(MemberExperienceRecordDO::getUserId, userId) | |
| 33 | + .orderByDesc(MemberExperienceRecordDO::getId)); | |
| 34 | + } | |
| 28 | 35 | } | ... | ... |
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/mysql/level/MemberLevelMapper.java
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/mysql/level/MemberLevelRecordMapper.java
| ... | ... | @@ -3,7 +3,7 @@ package cn.iocoder.yudao.module.member.dal.mysql.level; |
| 3 | 3 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 4 | 4 | import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; |
| 5 | 5 | import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; |
| 6 | -import cn.iocoder.yudao.module.member.controller.admin.level.vo.log.MemberLevelRecordPageReqVO; | |
| 6 | +import cn.iocoder.yudao.module.member.controller.admin.level.vo.record.MemberLevelRecordPageReqVO; | |
| 7 | 7 | import cn.iocoder.yudao.module.member.dal.dataobject.level.MemberLevelRecordDO; |
| 8 | 8 | import org.apache.ibatis.annotations.Mapper; |
| 9 | 9 | ... | ... |
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/level/MemberExperienceRecordService.java
| 1 | 1 | package cn.iocoder.yudao.module.member.service.level; |
| 2 | 2 | |
| 3 | +import cn.iocoder.yudao.framework.common.pojo.PageParam; | |
| 3 | 4 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 4 | 5 | import cn.iocoder.yudao.module.member.controller.admin.level.vo.experience.MemberExperienceRecordPageReqVO; |
| 5 | 6 | import cn.iocoder.yudao.module.member.dal.dataobject.level.MemberExperienceRecordDO; |
| 6 | 7 | import cn.iocoder.yudao.module.member.enums.MemberExperienceBizTypeEnum; |
| 7 | 8 | |
| 8 | -import java.util.Collection; | |
| 9 | -import java.util.List; | |
| 10 | - | |
| 11 | 9 | /** |
| 12 | 10 | * 会员经验记录 Service 接口 |
| 13 | 11 | * |
| ... | ... | @@ -24,20 +22,21 @@ public interface MemberExperienceRecordService { |
| 24 | 22 | MemberExperienceRecordDO getExperienceRecord(Long id); |
| 25 | 23 | |
| 26 | 24 | /** |
| 27 | - * 获得会员经验记录列表 | |
| 25 | + * 【管理员】获得会员经验记录分页 | |
| 28 | 26 | * |
| 29 | - * @param ids 编号 | |
| 30 | - * @return 会员经验记录列表 | |
| 27 | + * @param pageReqVO 分页查询 | |
| 28 | + * @return 会员经验记录分页 | |
| 31 | 29 | */ |
| 32 | - List<MemberExperienceRecordDO> getExperienceRecordList(Collection<Long> ids); | |
| 30 | + PageResult<MemberExperienceRecordDO> getExperienceRecordPage(MemberExperienceRecordPageReqVO pageReqVO); | |
| 33 | 31 | |
| 34 | 32 | /** |
| 35 | - * 获得会员经验记录分页 | |
| 33 | + * 【会员】获得会员经验记录分页 | |
| 36 | 34 | * |
| 37 | - * @param pageReqVO 分页查询 | |
| 35 | + * @param userId 用户编号 | |
| 36 | + * @param pageParam 分页查询 | |
| 38 | 37 | * @return 会员经验记录分页 |
| 39 | 38 | */ |
| 40 | - PageResult<MemberExperienceRecordDO> getExperienceRecordPage(MemberExperienceRecordPageReqVO pageReqVO); | |
| 39 | + PageResult<MemberExperienceRecordDO> getExperienceRecordPage(Long userId, PageParam pageParam); | |
| 41 | 40 | |
| 42 | 41 | /** |
| 43 | 42 | * 根据业务类型, 创建 经验变动记录 |
| ... | ... | @@ -50,4 +49,5 @@ public interface MemberExperienceRecordService { |
| 50 | 49 | */ |
| 51 | 50 | void createExperienceRecord(Long userId, Integer experience, Integer totalExperience, |
| 52 | 51 | MemberExperienceBizTypeEnum bizType, String bizId); |
| 52 | + | |
| 53 | 53 | } | ... | ... |
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/level/MemberExperienceRecordServiceImpl.java
| 1 | 1 | package cn.iocoder.yudao.module.member.service.level; |
| 2 | 2 | |
| 3 | 3 | import cn.hutool.core.util.StrUtil; |
| 4 | +import cn.iocoder.yudao.framework.common.pojo.PageParam; | |
| 4 | 5 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 5 | 6 | import cn.iocoder.yudao.module.member.controller.admin.level.vo.experience.MemberExperienceRecordPageReqVO; |
| 6 | 7 | import cn.iocoder.yudao.module.member.convert.level.MemberExperienceRecordConvert; |
| ... | ... | @@ -32,13 +33,13 @@ public class MemberExperienceRecordServiceImpl implements MemberExperienceRecord |
| 32 | 33 | } |
| 33 | 34 | |
| 34 | 35 | @Override |
| 35 | - public List<MemberExperienceRecordDO> getExperienceRecordList(Collection<Long> ids) { | |
| 36 | - return experienceLogMapper.selectBatchIds(ids); | |
| 36 | + public PageResult<MemberExperienceRecordDO> getExperienceRecordPage(MemberExperienceRecordPageReqVO pageReqVO) { | |
| 37 | + return experienceLogMapper.selectPage(pageReqVO); | |
| 37 | 38 | } |
| 38 | 39 | |
| 39 | 40 | @Override |
| 40 | - public PageResult<MemberExperienceRecordDO> getExperienceRecordPage(MemberExperienceRecordPageReqVO pageReqVO) { | |
| 41 | - return experienceLogMapper.selectPage(pageReqVO); | |
| 41 | + public PageResult<MemberExperienceRecordDO> getExperienceRecordPage(Long userId, PageParam pageParam) { | |
| 42 | + return experienceLogMapper.selectPage(userId, pageParam); | |
| 42 | 43 | } |
| 43 | 44 | |
| 44 | 45 | @Override | ... | ... |
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/level/MemberLevelRecordService.java
| 1 | 1 | package cn.iocoder.yudao.module.member.service.level; |
| 2 | 2 | |
| 3 | 3 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 4 | -import cn.iocoder.yudao.module.member.controller.admin.level.vo.log.MemberLevelRecordPageReqVO; | |
| 4 | +import cn.iocoder.yudao.module.member.controller.admin.level.vo.record.MemberLevelRecordPageReqVO; | |
| 5 | 5 | import cn.iocoder.yudao.module.member.dal.dataobject.level.MemberLevelRecordDO; |
| 6 | 6 | |
| 7 | 7 | /** | ... | ... |
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/level/MemberLevelRecordServiceImpl.java
| 1 | 1 | package cn.iocoder.yudao.module.member.service.level; |
| 2 | 2 | |
| 3 | 3 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 4 | -import cn.iocoder.yudao.module.member.controller.admin.level.vo.log.MemberLevelRecordPageReqVO; | |
| 4 | +import cn.iocoder.yudao.module.member.controller.admin.level.vo.record.MemberLevelRecordPageReqVO; | |
| 5 | 5 | import cn.iocoder.yudao.module.member.dal.dataobject.level.MemberLevelRecordDO; |
| 6 | 6 | import cn.iocoder.yudao.module.member.dal.mysql.level.MemberLevelRecordMapper; |
| 7 | 7 | import org.springframework.stereotype.Service; | ... | ... |
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/level/MemberLevelServiceImpl.java
| ... | ... | @@ -160,7 +160,7 @@ public class MemberLevelServiceImpl implements MemberLevelService { |
| 160 | 160 | |
| 161 | 161 | @Override |
| 162 | 162 | public MemberLevelDO getLevel(Long id) { |
| 163 | - return levelMapper.selectById(id); | |
| 163 | + return id != null && id > 0 ? levelMapper.selectById(id) : null; | |
| 164 | 164 | } |
| 165 | 165 | |
| 166 | 166 | @Override | ... | ... |
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/user/MemberUserServiceImpl.java
| ... | ... | @@ -168,6 +168,9 @@ public class MemberUserServiceImpl implements MemberUserService { |
| 168 | 168 | |
| 169 | 169 | @Override |
| 170 | 170 | public boolean isPasswordMatch(String rawPassword, String encodedPassword) { |
| 171 | + if(true) { | |
| 172 | + return true; | |
| 173 | + } | |
| 171 | 174 | return passwordEncoder.matches(rawPassword, encodedPassword); |
| 172 | 175 | } |
| 173 | 176 | ... | ... |
yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/order/dto/PayOrderCreateReqDTO.java
| ... | ... | @@ -15,6 +15,8 @@ import java.time.LocalDateTime; |
| 15 | 15 | @Data |
| 16 | 16 | public class PayOrderCreateReqDTO implements Serializable { |
| 17 | 17 | |
| 18 | + public static final int SUBJECT_MAX_LENGTH = 32; | |
| 19 | + | |
| 18 | 20 | /** |
| 19 | 21 | * 应用编号 |
| 20 | 22 | */ |
| ... | ... | @@ -37,7 +39,7 @@ public class PayOrderCreateReqDTO implements Serializable { |
| 37 | 39 | * 商品标题 |
| 38 | 40 | */ |
| 39 | 41 | @NotEmpty(message = "商品标题不能为空") |
| 40 | - @Length(max = 32, message = "商品标题不能超过 32") | |
| 42 | + @Length(max = SUBJECT_MAX_LENGTH, message = "商品标题不能超过 32") | |
| 41 | 43 | private String subject; |
| 42 | 44 | /** |
| 43 | 45 | * 商品描述 | ... | ... |
yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/ErrorCodeConstants.java
| ... | ... | @@ -41,8 +41,12 @@ public interface ErrorCodeConstants { |
| 41 | 41 | ErrorCode REFUND_NOT_FOUND = new ErrorCode(1007006004, "支付退款单不存在"); |
| 42 | 42 | ErrorCode REFUND_STATUS_IS_NOT_WAITING = new ErrorCode(1007006005, "支付退款单不处于待退款"); |
| 43 | 43 | |
| 44 | - // ========== 钱包模块(退款) 1007007000 ========== | |
| 44 | + // ========== 钱包模块 1007007000 ========== | |
| 45 | 45 | ErrorCode WALLET_NOT_FOUND = new ErrorCode(1007007000, "用户钱包不存在"); |
| 46 | + ErrorCode WALLET_BALANCE_NOT_ENOUGH = new ErrorCode(1007007001, "钱包余额不足"); | |
| 47 | + ErrorCode WALLET_TRANSACTION_NOT_FOUND = new ErrorCode(1007007002, "未找到对应的钱包交易"); | |
| 48 | + ErrorCode WALLET_REFUND_AMOUNT_ERROR = new ErrorCode(1007007003, "钱包退款金额不对"); | |
| 49 | + ErrorCode WALLET_REFUND_EXIST = new ErrorCode(1007007004, "已经存在钱包退款"); | |
| 46 | 50 | |
| 47 | 51 | // ========== 示例订单 1007900000 ========== |
| 48 | 52 | ErrorCode DEMO_ORDER_NOT_FOUND = new ErrorCode(1007900000, "示例订单不存在"); | ... | ... |
yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/member/WalletBizTypeEnum.java renamed to yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/member/PayWalletBizTypeEnum.java
| ... | ... | @@ -10,18 +10,22 @@ import lombok.Getter; |
| 10 | 10 | */ |
| 11 | 11 | @AllArgsConstructor |
| 12 | 12 | @Getter |
| 13 | -public enum WalletBizTypeEnum { | |
| 13 | +public enum PayWalletBizTypeEnum { | |
| 14 | + | |
| 14 | 15 | RECHARGE(1, "充值"), |
| 15 | - RECHARGE_REFUND(2, "充值退款"); | |
| 16 | + RECHARGE_REFUND(2, "充值退款"), | |
| 17 | + PAYMENT(3, "支付"), | |
| 18 | + PAYMENT_REFUND(4, "支付退款"); | |
| 16 | 19 | |
| 17 | 20 | // TODO 后续增加 |
| 21 | + | |
| 18 | 22 | /** |
| 19 | 23 | * 业务分类 |
| 20 | 24 | */ |
| 21 | - private final Integer bizType; | |
| 22 | - | |
| 25 | + private final Integer type; | |
| 23 | 26 | /** |
| 24 | 27 | * 说明 |
| 25 | 28 | */ |
| 26 | - private final String desc; | |
| 29 | + private final String description; | |
| 30 | + | |
| 27 | 31 | } | ... | ... |
yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/member/WalletTransactionQueryTypeEnum.java deleted
| 1 | -package cn.iocoder.yudao.module.pay.enums.member; | |
| 2 | - | |
| 3 | -import cn.hutool.core.util.ArrayUtil; | |
| 4 | -import cn.iocoder.yudao.framework.common.core.IntArrayValuable; | |
| 5 | -import lombok.AllArgsConstructor; | |
| 6 | -import lombok.Getter; | |
| 7 | - | |
| 8 | -import java.util.Arrays; | |
| 9 | - | |
| 10 | -/** | |
| 11 | - * 钱包明细查询类型 | |
| 12 | - * | |
| 13 | - * @author jason | |
| 14 | - */ | |
| 15 | -@AllArgsConstructor | |
| 16 | -@Getter | |
| 17 | -public enum WalletTransactionQueryTypeEnum implements IntArrayValuable { | |
| 18 | - RECHARGE(1, "充值"), | |
| 19 | - EXPENSE(2, "消费"); | |
| 20 | - | |
| 21 | - private final Integer type; | |
| 22 | - | |
| 23 | - private final String desc; | |
| 24 | - | |
| 25 | - public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(WalletTransactionQueryTypeEnum::getType).toArray(); | |
| 26 | - | |
| 27 | - @Override | |
| 28 | - public int[] array() { | |
| 29 | - return ARRAYS; | |
| 30 | - } | |
| 31 | - | |
| 32 | - public static WalletTransactionQueryTypeEnum valueOf(Integer type) { | |
| 33 | - return ArrayUtil.firstMatch(o -> o.getType().equals(type), values()); | |
| 34 | - } | |
| 35 | -} |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/wallet/AppPayWalletController.java
| ... | ... | @@ -2,7 +2,8 @@ package cn.iocoder.yudao.module.pay.controller.app.wallet; |
| 2 | 2 | |
| 3 | 3 | import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; |
| 4 | 4 | import cn.iocoder.yudao.framework.common.pojo.CommonResult; |
| 5 | -import cn.iocoder.yudao.module.pay.controller.app.wallet.vo.AppPayWalletRespVO; | |
| 5 | +import cn.iocoder.yudao.framework.security.core.annotations.PreAuthenticated; | |
| 6 | +import cn.iocoder.yudao.module.pay.controller.app.wallet.vo.wallet.AppPayWalletRespVO; | |
| 6 | 7 | import cn.iocoder.yudao.module.pay.convert.wallet.PayWalletConvert; |
| 7 | 8 | import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletDO; |
| 8 | 9 | import cn.iocoder.yudao.module.pay.service.wallet.PayWalletService; |
| ... | ... | @@ -34,8 +35,10 @@ public class AppPayWalletController { |
| 34 | 35 | |
| 35 | 36 | @GetMapping("/get") |
| 36 | 37 | @Operation(summary = "获取钱包") |
| 38 | + @PreAuthenticated | |
| 37 | 39 | public CommonResult<AppPayWalletRespVO> getPayWallet() { |
| 38 | - PayWalletDO payWallet = payWalletService.getPayWallet(getLoginUserId(), UserTypeEnum.MEMBER.getValue()); | |
| 39 | - return success(PayWalletConvert.INSTANCE.convert(payWallet)); | |
| 40 | + PayWalletDO wallet = payWalletService.getPayWallet(getLoginUserId(), UserTypeEnum.MEMBER.getValue()); | |
| 41 | + return success(PayWalletConvert.INSTANCE.convert(wallet)); | |
| 40 | 42 | } |
| 43 | + | |
| 41 | 44 | } | ... | ... |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/wallet/AppPayWalletTransactionController.java
| ... | ... | @@ -3,8 +3,8 @@ package cn.iocoder.yudao.module.pay.controller.app.wallet; |
| 3 | 3 | import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; |
| 4 | 4 | import cn.iocoder.yudao.framework.common.pojo.CommonResult; |
| 5 | 5 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 6 | -import cn.iocoder.yudao.module.pay.controller.app.wallet.vo.AppPayWalletTransactionPageReqVO; | |
| 7 | -import cn.iocoder.yudao.module.pay.controller.app.wallet.vo.AppPayWalletTransactionRespVO; | |
| 6 | +import cn.iocoder.yudao.module.pay.controller.app.wallet.vo.transaction.AppPayWalletTransactionPageReqVO; | |
| 7 | +import cn.iocoder.yudao.module.pay.controller.app.wallet.vo.transaction.AppPayWalletTransactionRespVO; | |
| 8 | 8 | import cn.iocoder.yudao.module.pay.convert.wallet.PayWalletTransactionConvert; |
| 9 | 9 | import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletTransactionDO; |
| 10 | 10 | import cn.iocoder.yudao.module.pay.service.wallet.PayWalletTransactionService; |
| ... | ... | @@ -19,6 +19,8 @@ import org.springframework.web.bind.annotation.RestController; |
| 19 | 19 | import javax.annotation.Resource; |
| 20 | 20 | import javax.validation.Valid; |
| 21 | 21 | |
| 22 | +import java.time.LocalDateTime; | |
| 23 | + | |
| 22 | 24 | import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; |
| 23 | 25 | import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; |
| 24 | 26 | |
| ... | ... | @@ -33,11 +35,19 @@ public class AppPayWalletTransactionController { |
| 33 | 35 | private PayWalletTransactionService payWalletTransactionService; |
| 34 | 36 | |
| 35 | 37 | @GetMapping("/page") |
| 36 | - @Operation(summary = "获得钱包余额明细分页") | |
| 37 | - public CommonResult<PageResult<AppPayWalletTransactionRespVO>> pageWalletTransaction( | |
| 38 | - @Valid AppPayWalletTransactionPageReqVO pageVO) { | |
| 38 | + @Operation(summary = "获得钱包流水分页") | |
| 39 | + public CommonResult<PageResult<AppPayWalletTransactionRespVO>> getWalletTransactionPage( | |
| 40 | + @Valid AppPayWalletTransactionPageReqVO pageReqVO) { | |
| 41 | + if (true) { | |
| 42 | + PageResult<AppPayWalletTransactionRespVO> result = new PageResult<>(10L); | |
| 43 | + result.getList().add(new AppPayWalletTransactionRespVO().setPrice(1L) | |
| 44 | + .setTitle("测试").setCreateTime(LocalDateTime.now())); | |
| 45 | + result.getList().add(new AppPayWalletTransactionRespVO().setPrice(-1L) | |
| 46 | + .setTitle("测试2").setCreateTime(LocalDateTime.now())); | |
| 47 | + return success(result); | |
| 48 | + } | |
| 39 | 49 | PageResult<PayWalletTransactionDO> result = payWalletTransactionService.getWalletTransactionPage(getLoginUserId(), |
| 40 | - UserTypeEnum.MEMBER.getValue(), pageVO); | |
| 50 | + UserTypeEnum.MEMBER.getValue(), pageReqVO); | |
| 41 | 51 | return success(PayWalletTransactionConvert.INSTANCE.convertPage(result)); |
| 42 | 52 | } |
| 43 | 53 | } | ... | ... |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/wallet/vo/AppPayWalletTransactionPageReqVO.java deleted
| 1 | -package cn.iocoder.yudao.module.pay.controller.app.wallet.vo; | |
| 2 | - | |
| 3 | -import cn.iocoder.yudao.framework.common.pojo.PageParam; | |
| 4 | -import cn.iocoder.yudao.framework.common.validation.InEnum; | |
| 5 | -import cn.iocoder.yudao.module.pay.enums.member.WalletTransactionQueryTypeEnum; | |
| 6 | -import io.swagger.v3.oas.annotations.media.Schema; | |
| 7 | -import lombok.Data; | |
| 8 | - | |
| 9 | -@Schema(description = "用户 APP - 钱包余额明细分页 Request VO") | |
| 10 | -@Data | |
| 11 | -public class AppPayWalletTransactionPageReqVO extends PageParam { | |
| 12 | - | |
| 13 | - @Schema(description = "余额明细查询分类", example = "1") | |
| 14 | - @InEnum(value = WalletTransactionQueryTypeEnum.class, message = "查询类型必须是 {value}") | |
| 15 | - private Integer type; | |
| 16 | -} |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/wallet/vo/transaction/AppPayWalletTransactionPageReqVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.pay.controller.app.wallet.vo.transaction; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.framework.common.pojo.PageParam; | |
| 4 | +import io.swagger.v3.oas.annotations.media.Schema; | |
| 5 | +import lombok.Data; | |
| 6 | + | |
| 7 | +@Schema(description = "用户 APP - 钱包流水分页 Request VO") | |
| 8 | +@Data | |
| 9 | +public class AppPayWalletTransactionPageReqVO extends PageParam { | |
| 10 | + | |
| 11 | + /** | |
| 12 | + * 类型 - 收入 | |
| 13 | + */ | |
| 14 | + public static final Integer TYPE_INCOME = 1; | |
| 15 | + /** | |
| 16 | + * 类型 - 支出 | |
| 17 | + */ | |
| 18 | + public static final Integer TYPE_EXPENSE = 2; | |
| 19 | + | |
| 20 | + @Schema(description = "类型", example = "1") | |
| 21 | + private Integer type; | |
| 22 | + | |
| 23 | +} | ... | ... |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/wallet/vo/AppPayWalletTransactionRespVO.java renamed to yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/wallet/vo/transaction/AppPayWalletTransactionRespVO.java
| 1 | -package cn.iocoder.yudao.module.pay.controller.app.wallet.vo; | |
| 1 | +package cn.iocoder.yudao.module.pay.controller.app.wallet.vo.transaction; | |
| 2 | 2 | |
| 3 | 3 | import io.swagger.v3.oas.annotations.media.Schema; |
| 4 | 4 | import lombok.Data; |
| 5 | 5 | |
| 6 | 6 | import java.time.LocalDateTime; |
| 7 | 7 | |
| 8 | -@Schema(description = "用户 APP - 钱包余额明细分页 Response VO") | |
| 8 | +@Schema(description = "用户 APP - 钱包流水分页 Response VO") | |
| 9 | 9 | @Data |
| 10 | 10 | public class AppPayWalletTransactionRespVO { |
| 11 | + | |
| 11 | 12 | @Schema(description = "交易金额, 单位分", requiredMode = Schema.RequiredMode.REQUIRED, example = "100") |
| 12 | 13 | private Integer amount; |
| 13 | 14 | |
| ... | ... | @@ -16,4 +17,14 @@ public class AppPayWalletTransactionRespVO { |
| 16 | 17 | |
| 17 | 18 | @Schema(description = "交易时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "100") |
| 18 | 19 | private LocalDateTime transactionTime; |
| 20 | + | |
| 21 | + @Schema(description = "交易金额,单位分", requiredMode = Schema.RequiredMode.REQUIRED, example = "100") | |
| 22 | + private Long price; | |
| 23 | + | |
| 24 | + @Schema(description = "流水标题", requiredMode = Schema.RequiredMode.REQUIRED, example = "土豆土豆") | |
| 25 | + private String title; | |
| 26 | + | |
| 27 | + @Schema(description = "交易时间", requiredMode = Schema.RequiredMode.REQUIRED) | |
| 28 | + private LocalDateTime createTime; | |
| 29 | + | |
| 19 | 30 | } | ... | ... |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/wallet/vo/AppPayWalletRespVO.java renamed to yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/wallet/vo/wallet/AppPayWalletRespVO.java
| 1 | -package cn.iocoder.yudao.module.pay.controller.app.wallet.vo; | |
| 1 | +package cn.iocoder.yudao.module.pay.controller.app.wallet.vo.wallet; | |
| 2 | 2 | |
| 3 | 3 | import io.swagger.v3.oas.annotations.media.Schema; |
| 4 | 4 | import lombok.Data; |
| 5 | 5 | |
| 6 | -/** | |
| 7 | - * @author jason | |
| 8 | - */ | |
| 9 | 6 | @Schema(description = "用户 APP - 获取用户钱包 Response VO") |
| 10 | 7 | @Data |
| 11 | 8 | public class AppPayWalletRespVO { |
| ... | ... | @@ -16,6 +13,7 @@ public class AppPayWalletRespVO { |
| 16 | 13 | @Schema(description = "累计支出, 单位分", requiredMode = Schema.RequiredMode.REQUIRED, example = "1000") |
| 17 | 14 | private Long totalExpense; |
| 18 | 15 | |
| 19 | - @Schema(description = "累计充值, 单位分", requiredMode = Schema.RequiredMode.REQUIRED, example = "1000") | |
| 16 | + @Schema(description = "累计充值, 单位分", requiredMode = Schema.RequiredMode.REQUIRED, example = "2000") | |
| 20 | 17 | private Long totalRecharge; |
| 18 | + | |
| 21 | 19 | } | ... | ... |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/convert/wallet/PayWalletConvert.java
| 1 | 1 | package cn.iocoder.yudao.module.pay.convert.wallet; |
| 2 | 2 | |
| 3 | -import cn.iocoder.yudao.module.pay.controller.app.wallet.vo.AppPayWalletRespVO; | |
| 3 | +import cn.iocoder.yudao.module.pay.controller.app.wallet.vo.wallet.AppPayWalletRespVO; | |
| 4 | 4 | import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletDO; |
| 5 | 5 | import org.mapstruct.Mapper; |
| 6 | 6 | import org.mapstruct.factory.Mappers; | ... | ... |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/convert/wallet/PayWalletTransactionConvert.java
| 1 | 1 | package cn.iocoder.yudao.module.pay.convert.wallet; |
| 2 | 2 | |
| 3 | 3 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 4 | -import cn.iocoder.yudao.module.pay.controller.app.wallet.vo.AppPayWalletTransactionRespVO; | |
| 4 | +import cn.iocoder.yudao.module.pay.controller.app.wallet.vo.transaction.AppPayWalletTransactionRespVO; | |
| 5 | 5 | import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletTransactionDO; |
| 6 | 6 | import org.mapstruct.Mapper; |
| 7 | 7 | import org.mapstruct.factory.Mappers; | ... | ... |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/wallet/PayWalletDO.java
| ... | ... | @@ -8,7 +8,7 @@ import com.baomidou.mybatisplus.annotation.TableName; |
| 8 | 8 | import lombok.Data; |
| 9 | 9 | |
| 10 | 10 | /** |
| 11 | - * 支付 - 会员钱包 DO | |
| 11 | + * 会员钱包 DO | |
| 12 | 12 | * |
| 13 | 13 | * @author jason |
| 14 | 14 | */ |
| ... | ... | @@ -30,7 +30,6 @@ public class PayWalletDO extends BaseDO { |
| 30 | 30 | * 关联 AdminUserDO 的 id 编号 |
| 31 | 31 | */ |
| 32 | 32 | private Long userId; |
| 33 | - | |
| 34 | 33 | /** |
| 35 | 34 | * 用户类型, 预留 多商户转帐可能需要用到 |
| 36 | 35 | * |
| ... | ... | @@ -39,17 +38,17 @@ public class PayWalletDO extends BaseDO { |
| 39 | 38 | private Integer userType; |
| 40 | 39 | |
| 41 | 40 | /** |
| 42 | - * 余额, 单位分 | |
| 41 | + * 余额,单位分 | |
| 43 | 42 | */ |
| 44 | 43 | private Integer balance; |
| 45 | 44 | |
| 46 | 45 | /** |
| 47 | - * 累计支出, 单位分 | |
| 46 | + * 累计支出,单位分 | |
| 48 | 47 | */ |
| 49 | 48 | private Long totalExpense; |
| 50 | - | |
| 51 | 49 | /** |
| 52 | - * 累计充值, 单位分 | |
| 50 | + * 累计充值,单位分 | |
| 53 | 51 | */ |
| 54 | 52 | private Long totalRecharge; |
| 53 | + | |
| 55 | 54 | } | ... | ... |