Browse Source

基因定制附件生成

陈长荣 5 months ago
parent
commit
b8c4cedbd1
17 changed files with 8949 additions and 13 deletions
  1. 4 3
      jfcloud-gene-biz/src/main/java/com/github/jfcloud/gene/file/controller/FileController.java
  2. 10 0
      jfcloud-gene-biz/src/main/java/com/github/jfcloud/gene/file/service/FileInfoService.java
  3. 29 0
      jfcloud-gene-biz/src/main/java/com/github/jfcloud/gene/file/service/impl/FileInfoServiceImpl.java
  4. 7 0
      jfcloud-gene-biz/src/main/java/com/github/jfcloud/gene/flow/controller/FlowController.java
  5. 3 0
      jfcloud-gene-biz/src/main/java/com/github/jfcloud/gene/flow/dto/FlowDetailDto.java
  6. 5 2
      jfcloud-gene-biz/src/main/java/com/github/jfcloud/gene/flow/dto/FlowPageDto.java
  7. 85 0
      jfcloud-gene-biz/src/main/java/com/github/jfcloud/gene/flow/entity/FlowFileVersion.java
  8. 9 0
      jfcloud-gene-biz/src/main/java/com/github/jfcloud/gene/flow/mapper/FlowFileVersionMapper.java
  9. 15 0
      jfcloud-gene-biz/src/main/java/com/github/jfcloud/gene/flow/service/FlowFileVersionService.java
  10. 11 0
      jfcloud-gene-biz/src/main/java/com/github/jfcloud/gene/flow/service/FlowInfoService.java
  11. 23 0
      jfcloud-gene-biz/src/main/java/com/github/jfcloud/gene/flow/service/impl/FlowFileVersionServiceImpl.java
  12. 88 3
      jfcloud-gene-biz/src/main/java/com/github/jfcloud/gene/flow/service/impl/FlowInfoServiceImpl.java
  13. 1 1
      jfcloud-gene-biz/src/main/java/com/github/jfcloud/gene/form/entity/StrainCustomInfo.java
  14. 91 0
      jfcloud-gene-biz/src/main/java/com/github/jfcloud/gene/util/WordDataService.java
  15. 89 0
      jfcloud-gene-biz/src/main/java/com/github/jfcloud/gene/util/WordUtil.java
  16. 8475 0
      jfcloud-gene-biz/src/main/resources/ftlTemplate/geneCustom.ftl
  17. 4 4
      jfcloud-gene-common/src/main/java/com/github/jfcloud/gene/common/interceptor/interceptor/StuffInterceptor.java

+ 4 - 3
jfcloud-gene-biz/src/main/java/com/github/jfcloud/gene/file/controller/FileController.java

@@ -4,6 +4,7 @@ import cn.hutool.core.io.file.FileNameUtil;
 import cn.hutool.core.util.IdUtil;
 import cn.hutool.core.util.StrUtil;
 import com.github.jfcloud.common.core.util.R;
+import com.github.jfcloud.common.file.core.FileProperties;
 import com.github.jfcloud.common.file.core.FileTemplate;
 import com.github.jfcloud.gene.file.vo.FileVo;
 import io.swagger.v3.oas.annotations.Operation;
@@ -25,7 +26,7 @@ import java.io.InputStream;
 @RequiredArgsConstructor
 public class FileController {
 
-    private static final String BUCKET_NAME = "jfcloud";
+    private final FileProperties ossProperties;
     private final FileTemplate fileTemplate;
 
     @Operation(summary = "上传文件")
@@ -33,11 +34,11 @@ public class FileController {
     public R<FileVo> upload(@RequestPart("file") MultipartFile file) {
         try (InputStream in = file.getInputStream()) {
             String fileName = IdUtil.simpleUUID() + StrUtil.DOT + FileNameUtil.getSuffix(file.getOriginalFilename());
-            fileTemplate.putObject(BUCKET_NAME, fileName, in);
+            fileTemplate.putObject(ossProperties.getBucketName(), fileName, in);
 
             FileVo vo = new FileVo();
             vo.setName(file.getOriginalFilename());
-            vo.setUrl(String.format("/admin/sys-file/%s/%s", BUCKET_NAME, fileName));
+            vo.setUrl(String.format("/admin/sys-file/%s/%s", ossProperties.getBucketName(), fileName));
             return R.ok(vo);
 
         } catch (Exception e) {

+ 10 - 0
jfcloud-gene-biz/src/main/java/com/github/jfcloud/gene/file/service/FileInfoService.java

@@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.extension.service.IService;
 import com.github.jfcloud.gene.file.entity.FileInfo;
 import com.github.jfcloud.gene.file.vo.FileVo;
 
+import java.io.InputStream;
 import java.util.List;
 
 public interface FileInfoService extends IService<FileInfo> {
@@ -14,4 +15,13 @@ public interface FileInfoService extends IService<FileInfo> {
      * @return
      */
     List<FileVo> listByRelateId(Long relateId);
+
+    /**
+     * 上传文件,自定义文件名
+     *
+     * @param fileInputStream 文件流
+     * @param fileName        文件名,带后缀
+     * @return
+     */
+    FileVo uploadFileWithFileName(InputStream fileInputStream, String fileName);
 }

+ 29 - 0
jfcloud-gene-biz/src/main/java/com/github/jfcloud/gene/file/service/impl/FileInfoServiceImpl.java

@@ -1,22 +1,32 @@
 package com.github.jfcloud.gene.file.service.impl;
 
 import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.lang.Assert;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.github.jfcloud.common.file.core.FileProperties;
+import com.github.jfcloud.common.file.core.FileTemplate;
 import com.github.jfcloud.gene.common.constant.WhetherEnum;
 import com.github.jfcloud.gene.file.entity.FileInfo;
 import com.github.jfcloud.gene.file.mapper.FileInfoMapper;
 import com.github.jfcloud.gene.file.service.FileInfoService;
 import com.github.jfcloud.gene.file.vo.FileVo;
+import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
 
+import java.io.InputStream;
 import java.util.List;
 
 @Slf4j
 @Service
+@RequiredArgsConstructor
 public class FileInfoServiceImpl extends ServiceImpl<FileInfoMapper, FileInfo> implements FileInfoService {
 
+    private final FileTemplate fileTemplate;
+
+    private final FileProperties ossProperties;
+
     @Override
     public List<FileVo> listByRelateId(Long relateId) {
         List<FileInfo> list = list(new LambdaQueryWrapper<>(FileInfo.class)
@@ -25,4 +35,23 @@ public class FileInfoServiceImpl extends ServiceImpl<FileInfoMapper, FileInfo> i
                 .orderByAsc(FileInfo::getId));
         return BeanUtil.copyToList(list, FileVo.class);
     }
+
+    public FileVo uploadFileWithFileName(InputStream fileInputStream, String fileName) {
+        Assert.notNull(fileInputStream, "FileInputStream can not be null");
+
+        FileVo vo = new FileVo();
+        vo.setName(fileName);
+
+        try {
+            String bucketName = ossProperties.getBucketName();
+            fileTemplate.removeObject(bucketName, fileName);
+            fileTemplate.putObject(bucketName, fileName, fileInputStream);
+
+            vo.setUrl(String.format("/admin/sys-file/%s/%s", bucketName, fileName));
+        } catch (Exception e) {
+            log.error("上传失败", e);
+            Assert.isTrue(false, "附件生成上传失败");
+        }
+        return vo;
+    }
 }

+ 7 - 0
jfcloud-gene-biz/src/main/java/com/github/jfcloud/gene/flow/controller/FlowController.java

@@ -95,4 +95,11 @@ public class FlowController {
         flowInfoService.execute(id);
         return R.ok();
     }
+
+    @Operation(summary = "生成文档", hidden = true)
+    @PostMapping("/generate/{id}")
+    public R generate(@PathVariable Long id) {
+        flowInfoService.geneWord(id);
+        return R.ok();
+    }
 }

+ 3 - 0
jfcloud-gene-biz/src/main/java/com/github/jfcloud/gene/flow/dto/FlowDetailDto.java

@@ -62,6 +62,9 @@ public class FlowDetailDto {
     @Schema(description = "状态")
     private String statusLabel;
 
+    @Schema(description = "文件下载链接")
+    private String fileUrl;
+
     @Schema(description = "品系定制")
     private StrainCustomDto custom;
 

+ 5 - 2
jfcloud-gene-biz/src/main/java/com/github/jfcloud/gene/flow/dto/FlowPageDto.java

@@ -6,7 +6,7 @@ import lombok.Data;
 @Data
 public class FlowPageDto {
 
-    @Schema(description = "项目id")
+    @Schema(description = "流程id")
     private Long id;
 
     /**
@@ -28,7 +28,7 @@ public class FlowPageDto {
     private Long projectLeaderId;
 
     @Schema(description = "项目负责人")
-    private Long projectLeaderName;
+    private String projectLeaderName;
 
     /**
      * 状态
@@ -50,4 +50,7 @@ public class FlowPageDto {
 
     @Schema(description = "申请人")
     private String createByName;
+
+    @Schema(description = "文件下载链接")
+    private String fileUrl;
 }

+ 85 - 0
jfcloud-gene-biz/src/main/java/com/github/jfcloud/gene/flow/entity/FlowFileVersion.java

@@ -0,0 +1,85 @@
+package com.github.jfcloud.gene.flow.entity;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.github.jfcloud.gene.common.interceptor.anno.AutoStuff;
+import com.github.jfcloud.gene.common.interceptor.enums.AnnoEnum;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 文档更新记录
+ * flow_file_version
+ */
+@EqualsAndHashCode(callSuper = true)
+@Accessors(chain = true)
+@Data
+public class FlowFileVersion extends Model implements Serializable {
+    /**
+     * 主键
+     */
+    private Long id;
+
+    /**
+     * 流程id
+     */
+    private Long flowId;
+
+    /**
+     * 流程状态
+     */
+    private String flowStatus;
+
+    /**
+     * 模板名称
+     */
+    private String templateName;
+
+    /**
+     * 模板数据
+     */
+    private String dataMap;
+
+    /**
+     * 文件名称
+     */
+    private String filename;
+
+    /**
+     * 文件路径
+     */
+    private String filepath;
+
+    /**
+     * 文件md5
+     */
+    private String fileMd5;
+
+    /**
+     * 请求路径
+     */
+    private String uri;
+
+    /**
+     * 创建人
+     */
+    @TableField(fill = FieldFill.INSERT)
+    @AutoStuff(annoType = AnnoEnum.CREATE_BY)
+    private String createBy;
+
+    /**
+     * 创建时间
+     */
+    @TableField(fill = FieldFill.INSERT, value = "create_time")
+    @AutoStuff(annoType = AnnoEnum.CREATE_TIME)
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date createTime;
+
+    private static final long serialVersionUID = 1L;
+}

+ 9 - 0
jfcloud-gene-biz/src/main/java/com/github/jfcloud/gene/flow/mapper/FlowFileVersionMapper.java

@@ -0,0 +1,9 @@
+package com.github.jfcloud.gene.flow.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.github.jfcloud.gene.flow.entity.FlowFileVersion;
+import org.apache.ibatis.annotations.Mapper;
+
+@Mapper
+public interface FlowFileVersionMapper extends BaseMapper<FlowFileVersion> {
+}

+ 15 - 0
jfcloud-gene-biz/src/main/java/com/github/jfcloud/gene/flow/service/FlowFileVersionService.java

@@ -0,0 +1,15 @@
+package com.github.jfcloud.gene.flow.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.github.jfcloud.gene.flow.entity.FlowFileVersion;
+
+public interface FlowFileVersionService extends IService<FlowFileVersion> {
+
+    /**
+     * 获取流程最新版本的文件地址
+     *
+     * @param flowId
+     * @return
+     */
+    String getLatestFileUrl(Long flowId);
+}

+ 11 - 0
jfcloud-gene-biz/src/main/java/com/github/jfcloud/gene/flow/service/FlowInfoService.java

@@ -13,6 +13,7 @@ public interface FlowInfoService extends IService<FlowInfo> {
 
     /**
      * 分页查询
+     *
      * @param vo
      * @return
      */
@@ -21,6 +22,7 @@ public interface FlowInfoService extends IService<FlowInfo> {
 
     /**
      * 详情
+     *
      * @param id
      * @return
      */
@@ -28,12 +30,14 @@ public interface FlowInfoService extends IService<FlowInfo> {
 
     /**
      * 新增
+     *
      * @param vo
      */
     void saveFlow(FlowDetailVo vo);
 
     /**
      * 编辑
+     *
      * @param id
      * @param vo
      */
@@ -60,4 +64,11 @@ public interface FlowInfoService extends IService<FlowInfo> {
      * @param id
      */
     void execute(Long id);
+
+    /**
+     * 生成文档
+     *
+     * @param flowInfo
+     */
+    void geneWord(Long flowId);
 }

+ 23 - 0
jfcloud-gene-biz/src/main/java/com/github/jfcloud/gene/flow/service/impl/FlowFileVersionServiceImpl.java

@@ -0,0 +1,23 @@
+package com.github.jfcloud.gene.flow.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.github.jfcloud.gene.flow.entity.FlowFileVersion;
+import com.github.jfcloud.gene.flow.mapper.FlowFileVersionMapper;
+import com.github.jfcloud.gene.flow.service.FlowFileVersionService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+@Slf4j
+@Service
+public class FlowFileVersionServiceImpl extends ServiceImpl<FlowFileVersionMapper, FlowFileVersion> implements FlowFileVersionService {
+
+    @Override
+    public String getLatestFileUrl(Long flowId) {
+        FlowFileVersion flowFileVersion = this.getOne(new LambdaQueryWrapper<>(FlowFileVersion.class)
+                .select(FlowFileVersion::getFilepath)
+                .eq(FlowFileVersion::getFlowId, flowId)
+                .orderByDesc(FlowFileVersion::getCreateTime).last("limit 1"));
+        return flowFileVersion != null ? flowFileVersion.getFilepath() : "";
+    }
+}

+ 88 - 3
jfcloud-gene-biz/src/main/java/com/github/jfcloud/gene/flow/service/impl/FlowInfoServiceImpl.java

@@ -1,23 +1,34 @@
 package com.github.jfcloud.gene.flow.service.impl;
 
 import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.date.DatePattern;
+import cn.hutool.core.date.DateUtil;
 import cn.hutool.core.lang.Assert;
+import cn.hutool.core.util.RandomUtil;
 import cn.hutool.core.util.StrUtil;
+import cn.hutool.crypto.digest.DigestUtil;
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.github.jfcloud.common.data.datascope.DataScope;
+import com.github.jfcloud.common.holder.RequestHolder;
 import com.github.jfcloud.gene.cache.UserIdNameCache;
 import com.github.jfcloud.gene.common.constant.StrConstant;
 import com.github.jfcloud.gene.common.constant.WhetherEnum;
 import com.github.jfcloud.gene.common.util.CustomIdGenerator;
 import com.github.jfcloud.gene.constants.GeneStatusEnum;
 import com.github.jfcloud.gene.constants.GeneTargetEnum;
+import com.github.jfcloud.gene.file.service.FileInfoService;
+import com.github.jfcloud.gene.file.vo.FileVo;
 import com.github.jfcloud.gene.flow.dto.FlowDetailDto;
 import com.github.jfcloud.gene.flow.dto.FlowPageDto;
 import com.github.jfcloud.gene.flow.entity.FlowAudit;
+import com.github.jfcloud.gene.flow.entity.FlowFileVersion;
 import com.github.jfcloud.gene.flow.entity.FlowInfo;
 import com.github.jfcloud.gene.flow.mapper.FlowInfoMapper;
+import com.github.jfcloud.gene.flow.service.FlowFileVersionService;
 import com.github.jfcloud.gene.flow.service.FlowInfoService;
 import com.github.jfcloud.gene.flow.service.NotifyService;
 import com.github.jfcloud.gene.flow.vo.FlowAuditVo;
@@ -27,10 +38,20 @@ import com.github.jfcloud.gene.form.entity.StrainCustomInfo;
 import com.github.jfcloud.gene.form.entity.StrainPurificationInfo;
 import com.github.jfcloud.gene.form.service.StrainCustomInfoService;
 import com.github.jfcloud.gene.form.service.StrainPurificationInfoService;
+import com.github.jfcloud.gene.util.WordDataService;
+import com.github.jfcloud.gene.util.WordUtil;
 import lombok.RequiredArgsConstructor;
+import lombok.SneakyThrows;
 import lombok.extern.slf4j.Slf4j;
+import org.docx4j.Docx4J;
+import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
 
+import javax.servlet.http.HttpServletRequest;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
 import java.util.List;
 import java.util.Objects;
 
@@ -43,6 +64,9 @@ public class FlowInfoServiceImpl extends ServiceImpl<FlowInfoMapper, FlowInfo> i
     private final StrainCustomInfoService customInfoService;
     private final StrainPurificationInfoService purificationInfoService;
     private final NotifyService notifyService;
+    private final WordDataService wordDataService;
+    private final FileInfoService fileInfoService;
+    private final FlowFileVersionService fileVersionService;
 
     @Override
     public Page<FlowPageDto> getPage(FlowPageVo vo) {
@@ -68,8 +92,13 @@ public class FlowInfoServiceImpl extends ServiceImpl<FlowInfoMapper, FlowInfo> i
         }
 
         List<FlowPageDto> records = BeanUtil.copyToList(page.getRecords(), FlowPageDto.class);
-        //补充申请人姓名
-        records.forEach(item -> item.setCreateByName(userIdNameCache.getNicknameByUserId(Long.parseLong(item.getCreateBy()))));
+
+        records.forEach(item -> {
+            //补充申请人姓名
+            item.setCreateByName(userIdNameCache.getNicknameByUserId(Long.parseLong(item.getCreateBy())));
+            //查询下载链接
+            item.setFileUrl(fileVersionService.getLatestFileUrl(item.getId()));
+        });
 
         Page<FlowPageDto> pageDto = new Page<>(page.getCurrent(), page.getSize(), page.getTotal());
         return pageDto.setRecords(records);
@@ -84,9 +113,14 @@ public class FlowInfoServiceImpl extends ServiceImpl<FlowInfoMapper, FlowInfo> i
         detail.setStatusLabel(Objects.requireNonNull(GeneStatusEnum.getByStatus(detail.getStatus())).getDescription());
         detail.setCustom(customInfoService.getByFlowId(id));
         detail.setPurification(purificationInfoService.getByFlowId(id));
+
+        //查询下载链接
+        detail.setFileUrl(fileVersionService.getLatestFileUrl(id));
+
         return detail;
     }
 
+    @Transactional(rollbackFor = Exception.class)
     @Override
     public void saveFlow(FlowDetailVo vo) {
         log.info("保存流程 项目名称:{}", vo.getProjectName());
@@ -114,8 +148,11 @@ public class FlowInfoServiceImpl extends ServiceImpl<FlowInfoMapper, FlowInfo> i
         }
         flowInfo.setStatus(GeneStatusEnum.DRAFT.getStatus());
         flowInfo.insert();
+
+        geneWord(flowInfo.getId());
     }
 
+    @Transactional(rollbackFor = Exception.class)
     @Override
     public void updateFlow(Long id, FlowDetailVo vo) {
         log.info("编辑流程 项目名称:{}", vo.getProjectName());
@@ -124,7 +161,6 @@ public class FlowInfoServiceImpl extends ServiceImpl<FlowInfoMapper, FlowInfo> i
         Assert.notNull(flowInfo, "基因定制流程不存在");
         BeanUtil.copyProperties(vo, flowInfo);
 
-
         StringBuilder target = new StringBuilder();
         if (vo.getCustom() == null) {
             customInfoService.remove(new LambdaQueryWrapper<>(StrainCustomInfo.class).eq(StrainCustomInfo::getFlowId, id));
@@ -148,6 +184,8 @@ public class FlowInfoServiceImpl extends ServiceImpl<FlowInfoMapper, FlowInfo> i
 
         flowInfo.setTarget(target.toString());
         flowInfo.updateById();
+
+        geneWord(flowInfo.getId());
     }
 
     @Override
@@ -233,4 +271,51 @@ public class FlowInfoServiceImpl extends ServiceImpl<FlowInfoMapper, FlowInfo> i
     public void execute(Long id) {
 
     }
+
+    /**
+     * 生成word
+     */
+    @SneakyThrows
+    public void geneWord(Long flowId) {
+        FlowDetailDto detail = getDetail(flowId);
+        FlowInfo flowInfo = getById(flowId);
+
+        //文件名称:项目名称-负责人-申请日期-随机四位.docx
+        String createDate = DateUtil.format(flowInfo.getCreateTime(), DatePattern.CHINESE_DATE_PATTERN);
+        String fileName = String.format("%s-%s-%s-%s.docx", detail.getProjectName(), detail.getProjectLeaderName(), createDate,
+                RandomUtil.randomString(RandomUtil.BASE_CHAR_NUMBER_LOWER, 4));
+        log.info("生成word 项目名称:{} 文件名称:{}", detail.getProjectName(), fileName);
+
+        JSONObject dataMap = JSON.parseObject(JSON.toJSONString(detail));
+        wordDataService.fillDocCreator(dataMap);
+
+        String modelName = "geneCustom.ftl";
+
+        try (InputStream inputStream = WordUtil.exportWord(modelName, dataMap);
+             ByteArrayOutputStream out = new ByteArrayOutputStream()) {
+            //转化为docx文件
+            WordprocessingMLPackage pkg = Docx4J.load(inputStream);
+            Docx4J.save(pkg, out);
+
+            //上传至文件服务器
+            byte[] byteArray = out.toByteArray();
+            try (ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArray)) {
+                FileVo fileVo = fileInfoService.uploadFileWithFileName(byteArrayInputStream, fileName);
+
+                HttpServletRequest request = RequestHolder.getRequest();
+                String uri = request.getMethod() + " " + request.getRequestURI();
+
+                new FlowFileVersion()
+                        .setFlowId(flowInfo.getId())
+                        .setFlowStatus(flowInfo.getStatus())
+                        .setDataMap(dataMap.toJSONString())
+                        .setFileMd5(DigestUtil.md5Hex(byteArray))
+                        .setFilename(fileVo.getName())
+                        .setFilepath(fileVo.getUrl())
+                        .setUri(uri)
+                        .setTemplateName(modelName)
+                        .insert();
+            }
+        }
+    }
 }

+ 1 - 1
jfcloud-gene-biz/src/main/java/com/github/jfcloud/gene/form/entity/StrainCustomInfo.java

@@ -34,7 +34,7 @@ public class StrainCustomInfo extends BaseEntity implements Serializable {
      * 目标基因名称(简称)
      */
     @Schema(description = "目标基因名称(简称)")
-    private String geneName;
+    private String targetGeneName;
     /**
      * NCBI Gene ID
      */

+ 91 - 0
jfcloud-gene-biz/src/main/java/com/github/jfcloud/gene/util/WordDataService.java

@@ -0,0 +1,91 @@
+package com.github.jfcloud.gene.util;
+
+import cn.hutool.core.io.IoUtil;
+import cn.hutool.core.util.StrUtil;
+import com.amazonaws.services.s3.model.S3Object;
+import com.github.jfcloud.common.file.core.FileTemplate;
+import com.github.jfcloud.common.util.DateUtil;
+import com.github.jfcloud.common.util.UserUtil;
+import com.github.jfcloud.gene.cache.UserIdNameCache;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+import java.io.InputStream;
+import java.util.Base64;
+import java.util.Date;
+import java.util.Map;
+import java.util.Optional;
+
+@Slf4j
+@RequiredArgsConstructor
+@Service
+public class WordDataService {
+
+    private final UserIdNameCache userIdNameCache;
+    private final FileTemplate fileTemplate;
+
+    /**
+     * 填充文档创建人、创建时间、修改人、修改时间
+     *
+     * @param dataMap
+     * @param createById 文档创建人id
+     * @param createTime 文档创建时间
+     */
+    public void fillDocCreator(Map<String, Object> dataMap) {
+        fillDocCreator(dataMap, UserUtil.getUserId(), new Date());
+    }
+
+    /**
+     * 填充文档创建人、创建时间、修改人、修改时间
+     *
+     * @param dataMap
+     * @param createById 文档创建人id
+     * @param createTime 文档创建时间
+     */
+    public void fillDocCreator(Map<String, Object> dataMap, Long createById, Date createTime) {
+        //文档创建人、创建时间
+        String createBy = UserUtil.getUserId().equals(createById) ?
+                UserUtil.getNickName() :
+                Optional.ofNullable(userIdNameCache.getNicknameByUserId(createById))
+                        .orElse("");
+        dataMap.put("docCreator", createBy);
+        dataMap.put("docCreatedTime", DateUtil.getISO8601Date(createTime));
+        dataMap.put("docLastModifiedBy", UserUtil.getNickName());
+        dataMap.put("docLastModifiedTime", DateUtil.getISO8601Date(new Date()));
+
+        //当前年份、月份、日
+        String[] split = DateUtil.formatDay(new Date()).split("-");
+        dataMap.put("currentYear", split[0]);
+        dataMap.put("currentMonth", split[1]);
+        dataMap.put("currentDay", split[2]);
+    }
+
+    /**
+     * 获取图片base64
+     *
+     * @param fileUrl 图片地址
+     * @return base64字符串
+     */
+    public String getBase64(String fileUrl) {
+        if (StrUtil.isBlank(fileUrl) || !fileUrl.startsWith("/admin/sys-file/")) {
+            return "";
+        }
+
+        //存储桶图片
+        String bucketName = fileUrl.substring(16);
+        bucketName = bucketName.substring(0, bucketName.indexOf("/"));
+        String filename = fileUrl.substring(fileUrl.lastIndexOf("/") + 1);
+
+        try (S3Object s3Object = fileTemplate.getObject(bucketName, filename);
+             InputStream inputStream = s3Object.getObjectContent()) {
+            byte[] bytes = IoUtil.readBytes(inputStream);
+            return Base64.getEncoder().encodeToString(bytes);
+
+        } catch (Exception e) {
+            log.error("图片读取异常: {}", e.getLocalizedMessage());
+            return "";
+        }
+    }
+
+}

+ 89 - 0
jfcloud-gene-biz/src/main/java/com/github/jfcloud/gene/util/WordUtil.java

@@ -0,0 +1,89 @@
+package com.github.jfcloud.gene.util;
+
+import freemarker.template.Configuration;
+import lombok.extern.slf4j.Slf4j;
+import sun.misc.BASE64Encoder;
+
+import java.io.*;
+import java.nio.charset.StandardCharsets;
+import java.util.Map;
+
+@Slf4j
+public class WordUtil {
+
+    /**
+     * @param modelName 模板的名称 比如"basic.ftl"
+     * @param dataMap   传入的数据(key=ftl 中的站位的名称同时 要是String )
+     */
+    public static ByteArrayOutputStream exportWordOut(String modelName, Map<String, Object> dataMap) {
+        if (dataMap != null) {
+            for (Map.Entry<String, Object> entry : dataMap.entrySet()) {
+                if (entry.getValue() == null) {
+                    entry.setValue("");
+                }
+            }
+        }
+
+        // freemaker配置
+        Configuration configuration = new Configuration(Configuration.VERSION_2_3_32);
+        configuration.setDefaultEncoding("utf-8");
+        configuration.setClassForTemplateLoading(WordUtil.class, "/ftlTemplate");
+
+        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+        try (Writer out = new BufferedWriter(new OutputStreamWriter(outputStream, StandardCharsets.UTF_8))){
+            configuration.getTemplate(modelName).process(dataMap, out);
+            return outputStream;
+        } catch (Exception e) {
+            log.error("导出word异常", e);
+        }
+        return null;
+    }
+
+    /**
+     * @param modelName 模板的名称 比如"basic.ftl"
+     * @param dataMap   传入的数据(key=ftl 中的站位的名称同时 要是String )
+     */
+    public static InputStream exportWord(String modelName, Map<String, Object> dataMap) {
+        try (ByteArrayOutputStream outputStream = exportWordOut(modelName, dataMap)){
+            if (outputStream != null) {
+                return new ByteArrayInputStream(outputStream.toByteArray());
+            }
+        } catch (Exception e) {
+            log.error("导出word异常", e);
+        }
+        return null;
+    }
+
+    /**
+     * 图片转换
+     * @param inputStream
+     * @return
+     */
+    public static String getImgFileToBase64(InputStream inputStream) {
+        //将图片文件转化为字节数组字符串,并对其进行Base64编码处理
+        byte[] buffer = null;
+        //读取图片字节数组
+        try {
+            int count = 0;
+            while (count == 0) {
+                count = inputStream.available();
+            }
+            buffer = new byte[count];
+            inputStream.read(buffer);
+        } catch (IOException e) {
+            log.error(e.getMessage(), e);
+        } finally {
+            if (inputStream != null) {
+                try {
+                    // 关闭inputStream流
+                    inputStream.close();
+                } catch (IOException e) {
+                    log.error(e.getMessage(), e);
+                }
+            }
+        }
+        // 对字节数组Base64编码
+        return new BASE64Encoder().encode(buffer);
+    }
+}
+

File diff suppressed because it is too large
+ 8475 - 0
jfcloud-gene-biz/src/main/resources/ftlTemplate/geneCustom.ftl


+ 4 - 4
jfcloud-gene-common/src/main/java/com/github/jfcloud/gene/common/interceptor/interceptor/StuffInterceptor.java

@@ -80,7 +80,7 @@ public class StuffInterceptor implements Interceptor {
                     continue;
                 }
                 if (AnnoEnum.CREATE_BY.getAnnoType().equals(annoType) && Objects.isNull(originalValue) && userId != null) {
-                    field.set(paramObj, userId);
+                    field.set(paramObj, userId.toString());
                     continue;
                 }
                 if (AnnoEnum.CREATE_TIME.getAnnoType().equals(annoType) && Objects.isNull(originalValue)) {
@@ -88,7 +88,7 @@ public class StuffInterceptor implements Interceptor {
                     continue;
                 }
                 if (AnnoEnum.UPDATE_BY.getAnnoType().equals(annoType) && Objects.isNull(originalValue) && userId != null) {
-                    field.set(paramObj, userId);
+                    field.set(paramObj, userId.toString());
                     continue;
                 }
                 if (AnnoEnum.UPDATE_TIME.getAnnoType().equals(annoType) && Objects.isNull(originalValue)) {
@@ -134,7 +134,7 @@ public class StuffInterceptor implements Interceptor {
                     if (autoStuff != null) {
                         String annoType = autoStuff.annoType().getAnnoType();
                         if (AnnoEnum.UPDATE_BY.getAnnoType().equals(annoType)) {
-                            field.set(value, userId);
+                            field.set(value, userId.toString());
                         }
                         if (AnnoEnum.UPDATE_TIME.getAnnoType().equals(annoType)) {
                             field.set(value, new Date());
@@ -153,7 +153,7 @@ public class StuffInterceptor implements Interceptor {
             if (autoStuff != null) {
                 String annoType = autoStuff.annoType().getAnnoType();
                 if (AnnoEnum.UPDATE_BY.getAnnoType().equals(annoType)) {
-                    field.set(paramObj, userId);
+                    field.set(paramObj, userId.toString());
                 }
                 if (AnnoEnum.UPDATE_TIME.getAnnoType().equals(annoType)) {
                     field.set(paramObj, new Date());

Some files were not shown because too many files changed in this diff