From 67bc268ffdc203fd0f3081261c8778bd61a23541 Mon Sep 17 00:00:00 2001 From: liyj <1003249715@qq.com> Date: Sat, 31 Aug 2024 16:03:38 +0800 Subject: [PATCH] 1、新增附件管理模块 --- dyh-service/dyh-sys/src/main/java/cn/huge/module/file/service/FileInfoService.java | 86 +++ dyh-service/dyh-base/src/main/java/cn/huge/module/sys/dto/FileInfoBaseDTO.java | 33 dyh-service/dyh-sys/src/main/java/cn/huge/module/file/controller/wechat/FileInfoWechatController.java | 173 ++++++ dyh-service/dyh-sys/src/main/java/cn/huge/module/file/utils/FtpUtils.java | 256 +++++++++ dyh-service/dyh-sys/pom.xml | 10 dyh-service/dyh-sys/src/main/java/cn/huge/module/file/utils/FileUtils.java | 40 + dyh-service/dyh-sys/src/main/java/cn/huge/module/file/service/FileRelateService.java | 42 + dyh-service/dyh-sys/src/main/java/cn/huge/module/file/utils/FtpMultipartFileWrapper.java | 184 +++++++ dyh-service/dyh-sys/src/main/java/cn/huge/module/file/config/FtpFileConfig.java | 108 ++++ dyh-service/dyh-base/src/main/java/cn/huge/module/sys/constant/FileBaseConsts.java | 44 + dyh-service/dyh-sys/src/main/java/cn/huge/module/file/domain/po/FileInfo.java | 49 + dyh-service/dyh-sys/src/main/resources/config/application.yml | 11 dyh-service/dyh-sys/src/main/java/cn/huge/module/file/controller/web/FileInfoWebController.java | 140 +++++ dyh-service/dyh-sys/src/main/java/cn/huge/module/file/domain/po/FileRelate.java | 2 dyh-service/dyh-sys/src/main/java/cn/huge/module/file/domain/dto/UploaderDTO.java | 37 + dyh-service/dyh-sys/src/main/java/cn/huge/module/client/api/impl/CustClientImpl.java | 188 +++++++ dyh-service/dyh-base/src/main/java/cn/huge/module/sys/constant/FileOwnerTypeBaseEnum.java | 24 dyh-service/dyh-sys/src/main/java/cn/huge/module/client/api/CustClient.java | 74 ++ 18 files changed, 1,474 insertions(+), 27 deletions(-) diff --git a/dyh-service/dyh-base/src/main/java/cn/huge/module/sys/constant/FileBaseConsts.java b/dyh-service/dyh-base/src/main/java/cn/huge/module/sys/constant/FileBaseConsts.java new file mode 100644 index 0000000..948e129 --- /dev/null +++ b/dyh-service/dyh-base/src/main/java/cn/huge/module/sys/constant/FileBaseConsts.java @@ -0,0 +1,44 @@ +package cn.huge.module.sys.constant; + +/** + * @title: 附件相关常量类 + * @description: 附件相关常量类 + * @company: hugeinfo + * @author: liyj + * @time: 2021-11-05 16:51:48 + * @version: 1.0.0 + */ +public class FileBaseConsts { + + /** + * 上传人类型,1:工作人员,2:申请方当事人,3:申请方代理人,4:被申请方当事人,5:被申请方代理人 + */ + public static final int UPLOADER_TYPE_1 = 1; + public static final int UPLOADER_TYPE_2 = 2; + public static final int UPLOADER_TYPE_3 = 3; + public static final int UPLOADER_TYPE_4 = 4; + public static final int UPLOADER_TYPE_5 = 5; + +} +/** + * -------------------_ooOoo_------------------- + * ------------------o8888888o------------------ + * ------------------88" . "88------------------ + * ------------------(| -_- |)------------------ + * ------------------O\ = /O------------------ + * ---------------____/`---'\____--------------- + * -------------.' \\| |// `.------------- + * ------------/ \\||| : |||// \------------ + * -----------/ _||||| -:- |||||- \----------- + * -----------| | \\\ - /// | |----------- + * -----------| \_| ''\---/'' | |----------- + * -----------\ .-\__ `-` ___/-. /----------- + * ---------___`. .' /--.--\ `. . __---------- + * ------."" '< `.___\_<|>_/___.' >'"".------- + * -----| | : `- \`.;`\ _ /`;.`/ - ` : | |----- + * -----\ \ `-. \_ __\ /__ _/ .-` / /----- + * ======`-.____`-.___\_____/___.-`____.-'====== + * -------------------`=---=' + * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + * ---------佛祖保佑---hugeinfo---永无BUG---------- + */ diff --git a/dyh-service/dyh-base/src/main/java/cn/huge/module/sys/constant/FileOwnerTypeBaseEnum.java b/dyh-service/dyh-base/src/main/java/cn/huge/module/sys/constant/FileOwnerTypeBaseEnum.java index 628bdc9..f70e518 100644 --- a/dyh-service/dyh-base/src/main/java/cn/huge/module/sys/constant/FileOwnerTypeBaseEnum.java +++ b/dyh-service/dyh-base/src/main/java/cn/huge/module/sys/constant/FileOwnerTypeBaseEnum.java @@ -228,6 +228,10 @@ case "22_00018-501": return OWNER_CAT_7.getIndex(); + case "22_00018-506": + return OWNER_CAT_7.getIndex(); + case "22_00018-507": + return OWNER_CAT_7.getIndex(); case "22_00018-502": return OWNER_CAT_9.getIndex(); @@ -247,7 +251,7 @@ case "22_00018-604": return OWNER_CAT_8.getIndex(); case "22_00018-605": - return OWNER_CAT_9.getIndex(); + return OWNER_CAT_8.getIndex(); default: return OWNER_CAT_4.getIndex(); @@ -273,6 +277,13 @@ return OWNER_CAT_5; case "22_00014-6": return OWNER_CAT_6; + case "22_00014-7": + return OWNER_CAT_7; + case "22_00014-8": + return OWNER_CAT_8; + case "22_00014-9": + return OWNER_CAT_9; + case "22_00018-101": return OWNER_TYPE_101; case "22_00018-102": @@ -327,6 +338,8 @@ return OWNER_TYPE_305; case "22_00018-306": return OWNER_TYPE_306; + case "22_00018-307": + return OWNER_TYPE_307; case "22_00018-401": return OWNER_TYPE_401; @@ -334,6 +347,8 @@ return OWNER_TYPE_402; case "22_00018-403": return OWNER_TYPE_403; + case "22_00018-405": + return OWNER_TYPE_405; case "22_00018-406": return OWNER_TYPE_406; case "22_00018-407": @@ -345,12 +360,19 @@ case "22_00018-501": return OWNER_TYPE_501; + case "22_00018-506": + return OWNER_TYPE_506; + case "22_00018-507": + return OWNER_TYPE_507; + case "22_00018-502": return OWNER_TYPE_502; case "22_00018-503": return OWNER_TYPE_503; case "22_00018-504": return OWNER_TYPE_504; + case "22_00018-505": + return OWNER_TYPE_505; case "22_00018-601": return OWNER_TYPE_601; diff --git a/dyh-service/dyh-base/src/main/java/cn/huge/module/sys/dto/FileInfoBaseDTO.java b/dyh-service/dyh-base/src/main/java/cn/huge/module/sys/dto/FileInfoBaseDTO.java index f50d37d..262daf2 100644 --- a/dyh-service/dyh-base/src/main/java/cn/huge/module/sys/dto/FileInfoBaseDTO.java +++ b/dyh-service/dyh-base/src/main/java/cn/huge/module/sys/dto/FileInfoBaseDTO.java @@ -1,5 +1,6 @@ package cn.huge.module.sys.dto; +import com.baomidou.mybatisplus.annotation.TableField; import lombok.Data; import java.util.Date; @@ -41,18 +42,18 @@ private String suffix; /** - * 附件分类,音频|视频|图片等 - */ + * 附件分类,音频|视频|图片等 + */ private String cat; /** - * 附件大小 - */ + * 附件大小 + */ private Double size; /** - * 单位 - */ + * 单位 + */ private String unit; /** @@ -91,9 +92,14 @@ private String zipUrl; /** - * 文件上传时间 + * 删除状态,0:已删除,1:未删除 */ - private Date createTime; + private Integer deleteStatus; + + /** + * 顾客编号 + */ + private String custId; /** * 状态时间 @@ -101,9 +107,9 @@ private Date updateTime; /** - * 顾客编号 - */ - private String custId; + * 创建时间 + */ + private Date createTime; /** * 所属业务编号 @@ -141,6 +147,11 @@ private String uploaderName; /** + * 上传人类型,1:工作人员,2:申请方当事人,3:申请方代理人,4:被申请方当事人,5:被申请方代理人 + */ + private Integer uploaderType; + + /** * 前端固定参数,值为:done */ private String status; diff --git a/dyh-service/dyh-sys/pom.xml b/dyh-service/dyh-sys/pom.xml index e3ca2fa..124dc92 100644 --- a/dyh-service/dyh-sys/pom.xml +++ b/dyh-service/dyh-sys/pom.xml @@ -18,7 +18,7 @@ </parent> <properties> - + <commons-net.version>3.1</commons-net.version> </properties> <dependencies> @@ -59,6 +59,14 @@ <scope>test</scope> </dependency> <!-- junit end --> + + <!-- net --> + <dependency> + <groupId>commons-net</groupId> + <artifactId>commons-net</artifactId> + <version>${commons-net.version}</version> + </dependency> + <!-- net end --> </dependencies> <build> diff --git a/dyh-service/dyh-sys/src/main/java/cn/huge/module/client/api/CustClient.java b/dyh-service/dyh-sys/src/main/java/cn/huge/module/client/api/CustClient.java new file mode 100644 index 0000000..4bc8525 --- /dev/null +++ b/dyh-service/dyh-sys/src/main/java/cn/huge/module/client/api/CustClient.java @@ -0,0 +1,74 @@ +package cn.huge.module.client.api; + +import cn.huge.base.common.bo.ReturnBO; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestParam; + +/** + * @title: 客户用户中心微服务调用接口 + * @description: 客户用户中心微服务调用接口 + * @company: hugeinfo + * @author: liyj + * @time: 2021-11-05 16:51:48 + * @version: 1.0.0 + */ +@FeignClient(name = "dyh-cust") +public interface CustClient { + + /** + * 内部用户-获取登录用户 + * @url {ctx}/api/v1/ctUser/clientGetUser?userId= + * @param userId 登录用户编号 + * @return ReturnBO + */ + @GetMapping("/api/v1/ctUser/clientGetUser") + ReturnBO clientGetUser(@RequestParam("userId") String userId); + + /** + * 内部用户-获取登录用户 + * @url {ctx}/api/v1/ctUser/clientGetUserAll?userId= + * @param userId 登录用户编号 + * @return + */ + @GetMapping("/api/v1/ctUser/clientGetUserAll") + ReturnBO clientGetUserAll(@RequestParam("userId") String userId); + + /** + * 当事人-获取登录用户 + * @url {ctx}/api/v1/paUser/clientGetUserAll?userId= + * @param userId 登录用户编号 + * @return ReturnBO + */ + @GetMapping("/api/v1/paUser/clientGetUserAll") + ReturnBO paclientGetUser(@RequestParam("userId") String userId); + + /** + * 根据组织和角色查询 + * @url {ctx}/api/v1/ctUser/listUserByUnitRole + * @return unitId 组织编号 + * @return roleCode 角色代码 + * @return ReturnBO + */ + @GetMapping("/api/v1/ctUser/listUserByUnitRole") + ReturnBO listUserByUnitRole(@RequestParam(value = "unitId") String unitId, @RequestParam(value = "roleCode") String roleCode); + + /** + * 根据部门和角色查询 + * @url {ctx}/api/v1/ctUser/listUserByDeptRole + * @return deptId 部门编号 + * @return roleCode 角色代码 + * @return ReturnBO + */ + @GetMapping("/api/v1/ctUser/listUserByDeptRole") + ReturnBO listUserByDeptRole(@RequestParam(value = "deptId") String deptId, @RequestParam(value = "roleCode") String roleCode); + + /** + * 查询客户下的法院 + * @url {ctx}/api/v1/ctUnit/listCourt1 + * @param userId 用户编号 + * @return ReturnBO + */ + @GetMapping("/api/v1/ctUnit/listCourt1") + ReturnBO listCourt1(@RequestParam(value = "userId") String userId); +} diff --git a/dyh-service/dyh-sys/src/main/java/cn/huge/module/client/api/impl/CustClientImpl.java b/dyh-service/dyh-sys/src/main/java/cn/huge/module/client/api/impl/CustClientImpl.java new file mode 100644 index 0000000..cf056ca --- /dev/null +++ b/dyh-service/dyh-sys/src/main/java/cn/huge/module/client/api/impl/CustClientImpl.java @@ -0,0 +1,188 @@ +package cn.huge.module.client.api.impl; + +import cn.huge.base.common.bo.ReturnBO; +import cn.huge.base.common.constant.ReturnConsts; +import cn.huge.base.common.dto.SelectTermDTO; +import cn.huge.base.common.exception.ClientException; +import cn.huge.base.common.exception.ServiceException; +import cn.huge.module.client.api.CustClient; +import cn.huge.module.cust.dto.CtUserDTO; +import cn.huge.module.cust.dto.PaUserDTO; +import com.alibaba.fastjson.JSON; +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.springframework.web.bind.annotation.RequestParam; + +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; + +/** + * @title: 客户用户中心微服务调用接口实现 + * @description: 客户用户中心微服务调用接口实现 + * @company: hugeinfo + * @author: liyj + * @time: 2021-11-05 16:51:48 + * @version: 1.0.0 + */ +@Slf4j +@Component +public class CustClientImpl { + + private CustClient custClient; + + @Autowired + public CustClientImpl(CustClient custClient) { + this.custClient = custClient; + } + + /** + * ObjectMapper工具类 + */ + private ObjectMapper objectMapper = new ObjectMapper(); + + /** + * 内部用户-获取登录用户 + * @param userId 用户编号 + * @return CtUserDTO + */ + public CtUserDTO clientGetUser(String userId){ + try{ + ReturnBO returnBo = custClient.clientGetUser(userId); + if (ReturnConsts.OK == returnBo.getCode()){ + CtUserDTO loginUser = objectMapper.convertValue(returnBo.getData(), CtUserDTO.class); + return loginUser; + }else{ + log.error("Client外服务接口[CustClientImpl.clientGetUser]请求异常:" + returnBo.getMsg(), returnBo.getMsg()); + throw new ClientException("CustClientImpl.clientGetUser", returnBo.getMsg()); + } + }catch (Exception e){ + log.error("service方法[CustClientImpl.clientGetUser]调用异常:"+e, e); + throw new ServiceException("CustClientImpl.clientGetUser", e); + } + } + + /** + * 内部用户-获取登录用户 + * @param userId + * @return + */ + public CtUserDTO clientGetUserAll(String userId){ + try{ + ReturnBO returnBo = custClient.clientGetUserAll(userId); + if (ReturnConsts.OK == returnBo.getCode()){ + CtUserDTO loginUser = objectMapper.convertValue(returnBo.getData(), CtUserDTO.class); + return loginUser; + }else{ + log.error("Client外服务接口[CustClientImpl.clientGetUserAll]请求异常:" + returnBo.getMsg(), returnBo.getMsg()); + throw new ClientException("CustClientImpl.clientGetUserAll", returnBo.getMsg()); + } + }catch (Exception e){ + log.error("service方法[CustClientImpl.clientGetUserAll]调用异常:"+e, e); + throw new ServiceException("CustClientImpl.clientGetUserAll", e); + } + } + + /** + * 当事人-获取登录用户 + * @param userId 用户编号 + * @return + */ + public PaUserDTO paclientGetUser(String userId){ + try{ + ReturnBO returnBo = custClient.paclientGetUser(userId); + if (ReturnConsts.OK == returnBo.getCode()){ + PaUserDTO loginUser = objectMapper.convertValue(returnBo.getData(), PaUserDTO.class); + return loginUser; + }else{ + log.error("Client外服务接口[CustClientImpl.paclientGetUser]请求异常:" + returnBo.getMsg(), returnBo.getMsg()); + throw new ClientException("CustClientImpl.paclientGetUser", returnBo.getMsg()); + } + }catch (Exception e){ + log.error("service方法[CustClientImpl.paclientGetUser]调用异常:"+e, e); + throw new ServiceException("CustClientImpl.paclientGetUser", e); + } + } + + /** + * 根据组织和角色查询 + * @return unitId 组织编号 + * @return roleCode 角色代码 + * @return Object + */ + public List<CtUserDTO> listUserByUnitRole(@RequestParam(value = "unitId") String unitId, @RequestParam(value = "roleCode") String roleCode) { + List<CtUserDTO> ctUserDTOList = new ArrayList<>(); + try{ + ReturnBO returnBo = custClient.listUserByUnitRole(unitId, roleCode); + if (ReturnConsts.OK == returnBo.getCode()){ + List<LinkedHashMap> list = (List<LinkedHashMap>) returnBo.getData(); + for (LinkedHashMap map : list) { + CtUserDTO ctUserDTO = JSON.parseObject(JSON.toJSONString(map), CtUserDTO.class); + ctUserDTOList.add(ctUserDTO); + } + return ctUserDTOList; + }else{ + log.error("Client外服务接口[CustClientImpl.listUserByUnitRole]请求异常:" + returnBo.getMsg(), returnBo.getMsg()); + throw new ClientException("CustClientImpl.listUserByUnitRole", returnBo.getMsg()); + } + }catch (Exception e){ + log.error("service方法[CustClientImpl.listUserByUnitRole]调用异常:"+e, e); + throw new ServiceException("CustClientImpl.listUserByUnitRole", e); + } + } + + /** + * 根据部门和角色查询 + * @return deptId 部门编号 + * @return roleCode 角色代码 + * @return Object + */ + public List<CtUserDTO> listUserByDeptRole(@RequestParam(value = "deptId") String deptId, @RequestParam(value = "roleCode") String roleCode) { + List<CtUserDTO> ctUserDTOList = new ArrayList<>(); + try{ + ReturnBO returnBo = custClient.listUserByDeptRole(deptId, roleCode); + if (ReturnConsts.OK == returnBo.getCode()){ + List<LinkedHashMap> list = (List<LinkedHashMap>) returnBo.getData(); + for (LinkedHashMap map : list) { + CtUserDTO ctUserDTO = JSON.parseObject(JSON.toJSONString(map), CtUserDTO.class); + ctUserDTOList.add(ctUserDTO); + } + return ctUserDTOList; + }else{ + log.error("Client外服务接口[CustClientImpl.listUserByDeptRole]请求异常:" + returnBo.getMsg(), returnBo.getMsg()); + throw new ClientException("CustClientImpl.listUserByDeptRole", returnBo.getMsg()); + } + }catch (Exception e){ + log.error("service方法[CustClientImpl.listUserByDeptRole]调用异常:"+e, e); + throw new ServiceException("CustClientImpl.listUserByDeptRole", e); + } + } + + /** + * 查询客户下的法院 + * @param userId + * @return + */ + public List<SelectTermDTO> listCourt1(String userId){ + List<SelectTermDTO> selectTermDTOList = new ArrayList<>(); + try{ + ReturnBO returnBo = custClient.listCourt1(userId); + if (ReturnConsts.OK == returnBo.getCode()){ + List<LinkedHashMap> list = (List<LinkedHashMap>) returnBo.getData(); + for (LinkedHashMap map : list) { + SelectTermDTO selectTermDTO = JSON.parseObject(JSON.toJSONString(map), SelectTermDTO.class); + selectTermDTOList.add(selectTermDTO); + } + return selectTermDTOList; + }else{ + log.error("Client外服务接口[CustClientImpl.listCourt1]请求异常:" + returnBo.getMsg(), returnBo.getMsg()); + throw new ClientException("CustClientImpl.listCourt1", returnBo.getMsg()); + } + }catch (Exception e){ + log.error("service方法[CustClientImpl.listCourt1]调用异常:"+e, e); + throw new ServiceException("CustClientImpl.listCourt1", e); + } + } +} diff --git a/dyh-service/dyh-sys/src/main/java/cn/huge/module/file/config/FtpFileConfig.java b/dyh-service/dyh-sys/src/main/java/cn/huge/module/file/config/FtpFileConfig.java new file mode 100644 index 0000000..1dd048e --- /dev/null +++ b/dyh-service/dyh-sys/src/main/java/cn/huge/module/file/config/FtpFileConfig.java @@ -0,0 +1,108 @@ +package cn.huge.module.file.config; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +/** + * @title: JSON工具类 + * @description: JSON工具类 + * @company: hugeinfo + * @author: liyj + * @time: 2021-11-05 16:51:48 + * @version: 1.0.0 + */ +@Component +public class FtpFileConfig { + + /** + * 服务器ip地址 + */ + public static String hostname; + + /** + * 端口 + */ + public static int port; + + /** + * 用户名 + */ + public static String username; + + /** + * 密码 + */ + public static String password; + + /** + * 附件存储根目录 + */ + public static String rootdir; + + @Value("${ftp.hostname}") + public void setHostname(String hostname) { + this.hostname = hostname; + } + + @Value("${ftp.port}") + public void setPort(int port) { + this.port = port; + } + + @Value("${ftp.username}") + public void setUsername(String username) { + this.username = username; + } + + @Value("${ftp.password}") + public void setPassword(String password) { + this.password = password; + } + + @Value("${ftp.rootdir}") + public void setRootdir(String rootdir) { + this.rootdir = rootdir; + } + + public static String getHostname() { + return hostname; + } + + public static int getPort() { + return port; + } + + public static String getUsername() { + return username; + } + + public static String getPassword() { + return password; + } + + public static String getRootdir() { + return rootdir; + } +} +/** + * -------------------_ooOoo_------------------- + * ------------------o8888888o------------------ + * ------------------88" . "88------------------ + * ------------------(| -_- |)------------------ + * ------------------O\ = /O------------------ + * ---------------____/`---'\____--------------- + * -------------.' \\| |// `.------------- + * ------------/ \\||| : |||// \------------ + * -----------/ _||||| -:- |||||- \----------- + * -----------| | \\\ - /// | |----------- + * -----------| \_| ''\---/'' | |----------- + * -----------\ .-\__ `-` ___/-. /----------- + * ---------___`. .' /--.--\ `. . __---------- + * ------."" '< `.___\_<|>_/___.' >'"".------- + * -----| | : `- \`.;`\ _ /`;.`/ - ` : | |----- + * -----\ \ `-. \_ __\ /__ _/ .-` / /----- + * ======`-.____`-.___\_____/___.-`____.-'====== + * -------------------`=---=' + * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + * ---------佛祖保佑---hugeinfo---永无BUG---------- + */ \ No newline at end of file diff --git a/dyh-service/dyh-sys/src/main/java/cn/huge/module/file/controller/web/FileInfoWebController.java b/dyh-service/dyh-sys/src/main/java/cn/huge/module/file/controller/web/FileInfoWebController.java index 088af92..340bf13 100644 --- a/dyh-service/dyh-sys/src/main/java/cn/huge/module/file/controller/web/FileInfoWebController.java +++ b/dyh-service/dyh-sys/src/main/java/cn/huge/module/file/controller/web/FileInfoWebController.java @@ -1,19 +1,42 @@ package cn.huge.module.file.controller.web; +import cn.huge.base.common.exception.ClientException; +import cn.huge.base.common.utils.ContentTypeUtils; import cn.huge.base.common.utils.ReturnFailUtils; import cn.huge.base.common.utils.ReturnSucUtils; +import cn.huge.base.config.CurrentUser; +import cn.huge.module.client.api.impl.CustClientImpl; +import cn.huge.module.constant.BaseConsts; +import cn.huge.module.cust.dto.CtUserDTO; +import cn.huge.module.file.domain.dto.UploaderDTO; import cn.huge.module.file.domain.po.FileInfo; import cn.huge.module.file.service.FileInfoService; +import cn.huge.module.file.service.FileRelateService; +import cn.huge.module.file.utils.FileUtils; +import cn.huge.module.file.utils.FtpUtils; +import cn.huge.module.sys.constant.FileOwnerTypeBaseEnum; +import cn.huge.module.sys.dto.FileInfoBaseDTO; import com.google.common.collect.Maps; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Sort; import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; +import org.springframework.web.multipart.MultipartHttpServletRequest; import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.URLEncoder; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; import java.util.Map; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -36,5 +59,122 @@ @Autowired private FileInfoService service; + @Autowired + private FileRelateService fileRelateService; + @Autowired + private CustClientImpl custClient; + + /** + * 页面附件上传-文件流方式 + * @url {ctx}/api/web/fileInfo/upload/{ownerId}/{ownerType} + * @param ownerId 所属业务编号 + * @param ownerType 所属业务类型 + * @param request 请求头 + * @return Object + */ + @PostMapping("/upload/{ownerId}/{ownerType}") + public Object upload(@PathVariable(value = "ownerId") String ownerId, @PathVariable(value = "ownerType") String ownerType, + @CurrentUser String userId, MultipartHttpServletRequest request) { + try{ + CtUserDTO loginUser = custClient.clientGetUser(userId); + UploaderDTO uploaderDTO = new UploaderDTO(); + BeanUtils.copyProperties(loginUser, uploaderDTO); + List<FileInfoBaseDTO> files = new ArrayList<>(); + Iterator<String> itr = request.getFileNames(); + int fileCount = fileRelateService.countByOwnerIdAndType(ownerId, ownerType)+1; + while (itr.hasNext()) { + MultipartFile file = request.getFile(itr.next()); + if(file.getSize() > 30000000){ + return ReturnFailUtils.getRepInfo("您上传的文件已超过30M大小限制!"); + }else { + String fileSuffix = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".")); + if (FileUtils.checkFileSuffix(fileSuffix)) { + if (StringUtils.isEmpty(ownerType)) { + ownerType = FileOwnerTypeBaseEnum.OWNER_TYPE_000.getIndex(); + } + FileInfo fileInfo = service.webPploadFile(file, ownerId, ownerType, fileCount, uploaderDTO); + FileInfoBaseDTO fileInfoBaseDTO = new FileInfoBaseDTO(); + BeanUtils.copyProperties(fileInfo, fileInfoBaseDTO); + files.add(fileInfoBaseDTO); + fileCount++; + } else { + return ReturnFailUtils.getRepInfo("您上传的文件格式不正确!"); + } + } + } + return ReturnSucUtils.getRepInfo( "上传成功!", files); + } catch (Exception e) { + return ReturnFailUtils.getRepInfo(); + } + } + + /** + * 在线查附件 + * @url {ctx}/api/web/fileInfo/show/{id} + * @param id 附件编号 + * @param response 响应头 + * @throws Exception + */ + @GetMapping("/show/{id}") + public void show(@PathVariable(value = "id") String id, HttpServletResponse response){ + try { + FileInfo fileInfo = service.getById(id); + response.reset(); + String contentType = ContentTypeUtils.getContentType(fileInfo.getSuffix()); + response.setContentType(contentType); + OutputStream outputStream = response.getOutputStream(); + FtpUtils ftpUtil = new FtpUtils(); + InputStream inputStream = ftpUtil.retrieveFileStream(fileInfo.getFullPath()); + +// double fileSize = fileInfo.getSize(); // 文件大小 + int chunkSize = 512 * 1024; // 分块大小( KB) + byte[] buffer = new byte[chunkSize]; + int bytesRead; + + // 循环读取和发送文件的各个部分 + while ((bytesRead = inputStream.read(buffer)) != -1) { + outputStream.write(buffer, 0, bytesRead); + outputStream.flush(); + } + +// IOUtils.copy(inputStream, outputStream, chunkSize); + //关闭流 + IOUtils.closeQuietly(inputStream); + IOUtils.closeQuietly(outputStream); + } catch (Exception e) { + log.error("controller接口[FileInfoWebController.show]请求异常:"+e, e); + throw new ClientException("FileInfoWebController.show", e); + } + } + + /** + * 在线下载附件-文件流方式 + * @url {ctx}/api/web/fileInfo/down/{id} + * @param id 附件编号 + * @param response 响应头 + */ + @GetMapping("/down/{id}") + public void down(@PathVariable(value = "id") String id, HttpServletResponse response){ + try { + FileInfo fileInfo = service.getById(id); + String contentType = ContentTypeUtils.getContentType(fileInfo.getSuffix()); + response.setContentType(contentType); + String fileName = URLEncoder.encode(fileInfo.getName() + BaseConsts.DOT + fileInfo.getSuffix(), "UTF-8"); + response.addHeader("Content-Disposition", "attachment;filename=" + fileName); + OutputStream outputStream = response.getOutputStream(); + FtpUtils ftpUtil = new FtpUtils(); + InputStream inputStream = ftpUtil.retrieveFileStream(fileInfo.getFullPath()); + IOUtils.copy(inputStream, outputStream); + //关闭流 + IOUtils.closeQuietly(inputStream); + IOUtils.closeQuietly(outputStream); + } catch (Exception e) { + log.error("controller接口[FileInfoWebController.down]请求异常:"+e, e); + throw new ClientException("FileInfoWebController.down", e); + } + } + + + } diff --git a/dyh-service/dyh-sys/src/main/java/cn/huge/module/file/controller/wechat/FileInfoWechatController.java b/dyh-service/dyh-sys/src/main/java/cn/huge/module/file/controller/wechat/FileInfoWechatController.java new file mode 100644 index 0000000..09a62b1 --- /dev/null +++ b/dyh-service/dyh-sys/src/main/java/cn/huge/module/file/controller/wechat/FileInfoWechatController.java @@ -0,0 +1,173 @@ +package cn.huge.module.file.controller.wechat; + +import cn.huge.base.common.exception.ClientException; +import cn.huge.base.common.utils.ContentTypeUtils; +import cn.huge.base.common.utils.ReturnFailUtils; +import cn.huge.base.common.utils.ReturnSucUtils; +import cn.huge.base.config.CurrentUser; +import cn.huge.module.client.api.impl.CustClientImpl; +import cn.huge.module.constant.BaseConsts; +import cn.huge.module.cust.dto.CtUserDTO; +import cn.huge.module.file.domain.dto.UploaderDTO; +import cn.huge.module.file.domain.po.FileInfo; +import cn.huge.module.file.service.FileInfoService; +import cn.huge.module.file.service.FileRelateService; +import cn.huge.module.file.utils.FileUtils; +import cn.huge.module.file.utils.FtpUtils; +import cn.huge.module.sys.constant.FileOwnerTypeBaseEnum; +import cn.huge.module.sys.dto.FileInfoBaseDTO; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; +import org.springframework.web.multipart.MultipartHttpServletRequest; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.URLEncoder; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +/** + * @title: 附件信息表接口api-wechat端 + * @description: 附件信息表接口api-wechat端 + * @company: hugeinfo + * @author: liyj + * @time: 2024-08-28 20:06:18 + * @version: 1.0.0 + */ +@Slf4j +@RestController +@RequestMapping("/api/wechat/fileInfo") +public class FileInfoWechatController { + + @Autowired(required = false) + private HttpServletRequest request; + + @Autowired + private FileInfoService service; + @Autowired + private FileRelateService fileRelateService; + @Autowired + private CustClientImpl custClient; + + /** + * 页面附件上传-文件流方式 + * @url {ctx}/api/wechat/fileInfo/upload/{ownerId}/{ownerType} + * @param ownerId 所属业务编号 + * @param ownerType 所属业务类型 + * @param request 请求头 + * @return Object + */ + @PostMapping("/upload/{ownerId}/{ownerType}") + public Object upload(@PathVariable(value = "ownerId") String ownerId, @PathVariable(value = "ownerType") String ownerType, + @CurrentUser String userId, MultipartHttpServletRequest request) { + try{ + CtUserDTO loginUser = custClient.clientGetUser(userId); + UploaderDTO uploaderDTO = new UploaderDTO(); + BeanUtils.copyProperties(loginUser, uploaderDTO); + List<FileInfoBaseDTO> files = new ArrayList<>(); + Iterator<String> itr = request.getFileNames(); + int fileCount = fileRelateService.countByOwnerIdAndType(ownerId, ownerType)+1; + while (itr.hasNext()) { + MultipartFile file = request.getFile(itr.next()); + if(file.getSize() > 30000000){ + return ReturnFailUtils.getRepInfo("您上传的文件已超过30M大小限制!"); + }else { + String fileSuffix = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".")); + if (FileUtils.checkFileSuffix(fileSuffix)) { + if (StringUtils.isEmpty(ownerType)) { + ownerType = FileOwnerTypeBaseEnum.OWNER_TYPE_000.getIndex(); + } + FileInfo fileInfo = service.webPploadFile(file, ownerId, ownerType, fileCount, uploaderDTO); + FileInfoBaseDTO fileInfoBaseDTO = new FileInfoBaseDTO(); + BeanUtils.copyProperties(fileInfo, fileInfoBaseDTO); + files.add(fileInfoBaseDTO); + fileCount++; + } else { + return ReturnFailUtils.getRepInfo("您上传的文件格式不正确!"); + } + } + } + return ReturnSucUtils.getRepInfo( "上传成功!", files); + } catch (Exception e) { + return ReturnFailUtils.getRepInfo(); + } + } + + /** + * 在线查附件 + * @url {ctx}/api/wechat/fileInfo/show/{id} + * @param id 附件编号 + * @param response 响应头 + * @throws Exception + */ + @GetMapping("/show/{id}") + public void show(@PathVariable(value = "id") String id, HttpServletResponse response){ + try { + FileInfo fileInfo = service.getById(id); + response.reset(); + String contentType = ContentTypeUtils.getContentType(fileInfo.getSuffix()); + response.setContentType(contentType); + OutputStream outputStream = response.getOutputStream(); + FtpUtils ftpUtil = new FtpUtils(); + InputStream inputStream = ftpUtil.retrieveFileStream(fileInfo.getFullPath()); + +// double fileSize = fileInfo.getSize(); // 文件大小 + int chunkSize = 512 * 1024; // 分块大小( KB) + byte[] buffer = new byte[chunkSize]; + int bytesRead; + + // 循环读取和发送文件的各个部分 + while ((bytesRead = inputStream.read(buffer)) != -1) { + outputStream.write(buffer, 0, bytesRead); + outputStream.flush(); + } + +// IOUtils.copy(inputStream, outputStream, chunkSize); + //关闭流 + IOUtils.closeQuietly(inputStream); + IOUtils.closeQuietly(outputStream); + } catch (Exception e) { + log.error("controller接口[FileInfoWechatController.show]请求异常:"+e, e); + throw new ClientException("FileInfoWechatController.show", e); + } + } + + /** + * 在线下载附件-文件流方式 + * @url {ctx}/api/wechat/fileInfo/down/{id} + * @param id 附件编号 + * @param response 响应头 + */ + @GetMapping("/down/{id}") + public void down(@PathVariable(value = "id") String id, HttpServletResponse response){ + try { + FileInfo fileInfo = service.getById(id); + String contentType = ContentTypeUtils.getContentType(fileInfo.getSuffix()); + response.setContentType(contentType); + String fileName = URLEncoder.encode(fileInfo.getName() + BaseConsts.DOT + fileInfo.getSuffix(), "UTF-8"); + response.addHeader("Content-Disposition", "attachment;filename=" + fileName); + OutputStream outputStream = response.getOutputStream(); + FtpUtils ftpUtil = new FtpUtils(); + InputStream inputStream = ftpUtil.retrieveFileStream(fileInfo.getFullPath()); + IOUtils.copy(inputStream, outputStream); + //关闭流 + IOUtils.closeQuietly(inputStream); + IOUtils.closeQuietly(outputStream); + } catch (Exception e) { + log.error("controller接口[FileInfoWechatController.down]请求异常:"+e, e); + throw new ClientException("FileInfoWechatController.down", e); + } + } + + + + +} diff --git a/dyh-service/dyh-sys/src/main/java/cn/huge/module/file/domain/dto/UploaderDTO.java b/dyh-service/dyh-sys/src/main/java/cn/huge/module/file/domain/dto/UploaderDTO.java new file mode 100644 index 0000000..8be3d8e --- /dev/null +++ b/dyh-service/dyh-sys/src/main/java/cn/huge/module/file/domain/dto/UploaderDTO.java @@ -0,0 +1,37 @@ +package cn.huge.module.file.domain.dto; + +import com.baomidou.mybatisplus.annotation.TableField; +import lombok.Data; + +/** + * @title: 附件上传人信息 + * @description: DTO数据传输对象。 + * @company:hugeinfo + * @author: chenx + * @time: 2022-02-22 14:19:43 + * @version 1.0.0 + */ +@Data +public class UploaderDTO { + + /** + * 上传人编号 + */ + private String uploaderId; + + /** + * 上传人姓名 + */ + private String uploaderName; + + /** + * 上传人类型,1:工作人员,2:申请方当事人,3:申请方代理人,4:被申请方当事人,5:被申请方代理人 + */ + private Integer uploaderType; + + /** + * 顾客编号 + */ + private String custId; + +} diff --git a/dyh-service/dyh-sys/src/main/java/cn/huge/module/file/domain/po/FileInfo.java b/dyh-service/dyh-sys/src/main/java/cn/huge/module/file/domain/po/FileInfo.java index 65f464c..49f1040 100644 --- a/dyh-service/dyh-sys/src/main/java/cn/huge/module/file/domain/po/FileInfo.java +++ b/dyh-service/dyh-sys/src/main/java/cn/huge/module/file/domain/po/FileInfo.java @@ -33,7 +33,7 @@ private String name; /** - * 附件原本名称(不带后缀) + * 附件原本名称(带后缀) */ @TableField(value = "true_name") private String trueName; @@ -134,5 +134,52 @@ */ @TableField(value = "create_time") private Date createTime; + /** + * 所属业务编号 + */ + @TableField(exist = false) + private String ownerId; + + /** + * 所属业务大类 + */ + @TableField(exist = false) + private String ownerCat; + + /** + * 所属业务大类名称 + */ + @TableField(exist = false) + private String ownerCatName; + + /** + * 所属业务类型W + */ + @TableField(exist = false) + private String ownerType; + + /** + * 所属业务类型名称 + */ + @TableField(exist = false) + private String ownerTypeName; + + /** + * 上传人编号 + */ + @TableField(exist = false) + private String uploaderId; + + /** + * 上传人姓名 + */ + @TableField(exist = false) + private String uploaderName; + + /** + * 上传人类型,1:工作人员,2:申请方当事人,3:申请方代理人,4:被申请方当事人,5:被申请方代理人 + */ + @TableField(exist = false) + private Integer uploaderType; } diff --git a/dyh-service/dyh-sys/src/main/java/cn/huge/module/file/domain/po/FileRelate.java b/dyh-service/dyh-sys/src/main/java/cn/huge/module/file/domain/po/FileRelate.java index e6eb19f..3fb96cd 100644 --- a/dyh-service/dyh-sys/src/main/java/cn/huge/module/file/domain/po/FileRelate.java +++ b/dyh-service/dyh-sys/src/main/java/cn/huge/module/file/domain/po/FileRelate.java @@ -63,7 +63,7 @@ private String uploaderName; /** - * 上传人类型,1:工作人员,2:申请方,3:被申请方 + * 上传人类型,1:工作人员,2:申请方当事人,3:申请方代理人,4:被申请方当事人,5:被申请方代理人 */ @TableField(value = "uploader_type") private Integer uploaderType; diff --git a/dyh-service/dyh-sys/src/main/java/cn/huge/module/file/service/FileInfoService.java b/dyh-service/dyh-sys/src/main/java/cn/huge/module/file/service/FileInfoService.java index a8018fd..0271ecd 100644 --- a/dyh-service/dyh-sys/src/main/java/cn/huge/module/file/service/FileInfoService.java +++ b/dyh-service/dyh-sys/src/main/java/cn/huge/module/file/service/FileInfoService.java @@ -4,19 +4,23 @@ import cn.huge.base.common.utils.DateUtils; import cn.huge.base.common.utils.IdUtils; import cn.huge.module.client.api.impl.UtilsClientImpl; +import cn.huge.module.constant.BaseConsts; import cn.huge.module.file.dao.mapper.FileInfoMapper; +import cn.huge.module.file.domain.dto.UploaderDTO; import cn.huge.module.file.domain.po.FileInfo; +import cn.huge.module.file.utils.FtpUtils; +import cn.huge.module.file.utils.FtpMultipartFileWrapper; +import cn.huge.module.sys.constant.FileOwnerTypeBaseEnum; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.PageRequest; import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.multipart.MultipartFile; -import javax.annotation.PostConstruct; import java.util.Date; import java.util.List; import java.util.Map; @@ -36,6 +40,8 @@ @Autowired private FileInfoMapper mapper; + @Autowired + private FileRelateService fileRelateService; @Autowired private UtilsClientImpl utilsClient; @@ -130,4 +136,80 @@ } } + /** + * web端上传附件,保存附件信息和业务关系 + * @param file 附件 + * @param ownerId 所属业务编号 + * @param ownerType 所属业务名称 + * @param fileCount 第几份附件 + * @param uploaderDTO 上传人信息 + * @return + */ + public FileInfo webPploadFile(MultipartFile file, String ownerId, String ownerType, int fileCount, UploaderDTO uploaderDTO) { + try { + String fileId = utilsClient.getNewTimeId(); + // 创建附件信息 + FileInfo fileInfo = new FtpMultipartFileWrapper(file).toWebFileInfo(fileId); + // 上传到ftp服务器 + FtpUtils ftpUtils = new FtpUtils(); + ftpUtils.upload(fileInfo.getPath(), fileInfo.getFileName(), file.getInputStream()); + // 保存附件信息 + fileInfo.setName(FileOwnerTypeBaseEnum.getDes(ownerType) + BaseConsts.UNDER + fileCount); + fileInfo.setOwnerId(ownerId); + fileInfo.setOwnerCat(FileOwnerTypeBaseEnum.getCat(ownerType)); + fileInfo.setOwnerCatName(FileOwnerTypeBaseEnum.getDes(fileInfo.getOwnerCat())); + fileInfo.setOwnerType(ownerType); + fileInfo.setOwnerTypeName(FileOwnerTypeBaseEnum.getDes(ownerType)); + fileInfo.setUploaderId(uploaderDTO.getUploaderId()); + fileInfo.setUploaderName(uploaderDTO.getUploaderName()); + fileInfo.setUploaderType(uploaderDTO.getUploaderType()); + fileInfo.setCustId(uploaderDTO.getCustId()); + mapper.insert(fileInfo); + // 保存业务关系 + fileRelateService.saveByFileInfo(fileInfo); + return fileInfo; + } catch (Exception e) { + log.error("service方法[FileInfoService.uploadFile]调用失败,异常信息:"+e, e); + throw new ServiceException("FileInfoService.uploadFile", e); + } + } + + /** + * wechat端上传附件,保存附件信息和业务关系 + * @param file 附件 + * @param ownerId 所属业务编号 + * @param ownerType 所属业务名称 + * @param fileCount 第几份附件 + * @param uploaderDTO 上传人信息 + * @return + */ + public FileInfo wechatPploadFile(MultipartFile file, String ownerId, String ownerType, int fileCount, UploaderDTO uploaderDTO) { + try { + String fileId = utilsClient.getNewTimeId(); + // 创建附件信息 + FileInfo fileInfo = new FtpMultipartFileWrapper(file).toWechatFileInfo(fileId); + // 上传到ftp服务器 + FtpUtils ftpUtils = new FtpUtils(); + ftpUtils.upload(fileInfo.getPath(), fileInfo.getFileName(), file.getInputStream()); + // 保存附件信息 + fileInfo.setName(FileOwnerTypeBaseEnum.getDes(ownerType) + BaseConsts.UNDER + fileCount); + fileInfo.setOwnerId(ownerId); + fileInfo.setOwnerCat(FileOwnerTypeBaseEnum.getCat(ownerType)); + fileInfo.setOwnerCatName(FileOwnerTypeBaseEnum.getDes(fileInfo.getOwnerCat())); + fileInfo.setOwnerType(ownerType); + fileInfo.setOwnerTypeName(FileOwnerTypeBaseEnum.getDes(ownerType)); + fileInfo.setUploaderId(uploaderDTO.getUploaderId()); + fileInfo.setUploaderName(uploaderDTO.getUploaderName()); + fileInfo.setUploaderType(uploaderDTO.getUploaderType()); + fileInfo.setCustId(uploaderDTO.getCustId()); + mapper.insert(fileInfo); + // 保存业务关系 + fileRelateService.saveByFileInfo(fileInfo); + return fileInfo; + } catch (Exception e) { + log.error("service方法[FileInfoService.uploadFile]调用失败,异常信息:"+e, e); + throw new ServiceException("FileInfoService.uploadFile", e); + } + } + } diff --git a/dyh-service/dyh-sys/src/main/java/cn/huge/module/file/service/FileRelateService.java b/dyh-service/dyh-sys/src/main/java/cn/huge/module/file/service/FileRelateService.java index 0bf31e4..50aea52 100644 --- a/dyh-service/dyh-sys/src/main/java/cn/huge/module/file/service/FileRelateService.java +++ b/dyh-service/dyh-sys/src/main/java/cn/huge/module/file/service/FileRelateService.java @@ -5,7 +5,10 @@ import cn.huge.base.common.utils.IdUtils; import cn.huge.module.client.api.impl.UtilsClientImpl; import cn.huge.module.file.dao.mapper.FileRelateMapper; +import cn.huge.module.file.domain.dto.UploaderDTO; +import cn.huge.module.file.domain.po.FileInfo; import cn.huge.module.file.domain.po.FileRelate; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -130,4 +133,43 @@ } } + /** + * 根据所属业务编号和类型统计 + * @param ownerId 所属业务编号 + * @param ownerType 所属业务类型 + * @return int 统计数 + */ + public int countByOwnerIdAndType(String ownerId, String ownerType){ + QueryWrapper<FileRelate> fileRelateQueryWrapper = new QueryWrapper<>(); + fileRelateQueryWrapper.eq("owner_id", ownerId).eq("owner_type", ownerType); + return mapper.selectCount(fileRelateQueryWrapper); + } + + /** + * 根据附件信息新增附件业务关系 + * @param fileInfo 附件信息 + */ + public void saveByFileInfo(FileInfo fileInfo) { + try { + // 保存业务关系 + FileRelate fileRelate = new FileRelate(); + fileRelate.setId(utilsClient.getNewTimeId()); + fileRelate.setFileId(fileInfo.getId()); + fileRelate.setOwnerId(fileInfo.getOwnerId()); + fileRelate.setOwnerCat(fileInfo.getOwnerCat()); + fileRelate.setOwnerType(fileInfo.getOwnerType()); + fileRelate.setUploaderId(fileInfo.getUploaderId()); + fileRelate.setUploaderName(fileInfo.getUploaderName()); + fileRelate.setUploaderType(fileInfo.getUploaderType()); + fileRelate.setCustId(fileInfo.getCustId()); + Date nowDate = DateUtils.getNowDate(); + fileRelate.setCreateTime(nowDate); + fileRelate.setUpdateTime(nowDate); + mapper.insert(fileRelate); + } catch (Exception e) { + log.error("service方法[FileRelateService.uploadFile]调用异常:"+e, e); + throw new ServiceException("FileRelateService.uploadFile", e); + } + } + } diff --git a/dyh-service/dyh-sys/src/main/java/cn/huge/module/file/utils/FileUtils.java b/dyh-service/dyh-sys/src/main/java/cn/huge/module/file/utils/FileUtils.java new file mode 100644 index 0000000..e8bdc50 --- /dev/null +++ b/dyh-service/dyh-sys/src/main/java/cn/huge/module/file/utils/FileUtils.java @@ -0,0 +1,40 @@ +package cn.huge.module.file.utils; + + +import cn.huge.base.common.constant.FileConsts; + +/** + * @author liyj + */ +public class FileUtils { + + /** + * 校验文件格式 + * + * @param fileSuffix + * @return + */ + public static Boolean checkFileSuffix(String fileSuffix){ + if(FileConsts._doc.equalsIgnoreCase(fileSuffix) || FileConsts._docx.equalsIgnoreCase(fileSuffix) || + FileConsts._jpeg.equalsIgnoreCase(fileSuffix) || FileConsts._jpg.equalsIgnoreCase(fileSuffix) || FileConsts._png.equalsIgnoreCase(fileSuffix) || FileConsts._bmp.equalsIgnoreCase(fileSuffix) || + FileConsts._pdf.equalsIgnoreCase(fileSuffix) || FileConsts._mp4.equalsIgnoreCase(fileSuffix) || FileConsts._mp3.equalsIgnoreCase(fileSuffix) || FileConsts._avi.equalsIgnoreCase(fileSuffix) + || FileConsts._xlsx.equalsIgnoreCase(fileSuffix)){ + return true; + }else { + return false; + } + // 不做限制 +// return true; + } + + public static Boolean checkImageSuffix(String fileSuffix){ + if(FileConsts._jpeg.equalsIgnoreCase(fileSuffix) || FileConsts._jpg.equalsIgnoreCase(fileSuffix) || + FileConsts._png.equalsIgnoreCase(fileSuffix) || FileConsts._bmp.equalsIgnoreCase(fileSuffix) || + FileConsts._gif.equalsIgnoreCase(fileSuffix)){ + return true; + }else { + return false; + } + } + +} diff --git a/dyh-service/dyh-sys/src/main/java/cn/huge/module/file/utils/FtpMultipartFileWrapper.java b/dyh-service/dyh-sys/src/main/java/cn/huge/module/file/utils/FtpMultipartFileWrapper.java new file mode 100644 index 0000000..b405487 --- /dev/null +++ b/dyh-service/dyh-sys/src/main/java/cn/huge/module/file/utils/FtpMultipartFileWrapper.java @@ -0,0 +1,184 @@ +package cn.huge.module.file.utils; + +import cn.huge.base.common.constant.FileCatEnum; +import cn.huge.base.common.exception.ServiceException; +import cn.huge.base.common.utils.DateUtils; +import cn.huge.module.constant.BaseConsts; +import cn.huge.module.file.config.FtpFileConfig; +import cn.huge.module.file.domain.po.FileInfo; +import org.apache.commons.codec.digest.DigestUtils; +import org.apache.commons.lang3.StringUtils; +import org.springframework.web.multipart.MultipartFile; + +import java.io.IOException; +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.util.Calendar; +import java.util.Date; + +/** + * @title: 上传附件包装处理类 + * @description: 上传附件包装处理类 + * @company: hugeinfo + * @author: liyj + * @time: 2021-11-05 16:51:48 + * @version: 1.0.0 + */ +public class FtpMultipartFileWrapper { + + static final long kilobyte = 1024; + static final long megabyte = 1024 * 1024L; + static final long gigabyte = 1024 * 1024 * 1024L; + + static final BigDecimal kilobyteDividend = new BigDecimal(kilobyte); + static final BigDecimal megabyteDividend = new BigDecimal(megabyte); + static final BigDecimal gigabyteDividend = new BigDecimal(gigabyte); + + static final String SHOW_URL_WEB = "/api/web/fileInfo/show"; + static final String DOWN_URL_WEB = "/api/web/fileInfo/down"; + static final String SHOW_URL_WECHAT = "/api/wechat/fileInfo/show"; + static final String DOWN_URL_WECHAT = "/api/wechat/fileInfo/down"; + + static final String STORE_WAY = "ftp"; + + private MultipartFile file; + + public FtpMultipartFileWrapper(MultipartFile file) { + this.file = file; + } + + /** + * web端上传附件 + * @param fileId + * @return + */ + public FileInfo toWebFileInfo(String fileId) { + FileInfo fileInfo = new FileInfo(); + fileInfo.setId(fileId); + fileInfo.setSuffix(this.getFileSuffix()); + fileInfo.setTrueName(this.getFileName() + BaseConsts.DOT + fileInfo.getSuffix()); + fileInfo.setFileName(this.getFileName() + BaseConsts.UNDER + fileInfo.getId() + BaseConsts.DOT + fileInfo.getSuffix()); + fileInfo.setCat(FileCatEnum.getFileCat(fileInfo.getSuffix())); + fileInfo.setSize(this.getFileSize()); + fileInfo.setUnit(this.getFileUnit()); + fileInfo.setMd5Code(this.getFileVerifyCode()); + fileInfo.setStoreWay(STORE_WAY); + fileInfo.setPath(this.getFileDir()); + fileInfo.setFullPath(fileInfo.getPath() + BaseConsts.SLANT + fileInfo.getFileName()); + fileInfo.setShowUrl(SHOW_URL_WEB + BaseConsts.SLANT + fileInfo.getId()); + fileInfo.setDownUrl(DOWN_URL_WEB + BaseConsts.SLANT + fileInfo.getId()); + // todo + fileInfo.setZipUrl(fileInfo.getShowUrl()); + Date nowDate = DateUtils.getNowDate(); + fileInfo.setCreateTime(nowDate); + fileInfo.setUpdateTime(nowDate); + fileInfo.setDeleteStatus(BaseConsts.DELETE_STATUS_1); + return fileInfo; + } + + /** + * wechat上传附件 + * @param fileId + * @return + */ + public FileInfo toWechatFileInfo(String fileId) { + FileInfo fileInfo = new FileInfo(); + fileInfo.setId(fileId); + fileInfo.setSuffix(this.getFileSuffix()); + fileInfo.setTrueName(this.getFileName() + BaseConsts.DOT + fileInfo.getSuffix()); + fileInfo.setFileName(this.getFileName() + BaseConsts.UNDER + fileInfo.getId() + BaseConsts.DOT + fileInfo.getSuffix()); + fileInfo.setCat(FileCatEnum.getFileCat(fileInfo.getSuffix())); + fileInfo.setSize(this.getFileSize()); + fileInfo.setUnit(this.getFileUnit()); + fileInfo.setMd5Code(this.getFileVerifyCode()); + fileInfo.setStoreWay(STORE_WAY); + fileInfo.setPath(this.getFileDir()); + fileInfo.setFullPath(fileInfo.getPath() + BaseConsts.SLANT + fileInfo.getFileName()); + fileInfo.setShowUrl(SHOW_URL_WECHAT + BaseConsts.SLANT + fileInfo.getId()); + fileInfo.setDownUrl(DOWN_URL_WECHAT + BaseConsts.SLANT + fileInfo.getId()); + // todo + fileInfo.setZipUrl(fileInfo.getShowUrl()); + Date nowDate = DateUtils.getNowDate(); + fileInfo.setCreateTime(nowDate); + fileInfo.setUpdateTime(nowDate); + fileInfo.setDeleteStatus(BaseConsts.DELETE_STATUS_1); + return fileInfo; + } + + /** + * 获取文件名称 + */ + public String getFileName() { + return StringUtils.substringBeforeLast(this.file.getOriginalFilename(), BaseConsts.DOT); + } + + /** + * 获取文件后缀 + */ + public String getFileSuffix() { + return StringUtils.substringAfterLast(this.file.getOriginalFilename(), BaseConsts.DOT); + } + + /** + * 获取文件存储目录,以斜杠开头(/home/ftp/huge-dyh/2022/3) + */ + public String getFileDir() { + //按照年月构建目录 + Calendar ca = Calendar.getInstance(); + StringBuilder builder = new StringBuilder(); + builder.append(FtpFileConfig.getRootdir()); + builder.append(BaseConsts.SLANT); + builder.append(ca.get(Calendar.YEAR)); + builder.append(BaseConsts.SLANT); + builder.append(ca.get(Calendar.MONTH) + 1); + return builder.toString(); + } + + /** + * 获取文件大小, 根据不同的单位进行运算 + */ + public double getFileSize() { + long size = this.file.getSize(); + BigDecimal divisor = new BigDecimal(size); + String unit = this.getFileUnit(); + + if (BaseConsts.B.equals(unit)) { + return size; + } else if (BaseConsts.KB.equals(unit)) { + return divisor.divide(kilobyteDividend, 2, RoundingMode.HALF_UP).doubleValue(); + } else if (BaseConsts.MB.equals(unit)) { + return divisor.divide(megabyteDividend, 2, RoundingMode.HALF_UP).doubleValue(); + } else if (BaseConsts.GB.equals(unit)) { + return divisor.divide(gigabyteDividend, 2, RoundingMode.HALF_UP).doubleValue(); + } + return 0.0; + } + + /** + * 获取文件单位, B|KB|MB|GB + */ + public String getFileUnit() { + long size = this.file.getSize(); + if (size > 0 && size <= kilobyte) { + return BaseConsts.B; + } else if (size > kilobyte && size <= megabyte) { + return BaseConsts.KB; + } else if (size > megabyte && size <= gigabyte) { + return BaseConsts.MB; + } else if (size > gigabyte) { + return BaseConsts.GB; + } + return BaseConsts.B; + } + + /** + * 获取文件校验码, MD5 + */ + public String getFileVerifyCode() { + try { + return DigestUtils.md5Hex(this.file.getBytes()); + } catch (IOException e) { + throw new ServiceException("MultipartFileWrapper.getFileVerifyCode", e); + } + } +} diff --git a/dyh-service/dyh-sys/src/main/java/cn/huge/module/file/utils/FtpUtils.java b/dyh-service/dyh-sys/src/main/java/cn/huge/module/file/utils/FtpUtils.java new file mode 100644 index 0000000..30c5e01 --- /dev/null +++ b/dyh-service/dyh-sys/src/main/java/cn/huge/module/file/utils/FtpUtils.java @@ -0,0 +1,256 @@ +package cn.huge.module.file.utils; + +import cn.huge.base.common.exception.MethodException; +import cn.huge.module.constant.BaseConsts; +import cn.huge.module.file.config.FtpFileConfig; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.net.ftp.FTPClient; +import org.apache.commons.net.ftp.FTPClientConfig; +import org.apache.commons.net.ftp.FTPReply; +import org.springframework.stereotype.Component; + +import java.io.IOException; +import java.io.InputStream; + +/** + * @title: ftp配工具类 + * @description: ftp配工具类 + * @company: hugeinfo + * @author: liyj + * @time: 2021-11-05 16:51:48 + * @version: 1.0.0 + */ +@Slf4j +@Component +public class FtpUtils { + + /** + * 上传附件. + * @param path 服务器存储路径(/home/ftp/huge-dyh) + * @param fileName 文件名(1.jpg) + * @param inputStream 文件流 + */ + public void upload(String path, String fileName, InputStream inputStream) { + FTPClient ftpClient = new FTPClient(); + try { + if (connect(ftpClient)) { + // 检查文件目录是否存在,不存在创建目录 + if (this.checkDir(ftpClient, path)) { + // 检查是否上传成功 + if (storeFile(ftpClient, fileName, inputStream)) { + disconnect(ftpClient); + }else{ + disconnect(ftpClient); + throw new MethodException("连接ftp成功,上传文件失败!"); + } + }else{ + disconnect(ftpClient); + throw new MethodException("连接ftp成功,检查文件目录不存在!"); + } + }else{ + disconnect(ftpClient); + throw new MethodException("连接ftp失败!"); + } + } catch (Exception e) { + disconnect(ftpClient); + log.error("方法[FtpUtils.upload]调用异常:"+e, e); + throw new MethodException("FtpUtils.upload", e); + } + } + + /** + * 从文件服务器获取文件流. + * @param filePath 文件存储完整路径(/home/ftp/huge-dyh/1.jpg) + * @return {@link InputStream} + * @throws IOException + */ + public InputStream retrieveFileStream(String filePath) { + if (StringUtils.isBlank(filePath)) { + throw new MethodException("文件路径为空!"); + } + log.info("读取文件路径[filePath]值" + filePath); + FTPClient ftpClient = new FTPClient(); + try { + if (connect(ftpClient)) { + filePath = new String(filePath.getBytes("UTF-8"), "iso-8859-1"); + InputStream inputStream = ftpClient.retrieveFileStream(filePath); + disconnect(ftpClient); + return inputStream; + }else{ + disconnect(ftpClient); + throw new MethodException("连接ftp失败!"); + } + } catch (Exception e) { + disconnect(ftpClient); + log.error("方法[FtpUtils.retrieveFileStream]调用异常:"+e, e); + throw new MethodException("FtpUtils.retrieveFileStream", e); + } + } + + /** + * 删除文件 + * @param filePath 文件存储完整路径(/home/ftp/huge-dyh/1.jpg) + */ + public void deleteFile(String filePath) { + try{ + String workingPath = filePath.substring(0, filePath.lastIndexOf("/")); + String fileName = filePath.substring(filePath.lastIndexOf("/") + 1, filePath.length()); + deleteFile(workingPath, fileName); + }catch (Exception e){ + log.error("方法[FtpUtils.deleteFile]调用异常:"+e, e); + throw new MethodException("FtpUtils.deleteFile", e); + } + } + + /** + * ftp操作-连接ftp + * @param ftpClient ftp工具 + * @return boolean + */ + private boolean connect(FTPClient ftpClient) { + boolean flag = false; + try { + // 远程ftp需要加上,允许被动连接 + ftpClient.enterLocalPassiveMode(); + FTPClientConfig clientConfig = new FTPClientConfig(); + clientConfig.setLenientFutureDates(true); + ftpClient.configure(clientConfig); + // 连接ftp + ftpClient.connect(FtpFileConfig.getHostname(), FtpFileConfig.getPort()); + if (FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) { + log.info("连接ftp成功!"); + ftpClient.login(FtpFileConfig.getUsername(), FtpFileConfig.getPassword()); + if (FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) { + // 设置以二进制方式传输 + ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE); + // 设置UTF-8编码 + ftpClient.setControlEncoding("UTF-8"); + //设置传输方式为流方式 + ftpClient.setFileTransferMode(FTPClient.STREAM_TRANSFER_MODE); + // 设置缓冲区大小 + ftpClient.setBufferSize(1024); + log.info("登录ftp成功!"); + flag = true; + } else { + log.error("登录ftp失败,可能用户名或密码错误!"); + } + }else{ + log.error("连接ftp失败,可能ip或端口错误!"); + } + return flag; + } catch (IOException e) { + log.error("方法[FtpUtils.connect]调用异常:"+e, e); + throw new MethodException("FtpUtils.connect", e); + } + } + + /** + * ftp操作-检查文件目录不存在时,创建目录 + * @param ftpClient ftp工具 + * @param path 服务器存储路径(/home/ftp/huge-dyh) + * @return String + */ + public Boolean checkDir(FTPClient ftpClient, String path){ + try{ + log.info("上传路径为:" + path); + Boolean flag = false; + if (!ftpClient.changeWorkingDirectory(path)) { + StringBuffer rootPath = new StringBuffer(); + rootPath.append(FtpFileConfig.getRootdir()); + // 创建文件目录 + path = path.replace(FtpFileConfig.getRootdir() + BaseConsts.SLANT, ""); + String[] paths = path.split(BaseConsts.SLANT); + for (String filePath: paths){ + if (StringUtils.isBlank(filePath)){ + continue; + }else{ + rootPath.append(BaseConsts.SLANT); + rootPath.append(filePath); + if (!ftpClient.changeWorkingDirectory(rootPath.toString())){ + ftpClient.makeDirectory(rootPath.toString()); + } + } + } + // 严谨一点,再检查文件目录是否存在 + if (ftpClient.changeWorkingDirectory(rootPath.toString())) { + flag = true; + } + }else{ + flag = true; + } + return flag; + }catch (Exception e){ + log.error("方法[FtpUtils.makeDir]调用异常:"+e, e); + throw new MethodException("FtpUtils.makeDir", e); + } + } + + /** + * ftp操作-上传文件到ftp + * @param ftpClient ftp工具 + * @param fileName 文件名称(1.jpg) + * @param fileInputStream 文件流 + * @return boolean + */ + private boolean storeFile(FTPClient ftpClient, String fileName, InputStream fileInputStream) { + boolean flag = false; + try { + fileName = new String(fileName.getBytes("UTF-8"), "iso-8859-1"); + log.info("上传文件名为:" + fileName); + ftpClient.storeFile(fileName, fileInputStream); + int reply = ftpClient.getReplyCode(); + if (FTPReply.isPositiveCompletion(reply)) { + flag = true; + log.info("上传文件成功!"); + }else{ + log.error("上传文件失败!请求响应码[reply]值为:" + reply); + } + fileInputStream.close(); + return flag; + } catch (IOException e) { + log.error("方法[FtpUtils.storeFile]调用异常:"+e, e); + throw new MethodException("FtpUtils.storeFile", e); + } + } + + /** + * ftp操作-删除附件. + * @param path 服务器存储路径(/home/ftp/huge-dyh) + * @param fileName 附件名称(1.jpg) + */ + public void deleteFile(String path, String fileName) { + FTPClient ftpClient = new FTPClient(); + try{ + connect(ftpClient); + if (ftpClient.changeWorkingDirectory(path)) { + // 删除文件 + ftpClient.dele(fileName); + disconnect(ftpClient); + }else { + disconnect(ftpClient); + throw new MethodException("文件路径不存在!"); + } + }catch (Exception e){ + disconnect(ftpClient); + log.error("方法[FtpUtils.deleteFile]调用异常:"+e, e); + throw new MethodException("FtpUtils.deleteFile", e); + } + } + + /** + * ftp操作-断开ftp连接. + * @param ftpClient ftp工具 + */ + private void disconnect(FTPClient ftpClient) { + if (ftpClient.isConnected()) { + try { + ftpClient.disconnect(); + } catch (IOException e) { + log.error("方法[FtpUtils.disconnect]调用异常:"+e, e); + throw new MethodException("FtpUtils.disconnect", e); + } + } + } + +} \ No newline at end of file diff --git a/dyh-service/dyh-sys/src/main/resources/config/application.yml b/dyh-service/dyh-sys/src/main/resources/config/application.yml index a05e20b..1f89e91 100644 --- a/dyh-service/dyh-sys/src/main/resources/config/application.yml +++ b/dyh-service/dyh-sys/src/main/resources/config/application.yml @@ -60,13 +60,4 @@ logic-delete-value: 1 #字段策略,IGNORED:忽略判断,NOT_NULL:非null判断,NOT_EMPTY:非空判断,DEFAULT:默认,NEVER:不加入sql update-strategy: IGNORED - mapper-locations: classpath*:/cn/huge/*/*/dao/mapper/xml/*Mapper.xml - -#附件配置 -file: - #存储方式 - store-way: ftp - #查看地址 - show-path: /api/fileInfo/show - #下载地址 - down-path: /api/fileInfo/down \ No newline at end of file + mapper-locations: classpath*:/cn/huge/*/*/dao/mapper/xml/*Mapper.xml \ No newline at end of file -- Gitblit v1.8.0