增加模版
This commit is contained in:
@@ -0,0 +1,40 @@
|
||||
package com.bms.system.domain;
|
||||
|
||||
import com.bms.common.core.domain.BaseEntity;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
/** System file template sys_file_template (OSS). */
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class SysFileTemplate extends BaseEntity
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public static final String TYPE_SALES = "SALES";
|
||||
public static final String TYPE_REDLINE = "REDLINE";
|
||||
public static final String TYPE_PRODUCT = "PRODUCT";
|
||||
public static final String TYPE_CHARGE_WEIGHT = "CHARGE_WEIGHT";
|
||||
|
||||
public static final String CODE_PRODUCT_ALL = "PRODUCT_ALL";
|
||||
public static final String CODE_PRODUCT_COUNTRY = "PRODUCT_COUNTRY";
|
||||
public static final String CODE_REDLINE_ALL = "REDLINE_ALL";
|
||||
public static final String CODE_REDLINE_COUNTRY = "REDLINE_COUNTRY";
|
||||
public static final String CODE_SALES = "SALES";
|
||||
public static final String CODE_CHARGE_WEIGHT = "CHARGE_WEIGHT";
|
||||
|
||||
private Long templateId;
|
||||
/** Dict: sys_file_template_type */
|
||||
private String templateType;
|
||||
/** Unique business code */
|
||||
private String fileCode;
|
||||
private String templateName;
|
||||
private String fileName;
|
||||
/** oss://bucket/key */
|
||||
private String filePath;
|
||||
private Long fileSize;
|
||||
private String contentType;
|
||||
private String fileExtension;
|
||||
/** 0 normal / 1 disable */
|
||||
private String status;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.bms.system.mapper;
|
||||
|
||||
import java.util.List;
|
||||
import com.bms.system.domain.SysFileTemplate;
|
||||
|
||||
public interface SysFileTemplateMapper
|
||||
{
|
||||
SysFileTemplate selectSysFileTemplateById(Long templateId);
|
||||
|
||||
SysFileTemplate selectByFileCode(String fileCode);
|
||||
|
||||
List<SysFileTemplate> selectSysFileTemplateList(SysFileTemplate query);
|
||||
|
||||
int insertSysFileTemplate(SysFileTemplate row);
|
||||
|
||||
int updateSysFileTemplate(SysFileTemplate row);
|
||||
|
||||
int deleteSysFileTemplateByIds(Long[] templateIds);
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.bms.system.service;
|
||||
|
||||
import java.util.List;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import com.bms.system.domain.SysFileTemplate;
|
||||
|
||||
public interface ISysFileTemplateService
|
||||
{
|
||||
SysFileTemplate selectSysFileTemplateById(Long templateId);
|
||||
|
||||
SysFileTemplate selectByFileCode(String fileCode);
|
||||
|
||||
List<SysFileTemplate> selectSysFileTemplateList(SysFileTemplate query);
|
||||
|
||||
int insertSysFileTemplate(SysFileTemplate row);
|
||||
|
||||
int updateSysFileTemplate(SysFileTemplate row);
|
||||
|
||||
int deleteSysFileTemplateByIds(Long[] templateIds);
|
||||
|
||||
/** Upload / replace Excel file on OSS for an existing template row. */
|
||||
SysFileTemplate uploadFile(Long templateId, MultipartFile file, String operName) throws Exception;
|
||||
|
||||
/** Download by file_code (enabled templates only). */
|
||||
void downloadByFileCode(String fileCode, HttpServletResponse response) throws Exception;
|
||||
}
|
||||
+32
-17
@@ -1,32 +1,34 @@
|
||||
package com.bms.system.service.impl;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import com.bms.common.config.BmsConfig;
|
||||
import com.bms.common.exception.ServiceException;
|
||||
import com.bms.common.utils.DateUtils;
|
||||
import com.bms.common.utils.StringUtils;
|
||||
import com.bms.common.utils.file.FileUploadUtils;
|
||||
import com.bms.common.utils.file.OssStorage;
|
||||
import com.bms.common.utils.uuid.IdUtils;
|
||||
import com.bms.system.domain.BmsBizAttachment;
|
||||
import com.bms.system.mapper.BmsBizAttachmentMapper;
|
||||
import com.bms.system.service.IBmsBizAttachmentService;
|
||||
|
||||
/** Business attachments: always store on OSS (file_path = oss://bucket/key). */
|
||||
@Service
|
||||
public class BmsBizAttachmentServiceImpl implements IBmsBizAttachmentService
|
||||
{
|
||||
private static final String SUB_DIR = "biz/attachment";
|
||||
private static final String OBJECT_DIR = "biz/attachment";
|
||||
|
||||
@Autowired
|
||||
private BmsBizAttachmentMapper attachmentMapper;
|
||||
|
||||
@Autowired
|
||||
private OssStorage ossStorage;
|
||||
|
||||
@Override
|
||||
public BmsBizAttachment selectBmsBizAttachmentById(Long attachmentId)
|
||||
{
|
||||
@@ -59,29 +61,30 @@ public class BmsBizAttachmentServiceImpl implements IBmsBizAttachmentService
|
||||
ext = "bin";
|
||||
}
|
||||
ext = ext.toLowerCase(Locale.ROOT);
|
||||
String contentType = resolveContentType(ext);
|
||||
String typeSeg = bizType.trim().toLowerCase(Locale.ROOT).replaceAll("[^a-z0-9_-]", "_");
|
||||
String objectKey = OBJECT_DIR + "/" + typeSeg + "/"
|
||||
+ DateUtils.datePath() + "/" + IdUtils.fastSimpleUUID() + "." + ext;
|
||||
|
||||
String uploadDir = BmsConfig.getUploadPath() + File.separator + SUB_DIR;
|
||||
String pathName = DateUtils.datePath() + "/" + IdUtils.fastSimpleUUID() + "." + ext;
|
||||
File dest = FileUploadUtils.getAbsoluteFile(uploadDir, pathName);
|
||||
FileOutputStream fos = null;
|
||||
Path temp = Files.createTempFile("biz-attach-", "." + ext);
|
||||
String storageKey;
|
||||
try
|
||||
{
|
||||
fos = new FileOutputStream(dest);
|
||||
fos.write(bytes);
|
||||
Files.write(temp, bytes);
|
||||
storageKey = ossStorage.upload(temp, objectKey, contentType);
|
||||
}
|
||||
finally
|
||||
{
|
||||
IOUtils.close(fos);
|
||||
try { Files.deleteIfExists(temp); } catch (Exception ignore) { }
|
||||
}
|
||||
String storedPath = FileUploadUtils.getPathFileName(uploadDir, pathName);
|
||||
|
||||
BmsBizAttachment row = new BmsBizAttachment();
|
||||
row.setBizType(bizType.trim());
|
||||
row.setBizId(bizId);
|
||||
row.setFileName(originalName);
|
||||
row.setFilePath(storedPath);
|
||||
row.setFilePath(storageKey);
|
||||
row.setFileSize(Long.valueOf(bytes.length));
|
||||
row.setContentType(resolveContentType(ext));
|
||||
row.setContentType(contentType);
|
||||
row.setFileExtension(ext);
|
||||
row.setRemark(remark);
|
||||
row.setCreateBy(operName);
|
||||
@@ -99,6 +102,18 @@ public class BmsBizAttachmentServiceImpl implements IBmsBizAttachmentService
|
||||
{
|
||||
return "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
|
||||
}
|
||||
return "";
|
||||
if ("pdf".equals(ext))
|
||||
{
|
||||
return "application/pdf";
|
||||
}
|
||||
if ("png".equals(ext))
|
||||
{
|
||||
return "image/png";
|
||||
}
|
||||
if ("jpg".equals(ext) || "jpeg".equals(ext))
|
||||
{
|
||||
return "image/jpeg";
|
||||
}
|
||||
return "application/octet-stream";
|
||||
}
|
||||
}
|
||||
|
||||
+226
@@ -0,0 +1,226 @@
|
||||
package com.bms.system.service.impl;
|
||||
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import com.bms.common.exception.ServiceException;
|
||||
import com.bms.common.utils.DateUtils;
|
||||
import com.bms.common.utils.StringUtils;
|
||||
import com.bms.common.utils.file.FileUtils;
|
||||
import com.bms.common.utils.file.OssStorage;
|
||||
import com.bms.common.utils.uuid.IdUtils;
|
||||
import com.bms.system.domain.SysFileTemplate;
|
||||
import com.bms.system.mapper.SysFileTemplateMapper;
|
||||
import com.bms.system.service.ISysFileTemplateService;
|
||||
|
||||
@Service
|
||||
public class SysFileTemplateServiceImpl implements ISysFileTemplateService
|
||||
{
|
||||
private static final String OBJECT_DIR = "system/fileTemplate";
|
||||
|
||||
@Autowired
|
||||
private SysFileTemplateMapper templateMapper;
|
||||
|
||||
@Autowired
|
||||
private OssStorage ossStorage;
|
||||
|
||||
@Override
|
||||
public SysFileTemplate selectSysFileTemplateById(Long templateId)
|
||||
{
|
||||
return templateMapper.selectSysFileTemplateById(templateId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SysFileTemplate selectByFileCode(String fileCode)
|
||||
{
|
||||
if (StringUtils.isEmpty(fileCode))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return templateMapper.selectByFileCode(fileCode.trim());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SysFileTemplate> selectSysFileTemplateList(SysFileTemplate query)
|
||||
{
|
||||
return templateMapper.selectSysFileTemplateList(query);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int insertSysFileTemplate(SysFileTemplate row)
|
||||
{
|
||||
normalize(row);
|
||||
assertFileCodeUnique(row.getFileCode(), null);
|
||||
return templateMapper.insertSysFileTemplate(row);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int updateSysFileTemplate(SysFileTemplate row)
|
||||
{
|
||||
normalize(row);
|
||||
assertFileCodeUnique(row.getFileCode(), row.getTemplateId());
|
||||
return templateMapper.updateSysFileTemplate(row);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int deleteSysFileTemplateByIds(Long[] templateIds)
|
||||
{
|
||||
if (templateIds == null || templateIds.length == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
for (Long id : templateIds)
|
||||
{
|
||||
SysFileTemplate old = templateMapper.selectSysFileTemplateById(id);
|
||||
if (old != null && StringUtils.isNotEmpty(old.getFilePath()) && old.getFilePath().startsWith("oss://"))
|
||||
{
|
||||
try { ossStorage.delete(old.getFilePath()); } catch (Exception ignore) { }
|
||||
}
|
||||
}
|
||||
return templateMapper.deleteSysFileTemplateByIds(templateIds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SysFileTemplate uploadFile(Long templateId, MultipartFile file, String operName) throws Exception
|
||||
{
|
||||
if (templateId == null)
|
||||
{
|
||||
throw new ServiceException("templateId required");
|
||||
}
|
||||
if (file == null || file.isEmpty())
|
||||
{
|
||||
throw new ServiceException("file empty");
|
||||
}
|
||||
SysFileTemplate row = templateMapper.selectSysFileTemplateById(templateId);
|
||||
if (row == null)
|
||||
{
|
||||
throw new ServiceException("template not found");
|
||||
}
|
||||
String originalName = file.getOriginalFilename();
|
||||
if (StringUtils.isEmpty(originalName))
|
||||
{
|
||||
originalName = "template.xlsx";
|
||||
}
|
||||
String ext = FilenameUtils.getExtension(originalName);
|
||||
if (StringUtils.isEmpty(ext))
|
||||
{
|
||||
ext = "xlsx";
|
||||
}
|
||||
ext = ext.toLowerCase(Locale.ROOT);
|
||||
if (!"xlsx".equals(ext) && !"xls".equals(ext))
|
||||
{
|
||||
throw new ServiceException("only xlsx/xls allowed");
|
||||
}
|
||||
String contentType = "xlsx".equals(ext)
|
||||
? "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
|
||||
: "application/vnd.ms-excel";
|
||||
String typeSeg = StringUtils.isEmpty(row.getTemplateType()) ? "misc"
|
||||
: row.getTemplateType().trim().toLowerCase(Locale.ROOT);
|
||||
String objectKey = OBJECT_DIR + "/" + typeSeg + "/"
|
||||
+ DateUtils.datePath() + "/" + IdUtils.fastSimpleUUID() + "." + ext;
|
||||
|
||||
Path temp = Files.createTempFile("sys-file-tpl-", "." + ext);
|
||||
String storageKey;
|
||||
try
|
||||
{
|
||||
file.transferTo(temp);
|
||||
storageKey = ossStorage.upload(temp, objectKey, contentType);
|
||||
}
|
||||
finally
|
||||
{
|
||||
try { Files.deleteIfExists(temp); } catch (Exception ignore) { }
|
||||
}
|
||||
|
||||
String oldPath = row.getFilePath();
|
||||
SysFileTemplate upd = new SysFileTemplate();
|
||||
upd.setTemplateId(templateId);
|
||||
upd.setFileName(originalName);
|
||||
upd.setFilePath(storageKey);
|
||||
upd.setFileSize(Long.valueOf(file.getSize()));
|
||||
upd.setContentType(contentType);
|
||||
upd.setFileExtension(ext);
|
||||
upd.setUpdateBy(operName);
|
||||
templateMapper.updateSysFileTemplate(upd);
|
||||
|
||||
if (StringUtils.isNotEmpty(oldPath) && oldPath.startsWith("oss://") && !oldPath.equals(storageKey))
|
||||
{
|
||||
try { ossStorage.delete(oldPath); } catch (Exception ignore) { }
|
||||
}
|
||||
return templateMapper.selectSysFileTemplateById(templateId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void downloadByFileCode(String fileCode, HttpServletResponse response) throws Exception
|
||||
{
|
||||
SysFileTemplate row = selectByFileCode(fileCode);
|
||||
if (row == null)
|
||||
{
|
||||
throw new ServiceException("template not found");
|
||||
}
|
||||
if (!"0".equals(StringUtils.nvl(row.getStatus(), "0")))
|
||||
{
|
||||
throw new ServiceException("template disabled");
|
||||
}
|
||||
if (StringUtils.isEmpty(row.getFilePath()))
|
||||
{
|
||||
throw new ServiceException("template file not uploaded");
|
||||
}
|
||||
String name = StringUtils.isNotEmpty(row.getFileName()) ? row.getFileName()
|
||||
: (row.getFileCode() + ".xlsx");
|
||||
response.setContentType(StringUtils.isNotEmpty(row.getContentType())
|
||||
? row.getContentType()
|
||||
: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
|
||||
FileUtils.setAttachmentResponseHeader(response, name);
|
||||
if (row.getFilePath().startsWith("oss://"))
|
||||
{
|
||||
ossStorage.download(row.getFilePath(), response.getOutputStream());
|
||||
return;
|
||||
}
|
||||
// Legacy local path fallback
|
||||
if (!FileUtils.checkAllowDownload(row.getFilePath()))
|
||||
{
|
||||
throw new ServiceException("template path illegal");
|
||||
}
|
||||
String local = com.bms.common.config.BmsConfig.getProfile() + FileUtils.stripPrefix(row.getFilePath());
|
||||
FileUtils.writeBytes(local, response.getOutputStream());
|
||||
}
|
||||
|
||||
private void normalize(SysFileTemplate row)
|
||||
{
|
||||
if (row == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (StringUtils.isNotEmpty(row.getTemplateType()))
|
||||
{
|
||||
row.setTemplateType(row.getTemplateType().trim().toUpperCase(Locale.ROOT));
|
||||
}
|
||||
if (StringUtils.isNotEmpty(row.getFileCode()))
|
||||
{
|
||||
row.setFileCode(row.getFileCode().trim().toUpperCase(Locale.ROOT));
|
||||
}
|
||||
if (StringUtils.isNotEmpty(row.getTemplateName()))
|
||||
{
|
||||
row.setTemplateName(row.getTemplateName().trim());
|
||||
}
|
||||
}
|
||||
|
||||
private void assertFileCodeUnique(String fileCode, Long excludeId)
|
||||
{
|
||||
if (StringUtils.isEmpty(fileCode))
|
||||
{
|
||||
throw new ServiceException("fileCode required");
|
||||
}
|
||||
SysFileTemplate exist = templateMapper.selectByFileCode(fileCode.trim());
|
||||
if (exist != null && (excludeId == null || !excludeId.equals(exist.getTemplateId())))
|
||||
{
|
||||
throw new ServiceException("fileCode already exists");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.bms.system.mapper.SysFileTemplateMapper">
|
||||
|
||||
<resultMap type="com.bms.system.domain.SysFileTemplate" id="SysFileTemplateResult">
|
||||
<id property="templateId" column="template_id" />
|
||||
<result property="templateType" column="template_type" />
|
||||
<result property="fileCode" column="file_code" />
|
||||
<result property="templateName" column="template_name" />
|
||||
<result property="fileName" column="file_name" />
|
||||
<result property="filePath" column="file_path" />
|
||||
<result property="fileSize" column="file_size" />
|
||||
<result property="contentType" column="content_type" />
|
||||
<result property="fileExtension" column="file_extension" />
|
||||
<result property="status" column="status" />
|
||||
<result property="remark" column="remark" />
|
||||
<result property="createBy" column="create_by" />
|
||||
<result property="createTime" column="create_time" />
|
||||
<result property="updateBy" column="update_by" />
|
||||
<result property="updateTime" column="update_time" />
|
||||
</resultMap>
|
||||
|
||||
<sql id="selectVo">
|
||||
select template_id, template_type, file_code, template_name, file_name, file_path,
|
||||
file_size, content_type, file_extension, status, remark,
|
||||
create_by, create_time, update_by, update_time
|
||||
from sys_file_template
|
||||
</sql>
|
||||
|
||||
<select id="selectSysFileTemplateById" resultMap="SysFileTemplateResult">
|
||||
<include refid="selectVo"/>
|
||||
where template_id = #{templateId}
|
||||
</select>
|
||||
|
||||
<select id="selectByFileCode" resultMap="SysFileTemplateResult">
|
||||
<include refid="selectVo"/>
|
||||
where file_code = #{fileCode}
|
||||
limit 1
|
||||
</select>
|
||||
|
||||
<select id="selectSysFileTemplateList" parameterType="com.bms.system.domain.SysFileTemplate" resultMap="SysFileTemplateResult">
|
||||
<include refid="selectVo"/>
|
||||
<where>
|
||||
<if test="templateType != null and templateType != ''">and template_type = #{templateType}</if>
|
||||
<if test="fileCode != null and fileCode != ''">and file_code like concat('%', #{fileCode}, '%')</if>
|
||||
<if test="templateName != null and templateName != ''">and template_name like concat('%', #{templateName}, '%')</if>
|
||||
<if test="status != null and status != ''">and status = #{status}</if>
|
||||
</where>
|
||||
order by template_type asc, file_code asc, template_id asc
|
||||
</select>
|
||||
|
||||
<insert id="insertSysFileTemplate" parameterType="com.bms.system.domain.SysFileTemplate" useGeneratedKeys="true" keyProperty="templateId">
|
||||
insert into sys_file_template (
|
||||
template_type, file_code, template_name, file_name, file_path, file_size,
|
||||
content_type, file_extension, status, remark, create_by, create_time
|
||||
) values (
|
||||
#{templateType}, #{fileCode}, #{templateName}, #{fileName}, #{filePath}, #{fileSize},
|
||||
#{contentType}, #{fileExtension}, ifnull(#{status}, '0'), #{remark}, #{createBy}, sysdate()
|
||||
)
|
||||
</insert>
|
||||
|
||||
<update id="updateSysFileTemplate" parameterType="com.bms.system.domain.SysFileTemplate">
|
||||
update sys_file_template
|
||||
<set>
|
||||
<if test="templateType != null and templateType != ''">template_type = #{templateType},</if>
|
||||
<if test="fileCode != null and fileCode != ''">file_code = #{fileCode},</if>
|
||||
<if test="templateName != null and templateName != ''">template_name = #{templateName},</if>
|
||||
<if test="fileName != null">file_name = #{fileName},</if>
|
||||
<if test="filePath != null">file_path = #{filePath},</if>
|
||||
<if test="fileSize != null">file_size = #{fileSize},</if>
|
||||
<if test="contentType != null">content_type = #{contentType},</if>
|
||||
<if test="fileExtension != null">file_extension = #{fileExtension},</if>
|
||||
<if test="status != null and status != ''">status = #{status},</if>
|
||||
<if test="remark != null">remark = #{remark},</if>
|
||||
<if test="updateBy != null">update_by = #{updateBy},</if>
|
||||
update_time = sysdate()
|
||||
</set>
|
||||
where template_id = #{templateId}
|
||||
</update>
|
||||
|
||||
<delete id="deleteSysFileTemplateByIds">
|
||||
delete from sys_file_template where template_id in
|
||||
<foreach collection="array" item="id" open="(" separator="," close=")">#{id}</foreach>
|
||||
</delete>
|
||||
</mapper>
|
||||
Reference in New Issue
Block a user