fix(*) 首次提交ResourceManager项目

This commit is contained in:
2023-08-23 16:39:04 +08:00
parent e34b326d9f
commit 4d8f27a991
28 changed files with 1677 additions and 0 deletions

2
.gitignore vendored
View File

@ -23,3 +23,5 @@
/Feign/src/main/resources/application-test.yml /Feign/src/main/resources/application-test.yml
/Feign/src/main/resources/bootstrap-test.yml /Feign/src/main/resources/bootstrap-test.yml
/Gateway/src/main/resources/application-test.yml /Gateway/src/main/resources/application-test.yml
/ResourceManager/src/main/resources/application-test.yml
/ResourceManager/src/main/resources/bootstrap-test.yml

145
ResourceManager/pom.xml Normal file
View File

@ -0,0 +1,145 @@
<?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">
<modelVersion>4.0.0</modelVersion>
<groupId>cn.crtech.cloud.resource_manager</groupId>
<artifactId>ResourceManager</artifactId>
<version>1.0.1</version>
<!-- 父工程 -->
<parent>
<groupId>cn.crtech.cloud.dependencies</groupId>
<artifactId>Dependencies</artifactId>
<version>1.0.1</version>
<relativePath/>
</parent>
<!-- 依赖的版本锁定 -->
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<aliyun.oss.version>3.13.2</aliyun.oss.version>
<minio.version>7.0.2</minio.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<!-- 使用launcher启动时放开 begin-->
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
<!-- 使用launcher启动时放开 end-->
</dependency>
<!-- 使用launcher启动时放开 begin -->
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<scope>provided</scope>
</dependency>
<!-- 使用launcher启动时放开 end -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<!-- nacos 客户端-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- 微服务RPC调用 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!-- 热部署 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional> <!-- 这个需要为 true 热部署才有效 -->
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<exclusions>
<exclusion>
<groupId>io.lettuce</groupId>
<artifactId>lettuce-core</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<dependency>
<groupId>cn.crtech.cloud.common</groupId>
<artifactId>Common</artifactId>
<version>1.0.1</version>
</dependency>
<!--阿里云oss-->
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>${aliyun.oss.version}</version>
</dependency>
<!--minio-->
<dependency>
<groupId>io.minio</groupId>
<artifactId>minio</artifactId>
<version>${minio.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<fork>true</fork>
<jvmArguments>-Dfile.encoding=UTF-8</jvmArguments>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,33 @@
package cn.crtech.cloud.resmanager;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import tk.mybatis.spring.annotation.MapperScan;
//微服务启动时使用 begin
@EnableDiscoveryClient
@SpringBootApplication
@MapperScan("cn.crtech.cloud.resmanager.mapper")
public class ResmanagerApplcation {
public static void main(String[] args) {
SpringApplication.run(ResmanagerApplcation.class, args);
}
}
//微服务启动时使用 end
//使用launcher启动时使用 begin
//launcher.NacosConfig @Component需要放开
//
//@SpringBootApplication
//@MapperScan("cn.crtech.cloud.resmanager.mapper")
//public class ResmanagerApplcation extends SpringBootServletInitializer {
// @Override
// protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
// return application.sources(ResmanagerApplcation.class);
// }
//}
//使用launcher启动时使用 end

View File

@ -0,0 +1,18 @@
package cn.crtech.cloud.resmanager.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Data
@Component
@ConfigurationProperties(prefix = "resmanager.aliyunoss")
public class AliYunOSSConfig {
private String serverUrl;
private String accessKey;
private String secretKey;
private String bucketName;
}

View File

@ -0,0 +1,14 @@
package cn.crtech.cloud.resmanager.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Data
@Component
@ConfigurationProperties(prefix = "resmanager.local")
public class LocalConfig {
private String path;
private String bucketName;
}

View File

@ -0,0 +1,26 @@
package cn.crtech.cloud.resmanager.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Data
@Component
@ConfigurationProperties(prefix = "resmanager.minio")
public class MinioConfig {
private String endpoint;
private Integer port;
private String accessKey;
private String secretKey;
private String bucketName;
private Boolean secure;
private String accessType;
private Integer urlExpires;
}

View File

@ -0,0 +1,30 @@
package cn.crtech.cloud.resmanager.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.repository.configuration.EnableRedisRepositories;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
/**
* Redis相关配置
*/
@Configuration
@EnableRedisRepositories
public class RedisRepositoryConfig {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(connectionFactory);
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
redisTemplate.setKeySerializer(stringRedisSerializer);
redisTemplate.setHashKeySerializer(stringRedisSerializer);
Jackson2JsonRedisSerializer<?> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
redisTemplate.afterPropertiesSet();
return redisTemplate;
}
}

View File

@ -0,0 +1,181 @@
package cn.crtech.cloud.resmanager.controller;
import cn.crtech.cloud.common.api.CommonResult;
import cn.crtech.cloud.common.utils.ThumbnailatorUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.json.JSONObject;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.ObjectMetadata;
import com.aliyun.oss.model.PutObjectResult;
import io.minio.MinioClient;
import io.minio.PutObjectOptions;
import io.minio.errors.*;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.*;
/**
* Author : yj
* Date : 2021-03-19
* Description:
*/
@RestController
@RequestMapping("/file")
public class FileController {
private static String endpoint = "http://oss-cn-chengdu.aliyuncs.com";
private static String accessKeyId = "LTAI5tGBETbnyAS6tAxULF8M";
private static String accessKeySecret = "lJppRT678UVMWJr9EBaJfbKdoZ7eBl";
private static String bucketName = "crtechtest";
@RequestMapping("/u1")
public CommonResult uploadFileTOALiYUN(HttpServletRequest request, HttpServletResponse response) {
OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
List<MultipartFile> files = ((MultipartHttpServletRequest) request).getFiles("file");
files.stream().forEach(file -> {
System.out.println(file.getOriginalFilename());
//System.out.println(file.getBytes());
System.out.println(file.getName());
System.out.println(file.getContentType());
System.out.println(file.getSize());
String fileKey = file.getOriginalFilename();
System.out.println();
try {
ObjectMetadata objectMetadata = new ObjectMetadata();
objectMetadata.setContentType("image/jpg");
PutObjectResult putObjectResult = ossClient.putObject(bucketName, fileKey, file.getResource().getInputStream(), objectMetadata);
// 设置URL过期时间为10年 3600l* 1000*24*365*10
Date expiration = new Date(new Date().getTime() + 3600l * 1000 * 24 * 365 * 10);
URL url = ossClient.generatePresignedUrl(bucketName, fileKey, expiration);
System.out.println(putObjectResult.getETag());
System.out.println(putObjectResult.getVersionId());
System.out.println(putObjectResult.getRequestId());
System.out.println(putObjectResult.getServerCRC());
System.out.println(url);
} catch (IOException e) {
ossClient.shutdown();
e.printStackTrace();
}
ossClient.shutdown();
});
return CommonResult.success(null);
}
@RequestMapping("/u")
public CommonResult uploadFileTOMINIO(HttpServletRequest request, HttpServletResponse response) throws Exception {
try {
// 使用MinIO服务的URL端口Access key和Secret key创建一个MinioClient对象
MinioClient minioClient = new MinioClient("http://localhost:9000", "minio", "KWbPmRsTWre2X2X6");
String bucketName = "bucket1";
// 检查存储桶是否已经存在
boolean isExist = minioClient.bucketExists(bucketName);
if (isExist) {
System.out.println("Bucket already exists.");
} else {
// 创建一个名为asiatrip的存储桶用于存储照片的zip文件。
minioClient.makeBucket(bucketName);
JSONObject jsonObject = new JSONObject();
ArrayList<Map<String, Object>> object = new ArrayList<Map<String, Object>>();
Map<String, Object> Map1 = new HashMap<>();
String[] str = new String[]{"s3:GetBucketLocation", "s3:ListBucket"};
Map1.put("Action", str);
Map1.put("Effect", "Allow");
Map1.put("Principal", "*");
Map1.put("Resource", "arn:aws:s3:::" + bucketName);
object.add(Map1);
Map<String, Object> Map2 = new HashMap<>();
Map2.put("Action", "s3:GetObject");
Map2.put("Effect", "Allow");
Map2.put("Principal", "*");
Map2.put("Resource", "arn:aws:s3:::" + bucketName + "/myobject*");
object.add(Map2);
jsonObject.set("Statement", object);
jsonObject.set("Version", "2012-10-17");
String policyJson = jsonObject.toString();
minioClient.setBucketPolicy(bucketName, policyJson);
}
String bucketPolicy = minioClient.getBucketPolicy(bucketName);
System.out.println(bucketPolicy);
List<MultipartFile> files = ((MultipartHttpServletRequest) request).getFiles("file");
String objectUrl = null;
for (MultipartFile file : files) {
//InputStream inputStream1 = file.getInputStream();
String fileKey = file.getOriginalFilename();
String fileType = fileKey.split(".")[1];
System.out.println(fileKey);
//System.out.println(file.getBytes());
System.out.println(file.getName());
System.out.println(file.getContentType());
System.out.println(file.getSize());
PutObjectOptions putObjectOptions = new PutObjectOptions(-1, 5L * 1024 * 1024);
putObjectOptions.setContentType("image/jpeg;charset=UTF-8");
// putObjectOptions.setContentType();
// putObjectOptions.setHeaders();
// 使用putObject上传一个文件到存储桶中。
try {
InputStream inputStream = file.getResource().getInputStream();
byte[] bytes = ThumbnailatorUtil.compressImageWithWH(file.getBytes(), 256, 256);
minioClient.putObject(bucketName, IdUtil.simpleUUID() + "." + fileType, inputStream, putObjectOptions);
objectUrl = minioClient.getObjectUrl(bucketName, fileKey);
System.out.println("====objectUrl===" + objectUrl);
} catch (ErrorResponseException e) {
e.printStackTrace();
} catch (InsufficientDataException e) {
e.printStackTrace();
} catch (InternalException e) {
e.printStackTrace();
} catch (InvalidBucketNameException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (InvalidResponseException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (XmlParserException e) {
e.printStackTrace();
}
}
// files.stream().forEach(file -> {
//
//
// });
Map<String, Object> retMap = new HashMap<>();
retMap.put("url", objectUrl);
return CommonResult.success(retMap);
} catch (Exception e) {
throw e;
}
}
}

View File

@ -0,0 +1,242 @@
package cn.crtech.cloud.resmanager.controller;
import cn.crtech.cloud.common.api.CommonResult;
import cn.crtech.cloud.common.dto.Result;
import cn.crtech.cloud.resmanager.pojo.Resource;
import cn.crtech.cloud.resmanager.service.ResourceService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@RestController
@RequestMapping("/")
public class ResourceController {
@Autowired
private ResourceService service;
@PostMapping("/list")
public CommonResult list(@RequestBody List<String> fileIds) throws Exception {
List<Resource> resources = service.listByIds(fileIds);
return CommonResult.success(resources);
}
@PostMapping("/remove")
public CommonResult remove(@RequestBody List<String> fileIds) throws Exception {
return CommonResult.success(service.remove(fileIds));
}
@PostMapping("/commit")
public CommonResult commit(@RequestBody List<String> fileIds) throws Exception {
return CommonResult.success(service.commit(fileIds));
}
@PostMapping("/rollback")
public CommonResult rollback(@RequestBody List<String> fileIds) throws Exception {
return CommonResult.success(service.rollback(fileIds));
}
/**
* 获取文件实际显示访问url
*
* @param fileId 文件ID
* @param response 返回结果
* @throws Exception 文件不存在/解析异常
*/
@GetMapping("/s/{fileId}")
public void showUrl(@PathVariable(value = "fileId") String fileId,
final HttpServletResponse response) throws Exception {
// return CommonResult.success(service.getUrl(fileId, false));
response.sendRedirect(service.getUrl(fileId, false));
}
@GetMapping("/getUrl/{fileId}")
public CommonResult getUrl(@PathVariable(value = "fileId") String fileId,
final HttpServletResponse response) throws Exception {
return CommonResult.success(service.getUrl(fileId, false));
}
/**
* @param params 参数
* <ul>
* <li>list: 文件ID集合</li>
* </ul>
* @return 返回查询结果
*/
@PostMapping("/s/much")
public CommonResult showMuchUrl(@RequestBody Map<String, Object> params) throws Exception {
List<String> list = (List<String>) params.get("list");
if (list.size() > 0) {
return CommonResult.success(service.getMuchUrl(list, false));
} else {
return CommonResult.failed("参数为空");
}
}
/**
* 获取文件实际下载url
*
* @param fileId 文件ID
* @param response 返回数据对象集合
* @throws Exception 可能存在文件不存在等异常
*/
@GetMapping("/d/{fileId}")
public void downloadUrl(@PathVariable(value = "fileId") String fileId,
final HttpServletResponse response) throws Exception {
response.sendRedirect(service.getUrl(fileId, true));
}
/**
* 使用本地链接访问时显示或下载文件流
* 本地存储时最后建议使用nginx做转发
* TODO: MinIO和AliYunOSS时由于要获取流可能要考虑做二级资源缓存然后使用nginx做转发
*
* @param contentType1
* @param contentType2
* @param request
* @param response
* @return
* @throws Exception
* @Params ** path: /ls/erp/prescription/202305111110183b5464d7ce964493a1e0a7714109cc48
*/
@GetMapping({"/res/{contentType1}/{contentType2}/**", "/down/{contentType1}/{contentType2}/**"})
public ResponseEntity<StreamingResponseBody> getSteam(
@PathVariable(value = "contentType1") String contentType1,
@PathVariable(value = "contentType2") String contentType2,
final HttpServletRequest request,
final HttpServletResponse response) throws Exception {
boolean download = request.getRequestURI().startsWith("/down");
response.setContentType(contentType1 + "/" + contentType2);
if (download) {
response.setHeader("Content-Disposition", "attachment");
}
String relativePath = "/" + URLDecoder.decode(request.getRequestURI().substring(((download ? "/down/" : "/res/") + contentType1 + "/" + contentType2 + "/").length()), "UTF-8");
StreamingResponseBody stream = outputStream -> {
InputStream inputStream = null;
try {
inputStream = service.getStreamByPath(relativePath);
byte[] bytes = new byte[1024];
int len;
while ((len = inputStream.read(bytes)) != -1) {
outputStream.write(bytes, 0, len);
}
outputStream.flush();
} catch (Exception e) {
throw new IOException(e);
} finally {
if (inputStream != null) inputStream.close();
if (outputStream != null) outputStream.close();
}
};
return new ResponseEntity(stream, HttpStatus.OK);
}
@PostMapping("/upload")
public CommonResult addFile(
@RequestParam(name = "file") MultipartFile file,
@RequestParam(name = "path") String path,
@RequestParam(name = "name") String name,
@RequestParam(name = "description") String description) throws Exception {
Resource resource = service.addFile(file, path, name, description);
return CommonResult.success(resource);
}
/**
* 拷贝文件
*
* @param fileId
* @return
* @throws Exception
*/
@GetMapping("/copyOfMinIoFile")
public Result copyOfMinIoFile(@RequestParam("fileId") String fileId) throws Exception {
return Result.success(service.copyOfMinIoFile(fileId));
}
/**
* 通过文件id获取文件流
*
* @param fileId
* @return
*/
@GetMapping("/getFileStream")
public ResponseEntity<StreamingResponseBody> getFileStream(@RequestParam("fileId") String fileId) {
StreamingResponseBody stream = outputStream -> {
InputStream inputStream = null;
try {
inputStream = service.getStreamByFileId(fileId);
byte[] bytes = new byte[1024];
int len;
while ((len = inputStream.read(bytes)) != -1) {
outputStream.write(bytes, 0, len);
}
outputStream.flush();
} catch (Exception e) {
throw new IOException(e);
} finally {
if (inputStream != null) inputStream.close();
outputStream.close();
}
};
return new ResponseEntity(stream, HttpStatus.OK);
}
/**
* 使用本地链接访问时显示或下载文件流
* 本地存储时最后建议使用nginx做转发
* TODO: MinIO和AliYunOSS时由于要获取流可能要考虑做二级资源缓存然后使用nginx做转发
*
* @param request
* @param response
* @return
* @throws Exception
* @Params ** path: /ls/erp/prescription/202305111110183b5464d7ce964493a1e0a7714109cc48
*/
@GetMapping({"/byte/res/stream/{fileId}", "/byte/down/stream/{fileId}"})
public CommonResult getFileStreamByteByFileId(
@PathVariable(name = "fileId") String fileId,
final HttpServletRequest request,
final HttpServletResponse response) throws Exception {
boolean download = request.getRequestURI().startsWith("/down");
if (download) {
response.setHeader("Content-Disposition", "attachment");
}
Resource resource = service.get(fileId);
String relativePath = URLDecoder.decode(resource.getPath() + "/" + resource.getName(), "UTF-8");
InputStream inputStream = service.getStreamByPath(relativePath);
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int num = inputStream.read(buffer);
while (num != -1) {
baos.write(buffer, 0, num);
num = inputStream.read(buffer);
}
baos.flush();
Map<String, Object> fileMap = new HashMap<>();
fileMap.put("fileByteArray", baos.toByteArray());
return CommonResult.success(fileMap, "获取成功");
} finally {
if (inputStream != null) {
inputStream.close();
}
}
}
}

View File

@ -0,0 +1,14 @@
package cn.crtech.cloud.resmanager.general;
import cn.crtech.cloud.common.api.CommonResult;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import java.util.Map;
@FeignClient("crtech-cloud-general")
public interface UserController {
@RequestMapping("/user/info")
CommonResult getUserInfo(@RequestBody Map<String, String> map);
}

View File

@ -0,0 +1,42 @@
package cn.crtech.cloud.resmanager.holder;
import cn.crtech.cloud.common.dto.UserDto;
import cn.hutool.core.convert.Convert;
import cn.hutool.json.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
/**
* 获取登录用户信息
* Created by macro on 2020/6/17.
*/
@Component
public class LoginUserHolder {
public UserDto getCurrentUser() {
//从Header中获取用户信息
ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = servletRequestAttributes.getRequest();
String userStr = null;
UserDto userDto = new UserDto();
try {
if (!StringUtils.isBlank(request.getHeader("user"))) {
userStr = URLDecoder.decode(request.getHeader("user"), "UTF-8");
JSONObject userJsonObject = new JSONObject(userStr);
userDto.setCompanyCode(userJsonObject.getStr("company_code"));
userDto.setUserName(userJsonObject.getStr("user_name"));
userDto.setId(Integer.valueOf(userJsonObject.getStr("id")));
userDto.setRoles(Convert.toList(String.class, userJsonObject.get("authorities")));
return userDto;
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return null;
}
}

View File

@ -0,0 +1,10 @@
package cn.crtech.cloud.resmanager.mapper;
import cn.crtech.cloud.resmanager.pojo.Resource;
import org.springframework.stereotype.Repository;
import tk.mybatis.mapper.additional.idlist.SelectByIdListMapper;
import tk.mybatis.mapper.common.Mapper;
@Repository
public interface ResourceMapper extends Mapper<Resource>, SelectByIdListMapper<Resource, String> {
}

View File

@ -0,0 +1,46 @@
package cn.crtech.cloud.resmanager.pojo;
import lombok.Data;
import javax.persistence.*;
import java.util.Date;
@Data
@Table(name = "resources")
public class Resource {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY, generator = "select uuid()")
private String id;
@Column(name = "mime_type")
private String mimeType;
@Column(name = "name")
private String name;
@Column(name = "size")
private Long size;
@Column(name = "path")
private String path;
@Column(name = "description")
private String description;
@Column(name = "create_time")
private Date createTime;
@Column(name = "create_user")
private Integer createUser;
@Column(name = "last_modify_time")
private Date lastModifyTime;
@Column(name = "last_modify_user")
private Integer lastModifyUser;
@Column(name = "is_temp")
private Integer isTemp;
/**
* 1 插入
* 2 修改(基本没用)
* 3 删除
*/
@Column(name = "temp_oper")
private Integer tempOper;
@Transient
private String url;
}

View File

@ -0,0 +1,74 @@
package cn.crtech.cloud.resmanager.server;
import cn.crtech.cloud.resmanager.pojo.Resource;
import cn.crtech.cloud.resmanager.server.impl.AliYunOSSStorage;
import cn.crtech.cloud.resmanager.server.impl.LocalStorage;
import cn.crtech.cloud.resmanager.server.impl.MinioStorage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import javax.validation.constraints.NotNull;
import java.io.InputStream;
@Component
public class ResmanagerServer implements ApplicationRunner {
@Value("${resmanager.type}")
private String type;
private Storage storage;
@Autowired
LocalStorage local;
@Autowired
MinioStorage minio;
@Autowired
AliYunOSSStorage aliYunOSS;
@Override
public void run(ApplicationArguments args) throws Exception {
initStorage();
}
private void initStorage() throws Exception {
if (local.getType().equals(type)) {
storage = local;
} else if (minio.getType().equals(type)) {
storage = minio;
} else if (aliYunOSS.getType().equals(type)) {
storage = aliYunOSS;
} else {
throw new Exception("unknown storage type: " + type);
}
storage.init();
}
public String getUrl(@NotNull Resource file, boolean download) throws Exception {
return storage.getUrl(file, download);
}
public InputStream getStream(String relativePath) throws Exception {
return storage.getStream(relativePath);
}
public InputStream getStreamByResource(Resource resource) throws Exception {
return storage.getStream(resource.getPath() + "/" + resource.getName());
}
public void store(Resource resource, MultipartFile file) throws Exception {
storage.store(resource, file);
}
public void remove(Resource file) throws Exception {
storage.remove(file);
}
public long getExpireTime() {
return storage.getExpireTime();
}
}

View File

@ -0,0 +1,23 @@
package cn.crtech.cloud.resmanager.server;
import cn.crtech.cloud.resmanager.pojo.Resource;
import org.springframework.web.multipart.MultipartFile;
import javax.validation.constraints.NotNull;
import java.io.InputStream;
public interface Storage {
String getType();
void init() throws Exception;
String getUrl(@NotNull Resource file, boolean download) throws Exception;
InputStream getStream(String relativePath) throws Exception;
void store(Resource resource, MultipartFile file) throws Exception;
void remove(Resource file) throws Exception;
long getExpireTime();
}

View File

@ -0,0 +1,50 @@
package cn.crtech.cloud.resmanager.server.impl;
import cn.crtech.cloud.resmanager.config.AliYunOSSConfig;
import cn.crtech.cloud.resmanager.pojo.Resource;
import cn.crtech.cloud.resmanager.server.Storage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import java.io.InputStream;
@Component
public class AliYunOSSStorage implements Storage {
@Autowired
private AliYunOSSConfig config;
@Override
public String getType() {
return "aliyunoss";
}
@Override
public void init() throws Exception {
}
@Override
public String getUrl(Resource file, boolean download) throws Exception {
return null;
}
@Override
public InputStream getStream(String relativePath) throws Exception {
return null;
}
@Override
public void store(Resource resource, MultipartFile file) throws Exception {
}
@Override
public void remove(Resource file) throws Exception {
}
@Override
public long getExpireTime() {
return 0;
}
}

View File

@ -0,0 +1,100 @@
package cn.crtech.cloud.resmanager.server.impl;
import cn.crtech.cloud.resmanager.config.LocalConfig;
import cn.crtech.cloud.resmanager.pojo.Resource;
import cn.crtech.cloud.resmanager.server.Storage;
import cn.hutool.core.util.ArrayUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.net.URLEncoder;
@Component
public class LocalStorage implements Storage {
@Autowired
private LocalConfig config;
@Override
public String getType() {
return "local";
}
@Override
public void init() throws Exception {
File file = new File(config.getPath(), config.getBucketName());
if (!file.exists()) {
file.mkdirs();
}
}
@Override
public String getUrl(Resource file, boolean download) throws Exception {
String[] split = file.getPath().split("/");
for (int i = 0; i < split.length; i++) {
split[i] = URLEncoder.encode(split[i], "UTF-8");
}
String path = "/" + ArrayUtil.join(split, "/") + "/" + URLEncoder.encode(file.getName(), "UTF-8");
if (download) {
return "/down/" + file.getMimeType() + path;
} else {
return "/res/" + file.getMimeType() + path;
}
}
@Override
public InputStream getStream(String relativePath) throws Exception {
File file = new File(config.getPath(), config.getBucketName());
if (!file.exists()) {
file.mkdirs();
}
file = new File(file, relativePath);
if (!file.exists()) {
throw new FileNotFoundException(file.getAbsolutePath());
}
return new FileInputStream(file);
}
@Override
public void store(Resource resource, MultipartFile file) throws Exception {
File f = new File(config.getPath(), config.getBucketName());
if (!f.exists()) {
f.mkdirs();
}
f = new File(f, resource.getPath().substring(1));
if (!f.exists()) {
f.mkdirs();
}
f = new File(f, resource.getName());
if (f.exists()) {
throw new Exception("文件已存在");
}
file.transferTo(f);
}
@Override
public void remove(Resource file) throws Exception {
File f = new File(config.getPath(), config.getBucketName());
if (!f.exists()) {
f.mkdirs();
}
f = new File(f, file.getPath().substring(1));
if (!f.exists()) {
f.mkdirs();
}
f = new File(f, file.getName());
if (f.exists()) {
f.delete();
}
}
@Override
public long getExpireTime() {
return 60 * 60;
}
}

View File

@ -0,0 +1,118 @@
package cn.crtech.cloud.resmanager.server.impl;
import cn.crtech.cloud.resmanager.config.MinioConfig;
import cn.crtech.cloud.resmanager.pojo.Resource;
import cn.crtech.cloud.resmanager.server.Storage;
import cn.hutool.core.util.ArrayUtil;
import io.minio.MinioClient;
import io.minio.ObjectStat;
import io.minio.PutObjectOptions;
import io.minio.errors.ErrorResponseException;
import io.minio.http.Method;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import java.io.InputStream;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;
@Component
public class MinioStorage implements Storage {
@Autowired
private MinioConfig config;
@Override
public String getType() {
return "minio";
}
private MinioClient minioClient;
@Override
public void init() throws Exception {
if (minioClient == null) {
minioClient = new MinioClient(config.getEndpoint(), config.getPort(), config.getAccessKey(), config.getSecretKey(), config.getSecure());
}
if (!minioClient.bucketExists(config.getBucketName())) {
minioClient.makeBucket(config.getBucketName());
//设置桶权限
// JSONObject jsonObject = new JSONObject();
// ArrayList<Map<String,Object>> object = new ArrayList<Map<String, Object>>();
// Map<String,Object> Map1 = new HashMap<>();
// String[] str = new String[]{"s3:GetBucketLocation","s3:ListBucket"};
// Map1.put("Action",str);
// Map1.put("Effect","Allow");
// Map1.put("Principal","*");
// Map1.put("Resource","arn:aws:s3:::"+config.getBucketName());
// object.add(Map1);
// Map<String,Object> Map2 = new HashMap<>();
// Map2.put("Action","s3:GetObject");
// Map2.put("Effect","Allow");
// Map2.put("Principal","*");
// Map2.put("Resource","arn:aws:s3:::"+config.getBucketName()+"/myobject*");
// object.add(Map2);
// jsonObject.set("Statement",object);
// jsonObject.set("Version","2012-10-17");
// String policyJson = jsonObject.toString();
// minioClient.setBucketPolicy(config.getBucketName(),policyJson);
}
}
@Override
public String getUrl(Resource file, boolean download) throws Exception {
String[] split = file.getPath().split("/");
for (int i = 0; i < split.length; i++) {
split[i] = URLEncoder.encode(split[i], "UTF-8");
}
String path = "/" + ArrayUtil.join(split, "/") + "/" + URLEncoder.encode(file.getName(), "UTF-8");
if ("minio".equals(config.getAccessType())) {
Map<String, String> queryParams = new HashMap<>();
if (download) {
queryParams.put("response-content-disposition", "attachment;");
}
return minioClient.getPresignedObjectUrl(Method.GET, config.getBucketName(), file.getPath().substring(1) + "/" + file.getName(), config.getUrlExpires(), queryParams);
} else if (download) {
return "/down/" + file.getMimeType() + path;
} else {
return "/res/" + file.getMimeType() + path;
}
}
@Override
public InputStream getStream(String relativePath) throws Exception {
return minioClient.getObject(config.getBucketName(), relativePath.substring(1));
}
@Override
public void store(Resource resource, MultipartFile file) throws Exception {
try {
ObjectStat objectStat = minioClient.statObject(config.getBucketName(), resource.getPath() + "/" + resource.getName());
if (objectStat != null) {
throw new Exception("文件已存在");
}
PutObjectOptions options = new PutObjectOptions(resource.getSize(), 5L * 1024 * 1024); //5M分片存储
options.setContentType(resource.getMimeType());
minioClient.putObject(config.getBucketName(), resource.getPath() + "/" + resource.getName(), file.getInputStream(), options);
} catch (ErrorResponseException e) {
if ("Object does not exist".equals(e.getMessage())) {
PutObjectOptions options = new PutObjectOptions(resource.getSize(), 5L * 1024 * 1024); //5M分片存储
options.setContentType(resource.getMimeType());
minioClient.putObject(config.getBucketName(), resource.getPath() + "/" + resource.getName(), file.getInputStream(), options);
} else {
throw new Exception(e);
}
}
}
@Override
public void remove(Resource file) throws Exception {
minioClient.removeObject(config.getBucketName(), file.getPath() + "/" + file.getName());
}
@Override
public long getExpireTime() {
return config.getUrlExpires();
}
}

View File

@ -0,0 +1,48 @@
package cn.crtech.cloud.resmanager.service;
import cn.crtech.cloud.common.dto.Result;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.common.Mapper;
import java.util.Map;
/**
* Created by Onion on 2022/01/11.
*/
public abstract class BaseService<T> {
public abstract Mapper<T> getMapper();
@Transactional(propagation = Propagation.REQUIRED)
public Result add(T obj) {
getMapper().insert(obj);
return Result.success(obj, "操作成功!");
}
@Transactional(propagation = Propagation.REQUIRED)
public Result update(T obj) {
getMapper().updateByPrimaryKeySelective(obj);
return Result.success(obj, "操作成功!");
}
@Transactional(propagation = Propagation.REQUIRED)
public Result deleteById(int id) {
getMapper().deleteByPrimaryKey(id);
return Result.success(id, "操作成功!");
}
@Transactional(propagation = Propagation.REQUIRED)
public Result delete(T obj) {
getMapper().delete(obj);
return Result.success(obj, "操作成功!");
}
public T getById(int id) {
return (T) getMapper().selectByPrimaryKey(id);
}
public abstract Result listByPage(Map<String, Object> params);
public abstract Result listByParams(Map<String, Object> params);
}

View File

@ -0,0 +1,203 @@
package cn.crtech.cloud.resmanager.service;
import cn.crtech.cloud.common.dto.Result;
import cn.crtech.cloud.common.utils.CommonFun;
import cn.crtech.cloud.resmanager.mapper.ResourceMapper;
import cn.crtech.cloud.resmanager.pojo.Resource;
import cn.crtech.cloud.resmanager.server.ResmanagerServer;
import cn.hutool.core.util.StrUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import tk.mybatis.mapper.common.Mapper;
import javax.validation.constraints.NotNull;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
@Service("resService")
public class ResourceService extends BaseService<Resource> {
public static final String RESOURCE_URL_KEY = "RM:URL:";
public static final String RESOURCE_DOWNLOAD_KEY = "RM:DOWNLOAD:";
@Autowired
private ResourceMapper resourceMapper;
@Override
public Mapper<Resource> getMapper() {
return resourceMapper;
}
@Autowired
private RedisTemplate redisTemplate;
@Autowired
private ResmanagerServer server;
public Resource get(String fileId) {
return resourceMapper.selectByPrimaryKey(fileId);
}
public List<Resource> listByIds(List<String> fileIds) {
return resourceMapper.selectByIdList(fileIds);
}
public int remove(List<String> fileIds) throws Exception {
for (String fileId : fileIds) {
Resource resource = get(fileId);
if (resource.getIsTemp() == 1 && resource.getTempOper() == 1) {
server.remove(resource);
resourceMapper.deleteByPrimaryKey(fileId);
} else {
resource.setIsTemp(1);
resource.setTempOper(3);
resourceMapper.updateByPrimaryKeySelective(resource);
}
}
return fileIds.size();
}
public int commit(List<String> fileIds) throws Exception {
for (String fileId : fileIds) {
Resource resource = get(fileId);
if (resource.getIsTemp() == 1 && resource.getTempOper() == 3) {
server.remove(resource);
resourceMapper.deleteByPrimaryKey(fileId);
} else if (resource.getIsTemp() == 1) {
resource.setIsTemp(0);
resource.setTempOper(0);
resource.setLastModifyTime(Calendar.getInstance().getTime());
// resource.setLastModifyUser(loginUserHolder.getCurrentUser().getId());
resourceMapper.updateByPrimaryKeySelective(resource);
}
}
return fileIds.size();
}
public int rollback(List<String> fileIds) throws Exception {
for (String fileId : fileIds) {
Resource resource = get(fileId);
if (resource.getIsTemp() == 1 && resource.getTempOper() == 1) {
server.remove(resource);
resourceMapper.deleteByPrimaryKey(fileId);
} else if (resource.getIsTemp() == 1) {
resource.setIsTemp(0);
resource.setTempOper(0);
resourceMapper.updateByPrimaryKeySelective(resource);
}
}
return fileIds.size();
}
public String getUrl(String fileId, boolean download) throws Exception {
String key = (download ? RESOURCE_DOWNLOAD_KEY : RESOURCE_URL_KEY) + fileId;
String url = (String) redisTemplate.opsForValue().get(key);
if (StrUtil.isNotBlank(url)) {
return url;
}
Resource resource = get(fileId);
url = server.getUrl(resource, download);
redisTemplate.opsForValue().set(key, url, server.getExpireTime(), TimeUnit.SECONDS);
return url;
}
public List<String> getMuchUrl(List<String> list, boolean download) throws Exception {
List<String> backList = new ArrayList<>();
for (int i = 0; i <= (list.size() - 1); i++) {
String url = getUrl(list.get(i), download);
backList.add(url);
}
return backList;
}
public InputStream getStream(String fileId) throws Exception {
Resource resource = get(fileId);
return server.getStream(resource.getPath());
}
public InputStream getStreamByFileId(String fileId) throws Exception {
return server.getStreamByResource(get(fileId));
}
public InputStream getStreamByPath(String relativePath) throws Exception {
return server.getStream(relativePath);
}
public Resource addFile(@NotNull MultipartFile file, String path, String name, String description) throws Exception {
/* UserDto userDto = loginUserHolder.getCurrentUser();*/
Resource resource = new Resource();
resource.setId(CommonFun.getSSID() + "");
resource.setMimeType(file.getContentType());
resource.setName(StrUtil.isBlank(name) ? file.getOriginalFilename() : name);
resource.setSize(file.getSize());
resource.setPath(StrUtil.isBlank(path) ? "/" : (path.startsWith("/") ? path : ("/" + path)));
resource.setDescription(description);
resource.setCreateTime(Calendar.getInstance().getTime());
/* if (userDto != null) {
resource.setCreateUser(loginUserHolder.getCurrentUser().getId());
resource.setLastModifyUser(loginUserHolder.getCurrentUser().getId());
}*/
resource.setLastModifyTime(Calendar.getInstance().getTime());
resource.setIsTemp(1);
resource.setTempOper(1);
synchronized (this) {
server.store(resource, file);
}
resourceMapper.insert(resource);
return resource;
}
public Resource copyOfMinIoFile(String fileId) throws Exception {
Resource selectResource = get(fileId);
if (selectResource == null) {
return null;
}
MultipartFile multipartFile = new MockMultipartFile(selectResource.getName(), getStreamByFileId(fileId));
String fileName = selectResource.getName();
//创建新文件
Resource resource = new Resource();
resource.setId(CommonFun.getSSID() + "");
resource.setMimeType(selectResource.getMimeType());
resource.setName(CommonFun.getSSID() + "." + getFileSuffixName(selectResource.getName()));
resource.setSize(multipartFile.getSize());
resource.setPath(selectResource.getPath());
resource.setDescription("复制文件");
resource.setCreateTime(Calendar.getInstance().getTime());
resource.setLastModifyTime(Calendar.getInstance().getTime());
resource.setIsTemp(1);
resource.setTempOper(1);
synchronized (this) {
server.store(resource, multipartFile);
}
resourceMapper.insert(resource);
return resource;
}
public static String getFileSuffixName(String image_name) {
return image_name.contains(".") ? image_name.substring(image_name.lastIndexOf(".") + 1) : null;
}
@Override
public Result listByPage(Map<String, Object> params) {
return null;
}
@Override
public Result listByParams(Map<String, Object> params) {
return null;
}
}

View File

@ -0,0 +1,49 @@
server:
port: 8082
servlet:
encoding:
charset: utf-8
enabled: true
force: true
tomcat:
uri-encoding: UTF-8
logging:
config: classpath:logback.xml
file:
path: logs/crtech-cloud-resmanager.log
level:
cn.crtech.cloud.resmanager: debug
spring:
servlet:
multipart:
enabled: true
max-file-size: 100MB
max-request-size: 1024MB
mybatis:
mapper-locations: classpath:/mapping/*.xml
type-aliases-package: cn.crtech.cloud.resmanager.pojo
#配置驼峰下划线
configuration:
map-underscore-to-camel-case: true
resmanager:
type: minio #local,minio,aliyunoss
local:
path: D:/minioserver
bucket-name: crtech-cloud
minio:
endpoint: 127.0.0.1
port: 9000
access-key: minioadmin
secret-key: minioadmin
bucket-name: crtech-cloud
secure: false
access-type: minio #minio 直接获取minio的url-expires秒的有效urllocal 获取本服务转发地址
url-expires: 1800 #minio直连url有效时间1~604800 秒
aliyunoss:
server-url: https://
access-key: minioadmin
secret-key: minioadmin
bucket-name: crtech-cloud
secure: false
access-type: aliyunoss #aliyunoss 直接获取minio的url-expires秒的有效urllocal 获取本服务转发地址
url-expires: 1800 #minio直连url有效时间1~604800 秒

View File

@ -0,0 +1,49 @@
server:
port: 8082
servlet:
encoding:
charset: utf-8
enabled: true
force: true
tomcat:
uri-encoding: UTF-8
logging:
config: classpath:logback.xml
file:
path: logs/crtech-cloud-resmanager.log
level:
cn.crtech.cloud.resmanager: debug
spring:
servlet:
multipart:
enabled: true
max-file-size: 100MB
max-request-size: 1024MB
mybatis:
mapper-locations: classpath:/mapping/*.xml
type-aliases-package: cn.crtech.cloud.resmanager.pojo
#配置驼峰下划线
configuration:
map-underscore-to-camel-case: true
resmanager:
type: minio #local,minio,aliyunoss
local:
path: D:/minioserver
bucket-name: crtech-cloud
minio:
endpoint: http://api.yaoxunk.com
port: 9008
access-key: minioadmin
secret-key: minioadmin
bucket-name: crtech-cloud
secure: false
access-type: minio #minio 直接获取minio的url-expires秒的有效urllocal 获取本服务转发地址
url-expires: 1800 #minio直连url有效时间1~604800 秒
aliyunoss:
server-url: https://
access-key: minioadmin
secret-key: minioadmin
bucket-name: crtech-cloud
secure: false
access-type: aliyunoss #aliyunoss 直接获取minio的url-expires秒的有效urllocal 获取本服务转发地址
url-expires: 1800 #minio直连url有效时间1~604800 秒

View File

@ -0,0 +1,16 @@
spring:
application:
name: crtech-cloud-resmanager # 项目名称尽量用小写
cloud:
nacos:
discovery:
server-addr: localhost:8848
redis:
database: 0
port: 6379
host: localhost
password:
datasource:
url: jdbc:mysql://chaoran.crtech.cn:9803/cr_cloud_general_dev?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&useSSL=false&allowPublicKeyRetrieval=true
username: crtech
password: www.server41.com

View File

@ -0,0 +1,16 @@
spring:
application:
name: crtech-cloud-resmanager # 项目名称尽量用小写
cloud:
nacos:
discovery:
server-addr: http://api.yaoxunk.com:28848
redis:
database: 0
port: 6689
host: 127.0.0.1
password:
datasource:
url: jdbc:mysql://rm-uf6wn1g5bm13lf3363o.mysql.rds.aliyuncs.com:3306/cr_cloud_general?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&useSSL=false&allowPublicKeyRetrieval=true
username: crtech
password: Crtech@yun_2023

View File

@ -0,0 +1,6 @@
spring:
profiles:
active: dev

View File

@ -0,0 +1,56 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="FILE"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>logs/crtech-cloud-resmanager.%d{yyyy-MM-dd}.log
</fileNamePattern>
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd_HH:mm:ss} %logger{18} -%msg%n
</pattern>
</encoder>
</appender>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
</pattern>
</encoder>
</appender>
<appender name="ASYNC" class="ch.qos.logback.classic.AsyncAppender">
<discardingThreshold>0</discardingThreshold>
<queueSize>1000</queueSize>
<appender-ref ref="FILE" />
</appender>
<logger name="org" level="info" additivity="false">
<appender-ref ref="FILE"></appender-ref>
<appender-ref ref="STDOUT"></appender-ref>
</logger>
<logger name="com" level="info" additivity="false">
<appender-ref ref="FILE"></appender-ref>
<appender-ref ref="STDOUT"></appender-ref>
</logger>
<logger name="net" level="info" additivity="false">
<appender-ref ref="FILE"></appender-ref>
<appender-ref ref="STDOUT"></appender-ref>
</logger>
<logger name="com.netflix" level="debug" additivity="false">
<appender-ref ref="STDOUT"></appender-ref>
<appender-ref ref="FILE"></appender-ref>
</logger>
<logger name="cn.crtech.cloud.resmanager" level="debug" additivity="false">
<appender-ref ref="STDOUT"></appender-ref>
<appender-ref ref="FILE"></appender-ref>
</logger>
<root level="INFO">
<appender-ref ref="ASYNC" />
</root>
</configuration>

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,37 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script type="application/javascript" src="sdk.js"></script>
<style>
.preview {
width: 100%;
height: 50vh;
background-color: rgba(0,0,0,0.75);
background-position: center;
background-repeat: no-repeat;
background-size: 80%;
}
</style>
</head>
<body>
<fieldset>
<legend>上传文件</legend>
<label>文件路径:<input name="path" value="ERP/商品图片/SP000001"></label>
<label>重命名文件:<input name="name" value="2.png"></label>
<label>文件:<input type="file" name="file" accept="image/png,image/jpeg"></label>
</fieldset>
<fieldset>
<legend>图片预览</legend>
<div class="preview"></div>
</fieldset>
</body>
<script type="application/javascript">
window.onload = () => {
console.log($rm.server_url);
let preview = document.getElementsByClassName("preview");
preview[0].setAttribute("style", "background-image: url('" + $rm.server_url + "/s/123')")
};
</script>
</html>