Bladeren bron

ipad 发送限制记录

吴树波 1 week geleden
bovenliggende
commit
e0c1d43861

+ 19 - 2
fs-admin/src/main/java/com/fs/course/controller/FsUserVideoController.java

@@ -180,8 +180,11 @@ public class FsUserVideoController extends BaseController
         return toAjax(fsUserVideoService.updateFsUserVideoIsShow(videoIds,0));
     }
 
-    private static final String VIDEO_UPLOAD_DIR = "C:\\fs\\uploadPath\\userVideo\\video";  // 上传目录
-    private static final String FRAME_OUTPUT_DIR = "C:\\fs\\uploadPath\\userVideo\\frame";  // 输出帧的目录
+//    private static final String VIDEO_UPLOAD_DIR = "C:\\fs\\uploadPath\\userVideo\\video";  // 上传目录
+//    private static final String FRAME_OUTPUT_DIR = "C:\\fs\\uploadPath\\userVideo\\frame";  // 输出帧的目录
+    // 改为使用系统临时目录或相对路径
+    private static final String VIDEO_UPLOAD_DIR = System.getProperty("java.io.tmpdir") + File.separator + "fs_upload" + File.separator + "userVideo" + File.separator + "video";
+    private static final String FRAME_OUTPUT_DIR = System.getProperty("java.io.tmpdir") + File.separator + "fs_upload" + File.separator + "userVideo" + File.separator + "frame";
 
 
     /**
@@ -198,16 +201,19 @@ public class FsUserVideoController extends BaseController
 
         // 保存上传的视频文件
         String videoFileName = System.currentTimeMillis() + "_" + UUID.randomUUID().toString().replaceAll("-", "").substring(0, 16);
+        createDir(VIDEO_UPLOAD_DIR);
         File videoFile = new File(VIDEO_UPLOAD_DIR, videoFileName);
         try {
             file.transferTo(videoFile);
         } catch (IOException e) {
+            e.printStackTrace();
             // 记录错误日志
             return R.error("获取封面失败");
         }
 
         // 提取视频第一帧
         String frameFileName = FilenameUtils.removeExtension(videoFileName) + "_frame.jpg";
+        createDir(FRAME_OUTPUT_DIR);
         File frameFile = new File(FRAME_OUTPUT_DIR, frameFileName);
         try {
             extractFirstFrame(videoFile.getAbsolutePath(), frameFile.getAbsolutePath());
@@ -268,6 +274,17 @@ public class FsUserVideoController extends BaseController
         }
     }
 
+    private void createDir(String path){
+        File videoUploadDir = new File(path);
+        if (!videoUploadDir.exists()) {
+            boolean created = videoUploadDir.mkdirs();
+            if (!created) {
+                log.error("创建视频上传目录失败: {}", path);
+            }
+            log.info("创建视频上传目录: {}", path);
+        }
+    }
+
     @PostMapping("/updateUrl")
     public R updateUrl()
     {

+ 154 - 0
fs-admin/src/main/java/com/fs/qw/controller/QwPushCountController.java

@@ -0,0 +1,154 @@
+package com.fs.qw.controller;
+
+import com.fs.common.annotation.Log;
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.core.page.TableDataInfo;
+import com.fs.common.enums.BusinessType;
+import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.qw.domain.QwPushCount;
+import com.fs.qw.service.IQwPushCountService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.io.ResourceLoader;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.*;
+
+/**
+ * 定义销售推送不同类型的企业消息的次数Controller
+ *
+ * @author fs
+ * @date 2025-08-22
+ */
+@RestController
+@RequestMapping("/qw/qwPushCount")
+public class QwPushCountController extends BaseController {
+    @Autowired
+    private IQwPushCountService qwPushCountService;
+    @Autowired
+    private ResourceLoader resourceLoader;
+
+    /**
+     * 查询定义销售推送不同类型的企业消息的次数列表
+     */
+    @PreAuthorize("@ss.hasPermi('qw:qwPushCount:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(QwPushCount qwPushCount) {
+        startPage();
+        List<QwPushCount> list = qwPushCountService.selectQwPushCountList(qwPushCount);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出定义销售推送不同类型的企业消息的次数列表
+     */
+    @PreAuthorize("@ss.hasPermi('qw:qwPushCount:export')")
+    @Log(title = "定义销售推送不同类型的企业消息的次数", businessType = BusinessType.EXPORT)
+    @GetMapping("/export")
+    public AjaxResult export(QwPushCount qwPushCount) {
+        List<QwPushCount> list = qwPushCountService.selectQwPushCountList(qwPushCount);
+        ExcelUtil<QwPushCount> util = new ExcelUtil<QwPushCount>(QwPushCount.class);
+        return util.exportExcel(list, "定义销售推送不同类型的企业消息的次数数据");
+    }
+
+    /**
+     * 获取定义销售推送不同类型的企业消息的次数详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('qw:qwPushCount:query')")
+    @GetMapping(value = "/{id}")
+    public AjaxResult getInfo(@PathVariable("id") Long id) {
+        List<Long> companyIdList=new ArrayList<>();
+        QwPushCount qwPushCount = qwPushCountService.selectQwPushCountById(id);
+        companyIdList.add(qwPushCount.getCompanyId());
+        qwPushCount.setCompanyIdList(companyIdList);
+        return AjaxResult.success(qwPushCount);
+    }
+
+
+    /**
+     * 新增定义销售推送不同类型的企业消息的次数
+     */
+    @PreAuthorize("@ss.hasPermi('qw:qwPushCount:add')")
+    @Log(title = "定义销售推送不同类型的企业消息的次数", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody QwPushCount qwPushCount) {
+        List<Long> existingIds = new ArrayList<>();
+        Map<String, Long> existingDataMap = new HashMap<>();
+        List<QwPushCount> existingPushCounts = qwPushCountService.selectQwPushCountLists();
+        if (existingPushCounts != null && !existingPushCounts.isEmpty()) {
+            existingPushCounts.forEach(item -> {
+                String key = buildDataKey(item.getType(), item.getCompanyId());
+                existingDataMap.put(key, item.getId());
+            });
+        }
+        // 处理公司ID列表(可能为null或空)
+        List<Long> companyIdList = qwPushCount.getCompanyIdList();
+        boolean isEmptyList = companyIdList == null || companyIdList.isEmpty();
+
+        if (isEmptyList) {
+            // 处理无公司ID列表的情况
+            String key = buildDataKey(qwPushCount.getType(), null);
+            if (existingDataMap.containsKey(key)) {
+                existingIds.add(qwPushCount.getId());
+            } else {
+                qwPushCountService.insertQwPushCount(qwPushCount);
+            }
+        } else {
+            // 处理有公司ID列表的情况
+            companyIdList.forEach(companyId -> {
+                String key = buildDataKey(qwPushCount.getType(), companyId);
+                if (existingDataMap.containsKey(key)) {
+                    existingIds.add(companyId);
+                } else {
+                    qwPushCount.setCompanyId(companyId);
+                    qwPushCountService.insertQwPushCount(qwPushCount);
+                }
+            });
+        }
+
+        // 统一处理返回结果
+        if (!existingIds.isEmpty()) {
+            return error("新增限定类型已存在:失败条数" + existingIds.size());
+        } else {
+            return toAjax(1);
+        }
+    }
+    private String buildDataKey(Integer type, Long companyId) {
+        return type + "_" + (companyId == null ? "null" : companyId);
+    }
+
+    /**
+     * 修改定义销售推送不同类型的企业消息的次数
+     */
+    @PreAuthorize("@ss.hasPermi('qw:qwPushCount:edit')")
+    @Log(title = "定义销售推送不同类型的企业消息的次数", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody QwPushCount qwPushCount) {
+        QwPushCount pushCount;
+        if (qwPushCount.getCompanyId() != null) {
+            pushCount = qwPushCountService.SelectQwPushCountByCompanyId(qwPushCount.getType(), qwPushCount.getCompanyId());
+        } else {
+            pushCount = qwPushCountService.SelectQwPushCountByType(qwPushCount.getType());
+        }
+        if (pushCount != null) {
+            if (!Objects.equals(pushCount.getId(), qwPushCount.getId()) && Objects.equals(pushCount.getCompanyId(), qwPushCount.getCompanyId()) && Objects.equals(pushCount.getType(), qwPushCount.getType())) {
+                return toAjax(0);
+            }
+            if (Objects.equals(pushCount.getPushCount(), qwPushCount.getPushCount())) {
+                return toAjax(0);
+            }
+        }
+        return toAjax(qwPushCountService.updateQwPushCount(qwPushCount));
+    }
+
+    /**
+     * 删除定义销售推送不同类型的企业消息的次数
+     */
+    @PreAuthorize("@ss.hasPermi('qw:qwPushCount:remove')")
+    @Log(title = "定义销售推送不同类型的企业消息的次数", businessType = BusinessType.DELETE)
+    @DeleteMapping("/{ids}")
+    public AjaxResult remove(@PathVariable Long[] ids) {
+        return toAjax(qwPushCountService.deleteQwPushCountByIds(ids));
+    }
+}

+ 25 - 0
fs-common/src/main/java/com/fs/common/utils/DateUtils.java

@@ -270,5 +270,30 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils
         cal.add(Calendar.DATE, days);
         return new SimpleDateFormat("yyyy-MM-dd").format(cal.getTime());
     }
+    /**
+     * 获取到当天时间的开始:当天0时0分0秒0毫秒
+     * @return
+     */
+    public static Long toStartTime( ) {
+        Calendar calendar = Calendar.getInstance();
+        calendar.set(Calendar.HOUR_OF_DAY, 0);
+        calendar.set(Calendar.MINUTE, 0);
+        calendar.set(Calendar.SECOND, 0);
+        calendar.set(Calendar.MILLISECOND, 0);
+        return calendar.getTimeInMillis();
+    }
+
+    /**
+     * 获取到当天时间的结束:当天23时59分59秒999毫秒
+     * @return
+     */
+    public static Long toEndTime() {
+        Calendar calendar = Calendar.getInstance();
+        calendar.set(Calendar.HOUR_OF_DAY, 23);
+        calendar.set(Calendar.MINUTE, 59);
+        calendar.set(Calendar.SECOND, 59);
+        calendar.set(Calendar.MILLISECOND, 999);
+        return calendar.getTimeInMillis();
+    }
 
 }

+ 67 - 18
fs-ipad-task/src/main/java/com/fs/app/task/SendMsg.java

@@ -5,6 +5,7 @@ import com.alibaba.fastjson.JSON;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.fs.app.service.IpadSendServer;
 import com.fs.common.core.redis.RedisCacheT;
+import com.fs.common.utils.DateUtils;
 import com.fs.common.utils.PubFun;
 import com.fs.company.service.ICompanyMiniappService;
 import com.fs.course.config.CourseConfig;
@@ -12,8 +13,12 @@ import com.fs.course.domain.FsCoursePlaySourceConfig;
 import com.fs.course.service.IFsCoursePlaySourceConfigService;
 import com.fs.ipad.vo.BaseVo;
 import com.fs.qw.domain.QwIpadServer;
+import com.fs.qw.domain.QwPushCount;
+import com.fs.qw.domain.QwRestrictionPushRecord;
 import com.fs.qw.domain.QwUser;
 import com.fs.qw.mapper.QwIpadServerMapper;
+import com.fs.qw.mapper.QwPushCountMapper;
+import com.fs.qw.mapper.QwRestrictionPushRecordMapper;
 import com.fs.qw.mapper.QwUserMapper;
 import com.fs.qw.service.impl.AsyncSopTestService;
 import com.fs.qw.vo.QwSopCourseFinishTempSetting;
@@ -55,6 +60,8 @@ public class SendMsg {
     private final AsyncSopTestService asyncSopTestService;
     private final ICompanyMiniappService companyMiniappService;
     private final IFsCoursePlaySourceConfigService fsCoursePlaySourceConfigService;
+    private final QwPushCountMapper qwPushCountMapper;
+    private final QwRestrictionPushRecordMapper qwRestrictionPushRecordMapper;
 
     @Value("${group-no}")
     private String groupNo;
@@ -65,7 +72,7 @@ public class SendMsg {
     @Qualifier("customThreadPool")
     private ThreadPoolTaskExecutor customThreadPool;
 
-    public SendMsg(QwUserMapper qwUserMapper, QwSopLogsMapper qwSopLogsMapper, IpadSendServer sendServer, SysConfigMapper sysConfigMapper, IQwSopLogsService qwSopLogsService, QwIpadServerMapper qwIpadServerMapper, RedisCacheT<Long> redisCache, AsyncSopTestService asyncSopTestService, ICompanyMiniappService companyMiniappService, IFsCoursePlaySourceConfigService fsCoursePlaySourceConfigService) {
+    public SendMsg(QwUserMapper qwUserMapper, QwSopLogsMapper qwSopLogsMapper, IpadSendServer sendServer, SysConfigMapper sysConfigMapper, IQwSopLogsService qwSopLogsService, QwIpadServerMapper qwIpadServerMapper, RedisCacheT<Long> redisCache, AsyncSopTestService asyncSopTestService, ICompanyMiniappService companyMiniappService, IFsCoursePlaySourceConfigService fsCoursePlaySourceConfigService, QwPushCountMapper qwPushCountMapper, QwRestrictionPushRecordMapper qwRestrictionPushRecordMapper) {
         this.qwUserMapper = qwUserMapper;
         this.qwSopLogsMapper = qwSopLogsMapper;
         this.sendServer = sendServer;
@@ -76,6 +83,8 @@ public class SendMsg {
         this.asyncSopTestService = asyncSopTestService;
         this.companyMiniappService = companyMiniappService;
         this.fsCoursePlaySourceConfigService = fsCoursePlaySourceConfigService;
+        this.qwPushCountMapper = qwPushCountMapper;
+        this.qwRestrictionPushRecordMapper = qwRestrictionPushRecordMapper;
     }
     private List<QwUser> getQwUserList() {
         if (qwUserList.isEmpty()) {
@@ -191,27 +200,67 @@ public class SendMsg {
                 continue;
             }
             redisCache.setCacheObject(key, System.currentTimeMillis(), 24, TimeUnit.HOURS);
+            List<QwPushCount> pushCountList = qwPushCountMapper.selectQwPushCountLists();
+            Map<Integer, List<QwPushCount>> pushMap = pushCountList.stream().collect(Collectors.groupingBy(QwPushCount::getType));
             // 循环发送消息里面的每一条消息
             for (QwSopCourseFinishTempSetting.Setting content : setting.getSetting()) {
                 long start4 = System.currentTimeMillis();
-                // 发送
-                sendServer.send(content, user, qwSopLogs, miniMap, parentVo);
-                long end4 = System.currentTimeMillis();
-                log.info("请求pad发送完成:{}, {}, 时长4:{}", user.getQwUserName(), qwSopLogs.getId(), end4 - start4);
-                if(content.getSendStatus() == 2 && ("请求失败:消息发送过于频繁,请稍后再试".equals(content.getSendRemarks()) || "请求失败:请求频率异常".equals(content.getSendRemarks()))){
-                    QwUser update = new QwUser();
-                    update.setRemark("请求频率异常,暂停发送,三小时后恢复继续发送");
-                    update.setUpdateTime(new Date());
-                    qwUserMapper.update(update, new QueryWrapper<QwUser>().eq("id", user.getId()));
-                    redisCache.setCacheObject("qw:user:id:" + user.getId(), user.getId(), 3, TimeUnit.HOURS);
-                    return;
+                //判断当前销售推送客户消息限制
+                Long qwUserId = qwUser.getId();//销售的Id
+                Integer type = Integer.valueOf(content.getContentType());//发送消息的类型
+                Long customerId = qwSopLogs.getExternalId();//客户ID
+                Long companyId = qwSopLogs.getCompanyId();//公司ID
+                Integer pushCount = -99;
+                if(pushMap.containsKey(type)){
+                    List<QwPushCount> qwPushCounts = pushMap.get(type);
+                    Optional<QwPushCount> optional = qwPushCounts.stream().filter(e -> Objects.equals(e.getCompanyId(), companyId)).findFirst();
+                    if(optional.isPresent()){
+                        pushCount = optional.get().getPushCount();
+                    }else{
+                        Optional<QwPushCount> nullCount = qwPushCounts.stream().filter(e -> e.getCompanyId() == null).findFirst();
+                        if(nullCount.isPresent()){
+                            pushCount = nullCount.get().getPushCount();
+                        }
+                    }
                 }
-                try {
-                    int delay = ThreadLocalRandom.current().nextInt(300, 1000);
-                    log.debug("pad发送消息等待:{}ms", delay);
-                    Thread.sleep(delay);
-                } catch (InterruptedException e) {
-                    log.error("线程等待错误!");
+                //查询是否有设置限制客服推送消息次数
+//                    Integer pushCount=pushCountMap.containsKey(String.valueOf(companyId)) ? pushCountMap.get(String.valueOf(companyId)): pushCountMap.getOrDefault(String.valueOf(type), -99);
+                int salesPushCustomerMessageCount = qwRestrictionPushRecordMapper.selectQwRestrictionPushRecord(qwUserId, customerId, type, DateUtils.toStartTime(), DateUtils.toEndTime());
+                if (pushCount != -99 && salesPushCustomerMessageCount >= pushCount) {
+                    content.setSendStatus(2);//设置发送失败状态
+                    content.setSendRemarks("发送次数达到上限");
+                } else {
+                    // 发送
+                    sendServer.send(content, user, qwSopLogs, miniMap, parentVo);
+                    //判断销售推送成功:保存记录
+                    if (content.getSendStatus() != 2) {
+                        QwRestrictionPushRecord qrpr = new QwRestrictionPushRecord();
+                        qrpr.setType(type);
+                        qrpr.setQwUserId(qwUserId);
+                        qrpr.setQwExternalId(customerId);
+                        qrpr.setCompanyId(companyId);
+                        qrpr.setStatus(1);
+                        qrpr.setCreateTime(DateUtils.getTime());
+                        qrpr.setTime(System.currentTimeMillis());
+                        qwRestrictionPushRecordMapper.insert(qrpr);
+                    }
+                    long end4 = System.currentTimeMillis();
+                    log.info("请求pad发送完成:{}, {}, 时长4:{}", user.getQwUserName(), qwSopLogs.getId(), end4 - start4);
+                    if(content.getSendStatus() == 2 && ("请求失败:消息发送过于频繁,请稍后再试".equals(content.getSendRemarks()) || "请求失败:请求频率异常".equals(content.getSendRemarks()))){
+                        QwUser update = new QwUser();
+                        update.setRemark("请求频率异常,暂停发送,三小时后恢复继续发送");
+                        update.setUpdateTime(new Date());
+                        qwUserMapper.update(update, new QueryWrapper<QwUser>().eq("id", user.getId()));
+                        redisCache.setCacheObject("qw:user:id:" + user.getId(), user.getId(), 3, TimeUnit.HOURS);
+                        return;
+                    }
+                    try {
+                        int delay = ThreadLocalRandom.current().nextInt(300, 1000);
+                        log.debug("pad发送消息等待:{}ms", delay);
+                        Thread.sleep(delay);
+                    } catch (InterruptedException e) {
+                        log.error("线程等待错误!");
+                    }
                 }
             }
             // 推送 APP

+ 5 - 1
fs-service/src/main/java/com/fs/hisStore/service/impl/FsStoreProductScrmServiceImpl.java

@@ -338,7 +338,7 @@ public class FsStoreProductScrmServiceImpl implements IFsStoreProductScrmService
         product.setStoreId(param.getStoreId());
         product.setIsDrug(param.getIsDrug().toString());
         //校验店铺资质信息
-        if(!("益善缘".equals(cloudHostProper.getCompanyName())) && !("康年堂".equals(cloudHostProper.getCompanyName()))){
+        if(!("益善缘".equals(cloudHostProper.getCompanyName())) && !("康年堂".equals(cloudHostProper.getCompanyName())) && !("纯正堂".equals(cloudHostProper.getCompanyName()))){
             //获取店铺
             FsStoreScrm store = fsStoreScrmService.selectFsStoreByStoreId(product.getStoreId());
             if(store == null || 1 != store.getStatus()){
@@ -369,6 +369,10 @@ public class FsStoreProductScrmServiceImpl implements IFsStoreProductScrmService
             }
         }
 
+        if("纯正堂".equals(cloudHostProper.getCompanyName())){
+            product.setIsAudit("1");
+        }
+
         if(param.getProductId() != null && param.getProductId() > 0){
             //对已上架的商品进行修改需要重新审核
             if(1 == product.getIsShow() && "1".equals(product.getIsAudit())){

+ 47 - 0
fs-service/src/main/java/com/fs/qw/domain/QwPushCount.java

@@ -0,0 +1,47 @@
+package com.fs.qw.domain;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.fs.common.annotation.Excel;
+import com.fs.common.core.domain.BaseEntity;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.util.List;
+
+/**
+ * 定义销售推送不同类型的企业消息的次数对象 qw_push_count
+ *
+ * @author fs
+ * @date 2025-08-22
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class QwPushCount extends BaseEntity{
+
+    /** $column.columnComment */
+    @TableId(type = IdType.AUTO)
+    private Long id;
+
+    /** 推送类型 */
+    @Excel(name = "推送类型")
+    private Integer type;
+
+    /** 销售推送企业微信消息的限定次数 */
+    @Excel(name = "销售推送企业微信消息的限定次数")
+    private Integer pushCount;
+
+    /** 推送公司id */
+    @Excel(name = "推送公司id")
+    private Long companyId;
+
+    /** 状态 */
+    @Excel(name = "状态")
+    private Integer status;
+
+    // 标记该字段不与数据库字段对应
+    @TableField(exist = false)
+    private List<Long> companyIdList;
+
+}

+ 39 - 0
fs-service/src/main/java/com/fs/qw/domain/QwRestrictionPushRecord.java

@@ -0,0 +1,39 @@
+package com.fs.qw.domain;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * 记录销售推送成功信息
+ *
+ * @author liupeng
+ * @date 2025-08-20
+ */
+@Data
+public class QwRestrictionPushRecord implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @TableId(type = IdType.AUTO)
+    private Integer id;
+
+    private Integer type;
+
+    private Long qwUserId;
+
+    private Long qwExternalId;
+
+    private Long companyId;
+
+    private Integer status;
+
+    private String createTime;
+
+    private Long time;
+
+    private String remarks;
+
+}

+ 78 - 0
fs-service/src/main/java/com/fs/qw/mapper/QwPushCountMapper.java

@@ -0,0 +1,78 @@
+package com.fs.qw.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.fs.qw.domain.QwPushCount;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Select;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+
+/**
+ * 销售推送不同类型消息次数Mapper接口
+ *
+ * @author liupeng
+ * @date 2025-08-20
+ */
+@Repository
+public interface QwPushCountMapper extends BaseMapper<QwPushCount> {
+
+    @Select("select id,type,push_count,company_id,status from qw_push_count WHERE status=0")
+    public List<QwPushCount> selectQwPushCountLists();
+
+    @Select("select id,type,push_count,company_id,status from qw_push_count WHERE type = #{type} and company_id=#{companyId} and status=0")
+    public QwPushCount SelectQwPushCountByCompanyId(@Param("type") Integer type, @Param("companyId") Long companyId);  // 注解和SQL中的参数名都使用companyId
+
+    @Select("select id,type,push_count,company_id,status from qw_push_count WHERE type = #{type} and company_id is null and status=0")
+    public QwPushCount SelectQwPushCountByType(@Param("type") Integer type);
+
+
+    /**
+     * 查询定义销售推送不同类型的企业消息的次数
+     *
+     * @param id 定义销售推送不同类型的企业消息的次数主键
+     * @return 定义销售推送不同类型的企业消息的次数
+     */
+    QwPushCount selectQwPushCountById(Long id);
+
+    /**
+     * 查询定义销售推送不同类型的企业消息的次数列表
+     *
+     * @param qwPushCount 定义销售推送不同类型的企业消息的次数
+     * @return 定义销售推送不同类型的企业消息的次数集合
+     */
+    List<QwPushCount> selectQwPushCountList(QwPushCount qwPushCount);
+
+    /**
+     * 新增定义销售推送不同类型的企业消息的次数
+     *
+     * @param qwPushCount 定义销售推送不同类型的企业消息的次数
+     * @return 结果
+     */
+    int insertQwPushCount(QwPushCount qwPushCount);
+
+    /**
+     * 修改定义销售推送不同类型的企业消息的次数
+     *
+     * @param qwPushCount 定义销售推送不同类型的企业消息的次数
+     * @return 结果
+     */
+    int updateQwPushCount(QwPushCount qwPushCount);
+
+    /**
+     * 删除定义销售推送不同类型的企业消息的次数
+     *
+     * @param id 定义销售推送不同类型的企业消息的次数主键
+     * @return 结果
+     */
+    int deleteQwPushCountById(Long id);
+
+    /**
+     * 批量删除定义销售推送不同类型的企业消息的次数
+     *
+     * @param ids 需要删除的数据主键集合
+     * @return 结果
+     */
+    int deleteQwPushCountByIds(Long[] ids);
+
+}

+ 49 - 0
fs-service/src/main/java/com/fs/qw/mapper/QwRestrictionPushRecordMapper.java

@@ -0,0 +1,49 @@
+package com.fs.qw.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.fs.qw.domain.QwRestrictionPushRecord;
+import org.apache.ibatis.annotations.Delete;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Select;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+
+/**
+ * 记录销售推送成功信息Mapper接口
+ *
+ * @author liupeng
+ * @date 2025-08-20
+ */
+@Repository
+public interface QwRestrictionPushRecordMapper extends BaseMapper<QwRestrictionPushRecord> {
+
+    int insert(QwRestrictionPushRecord qwRestrictionPushRecord);
+    /**
+     * 查询当前销售ID对应类型的QW推送成功的记录
+     *
+     * @param type
+     * @param startTime
+     * @param endTime
+     * @return
+     */
+    @Select("select count(id) from qw_restriction_push_record where qw_user_id=#{qwUserId} and qw_external_id=#{qwExternalId} and type=#{type} and time>#{startTime} and time<=#{endTime}")
+    int selectQwRestrictionPushRecord(@Param("qwUserId") Long qwUserId,
+                                      @Param("qwExternalId") Long qwExternalId,
+                                      @Param("type") Integer type,
+                                      @Param("startTime") Long startTime,
+                                      @Param("endTime") Long endTime);
+
+    @Select("select id from qw_restriction_push_record where time<#{time}")
+    List<Long> selectExpirePushRecord(@Param("time") Long time);
+
+    @Delete("<script>" +
+            "delete from qw_restriction_push_record " +
+            "where id in " +
+            "<foreach collection='ids' item='id' open='(' separator=',' close=')'>" +
+            "#{id}" +
+            "</foreach>" +
+            "</script>")
+    public int deleteQwRestrictionPushRecordIds(@Param("ids") Long[] ids);
+}
+

+ 68 - 0
fs-service/src/main/java/com/fs/qw/service/IQwPushCountService.java

@@ -0,0 +1,68 @@
+package com.fs.qw.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.fs.qw.domain.QwPushCount;
+
+import java.util.List;
+
+/**
+ * 定义销售推送不同类型的企业消息的次数Service接口
+ * 
+ * @author fs
+ * @date 2025-08-22
+ */
+public interface IQwPushCountService extends IService<QwPushCount>{
+
+    public List<QwPushCount> selectQwPushCountLists();
+
+    public QwPushCount SelectQwPushCountByCompanyId( Integer type,Long companyId);  // 注解和SQL中的参数名都使用companyId
+
+    public QwPushCount SelectQwPushCountByType(Integer type);
+    /**
+     * 查询定义销售推送不同类型的企业消息的次数
+     * 
+     * @param id 定义销售推送不同类型的企业消息的次数主键
+     * @return 定义销售推送不同类型的企业消息的次数
+     */
+    QwPushCount selectQwPushCountById(Long id);
+
+    /**
+     * 查询定义销售推送不同类型的企业消息的次数列表
+     * 
+     * @param qwPushCount 定义销售推送不同类型的企业消息的次数
+     * @return 定义销售推送不同类型的企业消息的次数集合
+     */
+    List<QwPushCount> selectQwPushCountList(QwPushCount qwPushCount);
+
+    /**
+     * 新增定义销售推送不同类型的企业消息的次数
+     * 
+     * @param qwPushCount 定义销售推送不同类型的企业消息的次数
+     * @return 结果
+     */
+    int insertQwPushCount(QwPushCount qwPushCount);
+
+    /**
+     * 修改定义销售推送不同类型的企业消息的次数
+     * 
+     * @param qwPushCount 定义销售推送不同类型的企业消息的次数
+     * @return 结果
+     */
+    int updateQwPushCount(QwPushCount qwPushCount);
+
+    /**
+     * 批量删除定义销售推送不同类型的企业消息的次数
+     * 
+     * @param ids 需要删除的定义销售推送不同类型的企业消息的次数主键集合
+     * @return 结果
+     */
+    int deleteQwPushCountByIds(Long[] ids);
+
+    /**
+     * 删除定义销售推送不同类型的企业消息的次数信息
+     * 
+     * @param id 定义销售推送不同类型的企业消息的次数主键
+     * @return 结果
+     */
+    int deleteQwPushCountById(Long id);
+}

+ 106 - 0
fs-service/src/main/java/com/fs/qw/service/impl/QwPushCountServiceImpl.java

@@ -0,0 +1,106 @@
+package com.fs.qw.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.fs.qw.domain.QwPushCount;
+import com.fs.qw.mapper.QwPushCountMapper;
+import com.fs.qw.service.IQwPushCountService;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * 定义销售推送不同类型的企业消息的次数Service业务层处理
+ * 
+ * @author fs
+ * @date 2025-08-22
+ */
+@Service
+public class QwPushCountServiceImpl extends ServiceImpl<QwPushCountMapper, QwPushCount> implements IQwPushCountService {
+
+    @Override
+    public List<QwPushCount> selectQwPushCountLists() {
+        return baseMapper.selectQwPushCountLists();
+    }
+
+    @Override
+    public QwPushCount SelectQwPushCountByCompanyId(Integer type, Long companyId) {
+        return baseMapper.SelectQwPushCountByCompanyId(type, companyId);
+    }
+
+    @Override
+    public QwPushCount SelectQwPushCountByType(Integer type) {
+        return baseMapper.SelectQwPushCountByType(type);
+    }
+
+    /**
+     * 查询定义销售推送不同类型的企业消息的次数
+     * 
+     * @param id 定义销售推送不同类型的企业消息的次数主键
+     * @return 定义销售推送不同类型的企业消息的次数
+     */
+    @Override
+    public QwPushCount selectQwPushCountById(Long id)
+    {
+        return baseMapper.selectQwPushCountById(id);
+    }
+
+    /**
+     * 查询定义销售推送不同类型的企业消息的次数列表
+     * 
+     * @param qwPushCount 定义销售推送不同类型的企业消息的次数
+     * @return 定义销售推送不同类型的企业消息的次数
+     */
+    @Override
+    public List<QwPushCount> selectQwPushCountList(QwPushCount qwPushCount)
+    {
+        return baseMapper.selectQwPushCountList(qwPushCount);
+    }
+
+    /**
+     * 新增定义销售推送不同类型的企业消息的次数
+     * 
+     * @param qwPushCount 定义销售推送不同类型的企业消息的次数
+     * @return 结果
+     */
+    @Override
+    public int insertQwPushCount(QwPushCount qwPushCount)
+    {
+        return baseMapper.insertQwPushCount(qwPushCount);
+    }
+
+    /**
+     * 修改定义销售推送不同类型的企业消息的次数
+     * 
+     * @param qwPushCount 定义销售推送不同类型的企业消息的次数
+     * @return 结果
+     */
+    @Override
+    public int updateQwPushCount(QwPushCount qwPushCount)
+    {
+        return baseMapper.updateQwPushCount(qwPushCount);
+    }
+
+    /**
+     * 批量删除定义销售推送不同类型的企业消息的次数
+     * 
+     * @param ids 需要删除的定义销售推送不同类型的企业消息的次数主键
+     * @return 结果
+     */
+    @Override
+    public int deleteQwPushCountByIds(Long[] ids)
+    {
+        return baseMapper.deleteQwPushCountByIds(ids);
+    }
+
+    /**
+     * 删除定义销售推送不同类型的企业消息的次数信息
+     * 
+     * @param id 定义销售推送不同类型的企业消息的次数主键
+     * @return 结果
+     */
+    @Override
+    public int deleteQwPushCountById(Long id)
+    {
+        return baseMapper.deleteQwPushCountById(id);
+    }
+}

+ 3 - 0
fs-service/src/main/resources/application-config-druid-czt.yml

@@ -93,3 +93,6 @@ wx_miniapp_temp:
 
 # 0 代表关闭 1代表开启(润天老商户号的扣款限制)
 enableRedPackAccount: 0
+video:
+  videoUploadDir:
+  frameOutputDir:

+ 71 - 0
fs-service/src/main/resources/mapper/qw/QwPushCountMapper.xml

@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.fs.qw.mapper.QwPushCountMapper">
+    
+    <resultMap type="QwPushCount" id="QwPushCountResult">
+        <result property="id"    column="id"    />
+        <result property="type"    column="type"    />
+        <result property="pushCount"    column="push_count"    />
+        <result property="companyId"    column="company_id"    />
+        <result property="status"    column="status"    />
+    </resultMap>
+
+    <sql id="selectQwPushCountVo">
+        select id, type, push_count, company_id, status from qw_push_count
+    </sql>
+
+    <select id="selectQwPushCountList" parameterType="QwPushCount" resultMap="QwPushCountResult">
+        <include refid="selectQwPushCountVo"/>
+        <where>  
+            <if test="type != null "> and type = #{type}</if>
+            <if test="pushCount != null "> and push_count = #{pushCount}</if>
+            <if test="companyId != null "> and company_id = #{companyId}</if>
+            <if test="status != null "> and status = #{status}</if>
+        </where>
+    </select>
+    
+    <select id="selectQwPushCountById" parameterType="Long" resultMap="QwPushCountResult">
+        <include refid="selectQwPushCountVo"/>
+        where id = #{id}
+    </select>
+        
+    <insert id="insertQwPushCount" parameterType="QwPushCount" useGeneratedKeys="true" keyProperty="id">
+        insert into qw_push_count
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="type != null">type,</if>
+            <if test="pushCount != null">push_count,</if>
+            <if test="companyId != null">company_id,</if>
+            <if test="status != null">status,</if>
+         </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="type != null">#{type},</if>
+            <if test="pushCount != null">#{pushCount},</if>
+            <if test="companyId != null">#{companyId},</if>
+            <if test="status != null">#{status},</if>
+         </trim>
+    </insert>
+
+    <update id="updateQwPushCount" parameterType="QwPushCount">
+        update qw_push_count
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="type != null">type = #{type},</if>
+            <if test="pushCount != null">push_count = #{pushCount},</if>
+            <if test="companyId != null">company_id = #{companyId},</if>
+            <if test="status != null">status = #{status},</if>
+        </trim>
+        where id = #{id}
+    </update>
+
+    <delete id="deleteQwPushCountById" parameterType="Long">
+        delete from qw_push_count where id = #{id}
+    </delete>
+
+    <delete id="deleteQwPushCountByIds" parameterType="String">
+        delete from qw_push_count where id in 
+        <foreach item="id" collection="array" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </delete>
+</mapper>

+ 7 - 0
fs-service/src/main/resources/mapper/qw/QwRestrictionPushRecordMapper.xml

@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.fs.qw.mapper.QwRestrictionPushRecordMapper">
+    
+</mapper>