parent
7ee125c479
commit
88b5dfc714
|
|
@ -32,6 +32,10 @@
|
|||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
</dependency>
|
||||
<!-- JWT -->
|
||||
<dependency>
|
||||
<groupId>io.jsonwebtoken</groupId>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,27 @@
|
|||
package com.chushang.common.core.config;
|
||||
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.web.servlet.MultipartConfigFactory;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import javax.servlet.MultipartConfigElement;
|
||||
|
||||
@Configuration
|
||||
public class MultipartConfig {
|
||||
|
||||
@Value("${spring.servlet.multipart.location:/tmp}")
|
||||
private String tmpLocation;
|
||||
|
||||
@Bean
|
||||
public MultipartConfigElement multipartConfigElement() {
|
||||
MultipartConfigFactory factory = new MultipartConfigFactory();
|
||||
// 若没有该目录,则创建,此处使用了第三方插件的FileUtil,各位可以使用原生File实现该逻辑
|
||||
if (!FileUtil.exist(tmpLocation)) {
|
||||
FileUtil.mkdir(tmpLocation);
|
||||
}
|
||||
factory.setLocation(tmpLocation);
|
||||
return factory.createMultipartConfig();
|
||||
}
|
||||
}
|
||||
|
|
@ -118,21 +118,17 @@ public class DateUtils {
|
|||
return format(localDateTime, dtf);
|
||||
}
|
||||
|
||||
|
||||
/** 时间格式(yyyy-MM-dd) */
|
||||
public final static String DATE_PATTERN = "yyyy-MM-dd";
|
||||
|
||||
public static LocalDate toLocalDate(long secondTimestamp){
|
||||
return Instant.ofEpochSecond(secondTimestamp).atZone(ZoneId.systemDefault()).toLocalDate();
|
||||
}
|
||||
|
||||
public static LocalDate parseDate(String date)
|
||||
{
|
||||
return parseDate(date,DATE_PATTERN);
|
||||
return parseDate(date,DatePattern.NORM_DATE_PATTERN);
|
||||
}
|
||||
|
||||
public static String format(LocalDate date){
|
||||
return format(date,DATE_PATTERN);
|
||||
return format(date,DatePattern.NORM_DATE_PATTERN);
|
||||
}
|
||||
|
||||
public static String format(LocalDate date,String pattern){
|
||||
|
|
@ -157,7 +153,7 @@ public class DateUtils {
|
|||
* @return 返回yyyy-MM-dd格式日期
|
||||
*/
|
||||
public static String format(Date date) {
|
||||
return format(date, DATE_PATTERN);
|
||||
return format(date, DatePattern.NORM_DATE_PATTERN);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -193,10 +189,10 @@ public class DateUtils {
|
|||
ZonedDateTime endDateTime = parseDate(endDateStr).atStartOfDay().atZone(clock.getZone());
|
||||
Set<String> timeSet = new HashSet<>();
|
||||
for (ZonedDateTime start = startDateTime; endDateTime.isAfter(start); start = start.plusDays(1L)){
|
||||
timeSet.add(format(start, DateUtils.DATE_PATTERN));
|
||||
timeSet.add(format(start, DatePattern.NORM_DATE_PATTERN));
|
||||
}
|
||||
// 最后需要添加一下 结束日期
|
||||
timeSet.add(format(endDateTime, DateUtils.DATE_PATTERN));
|
||||
timeSet.add(format(endDateTime, DatePattern.NORM_DATE_PATTERN));
|
||||
return timeSet;
|
||||
}
|
||||
|
||||
|
|
@ -261,11 +257,9 @@ public class DateUtils {
|
|||
return date.format(DateTimeFormatter.ofPattern("yyyy_MM_dd"));
|
||||
}
|
||||
|
||||
public final static String ISO_DATE_TIME_PATTERN = "yyyy-MM-dd'T'HH:mm:ss'Z'";
|
||||
public final static String DATE_PATTERN_2 = "yyyyMMdd";
|
||||
public static String isoFormat(LocalDateTime dateTime)
|
||||
{
|
||||
DateTimeFormatter dtf = DateTimeFormatter.ofPattern(ISO_DATE_TIME_PATTERN);
|
||||
DateTimeFormatter dtf = DateTimeFormatter.ofPattern(DatePattern.UTC_PATTERN);
|
||||
return dateTime.format(dtf);
|
||||
}
|
||||
|
||||
|
|
@ -284,7 +278,7 @@ public class DateUtils {
|
|||
* @param day 日期
|
||||
*/
|
||||
private static Date getWeekDate(String day) {
|
||||
Date date = stringToDate(day, DATE_PATTERN);
|
||||
Date date = stringToDate(day, DatePattern.NORM_DATE_PATTERN);
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.setTime(date);
|
||||
// 获得当前日期是一个星期的第几天
|
||||
|
|
|
|||
|
|
@ -1,7 +1,11 @@
|
|||
package com.chushang.common.core.util;
|
||||
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import cn.hutool.crypto.SecureUtil;
|
||||
import cn.hutool.crypto.digest.MD5;
|
||||
import lombok.SneakyThrows;
|
||||
import org.apache.commons.io.Charsets;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
|
@ -9,6 +13,7 @@ import javax.servlet.http.HttpServletRequest;
|
|||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.*;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.security.MessageDigest;
|
||||
|
|
@ -149,38 +154,22 @@ public class FileUtils extends FileUtil {
|
|||
}
|
||||
|
||||
public static String getMd5(File f) {
|
||||
try (FileInputStream fis = new FileInputStream(f)){
|
||||
try (FileInputStream fis = new FileInputStream(f)) {
|
||||
return getMd5(fis);
|
||||
}catch (Exception e){
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
public static String getMd5(InputStream is) throws IOException, NoSuchAlgorithmException {
|
||||
MessageDigest mdInst = MessageDigest.getInstance("MD5");
|
||||
byte[] buffer = new byte[1024];
|
||||
while (is.read(buffer) != -1) {
|
||||
mdInst.update(buffer);
|
||||
}
|
||||
return binaryToHexString(mdInst.digest());
|
||||
}
|
||||
|
||||
private static String binaryToHexString(byte[] result) {
|
||||
StringBuilder digestHexStr = new StringBuilder();
|
||||
|
||||
for (int i = 0; i < 16; ++i) {
|
||||
char[] ob = new char[]{Digit[result[i] >>> 4 & 15], Digit[result[i] & 15]};
|
||||
String s = new String(ob);
|
||||
digestHexStr.append(s);
|
||||
}
|
||||
|
||||
return digestHexStr.toString();
|
||||
public static String getMd5(InputStream is) {
|
||||
MD5 md5 = SecureUtil.md5();
|
||||
return md5.digestHex(is);
|
||||
}
|
||||
|
||||
public static boolean isText(File file) {
|
||||
boolean isText = true;
|
||||
try (FileInputStream fin = new FileInputStream(file)){
|
||||
try (FileInputStream fin = new FileInputStream(file)) {
|
||||
long len = file.length();
|
||||
for (int j = 0; j < (int) len; ++j) {
|
||||
int t = fin.read();
|
||||
|
|
@ -189,18 +178,44 @@ public class FileUtils extends FileUtil {
|
|||
break;
|
||||
}
|
||||
}
|
||||
}catch (Exception e){
|
||||
} catch (Exception e) {
|
||||
log.error("isText", e);
|
||||
}
|
||||
return isText;
|
||||
}
|
||||
|
||||
public static boolean isText(InputStream is) {
|
||||
try (BufferedReader reader = new BufferedReader(new InputStreamReader(is))) {
|
||||
// 读取一行,, 判断这一行是否有 不可打印字符
|
||||
String line = reader.readLine();
|
||||
while (line != null) {
|
||||
for (char c : line.toCharArray()) {
|
||||
// 检查是否包含 可打印字符, 包含时, 就代表其是 text
|
||||
return !(!Character.isISOControl(c) && !Character.isWhitespace(c));
|
||||
}
|
||||
line = reader.readLine();
|
||||
}
|
||||
return true;
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static String getFileCharset(File sourceFile) {
|
||||
String charset = "GBK";
|
||||
try (InputStream is = new FileInputStream(sourceFile)) {
|
||||
charset = getStreamCharset(is);
|
||||
} catch (Exception e) {
|
||||
log.error("", e);
|
||||
return charset;
|
||||
}
|
||||
return charset;
|
||||
}
|
||||
|
||||
public static String getStreamCharset(InputStream is) {
|
||||
String charset = "GBK";
|
||||
byte[] first3Bytes = new byte[3];
|
||||
String var7;
|
||||
try (FileInputStream fis = new FileInputStream(sourceFile);
|
||||
BufferedInputStream bis = new BufferedInputStream(fis)){
|
||||
try (BufferedInputStream bis = new BufferedInputStream(is)) {
|
||||
boolean checked = false;
|
||||
bis.mark(0);
|
||||
int read = bis.read(first3Bytes, 0, 3);
|
||||
|
|
@ -228,7 +243,7 @@ public class FileUtils extends FileUtil {
|
|||
read = bis.read();
|
||||
continue label248;
|
||||
}
|
||||
} while(224 > read || read > 239);
|
||||
} while (224 > read || read > 239);
|
||||
|
||||
read = bis.read();
|
||||
if (128 <= read && read <= 191) {
|
||||
|
|
@ -238,19 +253,21 @@ public class FileUtils extends FileUtil {
|
|||
}
|
||||
}
|
||||
break;
|
||||
} while(128 <= read && read <= 191);
|
||||
} while (128 <= read && read <= 191);
|
||||
}
|
||||
|
||||
bis.close();
|
||||
return charset;
|
||||
}
|
||||
|
||||
var7 = charset;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return charset;
|
||||
}
|
||||
return var7;
|
||||
return charset;
|
||||
}
|
||||
|
||||
public static String readFileToString(File file, Charset charsetName) throws IOException {
|
||||
return IOUtils.toString(() -> Files.newInputStream(file.toPath()), Charsets.toCharset(charsetName));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
|
||||
com.chushang.common.core.util.SpringUtils, \
|
||||
com.chushang.common.core.handler.GlobalExceptionHandler
|
||||
com.chushang.common.core.handler.GlobalExceptionHandler, \
|
||||
com.chushang.common.core.config.MultipartConfig
|
||||
|
|
|
|||
|
|
@ -121,7 +121,7 @@ public class SysLogAspect {
|
|||
// 将导出的response 过滤掉
|
||||
List<Object> argList =
|
||||
Arrays.stream(args)
|
||||
.filter(arg -> !(arg instanceof MultipartFile) && !(arg instanceof HttpServletResponse) && !(arg instanceof HttpServletRequest))
|
||||
.filter(arg -> !(arg instanceof MultipartFile) && !(arg instanceof HttpServletResponse) && !(arg instanceof HttpServletRequest) && !(arg instanceof MultipartFile[]))
|
||||
.collect(Collectors.toList());
|
||||
sysLogEntity.setParams(JacksonUtils.toJSONString(argList));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,11 @@
|
|||
package com.chushang.common.mybatis.enums;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 比较符
|
||||
*/
|
||||
@Getter
|
||||
public enum Operator {
|
||||
|
||||
/**
|
||||
|
|
@ -35,9 +38,13 @@ public enum Operator {
|
|||
LIMIT_ONE("limit 1")
|
||||
|
||||
;
|
||||
|
||||
/**
|
||||
* 比较符
|
||||
* -- GETTER --
|
||||
* 获取比较符
|
||||
*
|
||||
* @return {@link String}
|
||||
|
||||
*/
|
||||
private final String character;
|
||||
|
||||
|
|
@ -45,11 +52,4 @@ public enum Operator {
|
|||
this.character = character;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取比较符
|
||||
* @return {@link String}
|
||||
*/
|
||||
public String getCharacter() {
|
||||
return character;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,5 +29,10 @@
|
|||
<groupId>com.aliyun.oss</groupId>
|
||||
<artifactId>aliyun-sdk-oss</artifactId>
|
||||
</dependency>
|
||||
<!-- 权限控制 -->
|
||||
<dependency>
|
||||
<groupId>com.chushang</groupId>
|
||||
<artifactId>chushang-common-data-scope</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import java.io.Serial;
|
|||
import java.io.Serializable;
|
||||
|
||||
@Configuration
|
||||
@ConfigurationProperties(prefix = "oss")
|
||||
@ConfigurationProperties(prefix = "config.oss")
|
||||
@Data
|
||||
public class UploadConfig implements Serializable {
|
||||
@Serial
|
||||
|
|
|
|||
|
|
@ -2,16 +2,21 @@ package com.chushang.oss.entity;
|
|||
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
import com.chushang.common.mybatis.base.BaseEntity;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
@TableName("tb_oss_source_info")
|
||||
@TableName("tb_file_source_info")
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class FileSourceInfo extends BaseEntity{
|
||||
|
||||
|
||||
@TableId(value = "fid", type = IdType.INPUT)
|
||||
private String fid;
|
||||
/**
|
||||
|
|
@ -65,13 +70,33 @@ public class FileSourceInfo extends BaseEntity{
|
|||
*/
|
||||
@TableField("storage_region")
|
||||
private String storageRegion;
|
||||
/**
|
||||
* 文件存储位置, minio | ali | local
|
||||
*/
|
||||
@TableField("storage")
|
||||
private String storage;
|
||||
/**
|
||||
* 创建人
|
||||
*/
|
||||
@TableField(
|
||||
value = "create_by",
|
||||
updateStrategy = FieldStrategy.NEVER
|
||||
value = "create_by"
|
||||
)
|
||||
protected String createBy;
|
||||
private String createBy;
|
||||
/**
|
||||
* 部门Id, 只能看到权限下的图片
|
||||
*/
|
||||
@TableField(value = "dept_id")
|
||||
private Long deptId;
|
||||
/**
|
||||
* 修改人
|
||||
*/
|
||||
@TableField(
|
||||
value = "update_by"
|
||||
)
|
||||
private String updateBy;
|
||||
|
||||
|
||||
public FileSourceInfo(String fid){
|
||||
this.fid = fid;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,11 @@
|
|||
<groupId>com.chushang</groupId>
|
||||
<artifactId>chushang-common-log</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.tika</groupId>
|
||||
<artifactId>tika-core</artifactId>
|
||||
<version>2.8.0</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
|
|
|||
|
|
@ -2,11 +2,14 @@ package com.chushang.oss;
|
|||
|
||||
import com.chushang.common.core.enums.AppStartType;
|
||||
import com.chushang.common.feign.annotation.EnableOnnFeignClients;
|
||||
import com.chushang.common.feign.annotation.EnableTransferFeign;
|
||||
import com.chushang.security.annotation.EnableCustomConfig;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
|
||||
import org.springframework.transaction.annotation.EnableTransactionManagement;
|
||||
|
||||
/**
|
||||
* @auther: zhao
|
||||
|
|
@ -14,8 +17,10 @@ import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
|
|||
*/
|
||||
@EnableDiscoveryClient
|
||||
@EnableOnnFeignClients
|
||||
@SpringBootApplication
|
||||
//@EnableTransferFeign
|
||||
@SpringBootApplication(scanBasePackages = {"com.chushang.**"})
|
||||
@EnableTransferFeign
|
||||
@EnableCustomConfig
|
||||
@EnableTransactionManagement
|
||||
public class OssApplication {
|
||||
|
||||
private final static Logger log = LoggerFactory.getLogger(OssApplication.class);
|
||||
|
|
|
|||
|
|
@ -1,62 +1,92 @@
|
|||
package com.chushang.oss.controller;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.chushang.common.core.util.FileUtils;
|
||||
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.FileSourceInfo;
|
||||
import com.chushang.oss.entity.dto.OcrDTO;
|
||||
import com.chushang.oss.entity.vo.FileSourceVo;
|
||||
import com.chushang.oss.enums.OcrTypeEnum;
|
||||
import com.chushang.oss.service.FileSourceService;
|
||||
import com.chushang.oss.service.OcrService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping(value = "/file")
|
||||
public class FileController {
|
||||
|
||||
@Resource
|
||||
FileSourceService fileSourceService;
|
||||
// @Resource
|
||||
// OcrService ocrService;
|
||||
@Resource
|
||||
OcrService ocrService;
|
||||
|
||||
/**
|
||||
* todo
|
||||
* 文件上传
|
||||
*/
|
||||
@SysLog(value = "文件上传", businessType = BusinessType.INSERT)
|
||||
@PostMapping(value = "/upload")
|
||||
public AjaxResult uploadFile(@RequestParam(value = "file") MultipartFile file,
|
||||
@RequestParam(value = "ocrType", required = false) String ocrType) {
|
||||
FileSourceVo vo = BeanUtil.copyProperties(fileSourceService.addFile(file, "ip"), FileSourceVo.class);
|
||||
// if (StrUtil.isNotEmpty(ocrType)) {
|
||||
// OcrDTO ocr = new OcrDTO();
|
||||
// OcrTypeEnum ocrTypeEnum = OcrTypeEnum.findByCode(ocrType);
|
||||
// if (ocrTypeEnum != OcrTypeEnum.NONE) {
|
||||
// ocr.setOcrType(ocrTypeEnum);
|
||||
// ocr.setImgPath(vo.getFilePath());
|
||||
//// Result<JSONObject> ocrInfo = ocrService.ocr(ocr);
|
||||
//// if (ocrInfo.isSuccess()) {
|
||||
//// vo.setOcr(ocrInfo.getData());
|
||||
//// }
|
||||
// }
|
||||
// }
|
||||
return AjaxResult.success(vo);
|
||||
public AjaxResult uploadFile(@RequestParam(value = "files") MultipartFile[] files,
|
||||
@RequestParam(value = "ocrType", required = false) String ocrType)
|
||||
{
|
||||
List<FileSourceVo> result = new ArrayList<>();
|
||||
for (MultipartFile file : files) {
|
||||
FileSourceVo info = fileSourceService.addFile(file);
|
||||
if (StrUtil.isNotEmpty(ocrType)) {
|
||||
OcrDTO ocr = new OcrDTO();
|
||||
OcrTypeEnum ocrTypeEnum = OcrTypeEnum.findByCode(ocrType);
|
||||
if (ocrTypeEnum != OcrTypeEnum.NONE) {
|
||||
ocr.setOcrType(ocrTypeEnum);
|
||||
ocr.setImgPath(info.getFilePath());
|
||||
Result<JSONObject> ocrInfo = ocrService.ocr(ocr);
|
||||
if (ocrInfo.isSuccess()) {
|
||||
info.setOcr(ocrInfo.getData());
|
||||
}
|
||||
}
|
||||
}
|
||||
result.add(info);
|
||||
}
|
||||
return AjaxResult.success(result);
|
||||
}
|
||||
|
||||
@GetMapping(value="/{fid}/preview")
|
||||
public void preview(@PathVariable String fid, HttpServletResponse response)
|
||||
{
|
||||
log.info("[OSS]preview Request --> param:{}",fid);
|
||||
fileSourceService.getFileStream(fid, response, true);
|
||||
}
|
||||
|
||||
@SysLog(value = "文件下载", businessType = BusinessType.OTHER)
|
||||
@GetMapping(value = "/download/{fid}")
|
||||
public AjaxResult downloadFile(@PathVariable String fid) {
|
||||
return AjaxResult.success();
|
||||
public void downloadFile(@PathVariable String fid, HttpServletResponse response) {
|
||||
log.info("[OSS]preview Request --> param:{}",fid);
|
||||
fileSourceService.getFileStream(fid, response, false);
|
||||
}
|
||||
|
||||
@SysLog(value = "文件", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping(value = "/del/{fid}")
|
||||
public AjaxResult delFile() {
|
||||
public AjaxResult delFile(@PathVariable String fid) {
|
||||
fileSourceService.delFile(fid);
|
||||
return AjaxResult.success();
|
||||
}
|
||||
|
||||
@SysLog(value = "文件", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping(value = "/del/batch")
|
||||
public AjaxResult delFile(@RequestBody List<String> fids) {
|
||||
fileSourceService.delFileBatch(fids);
|
||||
return AjaxResult.success();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,15 +1,39 @@
|
|||
package com.chushang.oss.service;
|
||||
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import cn.hutool.core.date.DatePattern;
|
||||
import cn.hutool.core.util.IdUtil;
|
||||
import cn.hutool.core.util.ObjUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.chushang.common.core.exception.ResultException;
|
||||
import com.chushang.common.core.util.DateUtils;
|
||||
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.vo.FileSourceVo;
|
||||
import com.chushang.oss.mapper.FileSourceMapper;
|
||||
import com.chushang.oss.service.OssService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.tika.Tika;
|
||||
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;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.*;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @auther: zhao
|
||||
|
|
@ -19,14 +43,123 @@ import javax.annotation.Resource;
|
|||
@Service
|
||||
public class FileSourceService
|
||||
extends ServiceImpl<FileSourceMapper, FileSourceInfo>
|
||||
implements IService<FileSourceInfo>
|
||||
{
|
||||
implements IService<FileSourceInfo> {
|
||||
|
||||
@Resource
|
||||
OssService ossService;
|
||||
@Resource
|
||||
RedissonClient redissonClient;
|
||||
@Value("${config.oss.storage}")
|
||||
private String storage;
|
||||
|
||||
private String generateFid() {
|
||||
String uuid = IdUtil.simpleUUID();
|
||||
uuid = Integer.toHexString(Integer.parseInt(DateUtils.format(ZonedDateTime.now(), DatePattern.PURE_DATE_PATTERN))) + uuid;
|
||||
return uuid;
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传 到minio 或者 oss 服务中
|
||||
*
|
||||
* @param file 文件
|
||||
*/
|
||||
public FileSourceVo addFile(MultipartFile file) {
|
||||
String ip = IPUtils.clientIp(ServletUtils.getRequest());
|
||||
String fid = generateFid();
|
||||
String fName = file.getOriginalFilename();
|
||||
Tika t = new Tika();
|
||||
String mimetype = null;
|
||||
try {
|
||||
mimetype = t.detect(file.getBytes());
|
||||
if (fName.indexOf(".") < 0) {//如果文件名字没有后缀
|
||||
String ext = MimeTypes.getDefaultMimeTypes().forName(mimetype).getExtension();
|
||||
fName += ext;
|
||||
}
|
||||
} catch (IOException ignore) {
|
||||
} catch (MimeTypeException e) {
|
||||
log.error("文件后缀识别失败");
|
||||
}
|
||||
FileSourceInfo info = new FileSourceInfo();
|
||||
try {
|
||||
info.setFid(fid);
|
||||
info.setName(fName);
|
||||
// mimeType 还不是 后缀 类型
|
||||
info.setMimeType(mimetype);
|
||||
info.setSize(file.getSize());
|
||||
String md5 = FileUtils.getMd5(file.getInputStream());
|
||||
info.setMd5(md5);
|
||||
String path = ossService.getPrefixPath(md5,fName);
|
||||
// 不带https 的路径
|
||||
info.setPath(path);
|
||||
info.setStorage(storage);
|
||||
info.setUploadIp(ip);
|
||||
// 上传到 oss 或者 minio
|
||||
String realPath = ossService.upload(file.getInputStream(), info);
|
||||
// 带https 的路径
|
||||
info.setRealPath(realPath);
|
||||
RMap<String, FileSourceInfo> map = redissonClient.getMap("OSS-Cache");
|
||||
map.put(fid, info);
|
||||
// 入库
|
||||
save(info);
|
||||
map.remove(info.getFid());
|
||||
} catch (Exception e) {
|
||||
log.error("上传文件失败", e);
|
||||
}
|
||||
FileSourceVo vo = new FileSourceVo();
|
||||
vo.setFid(info.getFid());
|
||||
vo.setFilePath(info.getRealPath());
|
||||
vo.setName(fName);
|
||||
vo.setSize(info.getSize());
|
||||
return vo;
|
||||
}
|
||||
|
||||
|
||||
public FileSourceInfo addFile(MultipartFile file, String ip) {
|
||||
return null;
|
||||
public void getFileStream(String fid, HttpServletResponse response, boolean convertText) {
|
||||
// 文件信息
|
||||
FileSourceInfo info = getOne(new LambdaQueryWrapper<FileSourceInfo>()
|
||||
.eq(FileSourceInfo::getFid, fid)
|
||||
.last(Operator.LIMIT_ONE.getCharacter()));
|
||||
if (ObjUtil.isEmpty(info)) return;
|
||||
InputStream fileStream = ossService.getFileStream(info);
|
||||
response.setContentType(info.getMimeType());
|
||||
try (OutputStream os = response.getOutputStream()){
|
||||
if (FileUtils.isText(fileStream) && convertText){
|
||||
//是文本则读取内容输出
|
||||
OutputStreamWriter osw = new OutputStreamWriter(os);
|
||||
osw.write(IOUtils.toString(fileStream, FileUtils.getStreamCharset(fileStream)));
|
||||
osw.flush();
|
||||
}else {
|
||||
byte[] readByte = new byte[1024];
|
||||
int len = 0;
|
||||
while ((len = fileStream.read(readByte, 0, readByte.length)) != -1) {
|
||||
os.write(readByte, 0, len);
|
||||
}
|
||||
os.flush();
|
||||
}
|
||||
}catch (Exception e){
|
||||
log.error("文件流获取失败");
|
||||
}
|
||||
}
|
||||
|
||||
public void delFile(String fid) {
|
||||
// 文件信息
|
||||
FileSourceInfo info = getOne(new LambdaQueryWrapper<FileSourceInfo>()
|
||||
.eq(FileSourceInfo::getFid, fid)
|
||||
.last(Operator.LIMIT_ONE.getCharacter()));
|
||||
if (ObjUtil.isEmpty(info)) return;
|
||||
ossService.delFile(info.getPath());
|
||||
}
|
||||
|
||||
public void delFileBatch(List<String> fids) {
|
||||
// 文件信息
|
||||
List<FileSourceInfo> list = list(new LambdaQueryWrapper<FileSourceInfo>()
|
||||
.in(FileSourceInfo::getFid, fids));
|
||||
if (CollectionUtil.isEmpty(list)) return;
|
||||
List<String> strings
|
||||
= ossService.delFileBatch(list.stream().map(FileSourceInfo::getPath).toList());
|
||||
if (CollectionUtil.isNotEmpty(strings)){
|
||||
String key = String.join(",", strings);
|
||||
throw new ResultException("以下文件未删除: [" + key + "].");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,9 @@
|
|||
package com.chushang.oss.service;
|
||||
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.chushang.common.core.web.Result;
|
||||
import com.chushang.oss.entity.dto.OcrDTO;
|
||||
|
||||
public interface OcrService {
|
||||
Result<JSONObject> ocr(OcrDTO ocr);
|
||||
}
|
||||
|
|
@ -1,71 +1,37 @@
|
|||
package com.chushang.oss.service;
|
||||
|
||||
import com.chushang.common.core.util.IdUtils;
|
||||
import com.chushang.oss.entity.FileSourceInfo;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.util.List;
|
||||
|
||||
public interface OssService {
|
||||
|
||||
default String getSuffixPath(String suffix){
|
||||
default String getPrefixPath(String fileName){
|
||||
String nanoID = IdUtils.getId(32);
|
||||
return getSuffixPath(suffix, nanoID);
|
||||
|
||||
}
|
||||
/**
|
||||
* 文件路径
|
||||
* @param filename 文件名称
|
||||
* @param suffix 文件类型
|
||||
* @return 返回上传路径
|
||||
*/
|
||||
default String getSuffixPath(String suffix, String filename) {
|
||||
return filename + suffix;
|
||||
return getPrefixPath(nanoID, fileName);
|
||||
}
|
||||
|
||||
default String getPrefixPath(String prefix, String filename){
|
||||
return prefix + "/" + filename;
|
||||
}
|
||||
|
||||
default String getSuffixPath(String prefix, String suffix, String filename)
|
||||
{
|
||||
//文件路径
|
||||
return prefix + "/" + filename + suffix;
|
||||
}
|
||||
/**
|
||||
* 文件上传
|
||||
* @param data 文件字节数组
|
||||
* @param path 文件路径,包含文件名
|
||||
* @param info 文件信息
|
||||
* @return 返回http地址
|
||||
*/
|
||||
String upload(byte[] data, String path);
|
||||
default String upload(byte[] data, FileSourceInfo info){
|
||||
return upload(new ByteArrayInputStream(data), info);
|
||||
}
|
||||
String getPrefixPath(String prefix, String filename);
|
||||
|
||||
/**
|
||||
* 文件上传
|
||||
* @param data 文件字节数组
|
||||
* @param suffix 文件类型
|
||||
* @return 返回http地址
|
||||
* @param inputStream 文件字节数组
|
||||
* @param info 文件信息
|
||||
* @return 返回http地址
|
||||
*/
|
||||
String uploadSuffix(byte[] data, String suffix);
|
||||
|
||||
String uploadSuffix(byte[] data, String suffix, String filename);
|
||||
String uploadPrefix(byte[] data,String prefix, String suffix, String filename);
|
||||
String uploadPrefix(byte[] data,String prefix, String filename);
|
||||
|
||||
/**
|
||||
* 文件上传
|
||||
* @param inputStream 字节流
|
||||
* @param path 文件路径,包含文件名
|
||||
* @return 返回http地址
|
||||
*/
|
||||
String upload(InputStream inputStream, String path);
|
||||
|
||||
/**
|
||||
* 文件上传
|
||||
* @param inputStream 字节流
|
||||
* @param suffix 文件类型
|
||||
* @return 返回http地址
|
||||
*/
|
||||
String uploadSuffix(InputStream inputStream, String suffix);
|
||||
String upload(InputStream inputStream, FileSourceInfo info);
|
||||
|
||||
/**
|
||||
* 删除 cloud 中的文件
|
||||
|
|
@ -78,4 +44,6 @@ public interface OssService {
|
|||
*/
|
||||
List<String> delFileBatch(List<String> keys);
|
||||
|
||||
InputStream getFileStream(FileSourceInfo info);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import com.aliyun.oss.OSS;
|
|||
import com.aliyun.oss.OSSClientBuilder;
|
||||
import com.aliyun.oss.model.DeleteObjectsRequest;
|
||||
import com.aliyun.oss.model.DeleteObjectsResult;
|
||||
import com.aliyun.oss.model.OSSObject;
|
||||
import com.aliyun.oss.model.Payer;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.chushang.common.core.exception.ResultException;
|
||||
|
|
@ -21,7 +22,9 @@ import javax.annotation.PostConstruct;
|
|||
import javax.annotation.Resource;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
|
|
@ -51,54 +54,25 @@ public class AliServiceImpl implements OssService {
|
|||
oss.setBucketRequestPayment(config.getBucketName(), payer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String upload(byte[] data, String path) {
|
||||
public String getPrefixPath(String prefix, String filename){
|
||||
String aliyunPrefix = config.getPrefix();
|
||||
if (StringUtils.isNotEmpty(aliyunPrefix)){
|
||||
path = aliyunPrefix + "/" + path;
|
||||
prefix = aliyunPrefix + "/" + prefix + "/" + filename;
|
||||
}else {
|
||||
prefix = prefix + "/" + filename;
|
||||
}
|
||||
return upload(new ByteArrayInputStream(data), path);
|
||||
return prefix;
|
||||
}
|
||||
|
||||
/**
|
||||
* path
|
||||
* @param inputStream 字节流
|
||||
* @param path 文件路径,包含文件名
|
||||
*/
|
||||
@Override
|
||||
public String upload(InputStream inputStream, String path) {
|
||||
public String upload(InputStream inputStream, FileSourceInfo info) {
|
||||
String path = info.getPath();
|
||||
try {
|
||||
oss.putObject(config.getBucketName(), path, inputStream);
|
||||
} catch (Exception e){
|
||||
throw new ResultException("上传文件失败,请检查配置信息", e);
|
||||
}
|
||||
|
||||
return UploadConfig.getDomain() + "/" + path;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String uploadSuffix(byte[] data, String suffix) {
|
||||
return upload(data, getSuffixPath(suffix));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String uploadSuffix(byte[] data, String suffix, String filename) {
|
||||
return upload(data, getSuffixPath(suffix, filename));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String uploadPrefix(byte[] data, String prefix, String suffix, String filename) {
|
||||
return upload(data, getSuffixPath(prefix, suffix, filename));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String uploadPrefix(byte[] data, String prefix, String filename) {
|
||||
return upload(data, getPrefixPath(prefix, filename));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String uploadSuffix(InputStream inputStream, String suffix) {
|
||||
return upload(inputStream, getSuffixPath(suffix));
|
||||
return path;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -111,6 +85,7 @@ public class AliServiceImpl implements OssService {
|
|||
}
|
||||
|
||||
public List<String> delFileBatch(List<String> keys){
|
||||
if (CollectionUtil.isEmpty(keys)) return new ArrayList<>();
|
||||
try {
|
||||
// 批量删除
|
||||
DeleteObjectsRequest objectsRequest = new DeleteObjectsRequest(config.getBucketName());
|
||||
|
|
@ -120,10 +95,23 @@ public class AliServiceImpl implements OssService {
|
|||
objectsRequest.setEncodingType("url");
|
||||
|
||||
DeleteObjectsResult deleteObjectsResult = oss.deleteObjects(objectsRequest);
|
||||
// 这些是成功删除对象的key
|
||||
List<String> deletedObjects = deleteObjectsResult.getDeletedObjects();
|
||||
if (CollectionUtil.isNotEmpty(deletedObjects)){
|
||||
log.error("以下文件未从oss 中成功删除 : {}", deletedObjects);
|
||||
return deletedObjects;
|
||||
|
||||
|
||||
Iterator<String> iterator = keys.iterator();
|
||||
List<String> results = new ArrayList<>();
|
||||
while (iterator.hasNext()){
|
||||
String key = iterator.next();
|
||||
if (deletedObjects.contains(key)){
|
||||
iterator.remove();
|
||||
}else {
|
||||
results.add(key);
|
||||
}
|
||||
}
|
||||
if (CollectionUtil.isNotEmpty(results)){
|
||||
log.error("以下文件未从oss 中成功删除 : {}", results);
|
||||
return results;
|
||||
}
|
||||
} catch (Exception e){
|
||||
throw new ResultException("删除文件失败,请检查配置信息", e);
|
||||
|
|
@ -131,5 +119,11 @@ public class AliServiceImpl implements OssService {
|
|||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream getFileStream(FileSourceInfo info) {
|
||||
OSSObject object = oss.getObject(config.getBucketName(), info.getPath());
|
||||
return object.getObjectContent();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,61 +0,0 @@
|
|||
package com.chushang.oss.service.impl;
|
||||
|
||||
import com.chushang.oss.service.OssService;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @auther: zhao
|
||||
* @date: 2024/4/28 19:53
|
||||
*/
|
||||
@Service
|
||||
@ConditionalOnExpression("'${config.oss.storage}'.equals('local')")
|
||||
public class LocalServiceImpl implements OssService {
|
||||
@Override
|
||||
public String upload(byte[] data, String path) {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String uploadSuffix(byte[] data, String suffix) {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String uploadSuffix(byte[] data, String suffix, String filename) {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String uploadPrefix(byte[] data, String prefix, String suffix, String filename) {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String uploadPrefix(byte[] data, String prefix, String filename) {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String upload(InputStream inputStream, String path) {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String uploadSuffix(InputStream inputStream, String suffix) {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delFile(String path) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> delFileBatch(List<String> keys) {
|
||||
return List.of();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,61 +1,215 @@
|
|||
package com.chushang.oss.service.impl;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.chushang.common.core.exception.ResultException;
|
||||
import com.chushang.common.core.util.StringUtils;
|
||||
import com.chushang.oss.config.UploadConfig;
|
||||
import com.chushang.oss.entity.FileSourceInfo;
|
||||
import com.chushang.oss.service.OssService;
|
||||
import io.minio.*;
|
||||
import io.minio.errors.*;
|
||||
import io.minio.messages.Bucket;
|
||||
import io.minio.messages.DeleteError;
|
||||
import io.minio.messages.DeleteObject;
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.annotation.Resource;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.lang.module.ResolutionException;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @auther: zhao
|
||||
* @date: 2024/4/28 19:52
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
@ConditionalOnExpression("'$config.{oss.storage}'.equals('minio')")
|
||||
@ConditionalOnExpression("'${config.oss.storage}'.equals('minio')")
|
||||
public class MinioServiceImpl implements OssService {
|
||||
|
||||
private MinioClient minio;
|
||||
@Resource
|
||||
private UploadConfig config;
|
||||
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
minio = MinioClient.builder().endpoint(config.getEndPoint())
|
||||
.credentials(config.getAccessKey(), config.getSecretKey()).build();
|
||||
try {
|
||||
if (!minio.bucketExists(BucketExistsArgs.builder().bucket(config.getBucketName()).build())) {
|
||||
createBucket();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("MinIO Storage Connection Fail");
|
||||
}
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
private void createBucket(){
|
||||
String bucketName = config.getBucketName();
|
||||
|
||||
// 注意 minio通过nginx代理后无法判断桶是否存在 需要通过查询所有桶的形式
|
||||
List<Bucket> buckets = minio.listBuckets();
|
||||
|
||||
if (buckets != null) {
|
||||
Bucket bucket = buckets.stream().filter(b -> config.getBucketName().equals(b.name()))
|
||||
.findAny().orElse(null);
|
||||
if (bucket != null) {
|
||||
log.info("------------- 初始化 minio 配置 -------------");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
log.warn("【{}】桶不存在,开始创建", bucketName);
|
||||
|
||||
minio.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
|
||||
|
||||
// 设置默认桶策略
|
||||
String policy = StrUtil.format("{\n" +
|
||||
" \"Version\": \"2012-10-17\",\n" +
|
||||
" \"Statement\": [\n" +
|
||||
" {\n" +
|
||||
" \"Effect\": \"Allow\",\n" +
|
||||
" \"Principal\": {\n" +
|
||||
" \"AWS\": [\n" +
|
||||
" \"*\"\n" +
|
||||
" ]\n" +
|
||||
" },\n" +
|
||||
" \"Action\": [\n" +
|
||||
" \"s3:GetBucketLocation\"\n" +
|
||||
" ],\n" +
|
||||
" \"Resource\": [\n" +
|
||||
" \"arn:aws:s3:::{}\"\n" +
|
||||
" ]\n" +
|
||||
" },\n" +
|
||||
" {\n" +
|
||||
" \"Effect\": \"Allow\",\n" +
|
||||
" \"Principal\": {\n" +
|
||||
" \"AWS\": [\n" +
|
||||
" \"*\"\n" +
|
||||
" ]\n" +
|
||||
" },\n" +
|
||||
" \"Action\": [\n" +
|
||||
" \"s3:ListBucket\"\n" +
|
||||
" ],\n" +
|
||||
" \"Resource\": [\n" +
|
||||
" \"arn:aws:s3:::{}\"\n" +
|
||||
" ],\n" +
|
||||
" \"Condition\": {\n" +
|
||||
" \"StringEquals\": {\n" +
|
||||
" \"s3:prefix\": [\n" +
|
||||
" \"*\"\n" +
|
||||
" ]\n" +
|
||||
" }\n" +
|
||||
" }\n" +
|
||||
" },\n" +
|
||||
" {\n" +
|
||||
" \"Effect\": \"Allow\",\n" +
|
||||
" \"Principal\": {\n" +
|
||||
" \"AWS\": [\n" +
|
||||
" \"*\"\n" +
|
||||
" ]\n" +
|
||||
" },\n" +
|
||||
" \"Action\": [\n" +
|
||||
" \"s3:GetObject\"\n" +
|
||||
" ],\n" +
|
||||
" \"Resource\": [\n" +
|
||||
" \"arn:aws:s3:::{}/**\"\n" +
|
||||
" ]\n" +
|
||||
" }\n" +
|
||||
" ]\n" +
|
||||
"}", bucketName, bucketName, bucketName);
|
||||
|
||||
SetBucketPolicyArgs bucketPolicyArgs = SetBucketPolicyArgs.builder().bucket(bucketName).config(policy).build();
|
||||
|
||||
minio.setBucketPolicy(bucketPolicyArgs);
|
||||
|
||||
log.warn("【{}】桶创建完成", bucketName);
|
||||
|
||||
log.info("------------- 初始化 minio 配置 -------------");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String upload(byte[] data, String path) {
|
||||
return "";
|
||||
public String getPrefixPath(String prefix, String filename) {
|
||||
String minioPrefix = config.getPrefix();
|
||||
if (StringUtils.isNotEmpty(minioPrefix)) {
|
||||
prefix = minioPrefix + "/" + prefix + "/" + filename;
|
||||
} else {
|
||||
prefix = prefix + "/" + filename;
|
||||
}
|
||||
return prefix;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String uploadSuffix(byte[] data, String suffix) {
|
||||
return "";
|
||||
public String upload(InputStream inputStream, FileSourceInfo info) {
|
||||
try {
|
||||
minio.putObject(PutObjectArgs.builder().bucket(config.getBucketName())
|
||||
// 路径 object 为路径地址
|
||||
.object(info.getPath())
|
||||
.stream(inputStream, inputStream.available(), -1)
|
||||
.contentType(info.getMimeType())
|
||||
.build());
|
||||
} catch (Exception e) {
|
||||
log.error("上传MINio 异常", e);
|
||||
}
|
||||
// 需要添加上 bucket
|
||||
return config.getEndPoint() + "/" + config.getBucketName() + "/" + info.getPath();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String uploadSuffix(byte[] data, String suffix, String filename) {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String uploadPrefix(byte[] data, String prefix, String suffix, String filename) {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String uploadPrefix(byte[] data, String prefix, String filename) {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String upload(InputStream inputStream, String path) {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String uploadSuffix(InputStream inputStream, String suffix) {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delFile(String path) {
|
||||
|
||||
public void delFile(String fid) {
|
||||
try {
|
||||
minio.removeObject(RemoveObjectArgs.builder()
|
||||
.bucket(config.getBucketName())
|
||||
.object(fid)
|
||||
.build());
|
||||
} catch (Exception ig) {
|
||||
log.error("删除失败");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> delFileBatch(List<String> keys) {
|
||||
return List.of();
|
||||
Iterable<Result<DeleteError>> results
|
||||
= minio.removeObjects(RemoveObjectsArgs.builder()
|
||||
.bucket(config.getBucketName())
|
||||
.objects(keys.stream().map(DeleteObject::new).toList())
|
||||
.build());
|
||||
List<String> resultKey = new ArrayList<>();
|
||||
results.forEach(result -> {
|
||||
try {
|
||||
DeleteError deleteError = result.get();
|
||||
String s = deleteError.objectName();
|
||||
resultKey.add(s);
|
||||
} catch (Exception e) {
|
||||
log.error("删除result error", e);
|
||||
}
|
||||
});
|
||||
return resultKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream getFileStream(FileSourceInfo info) {
|
||||
try {
|
||||
GetObjectResponse object = minio.getObject(GetObjectArgs.builder()
|
||||
.bucket(config.getBucketName())
|
||||
.object(info.getPath())
|
||||
.build());
|
||||
return new ByteArrayInputStream(object.readAllBytes());
|
||||
} catch (Exception e) {
|
||||
log.error("获取minio object error", e);
|
||||
throw new ResultException("获取文件失败");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
package com.chushang.oss.service.impl;
|
||||
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.chushang.common.core.web.Result;
|
||||
import com.chushang.oss.entity.dto.OcrDTO;
|
||||
import com.chushang.oss.service.OcrService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
public class OcrServiceImpl implements OcrService {
|
||||
/**
|
||||
* 尚未接入ocr
|
||||
*/
|
||||
@Override
|
||||
public Result<JSONObject> ocr(OcrDTO ocr) {
|
||||
log.error("尚未接入ocr");
|
||||
return Result.failed("尚未接入ocr");
|
||||
}
|
||||
}
|
||||
|
|
@ -16,9 +16,9 @@ spring:
|
|||
datasource:
|
||||
type: com.zaxxer.hikari.HikariDataSource
|
||||
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||
username: ${conf.jdbc.master.oss.username}
|
||||
password: ${conf.jdbc.master.oss.password}
|
||||
url: jdbc:mysql://${conf.jdbc.master.oss.host}:${conf.jdbc.master.oss.port}/${conf.jdbc.master.oss.database}?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&allowMultiQueries=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=Asia/Shanghai
|
||||
username: ${config.jdbc.master.oss.username}
|
||||
password: ${config.jdbc.master.oss.password}
|
||||
url: jdbc:mysql://${config.jdbc.master.oss.host}:${config.jdbc.master.oss.port}/${config.jdbc.master.oss.database}?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&allowMultiQueries=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=Asia/Shanghai
|
||||
hikari:
|
||||
# 最大线程池数量
|
||||
maximum-pool-size: 30
|
||||
|
|
@ -88,4 +88,3 @@ management:
|
|||
logging:
|
||||
config: classpath:logback-nacos.xml
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@ spring:
|
|||
config:
|
||||
import:
|
||||
-: "classpath:application.yml"
|
||||
|
||||
application:
|
||||
name: @artifactId@
|
||||
cloud:
|
||||
|
|
@ -34,10 +33,8 @@ spring:
|
|||
refresh-enabled: true
|
||||
shared-configs:
|
||||
# 此处不应当 走common 了, 每个羡慕应该有自己单独的 db.yaml 文件 redis 可以使用公共
|
||||
- dataId: db-common.${spring.cloud.nacos.config.file-extension}
|
||||
- dataId: application-common.${spring.cloud.nacos.config.file-extension}
|
||||
group: ${spring.cloud.nacos.discovery.group}
|
||||
refresh: ${spring.cloud.nacos.config.refresh-enabled}
|
||||
profiles:
|
||||
active: @profiles.active@
|
||||
main:
|
||||
allow-bean-definition-overriding: true
|
||||
|
|
@ -55,8 +55,7 @@ public class SysConfig extends BaseEntity
|
|||
* 创建人
|
||||
*/
|
||||
@TableField(
|
||||
value = "create_by",
|
||||
updateStrategy = FieldStrategy.NEVER
|
||||
value = "create_by"
|
||||
)
|
||||
@ExcelProperty(value = "创建人", index = 5)
|
||||
private String createBy;
|
||||
|
|
@ -64,8 +63,7 @@ public class SysConfig extends BaseEntity
|
|||
* 修改人
|
||||
*/
|
||||
@TableField(
|
||||
value = "update_by",
|
||||
insertStrategy = FieldStrategy.NEVER
|
||||
value = "update_by"
|
||||
)
|
||||
@ExcelProperty(value = "修改人", index = 6)
|
||||
private String updateBy;
|
||||
|
|
|
|||
|
|
@ -60,16 +60,14 @@ public class SysDept extends BaseEntity
|
|||
* 创建人
|
||||
*/
|
||||
@TableField(
|
||||
value = "create_by",
|
||||
updateStrategy = FieldStrategy.NEVER
|
||||
value = "create_by"
|
||||
)
|
||||
private String createBy;
|
||||
/**
|
||||
* 修改人
|
||||
*/
|
||||
@TableField(
|
||||
value = "update_by",
|
||||
insertStrategy = FieldStrategy.NEVER
|
||||
value = "update_by"
|
||||
)
|
||||
private String updateBy;
|
||||
|
||||
|
|
|
|||
|
|
@ -79,16 +79,14 @@ public class SysDictData extends BaseEntity {
|
|||
* 创建人
|
||||
*/
|
||||
@TableField(
|
||||
value = "create_by",
|
||||
updateStrategy = FieldStrategy.NEVER
|
||||
value = "create_by"
|
||||
)
|
||||
protected String createBy;
|
||||
/**
|
||||
* 修改人
|
||||
*/
|
||||
@TableField(
|
||||
value = "update_by",
|
||||
insertStrategy = FieldStrategy.NEVER
|
||||
value = "update_by"
|
||||
)
|
||||
protected String updateBy;
|
||||
|
||||
|
|
|
|||
|
|
@ -52,8 +52,7 @@ public class SysDictType extends BaseEntity
|
|||
* 创建人
|
||||
*/
|
||||
@TableField(
|
||||
value = "create_by",
|
||||
updateStrategy = FieldStrategy.NEVER
|
||||
value = "create_by"
|
||||
)
|
||||
@ExcelProperty(value = "创建人", index = 4)
|
||||
protected String createBy;
|
||||
|
|
@ -61,8 +60,7 @@ public class SysDictType extends BaseEntity
|
|||
* 修改人
|
||||
*/
|
||||
@TableField(
|
||||
value = "update_by",
|
||||
insertStrategy = FieldStrategy.NEVER
|
||||
value = "update_by"
|
||||
)
|
||||
@ExcelProperty(value = "修改人", index = 5)
|
||||
protected String updateBy;
|
||||
|
|
|
|||
|
|
@ -97,16 +97,14 @@ public class SysMenu extends BaseEntity {
|
|||
* 创建人
|
||||
*/
|
||||
@TableField(
|
||||
value = "create_by",
|
||||
updateStrategy = FieldStrategy.NEVER
|
||||
value = "create_by"
|
||||
)
|
||||
protected String createBy;
|
||||
/**
|
||||
* 修改人
|
||||
*/
|
||||
@TableField(
|
||||
value = "update_by",
|
||||
insertStrategy = FieldStrategy.NEVER
|
||||
value = "update_by"
|
||||
)
|
||||
protected String updateBy;
|
||||
|
||||
|
|
|
|||
|
|
@ -56,8 +56,7 @@ public class SysPost extends BaseEntity
|
|||
* 创建人
|
||||
*/
|
||||
@TableField(
|
||||
value = "create_by",
|
||||
updateStrategy = FieldStrategy.NEVER
|
||||
value = "create_by"
|
||||
)
|
||||
@ExcelProperty(value = "创建人", index = 4)
|
||||
protected String createBy;
|
||||
|
|
@ -65,8 +64,7 @@ public class SysPost extends BaseEntity
|
|||
* 修改人
|
||||
*/
|
||||
@TableField(
|
||||
value = "update_by",
|
||||
insertStrategy = FieldStrategy.NEVER
|
||||
value = "update_by"
|
||||
)
|
||||
@ExcelProperty(value = "修改人", index = 5)
|
||||
protected String updateBy;
|
||||
|
|
|
|||
|
|
@ -91,16 +91,14 @@ public class SysRole extends BaseEntity {
|
|||
* 创建人
|
||||
*/
|
||||
@TableField(
|
||||
value = "create_by",
|
||||
updateStrategy = FieldStrategy.NEVER
|
||||
value = "create_by"
|
||||
)
|
||||
protected String createBy;
|
||||
/**
|
||||
* 修改人
|
||||
*/
|
||||
@TableField(
|
||||
value = "update_by",
|
||||
insertStrategy = FieldStrategy.NEVER
|
||||
value = "update_by"
|
||||
)
|
||||
protected String updateBy;
|
||||
/**
|
||||
|
|
|
|||
Loading…
Reference in New Issue