Prechádzať zdrojové kódy

新增:
知识条目新增备注
产品条目新增备注
问答记录新增折线图
人流记录新增折线图

范志成 3 mesiacov pred
rodič
commit
954a0e5932
30 zmenil súbory, kde vykonal 981 pridanie a 159 odobranie
  1. 10 1
      smsb-modules/smsb-device/src/main/java/com/inspur/device/controller/SmsbDeviceChatRecordController.java
  2. 12 0
      smsb-modules/smsb-device/src/main/java/com/inspur/device/controller/SmsbVisitorsFlowRateController.java
  3. 5 0
      smsb-modules/smsb-device/src/main/java/com/inspur/device/domain/SmsbDifyDatasetsProduct.java
  4. 5 0
      smsb-modules/smsb-device/src/main/java/com/inspur/device/domain/SmsbDifyDatasetsQuestion.java
  5. 6 0
      smsb-modules/smsb-device/src/main/java/com/inspur/device/domain/bo/SmsbDifyDatasetsProductBo.java
  6. 6 0
      smsb-modules/smsb-device/src/main/java/com/inspur/device/domain/bo/SmsbDifyDatasetsQuestionBo.java
  7. 28 0
      smsb-modules/smsb-device/src/main/java/com/inspur/device/domain/vo/DateAndCountVO.java
  8. 2 0
      smsb-modules/smsb-device/src/main/java/com/inspur/device/domain/vo/SmsbDeviceChatCountVo.java
  9. 7 0
      smsb-modules/smsb-device/src/main/java/com/inspur/device/domain/vo/SmsbDifyDatasetsProductVo.java
  10. 6 0
      smsb-modules/smsb-device/src/main/java/com/inspur/device/domain/vo/SmsbDifyDatasetsQuestionVo.java
  11. 2 0
      smsb-modules/smsb-device/src/main/java/com/inspur/device/domain/vo/SmsbVisitorsFlowRateCountVo.java
  12. 5 0
      smsb-modules/smsb-device/src/main/java/com/inspur/device/mapper/SmsbDeviceChatRecordMapper.java
  13. 5 0
      smsb-modules/smsb-device/src/main/java/com/inspur/device/mapper/SmsbVisitorsFlowRateMapper.java
  14. 3 0
      smsb-modules/smsb-device/src/main/java/com/inspur/device/service/ISmsbDeviceChatRecordService.java
  15. 3 0
      smsb-modules/smsb-device/src/main/java/com/inspur/device/service/ISmsbVisitorsFlowRateService.java
  16. 20 3
      smsb-modules/smsb-device/src/main/java/com/inspur/device/service/impl/SmsbDeviceChatRecordServiceImpl.java
  17. 22 0
      smsb-modules/smsb-device/src/main/java/com/inspur/device/service/impl/SmsbVisitorsFlowRateServiceImpl.java
  18. 33 0
      smsb-modules/smsb-device/src/main/resources/mapper/device/SmsbDeviceChatRecordMapper.xml
  19. 31 0
      smsb-modules/smsb-device/src/main/resources/mapper/device/SmsbVisitorsFlowRateMapper.xml
  20. 14 1
      smsb-plus-ui/src/api/smsb/device/device_chat_record.ts
  21. 13 0
      smsb-plus-ui/src/api/smsb/device/device_chat_record_type.ts
  22. 162 147
      smsb-plus-ui/src/api/smsb/device/difyDatasetsProduct_types.ts
  23. 13 1
      smsb-plus-ui/src/api/smsb/device/visitors_flow_rate.ts
  24. 13 0
      smsb-plus-ui/src/api/smsb/device/visitors_flow_rate_types.ts
  25. 54 3
      smsb-plus-ui/src/views/smsb/deviceChatRecord/chatCount.vue
  26. 3 0
      smsb-plus-ui/src/views/smsb/difyDatasetsProduct/index.vue
  27. 2 2
      smsb-plus-ui/src/views/smsb/difyDatasetsQuestion/index.vue
  28. 46 1
      smsb-plus-ui/src/views/smsb/visitorsFlowRate/rateCount.vue
  29. 225 0
      smsb-plus-ui/vite.config.ts.timestamp-1752482301244-80c5ecdf136a3.mjs
  30. 225 0
      smsb-plus-ui/vite.config.ts.timestamp-1752482613392-eb5f7a05e4af7.mjs

+ 10 - 1
smsb-modules/smsb-device/src/main/java/com/inspur/device/controller/SmsbDeviceChatRecordController.java

@@ -1,7 +1,6 @@
 package com.inspur.device.controller;
 
 import cn.dev33.satoken.annotation.SaCheckPermission;
-import com.inspur.device.domain.SmsbDeviceChatDetail;
 import com.inspur.device.domain.bo.SmsbDeviceChatRecordBo;
 import com.inspur.device.domain.vo.SmsbDeviceChatCountVo;
 import com.inspur.device.domain.vo.SmsbDeviceChatDetailVo;
@@ -25,6 +24,7 @@ import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
 
 import java.util.List;
+import java.util.Map;
 
 /**
  * 问答记录
@@ -67,6 +67,15 @@ public class SmsbDeviceChatRecordController extends BaseController {
         return R.ok(smsbDeviceChatRecordService.listDetail(conversationId));
     }
 
+    /**
+     * 查询问答记录列表
+     */
+    @SaCheckPermission("device:chatRecord:query")
+    @GetMapping("monthly/{deviceId}")
+    public R<Map<String, Object>> listMonthly(@PathVariable String deviceId) {
+        return R.ok(smsbDeviceChatRecordService.listMonthly(deviceId));
+    }
+
     /**
      * 导出问答记录列表
      */

+ 12 - 0
smsb-modules/smsb-device/src/main/java/com/inspur/device/controller/SmsbVisitorsFlowRateController.java

@@ -23,6 +23,7 @@ import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
 
 import java.util.List;
+import java.util.Map;
 
 /**
  * 人流记录
@@ -79,6 +80,17 @@ public class SmsbVisitorsFlowRateController extends BaseController {
         return R.ok(smsbVisitorsFlowRateService.queryById(id));
     }
 
+    /**
+     * 获取本月的人流量
+     *
+     * @param deviceId 设备id
+     */
+    @SaCheckPermission("device:visitorsFlowRate:query")
+    @GetMapping("/getMonthlyInfo/{deviceId}")
+    public R<Map<String, Object>> getMonthlyInfo(@PathVariable String deviceId) {
+        return R.ok(smsbVisitorsFlowRateService.getMonthlyInfo(deviceId));
+    }
+
     /**
      * 新增人流记录
      */

+ 5 - 0
smsb-modules/smsb-device/src/main/java/com/inspur/device/domain/SmsbDifyDatasetsProduct.java

@@ -72,4 +72,9 @@ public class SmsbDifyDatasetsProduct extends TenantEntity {
      */
     private String videoUrl;
 
+    /**
+     * 备注
+     */
+    private String remark;
+
 }

+ 5 - 0
smsb-modules/smsb-device/src/main/java/com/inspur/device/domain/SmsbDifyDatasetsQuestion.java

@@ -52,4 +52,9 @@ public class SmsbDifyDatasetsQuestion extends TenantEntity {
      */
     private String property;
 
+    /**
+     * 备注
+     */
+    private String remark;
+
 }

+ 6 - 0
smsb-modules/smsb-device/src/main/java/com/inspur/device/domain/bo/SmsbDifyDatasetsProductBo.java

@@ -80,4 +80,10 @@ public class SmsbDifyDatasetsProductBo extends BaseEntity {
      */
     // @NotBlank(message = "视频不能为空", groups = {AddGroup.class, EditGroup.class})
     private String videoUrl;
+
+    /**
+     * 备注
+     */
+    // @NotBlank(message = "备注不能为空", groups = {AddGroup.class, EditGroup.class})
+    private String remark;
 }

+ 6 - 0
smsb-modules/smsb-device/src/main/java/com/inspur/device/domain/bo/SmsbDifyDatasetsQuestionBo.java

@@ -57,4 +57,10 @@ public class SmsbDifyDatasetsQuestionBo extends BaseEntity {
     @NotBlank(message = "属性不能为空", groups = { AddGroup.class, EditGroup.class })
     private String property;
 
+    /**
+     * 备注
+     */
+//    @NotBlank(message = "备注不能为空", groups = { AddGroup.class, EditGroup.class })
+    private String remark;
+
 }

+ 28 - 0
smsb-modules/smsb-device/src/main/java/com/inspur/device/domain/vo/DateAndCountVO.java

@@ -0,0 +1,28 @@
+package com.inspur.device.domain.vo;
+
+/**
+ * 问答统计 - 当月列表
+ * @author zhicheng fan
+ */
+public class DateAndCountVO {
+
+    private String date;
+
+    private Integer count;
+
+    public void setDate(String date) {
+        this.date = date;
+    }
+
+    public void setCount(Integer count) {
+        this.count = count;
+    }
+
+    public String getDate() {
+        return date;
+    }
+
+    public Integer getCount() {
+        return count;
+    }
+}

+ 2 - 0
smsb-modules/smsb-device/src/main/java/com/inspur/device/domain/vo/SmsbDeviceChatCountVo.java

@@ -23,6 +23,8 @@ public class SmsbDeviceChatCountVo {
 
     private Integer weekNum;
 
+    private Integer lastWeekNum;
+
     private Integer monthNum;
 
     private Integer totalNum;

+ 7 - 0
smsb-modules/smsb-device/src/main/java/com/inspur/device/domain/vo/SmsbDifyDatasetsProductVo.java

@@ -84,4 +84,11 @@ public class SmsbDifyDatasetsProductVo implements Serializable {
     @ExcelProperty(value = "产品视频")
     private String videoUrl;
 
+
+    /**
+     * 备注
+     */
+    @ExcelProperty(value = "备注")
+    private String remark;
+
 }

+ 6 - 0
smsb-modules/smsb-device/src/main/java/com/inspur/device/domain/vo/SmsbDifyDatasetsQuestionVo.java

@@ -64,6 +64,12 @@ public class SmsbDifyDatasetsQuestionVo implements Serializable {
     @ExcelProperty(value = "属性")
     private String property;
 
+    /**
+     * 备注
+     */
+    @ExcelProperty(value = "备注")
+    private String remark;
+
     /**
      * 创建时间
      */

+ 2 - 0
smsb-modules/smsb-device/src/main/java/com/inspur/device/domain/vo/SmsbVisitorsFlowRateCountVo.java

@@ -21,6 +21,8 @@ public class SmsbVisitorsFlowRateCountVo {
 
     private Integer yesterdayNum;
 
+    private Integer lastWeekNum;
+
     private Integer weekNum;
 
     private Integer monthNum;

+ 5 - 0
smsb-modules/smsb-device/src/main/java/com/inspur/device/mapper/SmsbDeviceChatRecordMapper.java

@@ -3,11 +3,14 @@ package com.inspur.device.mapper;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.inspur.device.domain.SmsbDeviceChatRecord;
 import com.inspur.device.domain.bo.SmsbDeviceChatRecordBo;
+import com.inspur.device.domain.vo.DateAndCountVO;
 import com.inspur.device.domain.vo.SmsbDeviceChatCountVo;
 import com.inspur.device.domain.vo.SmsbDeviceChatRecordVo;
 import org.apache.ibatis.annotations.Param;
 import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
 
+import java.util.List;
+
 /**
  * 问答记录Mapper接口
  *
@@ -23,4 +26,6 @@ public interface SmsbDeviceChatRecordMapper extends BaseMapperPlus<SmsbDeviceCha
      * @return
      */
     Page<SmsbDeviceChatCountVo> selectChatCountList(@Param("page") Page<SmsbDeviceChatCountVo> page, @Param("bo") SmsbDeviceChatRecordBo bo);
+
+    List<DateAndCountVO> selectChatMonthlyInfo(String deviceId);
 }

+ 5 - 0
smsb-modules/smsb-device/src/main/java/com/inspur/device/mapper/SmsbVisitorsFlowRateMapper.java

@@ -3,11 +3,14 @@ package com.inspur.device.mapper;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.inspur.device.domain.SmsbVisitorsFlowRate;
 import com.inspur.device.domain.bo.SmsbVisitorsFlowRateBo;
+import com.inspur.device.domain.vo.DateAndCountVO;
 import com.inspur.device.domain.vo.SmsbVisitorsFlowRateCountVo;
 import com.inspur.device.domain.vo.SmsbVisitorsFlowRateVo;
 import org.apache.ibatis.annotations.Param;
 import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
 
+import java.util.List;
+
 /**
  * 人流记录Mapper接口
  *
@@ -23,4 +26,6 @@ public interface SmsbVisitorsFlowRateMapper extends BaseMapperPlus<SmsbVisitorsF
      * @return
      */
     Page<SmsbVisitorsFlowRateCountVo> selectFlowRateCountList(@Param("page") Page<SmsbVisitorsFlowRateCountVo> page, SmsbVisitorsFlowRateBo bo);
+
+    List<DateAndCountVO> selectVisitorsFlowRateMonthlyInfo(String deviceId);
 }

+ 3 - 0
smsb-modules/smsb-device/src/main/java/com/inspur/device/service/ISmsbDeviceChatRecordService.java

@@ -9,6 +9,7 @@ import org.dromara.common.mybatis.core.page.TableDataInfo;
 
 import java.util.Collection;
 import java.util.List;
+import java.util.Map;
 
 /**
  * 问答记录Service接口
@@ -88,4 +89,6 @@ public interface ISmsbDeviceChatRecordService {
      * @return
      */
     TableDataInfo<SmsbDeviceChatCountVo> chatCountList(SmsbDeviceChatRecordBo bo, PageQuery pageQuery);
+
+    Map<String, Object> listMonthly(String deviceId);
 }

+ 3 - 0
smsb-modules/smsb-device/src/main/java/com/inspur/device/service/ISmsbVisitorsFlowRateService.java

@@ -9,6 +9,7 @@ import org.dromara.common.mybatis.core.page.TableDataInfo;
 
 import java.util.Collection;
 import java.util.List;
+import java.util.Map;
 
 /**
  * 人流记录Service接口
@@ -83,4 +84,6 @@ public interface ISmsbVisitorsFlowRateService {
      * @return
      */
     TableDataInfo<SmsbVisitorsFlowRateCountVo> flowRateCount(SmsbVisitorsFlowRateBo bo, PageQuery pageQuery);
+
+    Map<String, Object> getMonthlyInfo(String deviceId);
 }

+ 20 - 3
smsb-modules/smsb-device/src/main/java/com/inspur/device/service/impl/SmsbDeviceChatRecordServiceImpl.java

@@ -26,9 +26,7 @@ import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
 import org.springframework.util.CollectionUtils;
 
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
+import java.util.*;
 
 /**
  * 问答记录Service业务层处理
@@ -224,6 +222,25 @@ public class SmsbDeviceChatRecordServiceImpl implements ISmsbDeviceChatRecordSer
         return TableDataInfo.build(result);
     }
 
+    @Override
+    public Map<String, Object> listMonthly(String deviceId) {
+        List<DateAndCountVO> voList = baseMapper.selectChatMonthlyInfo(deviceId);
+        if (CollectionUtils.isEmpty(voList)) {
+            return null;
+        }
+        String[] dates = new String[voList.size()];
+        int[] counts = new int[voList.size()];
+        HashMap<String, Object> map = new HashMap<>();
+        for (int i = 0; i < voList.size(); i++) {
+            DateAndCountVO vo = voList.get(i);
+            dates[i] = vo.getDate();
+            counts[i] = vo.getCount();
+        }
+        map.put("dates", dates);
+        map.put("counts", counts);
+        return map;
+    }
+
     private void createNewAddDetail(SmsbDeviceChatDetail addDetail, DifyChatDetailRspData detailRspData,String tenantId) {
         addDetail.setConversationId(detailRspData.getConversation_id());
         addDetail.setDifyId(detailRspData.getId());

+ 22 - 0
smsb-modules/smsb-device/src/main/java/com/inspur/device/service/impl/SmsbVisitorsFlowRateServiceImpl.java

@@ -6,6 +6,7 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.inspur.device.domain.SmsbDevice;
 import com.inspur.device.domain.SmsbVisitorsFlowRate;
 import com.inspur.device.domain.bo.SmsbVisitorsFlowRateBo;
+import com.inspur.device.domain.vo.DateAndCountVO;
 import com.inspur.device.domain.vo.SmsbDeviceVo;
 import com.inspur.device.domain.vo.SmsbVisitorsFlowRateCountVo;
 import com.inspur.device.domain.vo.SmsbVisitorsFlowRateVo;
@@ -20,8 +21,10 @@ import org.dromara.common.core.utils.StringUtils;
 import org.dromara.common.mybatis.core.page.PageQuery;
 import org.dromara.common.mybatis.core.page.TableDataInfo;
 import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
 
 import java.util.Collection;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
@@ -161,4 +164,23 @@ public class SmsbVisitorsFlowRateServiceImpl implements ISmsbVisitorsFlowRateSer
         Page<SmsbVisitorsFlowRateCountVo> result = baseMapper.selectFlowRateCountList(pageQuery.build(), bo);
         return TableDataInfo.build(result);
     }
+
+    @Override
+    public Map<String, Object> getMonthlyInfo(String deviceId) {
+        List<DateAndCountVO> voList = baseMapper.selectVisitorsFlowRateMonthlyInfo(deviceId);
+        if (CollectionUtils.isEmpty(voList)) {
+            return null;
+        }
+        String[] dates = new String[voList.size()];
+        int[] counts = new int[voList.size()];
+        HashMap<String, Object> map = new HashMap<>();
+        for (int i = 0; i < voList.size(); i++) {
+            DateAndCountVO vo = voList.get(i);
+            dates[i] = vo.getDate();
+            counts[i] = vo.getCount();
+        }
+        map.put("dates", dates);
+        map.put("counts", counts);
+        return map;
+    }
 }

+ 33 - 0
smsb-modules/smsb-device/src/main/resources/mapper/device/SmsbDeviceChatRecordMapper.xml

@@ -3,6 +3,7 @@
     PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
     "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 <mapper namespace="com.inspur.device.mapper.SmsbDeviceChatRecordMapper">
+
     <select id="selectChatCountList" resultType="com.inspur.device.domain.vo.SmsbDeviceChatCountVo" parameterType="com.inspur.device.domain.bo.SmsbDeviceChatRecordBo">
         SELECT
             sd.serial_number as deviceSn,
@@ -12,6 +13,7 @@
             IFNULL(chat.totalNum,0) AS totalNum,
             IFNULL(chat.todayNum,0) AS todayNum,
             IFNULL(chat.yesterdayNum,0) AS yesterdayNum,
+            IFNULL(chat.lastWeekNum,0) AS lastWeekNum,
             IFNULL(chat.weekNum,0) AS weekNum,
             IFNULL(chat.monthNum,0) AS monthNum
         FROM
@@ -23,6 +25,7 @@
                      COUNT(*) AS totalNum,
                      SUM(IF(DATE(create_time) = CURDATE(), 1, 0)) AS todayNum,
                      SUM(IF(DATE(create_time) = CURDATE() - INTERVAL 1 DAY, 1, 0)) AS yesterdayNum,
+                     SUM(IF(YEARWEEK(create_time, 1) = YEARWEEK(CURDATE(), 1) - 1, 1, 0)) AS lastWeekNum,
                      SUM(IF(YEARWEEK(create_time, 1) = YEARWEEK(CURDATE(), 1), 1, 0)) AS weekNum,
                      SUM(IF(MONTH(create_time) = MONTH(CURDATE()) AND YEAR(create_time) = YEAR(CURDATE()), 1, 0)) AS monthNum
                  FROM
@@ -39,4 +42,34 @@
         </if>
         ORDER BY totalNum desc
     </select>
+
+    <select id="selectChatMonthlyInfo" resultType="com.inspur.device.domain.vo.DateAndCountVO">
+        SELECT
+            dates.date AS date,
+            IFNULL(COUNT(smsb_device_chat_record.id),0) AS count
+        FROM
+            (
+                SELECT DATE_SUB(CURDATE(), INTERVAL n DAY) AS date
+                FROM
+                    (
+                    SELECT 0 AS n UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION
+                    SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION
+                    SELECT 8 UNION SELECT 9 UNION SELECT 10 UNION SELECT 11 UNION
+                    SELECT 12 UNION SELECT 13 UNION SELECT 14 UNION SELECT 15 UNION
+                    SELECT 16 UNION SELECT 17 UNION SELECT 18 UNION SELECT 19 UNION
+                    SELECT 20 UNION SELECT 21 UNION SELECT 22 UNION SELECT 23 UNION
+                    SELECT 24 UNION SELECT 25 UNION SELECT 26 UNION SELECT 27 UNION
+                    SELECT 28 UNION SELECT 29
+                    ) AS numbers
+            ) AS dates
+            LEFT JOIN
+            smsb_device_chat_record
+            ON smsb_device_chat_record.device_id = #{deviceId}
+                AND DATE (smsb_device_chat_record.create_time) = dates.date
+        GROUP BY
+            dates.date
+        ORDER BY
+            dates.date;
+    </select>
+
 </mapper>

+ 31 - 0
smsb-modules/smsb-device/src/main/resources/mapper/device/SmsbVisitorsFlowRateMapper.xml

@@ -13,6 +13,7 @@
             IFNULL(rate.totalNum,0) AS totalNum,
             IFNULL(rate.todayNum,0) AS todayNum,
             IFNULL(rate.yesterdayNum,0) AS yesterdayNum,
+            IFNULL(rate.lastWeekNum,0) AS lastWeekNum,
             IFNULL(rate.weekNum,0) AS weekNum,
             IFNULL(rate.monthNum,0) AS monthNum
         FROM
@@ -24,6 +25,7 @@
                 SUM(person_num) AS totalNum,
                 SUM(CASE WHEN DATE(create_time) = CURDATE() THEN person_num ELSE 0 END) AS todayNum,
                 SUM(CASE WHEN DATE(create_time) = CURDATE() - INTERVAL 1 DAY THEN person_num ELSE 0 END) AS yesterdayNum,
+                SUM(CASE WHEN YEARWEEK(create_time, 1) = YEARWEEK(CURDATE(), 1) - 1 THEN person_num ELSE 0 END) AS lastWeekNum,
                 SUM(CASE WHEN YEARWEEK(create_time, 1) = YEARWEEK(CURDATE(), 1) THEN person_num ELSE 0 END) AS weekNum,
                 SUM(CASE WHEN MONTH(create_time) = MONTH(CURDATE()) AND YEAR(create_time) = YEAR(CURDATE()) THEN person_num ELSE 0 END) AS monthNum
             FROM
@@ -40,4 +42,33 @@
         </if>
         ORDER BY totalNum DESC
     </select>
+
+    <select id="selectVisitorsFlowRateMonthlyInfo" resultType="com.inspur.device.domain.vo.DateAndCountVO">
+        SELECT
+            dates.date AS date,
+            IFNULL(COUNT(smsb_visitors_flow_rate.id),0) AS count
+        FROM
+            (
+            SELECT DATE_SUB(CURDATE(), INTERVAL n DAY) AS date
+            FROM
+            (
+            SELECT 0 AS n UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION
+            SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION
+            SELECT 8 UNION SELECT 9 UNION SELECT 10 UNION SELECT 11 UNION
+            SELECT 12 UNION SELECT 13 UNION SELECT 14 UNION SELECT 15 UNION
+            SELECT 16 UNION SELECT 17 UNION SELECT 18 UNION SELECT 19 UNION
+            SELECT 20 UNION SELECT 21 UNION SELECT 22 UNION SELECT 23 UNION
+            SELECT 24 UNION SELECT 25 UNION SELECT 26 UNION SELECT 27 UNION
+            SELECT 28 UNION SELECT 29
+            ) AS numbers
+            ) AS dates
+            LEFT JOIN
+            smsb_visitors_flow_rate
+            ON smsb_visitors_flow_rate.device_id = #{deviceId}
+                AND DATE(smsb_visitors_flow_rate.create_time) = dates.date
+        GROUP BY
+            dates.date
+        ORDER BY
+            dates.date;
+    </select>
 </mapper>

+ 14 - 1
smsb-plus-ui/src/api/smsb/device/device_chat_record.ts

@@ -1,6 +1,12 @@
 import request from '@/utils/request';
 import { AxiosPromise } from 'axios';
-import {ChatRecordVO, ChatRecordForm, ChatRecordQuery, ChatDetailVO} from '@/api/smsb/device/device_chat_record_type';
+import {
+  ChatRecordVO,
+  ChatRecordForm,
+  ChatRecordQuery,
+  ChatDetailVO,
+  ChatMonthRecordVO
+} from '@/api/smsb/device/device_chat_record_type';
 
 /**
  * 查询问答记录列表
@@ -16,6 +22,13 @@ export const listChatRecord = (query?: ChatRecordQuery): AxiosPromise<ChatRecord
   });
 };
 
+export const getChatRecordMonthInfo = (deviceId: string | number): AxiosPromise<ChatMonthRecordVO> => {
+  return request({
+    url: '/device/chatRecord/monthly/' + deviceId,
+    method: 'get',
+  });
+};
+
 export const listChatRecordCount = (query?: ChatRecordQuery): AxiosPromise<ChatRecordVO[]> => {
   return request({
     url: '/device/chatRecord/count',

+ 13 - 0
smsb-plus-ui/src/api/smsb/device/device_chat_record_type.ts

@@ -1,3 +1,16 @@
+export interface ChatMonthRecordVO {
+  /**
+   * 日期数组
+   */
+  dates: string[];
+
+  /**
+   * 数量数组
+   */
+  counts: number[];
+
+}
+
 export interface ChatRecordVO {
   /**
    * 主键ID

+ 162 - 147
smsb-plus-ui/src/api/smsb/device/difyDatasetsProduct_types.ts

@@ -1,160 +1,175 @@
 export interface DifyDatasetsProductVO {
-    /**
-     * 主键ID
-     */
-    id: string | number;
-
-    /**
-     * 名称
-     */
-    name: string;
-
-    /**
-     * 简介
-     */
-    note: string;
-
-    /**
-     * 序号
-     */
-    sort: number;
-
-    /**
-     * 产品图片
-     */
-    imgUrl: string;
-
-    /**
-     * 上传人
-     */
-    createUser: string;
-
-    /**
-     * 产品关键词
-     */
-    keyword: string,
-
-    /**
-     * 产品属性
-     */
-    property: number,
-
-    /**
-     * 产品价格
-     */
-    price: number,
-
-    /**
-     * 视频地址
-     */
-    videoUrl: string,
+  /**
+   * 主键ID
+   */
+  id: string | number;
+
+  /**
+   * 名称
+   */
+  name: string;
+
+  /**
+   * 简介
+   */
+  note: string;
+
+  /**
+   * 序号
+   */
+  sort: number;
+
+  /**
+   * 产品图片
+   */
+  imgUrl: string;
+
+  /**
+   * 上传人
+   */
+  createUser: string;
+
+  /**
+   * 产品关键词
+   */
+  keyword: string,
+
+  /**
+   * 产品属性
+   */
+  property: number,
+
+  /**
+   * 产品价格
+   */
+  price: number,
+
+  /**
+   * 视频地址
+   */
+  videoUrl: string,
+
+  /**
+   * 备注
+   */
+  remark: string,
 
 }
 
 export interface DifyDatasetsProductForm extends BaseEntity {
-    /**
-     * 主键ID
-     */
-    id?: string | number;
-
-    /**
-     * 名称
-     */
-    name?: string;
-
-    /**
-     * 简介
-     */
-    note?: string;
-
-    /**
-     * 序号
-     */
-    sort?: number;
-
-    /**
-     * 产品图片
-     */
-    imgUrl?: string;
-
-    /**
-     * 上传人
-     */
-    createUser?: string;
-
-    /**
-     * 产品关键词
-     */
-    keyword?: string,
-
-    /**
-     * 产品属性
-     */
-    property?: number,
-
-    /**
-     * 产品价格
-     */
-    price?: number,
-
-    /**
-     * 视频地址
-     */
-    videoUrl?: string,
+  /**
+   * 主键ID
+   */
+  id?: string | number;
+
+  /**
+   * 名称
+   */
+  name?: string;
+
+  /**
+   * 简介
+   */
+  note?: string;
+
+  /**
+   * 序号
+   */
+  sort?: number;
+
+  /**
+   * 产品图片
+   */
+  imgUrl?: string;
+
+  /**
+   * 上传人
+   */
+  createUser?: string;
+
+  /**
+   * 产品关键词
+   */
+  keyword?: string,
+
+  /**
+   * 产品属性
+   */
+  property?: number,
+
+  /**
+   * 产品价格
+   */
+  price?: number,
+
+  /**
+   * 视频地址
+   */
+  videoUrl?: string,
+
+  /**
+   * 备注
+   */
+  remark?: string,
 
 }
 
 export interface DifyDatasetsProductQuery extends PageQuery {
 
-    /**
-     * 名称
-     */
-    name?: string;
-
-    /**
-     * 简介
-     */
-    note?: string;
-
-    /**
-     * 序号
-     */
-    sort?: number;
-
-    /**
-     * 产品图片
-     */
-    imgUrl?: string;
-
-    /**
-     * 上传人
-     */
-    createUser?: string;
-
-    /**
-     * 日期范围参数
-     */
-    params?: any;
-
-    /**
-     * 产品关键词
-     */
-    keyword?: string,
-
-    /**
-     * 产品属性
-     */
-    property?: number,
-
-    /**
-     * 产品价格
-     */
-    price?: number,
-
-    /**
-     * 视频地址
-     */
-    videoUrl?: string,
+  /**
+   * 名称
+   */
+  name?: string;
+
+  /**
+   * 简介
+   */
+  note?: string;
+
+  /**
+   * 序号
+   */
+  sort?: number;
+
+  /**
+   * 产品图片
+   */
+  imgUrl?: string;
+
+  /**
+   * 上传人
+   */
+  createUser?: string;
+
+  /**
+   * 日期范围参数
+   */
+  params?: any;
+
+  /**
+   * 产品关键词
+   */
+  keyword?: string,
+
+  /**
+   * 产品属性
+   */
+  property?: number,
+
+  /**
+   * 产品价格
+   */
+  price?: number,
+
+  /**
+   * 视频地址
+   */
+  videoUrl?: string,
+
+  /**
+   * remark
+   */
+  remark?: string,
 }
 
 

+ 13 - 1
smsb-plus-ui/src/api/smsb/device/visitors_flow_rate.ts

@@ -1,6 +1,11 @@
 import request from '@/utils/request';
 import { AxiosPromise } from 'axios';
-import { VisitorsFlowRateVO, VisitorsFlowRateForm, VisitorsFlowRateQuery } from '@/api/smsb/device/visitors_flow_rate_types';
+import {
+  VisitorsFlowRateVO,
+  VisitorsFlowRateForm,
+  VisitorsFlowRateQuery,
+  VisitorsFlowRateMonthVO
+} from '@/api/smsb/device/visitors_flow_rate_types';
 import {ChatRecordQuery, ChatRecordVO} from "@/api/smsb/device/device_chat_record_type";
 
 /**
@@ -25,6 +30,13 @@ export const listVisitorsFlowRateCount = (query?: VisitorsFlowRateQuery): AxiosP
   });
 };
 
+export const getVisitorsFlowRateMonthInfo = (deviceId: string | number): AxiosPromise<VisitorsFlowRateMonthVO> => {
+  return request({
+    url: '/device/visitorsFlowRate/getMonthlyInfo/' + deviceId,
+    method: 'get',
+  });
+};
+
 /**
  * 查询人流记录详细
  * @param id

+ 13 - 0
smsb-plus-ui/src/api/smsb/device/visitors_flow_rate_types.ts

@@ -1,3 +1,16 @@
+export interface VisitorsFlowRateMonthVO {
+  /**
+   * 日期数组
+   */
+  dates: string[];
+
+  /**
+   * 数量数组
+   */
+  counts: number[];
+
+}
+
 export interface VisitorsFlowRateVO {
   /**
    * 主键ID

+ 54 - 3
smsb-plus-ui/src/views/smsb/deviceChatRecord/chatCount.vue

@@ -6,7 +6,8 @@
         <el-card shadow="hover" :style="{ marginTop: '10px', height: '60px' }">
           <el-form ref="queryFormRef" :model="queryParams" :inline="true" label-width="70px">
             <el-form-item label="设备名称" prop="deviceName">
-              <el-input v-model="queryParams.deviceName" placeholder="请输入设备名称" clearable @keyup.enter="handleQuery"/>
+              <el-input v-model="queryParams.deviceName" placeholder="请输入设备名称" clearable
+                        @keyup.enter="handleQuery"/>
             </el-form-item>
             <el-form-item>
               <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
@@ -28,10 +29,15 @@
           <el-table-column label="总对话" align="center" prop="totalNum" width="120"/>
           <el-table-column label="今日对话" align="center" prop="todayNum" width="120"/>
           <el-table-column label="昨日对话" align="center" prop="yesterdayNum" width="120"/>
+          <el-table-column label="上周对话" align="center" prop="lastWeekNum" width="120"/>
           <el-table-column label="本周对话" align="center" prop="weekNum" width="120"/>
           <el-table-column label="本月对话" align="center" prop="monthNum" width="120"/>
           <el-table-column label="操作" align="center" width="100" class-name="small-padding fixed-width">
             <template #default="scope">
+              <el-tooltip content="本月记录" placement="top">
+                <el-button link type="primary" icon="View" @click="handleMonthInfo(scope.row)"
+                           v-hasPermi="['device:chatRecord:query']"></el-button>
+              </el-tooltip>
               <el-tooltip content="问答列表" placement="top">
                 <el-button link type="primary" icon="Position" @click="handleInfo(scope.row)"
                            v-hasPermi="['device:chatRecord:query']"></el-button>
@@ -44,12 +50,28 @@
       <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum"
                   v-model:limit="queryParams.pageSize" @pagination="getList"/>
     </el-card>
+
+    <el-dialog :title="dialog.title" v-model="dialog.visible" append-to-body>
+      <div ref="chartRef" style="width: 100%; height: 400px;"></div>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button @click="cancel">关 闭</el-button>
+        </div>
+      </template>
+    </el-dialog>
   </div>
 </template>
 
 <script setup name="ChatRecord" lang="ts">
-import {listChatRecordCount,} from '@/api/smsb/device/device_chat_record';
-import {ChatRecordForm, ChatRecordQuery, ChatRecordVO} from '@/api/smsb/device/device_chat_record_type';
+import {getChatRecord, getChatRecordMonthInfo, listChatRecordCount,} from '@/api/smsb/device/device_chat_record';
+import {
+  ChatMonthRecordVO,
+  ChatRecordForm,
+  ChatRecordQuery,
+  ChatRecordVO
+} from '@/api/smsb/device/device_chat_record_type';
+import * as echarts from 'echarts';
+import {ref} from "vue";
 
 const {proxy} = getCurrentInstance() as ComponentInternalInstance;
 
@@ -61,6 +83,7 @@ const ids = ref<Array<string | number>>([]);
 const single = ref(true);
 const multiple = ref(true);
 const total = ref(0);
+const chartRef = ref();
 
 const queryFormRef = ref<ElFormInstance>();
 const chatRecordFormRef = ref<ElFormInstance>();
@@ -103,6 +126,34 @@ const getList = async () => {
   total.value = res.total;
   loading.value = false;
 }
+
+const handleMonthInfo = async (row?: ChatRecordVO) => {
+  const res = await getChatRecordMonthInfo(row.deviceId);
+  dialog.title = '本月问答记录';
+  dialog.visible = true;
+  // 使用 nextTick 确保 DOM 更新后再初始化图表
+  await nextTick();
+  const chart = echarts.init(chartRef.value, 'macaroons');
+  chart.setOption({
+    tooltip: {
+      trigger: 'axis',
+    },
+    xAxis: {
+      type: 'category',
+      data: res.data.dates,
+    },
+    yAxis: {
+      type: 'value',
+    },
+    series: [{
+      name: '问答次数',
+      type: 'line',
+      data: res.data.counts,
+      smooth: true,
+    }],
+  });
+}
+
 const handleInfo = async (row?: ChatRecordVO) => {
   const deviceName = row.deviceName;
   // 跳转页面 /source/push/review?id=1898991996092481537&type=approval&taskId=1898992031169445891

+ 3 - 0
smsb-plus-ui/src/views/smsb/difyDatasetsProduct/index.vue

@@ -127,6 +127,9 @@
         <el-form-item label="产品简介" prop="note">
           <el-input v-model="form.note" type="textarea" :rows="5" placeholder="请输入内容" :maxlength="500"/>
         </el-form-item>
+        <el-form-item label="备注" prop="remark">
+          <el-input type="textarea" placeholder="请输入内容" :rows="3"/>
+        </el-form-item>
       </el-form>
       <template #footer>
         <div class="dialog-footer">

+ 2 - 2
smsb-plus-ui/src/views/smsb/difyDatasetsQuestion/index.vue

@@ -87,7 +87,7 @@
         <el-table-column label="创建人" align="left" prop="createUser" width="120" :show-overflow-tooltip="true"/>
         <el-table-column label="更新时间" align="left" prop="updateTime" width="160"/>
         <el-table-column label="更新人" align="left" prop="updateBy" width="120" :show-overflow-tooltip="true"/>
-        <el-table-column label="备注" align="left" :show-overflow-tooltip="true"/>
+        <el-table-column label="备注" align="left" prop="remark" :show-overflow-tooltip="true"/>
         <el-table-column label="操作" align="left" width="120" class-name="small-padding fixed-width">
           <template #default="scope">
             <el-tooltip content="修改" placement="top">
@@ -130,7 +130,7 @@
         <el-form-item label="回答" prop="answer">
           <el-input v-model="form.answer" type="textarea" placeholder="请输入内容" :rows="5"/>
         </el-form-item>
-        <el-form-item label="备注">
+        <el-form-item label="备注" prop="remark">
           <el-input type="textarea" placeholder="请输入内容" :rows="3"/>
         </el-form-item>
       </el-form>

+ 46 - 1
smsb-plus-ui/src/views/smsb/visitorsFlowRate/rateCount.vue

@@ -28,10 +28,15 @@
           <el-table-column label="总人数" align="center" prop="totalNum" width="120"/>
           <el-table-column label="今日人数" align="center" prop="todayNum" width="120"/>
           <el-table-column label="昨日人数" align="center" prop="yesterdayNum" width="120"/>
+          <el-table-column label="上周人数" align="center" prop="lastWeekNum" width="120"/>
           <el-table-column label="本周人数" align="center" prop="weekNum" width="120"/>
           <el-table-column label="本月人数" align="center" prop="monthNum" width="120"/>
           <el-table-column label="操作" align="center" width="100" class-name="small-padding fixed-width">
             <template #default="scope">
+              <el-tooltip content="本月记录" placement="top">
+                <el-button link type="primary" icon="View" @click="handleMonthInfo(scope.row)"
+                           v-hasPermi="['device:chatRecord:query']"></el-button>
+              </el-tooltip>
               <el-tooltip content="人流列表" placement="top">
                 <el-button link type="primary" icon="Position" @click="handleInfo(scope.row)"
                            v-hasPermi="['device:visitorsFlowRate:query']"></el-button>
@@ -44,12 +49,24 @@
       <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum"
                   v-model:limit="queryParams.pageSize" @pagination="getList"/>
     </el-card>
+
+    <el-dialog :title="dialog.title" v-model="dialog.visible" append-to-body>
+      <div ref="chartRef" style="width: 100%; height: 400px;"></div>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button @click="cancel">关 闭</el-button>
+        </div>
+      </template>
+    </el-dialog>
   </div>
 </template>
 
 <script setup name="ChatRecord" lang="ts">
-import {listVisitorsFlowRateCount,} from '@/api/smsb/device/visitors_flow_rate';
+import {getVisitorsFlowRateMonthInfo, listVisitorsFlowRateCount,} from '@/api/smsb/device/visitors_flow_rate';
 import {VisitorsFlowRateVO,VisitorsFlowRateForm,VisitorsFlowRateQuery} from "@/api/smsb/device/visitors_flow_rate_types";
+import {ref} from "vue";
+import {ChatRecordVO} from "@/api/smsb/device/device_chat_record_type";
+import * as echarts from "echarts";
 
 const {proxy} = getCurrentInstance() as ComponentInternalInstance;
 
@@ -61,6 +78,7 @@ const ids = ref<Array<string | number>>([]);
 const single = ref(true);
 const multiple = ref(true);
 const total = ref(0);
+const chartRef = ref();
 
 const queryFormRef = ref<ElFormInstance>();
 const chatRecordFormRef = ref<ElFormInstance>();
@@ -105,6 +123,33 @@ const handleInfo = async (row?: VisitorsFlowRateVO) => {
   proxy.$router.push('/device/pc/visitorsFlowRate?deviceName=' + deviceName);
 }
 
+const handleMonthInfo = async (row?: ChatRecordVO) => {
+  const res = await getVisitorsFlowRateMonthInfo(row.deviceId);
+  dialog.title = '本月人流记录';
+  dialog.visible = true;
+  // 使用 nextTick 确保 DOM 更新后再初始化图表
+  await nextTick();
+  const chart = echarts.init(chartRef.value, 'macaroons');
+  chart.setOption({
+    tooltip: {
+      trigger: 'axis',
+    },
+    xAxis: {
+      type: 'category',
+      data: res.data.dates,
+    },
+    yAxis: {
+      type: 'value',
+    },
+    series: [{
+      name: '人流量',
+      type: 'line',
+      data: res.data.counts,
+      smooth: true,
+    }],
+  });
+}
+
 
 /** 取消按钮 */
 const cancel = () => {

Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 225 - 0
smsb-plus-ui/vite.config.ts.timestamp-1752482301244-80c5ecdf136a3.mjs


Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 225 - 0
smsb-plus-ui/vite.config.ts.timestamp-1752482613392-eb5f7a05e4af7.mjs


Niektoré súbory nie sú zobrazené, pretože je v týchto rozdielových dátach zmenené mnoho súborov