feat: 用户启停/注销、机构账号查询、手机号查记录、机构上传配置
1. 用户管理:新增启用(user/enable)/禁用(user/disable)/注销(user/admin_cancel)接口,
平台超管可操作全部用户,机构管理员限本机构;注销带分布式锁、禁自己/超管守卫
2. 禁用/注销立即踢下线:Redis黑名单(user:disabled:{uid}) + JWT过滤器拦截,
TTL与token有效期一致
3. 系统管理员查看各机构账号:GET user/page/org_account(机构/账号/手机号等筛选)
4. 按手机号查上传/发送/接收记录:GET user_file/record/page_by_phone,
发送/接收方向按部署侧 file.transfer.location 自动映射
5. 机构上传配置:新表 x_upload_config + upload_config/info|modify|check 接口,
上传总开关/后缀白名单/单文件大小限制,网盘落库时强制校验
6. 加固:UserInfoDTO.setPassword 缺省密码未配置时不再抛 rawPassword cannot be null
7. 新增 x_upload_config 建表脚本(upgrade-20260915-release.sql 为上线版)、
生产部署说明、前端接口文档×2、运维脚本 sfile-ctl.sh、AGENTS.md
This commit is contained in:
@@ -4,8 +4,11 @@ import com.senmesh.common.constant.CommonConstants;
|
||||
import com.senmesh.common.exception.util.Assert;
|
||||
import com.senmesh.common.util.ListUtil;
|
||||
import com.senmesh.common.util.UserContextHolder;
|
||||
import com.senmesh.component.file.config.FileProperties;
|
||||
import com.senmesh.component.file.service.FileService;
|
||||
import com.senmesh.component.file.util.FileUtils;
|
||||
import com.senmesh.sfile.constant.FileLocationEnum;
|
||||
import com.senmesh.sfile.constant.FileRecordTypeEnum;
|
||||
import com.senmesh.sfile.constant.FileStatusEnum;
|
||||
import com.senmesh.sfile.constant.FileTypeEnum;
|
||||
import com.senmesh.sfile.constant.RootTypeEnum;
|
||||
@@ -18,9 +21,12 @@ import com.senmesh.sfile.dto.UserFileDTO;
|
||||
import com.senmesh.sfile.dto.UserFileModifyDTO;
|
||||
import com.senmesh.sfile.dto.UserFileModifyStatusDTO;
|
||||
import com.senmesh.sfile.dto.UserFileQueryDTO;
|
||||
import com.senmesh.sfile.dto.UserFileRecordDTO;
|
||||
import com.senmesh.sfile.dto.UserFileRecordQueryDTO;
|
||||
import com.senmesh.sfile.dto.UserFileStatisticsDTO;
|
||||
import com.senmesh.sfile.entity.UserFile;
|
||||
import com.senmesh.sfile.service.UserFileService;
|
||||
import com.google.common.collect.Sets;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -30,9 +36,11 @@ import org.springframework.transaction.annotation.Transactional;
|
||||
import java.io.InputStream;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 用户文件ServiceImpl
|
||||
@@ -47,6 +55,9 @@ public class UserFileServiceImpl implements UserFileService {
|
||||
@Autowired
|
||||
private FileService fileService;
|
||||
|
||||
@Autowired
|
||||
private FileProperties fileProperties;
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public UserFileDTO create(UserFileCreateDTO createDTO) {
|
||||
@@ -346,5 +357,85 @@ public class UserFileServiceImpl implements UserFileService {
|
||||
queryDTO.disablePage();
|
||||
return userFileMapper.statisticsByCategory(queryDTO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pageRecordByPhone(UserFileRecordQueryDTO queryDTO) {
|
||||
Assert.isTrue(UserContextHolder.isSuperior(), "当前用户无操作权限");
|
||||
Assert.notBlank(queryDTO.getPhone(), "手机号不能为空");
|
||||
queryDTO.setPhone(queryDTO.getPhone().trim());
|
||||
if (queryDTO.getRecordType() != null) {
|
||||
Assert.notNull(FileRecordTypeEnum.getByType(queryDTO.getRecordType()),
|
||||
"记录类型不合法,仅支持1上传/2发送/3接收");
|
||||
}
|
||||
queryDTO.setRootTypeIn(resolveRootTypes(queryDTO.getRecordType()));
|
||||
List<UserFileRecordDTO> records = userFileMapper.listRecordByPhone(queryDTO);
|
||||
fillRecordType(records);
|
||||
}
|
||||
|
||||
/**
|
||||
* 记录类型 -> root_type 条件
|
||||
* 上传记录固定为普通(1);发送/接收方向与本端部署位置有关:
|
||||
* 内网侧发送为内穿外(2)、接收为外传内(3);外网侧相反
|
||||
*
|
||||
* @param recordType 记录类型,为空查全部
|
||||
*/
|
||||
private Set<String> resolveRootTypes(Integer recordType) {
|
||||
if (recordType == null) {
|
||||
return Sets.newHashSet(RootTypeEnum.NORMAL.getType(), getSendRootType(), getReceiveRootType());
|
||||
}
|
||||
switch (FileRecordTypeEnum.getByType(recordType)) {
|
||||
case UPLOAD:
|
||||
return Collections.singleton(RootTypeEnum.NORMAL.getType());
|
||||
case SEND:
|
||||
return Collections.singleton(getSendRootType());
|
||||
case RECEIVE:
|
||||
return Collections.singleton(getReceiveRootType());
|
||||
default:
|
||||
return resolveRootTypes(null);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 本端发送方向:内网侧为内穿外(2),外网侧为外传内(3),与TransferUserFileServiceImpl保持一致
|
||||
*/
|
||||
private String getSendRootType() {
|
||||
return FileLocationEnum.isInternal(fileProperties.getTransfer().getLocation())
|
||||
? RootTypeEnum.INTERNAL_TO_EXTERNAL.getType()
|
||||
: RootTypeEnum.EXTERNAL_TO_INTERNAL.getType();
|
||||
}
|
||||
|
||||
/**
|
||||
* 本端接收方向:内网侧为外传内(3),外网侧为内穿外(2),与TransferFileMonitorServiceImpl保持一致
|
||||
*/
|
||||
private String getReceiveRootType() {
|
||||
return FileLocationEnum.isInternal(fileProperties.getTransfer().getLocation())
|
||||
? RootTypeEnum.EXTERNAL_TO_INTERNAL.getType()
|
||||
: RootTypeEnum.INTERNAL_TO_EXTERNAL.getType();
|
||||
}
|
||||
|
||||
/**
|
||||
* 按本端部署位置回填记录类型与描述
|
||||
*/
|
||||
private void fillRecordType(List<UserFileRecordDTO> records) {
|
||||
if (records == null || records.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
for (UserFileRecordDTO record : records) {
|
||||
String rootType = record.getRootType();
|
||||
if (RootTypeEnum.NORMAL.getType().equals(rootType)) {
|
||||
record.setRecordType(FileRecordTypeEnum.UPLOAD.getType());
|
||||
} else if (getSendRootType().equals(rootType)) {
|
||||
record.setRecordType(FileRecordTypeEnum.SEND.getType());
|
||||
} else if (getReceiveRootType().equals(rootType)) {
|
||||
record.setRecordType(FileRecordTypeEnum.RECEIVE.getType());
|
||||
}
|
||||
if (record.getRecordType() != null) {
|
||||
record.setRecordTypeDesc(FileRecordTypeEnum.getByType(record.getRecordType()).getDesc());
|
||||
} else {
|
||||
RootTypeEnum rootTypeEnum = RootTypeEnum.getByType(rootType);
|
||||
record.setRecordTypeDesc(rootTypeEnum == null ? rootType : rootTypeEnum.getDesc());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user