项目细节优化

news2024/9/21 22:40:22

文章目录

    • 1.解决重复注册
        • 1.AuthUserDomainServiceImpl.java 在注册之前从db查询是否已经存在该用户
        • 2.AuthUserService.java
        • 3.AuthUserServiceImpl.java
        • 4.测试
          • 1.请求
          • 2.后台,提示已经注册
    • 2.用户信息查询
        • 1.接口设计
        • 2.代码实现
          • 1.UserController.java
          • 2.AuthUserDomainService.java
          • 3.AuthUserDomainServiceImpl.java
        • 3.测试
    • 3.用户退出登录
        • 1.UserController.java
    • 4.上传头像
        • 1.StorageAdapter.java
        • 2.MinioStorageAdapter.java
        • 3.FileService.java
        • 4.FileController.java
    • 5.分类题目数量更新
        • 1.SubjectCategoryDTO.java
        • 2.SubjectCategoryBO.java
        • 3.SubjectCategoryService.java
        • 4.SubjectCategoryServiceImpl.java
        • 5.SubjectCategoryDao.java
        • 6.SubjectCategoryDao.xml
    • 6.分类标签性能优化
        • 1.SubjectCategoryController.java
        • 2.SubjectCategoryDomainService.java
        • 3.SubjectCategoryDomainServiceImpl.java
        • 4.DTO和BO增加标签字段
          • 1.SubjectCategoryDTO.java
          • 2.SubjectCategoryBO.java
        • 5.测试
          • 1.接口设计
          • 2.测试
    • 7.用户权限获取
        • 1.PermissionController.java
        • 2.AuthPermissionDomainService.java
        • 3.AuthPermissionDomainServiceImpl.java
        • 4.测试

1.解决重复注册

1.AuthUserDomainServiceImpl.java 在注册之前从db查询是否已经存在该用户

image-20240611135226515

2.AuthUserService.java
/**
 * 查询总数
 *
 * @return
 */
List<AuthUser> queryByConditionCount(AuthUser authUser);
3.AuthUserServiceImpl.java
/**
 * 查询总数
 *
 * @return
 */
@Override
public List<AuthUser> queryByConditionCount(AuthUser authUser) {
    return this.authUserDao.queryAllByLimit(authUser);
}
4.测试
1.请求

2.后台,提示已经注册

image-20240611135401831

2.用户信息查询

1.接口设计

image-20240611141108115

2.代码实现
1.UserController.java
/**
 * 获取用户信息
 * @param authUserDTO
 * @return
 */
@RequestMapping("getUserInfo")
public Result<AuthUserDTO> getUserInfo(@RequestBody AuthUserDTO authUserDTO) {
    try {
        // 日志
        if (log.isInfoEnabled()) {
            log.info("UserController getUserInfo AuthUserDTO, authUserDTO:{}", JSON.toJSONString(authUserDTO));
        }
        // 参数校验
        Preconditions.checkArgument(!StringUtils.isBlank(authUserDTO.getUserName()), "用户名不能为空");
        // 转换DTO为BO
        AuthUserBO authUserBO = AuthUserDTOConverter.INSTANCE.convertDTO2BO(authUserDTO);
        // 调用领域服务
        // 获取用户信息
        AuthUserBO res = authUserDomainService.getUserInfo(authUserBO);
        // 将BO转换为DTO
        AuthUserDTO authUserDTO1 = AuthUserDTOConverter.INSTANCE.convertBO2DTO(res);
        return Result.ok(authUserDTO1);
    } catch (Exception e) {
        log.error("UserController getUserInfo error:{}", e.getMessage(), e);
        return Result.fail("获取用户信息失败");
    }
}
2.AuthUserDomainService.java
/**
 * 获取用户信息
 * @param authUserBO
 * @return
 */
AuthUserBO getUserInfo(AuthUserBO authUserBO);
3.AuthUserDomainServiceImpl.java
/**
 * 获取用户信息
 * @param authUserBO
 * @return
 */
@Override
public AuthUserBO getUserInfo(AuthUserBO authUserBO) {
    // 将BO转换为Entity
    AuthUser authUser = AuthUserBOConverter.INSTANCE.convertBO2Entity(authUserBO);
    List<AuthUser> authUsers = authUserService.queryByConditionCount(authUser);
    AuthUser authUser1 = authUsers.get(0);
    // 将Entity转换为BO
    AuthUserBO authUserBO1 = AuthUserBOConverter.INSTANCE.convertEntity2BO(authUser1);
    return authUserBO1;
}
3.测试

image-20240611141233345

3.用户退出登录

1.UserController.java
/**
 * 用户退出
 * @param userName
 * @return
 */
@RequestMapping("logOut")
public Result logOut(@RequestParam("userName") String userName) {
    try {
        // 日志
        if (log.isInfoEnabled()) {
            log.info("UserController logOut userName:{}", userName);
        }
        // 参数校验
        Preconditions.checkArgument(!StringUtils.isBlank(userName), "用户名不能为空");
        // 用户退出
        StpUtil.logout(userName);
        return Result.ok();
    } catch (Exception e) {
        log.error("UserController logOut error:{}", e.getMessage(), e);
        return Result.fail("用户退出失败");
    }
}

4.上传头像

1.StorageAdapter.java
@Override
@SneakyThrows
public String getUrl(String bucket, String objectName) {
    return url + "/" + bucket + "/" + objectName;
}
2.MinioStorageAdapter.java
@Override
@SneakyThrows
public String getUrl(String bucket, String objectName) {
    return url + "/" + bucket + "/" + objectName;
}
3.FileService.java
/**
 * 上传文件
 */
public String uploadFile(MultipartFile uploadFile, String bucket, String objectName){
    storageAdapter.uploadFile(uploadFile,bucket,objectName);
    objectName = objectName + "/" + uploadFile.getOriginalFilename();
    return storageAdapter.getUrl(bucket, objectName);
}
4.FileController.java
/**
 * 上传文件
 */
@RequestMapping("/upload")
public Result upload(MultipartFile uploadFile, String bucket, String objectName) throws Exception {
    String url = fileService.uploadFile(uploadFile, bucket, objectName);
    return Result.ok(url);
}

5.分类题目数量更新

1.SubjectCategoryDTO.java

image-20240611151600766

2.SubjectCategoryBO.java

image-20240611151630864

3.SubjectCategoryService.java
/**
 * 查询分类下的题目数量
 * @param id
 * @return
 */
Integer querySubjectCount(Long id);
4.SubjectCategoryServiceImpl.java
/**
 * 查询分类下的题目数量
 * @param id
 * @return
 */
@Override
public Integer querySubjectCount(Long id) {
    return this.subjectCategoryDao.querySubjectCount(id);
}
5.SubjectCategoryDao.java
/**
 * 查询分类下的题目数量
 * @param id
 * @return
 */
Integer querySubjectCount(@Param("id") Long id);
6.SubjectCategoryDao.xml
<!-- 根据分类Id查询题目数量 -->
<select id="querySubjectCount" resultType="java.lang.Integer">
    select count(distinct subject_id)
    from subject_mapping
    where category_id = #{id}
</select>

6.分类标签性能优化

1.SubjectCategoryController.java
/**
 * 查询分类及标签(一次性)
 * @param subjectCategoryDTO
 * @return
 */
@PostMapping("/queryCategoryAndLabel")
public Result<List<SubjectCategoryDTO>> queryCategoryAndLabel(@RequestBody SubjectCategoryDTO subjectCategoryDTO) {
    try {
        // 打日志
        if (log.isInfoEnabled()) {
            log.info("SubjectCategoryController queryCategoryAndLabel SubjectCategoryDTO, subjectCategoryDTO:{}", JSON.toJSONString(subjectCategoryDTO));
        }
        // 参数校验
        Preconditions.checkNotNull(subjectCategoryDTO.getId(), "分类id不能为空");
        // 转换DTO为BO
        SubjectCategoryBO subjectCategoryBO = SubjectCategoryDTOConverter.INSTANCE.convertDTOToSubjectCategory(subjectCategoryDTO);
        // 查询分类以及标签
        List<SubjectCategoryBO> subjectCategoryBOList = subjectCategoryDomainService.queryCategoryAndLabel(subjectCategoryBO);
        // 将BO转换为DAO
        List<SubjectCategoryDTO> subjectCategoryDTOList = new LinkedList<>();
        subjectCategoryBOList.forEach(subjectCategoryBO1 -> {
            SubjectCategoryDTO subjectCategoryDTO1 = new SubjectCategoryDTO();
            subjectCategoryDTO1.setId(subjectCategoryBO1.getId());
            subjectCategoryDTO1.setCategoryName(subjectCategoryBO1.getCategoryName());
            subjectCategoryDTO1.setCategoryType(subjectCategoryBO1.getCategoryType());
            subjectCategoryDTO1.setImageUrl(subjectCategoryBO1.getImageUrl());
            subjectCategoryDTO1.setParentId(subjectCategoryBO1.getParentId());
            subjectCategoryDTO1.setCount(subjectCategoryBO1.getCount());
            List<SubjectLabelBO> labelBOList = subjectCategoryBO1.getLabelBOList();
            // 将List<SubjectLabelBO> 转换为List<SubjectLabelDTO>
            List<SubjectLabelDTO> subjectLabelDTOList = SubjectLabelDTOConverter.INSTANCE.convertSubjectLabelToDto(labelBOList);
            subjectCategoryDTO1.setLabelDTOList(subjectLabelDTOList);
            subjectCategoryDTOList.add(subjectCategoryDTO1);
        });
        return Result.ok(subjectCategoryDTOList);
    } catch (Exception e) {
        // 记录日志
        log.error("SubjectCategoryController queryCategoryAndLabel error:{}", e.getMessage(), e);
        return Result.fail("查询分类及标签失败");
    }
}
2.SubjectCategoryDomainService.java
/**
 * 查询分类及标签
 * @param subjectCategoryBO
 * @return
 */
List<SubjectCategoryBO> queryCategoryAndLabel(SubjectCategoryBO subjectCategoryBO);
3.SubjectCategoryDomainServiceImpl.java
@Override
public List<SubjectCategoryBO> queryCategoryAndLabel(SubjectCategoryBO subjectCategoryBO) {
    // 查询大分类下的所有小分类
    SubjectCategory subjectCategory = new SubjectCategory();
    subjectCategory.setParentId(subjectCategoryBO.getParentId());
    subjectCategory.setIsDeleted(IsDeleteFlagEnum.UN_DELETED.getCode());
    List<SubjectCategory> subjectCategoryList = subjectCategoryService.queryCategory(subjectCategory);
    // 打日志
    if (log.isInfoEnabled()) {
        log.info("SubjectCategoryDomainServiceImpl queryCategoryAndLabel, subjectCategoryList:{}", JSON.toJSONString(subjectCategoryList));
    }
    // 先将所有分类转换为BO
    List<SubjectCategoryBO> subjectCategoryBOList = SubjectCategoryConverter.INSTANCE.convertSubjectCategoryToBo(subjectCategoryList);
    // 一次性获取标签信息
    subjectCategoryBOList.forEach(category -> {
        // 从mapping表中根据分类id查询所有标签的id
        SubjectMapping subjectMapping = new SubjectMapping();
        subjectMapping.setCategoryId(category.getId());
        subjectMapping.setIsDeleted(IsDeleteFlagEnum.UN_DELETED.getCode());
        List<SubjectMapping> subjectMappings = subjectMappingService.queryLabelId(subjectMapping);
        // 抽取所有的标签id
        List<Long> labelIdList = subjectMappings.stream().map(SubjectMapping::getLabelId).collect(Collectors.toList());
        // 得到所有的标签
        List<SubjectLabel> subjectLabelList = subjectLabelService.batchQueryById(labelIdList);
        // 将标签转换为BO
        List<SubjectLabelBO> subjectLabelBOList = SubjectLabelConverter.INSTANCE.convertSubjectLabelToBo(subjectLabelList);
        // 为这个分类设置标签
        category.setLabelBOList(subjectLabelBOList);
    });
    return subjectCategoryBOList;
}
4.DTO和BO增加标签字段
1.SubjectCategoryDTO.java

image-20240611162325818

2.SubjectCategoryBO.java

image-20240611162343060

5.测试
1.接口设计

image-20240611162411692

2.测试

image-20240611162426995

7.用户权限获取

1.PermissionController.java
/**
 * 获取权限信息
 * @param userName
 * @return
 */
@RequestMapping("getPermission")
public Result<Boolean> getPermission(String userName) {
    try {
        // 日志
        if (log.isInfoEnabled()) {
            log.info("PermissionController getPermission userName:{}", userName);
        }
        // 参数校验
        Preconditions.checkArgument(StringUtils.isNotBlank(userName), "用户名不能为空");
        return Result.ok(authPermissionDomainService.getPermission(userName));
    } catch (Exception e) {
        // error日志
        log.error("PermissionController getPermission error:{}", e.getMessage(), e);
        return Result.fail("获取权限信息失败");
    }
}
2.AuthPermissionDomainService.java
/**
 * 获取权限
 * @param userName
 * @return
 */
List<String> getPermission(String userName);
3.AuthPermissionDomainServiceImpl.java
/**
 * 根据用户名获取权限,从redis中获取
 * @param userName
 * @return
 */
@Override
public List<String> getPermission(String userName) {
    String permissionKey = redisUtil.buildKey(authPermissionPrefix, userName);
    String permissionValue = redisUtil.get(permissionKey);
    if (permissionValue == null) {
        return Collections.emptyList();
    }
    // 如果是权限列表,就反序列化为权限类型的
    List<AuthPermission> authPermissionList = new Gson().fromJson(permissionValue, new TypeToken<List<AuthPermission>>() {
    }.getType());
    // 得到permissionKey,放到authList中
    List<String> authList = authPermissionList.stream().map(AuthPermission::getPermissionKey).collect(Collectors.toList());
    return authList;
}
4.测试

image-20240611184541081

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1990452.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C语言:复读机2种写法(输入什么就输出什么)

&#xff08;1&#xff09;题目&#xff1a;输入什么内容&#xff0c;输出就是什么内容&#xff0c;遇到"#"为止。输入一个随便的字符 &#xff08;2&#xff09;代码&#xff1a; 【1】getchar()和putchar() #include "stdio.h"int main() {char ch;pr…

基于Python的Scrapy爬虫的个性化书籍推荐系统【Django框架、超详细系统设计原型】

文章目录 有需要本项目的代码或文档以及全部资源&#xff0c;或者部署调试可以私信博主项目介绍系统分析系统设计展示总结 有需要本项目的代码或文档以及全部资源&#xff0c;或者部署调试可以私信博主 项目介绍 近年来&#xff0c;随着互联网的蓬勃发展&#xff0c;企事业单…

linux docker 仓库拉取失败问题(已解决)

仓库拉取失败问题 前言错误示例解决注意 前言 我在服务器拉取仓库的镜像时&#xff0c;出现如下错误&#xff1a; Error response from daemon: Get “http://192.168.37.51:8050/v2/”: net/http: HTTP/1.x transport connection broken: malformed HTTP response “\x15\x0…

数据结构_study(七)

查找 查找表&#xff1a;同一类型的数据元素构成的集合 关键字&#xff08;键值&#xff09;&#xff1a;数据元素中某个数据项的值&#xff0c;用来标识数据元素 主关键字&#xff1a;唯一标识一个记录的关键字 次关键字&#xff1a;可以标识多个数据元素的关键字 查找&…

浅析DNS服务器:办公网DNS的架构思路分享

办公网 DNS 不同于业务网 DNS&#xff0c;主要承担的是企业或组织机构内部员工的日常办公的域名解析需求。比如日常的办公系统的访问、通过第三方认证系统进行身份认证才能访问办公系统资源、办公PC需要进行AD域控管理等……由于此办公网DNS服务器的设计需求也不尽相同&#xf…

【脚本说明撰写markdown】如何基于VScode 撰写使用说明文档,及格式转换.md、.html、.pdf格式

如何基于VScode 撰写使用说明文档&#xff0c;及格式转换.md、.html、.pdf格式 下载插件 下载markdown 进入vscode后&#xff0c;进入扩展工具&#xff08;快捷键ctrlshiftX&#xff09;&#xff0c;搜索markdown&#xff0c;选择markdown All in One并安装 安装Markdown Pr…

SolidWorks钣金中如何定义K因子、折弯系数

在使用SolidWorks设计钣金零件时总是会遇到折弯系数、K因子这样的专业名称&#xff0c;不知如何去定义他们的。 在SolidWorks中除了直接指定K因子确定折弯系数之外还可以利用折弯系数表来确定。在折弯系数表中指定钣金零件的折弯系数或折弯扣除数值等&#xff0c;折弯系数表还…

【Material-UI】按钮组:Split Button 详解

文章目录 一、Split Button 概述1. 组件介绍2. 基本用法 二、Split Button 的应用场景1. 提交操作2. 导出操作3. 文件操作 三、Split Button 的样式定制1. 变体&#xff08;Variants&#xff09;2. 颜色&#xff08;Colors&#xff09; 四、Split Button 的优势1. 提升用户体验…

江科大/江协科技 STM32学习笔记P20

文章目录 编码器接口测速定时器有关的库函数Encoder.cmain.c 编码器接口测速 编码器接口的初始化&#xff0c;第一步&#xff0c;RCC开启时钟&#xff0c;开启GPIO和定时器的时钟&#xff0c;第二步&#xff0c;配置GPIO&#xff0c;这里把PA6和PA7配置成输入模式&#xff0c;第…

【环绕字符串中唯一的子字符串】python刷题记录

R4-字符串 动态规划 class Solution:def findSubstringInWraproundString(self, s: str) -> int:dp[0]*26num1#dp初始化dp[ord(s[0])-ord(a)]1for c1,c2 in pairwise(s):if not (ord(c2)-ord(c1)-1)%26:num1else:num1dp[id]max(dp[id : ord(c2)-ord(a)],num)return sum(dp)p…

Java设计模式(适配器模式)

定义 将一个类的接口转换成客户希望的另一个接口。适配器模式让那些接口不兼容的类可以一起工作。 角色 目标抽象类&#xff08;Target&#xff09;&#xff1a;目标抽象类定义客户所需的接口&#xff08;在类适配器中&#xff0c;目标抽象类只能是接口&#xff09;。 适配器类…

笔记小结:《利用Python进行数据分析》之字符串操作(含正则表达式)

目录 字符串对象方法 使用split分割字符串 连接字符串 查找子串 字串计数 替换字串 字符串方法表 正则表达式 分割数量不定的空白符 匹配正则表达式的所有模式 匹配字符串 替换字符串 将字符串分组 带有分组功能的findall pandas矢量化字符串函数 Python能够成…

hongmeng开发

Image图片组件 Text组件 如在两个限定目录里面定义完后&#xff0c;也要在 base牡蛎下去定义一下&#xff0c;不然会报错 TextInput Button Slider 案例 State imageWidth:number30//构建 → 界面build() {Column(){Image($r(app.media.startIcon)).width(this.imageWidth)Te…

帆软填报报表单元格根据其它单元格内容决定另外的单元格可筛选什么值

效果图&#xff1a; 方法有三种&#xff1a; 方法一&#xff1a; 添加链接描述

基于sklearn的机器学习 — 支持向量机(SVM)

支持向量机&#xff08;SVM&#xff1a;support vector machine&#xff09;另一种功能强大、应用广泛的学习算法&#xff0c;可应用于分类、回归、密度估计、聚类等问题。SVM可以看作是感知器&#xff08;可被视为一种最简单形式的前馈神经网络&#xff0c;是一种二元线性分类…

AI在医学领域:使用眼底图像和基线屈光数据来定量预测近视

关键词&#xff1a;深度学习、近视预测、早期干预、屈光数据 儿童近视已经成为一个全球性的重大健康议题。其发病率持续攀升&#xff0c;且有可能演变成严重且不可逆转的状况&#xff0c;这不仅对家庭幸福构成威胁&#xff0c;还带来巨大的经济负担。当前的研究着重指出&#x…

Android Studio新版UI常用设置

新版UI固然好看&#xff0c;但启用后一些常用的功能也被初始化了&#xff0c;下面会说明如何设置一些常用的功能。 一、启用\禁用新版UI Setting -> Appearance & Behavior -> New UI -> Enable new UI 二、展示Git部分的Local Changes窗口 Setting -> Ve…

Leetcode JAVA刷刷站(1)两数之和

一、题目概述 二、思路方向 为了解决这个问题&#xff0c;你可以使用哈希表&#xff08;在Java中通常使用HashMap&#xff09;来存储遍历过的数组元素及其对应的索引。这样&#xff0c;当你遍历数组时&#xff0c;你可以检查target - 当前元素是否已经在哈希表中&#xff0c;如…

SpringBoot(Ⅰ)——HelloWorld和基本打包部署+Pom依赖概述+@SpringBootApplication注解+自动装配原理

前言 如果SSM学的比较好&#xff0c;那么SpringBoot说白了就两件事:约定大于配置和自动装配 SpringBoot不会提供任何的功能拓展&#xff0c;完全依赖我们手动添加 所以SpringBoot的本质是一个依赖脚手架&#xff0c;可以快速集成配置各种依赖 1.1 SpringBoot相关依赖 创建…

SQL注入---时间盲注

目录 1、时间盲注 1.1原理 2、常见函数 2.1延迟函数 2.2相关函数 3、注入流程 3.1判断注入点 3.2测试可注入方式 3.3猜数据库长度 3.4猜数据库名 4、靶场示例&#xff08;less9&#xff09; 4.1判断注入点 4.2猜测数据库长度 4.3猜数据库名 代码&#xff1a; 结…