目录
一、项目介绍
1.1、项目简介
1.2、技术框架
1.3、项目构建
1.4、配置依赖
二、mybatis-plus测试使用
三、角色管理
3.1、完善统一返回信息
3.2、整合knife4j
3.3、分页查询功能
3.4、添加、修改、删除功能
3.5、完善时间格式
3.6、异常统一处理
四、前端知识
4.1、vs code 安装与使用
4.1.1、创建文件夹,并添加到工作区
4.1.2、测试功能
4.2、ES6知识
4.2.1、模板字符串
4.2.2、对象扩展运算符
4.2.3、箭头函数
4.3、vue基础
4.3.1、vue入门案例
4.3.2、vue生命周期
4.3.3、Axios
4.4、node.js
五、前端框架启动
5.1、修改前端登录访问路径
5.2、角色增加修改删除前端构建
一、项目介绍
1.1、项目简介
云尚办公系统是一套自动办公系统,系统主要包含:管理端和员工端
管理端包含:权限管理、审批管理、公众号菜单管理
员工端采用微信公众号操作,包含:办公审批、微信授权登录、消息推送等功能
项目服务器端架构:SpringBoot + MyBatisPlus + SpringSecurity + Redis + Activiti+ MySQL
前端架构:vue-admin-template + Node.js + Npm + Vue + ElementUI + Axios
1.2、技术框架
基础框架:SpringBoot |
数据缓存:Redis |
数据库:MySQL |
权限控制:SpringSecurity |
工作流引擎:Activiti |
前端技术:vue-admin-template + Node.js + Npm + Vue + ElementUI + Axios | |
微信公众号:公众号菜单 + 微信授权登录 + 消息推送 |
1.3、项目构建
1.4、配置依赖
父工程依赖:
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<java.version>1.8</java.version>
<mybatis-plus.version>3.4.1</mybatis-plus.version>
<mysql.version>8.0.30</mysql.version>
<knife4j.version>3.0.3</knife4j.version>
<jwt.version>0.9.1</jwt.version>
<fastjson.version>2.0.21</fastjson.version>
</properties>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.11</version>
</parent>
<!--配置dependencyManagement锁定依赖的版本-->
<dependencyManagement>
<dependencies>
<!--mybatis-plus 持久层-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>${mybatis-plus.version}</version>
</dependency>
<!--mysql-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
<!--knife4j-->
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-spring-boot-starter</artifactId>
<version>${knife4j.version}</version>
</dependency>
<!--jjwt-->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>${jwt.version}</version>
</dependency>
<!--fastjson-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>${fastjson.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
common-util模块依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<scope>provided </scope>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
</dependency>
</dependencies>
service-util模块依赖
<dependencies>
<dependency>
<groupId>org.cjc</groupId>
<artifactId>common-util</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
</dependency>
<!--mysql-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
</dependencies>
model依赖
<dependencies>
<!--lombok用来简化实体类-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-spring-boot-starter</artifactId>
<scope>provided </scope>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<scope>provided </scope>
</dependency>
</dependencies>
service-oa依赖
<dependencies>
<dependency>
<groupId>org.cjc</groupId>
<artifactId>model</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.cjc</groupId>
<artifactId>service-util</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<finalName>${project.artifactId}</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
二、mybatis-plus测试使用
改yml
application.yml
spring:
application:
name: service-oa
profiles:
active: dev
application-dev.yml
server:
port: 8080
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 查看日志
spring:
datasource:
type: com.zaxxer.hikari.HikariDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/yaya-oa?serverTimezone=GMT%2B8&useSSL=false&characterEncoding=utf-8
username: root
password: 123456
数据库表
CREATE DATABASE `yaya-oa` ;
USE `yaya-oa`;
CREATE TABLE `sys_role` (
`id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '角色id',
`role_name` VARCHAR(20) NOT NULL DEFAULT '' COMMENT '角色名称',
`role_code` VARCHAR(20) DEFAULT NULL COMMENT '角色编码',
`description` VARCHAR(255) DEFAULT NULL COMMENT '描述',
`create_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`is_deleted` TINYINT(3) NOT NULL DEFAULT '0' COMMENT '删除标记(0:不可用 1:可用)',
PRIMARY KEY (`id`)
) ENGINE=INNODB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8 COMMENT='角色';
测试代码
@Mapper
public interface SysRoleMapper extends BaseMapper<SysRole> {
}
service层
public interface SysRoleService extends IService<SysRole> {
}
@Service
public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper,SysRole> implements SysRoleService {
}
@SpringBootTest
public class MapperTest {
@Autowired
private SysRoleMapper sysRoleMapper;
@Autowired
private SysRoleService service;
/**
* 查询所有记录
*/
@Test
public void getAll(){
List<SysRole> sysRoles = sysRoleMapper.selectList(null);
System.out.println(sysRoles);
}
/**
* 添加操作
*/
@Test
public void getAdd(){
SysRole sysRole = new SysRole();
sysRole.setRoleName("权限管理员");
sysRole.setDescription("权限管理员");
sysRole.setRoleCode("power");
sysRoleMapper.insert(sysRole);
}
/**
* 修改功能
*/
@Test
public void getUpdate(){
//根据id查询
SysRole sysRole = sysRoleMapper.selectById(10);
//设置修改值
sysRole.setRoleName("权限管理员1");
sysRoleMapper.updateById(sysRole);
}
/**
* 根据id删除
*/
@Test
public void getDelete(){
sysRoleMapper.deleteById(10);
}
/**
* 批量删除
*/
@Test
public void getDeleteBatch(){
sysRoleMapper.deleteBatchIds(Arrays.asList(1,2));
}
/**
* 条件查询
*/
@Test
public void query(){
//创建QueryWrapper对象,调用封装方法
QueryWrapper<SysRole> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("role_name","管理员");
List<SysRole> sysRoles = sysRoleMapper.selectList(queryWrapper);
System.out.println(sysRoles);
}
@Test
public void query1(){
//创建LambdaQueryWrapper对象,调用封装方法
LambdaQueryWrapper<SysRole> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(SysRole::getRoleName,"管理员");
List<SysRole> sysRoles = sysRoleMapper.selectList(queryWrapper);
System.out.println(sysRoles);
}
@Test
public void query2(){
List<SysRole> list = service.list();
System.out.println(list);
}
}
三、角色管理
3.1、完善统一返回信息
@Getter
public enum ResultCodeEnum {
SUCCESS(200,"成功"),
FAIL(201, "失败");
private Integer code;
private String message;
private ResultCodeEnum(Integer code, String message) {
this.code = code;
this.message = message;
}
}
@Data
public class Result<T> {
private Integer code;//状态码
private String message;//返回信息
private T data;//数据信息
//构造方法私有
private Result() {
}
//返回数据
public static <T> Result<T> build(T body,ResultCodeEnum resultCodeEnum){
Result<T> result = new Result<>();
//封装数据
if (body != null){
result.setData(body);
}
//状态码
result.setCode(resultCodeEnum.getCode());
//返回信息
result.setMessage(resultCodeEnum.getMessage());
return result;
}
//请求成功,无数据
public static <T> Result<T> ok(){
return build(null,ResultCodeEnum.SUCCESS);
}
//请求成功,有数据
public static<T> Result<T> ok(T data){
return build(data,ResultCodeEnum.SUCCESS);
}
//请求失败,无数据
public static<T> Result<T> fail(){
return build(null,ResultCodeEnum.FAIL);
}
//请求失败,有数据
public static<T> Result<T> fail(T data){
return build(data,ResultCodeEnum.FAIL);
}
//自定义返回信息
public Result<T> message(String msg){
this.setMessage(msg);
return this;
}
public Result<T> code(Integer code){
this.setCode(code);
return this;
}
}
@RestController
@RequestMapping("/admin/system/sysRole")
public class SysRoleController {
@Autowired
private SysRoleService sysRoleService;
/**
* 查询所有角色
* @return SysRole
*/
// @GetMapping("/findAll")
// public List<SysRole> findAll(){
// return sysRoleService.list();
// }
//统一返回数据结果
@GetMapping("/findAll")
public Result findAll(){
List<SysRole> list = sysRoleService.list();
return Result.ok(list);
}
}
3.2、整合knife4j
<!--knife4j-->
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-spring-boot-starter</artifactId>
</dependency>
@Configuration
@EnableSwagger2WebMvc
public class Knife4jConfig {
@Bean
public Docket adminApiConfig(){
List<Parameter> pars = new ArrayList<>();
ParameterBuilder tokenPar = new ParameterBuilder();
tokenPar.name("token")
.description("用户token")
.defaultValue("")
.modelRef(new ModelRef("string"))
.parameterType("header")
.required(false)
.build();
pars.add(tokenPar.build());
//添加head参数end
Docket adminApi = new Docket(DocumentationType.SWAGGER_2)
.groupName("adminApi")
.apiInfo(adminApiInfo())
.select()
//只显示admin路径下的页面
.apis(RequestHandlerSelectors.basePackage("com.cjc"))
.paths(PathSelectors.regex("/admin/.*"))
.build()
.globalOperationParameters(pars);
return adminApi;
}
private ApiInfo adminApiInfo(){
return new ApiInfoBuilder()
.title("后台管理系统-API文档")
.description("本文档描述了后台管理系统微服务接口定义")
.version("1.0")
.contact(new Contact("yaya", "http://yaya.com", "yaya@qq.com"))
.build();
}
}
异常报错:
org.springframework.context.ApplicationContextException: Failed to start bean 'documentationPluginsBootstrapper'; nested exception is java.lang.NullPointerException
at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:181) ~[spring-context-5.3.27.jar:5.3.27]
at org.springframework.context.support.DefaultLifecycleProcessor.access$200(DefaultLifecycleProcessor.java:54) ~[spring-context-5.3.27.jar:5.3.27]
at org.springframework.context.support.DefaultLifecycleProcessor$LifecycleGroup.start(DefaultLifecycleProcessor.java:356) ~[spring-context-5.3.27.jar:5.3.27]
at java.lang.Iterable.forEach(Iterable.java:75) ~[na:1.8.0_321]
at org.springframework.context.support.DefaultLifecycleProcessor.startBeans(DefaultLifecycleProcessor.java:155) ~[spring-context-5.3.27.jar:5.3.27]
at org.springframework.context.support.DefaultLifecycleProcessor.onRefresh(DefaultLifecycleProcessor.java:123) ~[spring-context-5.3.27.jar:5.3.27]
at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:937) ~[spring-context-5.3.27.jar:5.3.27]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:586) ~[spring-context-5.3.27.jar:5.3.27]
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:147) ~[spring-boot-2.7.11.jar:2.7.11]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:731) [spring-boot-2.7.11.jar:2.7.11]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:408) [spring-boot-2.7.11.jar:2.7.11]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:307) [spring-boot-2.7.11.jar:2.7.11]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1303) [spring-boot-2.7.11.jar:2.7.11]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1292) [spring-boot-2.7.11.jar:2.7.11]
at com.cjc.auth.ServiceAuthApplication.main(ServiceAuthApplication.java:11) [classes/:na]
解决方案:
在配置文件中进行配置
访问地址:http://localhost:8080/doc.html#/home
3.3、分页查询功能
@Configuration
@MapperScan("com.cjc.auth.mapper")
public class MybatisPlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return interceptor;
}
@Bean
public ConfigurationCustomizer configurationCustomizer() {
return configuration -> configuration.setUseDeprecatedExecutor(false);
}
}
/**
*
* @param page 当前页
* @param limit 每页显示记录数
* sysRoleQueryVo 条件对象
* @return
*/
@ApiOperation("条件分页查询")
@GetMapping("/pageQuery/{page}/{limit}")
public Result pageQuery(@PathVariable("page") Long page,
@PathVariable("limit") Long limit,
SysRoleQueryVo sysRoleQueryVo){
//创建Page对象,传递分页相关参数
Page<SysRole> rolePage = new Page<>(page,limit);
//封装条件
String roleName = sysRoleQueryVo.getRoleName();
LambdaQueryWrapper<SysRole> wrapper = new LambdaQueryWrapper<>();
//如果传值就模糊查询
if (StringUtils.hasLength(roleName)){
wrapper.like(SysRole::getRoleName,roleName);
}
return Result.ok(sysRoleService.page(rolePage, wrapper));
}
3.4、添加、修改、删除功能
@ApiOperation("添加角色")
@PostMapping("/save")
public Result save(@RequestBody SysRole role){
boolean save = sysRoleService.save(role);
if (save){
return Result.ok();
}
return Result.fail();
}
@ApiOperation("根据id查询")
@GetMapping("/getById/{id}")
public Result getById(@PathVariable("id") Long id){
SysRole sysRole = sysRoleService.getById(id);
return Result.ok(sysRole);
}
@ApiOperation("修改角色")
@PutMapping("/updateById")
public Result updateById(@RequestBody SysRole role){
boolean updateById = sysRoleService.updateById(role);
if (updateById){
return Result.ok();
}
return Result.fail();
}
@ApiOperation("根据id删除角色")
@DeleteMapping("/deleteById/{id}")
public Result deleteById(@PathVariable("id") Long id){
boolean removeById = sysRoleService.removeById(id);
if (removeById){
return Result.ok();
}
return Result.fail();
}
@ApiOperation("批量删除角色")
@DeleteMapping("/deleteBatch")
public Result deleteBatch(@RequestBody List<Long> list){
boolean removeByIds = sysRoleService.removeByIds(list);
if (removeByIds){
return Result.ok();
}
return Result.fail();
}
3.5、完善时间格式
3.6、异常统一处理
/**
* 自定义异常处理
*/
@Data
@ToString
public class CJCException extends RuntimeException{
private Integer code;//状态码
private String msg;//返回信息
public CJCException(Integer code,String msg){
super(msg);
this.code = code;
this.msg = msg;
}
/**
* 接收枚举类型
* @param resultCodeEnum
*/
public CJCException(ResultCodeEnum resultCodeEnum){
super(resultCodeEnum.getMessage());
this.code = resultCodeEnum.getCode();
this.msg = resultCodeEnum.getMessage();
}
}
@ControllerAdvice
public class GlobalException {
//全局异常处理方法
@ExceptionHandler(Exception.class)
@ResponseBody
public Result error(Exception e){
e.printStackTrace();
return Result.fail().message("执行全局异常处理");
}
//特定异常处理
@ExceptionHandler(ArithmeticException.class)
@ResponseBody
public Result error(ArithmeticException e){
e.printStackTrace();
return Result.fail().message("特定异常处理");
}
//自定义异常处理
@ExceptionHandler(CJCException.class)
@ResponseBody
public Result error(CJCException e){
e.printStackTrace();
return Result.fail().code(e.getCode()).message(e.getMsg());
}
}
@ApiOperation("查询所有角色")
@GetMapping("/findAll")
public Result findAll(){
List<SysRole> list = sysRoleService.list();
//模拟异常
try {
int i = 10 /0;
} catch (Exception e) {
throw new CJCException(500,"执行自定义异常");
}
return Result.ok(list);
}
四、前端知识
4.1、vs code 安装与使用
4.1.1、创建文件夹,并添加到工作区
4.1.2、测试功能
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1>hello</h1>
</body>
</html>
4.2、ES6知识
4.2.1、模板字符串
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
var name = "lucy"
var age = 10
//使用模板字符串 + 表达式
//模板字符串符号:``
//表达式:${}
var info = `名字是:${name},年龄加1:${age + 1}`
console.log(info)
</script>
</body>
</html>
4.2.2、对象扩展运算符
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
let person1 = {name: "tom",age: 15}
//对象复制
let someone = {...person1}
console.log(someone)
</script>
</body>
</html>
4.2.3、箭头函数
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=<device-width>, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
var f1 = function(a){
return a;
}
console.log(f1(2))
var f2 = b => b
console.log(f2(5))
var f3 = function(x,y){
return x + y;
}
console.log(f3(3,4))
var f4 = (z,c) => z*c
console.log(f4(9,7))
</script>
</body>
</html>
4.3、vue基础
4.3.1、vue入门案例
需要下载导入vue.min.js文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
{{message}}
</div>
<script src="vue.min.js"></script>
<script>
new Vue({
el: '#app',
data: {
message:'hello vue'
}
})
</script>
</body>
</html>
4.3.2、vue生命周期
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
{{message}}
</div>
<script src="vue.min.js"></script>
<script>
new Vue({
el: '#app',
data: {
message:'hello vue'
},
created(){ //在渲染前执行
debugger
console.log('created')
},
mounted(){ //在渲染后执行
debugger
console.log('mounted')
}
})
</script>
</body>
</html>
4.3.3、Axios
需要引入axios.min.js文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script src="vue.min.js"></script>
<script src="axios.min.js"></script>
<div id="app">
</div>
<script>
new Vue({
el: '#app',
data: {
userList:[] //列表数组
},
created(){ //在渲染前执行
//调用方法
this.getList()
},
methods:{ //在渲染后执行
//使用axios发送ajax请求
getList(){
axios.get("data.json")
//得到接口或者文件数据
.then(response => {
// console.log(response)
this.userList = response.data.data
console.log(this.userList)
})
//失败调用catch方法
.catch(error => {
console.log(error)
})
}
}
})
</script>
</body>
</html>
{
"success":true,
"code":200,
"data":[
{"name":"tom","age":12},
{"name":"jack","age":15}
]
}
4.4、node.js
console.log('hello node.js')
五、前端框架启动
启动命令:npm run dev
5.1、修改前端登录访问路径
proxy: {
'/dev-api': { // 匹配所有以 '/dev-api'开头的请求路径
target: 'http://localhost:8080',
changeOrigin: true, // 支持跨域
pathRewrite: { // 重写路径: 去掉路径中开头的'/dev-api'
'^/dev-api': ''
}
}
}
export function login(data) {
return request({
url: '/admin/system/index/login',
method: 'post',
data
})
}
export function getInfo(token) {
return request({
url: '/admin/system/index/info',
method: 'get',
params: { token }
})
}
export function logout() {
return request({
url: '/admin/system/index/logout',
method: 'post'
})
}
if (res.code !== 200) {
Message({
message: res.message || 'Error',
type: 'error',
duration: 5 * 1000
})
后端代码:
@RestController
@Api(tags = "后台登录模块")
@RequestMapping("/admin/system/index")
public class IndexController {
//
@PostMapping("/login")
public Result login(){
HashMap<String,String > map = new HashMap<>();
map.put("token","admin-token");
return Result.ok(map);
}
@GetMapping("/info")
public Result info(){
Map<String, Object> map = new HashMap<>();
map.put("roles","[admin]");
map.put("name","admin");
map.put("avatar","https://oss.aliyuncs.com/aliyun_id_photo_bucket/default_handsome.jpg");
return Result.ok(map);
}
@PostMapping("/logout")
public Result logout(){
return Result.ok();
}
}
5.2、角色增加修改删除前端构建
import request from '@/utils/request'
const api_name = '/admin/system/sysRole'
export default {
// 角色列表-条件分页查询
getPageList(current, limit, searchObj) {
return request({
url: `${api_name}/pageQuery/${current}/${limit}`,
method: 'get',
// 普通对象参数
params: searchObj
})
},
// 删除角色
deleteById(id) {
return request({
url: `${api_name}/deleteById/${id}`,
method: 'delete'
})
},
// 添加角色
saveRole(role) {
return request({
url: `${api_name}/save`,
method: 'post',
data: role
})
},
// 根据ID查询
getById(id) {
return request({
url: `${api_name}/getById/${id}`,
method: 'get'
})
},
// 修改角色
updateById(role) {
return request({
url: `${api_name}/updateById`,
method: 'put',
data: role
})
},
// 批量删除
deleteBatch(idList) {
return request({
url: `${api_name}/deleteBatch`,
method: 'delete',
data: idList
})
}
}
<template>
<div class="app-container">
<!--查询表单-->
<div class="search-div">
<el-form label-width="70px" size="small">
<el-row>
<el-col :span="24">
<el-form-item label="角色名称">
<el-input v-model="searchObj.roleName" style="width: 100%" placeholder="角色名称" />
</el-form-item>
</el-col>
</el-row>
<el-row style="display:flex">
<el-button type="primary" icon="el-icon-search" size="mini" :loading="loading" @click="fetchData()">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetData">重置</el-button>
</el-row>
</el-form>
</div>
<!-- 表格 -->
<el-table
v-loading="listLoading"
:data="list"
stripe
border
style="width: 100%;margin-top: 10px;"
@selection-change="handleSelectionChange"
>
<el-table-column type="selection" />
<el-table-column
label="序号"
width="70"
align="center"
>
<template slot-scope="scope">
{{ (page - 1) * limit + scope.$index + 1 }}
</template>
</el-table-column>
<el-table-column prop="roleName" label="角色名称" />
<el-table-column prop="roleCode" label="角色编码" />
<el-table-column prop="description" label="描述" />
<el-table-column prop="createTime" label="创建时间" width="160" />
<el-table-column label="操作" width="200" align="center">
<template slot-scope="scope">
<el-button type="primary" icon="el-icon-edit" size="mini" title="修改" @click="edit(scope.row.id)" />
<el-button type="danger" icon="el-icon-delete" size="mini" title="删除" @click="removeDataById(scope.row.id)" />
</template>
</el-table-column>
</el-table>
<!-- 工具条 -->
<div class="tools-div">
<el-button type="success" icon="el-icon-plus" size="mini" @click="add">添 加</el-button>
<el-button class="btn-add" size="mini" @click="batchRemove()">批量删除</el-button>
</div>
<!-- 分页组件 -->
<el-pagination
:current-page="page"
:total="total"
:page-size="limit"
style="padding: 30px 0; text-align: center;"
layout="total, prev, pager, next, jumper"
@current-change="fetchData"
/>
<el-dialog title="添加/修改" :visible.sync="dialogVisible" width="40%">
<el-form ref="dataForm" :model="sysRole" label-width="150px" size="small" style="padding-right: 40px;">
<el-form-item label="角色名称">
<el-input v-model="sysRole.roleName" />
</el-form-item>
<el-form-item label="角色编码">
<el-input v-model="sysRole.roleCode" />
</el-form-item>
<el-form-item label="描述">
<el-input v-model="sysRole.description" />
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button size="small" icon="el-icon-refresh-right" @click="dialogVisible = false">取 消</el-button>
<el-button type="primary" icon="el-icon-check" size="small" @click="saveOrUpdate()">确 定</el-button>
</span>
</el-dialog>
</div>
</template>
<script>
// 引入定义接口js文件
import api from '@/api/system/sysRole'
export default {
//
data() {
return {
list: [], // 角色列表
page: 1, // 当前页
limit: 2, // 每页显示记录数
total: 0, // 总记录数
searchObj: {}, // 条件对象
sysRole: {}, // 封装表单角色数据
dialogVisible: false, // 开/关弹窗
selection: [] // 多个复选框的值
}
},
created() { // 渲染之前执行
this.fetchData()
},
methods: { // 操作方法
// 选择复选框,把复选框所在行内容进行传递
handleSelectionChange(selection) {
this.selections = selection
console.log(this.selections)
},
// 批量删除
batchRemove() {
if (this.selections.length === 0) {
this.$message.warning('请选择要删除的记录!')
return
}
this.$confirm('此操作将永久删除该记录, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
var idList = []
// 遍历循序将id添加到数组中
this.selections.forEach(element => {
var id = element.id
idList.push(id)
})
return api.deleteBatch(idList)
.then(response => {
this.$message.success(response.message || '删除成功')
this.fetchData()
})
})
},
// 点击修改弹窗,根据id查询显示
edit(id) {
this.dialogVisible = true
// 根据id查询
this.fetchDataById(id)
},
// 点击添加弹框
add() {
this.dialogVisible = true
},
// 条件分页查询
fetchData(current = 1) {
this.page = current
api.getPageList(this.page, this.limit, this.searchObj)
.then(response => {
this.list = response.data.records
this.total = response.data.total
})
},
// 删除
removeDataById(id) {
this.$confirm('此操作将永久删除该记录, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => { // promise
// 点击确定,远程调用ajax
return api.deleteById(id)
}).then(response => {
this.fetchData()
this.$message.success(response.message || '删除成功')
})
},
// 调用添加和修改
saveOrUpdate() {
// 根据id判断修改/添加
if (!this.sysRole.id) {
this.save()
} else {
this.update()
}
},
// 添加
save() {
api.saveRole(this.sysRole)
.then(response => {
// 提示
this.$message.success(response.message || '添加成功')
// 关闭弹窗
this.dialogVisible = false
// 刷新界面
this.fetchData()
})
},
// 修改
update() {
api.updateById(this.sysRole)
.then(response => {
// 提示
this.$message.success(response.message || '修改成功')
// 关闭弹窗
this.dialogVisible = false
// 刷新界面
this.fetchData()
})
},
// 根据id查询
fetchDataById(id) {
api.getById(id)
.then(response => {
this.sysRole = response.data
})
}
}
}
</script>