Commit 683dc8d8 by huangtao

physic

parent 2c050fb7
Showing with 740 additions and 38 deletions
package com.jmai.physic.cloudsign;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.jmai.api.exception.ServiceException;
import com.jmai.sys.util.HttpUtils;
import com.jmai.sys.util.OpenUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
@Slf4j
@Component
public class CloudsignService {
private static final String HOST = "http://192.168.2.194:18087";
private static final String loginbypin = HOST+"/v1.0/cloudsign/loginbypin";
private static final String genloginqrcode =HOST+"/v1.0/cloudsign/genloginqrcode";
private static final String signdata =HOST+"/v1.0/cloudsign/signdata";
private static final String getstamp =HOST+"/v1.0/cloudsign/getstamp";
/**
* PIN吗登录
*/
public GenloginqrcodeRespon loginbypin(LoginBypinRequest request){
String logTip = "loginbypin";
String json = OpenUtil.toJson(request);
try {
log.info("{}-入参:{}",logTip,json);
String response = HttpUtils.sendPostRequestAndParse(loginbypin, json, null);
log.info("{}-返回数据:{}",logTip,response);
if(ObjectUtil.isEmpty(response)){
throw new ServiceException("获取失败");
}
GenloginqrcodeRespon genloginqrcodeRespon = JSON.parseObject(response, GenloginqrcodeRespon.class);
return genloginqrcodeRespon;
} catch (Exception exception) {
log.error("获取令牌失败,e:{}"+exception.getMessage());
throw new ServiceException("获取失败");
}
}
/**
* 请求云签二维码
* @param request
*/
public void genloginqrcode(GenloginqrcodeRequest request){
String logTip = "genloginqrcode";
String json = OpenUtil.toJson(request);
try {
log.info("{}-入参:{}",logTip,json);
String response = HttpUtils.sendPostRequestAndParse(genloginqrcode, json, null);
log.info("{}-返回数据:{}",logTip,response);
if(ObjectUtil.isEmpty(response)){
throw new ServiceException("获取失败");
}
GenloginqrcodeRespon genloginqrcodeRespon = JSON.parseObject(response, GenloginqrcodeRespon.class);
} catch (Exception exception) {
}
}
/**
* 云签证书数字签名
* @param request
*/
public SignDataRespon signdata(SignDataRequest request){
String logTip = "signdata";
String json = OpenUtil.toJson(request);
try {
log.info("{}-入参:{}",logTip,json);
String response = HttpUtils.sendPostRequestAndParse(signdata, json, null);
log.info("{}-返回数据:{}",logTip,response);
if(ObjectUtil.isEmpty(response)){
throw new ServiceException("获取失败");
}
SignDataRespon signDataRespon = JSON.parseObject(response, SignDataRespon.class);
return signDataRespon;
} catch (Exception exception) {
log.error("签名失败,e:{}"+exception.getMessage());
throw new ServiceException("签名失败");
}
}
/**
* 获取手写签名图片
* @param request
*/
public String getstamp(GetstampRequest request){
String logTip = "getstamp";
String json = OpenUtil.toJson(request);
try {
log.info("{}-入参:{}",logTip,json);
String response = HttpUtils.sendPostRequestAndParse(getstamp, json, null);
log.info("{}-返回数据:{}",logTip,response);
if(ObjectUtil.isEmpty(response)){
throw new ServiceException("获取失败");
}
GetstampRespon getstampRespon = JSON.parseObject(response, GetstampRespon.class);
if(getstampRespon.getStatusCode()==0){
return getstampRespon.getEventValue().getStampBase64();
}else{
throw new ServiceException(getstampRespon.getEventMsg());
}
} catch (Exception exception) {
log.error("获取手写签名图片失败,e:{}"+exception.getMessage());
throw new ServiceException("获取手写签名图片失败");
}
}
}
package com.jmai.physic.cloudsign;
import lombok.Data;
@Data
public class GenloginqrcodeRequest {
private String businessOrgCode;
private String businessSystemCode;
private String businessSystemAppID;
private String notifyUrl;
private Integer imageFormat;
}
package com.jmai.physic.cloudsign;
import lombok.Data;
@Data
public class GenloginqrcodeRespon {
private Integer statusCode;
private String eventMsg;
private EventValue eventValue;
@Data
public static class EventValue {
private String qRCodeBase64;
private Integer durateTime;
private String claimUuid;
private String encryptedToken;
}
}
package com.jmai.physic.cloudsign;
import lombok.Data;
@Data
public class GetstampRequest {
private String businessOrgCode;
private String relBizNo;
}
package com.jmai.physic.cloudsign;
import lombok.Data;
@Data
public class GetstampRespon {
private Integer statusCode;
private String eventMsg;
private EventValue eventValue;
@Data
public static class EventValue {
private String stampBase64;
}
}
package com.jmai.physic.cloudsign;
import lombok.Data;
@Data
public class LoginBypinRequest {
private String businessOrgCode;
private String businessSystemCode;
private String businessSystemAppID;
private String relBizNo;
private Integer userEncodePin;
private Integer loginType;
}
package com.jmai.physic.cloudsign;
import lombok.Data;
@Data
public class SignDataRequest {
private String businessOrgCode;
private String businessSystemCode;
private String businessSystemAppID;
private String businessTypeCode;
private String encryptedToken;
private String patientId;
private String bizId;
private String base64SourceData;
private String withTsa;
}
package com.jmai.physic.cloudsign;
import lombok.Data;
@Data
public class SignDataRespon {
private Integer statusCode;
private String eventMsg;
private EventValue eventValue;
@Data
public static class EventValue {
private String signedData;
private Integer timestamp;
}
}
......@@ -4,11 +4,8 @@ package com.jmai.physic.controller;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jmai.physic.dto.PhysicAmpouleCreateReq;
import com.jmai.physic.dto.PhysicAmpouleQueryReq;
import com.jmai.physic.dto.PhysicStorageAmpouleCreateReq;
import com.jmai.physic.entity.PhysicAmpoule;
import com.jmai.physic.entity.PhysicStorageAmpoule;
import com.jmai.physic.service.PhysicAmpouleService;
import com.jmai.physic.service.PhysicStorageAmpouleService;
import com.jmai.sys.aop.Auth;
import com.jmai.sys.dto.ResponseData;
import io.swagger.annotations.Api;
......@@ -28,7 +25,7 @@ import javax.validation.Valid;
@Auth
@RestController
@RequestMapping("/physicAmpoule")
@Api(tags = "药品专用登记-药房/科室")
@Api(tags = "药品专用登记-药室")
@ApiImplicitParams({@ApiImplicitParam(paramType = "header", name = "Access-Token", value = "凭证", required = true, dataType = "string")})
public class PhysicAmpouleController {
......
package com.jmai.physic.controller;
import com.jmai.physic.alihealth.AlihealthService;
import com.jmai.physic.dto.PhysicApplyCreateReq;
import com.jmai.physic.dto.PhysicInfoDTO;
import com.jmai.physic.dto.PhysicWarehouseCreateReq;
import com.jmai.physic.service.PhysicApplyService;
import com.jmai.physic.service.PhysicWarehouseService;
import com.jmai.physic.vo.PhysicApplyVO;
import com.jmai.physic.vo.PhysicWarehouseVO;
import com.jmai.sys.AbstractService;
import com.jmai.sys.aop.Auth;
import com.jmai.sys.dto.ResponseData;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
......@@ -23,10 +20,10 @@ import javax.validation.Valid;
import java.util.List;
@Slf4j
//@Auth
@Auth
@RestController
@RequestMapping("/physicApply")
@Api(tags = "药品入库单据")
@Api(tags = "药品申请单据")
@ApiImplicitParams({@ApiImplicitParam(paramType = "header", name = "Access-Token", value = "凭证", required = true, dataType = "string")})
public class PhysicApplyController extends AbstractService {
......
package com.jmai.physic.controller;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jmai.physic.dto.PhysicCheckQueryReq;
import com.jmai.physic.dto.PhysicDestroyCheckCreateReq;
import com.jmai.physic.dto.PhysicRecordCreateReq;
import com.jmai.physic.entity.PhysicDestroyCheck;
import com.jmai.physic.service.PhysicDestroyCheckService;
import com.jmai.physic.service.PhysicDestroyService;
import com.jmai.sys.aop.Auth;
import com.jmai.sys.dto.ResponseData;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping;
......@@ -22,7 +25,8 @@ import javax.validation.Valid;
@Auth
@RestController
@RequestMapping("/physicDestroyCheck")
@Api(tags = "镇痛泵销毁")
@Api(tags = "销毁审批")
@ApiImplicitParams({@ApiImplicitParam(paramType = "header", name = "Access-Token", value = "凭证", required = true, dataType = "string")})
public class PhysicDestroyCheckController {
@Resource
......@@ -34,4 +38,10 @@ public class PhysicDestroyCheckController {
physicDestroyCheckService.create(req);
return ResponseData.ok();
}
@PostMapping("/listPage")
@ApiOperation(value = "查询")
public Page<PhysicDestroyCheck> listPage(@RequestBody PhysicCheckQueryReq req) {
return physicDestroyCheckService.listPage(req);
}
}
package com.jmai.physic.controller;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jmai.physic.dto.PhysicCheckQueryReq;
import com.jmai.physic.dto.PhysicDestroyCheckCreateReq;
import com.jmai.physic.dto.PhysicDestroyCreateReq;
import com.jmai.physic.dto.PhysicRecordQueryReq;
import com.jmai.physic.entity.PhysicDestroy;
import com.jmai.physic.entity.PhysicRecord;
import com.jmai.physic.service.PhysicDestroyCheckService;
import com.jmai.physic.service.PhysicDestroyService;
import com.jmai.sys.aop.Auth;
import com.jmai.sys.dto.ResponseData;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import javax.validation.Valid;
@Slf4j
@Auth
@RestController
@Api(tags = "镇痛泵销毁")
@ApiImplicitParams({@ApiImplicitParam(paramType = "header", name = "Access-Token", value = "凭证", required = true, dataType = "string")})
@RequestMapping("/physicDestroy")
public class PhysicDestroyController {
@Resource
private PhysicDestroyService physicDestroyService;
@PostMapping("/create")
@ApiOperation(value = "创建")
public ResponseData create(@RequestBody @Valid PhysicDestroyCreateReq req) {
physicDestroyService.create(req);
return ResponseData.ok();
}
@PostMapping("/listPage")
@ApiOperation(value = "查询")
public Page<PhysicDestroy> listPage(@RequestBody PhysicCheckQueryReq req) {
return physicDestroyService.listPage(req);
}
}
......@@ -23,7 +23,7 @@ import java.util.List;
import java.util.Optional;
@Slf4j
//@Auth
@Auth
@RestController
@RequestMapping("/physicWarehouse")
@Api(tags = "药品入库单据")
......
package com.jmai.physic.dto;
import com.jmai.sys.dto.PageReq;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
public class PhysicCheckQueryReq extends PageReq {
@ApiModelProperty("关键字")
private String keyword;
@ApiModelProperty(value = "状态")
private Integer status;
}
......@@ -11,16 +11,12 @@ public class PhysicWarehouseCreateReq {
@ApiModelProperty(value = "药品类型")
private String physicType;
private String physicTypeDesc;
private String physicSpec;
private String pkgSpecCrit;
private String prepnSpec;
private String prepnTypeDesc;
private String unit;
@ApiModelProperty(value = "失效时间")
private String exprieDate;
private String expireDate;
@ApiModelProperty(value = "厂家名称")
private String factoryName;
......@@ -28,10 +24,15 @@ public class PhysicWarehouseCreateReq {
@ApiModelProperty(value = "供应商")
private String supplyName;
@ApiModelProperty(value = "批号")
private String batchNo;
@NotBlank(message = "凭证号不能为空")
@ApiModelProperty(value = "凭证号")
private String voucherNo;
@ApiModelProperty(value = "批号")
private String batchNo;
@ApiModelProperty(value = "数量")
private Integer physicNum;
}
......@@ -4,6 +4,7 @@ package com.jmai.physic.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import com.jmai.sys.entity.BaseVersionEntity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.Date;
......@@ -17,6 +18,8 @@ public class PhysicDestroy extends BaseVersionEntity {
private String sickName;
private String orderNo;
private String surplus;
@ApiModelProperty(value = "状态 0-代操作 1-待复核 2-已完成")
private Integer status;
private String czUser;
private String xhUser;
......
......@@ -4,6 +4,7 @@ package com.jmai.physic.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import com.jmai.sys.entity.BaseVersionEntity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
......@@ -16,5 +17,6 @@ public class PhysicDestroyCheck extends BaseVersionEntity {
private String applyReason;
private String images;
private Integer destroyNum;
@ApiModelProperty(value = "状态 0-审批中 1-已销毁 ")
private Integer status;
}
......@@ -19,13 +19,11 @@ public class PhysicWarehouse extends BaseVersionEntity{
@ApiModelProperty(value = "药品类型")
private String physicType;
private String physicTypeDesc;
private String physicSpec;
private String pkgSpecCrit;
private String unit;
private String prepnSpec;
private String prepnTypeDesc;
private Integer physicNum;
@ApiModelProperty(value = "失效时间")
private String expireDate;
......@@ -44,4 +42,10 @@ public class PhysicWarehouse extends BaseVersionEntity{
private String supplyName;
@ApiModelProperty(value = "状态 0 -待验收 1-待复核 2 -待保管 3 -完成")
private Integer status;
private String ysUser;
private String fhUser;
private String bgUser;
}
package com.jmai.physic.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jmai.physic.dto.PhysicCheckQueryReq;
import com.jmai.physic.entity.PhysicBill;
import com.jmai.physic.entity.PhysicDestroyCheck;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
@Mapper
public interface PhysicDestroyCheckMapper extends BaseMapper<PhysicDestroyCheck> {
Page<PhysicDestroyCheck> selectCheckPage(Page<PhysicDestroyCheck> page, @Param("req") PhysicCheckQueryReq req)
;
}
......@@ -2,9 +2,13 @@ package com.jmai.physic.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jmai.physic.dto.PhysicCheckQueryReq;
import com.jmai.physic.entity.PhysicDestroy;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
@Mapper
public interface PhysicDestroyMapper extends BaseMapper<PhysicDestroy> {
Page<PhysicDestroy> selectDestroyPage(@Param("page") Page<PhysicDestroy> page, @Param("req") PhysicCheckQueryReq req);
}
package com.jmai.physic.service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jmai.physic.dto.PhysicCheckQueryReq;
import com.jmai.physic.dto.PhysicDestroyCheckCreateReq;
import com.jmai.physic.entity.PhysicDestroyCheck;
import com.jmai.sys.service.BaseService;
......@@ -8,4 +10,6 @@ public interface PhysicDestroyCheckService extends BaseService<PhysicDestroyChec
void create(PhysicDestroyCheckCreateReq req);
Page<PhysicDestroyCheck> listPage(PhysicCheckQueryReq req);
}
package com.jmai.physic.service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jmai.physic.dto.PhysicAmpouleCreateReq;
import com.jmai.physic.dto.PhysicCheckQueryReq;
import com.jmai.physic.dto.PhysicDestroyCreateReq;
import com.jmai.physic.entity.PhysicDestroy;
public interface PhysicDestroyService {
void create(PhysicDestroyCreateReq req);
Page<PhysicDestroy> listPage(PhysicCheckQueryReq req);
}
package com.jmai.physic.service.impl;
import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jmai.physic.dto.PhysicCheckQueryReq;
import com.jmai.physic.dto.PhysicDestroyCheckCreateReq;
import com.jmai.physic.entity.PhysicDestroy;
import com.jmai.physic.entity.PhysicDestroyCheck;
......@@ -14,6 +16,8 @@ import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import static com.jmai.sys.AbstractService.buildEmptyPage;
@Service
public class PhysicDestroyCheckServiceImpl extends BaseServiceImpl<PhysicDestroyCheckMapper, PhysicDestroyCheck> implements PhysicDestroyCheckService {
......@@ -21,6 +25,9 @@ public class PhysicDestroyCheckServiceImpl extends BaseServiceImpl<PhysicDestroy
@Resource
private PhysicDestroyCheckDetailService physicDestroyCheckDetailService;
@Resource
private PhysicDestroyCheckMapper physicDestroyCheckMapper;
@Transactional
@Override
public void create(PhysicDestroyCheckCreateReq req) {
......@@ -32,4 +39,12 @@ public class PhysicDestroyCheckServiceImpl extends BaseServiceImpl<PhysicDestroy
}
physicDestroyCheckDetailService.saveBatch(req.getCheckDetailList());
}
@Override
public Page<PhysicDestroyCheck> listPage(PhysicCheckQueryReq req) {
Page<PhysicDestroyCheck> page = buildEmptyPage(req);
Page<PhysicDestroyCheck> checkPage = physicDestroyCheckMapper.selectCheckPage(page, req);
return checkPage;
}
}
package com.jmai.physic.service.impl;
import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jmai.physic.dto.PhysicCheckQueryReq;
import com.jmai.physic.dto.PhysicDestroyCreateReq;
import com.jmai.physic.entity.PhysicDestroy;
import com.jmai.physic.entity.PhysicRecord;
import com.jmai.physic.mapper.PhysicDestroyMapper;
import com.jmai.physic.service.PhysicBillService;
import com.jmai.physic.service.PhysicDestroyService;
......@@ -33,4 +36,11 @@ public class PhysicDestroyServiceImpl extends AbstractService implements PhysicD
physicDestroyMapper.insert(destroy);
}
@Override
public Page<PhysicDestroy> listPage(PhysicCheckQueryReq req) {
Page<PhysicDestroy> page = buildEmptyPage(req);
Page<PhysicDestroy> destroyPage = physicDestroyMapper.selectDestroyPage(page, req);
return destroyPage;
}
}
......@@ -34,6 +34,9 @@ public class PhysicWarehouseServiceImpl extends AbstractService implements Phys
PhysicWarehouse physicWarehouse = new PhysicWarehouse();
BeanUtil.copyProperties(req,physicWarehouse);
physicWarehouse.setStatus(0);
Long userId = SpringContextUtils.getUserId();
SysUser sysUser = sysUserMapper.selectById(userId);
physicWarehouse.setDeptId(sysUser.getDeptId());
physicWarehouseMapper.insert(physicWarehouse);
PhysicWarehouseVO info = getInfo(physicWarehouse.getId());
return info;
......
......@@ -9,22 +9,16 @@ public class PhysicWarehouseVO {
private Long physicWarehouseId;
@ApiModelProperty(value = "药品名称")
private String physicName;
@ApiModelProperty(value = "药品类型")
private String physicType;
private String physicTypeDesc;
private String pkgSpecCrit;
private String prepnSpec;
private String physicSpec;
private String prepnTypeDesc;
private String unit;
@ApiModelProperty(value = "失效时间")
private String exprieDate;
private String expireDate;
@ApiModelProperty(value = "凭证号")
private String voucherNo;
......
<?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.jmai.physic.mapper.PhysicDestroyCheckMapper">
<select id="selectCheckPage" resultType="com.jmai.physic.entity.PhysicDestroyCheck">
select * from physic_destroy_check
where del_flag =0
<if test="req.keyword != null and req.keyword != ''">
AND (
apply_name LIKE CONCAT('%', #{req.keyword}, '%')
OR apply_title LIKE CONCAT('%', #{req.keyword}, '%')
OR apply_reason LIKE CONCAT('%', #{req.keyword}, '%')
)
</if>
<if test="req.status =!null">
and status =#{req.status}
</if>
</select>
</mapper>
<?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.jmai.physic.mapper.PhysicDestroyMapper">
<select id="selectDestroyPage" resultType="com.jmai.physic.entity.PhysicDestroy">
select * from physic_destroy
where del_flag =0
<if test="req.keyword != null and req.keyword != ''">
AND (
sick_name LIKE CONCAT('%', #{req.keyword}, '%')
OR order_no LIKE CONCAT('%', #{req.keyword}, '%')
OR surplus LIKE CONCAT('%', #{req.keyword}, '%')
)
</if>
<if test="req.status =!null">
and status =#{req.status}
</if>
</select>
</mapper>
......@@ -4,7 +4,7 @@
<select id="selectRecordPage" resultType="com.jmai.physic.entity.PhysicRecord">
select * from physic_record
where del_flag
where del_flag =0
<if test="req.keyword != null and req.keyword != ''">
AND (
physic_name LIKE CONCAT('%', #{req.keyword}, '%')
......@@ -15,6 +15,7 @@
OR disease_name LIKE CONCAT('%', #{req.keyword}, '%')
OR prescription_number LIKE CONCAT('%', #{req.keyword}, '%')
OR prescription_doctor LIKE CONCAT('%', #{req.keyword}, '%')
)
</if>
<if test="req.status =!null">
......
package com.jmai.sys.controller;
import cn.hutool.core.util.ObjectUtil;
import com.google.common.collect.ImmutableMap;
import com.jmai.api.exception.ServiceException;
import com.jmai.sys.config.properties.InfynovaProperties;
import com.jmai.sys.dto.ResponseData;
import com.jmai.sys.dto.UploadResultVo;
import com.jmai.sys.dto.common.IdListReq;
import com.jmai.sys.dto.common.IdReq;
import com.jmai.sys.entity.SysFile;
import com.jmai.sys.service.SysFileService;
import com.jmai.sys.storage.FileStorageService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import static com.jmai.sys.exception.ErrorCode.FILE_TYPE_NOT_SUPPORTED;
import static com.jmai.sys.exception.ErrorCode.SYSTEM_501;
/**
*/
@Slf4j
@RestController
@RequestMapping("oss")
@Api(tags = "图片上传")
public class OSSController {
@Resource
private SysFileService sysFileService;
@Resource
private InfynovaProperties infynovaProperties;
@Resource
private FileStorageService fileStorageService;
@PostConstruct
private void printLog() {
log.info("OSSController 上传文件校验:是否开启={},文件类型={},内容类型={},文件头={},默认支持文件头={}",
infynovaProperties.getUploadFileTypeFilterEnabled(),
infynovaProperties.getUploadFileTypeWhitelist(),
infynovaProperties.getUploadContentTypeWhitelist(),
infynovaProperties.getUploadFileHeadWhitelist(),
fileTypeMap);
}
/**
* 检查文件后缀类型
*/
private void checkFilename(MultipartFile file) {
if (!infynovaProperties.getUploadFileTypeFilterEnabled()) {
return;
}
String filename = file.getOriginalFilename();
String fileType=filename.substring(filename.lastIndexOf("."));
if (fileType.startsWith(".")) {
fileType = fileType.substring(1);
}
checkValid(fileType, infynovaProperties.getUploadFileTypeWhitelist(), null);
}
/**
* 检查文件类型
*/
private void checkContentType(MultipartFile file) {
if (!infynovaProperties.getUploadFileTypeFilterEnabled()) {
return;
}
String contentType = file.getContentType();
checkValid(contentType, infynovaProperties.getUploadContentTypeWhitelist(), null);
}
/**
* 检测文件头
*/
private void checkFileHead(MultipartFile file) {
if (!infynovaProperties.getUploadFileTypeFilterEnabled()) {
return;
}
byte[] buf = new byte[16];
try (InputStream inputStream = file.getInputStream()) {
inputStream.read(buf);
StringBuilder fileHead = new StringBuilder();
for (int i = 0; i < buf.length; i++) {
int v = buf[i] & 0xFF;
fileHead.append(String.format("%02x", v).toUpperCase());
}
String fileTypeHex = fileHead.toString();
if (log.isDebugEnabled()) {
log.debug("checkFileHead 文件头:{}", fileTypeHex);
}
boolean matched = fileTypeMap.entrySet().stream()
.anyMatch(kv -> fileTypeHex.toUpperCase(Locale.ROOT).startsWith(kv.getValue()));
if (!matched) {
// 检查白名单
if (ObjectUtil.isNotEmpty(infynovaProperties.getUploadFileHeadWhitelist())) {
matched = infynovaProperties.getUploadFileHeadWhitelist().stream()
.anyMatch(header -> fileTypeHex.toUpperCase(Locale.ROOT).startsWith(header));
}
}
if (!matched) {
log.error("checkFileHead 不支持的文件头:文件头={},默认支持={},白名单={}",
fileHead, fileTypeMap, infynovaProperties.getUploadFileHeadWhitelist());
throw new ServiceException(FILE_TYPE_NOT_SUPPORTED);
}
} catch (ServiceException e) {
log.error("checkFileHead 不支持的文件类型", e);
throw new ServiceException(FILE_TYPE_NOT_SUPPORTED, e);
} catch (IOException e) {
log.error("checkFileHead 不支持的文件类型", e);
throw new ServiceException(FILE_TYPE_NOT_SUPPORTED, e);
}
}
/**
* 文件文件头
* 参考:
* https://blog.csdn.net/zhembrace/article/details/52717559
* https://blog.csdn.net/ccj2020/article/details/87603903
* https://zhuanlan.zhihu.com/p/158980459
* http://doc.chacuo.net/filehead
*/
private static final Map<String, String> fileTypeMap;
static {
fileTypeMap = ImmutableMap.<String, String>builder()
.put("jpg","FFD8FF")
.put("jpeg","FFD8FF")
.put("png","89504E47")
.put("gif","47494638")
.put("pdf","255044462D312E")
.put("doc","D0CF11E0")
.put("docx","504B0304")
.put("xls","D0CF11E0")
.put("xlsx","504B0304")
.put("zip","504B0304")
.put("rar","52617221")
.put("7z", "377ABCAF271C")
.build();
}
private void checkValid(String input, List<String> whitelist, List<String> blacklist) {
if (!infynovaProperties.getUploadFileTypeFilterEnabled()) {
return;
}
input = input.toLowerCase(Locale.ROOT);
if (ObjectUtil.isNotEmpty(whitelist) && !whitelist.contains(input)) {
log.error("checkValid 不支持的文件类型:白名单={},输入={}", whitelist, input);
throw new ServiceException(FILE_TYPE_NOT_SUPPORTED);
}
if (ObjectUtil.isNotEmpty(blacklist) && blacklist.contains(input)) {
log.error("checkValid 不支持的文件类型:黑名单={},输入={}", blacklist, input);
throw new ServiceException(FILE_TYPE_NOT_SUPPORTED);
}
}
// @Override
// public ResponseData<Long> saveFile(FileSaveIdReqVo reqVo) {
// return success(ossService.saveFile(reqVo));
// }
@ApiOperation(value = "获取图片信息")
@PostMapping(value = "getImgInfo")
public ResponseData<UploadResultVo> getImgInfoById(@Validated @RequestBody IdReq idReq) {
return ResponseData.ok(sysFileService.getUrlById(idReq.getId()));
}
@ApiOperation(value = "批量查询图片")
@PostMapping(value = "queryBatchById")
public ResponseData<List<UploadResultVo>> queryBatchById(@Validated @RequestBody IdListReq req) {
return ResponseData.ok(sysFileService.getUrlById(req.getIds()));
}
@ApiOperation(value = "获取图片地址")
@PostMapping(value = "getUrlById")
public ResponseData<String> getUrlById(@Validated @RequestBody IdReq idReq) {
return ResponseData.ok(sysFileService.getUrl(idReq.getId()));
}
@PostMapping(value = "getUrlById/{id}")
@ApiOperation(value = "获取图片地址通过ID获取")
public ResponseData<String> getUrlById(@PathVariable("id") Long id) {
return ResponseData.ok(sysFileService.getUrl(id));
}
@Deprecated
@GetMapping(value = "getUrlById/{id}")
@ApiOperation(value = "获取图片地址通过ID获取")
public ResponseData<String> getUrlById2(@PathVariable("id") Long id) {
return ResponseData.ok(sysFileService.getUrl(id));
}
@SneakyThrows
@PostMapping(value = "downloadFile")
@ApiOperation(value = "下载文件")
public void downloadFile(@RequestParam("fileId") Long fileId,HttpServletResponse response) {
SysFile sysFile = sysFileService.getById(fileId);
fileStorageService.download(sysFile.getId(),response,sysFile.getPlatform());
}
@Deprecated
@SneakyThrows
@GetMapping(value = "downloadFile")
@ApiOperation(value = "下载文件")
public void downloadFile2(@RequestParam("fileId") Long fileId, HttpServletResponse response) {
SysFile sysFile = sysFileService.getById(fileId);
fileStorageService.download(sysFile.getId(),response,sysFile.getPlatform());
}
@ApiOperation(value = "上传文件")
@PostMapping(value = "uploadFile")
@SneakyThrows
public ResponseData<UploadResultVo> uploadFile(@RequestParam("fileType") Integer fileType ,MultipartFile file) {
if(ObjectUtil.isEmpty(file)) {
return ResponseData.error(SYSTEM_501);
}
return ResponseData.ok(fileStorageService.save(file.getOriginalFilename(),fileType,file));
}
}
package com.jmai.sys.util;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.format.DateTimeParseException;
import java.time.temporal.ChronoField;
public class OpenUtil {
public static String toJson(Object object) {
if (null == object) {
return "";
}
return JSON.toJSONString(object, SerializerFeature.WriteNullStringAsEmpty,SerializerFeature.WriteMapNullValue,SerializerFeature.SortField);
}
public static LocalDate getLocalDate(String date) {
DateTimeFormatter flexibleFormatter = new DateTimeFormatterBuilder()
.appendPattern("yyyy-MM-dd")
.optionalStart() // 时间部分是可选的
.appendPattern(" HH:mm:ss")
.optionalEnd()
.parseDefaulting(ChronoField.HOUR_OF_DAY, 0) // 默认时间部分为 00:00:00
.parseDefaulting(ChronoField.MINUTE_OF_HOUR, 0)
.parseDefaulting(ChronoField.SECOND_OF_MINUTE, 0)
.toFormatter();
return LocalDate.parse(date, flexibleFormatter);
}
public static LocalDateTime getLocalDateTime(String date){
DateTimeFormatter flexibleFormatter = new DateTimeFormatterBuilder()
.appendPattern("yyyy-MM-dd")
.optionalStart() // 时间部分是可选的
.appendPattern(" HH:mm:ss")
.optionalEnd()
.parseDefaulting(ChronoField.HOUR_OF_DAY, 0) // 默认时间部分为 00:00:00
.parseDefaulting(ChronoField.MINUTE_OF_HOUR, 0)
.parseDefaulting(ChronoField.SECOND_OF_MINUTE, 0)
.toFormatter();
return LocalDateTime.parse(date, flexibleFormatter);
}
public static boolean isValidDate(String dateStr) {
try {
// 尝试解析为 yyyy-MM-dd 格式
DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
LocalDate.parse(dateStr, dateFormatter);
return true;
} catch (DateTimeParseException e1) {
try {
// 尝试解析为 yyyy-MM-dd HH:mm:ss 格式
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
LocalDateTime.parse(dateStr, dateTimeFormatter);
return true;
} catch (DateTimeParseException e2) {
return false;
}
}
}
}
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment