目录
一、项目介绍
技术选型:SpringBoot+MyBatisPlus+Flowable+SpringSecurity+Thymeleaf+MYSQL+HPlus
二、项目搭建
2.1、创建工程
第一步:创建Maven项目,你也可以直接创建SpringBoot项目
第二步:修改pom.xml文件
将如下代码依赖放入pom.xml文件中
<properties>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<spring-boot.version>2.3.7.RELEASE</spring-boot.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- 添加MyBatisPlus的依赖 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.1</version>
</dependency>
<!-- MySQL数据 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- druid 连接池-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.14</version>
</dependency>
<!-- MyBatisPlus 代码生成器 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.5.2</version>
</dependency>
<!-- 在MyBatisPlus的代码生成器中我们需要导入 freemarker的依赖 -->
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
<!-- JSR 303 的依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.3.7.RELEASE</version>
<configuration>
<mainClass>com.wanshu.wanshu.WanshuApplication</mainClass>
</configuration>
<executions>
<execution>
<id>repackage</id>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
第三步:添加application.properties
resources下,创建application.properties文件。
# 应用名称
spring.application.name=wanshu
# 应用服务 WEB 访问端口
server.port=8080
spring.datasource.driverClassName=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/wanshu?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=true&nullCatalogMeansCurrent=true
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
mybatis-plus.mapper-locations=classpath:mapper/*.xml
# 设置日志
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
# 配置数据库的统一前缀
mybatis-plus.global-config.db-config.table-prefix=sys_
# 设置全局的id自增策略
mybatis-plus.global-config.db-config.id-type=auto
# 配置逻辑删除
mybatis-plus.global-config.db-config.logic-delete-field=is_deleted
mybatis-plus.global-config.db-config.logic-delete-value=1
mybatis-plus.global-config.db-config.logic-not-delete-value=0
# THYMELEAF (ThymeleafAutoConfiguration)
# 开启模板缓存(默认值: true )
spring.thymeleaf.cache=false
# 检查模板是否存在,然后再呈现
spring.thymeleaf.check-template=true
# 检查模板位置是否正确(默认值 :true )
spring.thymeleaf.check-template-location=true
#Content-Type 的值(默认值: text/html )
spring.thymeleaf.content-type=text/html
# 开启 MVC Thymeleaf 视图解析(默认值: true )
spring.thymeleaf.enabled=true
# 模板编码
spring.thymeleaf.encoding=UTF-8
# 要被排除在解析之外的视图名称列表,⽤逗号分隔
spring.thymeleaf.excluded-view-names=
# 要运⽤于模板之上的模板模式。另⻅ StandardTemplate-ModeHandlers( 默认值: HTML5)
spring.thymeleaf.mode=HTML5
# 在构建 URL 时添加到视图名称前的前缀(默认值: classpath:/templates/ )
spring.thymeleaf.prefix=classpath:/templates/
# 在构建 URL 时添加到视图名称后的后缀(默认值: .html )
spring.thymeleaf.suffix=.html
第四步:resources下创建static和templates文件
第五步:创建启动类
你可以起名叫App.java,我这里是项目名+Application.java,文件放在java中你的包下。
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class WanshuApplication {
public static void main(String[] args) {
SpringApplication.run(WanshuApplication.class,args);
}
}
第六步:创建Mybatis分页插件配置类,并增加扫描注解
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
@MapperScan(basePackages = "com.wanshu.mapper")
public class MyBatisPlusConfiguration {
/**
* 新的分页插件,一缓和二缓遵循mybatis的规则,
* 需要设置 MybatisConfiguration#useDeprecatedExecutor = false 避免缓存出现问题(该属性会在旧插件移除后一同移除)
*/
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return interceptor;
}
}
2.2、导入数据库脚本
这里想要脚本的私心我...
2.3、Mybatis逆向工程生成代码
第一步:创建配置类
import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.config.OutputFile;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
import java.util.Collections;
public class MyFastGeneratorConfiguration {
public static void main(String[] args) {
FastAutoGenerator.create("jdbc:mysql://localhost:3306/wanshu?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=true"
, "root", "root")
.globalConfig(builder -> {
builder.author("clay") // 设置作者
//.enableSwagger() // 开启 swagger 模式
.fileOverride() // 覆盖已生成文件
.outputDir("D://wanshu"); // 指定输出目录
})
.packageConfig(builder -> {
builder.parent("com.wanshu") // 设置父包名
.pathInfo(Collections.singletonMap(OutputFile.xml, "D://wanshu")); // 设置mapperXml生成路径
})
.strategyConfig(builder -> {
builder.addInclude("sys_user","sys_role","sys_user_role","sys_menu","sys_role_menu","sys_oplog") // 设置需要生成的表名
.addTablePrefix("sys_"); // 设置过滤表前缀
})
.templateEngine(new FreemarkerTemplateEngine()) // 使用Freemarker引擎模板,默认的是Velocity引擎模板
.execute();
}
}
右键运行main方法,D盘目录下生成代码。
将生成好的controller、entity、mapper、service代码都复制到我们的工程下。
将生成好的.xml文件复制到resources/mapper下。
2.4、整合HPlus资源文件
没有HPlus资源的私信我...
第一步:在resources/templates下创建index.html
我们随便写句代码测试一下...
注意:这里我们测试前先把pom.xml文件里的security依赖注释掉。
第二步:将HPlus中的login_v2.html文件里的代码复制到我们刚创建的index.html文件中
第三步:在<html>标签中加入如下代码。
xmlns:th="http://www.thymeleaf.org"
第四步:将HPlus的静态文件复制到resources/static下
2.5、视图映射处理
我们将index.html名改为login.html
这是因为我们的页面.html文件是不允许用户直接访问的,需要控制器来进行转发。
创建配置类:
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class MyWebViewConfiguration implements WebMvcConfigurer {
/**
* 视图映射器
* @param registry
*/
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/login.html").setViewName("/login");
registry.addViewController("/home.html").setViewName("/home");
}
}
这时我们再次访问:
2.6、home页面
第一步:创建home.html页面,将HPlus中的index.html代码复制过来
第二步:因为我们上一节在配置类已经配置了/home,所以直接访问即可
第三步:删一删home.html的代码,左侧菜单只留主页和统计图表。
删除后,我们ctrl+F9编译下。
2.7、认证功能
首先我们pom.xml已经引入了SpringSecurity的依赖。
第一步:编写账号认证的Service类
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.wanshu.entity.User;
import com.wanshu.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
/**
* 账号认证的Service
*/
@Service
public class UserDetailsServiceImpl implements UserDetailsService {
@Autowired
IUserService userService;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
UserDetails userDetails = null;
if(StringUtils.isNotBlank(username)){
User user = new User();
user.setUserName(username);
// 做账号的认证
List<User> loginUsers = userService.queryByUser(user);
if(loginUsers != null && loginUsers.size() == 1){
// 登录返回的用户
User authUser = loginUsers.get(0);
// 当前登录用户的角色
List<SimpleGrantedAuthority> authorities = new ArrayList<>();
authorities.add(new SimpleGrantedAuthority("ROLE_ADMIN"));
// 说明登录成功
userDetails = new org.springframework.security.core.userdetails.User(
authUser.getUserName(),
authUser.getPassword(),
true,
true,
true,
true,
authorities
);
}
}
return userDetails;
}
public static void main(String[] args) {
BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
System.out.println("encoder.encode(\"123\") = " + encoder.encode("123"));
}
}
第二步:IUserService和实现类编写查询用户接口(根据username查询)
public interface IUserService extends IService<User> {
List<User> queryByUser(User user);
}
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {
@Override
public List<User> queryByUser(User user) {
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
if(user != null){
// 根据账号查询相关信息
queryWrapper.eq(StringUtils.isNotBlank(user.getUserName()),"user_name",user.getUserName());
}
return this.baseMapper.selectList(queryWrapper);
}
}
2.8、登录与注销
第一步:创建SpringSecurity配置类
import com.wanshu.service.impl.UserDetailsServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
@Configuration
@EnableWebSecurity
public class MySpringSecurityConfiguration extends WebSecurityConfigurerAdapter {
@Autowired
UserDetailsService userDetailsService;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService)
.passwordEncoder(new BCryptPasswordEncoder());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
// 放过静态资源通过,包括login.html
.antMatchers("/login.html","/css/**","/js/**","/img/**","/fonts/**","/docs/**")
.permitAll()
.antMatchers("/**")
.hasAnyRole("ADMIN")
.anyRequest()
.authenticated()
// 登录
.and()
.formLogin()
.loginPage("/login.html")
.loginProcessingUrl("/loginUrl") // 登录表单提交的认证地址
.defaultSuccessUrl("/home.html")
.permitAll()
.and()
.logout()
.and()
.csrf().disable()
// 针对 布局内嵌禁用放开
.headers().frameOptions().disable();
}
}
首先,使用http.authorizeRequests()方法配置HTTP请求的授权规则。
使用.antMatchers("/login.html","/css/**","/js/**","/img/**","/fonts/**","/docs/**")指定一些静态资源的路径,如登录页面、CSS、JS、图片、字体等。
使用.permitAll()方法将上述静态资源放行,不需要进行任何权限验证。
使用.antMatchers("/**")指定所有其他请求路径。
使用.hasAnyRole("ADMIN")指定只有拥有"ADMIN"角色的用户才能访问这些路径。
使用.authenticated()方法要求所有请求都需要进行身份验证。
使用.formLogin()方法配置基于表单的登录认证。
使用.loginPage("/login.html")指定登录页面的路径。
使用.loginProcessingUrl("/loginUrl")指定登录表单提交的认证地址。
使用.defaultSuccessUrl("/home.html")指定登录成功后要跳转的页面。
使用.permitAll()方法放行登录页面和认证地址,不需要进行任何权限验证。
使用.logout()方法配置退出登录的处理。
使用.csrf().disable()禁用CSRF保护。
使用.headers().frameOptions().disable()禁用内嵌页面的保护。
第二步:修改login.html页面代码
第三步:将User实体类中创建时间与修改时间字段类型改为Date
第四步:启动服务访问,用admin/123进行登录
第五步:home.html增加注销功能
三、用户管理
3.1、静态资源处理
第一步:修改home.html左侧菜单名称
第二步:templates下创建sys/user和sys/role文件夹
第三步:templates/user下创建user.html
将HPlus下的table_basic.html文件代码复制到user.html中
页面中ctrl+r进行替换,href="替换为href="/,src="替换为src="/
然后把下面两个div删掉
第四步:在UserController中定义跳转页面
@Controller
@RequestMapping("/user")
public class UserController {
@GetMapping("/list")
public String list() {
return "sys/user/user";
}
}
第五步:在home.html中把用户管理href修改一下
3.2、用户查询
第一步:controller定义查询方法
@Controller
@RequestMapping("/user")
public class UserController {
@Autowired
IUserService userService;
@GetMapping("/list")
public String list(@RequestParam(value = "key", required = false) String key, Model model) {
// 查询出所有的用户数据
List<User> list = userService.searchUser(key);
model.addAttribute("list",list);
model.addAttribute("key",key);
return "sys/user/user";
}
}
第二步:IUserService定义接口和实现类
List<User> searchUser(String key);
@Override
public List<User> searchUser(String key) {
QueryWrapper<User> qw = new QueryWrapper<>();
qw.like(StringUtils.isNotBlank(key), "user_name", key).or().like(StringUtils.isNotBlank(key), "nick_name", key);
return this.baseMapper.selectList(qw);
}
第三步:修改user.html代码
<tr th:each="user:${list}">
<td>
<input type="checkbox" checked class="i-checks" name="input[]">
</td>
<td>[[${user.id}]]</td>
<td>[[${user.userName}]]</td>
<td>[[${user.niceName}]]</td>
<td>[[${user.accountType}]]</td>
<td>[[${user.accountState}]]</td>
<td><a href="/table_basic.html#"><i class="fa fa-check text-navy"></i></a>
</td>
</tr>
将如下四个按钮放入div中
<a class="btn btn-success">
<i class="fa fa-plus"></i> 新增
</a>
<a class="btn btn-primary single disabled">
<i class="fa fa-edit"></i> 修改
</a>
<a class="btn btn-danger multiple disabled">
<i class="fa fa-remove"></i> 删除
</a>
<a class="btn btn-warning">
<i class="fa fa-download"></i> 导出
</a>
第四步:测试
再试试模糊查询,我们输入user
3.3、404页面与首页处理
现在的首页是404错误。
第一步:将404.html和500.html放入templates/error下
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>H+ 后台主题UI框架 - 404 页面</title>
<meta name="keywords" content="H+后台主题,后台bootstrap框架,会员中心主题,后台HTML,响应式后台">
<meta name="description" content="H+是一个完全响应式,基于Bootstrap3最新版本开发的扁平化主题,她采用了主流的左右两栏式布局,使用了Html5+CSS3等现代技术">
<link rel="shortcut icon" href="/favicon.ico"> <link href="/css/bootstrap.min.css?v=3.3.7" rel="stylesheet">
<link href="/css/font-awesome.css?v=4.4.0" rel="stylesheet">
<link href="/css/animate.css" rel="stylesheet">
<link href="/css/style.css?v=4.1.0" rel="stylesheet">
</head>
<body class="gray-bg">
<div class="middle-box text-center animated fadeInDown">
<h1>404</h1>
<h3 class="font-bold">页面未找到!</h3>
<div class="error-desc">
抱歉,页面好像去火星了~
<form class="form-inline m-t" role="form">
<div class="form-group">
<input type="email" class="form-control" placeholder="请输入您需要查找的内容 …">
</div>
<button type="submit" class="btn btn-primary">搜索</button>
</form>
</div>
</div>
<!-- 全局js -->
<script src="/js/jquery.min.js?v=2.1.4"></script>
<script src="/js/bootstrap.min.js?v=3.3.7"></script>
<script type="text/javascript" src="/http://tajs.qq.com/stats?sId=9051096" charset="UTF-8"></script>
<!--统计代码,可删除-->
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>H+ 后台主题UI框架 - 500错误</title>
<meta name="keywords" content="H+后台主题,后台bootstrap框架,会员中心主题,后台HTML,响应式后台">
<meta name="description" content="H+是一个完全响应式,基于Bootstrap3最新版本开发的扁平化主题,她采用了主流的左右两栏式布局,使用了Html5+CSS3等现代技术">
<link rel="shortcut icon" href="/favicon.ico"> <link href="/css/bootstrap.min.css?v=3.3.7" rel="stylesheet">
<link href="/css/font-awesome.css?v=4.4.0" rel="stylesheet">
<link href="/css/animate.css" rel="stylesheet">
<link href="/css/style.css?v=4.1.0" rel="stylesheet">
</head>
<body class="gray-bg">
<div class="middle-box text-center animated fadeInDown">
<h1>500</h1>
<h3 class="font-bold">服务器内部错误</h3>
<div class="error-desc">
服务器好像出错了...
<br/>您可以返回主页看看
<br/><a href="/index.html" class="btn btn-primary m-t">主页</a>
</div>
</div>
<!-- 全局js -->
<script src="/js/jquery.min.js?v=2.1.4"></script>
<script src="/js/bootstrap.min.js?v=3.3.7"></script>
<script type="text/javascript" src="/http://tajs.qq.com/stats?sId=9051096" charset="UTF-8"></script>
<!--统计代码,可删除-->
</body>
</html>
第二步:测试,刷新一下首页
第三步:创建index_v1.html放到templates下作为首页
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<!--360浏览器优先以webkit内核解析-->
<title>H+ 后台主题UI框架 - 主页示例</title>
<link rel="shortcut icon" href="favicon.ico" />
<link href="/css/bootstrap.min.css?v=3.3.7" rel="stylesheet" />
<link href="/css/font-awesome.css?v=4.4.0" rel="stylesheet" />
<link href="/css/animate.css" rel="stylesheet" />
<link href="/css/style.css?v=4.1.0" rel="stylesheet" />
</head>
<body class="gray-bg">
<div class="row border-bottom white-bg dashboard-header">
<div class="col-sm-12">
<blockquote class="text-warning" style="font-size: 14px;">
婉舒管理系统
<br />SpringBoot,MyBatisPlus,SpringSecurity,HPlus,Bootstrap....
<br />完善的认证授权体系…
<br />工作流引擎应用(Flowable,Activiti)…………
<h4 class="text-danger">来吧,看看吧</h4>
</blockquote>
</div>
<div class="col-sm-3">
<h2>Hello,Guest</h2>
<small>课件资料请扫描以下二维码:</small>
<br />
<br />
<img src="/img/boge.jpg" width="100%" style="max-width: 264px;" />
<br />
</div>
<div class="col-sm-5">
<h2>
婉舒管理系统
</h2>
<p>
在认证授权体系完善后,我们可以在这个基础上可以做CRM,OA等各种后台管理系统
</p>
</div>
<div class="col-sm-4">
</div>
</div>
<!-- 全局js -->
<script src="/js/jquery.min.js?v=2.1.4"></script>
<script src="/js/bootstrap.min.js?v=3.3.7"></script>
<script src="/js/plugins/layer/layer.min.js"></script>
<!-- 自定义js -->
<script src="/js/content.js"></script>
<!-- 欢迎信息 -->
<script src="/js/welcome.js"></script>
</body>
</html>
3.4、用户新增
弹出框
第一步:user.html修改代码
将如下代码复制到user.html中:
<div id="modal-form" class="modal fade" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-body">
<div class="row">
<div class="col-sm-6 b-r">
<h3 class="m-t-none m-b">登录</h3>
<p>欢迎登录本站(⊙o⊙)</p>
<form role="form">
<div class="form-group">
<label>用户名:</label>
<input type="email" placeholder="请输入用户名" class="form-control">
</div>
<div class="form-group">
<label>密码:</label>
<input type="password" placeholder="请输入密码" class="form-control">
</div>
<div>
<button class="btn btn-sm btn-primary pull-right m-t-n-xs" type="submit"><strong>登录</strong>
</button>
<label>
<input type="checkbox" class="i-checks">自动登录</label>
</div>
</form>
</div>
<div class="col-sm-6">
<h4>还不是会员?</h4>
<p>您可以注册一个账户</p>
<p class="text-center">
<a href="form_basic.html"><i class="fa fa-sign-in big-icon"></i></a>
</p>
</div>
</div>
</div>
</div>
</div>
</div>
启动服务点击新增按钮测试下:
以后此系统出现404或500错误时,springboot会自动去templates/error下找404.html和500.html。
第二步:修改弹出框代码
将整个弹出框代码替换为:
<div id="modal-form" class="modal fade" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-body">
<div class="row">
<div class="col-sm-12 b-r">
<h3 class="m-t-none m-b">添加用户信息</h3>
<form role="form" action="/user/save" method="post">
<div class="col-md-12 top5">
<div class="form-group ">
<label class="col-sm-3 control-label">用户名:</label>
<div class="col-sm-9">
<input type="text" name="userName" placeholder="请输入用户名" class="form-control">
<span class="help-block m-b-none"></span>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">密码:</label>
<div class="col-sm-9">
<input type="password" name="password" placeholder="请输入密码" class="form-control">
<span class="help-block m-b-none"></span>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">昵称:</label>
<div class="col-sm-9">
<input type="text" name="nickName" placeholder="请输入昵称" class="form-control">
<span class="help-block m-b-none"></span>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">手机号:</label>
<div class="col-sm-9">
<input type="number" name="mobile" placeholder="请输入手机号" class="form-control">
<span class="help-block m-b-none"></span>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">排序序号:</label>
<div class="col-sm-9">
<input type="number" name="orderRank" placeholder="请输入排序序号"
class="form-control">
<span class="help-block m-b-none"></span>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">账号类型:</label>
<div class="col-sm-9">
<select class="form-control" name="account_type">
<option value="1">系统账号</option>
<option value="2">普通账号</option>
</select>
<span class="help-block m-b-none"></span>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">账号状态:</label>
<div class="col-sm-9">
<select class="form-control" name="account_state">
<option value="0">启用</option>
<option value="1">冻结</option>
</select>
<span class="help-block m-b-none"></span>
</div>
</div>
<div>
<button class="btn btn-sm btn-primary pull-right m-t-n-xs" type="submit">
<strong>确定</strong>
</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
完成用户新增功能
第一步:UserController增加新增用户方法
@PostMapping("/save")
public String save(User user){
if(StringUtils.isNotBlank(user.getPassword())){
// 对明文密码加密处理
user.setPassword(WebUtils.passwordEncoder(user.getPassword()));
}
// 设置创建时间
user.setCreateTime(new Date());
// 设置创建的用户 获取当前登录的用户
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
UserDetails userDetails = (UserDetails) authentication.getPrincipal();
user.setCreateUser(userDetails.getUsername());
userService.save(user);
return "redirect:/user/list";
}
第二步:创建utils/WebUtils工具类
public class WebUtils {
/**
* 对密码做加密处理
* @param password
* @return
*/
public static String passwordEncoder(String password){
return new BCryptPasswordEncoder().encode(password);
}
public String loginUserName(){
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
UserDetails userDetails = (UserDetails) authentication.getPrincipal();
return userDetails.getUsername();
}
}
第三步:测试功能
第四步:完善排序
修改UserServiceImpl类的searchUser方法代码:
第五步:测试排序
3.5、删除用户
第一步:user.html增加操作按钮
<td>
<a th:if="!${#strings.equals(user.userName,'admin')}"
th:onclick="'deleteUser('+${user.id}+')'"
href="javascript:void(0)" class="btn btn-danger btn-sm ">
<i class="fa fa-remove"></i> 删除
</a>
</td>
第二步:引入sweetalert插件
<!-- Sweet Alert -->
<link href="/css/plugins/sweetalert/sweetalert.css" rel="stylesheet">
<script src="/js/plugins/sweetalert/sweetalert.min.js"></script>
第三步:添加JQuery代码
function deleteUser(userId) {
swal({
title: "您确定要删除这条信息吗" + userId,
text: "删除后将无法恢复,请谨慎操作!",
type: "warning",
showCancelButton: true,
confirmButtonColor: "#DD6B55",
confirmButtonText: "删除",
closeOnConfirm: false
}, function () {
// 做删除的操作
$.get("/user/deleteUser/" + userId, function (data) {
location.href = "/user/list"
})
});
}
第四步:测试样式
第五步:UserController编写删除用户方法
@GetMapping("/deleteUser/{id}")
@ResponseBody
public String deleteUser(@PathVariable(value = "id",required = true) Integer id){
boolean flag = userService.removeById(id);
return "success";
}
第六步:实现MybatisPlus逻辑删除
首先我们application.properties配置文件有如下配置:
# 配置逻辑删除
mybatis-plus.global-config.db-config.logic-delete-field=is_deleted
mybatis-plus.global-config.db-config.logic-delete-value=1
mybatis-plus.global-config.db-config.logic-not-delete-value=0
在User实体类中的isDeleted变量上增加@TableLogic注解
第七步:测试删除用户功能
3.6、更新用户
第一步:user.html中增加更新用户操作按钮代码
<a th:href="'/user/goUpdateUserPage?id='+${user.id}"
class="btn btn-primary btn-sm ">
<i class="fa fa-edit"></i> 更新
</a>
第二步:UserController编写根据用户ID查询用户信息的方法,用来回显
@GetMapping("/goUpdateUserPage")
public String goUpdateUserPage(@RequestParam(value = "id",required = false) Integer id,
Model model){
if(id != null){
User user = userService.getById(id);
model.addAttribute("user",user);
return "sys/user/userUpdate";
}
return "sys/user/userSave";
}
第三步:增加userUpdate.html文件
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>H+ 后台主题UI框架 - 基础表格</title>
<meta name="keywords" content="H+后台主题,后台bootstrap框架,会员中心主题,后台HTML,响应式后台">
<meta name="description" content="H+是一个完全响应式,基于Bootstrap3最新版本开发的扁平化主题,她采用了主流的左右两栏式布局,使用了Html5+CSS3等现代技术">
<link rel="shortcut icon" href="/favicon.ico">
<link href="/css/bootstrap.min.css?v=3.3.7" rel="stylesheet">
<link href="/css/font-awesome.css?v=4.4.0" rel="stylesheet">
<link href="/css/plugins/iCheck/custom.css" rel="stylesheet">
<link href="/css/animate.css" rel="stylesheet">
<link href="/css/style.css?v=4.1.0" rel="stylesheet">
<!-- Sweet Alert -->
<link href="/css/plugins/sweetalert/sweetalert.css" rel="stylesheet">
<style type="text/css">
</style>
</head>
<body class="gray-bg">
<div class="wrapper wrapper-content animated fadeInRight">
<div class="row">
<div class="col-sm-5">
<div class="ibox float-e-margins">
<div class="ibox-title">
<h5>更新用户</h5>
<div class="ibox-tools">
<a class="collapse-link">
<i class="fa fa-chevron-up"></i>
</a>
<a class="dropdown-toggle" data-toggle="dropdown" href="form_basic.html#">
<i class="fa fa-wrench"></i>
</a>
<ul class="dropdown-menu dropdown-user">
<li><a href="form_basic.html#">选项1</a>
</li>
<li><a href="form_basic.html#">选项2</a>
</li>
</ul>
<a class="close-link">
<i class="fa fa-times"></i>
</a>
</div>
</div>
<div class="ibox-content">
<form class="form-horizontal" action="/user/update" method="post">
<p>欢迎登录本站(⊙o⊙)</p>
<input type="hidden" name="id" th:value="${user.id}">
<input type="hidden" name="errorPath" th:value="'/wanshu/user/goUpdateUserPage?id='+${user.id}">
<div class="form-group">
<label class="col-sm-3 control-label">昵称:</label>
<div class="col-sm-8">
<input type="text" name="nickName" th:value="${user.nickName}" placeholder="昵称" class="form-control">
<span class="help-block m-b-none" th:style="${errors!=null?'color:red':''}"
th:text="${errors!=null?errors.get('nickName'):''}">请输入昵称</span>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">密码:</label>
<div class="col-sm-8">
<input type="password" name="password" placeholder="密码" class="form-control">
<span class="help-block m-b-none" th:style="${errors!=null?'color:red':''}"
th:text="${errors!=null?errors.get('password'):''}">请输入需要修改的密码</span>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">手机号:</label>
<div class="col-sm-8">
<input type="text" name="mobile" th:value="${user!=null?user.mobile:''}" placeholder="手机号" class="form-control">
<span class="help-block m-b-none" th:style="${errors!=null?'color:red':''}"
th:text="${errors!=null?errors.get('mobile'):''}">请输入手机号</span>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">账号类型</label>
<div class="col-sm-8">
<select class="form-control m-b" name="accountType">
<option value="1" th:selected="${user.accountType == 1}">系统账号</option>
<option value="2" th:selected="${user.accountType == 2}">普通账号</option>
</select>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">账号状态</label>
<div class="col-sm-8">
<select class="form-control m-b" name="accountState">
<option value="0" th:selected="${user.accountState == 0}">启用</option>
<option value="1" th:selected="${user.accountState == 1}">冻结</option>
</select>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">序号:</label>
<div class="col-sm-8">
<input type="number" name="orderRank" th:value="${user.orderRank}"
placeholder="录入排序序号" class="form-control">
<span class="help-block m-b-none" th:style="${errors!=null?'color:red':''}"
th:text="${errors!=null?errors.get('orderRank'):''}">请输入序号</span>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-3 col-sm-8">
<button class="btn btn-sm btn-white" type="submit">提交</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
<!-- 全局js -->
<script src="/js/jquery.min.js?v=2.1.4"></script>
<script src="/js/bootstrap.min.js?v=3.3.7"></script>
<!-- Peity -->
<script src="/js/plugins/peity/jquery.peity.min.js"></script>
<!-- 自定义js -->
<script src="/js/content.js?v=1.0.0"></script>
<!-- iCheck -->
<script src="/js/plugins/iCheck/icheck.min.js"></script>
<!-- Peity -->
<script src="/js/demo/peity-demo.js"></script>
<script>
$(document).ready(function () {
$('.i-checks').iCheck({
checkboxClass: 'icheckbox_square-green',
radioClass: 'iradio_square-green',
});
});
</script>
<script src="/js/plugins/sweetalert/sweetalert.min.js"></script>
<script type="text/javascript" src="http://tajs.qq.com/stats?sId=9051096" charset="UTF-8"></script>
<!--统计代码,可删除-->
</body>
</html>
第四步:测试回显
第五步:UserController增加更新方法
@PostMapping("/update")
public String updateUser(User user){
// 如果有更新密码
if(StringUtils.isNotBlank(user.getPassword())){
user.setPassword(WebUtils.passwordEncoder(user.getPassword()));
}
// 更新时间和更新的用户
user.setUpdateTime(new Date());
// 设置创建的用户 获取当前登录的用户
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
UserDetails userDetails = (UserDetails) authentication.getPrincipal();
user.setUpdateUser(userDetails.getUsername());
userService.updateById(user);
return "redirect:/user/list";
}
第六步:测试修改功能