Commit a71243d9 authored by dqjdda's avatar dqjdda
Browse files

完成了本地存储功能,用户头像存储方式改为本地

parent 76242d4d
......@@ -61,6 +61,7 @@ public class RedisConfig extends CachingConfigurerSupport {
// 建议使用这种方式,小范围指定白名单
ParserConfig.getGlobalInstance().addAccept("me.zhengjie.domain");
ParserConfig.getGlobalInstance().addAccept("me.zhengjie.modules.system.service.dto");
ParserConfig.getGlobalInstance().addAccept("me.zhengjie.service.dto");
ParserConfig.getGlobalInstance().addAccept("me.zhengjie.modules.system.domain");
ParserConfig.getGlobalInstance().addAccept("me.zhengjie.modules.quartz.domain");
ParserConfig.getGlobalInstance().addAccept("me.zhengjie.modules.monitor.domain");
......
......@@ -4,12 +4,16 @@ import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import me.zhengjie.exception.BadRequestException;
import org.springframework.web.multipart.MultipartFile;
import sun.misc.BASE64Encoder;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
......@@ -107,7 +111,7 @@ public class FileUtil extends cn.hutool.core.io.FileUtil {
* @param size
* @return
*/
public static String getSize(int size){
public static String getSize(long size){
String resultSize = "";
if (size / GB >= 1) {
//如果当前Byte的值大于等于1GB
......@@ -147,6 +151,47 @@ public class FileUtil extends cn.hutool.core.io.FileUtil {
return file;
}
/**
* 将文件名解析成文件的上传路径
*
* @param file
* @param filePath
* @return 上传到服务器的文件名
*/
public static File upload(MultipartFile file, String filePath) {
Date date = new Date();
SimpleDateFormat format = new SimpleDateFormat("yyyyMMddhhmmssS");
String name = getFileNameNoEx(file.getOriginalFilename());
String suffix = getExtensionName(file.getOriginalFilename());
String nowStr = "-" + format.format(date);
try {
String fileName = name + nowStr + "." + suffix;
String path = filePath + fileName;
File dest = new File(path);
// 检测是否存在目录
if (!dest.getParentFile().exists()) {
dest.getParentFile().mkdirs();// 新建文件夹
}
String d = dest.getPath();
file.transferTo(dest);// 文件写入
return dest;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static String fileToBase64(File file) throws Exception {
FileInputStream inputFile = new FileInputStream(file);
String base64 =null;
byte[] buffer = new byte[(int)file.length()];
inputFile.read(buffer);
inputFile.close();
base64=new BASE64Encoder().encode(buffer);
String encoded = base64.replaceAll("[\\s*\t\n\r]", "");
return encoded;
}
/**
* 导出excel
* @param list
......@@ -174,4 +219,26 @@ public class FileUtil extends cn.hutool.core.io.FileUtil {
//此处记得关闭输出Servlet流
IoUtil.close(out);
}
public static String getFileType(String type) {
String documents = "txt doc pdf ppt pps xlsx xls";
String music = "mp3 wav wma mpa ram ra aac aif m4a";
String video = "avi mpg mpe mpeg asf wmv mov qt rm mp4 flv m4v webm ogv ogg";
String image = "bmp dib pcp dif wmf gif jpg tif eps psd cdr iff tga pcd mpt png jpeg";
if(image.indexOf(type) != -1){
return "图片";
} else if(documents.indexOf(type) != -1){
return "文档";
} else if(music.indexOf(type) != -1){
return "音乐";
} else if(video.indexOf(type) != -1){
return "视频";
} else return "其他";
}
public static void checkSize(long maxSize, long size) {
if(size > (maxSize * 1024 * 1024)){
throw new BadRequestException("文件超出规定大小");
}
}
}
......@@ -3,6 +3,7 @@ package me.zhengjie.config;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
......@@ -25,6 +26,12 @@ import java.util.List;
@EnableWebMvc
public class ConfigurerAdapter implements WebMvcConfigurer {
@Value("${file.path}")
private String path;
@Value("${file.avatar}")
private String avatar;
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
......@@ -35,27 +42,12 @@ public class ConfigurerAdapter implements WebMvcConfigurer {
}
// 可解决Long 类型在 前端精度丢失的问题, 如不想全局 直接添加注解 @JsonSerialize(using= ToStringSerializer.class) 到相应的字段
// @Override
// public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
//
// MappingJackson2HttpMessageConverter jackson2HttpMessageConverter =
// new MappingJackson2HttpMessageConverter();
//
// ObjectMapper objectMapper = new ObjectMapper();
// SimpleModule simpleModule = new SimpleModule();
// simpleModule.addSerializer(BigInteger.class, ToStringSerializer.instance);
// simpleModule.addSerializer(Long.class, ToStringSerializer.instance);
// simpleModule.addSerializer(Long.TYPE, ToStringSerializer.instance);
// objectMapper.registerModule(simpleModule);
// jackson2HttpMessageConverter.setObjectMapper(objectMapper);
// converters.add(jackson2HttpMessageConverter);
// converters.add(new StringHttpMessageConverter(Charset.forName("UTF-8")));
// }
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
String avatarUtl = "file:" + avatar.replace("\\","/");
String pathUtl = "file:" + path.replace("\\","/");
registry.addResourceHandler("/avatar/**").addResourceLocations(avatarUtl).setCachePeriod(0);
registry.addResourceHandler("/file/**").addResourceLocations(pathUtl).setCachePeriod(0);
registry.addResourceHandler("/**").addResourceLocations("classpath:/META-INF/resources/").setCachePeriod(0);
}
}
......@@ -106,6 +106,11 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
// 接口限流测试
.antMatchers("/test/**").anonymous()
// 文件
.antMatchers("/avatar/**").anonymous()
.antMatchers("/file/**").anonymous()
// 放行OPTIONS请求
.antMatchers(HttpMethod.OPTIONS, "/**").anonymous()
.antMatchers("/druid/**").anonymous()
......
......@@ -31,7 +31,9 @@ public class User implements Serializable {
@Column(unique = true)
private String username;
private String avatar;
@OneToOne
@JoinColumn(name = "avatar_id")
private UserAvatar userAvatar;
@NotBlank
@Pattern(regexp = "([a-z0-9A-Z]+[-|\\.]?)+[a-z0-9A-Z]@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\\.)+[a-zA-Z]{2,}",message = "格式错误")
......@@ -69,7 +71,6 @@ public class User implements Serializable {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", avatar='" + avatar + '\'' +
", email='" + email + '\'' +
", enabled=" + enabled +
", password='" + password + '\'' +
......
package me.zhengjie.modules.system.domain;
import cn.hutool.core.util.ObjectUtil;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.persistence.*;
import java.sql.Timestamp;
/**
* @author Zheng Jie
* @date 2019年9月7日 16:16:59
*/
@Entity
@Table(name = "user_avatar")
@Data
@NoArgsConstructor
public class UserAvatar {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String realName;
private String path;
private String size;
public UserAvatar(UserAvatar userAvatar,String realName, String path, String size) {
this.id = ObjectUtil.isNotEmpty(userAvatar) ? userAvatar.getId() : null;
this.realName = realName;
this.path = path;
this.size = size;
}
}
package me.zhengjie.modules.system.repository;
import me.zhengjie.modules.system.domain.UserAvatar;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import java.util.Date;
/**
* @author Zheng Jie
* @date 2018-11-22
*/
public interface UserAvatarRepository extends JpaRepository<UserAvatar, Long>, JpaSpecificationExecutor {
}
......@@ -155,8 +155,7 @@ public class UserController {
*/
@PostMapping(value = "/users/updateAvatar")
public ResponseEntity updateAvatar(@RequestParam MultipartFile file){
Picture picture = pictureService.upload(file, SecurityUtils.getUsername());
userService.updateAvatar(SecurityUtils.getUsername(),picture.getUrl());
userService.updateAvatar(file);
return new ResponseEntity(HttpStatus.OK);
}
......
......@@ -8,6 +8,7 @@ import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.domain.Pageable;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
......@@ -67,11 +68,10 @@ public interface UserService {
/**
* 修改头像
* @param username
* @param url
* @param file
*/
@CacheEvict(allEntries = true)
void updateAvatar(String username, String url);
void updateAvatar(MultipartFile file);
/**
* 修改邮箱
......
......@@ -197,15 +197,13 @@ public class MenuServiceImpl implements MenuService {
if (menuDTO!=null){
List<MenuDTO> menuDTOList = menuDTO.getChildren();
MenuVo menuVo = new MenuVo();
menuVo.setName(ObjectUtil.isNotEmpty(menuDTO.getComponentName()) ? menuDTO.getComponentName() : RandomUtil.randomString(5));
menuVo.setPath(menuDTO.getPath());
menuVo.setName(ObjectUtil.isNotEmpty(menuDTO.getComponentName()) ? menuDTO.getComponentName() : menuDTO.getName());
// 一级目录需要加斜杠,不然会报警告
menuVo.setPath(menuDTO.getPid() == 0 ? "/" + menuDTO.getPath() :menuDTO.getPath());
menuVo.setHidden(menuDTO.getHidden());
// 如果不是外链
if(!menuDTO.getIFrame()){
if(menuDTO.getPid() == 0){
//一级目录需要加斜杠,不然访问 会跳转404页面
menuVo.setPath("/" + menuDTO.getPath());
menuVo.setComponent(StrUtil.isEmpty(menuDTO.getComponent())?"Layout":menuDTO.getComponent());
}else if(!StrUtil.isEmpty(menuDTO.getComponent())){
menuVo.setComponent(menuDTO.getComponent());
......
......@@ -7,24 +7,27 @@ import me.zhengjie.modules.monitor.service.RedisService;
import me.zhengjie.modules.system.domain.User;
import me.zhengjie.exception.EntityExistException;
import me.zhengjie.exception.EntityNotFoundException;
import me.zhengjie.modules.system.domain.UserAvatar;
import me.zhengjie.modules.system.repository.UserAvatarRepository;
import me.zhengjie.modules.system.repository.UserRepository;
import me.zhengjie.modules.system.service.UserService;
import me.zhengjie.modules.system.service.dto.RoleSmallDTO;
import me.zhengjie.modules.system.service.dto.UserDTO;
import me.zhengjie.modules.system.service.dto.UserQueryCriteria;
import me.zhengjie.modules.system.service.mapper.UserMapper;
import me.zhengjie.utils.FileUtil;
import me.zhengjie.utils.PageUtil;
import me.zhengjie.utils.QueryHelp;
import me.zhengjie.utils.ValidationUtil;
import me.zhengjie.utils.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;
......@@ -46,6 +49,12 @@ public class UserServiceImpl implements UserService {
@Autowired
private RedisService redisService;
@Autowired
private UserAvatarRepository userAvatarRepository;
@Value("${file.avatar}")
private String avatar;
@Override
public Object queryAll(UserQueryCriteria criteria, Pageable pageable) {
Page<User> page = userRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable);
......@@ -79,7 +88,6 @@ public class UserServiceImpl implements UserService {
// 默认密码 123456,此密码是加密后的字符
resources.setPassword("e10adc3949ba59abbe56e057f20f883e");
resources.setAvatar("https://i.loli.net/2019/04/04/5ca5b971e1548.jpeg");
return userMapper.toDto(userRepository.save(resources));
}
......@@ -149,8 +157,20 @@ public class UserServiceImpl implements UserService {
@Override
@Transactional(rollbackFor = Exception.class)
public void updateAvatar(String username, String url) {
userRepository.updateAvatar(username,url);
public void updateAvatar(MultipartFile multipartFile) {
User user = userRepository.findByUsername(SecurityUtils.getUsername());
UserAvatar userAvatar = user.getUserAvatar();
String oldPath = "";
if(userAvatar != null){
oldPath = userAvatar.getPath();
}
File file = FileUtil.upload(multipartFile, avatar);
userAvatar = userAvatarRepository.save(new UserAvatar(userAvatar,file.getName(), file.getPath(), FileUtil.getSize(multipartFile.getSize())));
user.setUserAvatar(userAvatar);
userRepository.save(user);
if(StringUtils.isNotBlank(oldPath)){
FileUtil.del(oldPath);
}
}
@Override
......
......@@ -4,8 +4,11 @@ import me.zhengjie.modules.system.domain.User;
import me.zhengjie.mapper.EntityMapper;
import me.zhengjie.modules.system.service.dto.UserDTO;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.ReportingPolicy;
import java.util.List;
/**
* @author Zheng Jie
* @date 2018-11-23
......@@ -13,4 +16,6 @@ import org.mapstruct.ReportingPolicy;
@Mapper(componentModel = "spring",uses = {RoleMapper.class, DeptMapper.class, JobMapper.class},unmappedTargetPolicy = ReportingPolicy.IGNORE)
public interface UserMapper extends EntityMapper<UserDTO, User> {
@Mapping(source = "user.userAvatar.realName",target = "avatar")
UserDTO toDto(User user);
}
......@@ -59,4 +59,12 @@ generator:
#是否开启 swagger-ui
swagger:
enabled: true
\ No newline at end of file
enabled: true
# 文件存储路径
file:
path: C:\eladmin\file\
avatar: C:\eladmin\avatar\
# 文件大小 /M
maxSize: 100
avatarMaxSize: 5
\ No newline at end of file
......@@ -68,4 +68,12 @@ generator:
#是否开启 swagger-ui
swagger:
enabled: false
\ No newline at end of file
enabled: false
# 文件存储路径
file:
path: /home/eladmin/file/
avatar: /home/eladmin/avatar/
# 文件大小 /M
maxSize: 100
avatarMaxSize: 5
\ No newline at end of file
<template>
<el-dialog :append-to-body="true" :visible.sync="dialog" :title="isAdd ? '新增' : '编辑'" width="500px">
<el-dialog :append-to-body="true" :close-on-click-modal="false" :before-close="cancel" :visible.sync="dialog" :title="isAdd ? '新增' : '编辑'" width="500px">
<el-form ref="form" :model="form" :rules="rules" size="small" label-width="80px">
<#if columns??>
<#list columns as column>
......
package me.zhengjie.domain;
import lombok.AllArgsConstructor;
import lombok.Data;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import lombok.NoArgsConstructor;
import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.UpdateTimestamp;
import javax.persistence.*;
import java.sql.Timestamp;
import java.io.Serializable;
/**
* @author Zheng Jie
* @date 2019-09-05
*/
@Entity
@Data
@Table(name="local_storage")
@AllArgsConstructor
@NoArgsConstructor
public class LocalStorage implements Serializable {
// ID
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
// 真实文件名
@Column(name = "real_name")
private String realName;
// 文件名
@Column(name = "name")
private String name;
// 后缀
@Column(name = "suffix")
private String suffix;
// 路径
@Column(name = "path")
private String path;
// 类型
@Column(name = "type")
private String type;
// 大小
@Column(name = "size")
private String size;
// 操作人
@Column(name = "operate")
private String operate;
// 创建日期
@Column(name = "create_time")
@CreationTimestamp
private Timestamp createTime;
// 修改日期
@Column(name = "update_time")
@UpdateTimestamp
private Timestamp updateTime;
public LocalStorage(String realName,String name, String suffix, String path, String type, String size, String operate) {
this.realName = realName;
this.name = name;
this.suffix = suffix;
this.path = path;
this.type = type;
this.size = size;
this.operate = operate;
}
public void copy(LocalStorage source){
BeanUtil.copyProperties(source,this, CopyOptions.create().setIgnoreNullValue(true));
}
}
\ No newline at end of file
package me.zhengjie.repository;
import me.zhengjie.domain.LocalStorage;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
/**
* @author Zheng Jie
* @date 2019-09-05
*/
public interface LocalStorageRepository extends JpaRepository<LocalStorage, Long>, JpaSpecificationExecutor {
}
\ No newline at end of file
......@@ -2,10 +2,16 @@ package me.zhengjie.repository;
import me.zhengjie.domain.QiniuConfig;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
/**
* @author Zheng Jie
* @date 2018-12-31
*/
public interface QiNiuConfigRepository extends JpaRepository<QiniuConfig,Long> {
@Modifying
@Query(value = "update qiniu_content set type = ?1", nativeQuery = true)
void update(String type);
}
package me.zhengjie.rest;
import me.zhengjie.aop.log.Log;
import me.zhengjie.domain.LocalStorage;
import me.zhengjie.service.LocalStorageService;
import me.zhengjie.service.dto.LocalStorageQueryCriteria;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import io.swagger.annotations.*;
import org.springframework.web.multipart.MultipartFile;
/**
* @author Zheng Jie
* @date 2019-09-05
*/
@Api(tags = "本地存储管理")
@RestController
@RequestMapping("api")
public class LocalStorageController {
@Autowired
private LocalStorageService localStorageService;
@ApiOperation(value = "查询文件")
@GetMapping(value = "/localStorage")
@PreAuthorize("hasAnyRole('ADMIN','LOCALSTORAGE_ALL','LOCALSTORAGE_SELECT')")
public ResponseEntity getLocalStorages(LocalStorageQueryCriteria criteria, Pageable pageable){
return new ResponseEntity(localStorageService.queryAll(criteria,pageable),HttpStatus.OK);
}
@ApiOperation(value = "上传文件")
@PostMapping(value = "/localStorage")
@PreAuthorize("hasAnyRole('ADMIN','LOCALSTORAGE_ALL','LOCALSTORAGE_CREATE')")
public ResponseEntity create(@RequestParam String name, @RequestParam("file") MultipartFile file){
return new ResponseEntity(localStorageService.create(name, file),HttpStatus.CREATED);
}
@ApiOperation(value = "修改文件")
@PutMapping(value = "/localStorage")
@PreAuthorize("hasAnyRole('ADMIN','LOCALSTORAGE_ALL','LOCALSTORAGE_EDIT')")
public ResponseEntity update(@Validated @RequestBody LocalStorage resources){
localStorageService.update(resources);
return new ResponseEntity(HttpStatus.NO_CONTENT);
}
@ApiOperation(value = "删除文件")
@DeleteMapping(value = "/localStorage/{id}")
@PreAuthorize("hasAnyRole('ADMIN','LOCALSTORAGE_ALL','LOCALSTORAGE_DELETE')")
public ResponseEntity delete(@PathVariable Long id){
localStorageService.delete(id);
return new ResponseEntity(HttpStatus.OK);
}
/**
* 删除多张图片
* @param ids
* @return
*/
@Log("删除图片")
@DeleteMapping(value = "/localStorage")
public ResponseEntity deleteAll(@RequestBody Long[] ids) {
localStorageService.deleteAll(ids);
return new ResponseEntity(HttpStatus.OK);
}
}
\ No newline at end of file
......@@ -38,6 +38,7 @@ public class QiniuController {
@PutMapping(value = "/qiNiuConfig")
public ResponseEntity emailConfig(@Validated @RequestBody QiniuConfig qiniuConfig){
qiNiuService.update(qiniuConfig);
qiNiuService.update(qiniuConfig.getType());
return new ResponseEntity(HttpStatus.OK);
}
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment