ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/domain/dto/MerVerifyMemberCouponDto.java
@@ -14,7 +14,7 @@ public class MerVerifyMemberCouponDto { @ApiModelProperty(value = "优惠券id") private String couponId; private Long couponId; @ApiModelProperty(value = "商户id") private Long shopId; ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/domain/poji/member/MemberCoupon.java
@@ -29,7 +29,7 @@ private static final long serialVersionUID = 1L; @TableId(value = "id") private String id; private Long id; /** * 删除标记 */ ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/domain/vo/MerVerifyCouponGetVo.java
@@ -18,7 +18,7 @@ public class MerVerifyCouponGetVo { @ApiModelProperty(value = "优惠券id") private String memberCouponId; private Long memberCouponId; @ApiModelProperty(value = "用户id") private Long userId; ruoyi-modules/ruoyi-member/pom.xml
@@ -59,13 +59,7 @@ <groupId>com.ruoyi</groupId> <artifactId>ruoyi-common-datasource</artifactId> </dependency> <!-- RuoYi Common DataScope --> <dependency> <groupId>com.ruoyi</groupId> <artifactId>ruoyi-common-datascope</artifactId> </dependency> <!-- RuoYi Common Log --> <dependency> <groupId>com.ruoyi</groupId> @@ -120,6 +114,24 @@ <artifactId>alibabacloud-dysmsapi20170525</artifactId> <version>2.0.24</version> </dependency> <!-- https://mvnrepository.com/artifact/org.apache.shardingsphere/sharding-jdbc-spring-boot-starter --> <dependency> <groupId>org.apache.shardingsphere</groupId> <artifactId>sharding-jdbc-spring-boot-starter</artifactId> <version>4.1.1</version> <exclusions> <exclusion> <artifactId>guava</artifactId> <groupId>com.google.guava</groupId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> ruoyi-modules/ruoyi-member/src/main/java/com/ruoyi/member/RuoYiMemberApplication.java
@@ -7,6 +7,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.ComponentScans; import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.scheduling.annotation.EnableScheduling; /** @@ -19,6 +20,7 @@ @EnableRyFeignClients @SpringBootApplication @EnableScheduling @EnableAsync @ComponentScans(value = {@ComponentScan("com.ruoyi.system.api"),@ComponentScan("com.ruoyi.common.security.utils")}) public class RuoYiMemberApplication { ruoyi-modules/ruoyi-member/src/main/java/com/ruoyi/member/config/DataSourceConfiguration.java
New file @@ -0,0 +1,85 @@ package com.ruoyi.member.config; import com.baomidou.dynamic.datasource.DynamicRoutingDataSource; import com.baomidou.dynamic.datasource.provider.AbstractDataSourceProvider; import com.baomidou.dynamic.datasource.provider.DynamicDataSourceProvider; import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DataSourceProperty; import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DynamicDataSourceAutoConfiguration; import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DynamicDataSourceProperties; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.SpringBootConfiguration; import org.springframework.boot.autoconfigure.AutoConfigureBefore; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; import javax.annotation.Resource; import javax.sql.DataSource; import java.util.Map; /** * @author mitao * @date 2024/3/2 */ @Configuration @AutoConfigureBefore({DynamicDataSourceAutoConfiguration.class, SpringBootConfiguration.class}) public class DataSourceConfiguration { /** * 分表数据源名称 */ private static final String SHARDING_DATA_SOURCE_NAME = "sharding"; /** * 动态数据源配置项 */ @Autowired private DynamicDataSourceProperties properties; /** * shardingjdbc有四种数据源,需要根据业务注入不同的数据源 * * <p>1. 未使用分片, 脱敏的名称(默认): shardingDataSource; * <p>2. 主从数据源: masterSlaveDataSource; * <p>3. 脱敏数据源:encryptDataSource; * <p>4. 影子数据源:shadowDataSource * */ @Resource private DataSource shardingSphereDataSource; @Bean public DynamicDataSourceProvider dynamicDataSourceProvider() { Map<String, DataSourceProperty> datasourceMap = properties.getDatasource(); return new AbstractDataSourceProvider() { @Override public Map<String, DataSource> loadDataSources() { Map<String, DataSource> dataSourceMap = createDataSourceMap(datasourceMap); // 将 shardingjdbc 管理的数据源也交给动态数据源管理 dataSourceMap.put(SHARDING_DATA_SOURCE_NAME, shardingSphereDataSource); return dataSourceMap; } }; } /** * 将动态数据源设置为首选的 * 当spring存在多个数据源时, 自动注入的是首选的对象 * 设置为主要的数据源之后,就可以支持shardingjdbc原生的配置方式了 */ @Primary @Bean public DataSource dataSource() { DynamicRoutingDataSource dataSource = new DynamicRoutingDataSource(); dataSource.setPrimary(properties.getPrimary()); dataSource.setStrict(properties.getStrict()); dataSource.setStrategy(properties.getStrategy()); dataSource.setP6spy(properties.getP6spy()); dataSource.setSeata(properties.getSeata()); return dataSource; } } ruoyi-modules/ruoyi-member/src/main/java/com/ruoyi/member/config/DataSourceHealthConfig.java
New file @@ -0,0 +1,65 @@ package com.ruoyi.member.config; import com.zaxxer.hikari.HikariDataSource; import org.springframework.beans.factory.ObjectProvider; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.actuate.autoconfigure.jdbc.DataSourceHealthContributorAutoConfiguration; import org.springframework.boot.actuate.health.AbstractHealthIndicator; import org.springframework.boot.actuate.jdbc.DataSourceHealthIndicator; import org.springframework.boot.jdbc.metadata.DataSourcePoolMetadata; import org.springframework.boot.jdbc.metadata.DataSourcePoolMetadataProvider; import org.springframework.boot.jdbc.metadata.HikariDataSourcePoolMetadata; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.util.StringUtils; import javax.sql.DataSource; import java.util.Map; @Configuration public class DataSourceHealthConfig { /** * 解决新版Spring中,健康健康检查用到 sharding jdbc 时,该组件没有完全实现MySQL驱动导致的问题. */ @Bean DataSourcePoolMetadataProvider dataSourcePoolMetadataProvider() { return dataSource -> new NotAvailableDataSourcePoolMetadata(); } /** * 不可用的数据源池元数据. */ private static class NotAvailableDataSourcePoolMetadata implements DataSourcePoolMetadata { @Override public Float getUsage() { return null; } @Override public Integer getActive() { return null; } @Override public Integer getMax() { return null; } @Override public Integer getMin() { return null; } @Override public String getValidationQuery() { // 该字符串是适用于MySQL的简单查询语句,用于检查检查,其他数据库可能需要更换 return "select 1"; } @Override public Boolean getDefaultAutoCommit() { return null; } } } ruoyi-modules/ruoyi-member/src/main/java/com/ruoyi/member/mapper/member/MemberCouponMapper.java
@@ -86,5 +86,5 @@ * @param shopId * @return void */ void sureMemberCoupon(@Param("memberCouponId")String memberCouponId,@Param("shopId")Long shopId); void sureMemberCoupon(@Param("memberCouponId")Long memberCouponId,@Param("shopId")Long shopId); } ruoyi-modules/ruoyi-member/src/main/java/com/ruoyi/member/service/impl/coupon/CouponServiceImpl.java
@@ -31,13 +31,13 @@ import com.ruoyi.system.api.service.RemoteConfigService; import com.ruoyi.system.api.service.RemoteGoodsService; import com.ruoyi.system.api.service.RemoteShopService; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import javax.annotation.Resource; import java.math.BigDecimal; import java.util.*; import java.util.concurrent.CompletableFuture; import java.util.concurrent.TimeUnit; import java.util.function.Function; import java.util.stream.Collectors; @@ -432,7 +432,7 @@ coupon.setRelGoodsIds(relGoodsIds); } //判断是否指定用户 List<Long> relUserIdList = null; List<Long> relUserIdList; if(coupon.getSendTarget()==5&&coupon.getRelationType()==1&&!mgtCouponEditDto.getRelUserIdList().isEmpty()){ relUserIdList = mgtCouponEditDto.getRelUserIdList(); List<CouponRelUser> couponRelUserList = new ArrayList<>(); @@ -448,10 +448,12 @@ } couponRelUserService.saveBatch(couponRelUserList); coupon.setRelUserIds(userIdSj.toString()); } else { relUserIdList = null; } //处理优惠券发放 if(coupon.getSendFlag() == 0 && coupon.getSendType()==2&&coupon.getSendTimeType()==1){ sendCoupon(coupon,relUserIdList); CompletableFuture.runAsync(()->sendCoupon(coupon,relUserIdList)); coupon.setSendFlag(1); this.saveOrUpdate(coupon); }else{ @@ -467,7 +469,6 @@ * @param relUserIdList * @return void */ @Async protected void sendCoupon(Coupon coupon, List<Long> relUserIdList){ //1.手动领取2.全部用户3.会员用户4非会员用户5自定义 Date nowTime = new Date(); @@ -507,14 +508,11 @@ MemberCoupon memberCoupon; Integer sendTotal = 0; Integer sendPerson = 0; String memberCouponId; Integer sendUserTotal; for(Long userId : userIdList){ if(coupon.getCouponFrom()==2){ for(int i=0;i<coupon.getLimitNumber();i++){ memberCouponId = IdUtils.simpleUUID(); memberCoupon = new MemberCoupon(); memberCoupon.setId(memberCouponId); memberCoupon.setDelFlag(0); memberCoupon.setCouponId(coupon.getCouponId()); memberCoupon.setUserId(userId); @@ -564,56 +562,56 @@ memberCouponRecordService.updateMemberCouponRecord(coupon,userId,1); } }else{ memberCouponId = IdUtils.simpleUUID(); memberCoupon = new MemberCoupon(); memberCoupon.setId(memberCouponId); memberCoupon.setDelFlag(0); memberCoupon.setCouponId(coupon.getCouponId()); memberCoupon.setUserId(userId); //memberCoupon.setShopId(coupon.getShopId()); memberCoupon.setCouponType(coupon.getCouponType()); if(coupon.getCouponType()==1){ memberCoupon.setMoneyThreshold(coupon.getMoneyThreshold()); memberCoupon.setDiscountMoney(coupon.getDiscountMoney()); }else if(coupon.getCouponType()==2){ memberCoupon.setDiscountPercent(coupon.getDiscountPercent()); }else if(coupon.getCouponType()==3){ memberCoupon.setDiscountMoney(coupon.getDiscountMoney()); }else{ memberCoupon.setRelGoodsIds(coupon.getRelGoodsIds()); } memberCoupon.setCouponStatus(coupon.getCouponStatus()); memberCoupon.setCouponName(coupon.getCouponName()); memberCoupon.setSendType(coupon.getSendType()); memberCoupon.setSendTarget(coupon.getSendTarget()); memberCoupon.setSendTimeType(coupon.getSendTimeType()); memberCoupon.setSendTime(coupon.getSendTime()); memberCoupon.setUseScope(coupon.getUseScope()); if(memberCoupon.getUseScope()==2){ memberCoupon.setRelGoodsIds(coupon.getRelGoodsIds()); } memberCoupon.setValidTimeType(coupon.getValidTimeType()); memberCoupon.setValidStartTime(coupon.getValidStartTime()); memberCoupon.setValidEndTime(coupon.getValidEndTime()); memberCoupon.setValidDay(coupon.getValidDay()); memberCoupon.setCouponFrom(coupon.getCouponFrom()); memberCoupon.setReceiveTime(nowTime); //有效期处理1.时间段2.领取之日起 if(coupon.getValidTimeType()==1){ memberCoupon.setDeadlineTime(coupon.getValidEndTime()); }else if(coupon.getValidTimeType()==2){ memberCoupon.setDeadlineTime(DateUtils.addDays(nowTime,coupon.getValidDay())); } memberCouponList.add(memberCoupon); sendTotal = sendTotal + 1; if(coupon.getSendType()==1){ sendUserTotal = memberCouponService.totalMemberCouponByUserAndCoupon(userId,coupon.getCouponId()); if(sendUserTotal!=null&&sendUserTotal>0){ for (Integer i = 0; i < coupon.getLimitNumber(); i++) { memberCoupon = new MemberCoupon(); memberCoupon.setDelFlag(0); memberCoupon.setCouponId(coupon.getCouponId()); memberCoupon.setUserId(userId); //memberCoupon.setShopId(coupon.getShopId()); memberCoupon.setCouponType(coupon.getCouponType()); if(coupon.getCouponType()==1){ memberCoupon.setMoneyThreshold(coupon.getMoneyThreshold()); memberCoupon.setDiscountMoney(coupon.getDiscountMoney()); }else if(coupon.getCouponType()==2){ memberCoupon.setDiscountPercent(coupon.getDiscountPercent()); }else if(coupon.getCouponType()==3){ memberCoupon.setDiscountMoney(coupon.getDiscountMoney()); }else{ sendPerson = sendPerson + 1; memberCoupon.setRelGoodsIds(coupon.getRelGoodsIds()); } memberCoupon.setCouponStatus(coupon.getCouponStatus()); memberCoupon.setCouponName(coupon.getCouponName()); memberCoupon.setSendType(coupon.getSendType()); memberCoupon.setSendTarget(coupon.getSendTarget()); memberCoupon.setSendTimeType(coupon.getSendTimeType()); memberCoupon.setSendTime(coupon.getSendTime()); memberCoupon.setUseScope(coupon.getUseScope()); if(memberCoupon.getUseScope()==2){ memberCoupon.setRelGoodsIds(coupon.getRelGoodsIds()); } memberCoupon.setValidTimeType(coupon.getValidTimeType()); memberCoupon.setValidStartTime(coupon.getValidStartTime()); memberCoupon.setValidEndTime(coupon.getValidEndTime()); memberCoupon.setValidDay(coupon.getValidDay()); memberCoupon.setCouponFrom(coupon.getCouponFrom()); memberCoupon.setReceiveTime(nowTime); //有效期处理1.时间段2.领取之日起 if(coupon.getValidTimeType()==1){ memberCoupon.setDeadlineTime(coupon.getValidEndTime()); }else if(coupon.getValidTimeType()==2){ memberCoupon.setDeadlineTime(DateUtils.addDays(nowTime,coupon.getValidDay())); } memberCouponList.add(memberCoupon); sendTotal = sendTotal + 1; if(coupon.getSendType()==1){ sendUserTotal = memberCouponService.totalMemberCouponByUserAndCoupon(userId,coupon.getCouponId()); if(sendUserTotal!=null&&sendUserTotal>0){ }else{ sendPerson = sendPerson + 1; } } memberCouponRecordService.updateMemberCouponRecord(coupon,userId,1); } memberCouponRecordService.updateMemberCouponRecord(coupon,userId,1); } } memberCouponService.saveBatch(memberCouponList); @@ -663,12 +661,9 @@ MemberCoupon memberCoupon; Integer sendTotal = 0; Integer sendPerson = 0; String memberCouponId; Integer sendUserTotal; for(Long userId : userIdList){ memberCouponId = IdUtils.simpleUUID(); memberCoupon = new MemberCoupon(); memberCoupon.setId(memberCouponId); memberCoupon.setDelFlag(0); memberCoupon.setCouponId(coupon.getCouponId()); memberCoupon.setUserId(userId); @@ -1253,8 +1248,9 @@ // 根据优惠券数量生成会员优惠券列表 for(int i=0;i<birthdayGiftSendDto.getCouponNumber();i++){ memberCoupon = new MemberCoupon(); //TODO memberCouponId = IdUtils.simpleUUID(); memberCoupon.setId(memberCouponId); //memberCoupon.setId(memberCouponId); memberCoupon.setDelFlag(0); memberCoupon.setCouponId(couponId); memberCoupon.setUserId(userId); @@ -1425,8 +1421,8 @@ } //生成用户优惠券 MemberCoupon memberCoupon = new MemberCoupon(); String memberCouponId = IdUtils.simpleUUID(); memberCoupon.setId(memberCouponId); //String memberCouponId = IdUtils.simpleUUID(); //memberCoupon.setId(memberCouponId); memberCoupon.setDelFlag(0); memberCoupon.setCouponId(couponId); memberCoupon.setUserId(userId); @@ -1466,8 +1462,8 @@ }else if(coupon.getValidTimeType()==2){ memberCoupon.setDeadlineTime(DateUtils.addDays(new Date(),coupon.getValidDay())); } memberCouponService.save(memberCoupon); memberCouponRecordService.updateMemberCouponRecord(coupon,userId,1); memberCouponService.insert(memberCoupon); } /** ruoyi-modules/ruoyi-member/src/main/java/com/ruoyi/member/service/impl/member/MemberCouponServiceImpl.java
@@ -1,5 +1,6 @@ package com.ruoyi.member.service.impl.member; import com.baomidou.dynamic.datasource.annotation.DS; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; @@ -42,6 +43,7 @@ * @since 2023-04-25 */ @Service @DS("sharding") public class MemberCouponServiceImpl extends ServiceImpl<MemberCouponMapper, MemberCoupon> implements MemberCouponService { @Resource @@ -356,7 +358,13 @@ * @return void */ @Override public void sureMemberCoupon(String memberCouponId,Long shopId){ public void sureMemberCoupon(Long memberCouponId, Long shopId){ memberCouponMapper.sureMemberCoupon(memberCouponId, shopId); } @Override @Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class) public void insert(MemberCoupon memberCoupon) { this.baseMapper.insert(memberCoupon); } } ruoyi-modules/ruoyi-member/src/main/java/com/ruoyi/member/service/member/MemberCouponService.java
@@ -116,5 +116,7 @@ * @param shopId * @return void */ void sureMemberCoupon(String memberCouponId,Long shopId); void sureMemberCoupon(Long memberCouponId,Long shopId); void insert(MemberCoupon memberCoupon); } ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/domain/pojo/order/ConsumerGoods.java
@@ -135,7 +135,7 @@ * 用户优惠券id */ @TableField("member_coupon_id") private String memberCouponId; private Long memberCouponId; @TableField("sure_num") private Integer sureNum; ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/domain/vo/MerVerifyCouponVo.java
@@ -28,7 +28,7 @@ private String userMobile; @ApiModelProperty(value = "优惠券id") private String memberCouponId; private Long memberCouponId; @ApiModelProperty(value = "优惠券名称") private String couponName;