Prechádzať zdrojové kódy

fix(app):
1.接口防抖,防重复提交注解
2.bug修复

wzq 3 týždňov pred
rodič
commit
6a3c4938f4
13 zmenil súbory, kde vykonal 215 pridanie a 47 odobranie
  1. 5 1
      national-motion-base-core/pom.xml
  2. 66 0
      national-motion-base-core/src/main/java/org/jeecg/common/aspect/NoRepeatSubmitAspect.java
  3. 27 0
      national-motion-base-core/src/main/java/org/jeecg/common/aspect/annotation/RepeatSubmit.java
  4. 5 1
      national-motion-base-core/src/main/java/org/jeecg/common/constant/CommonConstant.java
  5. 16 0
      national-motion-base-core/src/main/java/org/jeecg/config/RepeatAutoConfiguration.java
  6. 2 2
      national-motion-base-core/src/main/java/org/jeecg/config/shiro/ShiroConfig.java
  7. 3 1
      national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/app/controller/OrderController.java
  8. 12 9
      national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/app/service/impl/OrderServiceImpl.java
  9. 11 8
      national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/redission/RedissonDelayQueue.java
  10. 2 1
      national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/system/app/mapper/xml/AppSitePriceRulesMapper.xml
  11. 4 3
      national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/system/app/service/impl/AppCoureseServiceImpl.java
  12. 31 1
      national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/system/app/service/impl/AppCoursesVerificationRecordServiceImpl.java
  13. 31 20
      national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/system/app/service/impl/AppOrderServiceImpl.java

+ 5 - 1
national-motion-base-core/pom.xml

@@ -319,5 +319,9 @@
 			<groupId>org.jeecgframework.boot</groupId>
 			<artifactId>jeecg-boot-starter-chatgpt</artifactId>
 		</dependency>
-	</dependencies>
+        <dependency>
+            <groupId>org.redisson</groupId>
+            <artifactId>redisson</artifactId>
+        </dependency>
+    </dependencies>
 </project>

+ 66 - 0
national-motion-base-core/src/main/java/org/jeecg/common/aspect/NoRepeatSubmitAspect.java

@@ -0,0 +1,66 @@
+package org.jeecg.common.aspect;
+
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Pointcut;
+import org.aspectj.lang.reflect.MethodSignature;
+import org.jeecg.common.aspect.annotation.RepeatSubmit;
+import org.redisson.api.RedissonClient;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import javax.servlet.http.HttpServletRequest;
+import java.lang.reflect.Method;
+import java.util.concurrent.TimeUnit;
+
+@Aspect  // 定义一个切面
+@Component  // 标识为Spring组件
+public class NoRepeatSubmitAspect {
+
+    @Autowired
+    private RedissonClient redissonClient;  // 注入RedissonClient,用于分布式锁
+
+    // 定义切入点,匹配所有被RepeatSubmit注解标注的方法
+    @Pointcut("@annotation(repeatSubmit)")
+    public void pointCutNoRepeatSubmit(RepeatSubmit repeatSubmit) {
+    }
+
+    // 定义环绕通知
+    @Around("pointCutNoRepeatSubmit(repeatSubmit)")
+    public Object around(ProceedingJoinPoint joinPoint, RepeatSubmit repeatSubmit) throws Throwable {
+        // 获取当前HTTP请求
+        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
+        String serviceId = repeatSubmit.serviceId();  // 获取RepeatSubmit注解中的serviceId
+        String type = repeatSubmit.limitType().name();  // 获取防重提交的类型
+        if (type.equalsIgnoreCase(RepeatSubmit.Type.PARAM.name())) {
+            long lockTime = repeatSubmit.lockTime();  // 获取锁的超时时间
+            String ipAddr = request.getRemoteAddr();  // 获取客户端IP地址
+            MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
+            Method method = methodSignature.getMethod();  // 获取目标方法
+
+            // 生成唯一的key,用于获取分布式锁
+            String key = generateUniqueKey(ipAddr, method, serviceId);
+            boolean isLocked = redissonClient.getLock(key).tryLock(lockTime, TimeUnit.MILLISECONDS);  // 尝试获取锁
+
+            if (!isLocked) {
+                throw new RuntimeException("重复提交,请稍后再试");  // 如果获取锁失败,抛出异常
+            }
+
+            try {
+                Object result = joinPoint.proceed();  // 执行目标方法 这里的目标方法是使用了@repeatSubmit注解的方法
+                return result;  // 返回目标方法的执行结果
+            } finally {
+                redissonClient.getLock(key).unlock();  // 释放锁  不释放的话可以在上面上锁时定义自动释放
+            }
+        }
+        return joinPoint.proceed();  // 默认执行目标方法
+    }
+
+    // 生成唯一的key,用于获取分布式锁
+    private String generateUniqueKey(String ipAddr, Method method, String serviceId) {
+        return ipAddr + ":" + method.getDeclaringClass().getName() + "." + method.getName() + ":" + serviceId;
+    }
+}

+ 27 - 0
national-motion-base-core/src/main/java/org/jeecg/common/aspect/annotation/RepeatSubmit.java

@@ -0,0 +1,27 @@
+package org.jeecg.common.aspect.annotation;
+import java.lang.annotation.*;
+
+@Documented
+@Target(ElementType.METHOD)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface RepeatSubmit {
+
+    /**
+     * 设置默认的防重提交方式为基于方法参数。也可以使用默认值
+     */
+    Type limitType() default Type.PARAM;
+
+    /**
+     * 允许设置加锁的过期时间,默认为5秒。这意味着在第一次请求之后的5秒内,相同的请求将被视为重复并被阻止
+     */
+    long lockTime() default 5;
+
+    //提供了一个可选的服务ID参数,通过token时用作KEY计算
+    String serviceId() default "";
+
+    /**
+     * 定义了两种防止重复提交的方式,PARAM 表示基于方法参数来防止重复,TOKEN 则可能涉及生成和验证token的机制
+     */
+    enum Type {PARAM, TOKEN}
+}
+

+ 5 - 1
national-motion-base-core/src/main/java/org/jeecg/common/constant/CommonConstant.java

@@ -666,10 +666,14 @@ public interface CommonConstant {
     Integer ISIN_STATUS_2 = 2;
 
     /**
-     * 子订单状态(0-待使用 1-已使用 2-已取消)
+     * 子订单状态0-待付款 1-待使用 2-已使用 3-已到期 4-已取消 5-退款中 6已退款
      */
     Integer ORDER_STATUS_0 = 0;
     Integer ORDER_STATUS_1 = 1;
     Integer ORDER_STATUS_2 = 2;
+    Integer ORDER_STATUS_3 = 3;
+    Integer ORDER_STATUS_4 = 4;
+    Integer ORDER_STATUS_5 = 5;
+    Integer ORDER_STATUS_6 = 6;
 
 }

+ 16 - 0
national-motion-base-core/src/main/java/org/jeecg/config/RepeatAutoConfiguration.java

@@ -0,0 +1,16 @@
+package org.jeecg.config;
+
+import org.jeecg.common.aspect.NoRepeatSubmitAspect;
+import org.springframework.boot.autoconfigure.AutoConfigureAfter;
+import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration(proxyBeanMethods = false)
+@AutoConfigureAfter(RedisAutoConfiguration.class)
+public class RepeatAutoConfiguration {
+    @Bean
+    public NoRepeatSubmitAspect repeatSubmitAspect() {
+        return new NoRepeatSubmitAspect();
+    }
+}

+ 2 - 2
national-motion-base-core/src/main/java/org/jeecg/config/shiro/ShiroConfig.java

@@ -106,8 +106,8 @@ public class ShiroConfig {
         filterChainDefinitionMap.put("/app/user/loginByCode", "anon");//APP首页接口
         filterChainDefinitionMap.put("/app/esign/signCallback", "anon");//APP首页接口
 
-        filterChainDefinitionMap.put("/applet/wechatPayNotify", "anon");//支付回调
-        filterChainDefinitionMap.put("/applet/refundOrderNotify", "anon");//退款回调
+        filterChainDefinitionMap.put("/app/order/wechatPayNotify", "anon");//支付回调
+        filterChainDefinitionMap.put("/app/order/refundOrderNotify", "anon");//退款回调
 
 
 //        filterChainDefinitionMap.put("/app/user/**", "anon");//小程序相关

+ 3 - 1
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/app/controller/OrderController.java

@@ -7,6 +7,7 @@ import io.swagger.v3.oas.annotations.media.Schema;
 import io.swagger.v3.oas.annotations.tags.Tag;
 import lombok.extern.slf4j.Slf4j;
 import org.jeecg.common.api.vo.Result;
+import org.jeecg.common.aspect.annotation.RepeatSubmit;
 import org.jeecg.modules.app.dto.AppOrderInfoDTO;
 import org.jeecg.modules.app.form.CreateOrderForm;
 import org.jeecg.modules.app.form.PageOrdersForm;
@@ -122,6 +123,7 @@ public class OrderController {
      * @return
      */
     @Operation(summary = "订单-创建")
+    @RepeatSubmit(serviceId = "createOrder", limitType = RepeatSubmit.Type.PARAM, lockTime = 3)
     @PostMapping("/createOrder")
     public Result<UserPayForm> createOrder(@Validate @RequestBody CreateOrderForm createOrderForm) throws IOException {
         return Result.ok(appOrderService.createOrder(createOrderForm));
@@ -134,7 +136,7 @@ public class OrderController {
      */
     @Operation(summary = "支付回调")
     @RequestMapping("/wechatPayNotify")
-    public Map<String, String> wechatPayNotify(HttpServletRequest request) {
+    public Map<String, String> wechatPayNotify(HttpServletRequest request) throws InterruptedException {
         return appOrderService.wechatPayNotify(request);
     }
 

+ 12 - 9
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/app/service/impl/OrderServiceImpl.java

@@ -531,6 +531,9 @@ public class OrderServiceImpl implements IOrderService {
                         }
                         redisTemplate.opsForValue().set(productKey, JSON.toJSONString(product), 60 * 60 * 24, TimeUnit.SECONDS);
                         // 数据库的库存信息要根据实际业务来获取,如果商品有规格信息,库存应该根据规格来获取
+                        if (product.getTicketNum() == null){
+                            throw new JeecgBootException("订单提交失败,当前商品库存为空");
+                        }
                         stock = product.getTicketNum();
                         redisTemplate.opsForValue().set(stockKey, stock, 60 * 60 * 24, TimeUnit.SECONDS);
                     }
@@ -640,7 +643,7 @@ public class OrderServiceImpl implements IOrderService {
                         appOrder.setOrgCode(appSitePlace.getOrgCode())
                                 .setTenantId(appSitePlace.getTenantId()).setAddressSiteId(appSite.getId());
 
-                        sumPrice = sumPrice.add(priceRule.getSellingPrice()).setScale(2, BigDecimal.ROUND_DOWN);
+                        sumPrice = sumPrice.add(priceRule.getSellingPrice());
                     }
 
                     //计算订单总价
@@ -691,8 +694,8 @@ public class OrderServiceImpl implements IOrderService {
                         appOrderProInfo.setDelFlag(CommonConstant.DEL_FLAG_0);
 
                         proInfoList.add(appOrderProInfo);
-                        tDiscounts = tDiscounts.add(priceRule.getOriginalPrice().subtract(priceRule.getSellingPrice())).setScale(2, BigDecimal.ROUND_DOWN);
-                        sumPrice = sumPrice.add(priceRule.getSellingPrice()).setScale(2, BigDecimal.ROUND_DOWN);
+                        tDiscounts = tDiscounts.add(priceRule.getOriginalPrice().subtract(priceRule.getSellingPrice()));
+                        sumPrice = sumPrice.add(priceRule.getSellingPrice());
                     }
 
                     //计算订单总价
@@ -756,7 +759,7 @@ public class OrderServiceImpl implements IOrderService {
 
                     proInfoList.add(appOrderProInfo);
 
-                    sumPrice = sumPrice.add(appGamePriceRules.getSellingPrice()).setScale(2, BigDecimal.ROUND_DOWN);
+                    sumPrice = sumPrice.add(appGamePriceRules.getSellingPrice());
                 }
                 //计算订单总价
                 totalPrice = totalPrice.add(sumPrice).setScale(2, BigDecimal.ROUND_DOWN);
@@ -859,8 +862,8 @@ public class OrderServiceImpl implements IOrderService {
 
                     proInfoList.add(appOrderProInfo);
 
-                    tDiscounts = tDiscounts.add(appCourse.getOriginalPrice().subtract(appCourse.getSellingPrice())).setScale(2, BigDecimal.ROUND_DOWN);
-                    sumCoursePrice = sumCoursePrice.add(appCourse.getSellingPrice()).setScale(2, BigDecimal.ROUND_DOWN);
+                    tDiscounts = tDiscounts.add(appCourse.getOriginalPrice().subtract(appCourse.getSellingPrice()));
+                    sumCoursePrice = sumCoursePrice.add(appCourse.getSellingPrice());
                 }
 
                 //计算订单总价
@@ -910,7 +913,7 @@ public class OrderServiceImpl implements IOrderService {
                 ;
                 insureOrderInfoList.add(insureOrderInfo);
 
-                sumPrice = sumPrice.add(insurePrice.getInsurePrice()).setScale(2, BigDecimal.ROUND_HALF_UP);
+                sumPrice = sumPrice.add(insurePrice.getInsurePrice()).setScale(2, BigDecimal.ROUND_DOWN);
             }
             //计算总价 = 订单金额 + 保单金额
             totalPrice = totalPrice.add(sumPrice);
@@ -1562,8 +1565,8 @@ public class OrderServiceImpl implements IOrderService {
                     .eq(AppOrderProInfo::getOrderId, record.getOrderId())
             );
             if (ObjectUtil.isNotEmpty(proInfoList)) {
-                List<AppOrderProInfo> infoList = proInfoList.stream().filter(orderProInfo -> orderProInfo.getType() != 7).collect(Collectors.toList());
-                List<AppOrderProInfo> insureList = proInfoList.stream().filter(orderProInfo -> orderProInfo.getType() == 7).collect(Collectors.toList());
+                List<AppOrderProInfo> infoList = proInfoList.stream().filter(orderProInfo -> !Objects.equals(orderProInfo.getType(), CommonConstant.ORDER_PRO_INFO_TYPE_6)).collect(Collectors.toList());
+                List<AppOrderProInfo> insureList = proInfoList.stream().filter(orderProInfo -> Objects.equals(orderProInfo.getType(), CommonConstant.ORDER_PRO_INFO_TYPE_6)).collect(Collectors.toList());
                 record.setOrderProInfoList(infoList);
                 record.setOrderInsureList(insureList);
             }

+ 11 - 8
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/redission/RedissonDelayQueue.java

@@ -4,6 +4,7 @@ import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.util.ObjectUtil;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import lombok.extern.slf4j.Slf4j;
+import org.jeecg.common.constant.CommonConstant;
 import org.jeecg.modules.system.app.entity.AppOrder;
 import org.jeecg.modules.system.app.entity.AppOrderProInfo;
 import org.jeecg.modules.system.app.service.IAppOrderProInfoService;
@@ -17,6 +18,7 @@ import javax.annotation.PostConstruct;
 import javax.annotation.Resource;
 import java.util.Arrays;
 import java.util.List;
+import java.util.Objects;
 import java.util.concurrent.TimeUnit;
 import java.util.stream.Collectors;
 
@@ -65,19 +67,20 @@ public class RedissonDelayQueue {
                     String orderId = Arrays.stream(task.split("_")).collect(Collectors.toList()).get(1);
                     AppOrder appOrder = appOrderService.getById(orderId);
                     if(ObjectUtil.isNotEmpty(appOrder)){
-                        if (appOrder.getOrderStatus() == 0){
+                        if (Objects.equals(appOrder.getOrderStatus(), CommonConstant.ORDER_STATUS_0)){
                             log.info("修改订单:{},支付状态为已取消", orderId);
                             appOrder.setOrderStatus(4);
                             appOrderService.updateById(appOrder);
-                        }
-                        //修改子订单状态
-                        List<AppOrderProInfo> appOrderProInfoList = appOrderProInfoService.list(Wrappers.<AppOrderProInfo>lambdaQuery().eq(AppOrderProInfo::getOrderId, orderId));
-                        if (CollUtil.isNotEmpty(appOrderProInfoList)){
-                            for (AppOrderProInfo appOrderProInfo : appOrderProInfoList) {
-                                appOrderProInfo.setOrderStatus(4);
-                                appOrderProInfoService.updateById(appOrderProInfo);
+                            //修改子订单状态
+                            List<AppOrderProInfo> appOrderProInfoList = appOrderProInfoService.list(Wrappers.<AppOrderProInfo>lambdaQuery().eq(AppOrderProInfo::getOrderId, orderId));
+                            if (CollUtil.isNotEmpty(appOrderProInfoList)){
+                                for (AppOrderProInfo appOrderProInfo : appOrderProInfoList) {
+                                    appOrderProInfo.setOrderStatus(4);
+                                    appOrderProInfoService.updateById(appOrderProInfo);
+                                }
                             }
                         }
+
                     }
                 } catch (Exception e) {
                     e.printStackTrace();

+ 2 - 1
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/system/app/mapper/xml/AppSitePriceRulesMapper.xml

@@ -98,7 +98,7 @@
     </select>
 
     <insert id="insertList" parameterType="java.util.List">
-        INSERT INTO `nm_site_price_rules` (id,org_code,tenant_id,site_place_id,category_id,type,date_of_sale,start_time,end_time,day_of_week,original_price,selling_price,is_teaching,inventory,site_rule_time_id,revision,create_by,create_time,update_by,update_time,status,del_flag)
+        INSERT INTO `nm_site_price_rules` (id,org_code,tenant_id,site_place_id,category_id,type,date_of_sale,start_time,end_time,day_of_week,original_price,selling_price,ticket_num,is_teaching,inventory,site_rule_time_id,revision,create_by,create_time,update_by,update_time,status,del_flag)
         VALUES
         <foreach collection="list" item="item" separator=",">
             (#{item.id},
@@ -113,6 +113,7 @@
             #{item.dayOfWeek},
             #{item.originalPrice},
             #{item.sellingPrice},
+            #{item.ticket_num},
             #{item.isTeaching},
             #{item.inventory},
             #{item.siteRuleTimeId},

+ 4 - 3
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/system/app/service/impl/AppCoureseServiceImpl.java

@@ -391,7 +391,8 @@ public class AppCoureseServiceImpl extends ServiceImpl<AppCoursesMapper, AppCour
     @Override
     public List<FamilyUserVO> getClassPostponeUsers(String coursePriceRulesId) {
 
-        List<AppCoursesVerificationRecord> verificationRecordList = appCoursesVerificationRecordMapper.selectList(Wrappers.<AppCoursesVerificationRecord>lambdaQuery().eq(AppCoursesVerificationRecord::getCoursesPriceRuleId, coursePriceRulesId));
+        List<AppCoursesVerificationRecord> verificationRecordList = appCoursesVerificationRecordMapper.selectList(Wrappers.<AppCoursesVerificationRecord>lambdaQuery()
+                .eq(AppCoursesVerificationRecord::getCoursesPriceRuleId, coursePriceRulesId).eq(AppCoursesVerificationRecord::getOrPostpone, 0));
         List<FamilyUserVO> list = verificationRecordList.stream()
                 .collect(Collectors.collectingAndThen(
                         Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(AppCoursesVerificationRecord::getUseUserId))),
@@ -417,8 +418,8 @@ public class AppCoureseServiceImpl extends ServiceImpl<AppCoursesMapper, AppCour
         //补课课时
         AppCoursesPriceRules appCoursesPriceRules = priceRulesMapper.selectById(form.getCoursePriceRulesId());
         //设置为延期状态
-        coursesPriceRules.setClassStatus(CommonConstant.STATUS_1_INT);
-        priceRulesMapper.updateById(appCoursesPriceRules);
+//        coursesPriceRules.setClassStatus(CommonConstant.STATUS_1_INT);
+//        priceRulesMapper.updateById(appCoursesPriceRules);
         List<JobExtendedClassNoticeVo> jobExtendedClassNoticeVos = new ArrayList<>();
 
         for (FamilyUserVO familyUserVO : form.getFamilyUserVOList()) {

+ 31 - 1
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/system/app/service/impl/AppCoursesVerificationRecordServiceImpl.java

@@ -2,6 +2,7 @@ package org.jeecg.modules.system.app.service.impl;
 
 
 import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.ObjectUtil;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import org.apache.shiro.SecurityUtils;
@@ -9,16 +10,21 @@ import org.jeecg.common.constant.CommonConstant;
 import org.jeecg.common.exception.JeecgBootException;
 import org.jeecg.common.system.vo.LoginUser;
 import org.jeecg.modules.system.app.entity.AppCoursesVerificationRecord;
+import org.jeecg.modules.system.app.entity.AppOrder;
+import org.jeecg.modules.system.app.entity.AppOrderProInfo;
 import org.jeecg.modules.system.app.entity.FamilyMembers;
 import org.jeecg.modules.system.app.form.CoursesVerificationRecordForm;
 import org.jeecg.modules.system.app.form.VerifyForm;
 import org.jeecg.modules.system.app.mapper.AppCoursesVerificationRecordMapper;
+import org.jeecg.modules.system.app.mapper.AppOrderMapper;
+import org.jeecg.modules.system.app.mapper.AppOrderProInfoMapper;
 import org.jeecg.modules.system.app.mapper.FamilyMembersMapper;
 import org.jeecg.modules.system.app.service.IAppCoursesVerificationRecordService;
 import org.springframework.stereotype.Service;
 
 import javax.annotation.Resource;
 import java.util.List;
+import java.util.Objects;
 
 /**
  * @Description: nm_courses_verification_record
@@ -30,7 +36,13 @@ import java.util.List;
 public class AppCoursesVerificationRecordServiceImpl extends ServiceImpl<AppCoursesVerificationRecordMapper, AppCoursesVerificationRecord> implements IAppCoursesVerificationRecordService {
 
     @Resource
-    FamilyMembersMapper  familyMembersMapper;
+    private FamilyMembersMapper  familyMembersMapper;
+
+    @Resource
+    private AppOrderMapper appOrderMapper;
+
+    @Resource
+    private AppOrderProInfoMapper appOrderProInfoMapper;
 
     @Override
     public Boolean courseUploadImage(VerifyForm verifyForm) {
@@ -55,6 +67,24 @@ public class AppCoursesVerificationRecordServiceImpl extends ServiceImpl<AppCour
                 verificationRecord.setVerifyUserName(sysUser.getRealname());
                 verificationRecord.setVerifyImage(coursesVerificationRecordForm.getVerifyImage());
                 baseMapper.updateById(verificationRecord);
+                //修改订单状态
+                String useUserId = verificationRecord.getUseUserId();
+                String coursesId = verificationRecord.getCoursesId();
+                AppOrderProInfo orderProInfo = appOrderProInfoMapper.selectOne(Wrappers.<AppOrderProInfo>lambdaQuery().eq(AppOrderProInfo::getFamilyUserId, useUserId).eq(AppOrderProInfo::getProductId, coursesId).last("limit 1"));
+                if (ObjectUtil.isNotEmpty(orderProInfo)){
+                    orderProInfo.setOrderStatus(CommonConstant.ORDER_STATUS_2);
+                    appOrderProInfoMapper.updateById(orderProInfo);
+                }
+                String orderId = orderProInfo.getOrderId();
+                AppOrder appOrder = appOrderMapper.selectById(orderId);
+                if (ObjectUtil.isNotEmpty(appOrder)){
+                    List<AppOrderProInfo> proInfoList = appOrderProInfoMapper.selectList(Wrappers.<AppOrderProInfo>lambdaQuery().eq(AppOrderProInfo::getOrderId, orderId).eq(AppOrderProInfo::getType, CommonConstant.ORDER_PRO_INFO_TYPE_5));
+                    long count = proInfoList.stream().filter(info -> Objects.equals(info.getOrderStatus(), CommonConstant.ORDER_STATUS_2)).count();
+                    if(count == proInfoList.size()){
+                        appOrder.setOrderStatus(CommonConstant.ORDER_STATUS_2);
+                        appOrderMapper.updateById(appOrder);
+                    }
+                }
             });
         }
         return Boolean.TRUE;

+ 31 - 20
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/system/app/service/impl/AppOrderServiceImpl.java

@@ -30,13 +30,9 @@ import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
 import javax.annotation.Resource;
-import java.math.BigDecimal;
 import java.time.LocalDate;
 import java.time.LocalTime;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
 import java.util.function.Function;
 import java.util.stream.Collectors;
 
@@ -203,24 +199,23 @@ public class AppOrderServiceImpl extends ServiceImpl<AppOrderMapper, AppOrder> i
             List<AppGameScheduleVO> gameScheduleVOList = appGameScheduleMapper.getListVo(gameId);
             appOrderInfoVO.setGameScheduleVOList(gameScheduleVOList);
         }
+        //无固定场团购优惠
+        if (appOrder.getOrderType() == 2) {
+            appOrderInfoVO.setTDiscounts(appOrder.getTDiscounts());
+            appOrderInfoVO.setTotalPrice(appOrderInfoVO.getTotalPrice().add(appOrder.getTDiscounts()));
+        }
         //课程才有核销记录和优惠信息
         if (appOrder.getType() == 2) {
-            BigDecimal sDiscounts = BigDecimal.ZERO;
-            BigDecimal tDiscounts = BigDecimal.ZERO;
-            for (AppOrderProInfo proInfo : proInfoList) {
-                if (proInfo.getOrFreePro() == 1) {
-                    sDiscounts = sDiscounts.add(proInfo.getOriginalPrice());
-                }
-                BigDecimal discounts = proInfo.getOriginalPrice().subtract(proInfo.getPrice());
-                tDiscounts = tDiscounts.add(discounts);
-            }
             //优惠信息
-            if (sDiscounts.compareTo(BigDecimal.ZERO) != 0) {
-                appOrderInfoVO.setSDiscounts(sDiscounts);
+            if (appOrder.getSDiscounts() != null){
+                appOrderInfoVO.setSDiscounts(appOrder.getSDiscounts());
+                appOrderInfoVO.setTotalPrice(appOrderInfoVO.getTotalPrice().add(appOrder.getSDiscounts()));
             }
-            if (tDiscounts.compareTo(BigDecimal.ZERO) != 0) {
-                appOrderInfoVO.setTDiscounts(tDiscounts);
+            if (appOrder.getTDiscounts() != null){
+                appOrderInfoVO.setTDiscounts(appOrder.getTDiscounts());
+                appOrderInfoVO.setTotalPrice(appOrderInfoVO.getTotalPrice().add(appOrder.getTDiscounts()));
             }
+
             //核销记录
             List<AppCoursesVerificationRecord> verificationRecords =
                     appCoursesVerificationRecordMapper.selectList(Wrappers.<AppCoursesVerificationRecord>lambdaQuery().eq(AppCoursesVerificationRecord::getOrderId, orderId));
@@ -229,7 +224,7 @@ public class AppOrderServiceImpl extends ServiceImpl<AppOrderMapper, AppOrder> i
                 listMap.keySet().forEach(p -> {
                     VerificationRecordDTO verificationRecordDTO = new VerificationRecordDTO();
                     verificationRecordDTO.setCoursesType(p).setVerificationRecordList(listMap.get(p));
-                    verificationRecordDTOList.add(new VerificationRecordDTO());
+                    verificationRecordDTOList.add(verificationRecordDTO);
                 });
                 appOrderInfoVO.setVerificationRecordDTOList(verificationRecordDTOList);
             }
@@ -299,16 +294,32 @@ public class AppOrderServiceImpl extends ServiceImpl<AppOrderMapper, AppOrder> i
     @Transactional(rollbackFor = Exception.class)
     public Boolean scanCodeVerification(List<String> isinIds) {
 
+        LoginUser loginUser = (LoginUser)SecurityUtils.getSubject().getPrincipal();
+
         for (String isinId : isinIds) {
             //查询对应券号
             AppIsin appIsin = appIsinMapper.selectById(isinId);
             appIsin.setIsinStatus(CommonConstant.ISIN_STATUS_2);
+            appIsin.setVerifyUserId(loginUser.getId());
+            appIsin.setVerifyUserName(loginUser.getUsername());
+            appIsin.setUseTime(new Date());
             appIsinMapper.updateById(appIsin);
             //修改订单状态
             String orderProInfoId = appIsin.getOrderProInfoId();
             AppOrderProInfo appOrderProInfo = appOrderProInfoMapper.selectById(orderProInfoId);
-            appOrderProInfo.setOrderStatus(CommonConstant.ORDER_STATUS_1);
+            appOrderProInfo.setOrderStatus(CommonConstant.ORDER_STATUS_2);
             appOrderProInfoMapper.updateById(appOrderProInfo);
+            //修改订单状态
+            String orderId = appOrderProInfo.getOrderId();
+            AppOrder appOrder = appOrderMapper.selectById(orderId);
+            if (ObjectUtil.isNotEmpty(appOrder)){
+                List<AppOrderProInfo> proInfoList = appOrderProInfoMapper.selectList(Wrappers.<AppOrderProInfo>lambdaQuery().eq(AppOrderProInfo::getOrderId, orderId).eq(AppOrderProInfo::getType, CommonConstant.ORDER_PRO_INFO_TYPE_5));
+                long count = proInfoList.stream().filter(info -> Objects.equals(info.getOrderStatus(), CommonConstant.ORDER_STATUS_2)).count();
+                if(count == proInfoList.size()){
+                    appOrder.setOrderStatus(CommonConstant.ORDER_STATUS_2);
+                    appOrderMapper.updateById(appOrder);
+                }
+            }
         }
         return Boolean.TRUE;
     }