package cn.iocoder.yudao.module.mes.service.safety;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.module.infra.api.file.FileApi;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* 安全生产 - 移动端附件上传 Service
*
*
巡检、隐患、作业票、演练等环节的现场拍照统一走这里:
* 落到 infra 文件存储,返回可访问 URL,多个附件逗号拼接后存入业务表。
*
* @author 超级管理员
*/
@Service
@Slf4j
public class SafetyFileService {
/** 单个文件最大 20MB,手机原图裁切后足够 */
private static final long MAX_SIZE = 20L * 1024 * 1024;
/** 允许的图片类型 */
private static final List ALLOWED_EXT = List.of(
"jpg", "jpeg", "png", "webp", "heic", "gif", "bmp", "pdf", "doc", "docx", "xls", "xlsx");
@Resource
private FileApi fileApi;
/**
* 上传单个文件
*
* @param file 文件
* @param bizType 业务类型(safety/inspection、safety/hazard 等),用作存储目录
* @return 文件访问 URL
*/
public String upload(MultipartFile file, String bizType) {
if (file == null || file.isEmpty()) {
throw new IllegalArgumentException("上传文件不能为空");
}
if (file.getSize() > MAX_SIZE) {
throw new IllegalArgumentException("单个文件不能超过 20MB");
}
String originalName = StrUtil.blankToDefault(file.getOriginalFilename(), "photo.jpg");
String ext = StrUtil.subAfter(originalName, ".", true).toLowerCase();
if (StrUtil.isNotBlank(ext) && !ALLOWED_EXT.contains(ext)) {
throw new IllegalArgumentException("不支持的文件类型:" + ext);
}
byte[] content;
try {
content = IoUtil.readBytes(file.getInputStream());
} catch (IOException e) {
throw new IllegalStateException("读取上传文件失败", e);
}
String directory = StrUtil.blankToDefault(bizType, "safety") + "/" + java.time.LocalDate.now();
return fileApi.createFile(content, originalName, directory, file.getContentType());
}
/**
* 批量上传(移动端一次拍多张)
*
* @return 文件 URL 列表
*/
public List uploadBatch(List files, String bizType) {
if (files == null || files.isEmpty()) {
return List.of();
}
if (files.size() > 9) {
throw new IllegalArgumentException("单次最多上传 9 张");
}
List urls = new ArrayList<>();
for (MultipartFile file : files) {
urls.add(upload(file, bizType));
}
return urls;
}
/**
* 删除附件(从逗号串里剔除某个 URL)
*/
public String removeUrl(String urls, String target) {
if (StrUtil.isBlank(urls) || StrUtil.isBlank(target)) {
return urls;
}
return Arrays.stream(urls.split(","))
.map(String::trim)
.filter(url -> !url.equals(target.trim()))
.reduce((a, b) -> a + "," + b)
.orElse("");
}
}