application.yml
server:
port: 8082
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC
username: root
password: xxxxxxxxx
redis:
host: 127.0.0.1
port: 6379
database: 0
servlet:
multipart:
max-file-size: 200MB #设置单个文件的大小 因为springboot内置tomact的的文件传输默认为10MB
max-request-size: 500MB #设置单次请求的文件总大小
enabled: true #千万注意要设置该参数,否则不生效
mybatis:
mapper-locations: classpath:mapper/*Dao.xml
logging:
level:
com.woniu.dao: debug
pattern:
console: '%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n'
# .file:
# path: D:/log/mylog.log
minio:
endpoint: http://127.0.0.1:9000
accesskey: minioadmin
secretKey: minioadmin
依赖
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0modelVersion>
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>2.5.4version>
<relativePath/>
parent>
<groupId>com.woniugroupId>
<artifactId>springsecurityday01artifactId>
<version>0.0.1-SNAPSHOTversion>
<name>springsecurityday01name>
<description>Demo project for Spring Bootdescription>
<properties>
<java.version>1.8java.version>
properties>
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-securityartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
<optional>trueoptional>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-testartifactId>
<scope>testscope>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-securityartifactId>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<version>8.0.32version>
dependency>
<dependency>
<groupId>com.baomidougroupId>
<artifactId>mybatis-plus-boot-starterartifactId>
<version>3.5.1version>
dependency>
<dependency>
<groupId>org.mybatis.spring.bootgroupId>
<artifactId>mybatis-spring-boot-starterartifactId>
<version>2.2.0version>
dependency>
<dependency>
<groupId>com.alibabagroupId>
<artifactId>fastjsonartifactId>
<version>2.0.12version>
dependency>
<dependency>
<groupId>com.nimbusdsgroupId>
<artifactId>nimbus-jose-jwtartifactId>
<version>9.11.1version>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-data-redisartifactId>
dependency>
<dependency>
<groupId>org.apache.commonsgroupId>
<artifactId>commons-pool2artifactId>
dependency>
<dependency>
<groupId>com.github.pagehelpergroupId>
<artifactId>pagehelper-spring-boot-starterartifactId>
<version>1.3.1version>
dependency>
<dependency>
<groupId>com.squareup.okhttp3groupId>
<artifactId>okhttpartifactId>
<version>4.8.1version>
dependency>
<dependency>
<groupId>io.miniogroupId>
<artifactId>minioartifactId>
<version>8.3.9version>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-configuration-processorartifactId>
<optional>trueoptional>
dependency>
dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-maven-pluginartifactId>
plugin>
<plugin>
<groupId>org.apache.maven.pluginsgroupId>
<artifactId>maven-resources-pluginartifactId>
<version>3.0.2version>
plugin>
plugins>
build>
project>
util/MinioProp.java
package com.x.springsecurityday01.util;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Data
@Component
@ConfigurationProperties(prefix = "minio")
public class MinioProp {
private String endpoint;
private String accesskey;
private String secretKey;
}
util/MinioUtils.java
package com.x.springsecurityday01.util;
import com.alibaba.fastjson.JSONObject;
import io.minio.BucketExistsArgs;
import io.minio.MakeBucketArgs;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import java.io.InputStream;
@Slf4j
@Component
public class MinioUtils {
@Autowired
private MinioClient client;
@Autowired
private MinioProp minioProp;
/**
* 创建bucket
*/
public void createBucket(String bucketName) {
BucketExistsArgs bucketExistsArgs = BucketExistsArgs.builder().bucket(bucketName).build();
MakeBucketArgs makeBucketArgs = MakeBucketArgs.builder().bucket(bucketName).build();
try {
if (client.bucketExists(bucketExistsArgs))
return;
client.makeBucket(makeBucketArgs);
} catch (Exception e) {
log.error("创建桶失败:{}", e.getMessage());
throw new RuntimeException(e);
}
}
/**
* @param file 文件
* @param bucketName 存储桶
* @return
*/
public JSONObject uploadFile(MultipartFile file, String bucketName) throws Exception {
JSONObject res = new JSONObject();
res.put("code", 0);
// 判断上传文件是否为空
if (null == file || 0 == file.getSize()) {
res.put("msg", "上传文件不能为空");
return res;
}
// 判断存储桶是否存在
createBucket(bucketName);
// 文件名
String originalFilename = file.getOriginalFilename();
// 新的文件名 = 存储桶名称_时间戳.后缀名
String fileName = bucketName + "_" + System.currentTimeMillis() + originalFilename.substring(originalFilename.lastIndexOf("."));
// 开始上传
InputStream inputStream = file.getInputStream();
PutObjectArgs args = PutObjectArgs.builder().bucket(bucketName).object(fileName)
.stream(inputStream,inputStream.available(),-1).build();
client.putObject(args);
res.put("code", 1);
res.put("msg", minioProp.getEndpoint() + "/" + bucketName + "/" + fileName);
return res;
}
}
config/MinioConfig.java
package com.x.springsecurityday01.config;
import com.woniu.springsecurityday01.util.MinioProp;
import io.minio.MinioClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
@EnableConfigurationProperties(MinioProp.class)
public class MinioConfig {
@Autowired
private MinioProp minioProp;
@Bean
public MinioClient minioClient() throws Exception {
return MinioClient.builder().endpoint(minioProp.getEndpoint())
.credentials(minioProp.getAccesskey(), minioProp.getSecretKey()).build();
}
}
controller
//写在controller内
@Autowired
private MinioUtils minioUtils;
@PostMapping("upload")
public JSONObject uploadImg(MultipartFile file){
JSONObject test=null;
try {
test = minioUtils.uploadFile(file, "test");
} catch (Exception e) {
e.printStackTrace();
}
return test;
}
<el-form-item>
<el-upload
action="api/user/upload"
:show-file-list="false"
:on-success="handleAvatarSuccess"
>
<img v-if="imageUrl" :src="imageUrl">
<i v-else class="el-icon-plus avatar-uploader-icon">i>
el-upload>
el-form-item>
data(){
return {
imageUrl:''
}
},
methods:{
handleAvatarSuccess(res,file){
console.log(res.msg)
this.imageUrl=res.msg;
//写请求,把图片路径保存到数据库
//this.$axios.....
},
}
<template>
<div>
<el-row>
<el-col :span="20">
<el-form :inline="true" class="demo-form-inline">
<el-form-item label="用户名">
<el-input placeholder="用户名" v-model="name">el-input>
el-form-item>
<el-form-item label="活动区域">
<el-input placeholder="审批人">el-input>
el-form-item>
<el-form-item>
<el-button type="primary" @click="queryBtn">查询el-button>
el-form-item>
el-form>
<el-button type="danger" @click="batchDel">删除el-button>
el-col>
<el-col :span="4">
<template>
<div class="demo-type">
<div>
<el-avatar src="https://cube.elemecdn.com/0/88/03b0d39583f48206768a7534e55bcpng.png">el-avatar>
<el-button type="" @click="queryBtn">更换头像el-button>
div>
div>
template>
el-col>
el-row>
<el-row>
<el-col :span="24">
<el-table
:data="tableData"
stripe
border
style="width: 100%"
@selection-change="handleSelectionChange"
>
<el-table-column
type="selection"
width="55">
el-table-column>
<el-table-column
prop="id"
label="编号"
width="180">
el-table-column>
<el-table-column
prop="username"
label="姓名"
align="center"
width="180">
el-table-column>
<el-table-column
prop="phone"
label="手机号码">
el-table-column>
<el-table-column
label="操作">
<template slot-scope="scope">
<el-button type="primary" icon="el-icon-edit" circle @click="updateData(scope.row)">el-button>
<el-button type="warning" icon="el-icon-share" circle @click="authMenu(scope.row)">el-button>
<el-button type="danger" icon="el-icon-delete" circle>el-button>
template>
el-table-column>
el-table>
el-col>
el-row>
<el-row>
<el-col :span="24" :offset="16">
<el-pagination
background
:page-sizes="[2, 10, 20]"
:page-size="pageSize"
:current-page="pageNum"
@prev-click="prevPage"
@next-click="nextPage"
@size-change="changePage"
layout="total, sizes, prev, pager, next"
:total="total">
el-pagination>
el-col>
el-row>
<el-dialog title="收货地址" :visible.sync="dialogFormVisible">
<el-row>
<el-col :span="18">
<el-form >
<el-form-item label="日期" label-width="80px">
<el-input v-model="dialogform.date">el-input>
el-form-item>
<el-form-item label="姓名" label-width="80px">
<el-input v-model="dialogform.name">el-input>
el-form-item>
<el-form-item label="地址" label-width="80px">
<el-input v-model="dialogform.address">el-input>
el-form-item>
<el-form-item>
<el-upload
action="api/user/upload"
:show-file-list="false"
:on-success="handleAvatarSuccess"
>
<img v-if="imageUrl" :src="imageUrl">
<i v-else class="el-icon-plus avatar-uploader-icon">i>
el-upload>
el-form-item>
el-form>
el-col>
el-row>
<div slot="footer" class="dialog-footer">
<el-button @click="dialogFormVisible = false">取 消el-button>
<el-button type="primary" @click="dialogFormVisible = false">确 定el-button>
div>
el-dialog>
<el-dialog title="菜单授权" :visible.sync="dialogManuVisible">
<el-row>
<el-col :span="18">
<el-tree
:data="data"
show-checkbox
node-key="id"
ref="tree"
:default-checked-keys="userMenuId"
:check-strictly="ischeck"
:props="defaultProps">
el-tree>
el-col>
el-row>
<div slot="footer" class="dialog-footer">
<el-button @click="dialogManuVisible = false">取 消el-button>
<el-button type="primary" @click="saveMenuTree">确 定el-button>
div>
el-dialog>
div>
template>
<script>
export default {
data(){
return {
pageNum:1,
pageSize:2,
total:0,
name:'',
dialogFormVisible:false,
dialogManuVisible:false,
dialogform:{
date: '',
name: '',
address: ''
},
tableData: [],
selectionData:[],
ischeck:false,
data: [],
userMenuId:[],
// label :树图显示内容
defaultProps: {
children: 'childrenMenu',
label: 'name'
},
userId:'',
imageUrl:''
}
},
methods:{
handleAvatarSuccess(res,file){
console.log(res.msg)
this.imageUrl=res.msg;
//写请求,把图片路径保存到数据库
//this.$axios.....
},
saveMenuTree(){
//获取选中的节点id
let checkid= this.$refs.tree.getCheckedKeys();
//获取半选中的节点id(选中子节点,父节点被级联选中的)
let Halfid= this.$refs.tree.getHalfCheckedKeys();
let menutree={};
menutree.userId=this.userId;
//concat 把两个数组组合
menutree.menus=checkid.concat(Halfid);
let jwt = localStorage.getItem("jwt");
this.$axios.post('api/user/saveUserMenu',menutree,{headers:{'jwt':jwt}})
.then(res=>{
console.log(res.data);
if(res.data.code==200){
this.$message({
type:'success',
message:'授权成功'
})
}
})
this.dialogManuVisible = false;
},
authMenu(val){
let account=val.account;
this.userId=val.id;
//1:查系统所有的菜单,并以树形图展示
//2: 查用户拥有菜单,并在树形图回显
let jwt = localStorage.getItem("jwt");
this.$axios.get('api/user/queryUserMenuTree?account='+account,{headers:{'jwt':jwt}})
.then(res => {
console.log(res.data);
if(res.data.code==200){
//树型菜单数据
this.ischeck=true;//是没有级联效果
this.$nextTick(() => {
this.data=res.data.data.menus;
this.userMenuId=res.data.data.userMenuId;
this.ischeck=false;
})
this.dialogManuVisible = true;
}
})
},
updateData(row){
this.dialogFormVisible = true;
this.dialogform = JSON.parse(JSON.stringify(row));
},
prevPage(val){
this.pageNum = val;
//alert(val)
this.queryUser();
},
nextPage(val){
this.pageNum = val;
//alert(val)
this.queryUser();
},
changePage(val){
this.pageNum = 1;
this.pageSize =val;
//alert(val)
this.queryUser();
},
queryBtn(){
this.pageNum = 1;
this.queryUser();
},
queryUser(){
let jwt = localStorage.getItem("jwt");
let param = {};
param.pageNum = this.pageNum;
param.pageSize = this.pageSize;
let data = {};
data.username = this.name;
param.data = data;
this.$axios.post('api/user/queryUser',param ,{headers:{'jwt':jwt}})
.then(res =>{
console.log(res.data);
if(res.data.code == 200){
let pageData = res.data.data;
this.tableData = pageData.list;
this.pageNum = pageData.pageNum;
this.pageSize = pageData.pageSize;
this.total = pageData.total
}
})
},
handleSelectionChange(val){
//每行数据
//console.log(val);
this.selectionData = val;
},
batchDel(){
//怎么拿到选中id?
let ids = [];
this.selectionData.forEach(e =>{
ids.push(e.id);
});
console.log(ids);
if(ids.length == 0){
//alert("请选择数据!")
this.$message({
message: '请选择数据!',
type: 'warning'
});
return;
}
let jwt = localStorage.getItem('jwt');
this.$axios.post('api/user/batchDelUser',ids,{headers:{'jwt':jwt}})
.then(res => {
if(res.data.code == 200){
this.$message({
message: '删除成功!',
type: 'success'
});
this.queryBtn();
}
})
}
},
created(){
this.queryBtn();
}
}
script>
<style scoped>
.el-row{
margin-top: 20px;
}
style>