浏览代码

bug修复和优化

wangxy 15 小时之前
父节点
当前提交
dce3129a84
共有 22 个文件被更改,包括 346 次插入55 次删除
  1. 1 1
      fs-admin/src/main/java/com/fs/crm/controller/IntegralOrderMsgController.java
  2. 1 1
      fs-admin/src/main/java/com/fs/his/task/Task.java
  3. 33 0
      fs-service/src/main/java/com/fs/course/mapper/FsCourseWatchLogMapper.java
  4. 10 0
      fs-service/src/main/java/com/fs/course/service/IFsCourseWatchLogService.java
  5. 5 0
      fs-service/src/main/java/com/fs/his/domain/FsStoreProduct.java
  6. 3 0
      fs-service/src/main/java/com/fs/his/domain/FsStoreProductAttrValue.java
  7. 9 0
      fs-service/src/main/java/com/fs/his/mapper/FsStoreProductMapper.java
  8. 4 3
      fs-service/src/main/java/com/fs/his/mapper/FsUserMapper.java
  9. 6 0
      fs-service/src/main/java/com/fs/his/service/IFsStoreProductService.java
  10. 2 0
      fs-service/src/main/java/com/fs/his/service/IFsUserService.java
  11. 72 0
      fs-service/src/main/java/com/fs/his/service/impl/FsExternalOrderServiceImpl.java
  12. 20 10
      fs-service/src/main/java/com/fs/his/service/impl/FsStoreOrderServiceImpl.java
  13. 24 3
      fs-service/src/main/java/com/fs/his/service/impl/FsStoreProductServiceImpl.java
  14. 62 0
      fs-service/src/main/java/com/fs/his/service/impl/FsUserServiceImpl.java
  15. 3 0
      fs-service/src/main/java/com/fs/store/param/h5/FsUserPageListParam.java
  16. 58 0
      fs-service/src/main/resources/mapper/course/FsCourseWatchLogMapper.xml
  17. 1 1
      fs-service/src/main/resources/mapper/course/FsPublicCourseTrafficLogMapper.xml
  18. 1 0
      fs-service/src/main/resources/mapper/his/FsExternalOrderMapper.xml
  19. 5 1
      fs-service/src/main/resources/mapper/his/FsStoreProductAttrValueMapper.xml
  20. 5 1
      fs-service/src/main/resources/mapper/his/FsStoreProductMapper.xml
  21. 20 0
      fs-service/src/main/resources/mapper/his/FsUserMapper.xml
  22. 1 34
      fs-user-app/src/main/java/com/fs/app/controller/AppLoginController.java

+ 1 - 1
fs-admin/src/main/java/com/fs/crm/controller/IntegralOrderMsgController.java

@@ -1,4 +1,4 @@
-package com.fs.admin.controller.crm;
+package com.fs.crm.controller;
 
 import com.fs.common.core.controller.BaseController;
 import com.fs.common.core.domain.AjaxResult;

+ 1 - 1
fs-admin/src/main/java/com/fs/his/task/Task.java

@@ -1919,7 +1919,7 @@ public class Task {
                     continue;
                 }
                 
-                FsStore store = fsStoreMapper.selectFsStoreByStoreId(product.getStoreId());
+                FsStore store = fsStoreMapper.selectFsStoreByShopCode(String.valueOf(product.getStoreId()));
                 if (store == null || store.getStoreName() == null) {
                     continue;
                 }

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

@@ -617,6 +617,29 @@ public interface FsCourseWatchLogMapper extends BaseMapper<FsCourseWatchLog> {
 
     List<FsCourseWatchLog> getWatchCourseByVideoId(@Param("videoId") Long videoId, @Param("userIds") List<Long> userIds);
 
+    @Select("SELECT l.* FROM fs_course_watch_log l " +
+            "INNER JOIN ( " +
+            "    SELECT user_id, video_id, MAX(log_id) AS log_id " +
+            "    FROM fs_course_watch_log " +
+            "    WHERE user_id IS NOT NULL AND user_id > 0 " +
+            "      AND watch_type = 1 " +
+            "      AND send_type = 1 " +
+            "      AND create_time >= CURDATE() " +
+            "      AND create_time < DATE_ADD(CURDATE(), INTERVAL 1 DAY) " +
+            "    GROUP BY user_id, video_id " +
+            ") latest ON l.log_id = latest.log_id " +
+            "WHERE l.log_type <> 2 " +
+            "  AND l.watch_type = 1 " +
+            "  AND l.send_type = 1 " +
+            "  AND NOT EXISTS ( " +
+            "      SELECT 1 FROM fs_course_watch_log f " +
+            "      WHERE f.user_id = l.user_id " +
+            "        AND f.video_id = l.video_id " +
+            "        AND f.log_type = 2 " +
+            "  ) " +
+            "ORDER BY l.log_id ASC LIMIT #{limit}")
+    List<FsCourseWatchLog> selectTodayUnfinishedCoursePushList(@Param("limit") Integer limit);
+
 
     /**
      * 查询训练营看课人数
@@ -926,4 +949,14 @@ public interface FsCourseWatchLogMapper extends BaseMapper<FsCourseWatchLog> {
      * 销售部门维度订单统计
      */
     List<AppSalesWatchLogReportVO> selectAppDeptOrderStats(FsCourseWatchLogStatisticsListParam param);
+
+    /**
+     * APP用户看课记录列表
+     */
+    List<AppUserWatchLogVO> selectAppUserWatchLogList(@Param("userId") Long userId);
+
+    /**
+     * 查询用户当日未完课的课程列表
+     */
+    List<TodayUnfinishedCourseVO> selectTodayUnfinishedCourseList(@Param("userId") Long userId);
 }

+ 10 - 0
fs-service/src/main/java/com/fs/course/service/IFsCourseWatchLogService.java

@@ -207,4 +207,14 @@ public interface IFsCourseWatchLogService extends IService<FsCourseWatchLog> {
      * 检查飞书看课状态
      */
     void checkFeiShuWatchStatus();
+
+    /**
+     * APP用户看课记录列表
+     */
+    List<AppUserWatchLogVO> selectAppUserWatchLogList(Long userId);
+
+    /**
+     * 查询用户当日未完课的课程列表
+     */
+    List<TodayUnfinishedCourseVO> selectTodayUnfinishedCourseList(Long userId);
 }

+ 5 - 0
fs-service/src/main/java/com/fs/his/domain/FsStoreProduct.java

@@ -35,6 +35,11 @@ public class FsStoreProduct extends BaseEntity {
     @Excel(name = "商品图片")
     private String imgUrl;
 
+    /**
+     * ERP原始图片地址
+     */
+    private String erpImgUrl;
+
     /**
      * 轮播图
      */

+ 3 - 0
fs-service/src/main/java/com/fs/his/domain/FsStoreProductAttrValue.java

@@ -47,6 +47,9 @@ public class FsStoreProductAttrValue extends BaseEntity
     @Excel(name = "图片")
     private String image;
 
+    /** ERP原始图片地址 */
+    private String erpImageUrl;
+
     /** 成本价 */
     @Excel(name = "成本价")
     private BigDecimal cost;

+ 9 - 0
fs-service/src/main/java/com/fs/his/mapper/FsStoreProductMapper.java

@@ -288,4 +288,13 @@ public interface FsStoreProductMapper {
             "</if>" +
             "</script>"})
     List<FsStoreProductListVO> liveList(@Param("maps") LiveGoods maps);
+
+    /**
+     * 根据商品brand字段匹配店铺名称,更新商品的store_id
+     */
+    @Update("UPDATE fs_store_product p " +
+            "INNER JOIN fs_store s ON p.brand = s.store_name " +
+            "SET p.store_id = s.store_id " +
+            "WHERE p.brand IS NOT NULL AND p.brand != ''")
+    int updateStoreIdByBrandMatch();
 }

+ 4 - 3
fs-service/src/main/java/com/fs/his/mapper/FsUserMapper.java

@@ -84,7 +84,7 @@ public interface FsUserMapper
 
     @Select("SELECT * \n" +
             "FROM fs_user\n" +
-            "WHERE phone IS NOT NULL AND phone != '' and is_del = 0\n" +
+            "WHERE phone IS NOT NULL or phone != '' and is_del = 0\n" +
             "GROUP BY phone \n" +
             "HAVING COUNT(*) > 1")
     List<FsUser> findDuplicatePhonesWithCount();
@@ -573,7 +573,8 @@ public interface FsUserMapper
     void updatePasswordByPhone(@Param("password")String password, @Param("encryptPhone")String encryptPhone);
 
     /**
-     * 查询公司维度的 APP 会员列表(按 user_id + company_user_id 去重)
+     * 查询公司维度的 APP 会员列表(按公司+用户去重)
+     * 同一用户在同一公司内只算一次,不管关联了多少项目
      * 用于后续计算活跃人数
      * @return APP 会员列表
      */
@@ -597,7 +598,7 @@ public interface FsUserMapper
             "<if test=\"param.startDate != null and param.startDate != '' and param.endDate != null and param.endDate != ''\"> " +
             "  AND u.app_create_time &gt;= #{param.startDate} AND u.app_create_time &lt; CONCAT(#{param.endDate}, ' 23:59:59') " +
             "</if> " +
-            "GROUP BY ucu.user_id " +
+            "GROUP BY ucu.user_id, c.company_id" +
             "</script>"})
     List<AppUserCompanyDTO> selectAppUserListForActiveCount(@Param("param")FsCourseWatchLogStatisticsListParam param);
 

+ 6 - 0
fs-service/src/main/java/com/fs/his/service/IFsStoreProductService.java

@@ -124,4 +124,10 @@ public interface IFsStoreProductService
      */
     int replaceErpImageUrls();
 
+    /**
+     * 根据商品brand字段匹配店铺名称,更新商品的store_id
+     * @return 更新成功的记录数
+     */
+    int updateStoreIdByBrandMatch();
+
 }

+ 2 - 0
fs-service/src/main/java/com/fs/his/service/IFsUserService.java

@@ -319,4 +319,6 @@ public interface IFsUserService
      * 查询外部用户列表(isExternal = 0)
      */
     List<FsUserVO> selectExternalUserList(FsUserParam fsUser);
+
+    void fixDuplicatePhoneEncryption();
 }

+ 72 - 0
fs-service/src/main/java/com/fs/his/service/impl/FsExternalOrderServiceImpl.java

@@ -8,6 +8,7 @@ import java.util.*;
 import javax.annotation.PostConstruct;
 
 import com.alibaba.fastjson.JSON;
+import com.fs.common.annotation.DataScope;
 import com.fs.company.domain.Company;
 import com.fs.company.domain.CompanyDept;
 import com.fs.company.domain.CompanyUser;
@@ -39,6 +40,7 @@ import com.fs.his.domain.FsUser;
 import com.fs.his.domain.FsUserAddress;
 import com.fs.his.domain.vo.FsExternalOrderListVO;
 import com.fs.his.dto.ExternalOrderProductDTO;
+import com.fs.his.enums.ProductSourceTypeEnum;
 import com.fs.his.mapper.FsExternalOrderMapper;
 import com.fs.his.mapper.FsExternalOrderItemMapper;
 import com.fs.his.mapper.FsStoreMapper;
@@ -133,6 +135,7 @@ public class FsExternalOrderServiceImpl implements IFsExternalOrderService {
     }
 
     @Override
+    @DataScope(deptAlias = "cu",userAlias = "cu")
     public List<FsExternalOrderListVO> selectExternalOrderListVO(FsExternalOrder fsExternalOrder) {
         return fsExternalOrderMapper.selectExternalOrderListVO(fsExternalOrder);
     }
@@ -314,6 +317,19 @@ public class FsExternalOrderServiceImpl implements IFsExternalOrderService {
                 continue;
             }
 
+            // 发货权限校验
+            if (order.getStoreId() != null) {
+                FsStore fsStore = fsStoreMapper.selectFsStoreByShopCode(order.getStoreId().toString());
+                if (fsStore != null) {
+                    List<FsExternalOrderItem> orderItems = fsExternalOrderItemMapper.selectFsExternalOrderItemByOrderId(orderId);
+                    String deliveryCheckResult = checkDeliveryPermissionForErp(fsStore, orderItems);
+                    if (deliveryCheckResult != null) {
+                        log.warn("外部订单{}发货权限校验失败: {}", order.getOrderCode(), deliveryCheckResult);
+                        continue;
+                    }
+                }
+            }
+
             ShopOrderDTO shopOrderDTO = buildShopOrderDTO(order);
             if (shopOrderDTO != null) {
                 shopOrderList.add(shopOrderDTO);
@@ -628,4 +644,60 @@ public class FsExternalOrderServiceImpl implements IFsExternalOrderService {
         }
         return R.error("取消订单失败");
     }
+
+    /**
+     * 检查外部订单发货权限
+     * 如果店铺或商品的连锁品牌、商品来源类型未配置,则不校验
+     * @param store 店铺信息
+     * @param orderItems 外部订单商品列表
+     * @return 校验失败返回错误信息,成功返回null
+     */
+    private String checkDeliveryPermissionForErp(FsStore store, List<FsExternalOrderItem> orderItems) {
+        if (orderItems == null || orderItems.isEmpty()) {
+            return null;
+        }
+        
+        String storeChainBrands = store.getChainBrands();
+        if (storeChainBrands == null || storeChainBrands.trim().isEmpty()) {
+            return null;
+        }
+        
+        Set<String> storeAllowedBrands = new HashSet<>();
+        String[] brands = storeChainBrands.split(",");
+        for (String brand : brands) {
+            storeAllowedBrands.add(brand.trim());
+        }
+        
+        for (FsExternalOrderItem item : orderItems) {
+            if (item.getProductId() == null) {
+                continue;
+            }
+            FsStoreProduct product = fsStoreProductMapper.selectFsStoreProductByProductId(item.getProductId());
+            if (product == null) {
+                continue;
+            }
+            
+            Integer productSourceType = product.getProductSourceType();
+            if (productSourceType == null) {
+                continue;
+            }
+            
+            String productChainBrand = product.getChainBrand();
+            if (productChainBrand == null || productChainBrand.trim().isEmpty()) {
+                continue;
+            }
+            
+            if (ProductSourceTypeEnum.BIG_PACKAGE.getCode().equals(productSourceType)) {
+                if (!storeAllowedBrands.contains(productChainBrand)) {
+                    return "店铺无权发货大包品【" + product.getProductName() + "】,连锁品牌:" + productChainBrand;
+                }
+            } else if (ProductSourceTypeEnum.SELF_STORE.getCode().equals(productSourceType)) {
+                if (!store.getStoreId().equals(product.getStoreId())) {
+                    return "商品【" + product.getProductName() + "】为自库品,不属于当前店铺";
+                }
+            }
+        }
+        
+        return null;
+    }
 }

+ 20 - 10
fs-service/src/main/java/com/fs/his/service/impl/FsStoreOrderServiceImpl.java

@@ -5293,18 +5293,27 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService {
         }
     }
 
+    /**
+     * 检查发货权限
+     * 如果店铺或商品的连锁品牌、商品来源类型未配置,则不校验
+     * @param store 店铺信息
+     * @param orderItems 订单商品列表
+     * @return 校验失败返回错误信息,成功返回null
+     */
     private String checkDeliveryPermissionForErp(FsStore store, List<FsStoreOrderItem> orderItems) {
         if (orderItems == null || orderItems.isEmpty()) {
             return null;
         }
         
         String storeChainBrands = store.getChainBrands();
+        if (storeChainBrands == null || storeChainBrands.trim().isEmpty()) {
+            return null;
+        }
+        
         Set<String> storeAllowedBrands = new HashSet<>();
-        if (storeChainBrands != null && !storeChainBrands.trim().isEmpty()) {
-            String[] brands = storeChainBrands.split(",");
-            for (String brand : brands) {
-                storeAllowedBrands.add(brand.trim());
-            }
+        String[] brands = storeChainBrands.split(",");
+        for (String brand : brands) {
+            storeAllowedBrands.add(brand.trim());
         }
         
         for (FsStoreOrderItem item : orderItems) {
@@ -5315,14 +5324,15 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService {
             
             Integer productSourceType = product.getProductSourceType();
             if (productSourceType == null) {
-                productSourceType = ProductSourceTypeEnum.SELF_STORE.getCode();
+                continue;
+            }
+            
+            String productChainBrand = product.getChainBrand();
+            if (productChainBrand == null || productChainBrand.trim().isEmpty()) {
+                continue;
             }
             
             if (ProductSourceTypeEnum.BIG_PACKAGE.getCode().equals(productSourceType)) {
-                String productChainBrand = product.getChainBrand();
-                if (productChainBrand == null || productChainBrand.trim().isEmpty()) {
-                    return "商品【" + product.getProductName() + "】为大包品但未配置连锁品牌";
-                }
                 if (!storeAllowedBrands.contains(productChainBrand)) {
                     return "店铺无权发货大包品【" + product.getProductName() + "】,连锁品牌:" + productChainBrand;
                 }

+ 24 - 3
fs-service/src/main/java/com/fs/his/service/impl/FsStoreProductServiceImpl.java

@@ -982,6 +982,8 @@ public class FsStoreProductServiceImpl implements IFsStoreProductService {
     }
 
     private int insertProductByErpData(ProductResponseDTO.ProductInfo erpProduct) {
+        String syncedImageUrl = normalizeErpImageUrl(erpProduct.getPic());
+
         FsStoreProduct newProduct = new FsStoreProduct();
         newProduct.setStoreId(20191853L);
         newProduct.setBarCode(erpProduct.getSkuId());
@@ -989,7 +991,8 @@ public class FsStoreProductServiceImpl implements IFsStoreProductService {
         newProduct.setPrice(erpProduct.getSalePrice());
         newProduct.setCostPrice(erpProduct.getCostPrice());
         newProduct.setOtPrice(erpProduct.getMarketPrice());
-        newProduct.setImgUrl(normalizeErpImageUrl(erpProduct.getPic()));
+        newProduct.setImgUrl(syncedImageUrl);
+        newProduct.setErpImgUrl(erpProduct.getPic());
         newProduct.setUnitName(erpProduct.getUnit());
         newProduct.setBrand(erpProduct.getBrand());
         newProduct.setPrescribeSpec(erpProduct.getPropertiesValue());
@@ -1019,6 +1022,7 @@ public class FsStoreProductServiceImpl implements IFsStoreProductService {
         newAttr.setSales(0);
         newAttr.setPrice(erpProduct.getSalePrice());
         newAttr.setImage(newProduct.getImgUrl());
+        newAttr.setErpImageUrl(erpProduct.getPic());
         newAttr.setCost(erpProduct.getCostPrice());
         newAttr.setBarCode(erpProduct.getSkuId());
         newAttr.setOtPrice(erpProduct.getMarketPrice());
@@ -1040,7 +1044,8 @@ public class FsStoreProductServiceImpl implements IFsStoreProductService {
         updateProduct.setPrice(erpProduct.getSalePrice());
         updateProduct.setCostPrice(erpProduct.getCostPrice());
         updateProduct.setOtPrice(erpProduct.getMarketPrice());
-        updateProduct.setImgUrl(normalizeErpImageUrl(erpProduct.getPic()));
+        updateProduct.setImgUrl(resolveSyncImageUrl(product.getImgUrl(), product.getErpImgUrl(), erpProduct.getPic()));
+        updateProduct.setErpImgUrl(erpProduct.getPic());
         updateProduct.setUnitName(erpProduct.getUnit());
         updateProduct.setBrand(erpProduct.getBrand());
         updateProduct.setPrescribeSpec(erpProduct.getPropertiesValue());
@@ -1054,7 +1059,8 @@ public class FsStoreProductServiceImpl implements IFsStoreProductService {
         updateAttr.setPrice(erpProduct.getSalePrice());
         updateAttr.setCost(erpProduct.getCostPrice());
         updateAttr.setOtPrice(erpProduct.getMarketPrice());
-        updateAttr.setImage(product.getImgUrl());
+        updateAttr.setImage(resolveSyncImageUrl(attr.getImage(), attr.getErpImageUrl(), erpProduct.getPic()));
+        updateAttr.setErpImageUrl(erpProduct.getPic());
         updateAttr.setWeight(erpProduct.getWeight());
         fsStoreProductAttrValueMapper.updateFsStoreProductAttrValue(updateAttr);
     }
@@ -1078,6 +1084,16 @@ public class FsStoreProductServiceImpl implements IFsStoreProductService {
         return Math.min(pageSize, DEFAULT_ERP_PAGE_SIZE);
     }
 
+    private String resolveSyncImageUrl(String currentImageUrl, String currentErpImageUrl, String erpImageUrl) {
+        if (StringUtils.isBlank(erpImageUrl)) {
+            return currentImageUrl;
+        }
+        if (StringUtils.equals(currentErpImageUrl, erpImageUrl) && StringUtils.isNotBlank(currentImageUrl)) {
+            return currentImageUrl;
+        }
+        return normalizeErpImageUrl(erpImageUrl);
+    }
+
     private String normalizeErpImageUrl(String imageUrl) {
         if (StringUtils.isBlank(imageUrl)) {
             return imageUrl;
@@ -1263,4 +1279,9 @@ public class FsStoreProductServiceImpl implements IFsStoreProductService {
             }
         }
     }
+
+    @Override
+    public int updateStoreIdByBrandMatch() {
+        return fsStoreProductMapper.updateStoreIdByBrandMatch();
+    }
 }

+ 62 - 0
fs-service/src/main/java/com/fs/his/service/impl/FsUserServiceImpl.java

@@ -13,6 +13,8 @@ import java.util.concurrent.TimeUnit;
 import java.util.function.Function;
 import java.util.stream.Collectors;
 
+
+
 import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
 import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.util.IdUtil;
@@ -2437,4 +2439,64 @@ public class FsUserServiceImpl implements IFsUserService {
         return fsUserMapper.selectExternalUserList(fsUser);
     }
 
+
+    
+    /**
+     * 处理重复手机号加密问题(建议在服务中调用)
+     */
+    @Override
+    public void fixDuplicatePhoneEncryption() {
+        // 查询有重复手机号的记录
+        List<FsUser> duplicatePhoneUsers = fsUserMapper.findDuplicatePhonesWithCount();
+        System.out.println("发现 " + duplicatePhoneUsers.size() + " 个重复手机号");
+
+        for (FsUser user : duplicatePhoneUsers) {
+            String phone = user.getPhone();
+            if (StringUtils.isEmpty(phone)) {
+                continue;
+            }
+
+            // 循环解密直到长度<=11位
+            String decryptedPhone = phone;
+            int decryptCount = 0;
+            while (decryptedPhone.length() > 11 && decryptCount < 10) {
+                try {
+                    String temp = PhoneUtil.decryptPhone(decryptedPhone);
+                    if (temp == null || temp.equals(decryptedPhone)) {
+                        // 解密失败或没有变化,退出循环
+                        break;
+                    }
+                    decryptedPhone = temp;
+                    decryptCount++;
+                } catch (Exception e) {
+                    System.err.println("解密异常,userId=" + user.getUserId() + ", phone=" + decryptedPhone);
+                    break;
+                }
+            }
+            
+            // 如果解密后长度仍大于11位,记录错误并跳过
+            if (decryptedPhone.length() > 11) {
+                System.err.println("解密后长度仍大于11位,userId=" + user.getUserId() + ", 最终长度=" + decryptedPhone.length() + ", 解密次数=" + decryptCount);
+                continue;
+            }
+
+            // 解密完成后,重新加密并回写数据库
+            String encryptedPhone = PhoneUtil.encryptPhone(decryptedPhone);
+            
+            // 更新回数据库
+            FsUser updateUser = new FsUser();
+            updateUser.setUserId(user.getUserId());
+            updateUser.setPhone(encryptedPhone);
+            int result = fsUserMapper.updateFsUser(updateUser);
+
+            if (result > 0) {
+                System.out.println("更新成功,userId=" + user.getUserId() + ", 解密次数=" + decryptCount + ", 最终长度=" + decryptedPhone.length());
+            } else {
+                System.err.println("更新失败,userId=" + user.getUserId());
+            }
+        }
+        
+        System.out.println("处理完成");
+    }
+
 }

+ 3 - 0
fs-service/src/main/java/com/fs/store/param/h5/FsUserPageListParam.java

@@ -110,6 +110,9 @@ public class FsUserPageListParam implements Serializable {
     @ApiModelProperty(value = "是否下载APP 1=已下载 0=未下载")
     private Integer isDownloadApp;
 
+    @ApiModelProperty(value = "是否绑定手机号 1=已绑定 0=未绑定")
+    private  Integer isBindPhone;
+
 
 }
 

+ 58 - 0
fs-service/src/main/resources/mapper/course/FsCourseWatchLogMapper.xml

@@ -2411,4 +2411,62 @@ FROM
         <include refid="commonConditions"/>
         GROUP BY cd.dept_id, log.period_id, log.video_id
     </select>
+
+    <!-- APP用户看课记录列表 -->
+    <select id="selectAppUserWatchLogList" resultType="com.fs.course.vo.AppUserWatchLogVO">
+        SELECT
+            l.log_id AS logId,
+            l.course_id AS courseId,
+            c.course_name AS courseName,
+            l.video_id AS videoId,
+            v.title AS videoName,
+            l.log_type AS logType,
+            l.duration AS duration,
+            SEC_TO_TIME(l.duration) AS durationFormat,
+            l.create_time AS createTime,
+            l.finish_time AS finishTime,
+            l.watch_type AS watchType
+        FROM fs_course_watch_log l
+        LEFT JOIN fs_user_course c ON l.course_id = c.course_id
+        LEFT JOIN fs_user_course_video v ON l.video_id = v.video_id
+        WHERE l.user_id = #{userId} and watch_type=1 and send_type=1
+        ORDER BY l.create_time DESC
+    </select>
+
+    <!-- 查询用户当日未完课的课程列表 -->
+    <select id="selectTodayUnfinishedCourseList" resultType="com.fs.course.vo.TodayUnfinishedCourseVO">
+        SELECT
+            l.log_id AS logId,
+            l.course_id AS courseId,
+            c.course_name AS courseName,
+            l.video_id AS videoId,
+            v.title AS videoName,
+            l.log_type AS logType,
+            l.duration AS duration,
+            v.duration AS totalDuration,
+            l.create_time AS createTime,
+            l.watch_type AS watchType,
+            l.period_id AS periodId,
+            p.period_name AS periodName,
+            pd.start_date_time AS startDateTime,
+            pd.end_date_time AS endDateTime
+        FROM fs_course_watch_log l
+        LEFT JOIN fs_user_course c ON l.course_id = c.course_id
+        LEFT JOIN fs_user_course_video v ON l.video_id = v.video_id
+        LEFT JOIN fs_user_course_period_days pd ON l.video_id = pd.video_id AND l.period_id = pd.period_id
+        LEFT JOIN fs_user_course_period p ON l.period_id = p.period_id
+        WHERE l.user_id = #{userId}
+        AND l.watch_type = 1
+        AND l.send_type = 1
+        AND l.create_time &gt;= CURDATE()
+        AND l.create_time &lt; DATE_ADD(CURDATE(), INTERVAL 1 DAY)
+        AND l.log_type &lt;&gt; 2
+        AND NOT EXISTS (
+            SELECT 1 FROM fs_course_watch_log f
+            WHERE f.user_id = l.user_id
+            AND f.video_id = l.video_id
+            AND f.log_type = 2
+        )
+        ORDER BY l.create_time DESC
+    </select>
 </mapper>

+ 1 - 1
fs-service/src/main/resources/mapper/course/FsPublicCourseTrafficLogMapper.xml

@@ -13,7 +13,7 @@
         <result property="internetTraffic" column="internet_traffic"/>
         <result property="status" column="status"/>
         <result property="createTime" column="create_time"/>
-        <result property="project_id" column="projectId"/>
+        <result property="projectId" column="project_id"/>
     </resultMap>
 
     <sql id="selectFsPublicCourseTrafficLogVo">

+ 1 - 0
fs-service/src/main/resources/mapper/his/FsExternalOrderMapper.xml

@@ -215,6 +215,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="companyId != null"> AND o.company_id = #{companyId}</if>
             <if test="companyUserId != null"> AND o.company_user_id = #{companyUserId}</if>
             <if test="isSync != null"> AND o.is_sync = #{isSync}</if>
+            ${params.dataScope}
         </where>
         GROUP BY o.order_id
         ORDER BY o.create_time DESC

+ 5 - 1
fs-service/src/main/resources/mapper/his/FsStoreProductAttrValueMapper.xml

@@ -12,6 +12,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         <result property="sales"    column="sales"    />
         <result property="price"    column="price"    />
         <result property="image"    column="image"    />
+        <result property="erpImageUrl"    column="erp_image_url"    />
         <result property="cost"    column="cost"    />
         <result property="agentPrice"    column="agent_price"    />
         <result property="barCode"    column="bar_code"    />
@@ -28,7 +29,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
     </resultMap>
 
     <sql id="selectFsStoreProductAttrValueVo">
-        select id,doctor_brokerage, product_id, sku, stock, sales, price, image, cost_price cost, bar_code, ot_price, weight, volume, brokerage, brokerage_two,brokerage_three,give_integral  from fs_store_product_attr_value
+        select id,doctor_brokerage, product_id, sku, stock, sales, price, image, erp_image_url, cost_price cost, bar_code, ot_price, weight, volume, brokerage, brokerage_two,brokerage_three,give_integral  from fs_store_product_attr_value
     </sql>
 
     <select id="selectFsStoreProductAttrValueList" parameterType="FsStoreProductAttrValue" resultMap="FsStoreProductAttrValueResult">
@@ -66,6 +67,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="sales != null">sales,</if>
             <if test="price != null">price,</if>
             <if test="image != null">image,</if>
+            <if test="erpImageUrl != null and erpImageUrl != ''">erp_image_url,</if>
             <if test="cost != null">cost_price,</if>
             <if test="barCode != null">bar_code,</if>
             <if test="otPrice != null">ot_price,</if>
@@ -85,6 +87,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="sales != null">#{sales},</if>
             <if test="price != null">#{price},</if>
             <if test="image != null">#{image},</if>
+            <if test="erpImageUrl != null and erpImageUrl != ''">#{erpImageUrl},</if>
             <if test="cost != null">#{cost},</if>
             <if test="barCode != null">#{barCode},</if>
             <if test="otPrice != null">#{otPrice},</if>
@@ -107,6 +110,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="sales != null">sales = #{sales},</if>
             <if test="price != null">price = #{price},</if>
             <if test="image != null">image = #{image},</if>
+            <if test="erpImageUrl != null and erpImageUrl != ''">erp_image_url = #{erpImageUrl},</if>
             <if test="cost != null">cost_price = #{cost},</if>
             <if test="agentPrice != null">agent_price = #{agentPrice},</if>
             <if test="barCode != null">bar_code = #{barCode},</if>

+ 5 - 1
fs-service/src/main/resources/mapper/his/FsStoreProductMapper.xml

@@ -8,6 +8,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         <result property="productId"    column="product_id"    />
         <result property="storeId"    column="store_id"    />
         <result property="imgUrl"    column="img_url"    />
+        <result property="erpImgUrl"    column="erp_img_url"    />
         <result property="images"    column="images"    />
         <result property="productName"    column="product_name"    />
         <result property="productIntroduce"    column="product_introduce"    />
@@ -50,7 +51,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
     </resultMap>
 
     <sql id="selectFsStoreProductVo">
-        select product_id,is_prescribe,is_drug, store_id, img_url, images, product_name, product_introduce, keyword, bar_code, cate_id, price, ot_price, unit_name, sort, sales, stock, is_show, is_hot, is_benefit, is_best, is_new, `desc`, create_time, update_time, is_postage, is_del, give_integral, cost_price, views, code_url, spec_type, product_type, prescribe_code, prescribe_spec, prescribe_factory, prescribe_name, is_display, temp_id,brand,product_source_type,chain_brand from fs_store_product
+        select product_id,is_prescribe,is_drug, store_id, img_url, erp_img_url, images, product_name, product_introduce, keyword, bar_code, cate_id, price, ot_price, unit_name, sort, sales, stock, is_show, is_hot, is_benefit, is_best, is_new, `desc`, create_time, update_time, is_postage, is_del, give_integral, cost_price, views, code_url, spec_type, product_type, prescribe_code, prescribe_spec, prescribe_factory, prescribe_name, is_display, temp_id,brand,product_source_type,chain_brand from fs_store_product
     </sql>
 
     <select id="selectFsStoreProductList" parameterType="FsStoreProduct" resultMap="FsStoreProductResult">
@@ -107,6 +108,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         <trim prefix="(" suffix=")" suffixOverrides=",">
             <if test="storeId != null">store_id,</if>
             <if test="imgUrl != null and imgUrl != ''">img_url,</if>
+            <if test="erpImgUrl != null and erpImgUrl != ''">erp_img_url,</if>
             <if test="images != null and images != ''">images,</if>
             <if test="productName != null">product_name,</if>
             <if test="productIntroduce != null">product_introduce,</if>
@@ -150,6 +152,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         <trim prefix="values (" suffix=")" suffixOverrides=",">
             <if test="storeId != null">#{storeId},</if>
             <if test="imgUrl != null and imgUrl != ''">#{imgUrl},</if>
+            <if test="erpImgUrl != null and erpImgUrl != ''">#{erpImgUrl},</if>
             <if test="images != null and images != ''">#{images},</if>
             <if test="productName != null">#{productName},</if>
             <if test="productIntroduce != null">#{productIntroduce},</if>
@@ -197,6 +200,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         <trim prefix="SET" suffixOverrides=",">
             <if test="storeId != null">store_id = #{storeId},</if>
             <if test="imgUrl != null and imgUrl != ''">img_url = #{imgUrl},</if>
+            <if test="erpImgUrl != null and erpImgUrl != ''">erp_img_url = #{erpImgUrl},</if>
             <if test="images != null and images != ''">images = #{images},</if>
             <if test="productName != null">product_name = #{productName},</if>
             <if test="productIntroduce != null">product_introduce = #{productIntroduce},</if>

+ 20 - 0
fs-service/src/main/resources/mapper/his/FsUserMapper.xml

@@ -450,6 +450,16 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
                     </when>
                 </choose>
             </if>
+            <if test="isBindPhone != null">
+                <choose>
+                    <when test="isBindPhone == 1">
+                        and fs_user.phone is not null and fs_user.phone != ''
+                    </when>
+                    <when test="isBindPhone == 0">
+                        and fs_user.phone is null or fs_user.phone = ''
+                    </when>
+                </choose>
+            </if>
         </where>
         limit ${(pageNum-1)*pageSize},${pageSize}
     </select>
@@ -509,6 +519,16 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
                     </when>
                 </choose>
             </if>
+            <if test="isBindPhone != null">
+                <choose>
+                    <when test="isBindPhone == 1">
+                        and fs_user.phone is not null and fs_user.phone != ''
+                    </when>
+                    <when test="isBindPhone == 0">
+                        and fs_user.phone is null or fs_user.phone = ''
+                    </when>
+                </choose>
+            </if>
         </where>
     </select>
     <update id="transferCompanyUser">

+ 1 - 34
fs-user-app/src/main/java/com/fs/app/controller/AppLoginController.java

@@ -732,40 +732,7 @@ public class AppLoginController extends AppBaseController{
 
     @PostMapping("/registerByPhone")
     public R registerByPhone(@RequestBody Map<String,String> map){
-        String phone = map.get("phone");
-        String code = map.get("code");
-        String password = map.get("password");
-        String encryptPhone = encryptPhone(phone);
-        List<FsUser> users = userService.selectFsUserListByPhone(encryptPhone);
-        if (users == null || CollectionUtil.isEmpty(users)){
-            String s = encryptPhoneOldKey(phone);
-            users = userService.selectFsUserListByPhone(s);
-        }
-        if (!CollectionUtil.isEmpty(users)){
-            return R.error("此账号已经注册");
-        }
-        String redisCode = redisCache.getCacheObject("sms:code:" + phone);
-        if (StringUtils.isEmpty(redisCode)){
-            return R.error("验证码已过期,请重新发送");
-        }
-        if (!redisCode.equals(code)) {
-            return R.error("验证码错误");
-        }
-        FsUser user = new FsUser();
-        // 创建新用户
-        user.setPhone(encryptPhone);
-        user.setJpushId(map.get("jpushId"));
-        user.setSource(map.get("source"));
-        user.setNickName("app用户" + phone.substring(phone.length() - 4));
-        user.setStatus(1);
-        user.setAvatar("https://cos.his.cdwjyyh.com/fs/20240926/420728ee06e54575ba82665dedb4756b.png");
-        user.setPassword(Md5Utils.hash(password));
-        user.setCreateTime(new Date());
-        if (userService.insertFsUser(user) > 0) {
-            return R.ok("注册成功");
-        } else {
-            return R.error("注册失败");
-        }
+        return R.error("请升级app最新版本");
     }
 
     @PostMapping("/resetPassword")