Prechádzať zdrojové kódy

增加商城订单归属

yuhongqi 3 týždňov pred
rodič
commit
6e2d054854

+ 12 - 4
fs-company-app/src/main/java/com/fs/app/controller/StoreProductController.java

@@ -3,8 +3,11 @@ package com.fs.app.controller;
 import com.fs.app.annotation.Login;
 import com.fs.common.core.domain.R;
 import com.fs.common.utils.StringUtils;
+import com.fs.hisStore.domain.FsStoreProductAttrScrm;
 import com.fs.hisStore.domain.FsStoreProductAttrValueScrm;
+import com.fs.hisStore.domain.FsStoreProductPurchaseLimitScrm;
 import com.fs.hisStore.domain.FsStoreProductScrm;
+import com.fs.hisStore.service.IFsStoreProductAttrScrmService;
 import com.fs.hisStore.service.IFsStoreProductAttrValueScrmService;
 import com.fs.hisStore.service.IFsStoreProductScrmService;
 import com.fs.hisStore.vo.FsStoreProductListVO;
@@ -32,6 +35,9 @@ public class StoreProductController extends AppBaseController {
     @Autowired
     private IFsStoreProductAttrValueScrmService attrValueService;
 
+    @Autowired
+    private IFsStoreProductAttrScrmService attrService;
+
     /**
      * 查询本公司下的商城产品列表
      */
@@ -77,10 +83,12 @@ public class StoreProductController extends AppBaseController {
             return R.error("无权查看该商品");
         }
         // 查询商品规格属性值
-        FsStoreProductAttrValueScrm attrQuery = new FsStoreProductAttrValueScrm();
-        attrQuery.setProductId(productId);
-        List<FsStoreProductAttrValueScrm> values = attrValueService.selectFsStoreProductAttrValueList(attrQuery);
-        return R.ok().put("product", product).put("values", values);
+        List<FsStoreProductAttrScrm> productAttr=attrService.selectFsStoreProductAttrByProductId(product.getProductId());
+        List<FsStoreProductAttrValueScrm> productValues=attrValueService.selectFsStoreProductAttrValueByProductId(product.getProductId());
+
+        return R.ok().put("product", product)
+                .put("productAttr",productAttr)
+                .put("productValues",productValues);
     }
 
     /**

+ 12 - 0
fs-service/src/main/java/com/fs/course/mapper/FsCourseWatchLogMapper.java

@@ -931,4 +931,16 @@ public interface FsCourseWatchLogMapper extends BaseMapper<FsCourseWatchLog> {
             "    GROUP BY user_id\n" +
             "  )")
     List<Long> selectWatchLogOutdatedInfo();
+
+    /**
+     * 查询用户最近一次看课记录(看课时长>0,按创建时间倒序取第一条)
+     * 包含手动发课(send_type=1)和SOP发课(send_type=2)
+     */
+    @Select("SELECT * FROM fs_course_watch_log " +
+            "WHERE user_id = #{userId} " +
+            "AND duration > 0 " +
+            "AND (send_type = 1 OR send_type = 2) " +
+            "ORDER BY create_time DESC " +
+            "LIMIT 1")
+    FsCourseWatchLog selectLatestWatchLogByUserId(@Param("userId") Long userId);
 }

+ 5 - 0
fs-service/src/main/java/com/fs/hisStore/config/StoreConfig.java

@@ -64,4 +64,9 @@ public class StoreConfig implements Serializable {
      * 是否开启购物积分(用户实际支付金额1:1向下取整折算积分)
      */
     private Boolean enableShoppingPoints;
+
+    /**
+     * 是否开启商城订单归属绑定(开启后,orderType=0的商城订单会自动绑定归属销售)
+     */
+    private Boolean enableStoreOrderAttribution;
 }

+ 2 - 2
fs-service/src/main/java/com/fs/hisStore/service/impl/FsStoreAfterSalesScrmServiceImpl.java

@@ -939,8 +939,8 @@ public class FsStoreAfterSalesScrmServiceImpl implements IFsStoreAfterSalesScrmS
         if (order.getShoppingPointsClaimed() != null && order.getShoppingPointsClaimed() == 1
                 && order.getPayMoney() != null && order.getPayMoney().compareTo(BigDecimal.ZERO) > 0) {
             try {
-                // 计算应扣除的购物积分(与发放时一致:pay_money向下取整)
-                long pointsToDeduct = order.getPayMoney().setScale(0, BigDecimal.ROUND_DOWN).longValue();
+                // 计算应扣除的购物积分(按实际退款金额向下取整)
+                long pointsToDeduct = storeAfterSales.getRefundAmount().setScale(0, BigDecimal.ROUND_DOWN).longValue();
                 if (pointsToDeduct > 0) {
                     // 查询用户当前积分,积分不足则扣除全部积分
                     FsUserScrm user = fsUserScrmMapper.selectFsUserByUserId(order.getUserId());

+ 67 - 0
fs-service/src/main/java/com/fs/hisStore/service/impl/FsStoreOrderScrmServiceImpl.java

@@ -49,6 +49,8 @@ import com.fs.course.dto.FsOrderDeliveryNoteDTO;
 import com.fs.course.dto.OrderOpenIdTransDTO;
 import com.fs.course.mapper.FsCoursePlaySourceConfigMapper;
 import com.fs.course.mapper.FsUserCompanyUserMapper;
+import com.fs.course.mapper.FsCourseWatchLogMapper;
+import com.fs.course.domain.FsCourseWatchLog;
 import com.fs.erp.domain.*;
 import com.fs.erp.dto.*;
 import com.fs.erp.dto.df.*;
@@ -227,6 +229,9 @@ public class FsStoreOrderScrmServiceImpl implements IFsStoreOrderScrmService {
     @Autowired
     private FsUserCompanyUserMapper fsUserCompanyUserMapper;
 
+    @Autowired
+    private FsCourseWatchLogMapper fsCourseWatchLogMapper;
+
     @Autowired
     private FsUserAddressScrmMapper userAddressMapper;
 
@@ -1314,6 +1319,16 @@ public class FsStoreOrderScrmServiceImpl implements IFsStoreOrderScrmService {
             orderStatusService.create(storeOrder.getId(), OrderLogEnum.CREATE_ORDER.getValue(),
                     OrderLogEnum.CREATE_ORDER.getDesc());
 
+            // 商城订单归属绑定
+            if (Boolean.TRUE.equals(config.getEnableStoreOrderAttribution())
+                    && storeOrder.getOrderType() != null && storeOrder.getOrderType() == 0) {
+                try {
+                    bindStoreOrderAttribution(storeOrder, userId);
+                } catch (Exception e) {
+                    log.error("商城订单归属绑定异常,订单号:{},用户ID:{}", storeOrder.getOrderCode(), userId, e);
+                }
+            }
+
             //加入redis,24小时自动取消
             String redisKey = String.valueOf(StrUtil.format("{}{}",
                     StoreConstants.REDIS_ORDER_OUTTIME_UNPAY, storeOrder.getId()));
@@ -7220,4 +7235,56 @@ public class FsStoreOrderScrmServiceImpl implements IFsStoreOrderScrmService {
 //        return R.ok().put("data",result);
 //    }
 
+    /**
+     * 商城订单归属绑定逻辑
+     * 1. 查询fs_user_company_user表,获取用户绑定的销售列表(status=1正常状态)
+     * 2. 如果只绑定了一个销售,直接将该销售的companyId和companyUserId绑定到订单
+     * 3. 如果绑定了多个销售,查询用户最近看课记录(看课时长>0),将看课记录对应的销售绑定到订单
+     * 4. 如果无看课记录则不绑定归属
+     */
+    private void bindStoreOrderAttribution(FsStoreOrderScrm storeOrder, Long userId) {
+        // 查询用户绑定的正常状态的销售列表
+        FsUserCompanyUser queryParam = new FsUserCompanyUser();
+        queryParam.setUserId(userId);
+        queryParam.setStatus(1);
+        List<FsUserCompanyUser> bindList = fsUserCompanyUserMapper.selectFsUserCompanyUserList(queryParam);
+
+        if (bindList == null || bindList.isEmpty()) {
+            log.info("商城订单归属:用户{}无绑定销售,不绑定归属,订单号:{}", userId, storeOrder.getOrderCode());
+            return;
+        }
+
+        Long bindCompanyId = null;
+        Long bindCompanyUserId = null;
+
+        if (bindList.size() == 1) {
+            // 只绑定了一个销售,直接使用
+            FsUserCompanyUser bind = bindList.get(0);
+            bindCompanyId = bind.getCompanyId();
+            bindCompanyUserId = bind.getCompanyUserId();
+            log.info("商城订单归属:用户{}只绑定1个销售,直接绑定,companyId={},companyUserId={},订单号:{}",
+                    userId, bindCompanyId, bindCompanyUserId, storeOrder.getOrderCode());
+        } else {
+            // 绑定了多个销售,查询最近看课记录
+            FsCourseWatchLog latestLog = fsCourseWatchLogMapper.selectLatestWatchLogByUserId(userId);
+            if (latestLog != null && latestLog.getCompanyUserId() != null) {
+                bindCompanyId = latestLog.getCompanyId();
+                bindCompanyUserId = latestLog.getCompanyUserId();
+                log.info("商城订单归属:用户{}绑定多个销售,通过最近看课记录绑定,companyId={},companyUserId={},订单号:{}",
+                        userId, bindCompanyId, bindCompanyUserId, storeOrder.getOrderCode());
+            } else {
+                log.info("商城订单归属:用户{}绑定多个销售但无看课记录,不绑定归属,订单号:{}", userId, storeOrder.getOrderCode());
+                return;
+            }
+        }
+
+        // 绑定归属到订单
+        if (bindCompanyId != null || bindCompanyUserId != null) {
+            storeOrder.setCompanyId(bindCompanyId);
+            storeOrder.setCompanyUserId(bindCompanyUserId);
+            log.info("商城订单归属绑定成功,订单号:{},companyId={},companyUserId={}",
+                    storeOrder.getOrderCode(), bindCompanyId, bindCompanyUserId);
+        }
+    }
+
 }

+ 111 - 0
fs-user-app/src/main/java/com/fs/app/controller/store/StoreProductController.java

@@ -0,0 +1,111 @@
+package com.fs.app.controller.store;
+
+import com.fs.app.annotation.Login;
+import com.fs.app.controller.AppBaseController;
+import com.fs.common.core.domain.R;
+import com.fs.common.utils.StringUtils;
+import com.fs.hisStore.domain.FsStoreProductAttrScrm;
+import com.fs.hisStore.domain.FsStoreProductAttrValueScrm;
+import com.fs.hisStore.domain.FsStoreProductScrm;
+import com.fs.hisStore.service.IFsStoreProductAttrScrmService;
+import com.fs.hisStore.service.IFsStoreProductAttrValueScrmService;
+import com.fs.hisStore.service.IFsStoreProductScrmService;
+import com.fs.hisStore.vo.FsStoreProductListVO;
+import com.github.pagehelper.PageHelper;
+import com.github.pagehelper.PageInfo;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+
+@Api("商城产品")
+@RestController
+@RequestMapping("/app/storeProduct")
+public class StoreProductController extends AppBaseController {
+
+    @Autowired
+    private IFsStoreProductScrmService fsStoreProductService;
+
+    @Autowired
+    private IFsStoreProductAttrValueScrmService attrValueService;
+
+    @Autowired
+    private IFsStoreProductAttrScrmService attrService;
+
+    /**
+     * 查询本公司下的商城产品列表
+     */
+    @ApiOperation("查询本公司下的商城产品列表")
+    @GetMapping("/list")
+    public R list(Integer page, Integer pageSize, String productName,
+                  @RequestParam("companyId") Long companyId,
+                  @RequestParam("companyUserId") Long companyUserId) {
+        if (page == null || page < 1) {
+            page = 1;
+        }
+        if (pageSize == null || pageSize < 1) {
+            pageSize = 10;
+        }
+        if (companyId == null) {
+            return R.error("companyId不能为空");
+        }
+        PageHelper.startPage(page, pageSize);
+        FsStoreProductScrm query = new FsStoreProductScrm();
+        query.setIsDel(0);
+        query.setIsShow(1);
+        query.setIsAudit("1");
+        query.setCompanyIds(String.valueOf(companyId));
+        if (StringUtils.isNotEmpty(productName)) {
+            query.setProductName(productName);
+        }
+        List<FsStoreProductListVO> list = fsStoreProductService.selectFsStoreProductListVO(query);
+        PageInfo<FsStoreProductListVO> pageInfo = new PageInfo<>(list);
+        return R.ok().put("data", pageInfo);
+    }
+
+    /**
+     * 查看商品详情
+     */
+    @ApiOperation("查看商品详情")
+    @GetMapping("/{productId}")
+    public R getInfo(@PathVariable("productId") Long productId,
+                     @RequestParam("companyId") Long companyId,
+                     @RequestParam("companyUserId") Long companyUserId) {
+        FsStoreProductScrm product = fsStoreProductService.selectFsStoreProductById(productId);
+        if (product == null) {
+            return R.error("商品不存在");
+        }
+        // 校验该商品是否属于指定公司
+        String companyIds = product.getCompanyIds();
+        if (StringUtils.isEmpty(companyIds) || !containsCompanyId(companyIds, companyId)) {
+            return R.error("无权查看该商品");
+        }
+        // 查询商品规格属性值
+        List<FsStoreProductAttrScrm> productAttr=attrService.selectFsStoreProductAttrByProductId(product.getProductId());
+        List<FsStoreProductAttrValueScrm> productValues=attrValueService.selectFsStoreProductAttrValueByProductId(product.getProductId());
+
+        return R.ok().put("product", product)
+                .put("productAttr",productAttr)
+                .put("productValues",productValues);
+    }
+
+    /**
+     * 判断 companyIds 字符串中是否包含指定 companyId
+     * companyIds 格式可能是 "123" 或 "123,456" 等
+     */
+    private boolean containsCompanyId(String companyIds, Long companyId) {
+        if (StringUtils.isEmpty(companyIds)) {
+            return false;
+        }
+        String[] ids = companyIds.split(",");
+        for (String id : ids) {
+            if (id.trim().equals(String.valueOf(companyId))) {
+                return true;
+            }
+        }
+        return false;
+    }
+}