帝可得项目总结

news/2024/9/23 18:02:36/

业务需求

  1. 区域列表查询中,需要显示每个区域的点位数

(1)同步存储:在区域表中有点位数的字段(冗余字段6.),当点位发生变化时,同步区域表中的点位数。

优点:由于是单表查询操作,查询列表效率最高。

缺点:需要在点位增删改时修改区域表中的数据,有额外的开销,数据也可能不一致在更新点位数据时,如果事务没有正确处理或者系统出现故障(如网络中断、数据库宕机等),可能会导致区域表中的点位数未能及时更新或更新失败,从而造成数据不一致的情况。

(2)关联查询:编写关联查询语句,在mapper 层封装。

优点:实时查询,数据100%正确,不需要单独维护

缺点:SQL语句较复杂,如果数据量大,性能比较低。

SELECT r.*, COUNT(n.id) AS node_count FROM tb_region r LEFT JOIN tb_node n ON r.id = n.region_id GROUP BY r.id;

左外连接(LEFT OUTER JOIN)

左外连接会返回左表(FROM子句中的第一个表)的所有记录,以及右表(JOIN子句中的第二个表)中与左表相匹配的记录。如果右表中没有与左表匹配的记录,则结果集中相应的列将为NULL。

  1. 在点位列表查询中,会关联显示区域、商圈等信息

关联实体:我们会采用Mybatis提供的嵌套查询功能。

MyBatis 嵌套查询就是将原来多表查询中的联合查询语句拆成单个表的查询,再使用mybatis的语法嵌套在一 起,通过定义resultMap和sql语句中的association(一对一或多对一)或collection(一对多)元素来实现嵌套查询。

点位与区域商圈是多对一的关系

货道与商品是多对一

定义一个新的resultMap标签作为selectNodeVoList的xml语句的返回结果

  1. 数据完整性

当我们删除区域或合作商数据时,与之关联的点位数据该如何处理?

RESTRICT(限制):在尝试删除或更新父表中的记录之前,数据库首先检查是否有相关联的子记录存在。如果有,则拒绝执行删除或更新操作,以防止意外丢失数据或破坏数据关系的完整性。这是一种保守策略,确保数据间的引用完整性。

在MYSQL图形化界面-修改表-修改表的删除规则即可

4.错误提示信息统一处理

修改完毕后,如果你尝试进行删除操作,会发现数据库的完整性约束生效了,它会阻止删除操作并给出错误提示。但是,这个错误提示信息可能对于用户来说不够友好,可能会让用户感到困惑。

SpringBoot全局异常处理器

com.dkd.framework.web.exception.GlobalExceptionHandler

5.前端:修改时需要显示创建时间,新建时不需要

使用v-if标签,修改时会回显id而新增时不会。修改时id!= null

  1. 修改区域表时对应的员工表的区域字段也需更改

关系到两张表的操作,使用@Transational注解开启事务

设置 rollbackFor = Exception.class 表示只要方法执行过程中抛出任何异常,都会触发事务回滚。这样可以确保数据的一致性和完整性,避免因异常导致的数据错误。

  1. 日期格式化

 前端

后端

8.小数精度问题

商品价格在java中如果用double会有精确度降低的风险,所以后端返回的价格是以分为单位的int类型,前端展示为元为单位就需要除以100

9.将商品管理展示的商品类型id改为商品类型名称进行展示前端

查询商品类型列表->当商品类型id等于当前选中的id时再进行展示

10.逻辑外键

在删除商品时,需要判断此商品是否被售货机的货道关联,如果关联则无法删除(外键)

物理外键约束(在字段后面加上属性):通过在子表中添加一个外键列和约束,该列与父表的主键列相关联,由数据库维护数据的一致性和完整性

逻辑外键约束:在不使用数据库外键约束的情况下,通常在应用程序中通过代码来检查和维护数据的一致性和完整性

使用逻辑外键约束的原因(sku_id = 商品表的id):我们在新增售货机货道记录时暂不指定商品,货道表中的SKU_ID有默认值0,而这个值在商品表中并不存在,那么物理外键约束会阻止货道表的插入,因为0并不指向任何有效的商品记录

在实际业务场景中,有时需要先创建货道记录,但暂时不确定具体对应哪个商品。
为了方便操作,可以将 SKU_ID 设置为默认值 0,表示“暂未分配商品”。

删除商品方法前面加上对商品关联货道的查询,即根据商品id查询货道数量,如果大于0则抛出异常

  1. 批量新增(技术5.)

public List<T> importExcel(InputStream is)

1.接收一个输入流 is 作为参数。

2.尝试调用 importExcel 方法,并传入输入流和索引 0(表示首张工作表)。

12.DTO转VO可以用stream的map,最后collect收集

13.用于接收前端传过来的各种参数工单类型

运营和运营工单共享一套后端接口,通过特定的查询条件区分工单类型,并在返回结果中包含工单类型的详细信息

所有的类都继承BaseEntity

接收的参数为map集合,key的名称为isRepair

14.用户登录流程后端)(技术点9.

1.验证码校验

·检查系统是否开启验证码功能。

·若开启,则从Redis缓存redisCache中获取对应uuid(唯一标识)的验证码。并从缓存中删除

·如果验证码已过期或不存在,记录登录失败信息并抛出异常。

·比较用户输入的验证码与实际验证码,不一致时记录失败信息并抛出异常。

  1. 登录前置校验

·检查用户名和密码是否为空,若空则记录登录信息并抛出异常。

·验证密码长度是否在规定范围内,否则记录信息并抛出异常。

·检查用户名长度是否符合要求,不符合则记录信息并抛出异常。

·校验客户端IP地址是否在黑名单中,若在黑名单,则记录登录失败信息 并抛出异常。

  1. ss认证管理器用户校验

·使用 UsernamePasswordAuthenticationToken 对象进行用户认证,放入AuthenticationContextHolder中(底层是ThreadLocal,来为每个线程提供独立的身份验证信息存储空间。)

若认证失败,记录日志并抛出异常;

认证成功后记录成功登录信息,并依据认证信息记录用户登录详情;

4.登陆成功,记录日志。

5.更新登录用户信息

6.生成token,并将登录用户信息缓存在redis中。

7.返回token

  1. 获取用户角色和权限

查询该用户权限(菜单)集合用set集合,一个用户可能有多个角色,多个角色的权限可能有重复的

16.数据权限

我们有一个系统登录日志,里面记录了所有用户的登录信息。

但是,并不是所有人都应该看到所有的日志数据。所以,我们需要根据用户的角色来控制他们能查看的数据范围。

17.跨域

在前端开发中,跨域是一个常见的问题,特别是在使用Vue框架进行开发时。跨域是指在浏览器中发送的AJAX请求的目标地址与当前页面的地址不在同一个域下,这会导致浏览器的同源策略产生限制,从而阻止了跨域请求的发送。然而,我们可以通过代理服务器来解决这个问题。

代理服务器是位于客户端和目标服务器之间的一台服务器,它接收客户端发送的请求,并将请求转发给目标服务器。通过在代理服务器上进行请求转发,可以绕过浏览器的同源策略限制,从而实现跨域请求。

技术点

  1. MyBatis 嵌套查询

MyBatis 嵌套查询就是将原来多表查询中的联合查询语句拆成单个表的查询,再使用mybatis的语法嵌套在一 起,通过定义resultMap和sql语句中的association(一对一或多对一)或collection(一对多)元素来实现嵌套查询。

主sql语句为前者

  1. SpringBoot全局异常处理器

SQLIntegrityConstraintViolationException是Java中的一个异常类,这个类通常用于表示SQL数据库操作中的完整性约束违反异常

例如:外键约束、唯一约束等。当数据库操作违反了这些约束时,就会抛出这个异常。

这个错误是由于外键约束导致的。它表明在删除或更新父表的行时,存在外键约束,子表中的相关行会受到影响。

是因为在删除tb_region表中的行时,tb_node表中的region_id外键约束会阻止操作。

如果你在使用Spring框架进行数据库操作,可能会先遇到DataIntegrityViolationException,它是对SQLIntegrityConstraintViolationException的一个更高层次的抽象,旨在提供一种更加面向应用的错误表示。

而SQLIntegrityConstraintViolationException是更底层的异常,直接来源于数据库驱动,包含更多底层数据库相关的细节。

在实际开发中,推荐捕获并处理DataIntegrityViolationException,因为它更符合Spring应用的异常处理模式,同时也可以通过其内部的cause(原因)属性来获取具体的SQLIntegrityConstraintViolationException,进而获取详细的错误信息。

3.MtBatis注解

1.@Param: 当方法中有多个参数时,使用 @Param 可以为每个参数指定一个名字。这在 SQL 映射文件中引用参数时非常有用,特别是当需要传递多个参数给 SQL 语句时。

4.x-file-storage

一行代码将文件存储到本地、阿里云 OSS、华为云 OBS等

5.EasyExcel

基于JAVA的EXCEL处理工具

easyexcel重写了poi对07版Excel的解析,一个3M的excel用POI sax解析依然需要100M左右内存,改用easyexcel可以降低到几M,并且再大的excel也不会出现内存溢出

  1. Redis计数器

自动生成工单编号-使用redis的计数器

redisTemplate.opsForValue().set(key, 1, Duration.ofDays(1));

使用opsForValue()方法获取操作字符串值的对象。
调用set方法存储值1。
使用Duration.ofDays(1)设置键的有效期为一天。

dateStr+StrUtil.padPre(redisTemplate.opsForValue().increment(key).toString(),4,'0');

从Redis中获取指定键的值,并对其执行自增操作。
将自增后的值转换为字符串。
在字符串左侧填充‘0’,确保总长度为4位。
将填充后的字符串与日期字符串(dateStr)拼接后返回。

7.Knife4j

如果不习惯使用swagger可以使用前端UI的增强解决方案knife4j,对比swagger相比有以下优势,友好界面,离线文档,接口排序,安全控制,在线调试,文档清晰,注解增强,容易上手。

TaskDetailsController添加swagger注解

@Api: 用于类级别,描述API的标签和描述。

@ApiOperation: 用于方法级别,描述一个HTTP操作。

@ApiParam: 用于参数级别,描述请求参数。

注意:若依框架的AjaxResult由于继承自HashMap导致与Swagger和knife4j不兼容的问题,选择替换返回值类型为R<>以解决Swagger解析问题,减少整体改动量。

8.Velocity模版引擎

实体类支持Lombok@Data,Controller类支持Swagger(@Apioperation)

(导入坐标,修改模板代码)

Velocity是一个基于Java的模板引擎,可以通过特定的语法获取在java对象的数据 , 填充到模板中,从而实现界面和java代码的分离 !

Velocity中的变量有两类

在模板中定义变量: #set开头,比如 #set($name = "velocity")

获取变量的的值: $name 或者 ${name}

9.RBAC权限控制

1.SpringSecurity配置:SecurityConfig类上加上@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)

开启方法级别的权限控制

方法的controller层加上@PreAuthorize("@ss.hasPermi('manage:taskType:list')")

@PreAuthorize:Spring Security注解,用于在执行方法前检查用户权限。

@ss.hasPermi:自定义权限校验方法,验证用户是否具有指定权限。

ss:Spring容器管理的一个bean

 @PreAuthorize 是 Spring Security 框架中提供的一个安全注解,用于实现基于注解的访问控制。它允许开发者在方法级别上声明特定的安全约束,以确保只有满足指定条件的用户才能调用该方法

- 当 @PreAuthorize 注解被应用于某个方法时,Spring Security 在该方法执行前会先对当前认证的用户进行权限检查。如果检查通过,方法调用得以继续;否则,框架会抛出相应的权限异常(如 AccessDeniedException),阻止方法执行。

2.如果有些接口是不需要验证权限可以公开访问的,这个时候就需要我们给接口放行。

使用注解方式,只需要在Controller的类或方法上加入@Anonymous该注解即可

10.异步任务管理器

主要用于处理一些不需要即时返回结果的后台任务,从而提高应用程序的整体性能

// 多线程执行任务me()创建单例对象(饿汉式)
AsyncManager.me().execute(AsyncFactory.createTimerTask());

若依异步任务管理器是一个单例对象使用了线程池+异步工厂(产生任务用)

1、 AsyncManager.me()获取AsyncManager对象

2、调用execute方法,执行TimerTask任务(记录登录日志),它实现了runnable接口,由线程Thread去执行

3、execute方法内部调用ScheduledExecutorService异步操作任务调度线程池的schedule方法用于延迟10毫秒执行一个任务

11.操作日志

在需要被记录日志的controller方法上添加@Log注解

若依操作日志使用了自定义注解+AOP切面+异步任务管理器

通过实现AOP切面编程,对目标方法进行拦截(标注Log注解的方法),实现了操作日志的自动记录

异步任务管理器来将任务(记录操作日志到数据库)交给线程池来完成

  1. 定时任务

13.数据权限

在系统中,权限的分配和控制主要依赖于角色。每个角色可以被赋予不同的菜单权限和数据权限,用户则通过他们的角色来继承这些权限,进而决定他们能访问哪些系统资源。

目前,系统支持以下五种数据权限类型:

全部数据权限:无限制访问所有数据,相当于拥有最高权限的通行证。

自定数据权限:用户可以根据自己的需求设定访问特定数据的规则。

部门数据权限:只能访问自己所在部门的数据,限制在本部门范围内。

部门及以下数据权限:可以访问自己部门及下属部门的数据,适用于管理层级。

仅本人数据权限:只能访问和操作自己的数据,保障个人隐私和数据隔离。

在需要数据权限控制方法上添加@DataScope注解,其中d和u用来表示表的别名

在mybatis查询底部标签添加数据范围过滤(其作用就是相当于在一个 select 语句后面拼接一个 and 条件语句,来实现查询限制)

若依数据权限底层使用了自定义注解+AOP切面+SQL拼接

通过实现AOP编程,对目标方法进行拦截(标注DataScope 注解的方法),实现了构建数据范围SQL过滤条件

仅实体继承`BaseEntity`才会进行处理,`SQL`语句会存放到`BaseEntity`对象中的`params`属性中,然后在`xml`中通过`${params.dataScope}`获取拼接后的语句。


http://www.ppmy.cn/news/1529434.html

相关文章

RHEL7(RedHat红帽)软件安装教程

目录 1、下载RHEL7镜像 2、安装RedHat7 注&#xff1a;如果以下教程不想看&#xff0c;可以远程控制安装V:OYH-Cx330 【风险告知】 本人及本篇博文不为任何人及任何行为的任何风险承担责任&#xff0c;图解仅供参考&#xff0c;请悉知&#xff01;本次安装图解是在一个全新的演…

【人工智能学习之卷积神经网络发展简述】

【人工智能学习之卷积神经网络发展简述】 早期探索&#xff08;1960s-1980s&#xff09;初步发展&#xff08;1990s-2000s&#xff09;快速增长&#xff08;2010s&#xff09;当前进展&#xff08;2010s末-2020s&#xff09;未来趋势总结 卷积神经网络&#xff08;Convolutiona…

[论文笔记]MRRNET

这是一篇河大的论文 感觉跟SANET很像 摘要 摘要&#xff1a;随着物联网&#xff08;IoT&#xff09;的大规模部署&#xff0c;道路场景中实时感知和环境理解的需求变得越来越迫切。 同时&#xff0c;语义分割作为像素级场景解析得到了广泛的研究。 然而&#xff0c;资源有限…

解决 TortoiseGitPlink Fatal Error:深入解析

解决 TortoiseGitPlink Fatal Error&#xff1a;深入解析 在 Windows 平台上&#xff0c;开发者使用 Git 和 TortoiseGit 进行版本控制时&#xff0c;有时会遇到 TortoiseGitPlink Fatal Error。该错误通常是在推送/拉取代码时&#xff0c;客户端未能提供正确的 SSH 密钥。 1…

11年408考研真题解析-计算机网络

第一题&#xff1a; 解析&#xff1a;网络层虚电路服务和数据报服务 传输服务只有&#xff1a;有连接可靠和无连接不可靠两种&#xff0c;直接排除BC。 网络层指的是IP协议&#xff0c;由图二可知&#xff1a;运输层&#xff0c;网际层&#xff0c;网络接口层唯一有连接可靠的协…

开放标准如何破解企业数字化与可持续发展的困境:The Open Group引领生态系统架构创新

应对数字化与可持续发展的双重挑战&#xff0c;开放标准是关键 在当今快速变化的商业环境中&#xff0c;企业不仅需要通过数字化转型提升竞争力&#xff0c;还面临日益严格的可持续发展要求。开放标准正在成为企业破解这一双重挑战的核心工具。The Open Group 2024生态系统架构…

某省公共资源交易电子平台爬虫逆向

目标网站 aHR0cHM6Ly9nZ3p5ZncuZnVqaWFuLmdvdi5jbi9pbmRleC9uZXc 一、抓包分析 1、请求参数加密 二、逆向分析 搜索定位加密参数位置 这里生成&#xff0c;扣取响应代码到本地即可 2、响应数据加密解密 xhr断点 向下跟栈&#xff0c;直到出现加密数据 解密函数 本地获取数据…

【QT】系统-下

欢迎来到Cefler的博客&#x1f601; &#x1f54c;博客主页&#xff1a;折纸花满衣 &#x1f3e0;个人专栏&#xff1a;QT 目录 &#x1f449;&#x1f3fb;QTheadrun() &#x1f449;&#x1f3fb;QMutex&#x1f449;&#x1f3fb;QWaitCondition&#x1f449;&#x1f3fb;Q…