| | |
| | | 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; |
| | | } |
| | | } |
| | |
| | | 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); |
| | | } |
| | | } |
| | |
| | | |
| | | import java.util.stream.Collectors; |
| | | import java.util.stream.IntStream; |
| | | import java.util.stream.Stream; |
| | | |
| | | @RestController |
| | | @RequestMapping("/collect") |
| | |
| | | |
| | | 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 -> { |
| | |
| | | .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()))); |
| | |
| | | // 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()) { |
| | |
| | | |
| | | 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()) |
| | |
| | | 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()); |
| | |
| | | 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); |
| | |
| | | questionService.updateBatchById(questionsToUpdate); |
| | | System.out.println("成功批量更新 " + questionsToUpdate.size() + " 个问题"); |
| | | } |
| | | referenceService.saveBatch(allReferences); |
| | | |
| | | // 5. 批量插入引用,使用流式分批处理 |
| | | // if (!allReferences.isEmpty()) { |
| | | // int batchSize = 1000; |
| | |
| | | @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(); |
| | |
| | | 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<>()); |
| | | } |
| | | |
| | | } |
| | |
| | | @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) |
| | |
| | | @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<>()); |
| | | } |
| | | } |
| | | |
| | | /** |
| | |
| | | @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) |
| | |
| | | import java.util.ArrayList; |
| | | import java.util.Arrays; |
| | | import java.util.List; |
| | | import java.util.Objects; |
| | | import java.util.stream.Collectors; |
| | | |
| | | @RestController |
| | |
| | | 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 |
| | |
| | | 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; |
| | |
| | | |
| | | } |
| | | |
| | | /** |
| | | * 列表和底下用户数据 |
| | | */ |
| | | @GetMapping("/sectionalizationUser") |
| | | @ApiOperation(value = "获取分组列表和底下用户数据") |
| | | public ResponseResult<List<SectionalizationUserVO>> sectionalizationUser() { |
| | | List<SectionalizationUserVO> list = sectionalizationService.SectionalizationUser(); |
| | | return ResponseResult.success(list); |
| | | |
| | | } |
| | | } |
| | |
| | | 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; |
| | |
| | | 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") |
| | |
| | | if (list != null && list.size() > 0) { |
| | | return ResponseResult.error("该邮箱已存在"); |
| | | } |
| | | user.setStatus("正常"); |
| | | userService.save(user); |
| | | return ResponseResult.success(); |
| | | |
| | |
| | | * 修改用户 |
| | | */ |
| | | @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())); |
| | |
| | | * 分页查询 |
| | | */ |
| | | @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(); |
| | |
| | | /** |
| | | * 导入文件 |
| | | */ |
| | | // 导入文件 |
| | | @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()); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | |
| | | */ |
| | | 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); |
| | | } |
| | | |
| | | |
| | |
| | | private Integer keywordId; |
| | | private Integer questionId; |
| | | private Integer typeId; |
| | | @ApiModelProperty("轮数 0:当前 1:前一轮") |
| | | @ApiModelProperty("轮数 0:当前 1:首次") |
| | | private Integer isNow; |
| | | } |
| | |
| | | private Integer keywordId; |
| | | @ApiModelProperty("提问词id") |
| | | private Integer questionId; |
| | | @ApiModelProperty("是否首次 0-否 1- 是") |
| | | private Integer isFirst; |
| | | } |
| | |
| | | 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; |
| | |
| | | |
| | | @TableField(exist = false) |
| | | private static final long serialVersionUID = 1L; |
| | | @TableId |
| | | @TableId(type = IdType.AUTO) |
| | | private Integer sectionalization_id; |
| | | |
| | | @NotEmpty(message = "用户名不能为空") |
| | |
| | | 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; |
| | |
| | | import javax.validation.constraints.NotBlank; |
| | | import javax.validation.constraints.Size; |
| | | |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import lombok.Data; |
| | | |
| | | /** |
| | |
| | | /** |
| | | * 用户id |
| | | */ |
| | | @TableId |
| | | @TableId(type = IdType.AUTO) |
| | | private Integer user_id; |
| | | |
| | | /** |
| | |
| | | /** |
| | | * 手机号 |
| | | */ |
| | | @ApiModelProperty(hidden = true) |
| | | private Integer phone; |
| | | |
| | | /** |
New file |
| | |
| | | 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; |
| | | } |
| | |
| | | import lombok.Data; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.time.LocalDateTime; |
| | | import java.util.List; |
| | | |
| | | @Data |
| | |
| | | @ApiModelProperty("当前统计记录") |
| | | private List<KeywordStaticsVO> nowRecord; |
| | | |
| | | @ApiModelProperty("统计记录-前一次") |
| | | @ApiModelProperty("统计记录-首次") |
| | | private List<KeywordStaticsVO> beforeRecord; |
| | | |
| | | } |
| | |
| | | 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; |
| | |
| | | @Data |
| | | @ApiModel("关键词统计") |
| | | public class KeywordStaticsVO { |
| | | @ApiModelProperty("发布平台id") |
| | | @ExcelIgnore |
| | | private String platform_id; |
| | | @ApiModelProperty("发布平台") |
| | | @ExcelProperty("发布平台") |
| | | private String platform_name; |
New file |
| | |
| | | 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; |
| | | } |
| | |
| | | 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; |
| | |
| | | @ApiModelProperty("分组名称") |
| | | private String sectionalization_name; |
| | | |
| | | @ApiModelProperty("分组名称") |
| | | private Integer sectionalization_id; |
| | | @ApiModelProperty("状态") |
| | | private String status; |
| | | |
| | |
| | | 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; |
| | | |
| | |
| | | */ |
| | | public interface SectionalizationService extends IService<Sectionalization> { |
| | | |
| | | List<SectionalizationUserVO> SectionalizationUser(); |
| | | } |
| | |
| | | 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); |
| | |
| | | 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 |
| | |
| | | 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()); |
| | | } |
| | | } |
| | | |
| | | |
| | |
| | | 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 { |
| | |
| | | /** |
| | | * AES加密(假设 open-crypt 默认使用AES-CBC模式) |
| | | */ |
| | | public String encrypt(User user) { |
| | | public String encrypt(String user) { |
| | | try { |
| | | // 调用 open-crypt 的加密方法(根据实际API调整) |
| | | //user转为 json |
| | |
| | | </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} |
| | |
| | | </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( |