From d8143b9121bbe941f116230eaa5524ab2cc12a66 Mon Sep 17 00:00:00 2001
From: huliguo <2023611923@qq.com>
Date: 星期四, 10 七月 2025 21:20:21 +0800
Subject: [PATCH] 新增

---
 src/main/java/com/linghu/model/vo/KeywordStaticsListVO.java            |    3 
 src/main/java/com/linghu/model/dto/ExportGetResultDTO.java             |    2 
 src/main/java/com/linghu/model/dto/ExportStaticsDTO.java               |    2 
 src/main/java/com/linghu/controller/UserController.java                |  115 ++++++++++++
 src/main/java/com/linghu/service/impl/KeywordServiceImpl.java          |    2 
 src/main/java/com/linghu/controller/QuestionController.java            |    9 
 src/main/java/com/linghu/utils/OpenCryptUtil.java                      |    2 
 src/main/java/com/linghu/config/MyBatisPlusConfig.java                 |   12 +
 src/main/java/com/linghu/model/vo/KeywordStaticsVO.java                |    4 
 src/main/java/com/linghu/model/vo/SectionalizationUserVO.java          |   18 ++
 src/main/resources/mapper/UserMapper.xml                               |   17 +
 src/main/java/com/linghu/mapper/UserMapper.java                        |    2 
 src/main/java/com/linghu/model/vo/GetTimeVO.java                       |   21 ++
 src/main/java/com/linghu/service/SectionalizationService.java          |    2 
 src/main/java/com/linghu/service/impl/SectionalizationServiceImpl.java |   52 +++++
 src/main/java/com/linghu/controller/CollectController.java             |  110 +++++++++---
 src/main/java/com/linghu/model/vo/UserPageVO.java                      |    6 
 src/main/resources/mapper/keywordMapper.xml                            |    1 
 src/main/java/com/linghu/controller/AuthController.java                |   22 +-
 src/main/java/com/linghu/model/entity/Sectionalization.java            |    3 
 src/main/java/com/linghu/controller/SectionalizationController.java    |   11 +
 src/main/java/com/linghu/model/entity/User.java                        |    5 
 src/main/java/com/linghu/controller/KeywordController.java             |   91 ++++++++--
 src/main/java/com/linghu/timeTask/ScheduledTasks.java                  |    5 
 24 files changed, 425 insertions(+), 92 deletions(-)

diff --git a/src/main/java/com/linghu/config/MyBatisPlusConfig.java b/src/main/java/com/linghu/config/MyBatisPlusConfig.java
index bb1be96..2b9dfdf 100644
--- a/src/main/java/com/linghu/config/MyBatisPlusConfig.java
+++ b/src/main/java/com/linghu/config/MyBatisPlusConfig.java
@@ -1,18 +1,24 @@
 package com.linghu.config;
 
+import com.baomidou.mybatisplus.annotation.DbType;
 import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
 import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
+import org.mybatis.spring.annotation.MapperScan;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 
 @Configuration
-public class MyBatisPlusConfig {
+@MapperScan("com.linghu.mapper")
+public class MybatisPlusConfig {
 
+    /**
+     * 添加分页插件
+     */
     @Bean
     public MybatisPlusInterceptor mybatisPlusInterceptor() {
         MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
-        // 添加分页插件,这里可指定数据库类型(如 MySQL),也可默认
-        interceptor.addInnerInterceptor(new PaginationInnerInterceptor()); 
+        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); // 如果配置多个插件, 切记分页最后添加
+        // 如果有多数据源可以不配具体类型, 否则都建议配上具体的 DbType
         return interceptor;
     }
 }
\ No newline at end of file
diff --git a/src/main/java/com/linghu/controller/AuthController.java b/src/main/java/com/linghu/controller/AuthController.java
index 57547b5..6ff8df4 100644
--- a/src/main/java/com/linghu/controller/AuthController.java
+++ b/src/main/java/com/linghu/controller/AuthController.java
@@ -63,15 +63,15 @@
         return ResponseEntity.ok(decrypt);
     }
 
-//    @GetMapping("/getToken")
-//    @ApiOperation(value = "获取token")
-//    public ResponseEntity<?> getToken(@RequestBody User user) {
-//        // 创建用户对
-//
-//        // 创建JwtUtils对象,并生成JWT令牌
-//        OpenCryptUtil openCryptUtil = new OpenCryptUtil();
-//        String decrypt = openCryptUtil.encrypt(user);
-//        // 返回JWT令牌
-//        return ResponseEntity.ok(decrypt);
-//    }
+    @GetMapping("/getToken")
+    @ApiOperation(value = "获取token")
+    public ResponseEntity<?> getToken( String user) {
+        // 创建用户对
+
+        // 创建JwtUtils对象,并生成JWT令牌
+        OpenCryptUtil openCryptUtil = new OpenCryptUtil();
+        String decrypt = openCryptUtil.encrypt(user);
+        // 返回JWT令牌
+        return ResponseEntity.ok(decrypt);
+    }
 }
\ No newline at end of file
diff --git a/src/main/java/com/linghu/controller/CollectController.java b/src/main/java/com/linghu/controller/CollectController.java
index e6b7671..bbd9f8e 100644
--- a/src/main/java/com/linghu/controller/CollectController.java
+++ b/src/main/java/com/linghu/controller/CollectController.java
@@ -47,6 +47,7 @@
 
 import java.util.stream.Collectors;
 import java.util.stream.IntStream;
+import java.util.stream.Stream;
 
 @RestController
 @RequestMapping("/collect")
@@ -206,10 +207,11 @@
 
        int maxConcurrentUsers = searchTaskRequest.getConfig() != null ?
                searchTaskRequest.getConfig().getMax_concurrent_users() : 3;
-       List<List<UserDto>> userBatches = splitUsersIntoBatches(searchTaskRequest.getUsers(), maxConcurrentUsers);
 
        // 获取 keywordId
        Integer keywordId = searchTaskRequest.getKeyword_id();
+       //分割
+       List<List<UserDto>> userBatches = splitUsersIntoBatches(searchTaskRequest.getUsers(), maxConcurrentUsers,keywordId);
 
        return Flux.fromIterable(userBatches)
                .flatMap(batch -> {
@@ -255,7 +257,15 @@
                 .then();
     }
 
-    private List<List<UserDto>> splitUsersIntoBatches(List<UserDto> users, int batchSize) {
+    private List<List<UserDto>> splitUsersIntoBatches(List<UserDto> users, int batchSize,Integer keywordId) {
+
+        Keyword keyword = keywordService.getById(keywordId);
+        if (null==keyword.getNum()){
+            keyword.setNum(0);
+        }
+        keyword.setNum(keyword.getNum()+1);
+        keywordService.updateById(keyword);
+
         List<List<UserDto>> batches = new ArrayList<>();
         for (int i = 0; i < users.size(); i += batchSize) {
             batches.add(users.subList(i, Math.min(i + batchSize, users.size())));
@@ -485,7 +495,7 @@
                 // 3. 收集所有需要更新的问题和引用
                 List<Question> questionsToUpdate = new ArrayList<>();
                 List<Reference> allReferences = new ArrayList<>();
-
+                List<Reference> resultList = new ArrayList<>();
                 // 遍历结果
                 for (UserResult userResult : result.getResults()) {
                     for (QuestionResult questionResult : userResult.getQuestions_results()) {
@@ -511,17 +521,6 @@
 
                                 questionsToUpdate.add(question);
 
-                                //如果查询结果不为空查询num
-                                Integer maxNumByKeywordId = referenceService.getMaxNumByKeywordId(keyword.getKeyword_id());
-                               if (maxNumByKeywordId != null){
-                                   maxNumByKeywordId++;
-                               }else {
-                                   maxNumByKeywordId = 1;
-                               }
-
-
-                                // 收集引用数据,处理空集合情况
-                                Integer finalMaxNumByKeywordId = maxNumByKeywordId;
                                 List<Reference> references =
                                         Optional.ofNullable(questionResult.getReferences())
                                                 .orElse(Collections.emptyList())
@@ -532,30 +531,38 @@
                                                     reference.setTitle(ref.getTitle());
                                                     reference.setUrl(ref.getUrl());
                                                     reference.setDomain(ref.getDomain());
-                                                    reference.setNum(finalMaxNumByKeywordId);
+                                                    reference.setNum(keyword.getNum());
                                                     reference.setTask_id(result.getTask_id());
                                                     reference.setKeyword_id(keyword.getKeyword_id());
                                                     //域名和平台id映射
                                                     reference.setCreate_time(LocalDateTime.now());
                                                     Platform platform = platformService.getPlatformByDomain(reference.getDomain());
-//                                                    if (platform == null) {
-//                                                        throw new RuntimeException("未找到对应的平台: " + reference.getDomain());
-//                                                    }
-                                                    if (platform != null){
+                                                    if (platform == null) {
+                                                        //平台为空 创建平台 类型为“默认”
+                                                        Type type = typeService.getOne(new LambdaQueryWrapper<Type>().eq(Type::getType_name,"默认"));
+                                                        if (type == null) {
+                                                            Type newType = new Type();
+                                                            newType.setType_name("默认");
+                                                            typeService.save(newType);
+                                                            type = newType;
+                                                        }
+                                                        Platform platform1 = new Platform();
+                                                        platform1.setDomain(reference.getDomain());
+                                                        platform1.setPlatform_name(reference.getDomain());
+                                                        platform1.setType_id(type.getType_id());
+                                                        platformService.save(platform1);
+
+                                                        reference.setType_id(type.getType_id());
+                                                        reference.setPlatform_id(platform1.getPlatform_id());
+
+                                                    }
+                                                    else {
                                                         reference.setPlatform_id(platform.getPlatform_id());
                                                         Type type = typeService.getById(platform.getType_id());
-//                                                    if (type == null) {
-//                                                        throw new RuntimeException("未找到对应的类型: " + reference.getDomain());
-//                                                    }
                                                         if (type != null){
                                                             reference.setType_id(type.getType_id());
                                                         }
                                                     }
-
-
-                                                    // 根据 domain 查询类型
-
-
                                                     return reference;
                                                 })
                                                 .collect(Collectors.toList());
@@ -564,6 +571,53 @@
                                 if (!references.isEmpty()) {
                                     allReferences.addAll(references);
                                 }
+
+                                //取数据库中当前关键词的当前轮次的当前问题id结果拿出来
+                                List<Reference> dbList = referenceService.list(new LambdaQueryWrapper<Reference>().eq(Reference::getKeyword_id, keyword.getKeyword_id())
+                                        .eq(Reference::getNum, keyword.getNum())
+                                        .eq(Reference::getQuestion_id, question.getQuestion_id())
+                                );
+
+                                // 1. 合并两个列表
+                                List<Reference> combinedList = new ArrayList<>();
+                                combinedList.addAll(allReferences);
+                                combinedList.addAll(dbList);
+
+                                // 2. 创建复合键的Map,用于统计完全匹配的记录
+                                Map<String, List<Reference>> compositeKeyMap = combinedList.stream()
+                                        .collect(Collectors.groupingBy(
+                                                ref -> ref.getTitle() + "|" + ref.getUrl() + "|" + ref.getDomain()
+                                        ));
+
+                                // 3. 处理每组重复记录
+
+                                compositeKeyMap.forEach((key, refGroup) -> {
+                                    // 3.1 找出组内有ID的记录(优先从dbList中获取)
+                                    Optional<Reference> existingRecord = refGroup.stream()
+                                            .filter(ref -> ref.getReference_id() != null)
+                                            .findFirst();
+
+                                    // 3.2 统计该组的重复次数(总数-1)
+                                    int repetitionCount = refGroup.size() - 1;
+
+                                    // 3.3 决定最终保留的记录
+                                    Reference recordToSave;
+                                    if (existingRecord.isPresent()) {
+                                        // 使用已有ID的记录并更新重复次数
+                                        recordToSave = existingRecord.get();
+                                        recordToSave.setRepetition_num(
+                                                (recordToSave.getRepetition_num() == null ? 0 : recordToSave.getRepetition_num())
+                                                        + repetitionCount
+                                        );
+                                    } else {
+                                        // 没有ID记录则取第一条并设置重复次数
+                                        recordToSave = refGroup.get(0);
+                                        recordToSave.setRepetition_num(repetitionCount);
+                                    }
+
+                                    resultList.add(recordToSave);
+                                });
+                                referenceService.saveOrUpdateBatch(resultList);
                             }
                         } catch (Exception e) {
                             log.error(e.getMessage(), e);
@@ -578,7 +632,7 @@
                     questionService.updateBatchById(questionsToUpdate);
                     System.out.println("成功批量更新 " + questionsToUpdate.size() + " 个问题");
                 }
-                referenceService.saveBatch(allReferences);
+
                 // 5. 批量插入引用,使用流式分批处理
 //                if (!allReferences.isEmpty()) {
 //                    int batchSize = 1000;
diff --git a/src/main/java/com/linghu/controller/KeywordController.java b/src/main/java/com/linghu/controller/KeywordController.java
index 0128509..58358e0 100644
--- a/src/main/java/com/linghu/controller/KeywordController.java
+++ b/src/main/java/com/linghu/controller/KeywordController.java
@@ -75,14 +75,58 @@
     @ApiOperation(value = "EChart图")
     public ResponseResult<KeywordStaticsListVO> statics(@RequestParam("id") Integer keywordId,
             @RequestParam(value = "questionId", required = false) Integer questionId) {
+            //
         return keywordService.statics(keywordId, questionId);
     }
+
+    @GetMapping("/getTime")
+    @ApiOperation(value = "查看时间")
+    public ResponseResult<GetTimeVO> getTime(@RequestParam("id") Integer keywordId,@RequestParam(value = "questionId", required = false) Integer questionId) {
+        //
+        GetTimeVO vo = new GetTimeVO();
+        Keyword keyword = keywordService.getById(keywordId);
+
+        LambdaQueryWrapper<Reference> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(Reference::getKeyword_id, keywordId);
+        if (questionId != null) {
+            queryWrapper.eq(Reference::getQuestion_id, questionId);
+        }
+        queryWrapper.eq(Reference::getNum,keyword.getNum());
+
+        List<Reference> list = referenceService.list(queryWrapper);
+        if (null != list && !list.isEmpty()) {
+            vo.setNow(list.get(0).getCreate_time());
+        }
+        //首次
+        LambdaQueryWrapper<Reference> queryWrapper2 = new LambdaQueryWrapper<>();
+        queryWrapper2.eq(Reference::getKeyword_id, keywordId);
+        if (questionId != null) {
+            queryWrapper2.eq(Reference::getQuestion_id, questionId);
+        }
+        queryWrapper2.eq(Reference::getNum,1);
+
+        List<Reference> list2 = referenceService.list(queryWrapper2);
+        if (null != list2 && !list2.isEmpty()) {
+            vo.setFirst(list2.get(0).getCreate_time());
+        }
+
+        return ResponseResult.success(vo);
+    }
+
 
     @PostMapping(value = "/exportStatics")
     @ApiOperation(value = "EChart图导出")
     public ResponseEntity<byte[]> exportStatics(@RequestBody ExportStaticsDTO exportStaticsDTO) {
+
         Keyword keyword = keywordMapper.selectById(exportStaticsDTO.getKeywordId());
-        List<KeywordStaticsVO> voList = keywordMapper.statics(exportStaticsDTO.getKeywordId(), exportStaticsDTO.getQuestionId(), keyword.getNum());
+        List<KeywordStaticsVO> voList=new ArrayList<>();
+        if (exportStaticsDTO.getIsFirst()==0){
+            voList = keywordMapper.statics(exportStaticsDTO.getKeywordId(), exportStaticsDTO.getQuestionId(), keyword.getNum());
+
+        }else {
+            voList = keywordMapper.statics(exportStaticsDTO.getKeywordId(), exportStaticsDTO.getQuestionId(), 1);
+
+        }
 
         // 3. 导出Excel
         ByteArrayOutputStream out = new ByteArrayOutputStream();
@@ -112,14 +156,10 @@
                     keyword.getNum() , typeId);
 
             return ResponseResult.success(result);
-        }
-        if (isNow > 0 && keyword.getNum()>isNow){
-            List<PlatformProportionVO> result = keywordMapper.getResultByTypeId(keywordId, questionId,
-                    keyword.getNum() - isNow, typeId);
+        }else {
+            List<PlatformProportionVO> result = keywordMapper.getResultByTypeId(keywordId, questionId, 1, typeId);
 
             return ResponseResult.success(result);
-        }else {
-            return ResponseResult.success(new ArrayList<>());
         }
 
     }
@@ -131,8 +171,18 @@
     @ApiOperation(value = "导出:根据类别查看")
     public ResponseEntity<byte[]> exportGetResultByTypeId(@RequestBody ExportGetResultDTO dto) {
         Keyword keyword = keywordService.getById(dto.getKeywordId());
-        List<PlatformProportionVO> result = keywordMapper.getResultByTypeId(dto.getKeywordId(), dto.getQuestionId(),
-                keyword.getNum() - dto.getIsNow(), dto.getTypeId());
+        List<PlatformProportionVO> result =new ArrayList<>();
+
+        if (dto.getIsNow()==0){
+            result = keywordMapper.getResultByTypeId(dto.getKeywordId(), dto.getQuestionId(),
+                    keyword.getNum() , dto.getTypeId());
+        }else {
+            result = keywordMapper.getResultByTypeId(dto.getKeywordId(), dto.getQuestionId(),
+                    1 , dto.getTypeId());
+        }
+
+
+
         // 3. 导出Excel
         ByteArrayOutputStream out = new ByteArrayOutputStream();
         EasyExcel.write(out, PlatformProportionVO.class)
@@ -156,19 +206,16 @@
             @RequestParam(value = "platformId", required = false) Integer platformId,
             @RequestParam(value = "isNow") Integer isNow) {
         Keyword keyword = keywordService.getById(keywordId);
-        if (isNow==0){
+        if (isNow == 0) {
             List<ResultListVO> result = keywordMapper.getResultByPlatformId(keywordId, questionId, keyword.getNum(),
                     platformId);
             return ResponseResult.success(result);
+        } else {
+            List<ResultListVO> result = keywordMapper.getResultByPlatformId(keywordId, questionId, 1,
+                    platformId);
+            return ResponseResult.success(result);
         }
-        if (isNow > 0 && keyword.getNum()>isNow){
-        List<ResultListVO> result = keywordMapper.getResultByPlatformId(keywordId, questionId, keyword.getNum() - isNow,
-                platformId);
 
-        return ResponseResult.success(result);
-        }else {
-            return ResponseResult.success(new ArrayList<>());
-        }
     }
 
     /**
@@ -178,8 +225,14 @@
     @ApiOperation(value = "导出:根据平台查看")
     public ResponseEntity<byte[]> exportGetResultByPlatformId(@RequestBody ExportGetResultByPlatformIdDTO dto) {
         Keyword keyword = keywordService.getById(dto.getKeywordId());
-        List<ResultListVO> result = keywordMapper.getResultByPlatformId(dto.getKeywordId(), dto.getQuestionId(), keyword.getNum() - dto.getIsNow(),
-                dto.getPlatformId());
+        List<ResultListVO> result=new ArrayList<>();
+        if (dto.getIsNow()==0){
+            result = keywordMapper.getResultByPlatformId(dto.getKeywordId(), dto.getQuestionId(), keyword.getNum(),
+                    dto.getPlatformId());
+        }else {
+            result = keywordMapper.getResultByPlatformId(dto.getKeywordId(), dto.getQuestionId(), 1,
+                    dto.getPlatformId());
+        }
         // 3. 导出Excel
         ByteArrayOutputStream out = new ByteArrayOutputStream();
         EasyExcel.write(out, ResultListVO.class)
diff --git a/src/main/java/com/linghu/controller/QuestionController.java b/src/main/java/com/linghu/controller/QuestionController.java
index 77330f8..5b6732f 100644
--- a/src/main/java/com/linghu/controller/QuestionController.java
+++ b/src/main/java/com/linghu/controller/QuestionController.java
@@ -25,6 +25,7 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
+import java.util.Objects;
 import java.util.stream.Collectors;
 
 @RestController
@@ -91,13 +92,11 @@
                     return question;
                 }).collect(Collectors.toList());
 
-        boolean success = questionService.saveBatch(questionList);
+         questionService.saveBatch(questionList);
+
+         return ResponseResult.success();
 
 
-        if(success) {
-            return ResponseResult.success(questionList);
-        }
-        return ResponseResult.error("更新提问词失败");
     }
 
 //    @PutMapping
diff --git a/src/main/java/com/linghu/controller/SectionalizationController.java b/src/main/java/com/linghu/controller/SectionalizationController.java
index 7df12ea..223add5 100644
--- a/src/main/java/com/linghu/controller/SectionalizationController.java
+++ b/src/main/java/com/linghu/controller/SectionalizationController.java
@@ -3,6 +3,7 @@
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.linghu.model.common.ResponseResult;
 import com.linghu.model.entity.Sectionalization;
+import com.linghu.model.vo.SectionalizationUserVO;
 import com.linghu.service.SectionalizationService;
 import com.linghu.service.UserService;
 import io.swagger.annotations.Api;
@@ -75,4 +76,14 @@
 
     }
 
+    /**
+     * 列表和底下用户数据
+     */
+    @GetMapping("/sectionalizationUser")
+    @ApiOperation(value = "获取分组列表和底下用户数据")
+    public ResponseResult<List<SectionalizationUserVO>> sectionalizationUser() {
+        List<SectionalizationUserVO> list = sectionalizationService.SectionalizationUser();
+        return ResponseResult.success(list);
+
+    }
 }
diff --git a/src/main/java/com/linghu/controller/UserController.java b/src/main/java/com/linghu/controller/UserController.java
index 9165d8c..76ccb70 100644
--- a/src/main/java/com/linghu/controller/UserController.java
+++ b/src/main/java/com/linghu/controller/UserController.java
@@ -5,11 +5,10 @@
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.linghu.model.common.ResponseResult;
 import com.linghu.model.entity.Sectionalization;
-import com.linghu.model.entity.Type;
 import com.linghu.model.entity.User;
-import com.linghu.model.excel.KeywordExcel;
 import com.linghu.model.excel.UserExcel;
 import com.linghu.model.vo.UserPageVO;
+import com.linghu.service.SectionalizationService;
 import com.linghu.service.UserService;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
@@ -17,12 +16,16 @@
 import org.springframework.http.HttpHeaders;
 import org.springframework.http.MediaType;
 import org.springframework.http.ResponseEntity;
+import org.springframework.util.StringUtils;
 import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
 
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
 
 @RestController
 @RequestMapping("/user")
@@ -42,6 +45,7 @@
         if (list != null && list.size() > 0) {
             return ResponseResult.error("该邮箱已存在");
         }
+        user.setStatus("正常");
         userService.save(user);
         return ResponseResult.success();
 
@@ -52,8 +56,12 @@
      * 修改用户
      */
     @PutMapping
-    @ApiOperation(value = "添加")
+    @ApiOperation(value = "修改")
     public ResponseResult edit(@RequestBody User user) {
+        User user1 = userService.getById(user.getUser_id());
+        if (user1 == null) {
+            return ResponseResult.error("该账户不存在");
+        }
         List<User> list = userService.list(new LambdaQueryWrapper<User>()
                         .ne(User::getUser_id, user.getUser_id())
                 .eq(User::getUser_email, user.getUser_email()));
@@ -80,22 +88,20 @@
      * 分页查询
      */
     @GetMapping
-    @ApiOperation(value = "删除")
+    @ApiOperation(value = "分页")
     public ResponseResult<Page<UserPageVO>> page(@RequestParam(value = "pageSize", required = false, defaultValue = "10")Integer pageSize,
                                                  @RequestParam(value = "pageNum", required = false,defaultValue = "1")Integer pageNum,
                                                  @RequestParam(value = "sectionalization_id",required = false)Integer sectionalization_id,
                                                  @RequestParam(value = "status" ,required = false)String status) {
         Page<UserPageVO> page = new Page<>(pageNum, pageSize);
         return ResponseResult.success( userService.getPage(page,sectionalization_id,status));
-
-
     }
 
     /**
      * 下载模板
      */
 
-    @PostMapping("/downloadTemplate")
+    @GetMapping("/downloadTemplate")
     @ApiOperation("下载模板")
     public ResponseEntity<byte[]> downloadTemplate() throws IOException {
         ByteArrayOutputStream out = new ByteArrayOutputStream();
@@ -111,7 +117,102 @@
     /**
      * 导入文件
      */
+    // 导入文件
+    @Autowired
+    private SectionalizationService sectionalizationService;
+    @PostMapping("/importUserExcel")
+    @ApiOperation("导入用户数据")
+    public ResponseResult importUserExcel(@RequestParam("file") MultipartFile file) {
+        //查找出用户列表
+        List<User> userList = userService.list();
+        //名称
+        Map<String, User> nameMap = userList.stream()
+                .collect(Collectors.toMap(
+                        User::getUser_name,  // Key映射
+                        excel -> excel,  // Value映射
+                        (oldValue, newValue) -> oldValue  // 键冲突处理(保留旧值)
+                ));
 
+        //查找出分组列表
+        List<Sectionalization>  list = sectionalizationService.list();
+        //分组
+        Map<String, Sectionalization> sectionalizationMap = list.stream()
+                .collect(Collectors.toMap(
+                        Sectionalization::getSectionalization_name,  // Key映射
+                        excel -> excel,  // Value映射
+                        (oldValue, newValue) -> oldValue  // 键冲突处理(保留旧值)
+                ));
+
+        try {
+            // 检查文件是否为空
+            if (file.isEmpty()) {
+                return ResponseResult.error("上传文件不能为空");
+            }
+
+            // 读取Excel数据
+            List<UserExcel> excelList = EasyExcel.read(file.getInputStream())
+                    .head(UserExcel.class)
+                    .sheet()
+                    .doReadSync();
+
+            // 数据转换与验证
+            List<String> errorMessages = new ArrayList<>();
+            for (UserExcel excel : excelList) {
+                // 检查必要字段
+                if (!StringUtils.hasText(excel.getUser_name())) {
+                    errorMessages.add("账户名不能为空");
+                    continue;
+                }
+                if (!StringUtils.hasText(excel.getUser_email())) {
+                    errorMessages.add("邮箱不能为空");
+                    continue;
+                }
+                if (!StringUtils.hasText(String.valueOf(excel.getPassword()))) {
+                    errorMessages.add("密码不能为空");
+                    continue;
+                }
+
+                if (!StringUtils.hasText(excel.getSectionalization_name())) {
+                    errorMessages.add("分组不能为空");
+                    continue;
+                }
+                if (nameMap.containsKey(excel.getUser_name())){
+                    errorMessages.add("用户名称重复");
+                    continue;
+                }
+            }
+            // 处理错误
+            if (!errorMessages.isEmpty()) {
+                return ResponseResult.error("数据验证失败: " + String.join("; ", errorMessages));
+            }
+            // 开始添加
+            for (UserExcel excel : excelList) {
+                User user = new User();
+                if (sectionalizationMap.containsKey(excel.getSectionalization_name())) {
+                    user.setSectionalization_id(sectionalizationMap.get(excel.getSectionalization_name()).getSectionalization_id());
+                }else {
+                    //新增
+                    Sectionalization sectionalization = new Sectionalization();
+                    sectionalization.setSectionalization_name(excel.getSectionalization_name());
+                    sectionalizationService.save(sectionalization);
+                    user.setSectionalization_id(sectionalization.getSectionalization_id());
+                }
+                user.setUser_email(excel.getUser_email());
+                user.setUser_name(excel.getUser_name());
+                user.setPassword(excel.getPassword());
+                user.setStatus("正常");
+                userService.save(user);
+
+            }
+            // 返回信息
+            return ResponseResult.success();
+        }
+        catch (Exception e) {
+            // 记录详细异常信息
+
+            return ResponseResult.error("文件解析失败:" + e.getMessage());
+        }
+    }
 
 
 
diff --git a/src/main/java/com/linghu/mapper/UserMapper.java b/src/main/java/com/linghu/mapper/UserMapper.java
index 50ac193..d149261 100644
--- a/src/main/java/com/linghu/mapper/UserMapper.java
+++ b/src/main/java/com/linghu/mapper/UserMapper.java
@@ -14,7 +14,7 @@
 */
 public interface UserMapper extends BaseMapper<User> {
 
-    Page<UserPageVO> getPage(Page<UserPageVO> page, @Param("sectionalizationId") Integer sectionalizationId, @Param("status") String status);
+    Page<UserPageVO> getPage(@Param("page") Page<UserPageVO> page, @Param("sectionalizationId") Integer sectionalizationId, @Param("status") String status);
 }
 
 
diff --git a/src/main/java/com/linghu/model/dto/ExportGetResultDTO.java b/src/main/java/com/linghu/model/dto/ExportGetResultDTO.java
index 631f97e..c6c0454 100644
--- a/src/main/java/com/linghu/model/dto/ExportGetResultDTO.java
+++ b/src/main/java/com/linghu/model/dto/ExportGetResultDTO.java
@@ -9,6 +9,6 @@
     private Integer keywordId;
     private  Integer questionId;
     private Integer typeId;
-    @ApiModelProperty("轮数 0:当前 1:前一轮")
+    @ApiModelProperty("轮数 0:当前 1:首次")
     private Integer isNow;
 }
diff --git a/src/main/java/com/linghu/model/dto/ExportStaticsDTO.java b/src/main/java/com/linghu/model/dto/ExportStaticsDTO.java
index 0aa7857..cfd0ba5 100644
--- a/src/main/java/com/linghu/model/dto/ExportStaticsDTO.java
+++ b/src/main/java/com/linghu/model/dto/ExportStaticsDTO.java
@@ -9,4 +9,6 @@
     private Integer keywordId;
     @ApiModelProperty("提问词id")
     private  Integer questionId;
+    @ApiModelProperty("是否首次 0-否 1- 是")
+    private  Integer isFirst;
 }
diff --git a/src/main/java/com/linghu/model/entity/Sectionalization.java b/src/main/java/com/linghu/model/entity/Sectionalization.java
index 6136124..e853af8 100644
--- a/src/main/java/com/linghu/model/entity/Sectionalization.java
+++ b/src/main/java/com/linghu/model/entity/Sectionalization.java
@@ -1,5 +1,6 @@
 package com.linghu.model.entity;
 
+import com.baomidou.mybatisplus.annotation.IdType;
 import com.baomidou.mybatisplus.annotation.TableField;
 import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableName;
@@ -14,7 +15,7 @@
 
     @TableField(exist = false)
     private static final long serialVersionUID = 1L;
-    @TableId
+    @TableId(type = IdType.AUTO)
     private Integer sectionalization_id;
 
     @NotEmpty(message = "用户名不能为空")
diff --git a/src/main/java/com/linghu/model/entity/User.java b/src/main/java/com/linghu/model/entity/User.java
index b5b1510..885be39 100644
--- a/src/main/java/com/linghu/model/entity/User.java
+++ b/src/main/java/com/linghu/model/entity/User.java
@@ -1,5 +1,6 @@
 package com.linghu.model.entity;
 
+import com.baomidou.mybatisplus.annotation.IdType;
 import com.baomidou.mybatisplus.annotation.TableField;
 import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableName;
@@ -9,6 +10,7 @@
 import javax.validation.constraints.NotBlank;
 import javax.validation.constraints.Size;
 
+import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 
 /**
@@ -21,7 +23,7 @@
     /**
      * 用户id
      */
-    @TableId
+    @TableId(type = IdType.AUTO)
     private Integer user_id;
 
     /**
@@ -47,6 +49,7 @@
     /**
      * 手机号
      */
+    @ApiModelProperty(hidden = true)
     private Integer phone;
 
     /**
diff --git a/src/main/java/com/linghu/model/vo/GetTimeVO.java b/src/main/java/com/linghu/model/vo/GetTimeVO.java
new file mode 100644
index 0000000..63d3911
--- /dev/null
+++ b/src/main/java/com/linghu/model/vo/GetTimeVO.java
@@ -0,0 +1,21 @@
+package com.linghu.model.vo;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import sun.util.resources.LocaleData;
+
+import java.time.LocalDateTime;
+
+@Data
+public class GetTimeVO {
+
+    @ApiModelProperty("本次采集时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private LocalDateTime now;
+
+    @ApiModelProperty("首次采集时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private LocalDateTime first;
+}
diff --git a/src/main/java/com/linghu/model/vo/KeywordStaticsListVO.java b/src/main/java/com/linghu/model/vo/KeywordStaticsListVO.java
index 3b298c6..d329627 100644
--- a/src/main/java/com/linghu/model/vo/KeywordStaticsListVO.java
+++ b/src/main/java/com/linghu/model/vo/KeywordStaticsListVO.java
@@ -5,6 +5,7 @@
 import lombok.Data;
 
 import java.math.BigDecimal;
+import java.time.LocalDateTime;
 import java.util.List;
 
 @Data
@@ -13,7 +14,7 @@
     @ApiModelProperty("当前统计记录")
     private List<KeywordStaticsVO> nowRecord;
 
-    @ApiModelProperty("统计记录-前一次")
+    @ApiModelProperty("统计记录-首次")
     private List<KeywordStaticsVO> beforeRecord;
 
 }
diff --git a/src/main/java/com/linghu/model/vo/KeywordStaticsVO.java b/src/main/java/com/linghu/model/vo/KeywordStaticsVO.java
index 2ac5c74..9c520ff 100644
--- a/src/main/java/com/linghu/model/vo/KeywordStaticsVO.java
+++ b/src/main/java/com/linghu/model/vo/KeywordStaticsVO.java
@@ -1,5 +1,6 @@
 package com.linghu.model.vo;
 
+import com.alibaba.excel.annotation.ExcelIgnore;
 import com.alibaba.excel.annotation.ExcelProperty;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
@@ -10,6 +11,9 @@
 @Data
 @ApiModel("关键词统计")
 public class KeywordStaticsVO {
+    @ApiModelProperty("发布平台id")
+    @ExcelIgnore
+    private String platform_id;
     @ApiModelProperty("发布平台")
     @ExcelProperty("发布平台")
     private String platform_name;
diff --git a/src/main/java/com/linghu/model/vo/SectionalizationUserVO.java b/src/main/java/com/linghu/model/vo/SectionalizationUserVO.java
new file mode 100644
index 0000000..c3f02fc
--- /dev/null
+++ b/src/main/java/com/linghu/model/vo/SectionalizationUserVO.java
@@ -0,0 +1,18 @@
+package com.linghu.model.vo;
+
+import com.linghu.model.entity.User;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class SectionalizationUserVO {
+
+    @ApiModelProperty("分组id")
+    private Integer sectionalization_id;
+    @ApiModelProperty("分组名称")
+    private String sectionalization_name;
+    @ApiModelProperty("用户VO")
+    private List<User> sectionalization_users;
+}
diff --git a/src/main/java/com/linghu/model/vo/UserPageVO.java b/src/main/java/com/linghu/model/vo/UserPageVO.java
index ade1556..0f13c21 100644
--- a/src/main/java/com/linghu/model/vo/UserPageVO.java
+++ b/src/main/java/com/linghu/model/vo/UserPageVO.java
@@ -10,10 +10,10 @@
     private Integer user_id;
 
     @ApiModelProperty("用户名")
-    private Integer user_name;
+    private String user_name;
 
     @ApiModelProperty("用户邮箱")
-    private Integer user_email;
+    private String user_email;
 
     @ApiModelProperty("密码")
     private String password;
@@ -21,6 +21,8 @@
     @ApiModelProperty("分组名称")
     private String sectionalization_name;
 
+    @ApiModelProperty("分组名称")
+    private Integer sectionalization_id;
     @ApiModelProperty("状态")
     private String status;
 
diff --git a/src/main/java/com/linghu/service/SectionalizationService.java b/src/main/java/com/linghu/service/SectionalizationService.java
index fa3a4d3..5df876f 100644
--- a/src/main/java/com/linghu/service/SectionalizationService.java
+++ b/src/main/java/com/linghu/service/SectionalizationService.java
@@ -5,6 +5,7 @@
 import com.linghu.model.dto.OrderDto;
 import com.linghu.model.entity.Orders;
 import com.linghu.model.entity.Sectionalization;
+import com.linghu.model.vo.SectionalizationUserVO;
 
 import java.util.List;
 
@@ -15,4 +16,5 @@
  */
 public interface SectionalizationService extends IService<Sectionalization> {
 
+    List<SectionalizationUserVO> SectionalizationUser();
 }
diff --git a/src/main/java/com/linghu/service/impl/KeywordServiceImpl.java b/src/main/java/com/linghu/service/impl/KeywordServiceImpl.java
index c8a3bd6..087c037 100644
--- a/src/main/java/com/linghu/service/impl/KeywordServiceImpl.java
+++ b/src/main/java/com/linghu/service/impl/KeywordServiceImpl.java
@@ -41,7 +41,7 @@
         List<KeywordStaticsVO> statics = this.getBaseMapper().statics(keywordId, questionId, keyword.getNum());
         vo.setNowRecord(statics);
         if (keyword.getNum() > 1) {
-            statics = this.getBaseMapper().statics(keywordId, questionId, keyword.getNum() - 1);
+            statics = this.getBaseMapper().statics(keywordId, questionId, 1);
             vo.setBeforeRecord(statics);
         }
         return ResponseResult.success(vo);
diff --git a/src/main/java/com/linghu/service/impl/SectionalizationServiceImpl.java b/src/main/java/com/linghu/service/impl/SectionalizationServiceImpl.java
index e66d702..ac9035e 100644
--- a/src/main/java/com/linghu/service/impl/SectionalizationServiceImpl.java
+++ b/src/main/java/com/linghu/service/impl/SectionalizationServiceImpl.java
@@ -1,13 +1,21 @@
 package com.linghu.service.impl;
 
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.linghu.mapper.SectionalizationMapper;
 import com.linghu.mapper.UserMapper;
 import com.linghu.model.entity.Sectionalization;
 import com.linghu.model.entity.User;
+import com.linghu.model.vo.SectionalizationUserVO;
 import com.linghu.service.SectionalizationService;
 import com.linghu.service.UserService;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
 
 /**
 * @author xy
@@ -18,6 +26,50 @@
 public class SectionalizationServiceImpl extends ServiceImpl<SectionalizationMapper, Sectionalization>
     implements SectionalizationService {
 
+    @Autowired
+    private UserMapper userMapper;
+    @Override
+    public List<SectionalizationUserVO> SectionalizationUser() {
+        // 1. 查询所有状态为"正常"的用户
+        List<User> userList = userMapper.selectList(
+                new LambdaQueryWrapper<User>()
+                        .eq(User::getStatus, "正常")
+        );
+
+        // 2. 提取所有分组ID并去重
+        List<Integer> sectionalizationIdList = userList.stream()
+                .map(User::getSectionalization_id)
+                .distinct()
+                .collect(Collectors.toList());
+
+        // 3. 查询这些分组的基本信息
+        List<Sectionalization> sectionalizationList = this.baseMapper.selectList(
+                new LambdaQueryWrapper<Sectionalization>()
+                        .in(Sectionalization::getSectionalization_id, sectionalizationIdList)
+        );
+
+        // 4. 创建分组ID到分组名称的映射
+        Map<Integer, String> sectionalizationNameMap = sectionalizationList.stream()
+                .collect(Collectors.toMap(
+                        Sectionalization::getSectionalization_id,
+                        Sectionalization::getSectionalization_name
+                ));
+
+        // 5. 按分组ID对用户进行分组
+        Map<Integer, List<User>> usersBySectionalization = userList.stream()
+                .collect(Collectors.groupingBy(User::getSectionalization_id));
+
+        // 6. 构建最终返回结果
+        return sectionalizationIdList.stream()
+                .map(id -> {
+                    SectionalizationUserVO vo = new SectionalizationUserVO();
+                    vo.setSectionalization_id(id);
+                    vo.setSectionalization_name(sectionalizationNameMap.get(id));
+                    vo.setSectionalization_users(usersBySectionalization.getOrDefault(id, Collections.emptyList()));
+                    return vo;
+                })
+                .collect(Collectors.toList());
+    }
 }
 
 
diff --git a/src/main/java/com/linghu/timeTask/ScheduledTasks.java b/src/main/java/com/linghu/timeTask/ScheduledTasks.java
index 95c2a50..a22011b 100644
--- a/src/main/java/com/linghu/timeTask/ScheduledTasks.java
+++ b/src/main/java/com/linghu/timeTask/ScheduledTasks.java
@@ -62,8 +62,9 @@
                                     t.setStatus("completed");
                                     return t;
                                 });
-                    } else if (!"submit".equalsIgnoreCase(statusResponse.getStatus())
-                            && !"running".equalsIgnoreCase(statusResponse.getStatus())) {
+                    } else if (!"submitted".equalsIgnoreCase(statusResponse.getStatus())
+                            && !"running".equalsIgnoreCase(statusResponse.getStatus())
+                            && !"Error".equalsIgnoreCase(statusResponse.getStatus())) {
                         task.setStatus("false");
                         return Mono.just(task);
                     } else {
diff --git a/src/main/java/com/linghu/utils/OpenCryptUtil.java b/src/main/java/com/linghu/utils/OpenCryptUtil.java
index 388af01..b48aea6 100644
--- a/src/main/java/com/linghu/utils/OpenCryptUtil.java
+++ b/src/main/java/com/linghu/utils/OpenCryptUtil.java
@@ -32,7 +32,7 @@
     /**
      * AES加密(假设 open-crypt 默认使用AES-CBC模式)
      */
-    public String encrypt(User user) {
+    public String encrypt(String user) {
         try {
             // 调用 open-crypt 的加密方法(根据实际API调整)
             //user转为 json
diff --git a/src/main/resources/mapper/UserMapper.xml b/src/main/resources/mapper/UserMapper.xml
index cbb1688..b7a0ec8 100644
--- a/src/main/resources/mapper/UserMapper.xml
+++ b/src/main/resources/mapper/UserMapper.xml
@@ -20,15 +20,16 @@
     </sql>
     <select id="getPage" resultType="com.linghu.model.vo.UserPageVO">
         SELECT
-            u.user_id,
-            u.user_name,
-            u.user_email,
-            u.`password`,
-            s.sectionalization_name,
-            u.status
+        u.user_id,
+        u.user_name,
+        u.user_email,
+        u.`password`,
+        s.sectionalization_name,
+        s.sectionalization_id,
+        u.status
         FROM
-            `user` u
-                LEFT JOIN sectionalization s on u.sectionalization_id = s.sectionalization_id
+        `user` u
+        LEFT JOIN sectionalization s on u.sectionalization_id = s.sectionalization_id
         <where>
             <if test="sectionalizationId!=null">
                 and s.sectionalization_id= #{sectionalizationId}
diff --git a/src/main/resources/mapper/keywordMapper.xml b/src/main/resources/mapper/keywordMapper.xml
index 8200479..87e4837 100644
--- a/src/main/resources/mapper/keywordMapper.xml
+++ b/src/main/resources/mapper/keywordMapper.xml
@@ -19,6 +19,7 @@
     </sql>
     <select id="statics" resultType="com.linghu.model.vo.KeywordStaticsVO">
         SELECT
+        p.platform_id,
         p.platform_name,
         SUM( r.repetition_num ) AS total_repetitions,
         ROUND(

--
Gitblit v1.7.1