1. 添加 字典模块

2. 菜单 添加字典尝试
3. oss 添加权限控制
This commit is contained in:
zhaowenyuan 2024-06-07 17:17:41 +08:00
parent f0a3a39f57
commit a977c11faa
18 changed files with 282 additions and 33 deletions

View File

@ -32,6 +32,11 @@
<artifactId>chushang-common-data-scope</artifactId>
<version>${common.version}</version>
</dependency>
<dependency>
<groupId>com.chushang</groupId>
<artifactId>chushang-common-dict</artifactId>
<version>${common.version}</version>
</dependency>
<dependency>
<groupId>com.chushang</groupId>
<artifactId>chushang-common-easy-es</artifactId>

View File

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>chushang-common</artifactId>
<groupId>com.chushang</groupId>
<version>1.0.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<version>1.0.0</version>
<artifactId>chushang-common-dict</artifactId>
<dependencies>
<dependency>
<groupId>com.chushang</groupId>
<artifactId>chushang-common-core</artifactId>
</dependency>
<dependency>
<groupId>com.chushang</groupId>
<artifactId>chushang-common-redis</artifactId>
</dependency>
<dependency>
<groupId>com.chushang</groupId>
<artifactId>chushang-common-feign</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,22 @@
package com.chushang.common.dict.annotation;
import com.chushang.common.dict.jackson.DictJsonSerializer;
import com.fasterxml.jackson.annotation.JacksonAnnotationsInside;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@JacksonAnnotationsInside
@JsonSerialize(using = DictJsonSerializer.class)
public @interface DictFormat {
/**
* 设置字典的type值 (: sys_user_sex)
*/
String dictType() default "";
}

View File

@ -0,0 +1,25 @@
package com.chushang.common.dict.feign;
import com.chushang.common.core.constant.SecurityConstants;
import com.chushang.common.core.web.Result;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestHeader;
import java.util.Map;
/**
* @auther: zhao
* @date: 2024/6/7 14:38
*/
@FeignClient(contextId = "remoteDictDataService",
value = "system-service",
path = "/system/dict/data/remote"
)
public interface RemoteDictDataService {
@GetMapping(value = "/type/{dictType}")
Result<Map<String, String>> getInfo(@PathVariable(value = "dictType") String dictType, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
}

View File

@ -0,0 +1,46 @@
package com.chushang.common.dict.jackson;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.StrUtil;
import com.chushang.common.dict.annotation.DictFormat;
import com.chushang.common.dict.utils.DictUtils;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.BeanProperty;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.ContextualSerializer;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import java.io.IOException;
import java.util.List;
import java.util.Objects;
@Slf4j
public class DictJsonSerializer extends JsonSerializer<Object> implements ContextualSerializer {
private String dictType;
@Override
public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property) throws JsonMappingException {
DictFormat anno = property.getAnnotation(DictFormat.class);
if (Objects.nonNull(anno) && StrUtil.isNotBlank(anno.dictType())) {
this.dictType = anno.dictType();
return this;
}
return prov.findValueSerializer(property.getType(), property);
}
@Override
public void serialize(Object value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
try {
gen.writeObject(value);
gen.writeFieldName(gen.getOutputContext().getCurrentName() + "Name");
String dictLabel = DictUtils.getDictLabel(dictType, Convert.toStr(value));
gen.writeString(dictLabel);
} catch (BeansException e) {
log.error("字典数据未查到, 采用默认处理【{}】", e.getMessage());
gen.writeObject(value);
}
}
}

View File

@ -0,0 +1,59 @@
package com.chushang.common.dict.utils;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.chushang.common.core.web.Result;
import com.chushang.common.dict.feign.RemoteDictDataService;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RBucket;
import org.redisson.api.RedissonClient;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Slf4j
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class DictUtils {
private static final RemoteDictDataService remoteService = SpringUtil.getBean(RemoteDictDataService.class);
private static final RedissonClient redissonClient = SpringUtil.getBean(RedissonClient.class);
private static final String DICT_MAP_KEY = "dict_map_key:";
private static final Map<String, Map<String, String>> DICT_CACHE = MapUtil.newConcurrentHashMap(25);
/**
* 远程调用
*/
private static Map<String, String> getDictDataByType(String dictType) {
// 获取到的缓存
Result<Map<String, String>> result = remoteService.getInfo(dictType, "inner");
if (result.isSuccess()) {
return result.getData();
}
return new HashMap<>();
}
/**
* 根据字段值获取字典标签
*
* @param dictType 字典类型
* @param value 字典值
* @return 字典标签
*/
public static String getDictLabel(String dictType, String value) {
RBucket<Map<String, String>> bucket = redissonClient.getBucket(DICT_MAP_KEY + dictType);
Map<String, String> dictMap = bucket.get();
if (CollUtil.isEmpty(dictMap)) {
dictMap = getDictDataByType(dictType);
if (CollUtil.isEmpty(dictMap)) {
return null;
}
bucket.set(dictMap);
}
return dictMap.get(value);
}
}

View File

@ -0,0 +1 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=

View File

@ -18,6 +18,7 @@
<module>chushang-common-canal</module>
<module>chushang-common-core</module>
<module>chushang-common-data-scope</module>
<module>chushang-common-dict</module>
<module>chushang-common-easy-es</module>
<module>chushang-common-excel</module>
<module>chushang-common-feign</module>

View File

@ -24,6 +24,7 @@ public interface RemoteOssService {
@RequestParam(value = "ocrType", required = false) String ocrType,
@RequestParam(value = "sealFlag", required = false, defaultValue= "false") Boolean sealFlag,
@RequestParam(value = "formats", required = false) String formats,
@RequestParam(value = "fileType", required = false) String fileType,
@RequestHeader(SecurityConstants.FROM_SOURCE) String source);
}

View File

@ -14,6 +14,7 @@ import com.chushang.oss.enums.OcrTypeEnum;
import com.chushang.oss.remote.RemoteFileController;
import com.chushang.oss.service.FileSourceService;
import com.chushang.oss.service.OcrService;
import com.chushang.security.annotation.RequiresPermissions;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
@ -37,15 +38,19 @@ public class FileController {
*/
@SysLog(value = "文件上传", businessType = BusinessType.INSERT)
@PostMapping(value = "/upload")
@RequiresPermissions("system:file:upload")
public AjaxResult uploadFile(@RequestParam(value = "files") MultipartFile[] files,
@RequestParam(value = "ocrType", required = false) String ocrType,
@RequestParam(value = "sealFlag", required = false, defaultValue= "false") Boolean sealFlag,
@RequestParam(value = "formats", required = false) String formats)
@RequestParam(value = "formats", required = false) String formats,
@RequestParam(value = "fileType", required = false) String fileType)
{
return AjaxResult.success(fileSourceService.addFile(files, ocrType, sealFlag, formats));
return AjaxResult.success(fileSourceService.addFile(files, ocrType, sealFlag, formats, fileType));
}
@SysLog(value = "文件预览", businessType = BusinessType.OTHER)
@GetMapping(value="/{fid}/preview")
@RequiresPermissions("system:file:preview")
public void preview(@PathVariable String fid, HttpServletResponse response)
{
log.info("[OSS]preview Request --> param:{}",fid);
@ -54,20 +59,23 @@ public class FileController {
@SysLog(value = "文件下载", businessType = BusinessType.OTHER)
@GetMapping(value = "/download/{fid}")
@RequiresPermissions("system:file:download")
public void downloadFile(@PathVariable String fid, HttpServletResponse response) {
log.info("[OSS]preview Request --> param:{}",fid);
log.info("[OSS]download Request --> param:{}",fid);
fileSourceService.getFileStream(fid, response, false);
}
@SysLog(value = "文件", businessType = BusinessType.DELETE)
@DeleteMapping(value = "/del/{fid}")
@RequiresPermissions("system:file:del")
public AjaxResult delFile(@PathVariable String fid) {
fileSourceService.delFile(fid);
return AjaxResult.success();
}
@SysLog(value = "文件", businessType = BusinessType.DELETE)
@SysLog(value = "批量文件", businessType = BusinessType.DELETE)
@DeleteMapping(value = "/del/batch")
@RequiresPermissions("system:file:del")
public AjaxResult delFile(@RequestBody List<String> fids) {
fileSourceService.delFileBatch(fids);
return AjaxResult.success();

View File

@ -1,25 +1,19 @@
package com.chushang.oss.remote;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSONObject;
import com.chushang.common.core.web.AjaxResult;
import com.chushang.common.core.web.Result;
import com.chushang.common.log.annotation.SysLog;
import com.chushang.common.log.enums.BusinessType;
import com.chushang.oss.entity.dto.OcrDTO;
import com.chushang.oss.entity.vo.FileSourceVo;
import com.chushang.oss.enums.OcrTypeEnum;
import com.chushang.oss.feign.RemoteOssService;
import com.chushang.oss.service.FileSourceService;
import com.chushang.oss.service.OcrService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
@Slf4j
@ -31,8 +25,13 @@ public class RemoteFileController implements RemoteOssService {
@Override
@SysLog(value = "feign文件上传", businessType = BusinessType.INSERT)
@PostMapping(value = "/upload")
public Result<List<FileSourceVo>> uploadFile(MultipartFile[] files, String ocrType, Boolean sealFlag, String formats, String source) {
return Result.ok(fileSourceService.addFile(files, ocrType, sealFlag, formats));
public Result<List<FileSourceVo>> uploadFile(@RequestParam(value = "files") MultipartFile[] files,
@RequestParam(value = "ocrType", required = false) String ocrType,
@RequestParam(value = "sealFlag", required = false, defaultValue= "false") Boolean sealFlag,
@RequestParam(value = "formats", required = false) String formats,
String source,
@RequestParam(value = "fileType", required = false) String fileType) {
return Result.ok(fileSourceService.addFile(files, ocrType, sealFlag, formats, fileType));
}
}

View File

@ -15,6 +15,7 @@ import com.chushang.common.core.util.FileUtils;
import com.chushang.common.core.util.IPUtils;
import com.chushang.common.core.util.ServletUtils;
import com.chushang.common.mybatis.enums.Operator;
import com.chushang.oss.config.UploadConfig;
import com.chushang.oss.entity.FileSourceInfo;
import com.chushang.oss.entity.dto.OcrDTO;
import com.chushang.oss.entity.vo.FileSourceVo;
@ -27,7 +28,6 @@ import org.apache.tika.mime.MimeTypeException;
import org.apache.tika.mime.MimeTypes;
import org.redisson.api.RMap;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
@ -54,8 +54,8 @@ public class FileSourceService
RedissonClient redissonClient;
@Resource
OcrService ocrService;
@Value("${config.oss.storage}")
private String storage;
@Resource
UploadConfig uploadConfig;
private String generateFid() {
String uuid = IdUtil.simpleUUID();
@ -69,8 +69,9 @@ public class FileSourceService
* @param file 文件
* @param sealFlag
* @param formats
* @param fileType
*/
public FileSourceVo addFile(MultipartFile file, Boolean sealFlag, String formats)
public FileSourceVo addFile(MultipartFile file, Boolean sealFlag, String formats, String fileType)
{
String ip = IPUtils.clientIp(ServletUtils.getRequest());
String fid = generateFid();
@ -99,12 +100,14 @@ public class FileSourceService
String path = ossService.getPrefixPath(md5,fName);
// 不带https 的路径
info.setPath(path);
info.setStorage(storage);
info.setStorage(uploadConfig.getStorage());
info.setUploadIp(ip);
// 上传到 oss 或者 minio
String realPath = ossService.upload(file.getBytes(), info, sealFlag, formats);
// 带https 的路径
info.setRealPath(realPath);
info.setFileType(fileType);
info.setBucketName(uploadConfig.getBucketName());
RMap<String, FileSourceInfo> map = redissonClient.getMap("OSS-Cache");
map.put(fid, info);
// 入库
@ -121,10 +124,10 @@ public class FileSourceService
return vo;
}
public List<FileSourceVo> addFile(MultipartFile[] files,String ocrType, Boolean sealFlag, String formats){
public List<FileSourceVo> addFile(MultipartFile[] files, String ocrType, Boolean sealFlag, String formats, String fileType){
List<FileSourceVo> result = new ArrayList<>();
for (MultipartFile file : files) {
FileSourceVo info = addFile(file, sealFlag, formats);
FileSourceVo info = addFile(file, sealFlag, formats, fileType);
if (StrUtil.isNotEmpty(ocrType)) {
OcrDTO ocr = new OcrDTO();
OcrTypeEnum ocrTypeEnum = OcrTypeEnum.findByCode(ocrType);

View File

@ -37,5 +37,9 @@
<groupId>com.chushang</groupId>
<artifactId>chushang-common-data-scope</artifactId>
</dependency>
<dependency>
<groupId>com.chushang</groupId>
<artifactId>chushang-common-dict</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -1,6 +1,7 @@
package com.chushang.system.entity.po;
import com.baomidou.mybatisplus.annotation.*;
import com.chushang.common.dict.annotation.DictFormat;
import com.chushang.common.mybatis.base.BaseEntity;
import com.chushang.system.entity.enums.MenuTypeEnum;
import lombok.*;
@ -59,18 +60,22 @@ public class SysMenu extends BaseEntity {
/**
* 是否 外链 1 为内链, 0 为外链
*/
@DictFormat(dictType = "sys_frame_no")
private Boolean frame;
/** 是否缓存1缓存 0不缓存 */
@DictFormat(dictType = "sys_cache_nocache")
private Boolean cache;
/**
* 是否显示 1 显示
*/
@DictFormat(dictType = "sys_show_hide")
private Boolean visible;
/**
* 状态 0 停用
*/
@DictFormat(dictType = "sys_menu_status")
private Boolean status;
/**

View File

@ -31,9 +31,6 @@ public class DictController {
@Resource
SysDictDataService dictDataService;
@Resource
ISysDictTypeService dictTypeService;
/**
* 获取字典数据值
*/

View File

@ -32,11 +32,12 @@ public class MenuController {
/**
* 获取菜单列表
*/
@RequiresPermissions("system:menu:list")
// @RequiresPermissions("system:menu:list")
@GetMapping("/list")
public AjaxResult list(ListMenuDTO listMenu)
{
Long userId = SecurityUtils.getUserId();
// Long userId = SecurityUtils.getUserId();
Long userId = 1L;
List<SysMenu> menus = menuService.selectMenuList(listMenu, userId);
return AjaxResult.success(menus);
}

View File

@ -0,0 +1,43 @@
package com.chushang.system.remote;
import cn.hutool.core.collection.CollectionUtil;
import com.chushang.common.core.web.Result;
import com.chushang.common.dict.feign.RemoteDictDataService;
import com.chushang.security.annotation.InnerAuth;
import com.chushang.system.entity.po.SysDictData;
import com.chushang.system.service.SysDictDataService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* @auther: zhao
* @date: 2024/6/7 14:39
*/
@RestController
@RequestMapping(value = "/dict/data/remote")
public class RemoteDictDataController implements RemoteDictDataService {
@Resource
SysDictDataService dictDataService;
/**
* 获取字典数据值
*/
@GetMapping(value = "/type/{dictType}")
@InnerAuth
public Result<Map<String, String>> getInfo(@PathVariable String dictType, String source)
{
List<SysDictData> sysDictData = dictDataService.selectDictDataByType(dictType);
Map<String, String> resultMap = new HashMap<>();
if (CollectionUtil.isNotEmpty(sysDictData)){
resultMap = sysDictData.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel, (o,n)->n));
}
return Result.ok(resultMap);
}
}

View File

@ -56,15 +56,15 @@ public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> impl
@Override
public List<SysMenu> selectMenuList(ListMenuDTO menu, Long userId) {
List<SysMenu> menuList;
if (SecurityUtils.isAdmin())
{
// if (SecurityUtils.isAdmin())
// {
menuList = baseMapper.selectMenuList(menu);
}
else
{
menu.getSqlParam().put("userId", userId);
menuList = baseMapper.selectMenuListByUserId(menu);
}
// }
// else
// {
// menu.getSqlParam().put("userId", userId);
// menuList = baseMapper.selectMenuListByUserId(menu);
// }
return menuList;
}