新增文件下载和密钥获取功能,更新用户服务以支持从Excel批量导入用户,新增用户导入模板文件。

This commit is contained in:
刘倡
2025-07-24 17:13:37 +08:00
parent f1efffdd32
commit 42a92dca64
10 changed files with 300 additions and 41 deletions

View File

@ -382,5 +382,28 @@ public class FileController extends BaseController {
return ok(aBoolean);
}
/**
* 描述: 下载大附件
*
* @author: MengHaoHao
* @Date 创建时间: 2021/6/24
*/
@GetMapping("/getDownload")
public BaseResponse<Boolean> getDownload(@RequestParam("fileId") String fileId,HttpServletResponse httpServletResponse ,@RequestParam("documentSecretKey") String documentSecretKey){
return fileService.getDownload(fileId,httpServletResponse,documentSecretKey);
}
/**
* 描述: 获取密钥
*
* @author: MengHaoHao
* @Date 创建时间: 2021/6/24
*/
@GetMapping("/getSecretKey")
public BaseResponse<String> getSecretKey(){
return fileService.getSecretKey();
}
}

View File

@ -160,8 +160,8 @@ public interface SysStorageService extends IService<SysStoragePO> {
Boolean saveCutover(List<SysStoragePO> sysStoragePOList);
// BaseResponse<Boolean> getDownload(String fileId, HttpServletResponse httpServletResponse, String documentSecretKey);
BaseResponse<Boolean> getDownload(String fileId, HttpServletResponse httpServletResponse, String documentSecretKey);
// BaseResponse<String> getSecretKey();
BaseResponse<String> getSecretKey();
}

View File

@ -1,8 +1,15 @@
package com.coscoshipping.ebtp.system.files.service.impl;
import com.amazonaws.ClientConfiguration;
import com.amazonaws.Protocol;
import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3Client;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.chinaunicom.mall.ebtp.common.base.entity.BaseResponse;
import com.chinaunicom.mall.ebtp.common.exception.entity.BusinessException;
import com.coscoshipping.ebtp.system.common.framework.enums.ResponseEnum;
import com.coscoshipping.ebtp.system.common.framework.response.BasePageResponse;
@ -20,25 +27,27 @@ import com.coscoshipping.ebtp.system.storage.common.StorageProperties;
import com.coscoshipping.ebtp.system.storage.entity.Storage;
import com.coscoshipping.ebtp.system.storage.service.StorageService;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.*;
import java.util.concurrent.TimeUnit;
/**
* <p>
@ -57,7 +66,8 @@ public class SysStorageServiceImpl extends ServiceImpl<SysStorageMapper, SysStor
private final StorageProperties properties;
@Resource
private SysStorageAnnexServiceImpl sysStorageAnnexService;
@Autowired
private RedisTemplate redisTemplate;
@Autowired
public SysStorageServiceImpl(StorageProperties properties) {
@ -658,4 +668,93 @@ public class SysStorageServiceImpl extends ServiceImpl<SysStorageMapper, SysStor
return null;
}
@Override
public BaseResponse<Boolean> getDownload(String fileId, HttpServletResponse httpServletResponse, String documentSecretKey) {
Object redisDocumentSecretKey = redisTemplate.opsForValue().get("documentSecretKey");
if (redisDocumentSecretKey==null ||!documentSecretKey.equals(redisDocumentSecretKey.toString())){
return new BaseResponse<Boolean>(0,false,"密钥不正确",false);
}
Set<String> keys = redisTemplate.keys("documentSecretKey");
if (CollectionUtils.isNotEmpty(keys)) {
this.redisTemplate.delete(keys);
}
SysStoragePO sysStoragePO = this.baseMapper.selectFileById(fileId);
if (sysStoragePO == null) {
return new BaseResponse<>(0, false, "fileId不存在", null);
}
try {
httpServletResponse.setHeader("Content-Disposition", "attachment;filename="
+ URLEncoder.encode(sysStoragePO.getOriginalName(), "utf-8")); //originalName:这个下载附件名字 比如abc.jpg
} catch (Exception e) {
e.printStackTrace();
}
if ("0".equals(sysStoragePO.getCutoverStatus()) && sysStoragePO.getLogoFilePath() != null) {
try {
URL url = new URL(sysStoragePO.getLogoFilePath());
InputStream inputStream = url.openStream();
ServletOutputStream outputStream = httpServletResponse.getOutputStream();
byte[] buffer = new byte[1024];
int length;
while ((length = inputStream.read(buffer)) > 0) {
outputStream.write(buffer, 0, length);
}
} catch (Exception e) {
e.printStackTrace();
return new BaseResponse<>(0, false, "下载割接附件失败", null);
}
}
try {
// 因自定义HTTPS证书问题忽略自定义证书报错指定系统变量可忽略此错误
System.setProperty("com.amazonaws.sdk.disableCertChecking", "true");
InputStream inputStream = initAmazonS3Object().getObject(properties.getBucketName(), sysStoragePO.getFilePath()).getObjectContent();
// InputStream inputStream = uniStorageManager.downloadFileAsStream(sysStoragePO.getFilePath());
ServletOutputStream outputStream = httpServletResponse.getOutputStream();
byte[] buffer = new byte[1024];
int length;
while ((length = inputStream.read(buffer)) > 0) {
outputStream.write(buffer, 0, length);
outputStream.flush();
}
outputStream.close();
} catch (Exception e) {
e.printStackTrace();
return new BaseResponse<>(0,false,"下载3.0附件失败",null);
}
return new BaseResponse<>(1,true,"下载附件成功",null);
}
@Override
public BaseResponse<String> getSecretKey() {
String ymd = System.currentTimeMillis() + UUID.randomUUID().toString();
try {
this.redisTemplate.opsForValue().set("documentSecretKey", ymd);
this.redisTemplate.expire("documentSecretKey", 60l, TimeUnit.SECONDS);
return new BaseResponse<String>(1, true, "获取密钥成功", ymd);
} catch (Exception e) {
e.printStackTrace();
}
return new BaseResponse<String>(0, false, "获取密钥失败,请稍后重试", null);
}
private AmazonS3 initAmazonS3Object() {
// 新建一个凭证
AWSCredentials credentials = new BasicAWSCredentials(properties.getAccessKey(), properties.getSecretKey());
ClientConfiguration clientConfig = new ClientConfiguration();
clientConfig.withProtocol(Protocol.HTTPS);
AmazonS3 amazonS3Client = new AmazonS3Client(credentials, clientConfig);
// 对象网关地址
amazonS3Client.setEndpoint(properties.getEndpoint());
return amazonS3Client;
}
}

View File

@ -120,7 +120,7 @@ public class BaseUserServiceImpl extends BaseServiceImpl<BaseUserMapper, SysUser
long startTime = System.currentTimeMillis();
String loginIp = getUserHost();
String userAgent = getUserAgent();
try {
List<SysUser> userList = this.list(new LambdaQueryWrapper<SysUser>().eq(SysUser::getEmployeeNumber, account)
@ -230,22 +230,18 @@ public class BaseUserServiceImpl extends BaseServiceImpl<BaseUserMapper, SysUser
long startTime = System.currentTimeMillis();
String loginIp = getUserHost();
String userAgent = getUserAgent();
try {
List<SysSupplierUser> userList = sysSupplierUserMapper
.selectList(new LambdaQueryWrapper<SysSupplierUser>().eq(SysSupplierUser::getUsername, account)
.eq(SysSupplierUser::getStatus, Integer.parseInt(Constants.USER_STATUS_LIVE)));
if (userList == null || userList.size() == 0) {
// 记录登录失败日志
sysLoginLogService.recordLoginFail(account, SysLoginLog.USER_TYPE_SUPPLIER, loginIp, "无效用户", userAgent);
throw new RuntimeException("无效用户!");
}
SysSupplierUser user = userList.get(0);
if (Constants.USER_STATUS_FREEZE.equals(user.getStatus().toString())) {
// 记录登录失败日志
sysLoginLogService.recordLoginFail(account, SysLoginLog.USER_TYPE_SUPPLIER, loginIp, "账号已冻结", userAgent);
throw new RuntimeException("账号已冻结!");
}
@ -254,8 +250,6 @@ public class BaseUserServiceImpl extends BaseServiceImpl<BaseUserMapper, SysUser
String pw = new String(decode);
if (!Md5Util.encode(pw).equals(user.getPassword())) {
// 记录登录失败日志
sysLoginLogService.recordLoginFail(account, SysLoginLog.USER_TYPE_SUPPLIER, loginIp, "用户名或密码错误", userAgent);
throw new RuntimeException("用户名或密码错误!");
}
@ -265,7 +259,7 @@ public class BaseUserServiceImpl extends BaseServiceImpl<BaseUserMapper, SysUser
// 首次登录需要强制修改密码,返回特殊状态
BaseSelf baseSelf = userSupplierLogin(user);
baseSelf.setFirstLogin(true); // 设置首次登录标识
// 记录首次登录日志
long loginTime = System.currentTimeMillis() - startTime;
sysLoginLogService.recordLoginSuccess(
@ -279,7 +273,7 @@ public class BaseUserServiceImpl extends BaseServiceImpl<BaseUserMapper, SysUser
userAgent,
true
);
return baseSelf;
}
@ -288,7 +282,15 @@ public class BaseUserServiceImpl extends BaseServiceImpl<BaseUserMapper, SysUser
sysSupplierUserMapper.updateById(user);
BaseSelf baseSelf = userSupplierLogin(user);
// 存入redis
// String token = baseSelf.getToken();
// userinfoRedisTemplate.opsForValue().set(
// REDIS_USER_KEY + token,
// baseCacheUser,
// Long.parseLong(valid_time_limit),
// TimeUnit.HOURS);
// 记录登录成功日志
long loginTime = System.currentTimeMillis() - startTime;
sysLoginLogService.recordLoginSuccess(
@ -302,18 +304,12 @@ public class BaseUserServiceImpl extends BaseServiceImpl<BaseUserMapper, SysUser
userAgent,
false
);
return baseSelf;
} catch (BadPaddingException e) {
// 记录登录失败日志
sysLoginLogService.recordLoginFail(account, SysLoginLog.USER_TYPE_SUPPLIER, loginIp, "RSA解密异常", userAgent);
log.error("RSA解密异常", e);
CommonExceptionEnum.FRAME_EXCEPTION_COMMON_DATA_OTHER_ERROR.customValidName("用户名或密码错误", true);
} catch (Exception e) {
// 记录登录失败日志
if (!e.getMessage().contains("无效用户") && !e.getMessage().contains("账号已冻结") && !e.getMessage().contains("用户名或密码错误")) {
sysLoginLogService.recordLoginFail(account, SysLoginLog.USER_TYPE_SUPPLIER, loginIp, e.getMessage(), userAgent);
}
log.error("登录异常", e);
CommonExceptionEnum.FRAME_EXCEPTION_COMMON_DATA_OTHER_ERROR.customValidName(e.getMessage(), true);
}
@ -326,7 +322,7 @@ public class BaseUserServiceImpl extends BaseServiceImpl<BaseUserMapper, SysUser
long startTime = System.currentTimeMillis();
String loginIp = getUserHost();
String userAgent = getUserAgent();
try {
List<SysExpertUser> userList = sysExpertUserMapper
@ -356,7 +352,7 @@ public class BaseUserServiceImpl extends BaseServiceImpl<BaseUserMapper, SysUser
}
BaseSelf baseSelf = userExpertLogin(user);
// 记录登录成功日志
long loginTime = System.currentTimeMillis() - startTime;
sysLoginLogService.recordLoginSuccess(
@ -370,7 +366,7 @@ public class BaseUserServiceImpl extends BaseServiceImpl<BaseUserMapper, SysUser
userAgent,
false
);
return baseSelf;
} catch (BadPaddingException e) {
// 记录登录失败日志

View File

@ -26,6 +26,12 @@ import com.coscoshipping.ebtp.system.user.entity.SysUser;
import com.coscoshipping.ebtp.system.user.service.SysUserService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.core.io.ClassPathResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import java.io.IOException;
@RestController
@Api(value = "门户用户表")
@ -173,4 +179,26 @@ public class SysUserController {
Boolean result = iSysUserService.syncIamUser(iamUser);
return BaseResponse.success(result);
}
/**
* 批量导入用户Excel
*/
@ApiOperation("批量导入用户Excel")
@PostMapping("/import")
public BaseResponse<Boolean> importUsers(@RequestParam("file") MultipartFile file) {
return BaseResponse.success(iSysUserService.importUsersFromExcel(file));
}
/**
* 下载用户导入模板
*/
@ApiOperation("下载用户导入模板")
@GetMapping("/downloadTemplate")
public ResponseEntity<ClassPathResource> downloadTemplate() throws IOException {
ClassPathResource resource = new ClassPathResource("template/user_import_template.xlsx");
return ResponseEntity.ok()
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=user_import_template.xlsx")
.contentType(MediaType.parseMediaType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"))
.body(resource);
}
}

View File

@ -0,0 +1,57 @@
package com.coscoshipping.ebtp.system.user.entity.dto;
import com.alibaba.excel.annotation.ExcelProperty;
public class SysUserExcelDTO {
@ExcelProperty("账号")
private String username;
@ExcelProperty("姓名")
private String realName;
@ExcelProperty("手机号")
private String phone;
@ExcelProperty("邮箱")
private String email;
@ExcelProperty("部门")
private String dept;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getRealName() {
return realName;
}
public void setRealName(String realName) {
this.realName = realName;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getDept() {
return dept;
}
public void setDept(String dept) {
this.dept = dept;
}
}

View File

@ -62,4 +62,11 @@ public interface SysUserService extends IBaseService<SysUser> {
* @return 是否成功
*/
Boolean syncIamUser(com.coscoshipping.ebtp.system.user.entity.IamApiUser iamUser);
/**
* 批量导入用户Excel
* @param file Excel文件
* @return 是否成功
*/
Boolean importUsersFromExcel(org.springframework.web.multipart.MultipartFile file);
}

View File

@ -13,6 +13,7 @@ import com.coscoshipping.ebtp.system.org.service.SysOrgService;
import com.coscoshipping.ebtp.system.role.entity.SysRole;
import com.coscoshipping.ebtp.system.role.entity.vo.AllRolesAndAssignRoleVO;
import com.coscoshipping.ebtp.system.user.entity.dto.SysInnerUserInfo;
import com.coscoshipping.ebtp.system.user.entity.dto.SysUserExcelDTO;
import com.coscoshipping.ebtp.system.user.entity.vo.SysUserVO;
import com.coscoshipping.ebtp.system.user.util.Md5Util;
import com.coscoshipping.ebtp.system.userrole.service.SysUserRoleService;
@ -25,6 +26,12 @@ import com.chinaunicom.mall.ebtp.common.util.PropertyUtils;
import com.coscoshipping.ebtp.system.user.dao.SysUserMapper;
import com.coscoshipping.ebtp.system.user.entity.SysUser;
import com.coscoshipping.ebtp.system.user.service.SysUserService;
import org.springframework.web.multipart.MultipartFile;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.support.ExcelTypeEnum;
import java.util.ArrayList;
import java.time.LocalDateTime;
import java.util.List;
@ -159,6 +166,42 @@ public class SysUserServiceImpl extends BaseServiceImpl<SysUserMapper, SysUser>
}
}
@Override
public Boolean importUsersFromExcel(MultipartFile file) {
try {
String filename = file.getOriginalFilename();
ExcelTypeEnum excelTypeEnum = com.alibaba.excel.support.ExcelTypeEnum.XLSX;
if (filename != null && filename.toLowerCase().endsWith(".xlsx")) {
excelTypeEnum = ExcelTypeEnum.XLSX;
}
List<SysUserExcelDTO> userList = com.alibaba.excel.EasyExcel.read(file.getInputStream(), SysUserExcelDTO.class, null)
.excelType(excelTypeEnum)
.sheet()
.doReadSync();
List<SysUser> saveList = new ArrayList<>();
for (SysUserExcelDTO dto : userList) {
if (dto.getUsername() == null || dto.getUsername().trim().isEmpty()) continue;
SysUser user = new SysUser();
user.setUserId(PropertyUtils.getSnowflakeId());
user.setName(dto.getRealName());
user.setDisplayName(dto.getRealName());
user.setMobile(dto.getPhone());
user.setEmail(dto.getEmail());
user.setOrgId(dto.getDept());
user.setStatus(1);
user.setEmployeeNumber(dto.getUsername());
user.setPassword(Md5Util.encode(resetPassword));
saveList.add(user);
}
this.saveBatch(saveList);
return true;
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("导入失败: " + e.getMessage());
}
}
/**
* 保存前的数据校验
*/

Binary file not shown.