BUGFIX:1、教育通过上传文件批量创建子账号没有任何校验
2、下载子账号所有信息接口缺失(原下载模板接口保留) 3、保存个人模特到collection时类型设置为System 4、创建子账号时设置积分无效
This commit is contained in:
@@ -369,6 +369,12 @@ public class AccountController {
|
||||
accountService.subAccountImportExcelDownload(response);
|
||||
}
|
||||
|
||||
@GetMapping("/exportAccountsToExcel")
|
||||
@ApiOperation(value = "下载子账号信息")
|
||||
public void exportAccountsToExcel(HttpServletResponse response) {
|
||||
accountService.exportAccountsToExcel(response);
|
||||
}
|
||||
|
||||
@PostMapping("/subAccountImport")
|
||||
@ApiOperation(value = "模板导入")
|
||||
public Response<Boolean> subAccountImport(@RequestParam("file") MultipartFile file) {
|
||||
|
||||
@@ -19,4 +19,6 @@ public class GetNextSysElementVO {
|
||||
@ApiModelProperty("对应的图片的绝对路径")
|
||||
private String path;
|
||||
|
||||
public GetNextSysElementVO() {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -233,6 +233,8 @@ public interface AccountService extends IService<Account> {
|
||||
|
||||
void subAccountImportExcelDownload(HttpServletResponse response);
|
||||
|
||||
void exportAccountsToExcel(HttpServletResponse response);
|
||||
|
||||
Boolean subAccountImport(MultipartFile file);
|
||||
|
||||
Set<String> organizationNameSearch(String type, String name);
|
||||
|
||||
@@ -39,6 +39,8 @@ import com.zaxxer.hikari.HikariDataSource;
|
||||
import io.netty.util.internal.StringUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.poi.ss.usermodel.*;
|
||||
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.stereotype.Service;
|
||||
@@ -2162,7 +2164,7 @@ public class AccountServiceImpl extends ServiceImpl<AccountMapper, Account> impl
|
||||
int subUserRole = getSubUserRole(account.getSystemUser());
|
||||
|
||||
if (addSubAccountDTO.getId() == null) {
|
||||
return createSubAccount(addSubAccountDTO, account, subUserRole, null, null);
|
||||
return createSubAccount(addSubAccountDTO, account, subUserRole, addSubAccountDTO.getCreditsUsageLimit(), null);
|
||||
} else {
|
||||
return updateSubAccount(addSubAccountDTO, account, subUserRole);
|
||||
}
|
||||
@@ -3056,6 +3058,88 @@ public class AccountServiceImpl extends ServiceImpl<AccountMapper, Account> impl
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exportAccountsToExcel(HttpServletResponse response) {
|
||||
Workbook workbook = null;
|
||||
try {
|
||||
// 1. 查询数据
|
||||
Account adminAcc = baseMapper.selectById(UserContext.getUserHolder().getId());
|
||||
List<Account> accounts = accountMapper.selectList(new QueryWrapper<Account>()
|
||||
.eq("organization_name", adminAcc.getOrganizationName())
|
||||
.eq("system_user", 8)
|
||||
.select("user_name", "user_email", "user_password", "credits_usage_limit"));
|
||||
|
||||
// 2. 创建Excel工作簿
|
||||
workbook = new XSSFWorkbook();
|
||||
Sheet sheet = workbook.createSheet("subAccounts");
|
||||
|
||||
// 3. 创建标题行
|
||||
Row headerRow = sheet.createRow(0);
|
||||
String[] headers = {"name", "email", "password", "creditsUsageLimit"};
|
||||
|
||||
// 设置标题样式
|
||||
CellStyle headerStyle = workbook.createCellStyle();
|
||||
Font headerFont = workbook.createFont();
|
||||
headerFont.setBold(true);
|
||||
headerStyle.setFont(headerFont);
|
||||
|
||||
// 写入标题
|
||||
for (int i = 0; i < headers.length; i++) {
|
||||
Cell cell = headerRow.createCell(i);
|
||||
cell.setCellValue(headers[i]);
|
||||
cell.setCellStyle(headerStyle);
|
||||
}
|
||||
|
||||
// 4. 写入数据
|
||||
int rowNum = 1;
|
||||
for (Account account : accounts) {
|
||||
Row row = sheet.createRow(rowNum++);
|
||||
row.createCell(0).setCellValue(account.getUserName() != null ? account.getUserName() : "");
|
||||
row.createCell(1).setCellValue(account.getUserEmail() != null ? account.getUserEmail() : "");
|
||||
row.createCell(2).setCellValue(account.getUserPassword() != null ? account.getUserPassword() : "");
|
||||
|
||||
// 更安全的数据类型处理
|
||||
if (account.getCreditsUsageLimit() != null) {
|
||||
row.createCell(3).setCellValue(String.valueOf(account.getCreditsUsageLimit()));
|
||||
} else {
|
||||
row.createCell(3).setCellValue(""); // 空字符串
|
||||
}
|
||||
}
|
||||
|
||||
// 5. 自动调整列宽
|
||||
for (int i = 0; i < headers.length; i++) {
|
||||
sheet.autoSizeColumn(i);
|
||||
}
|
||||
|
||||
// 6. 重置响应(重要!)
|
||||
response.reset();
|
||||
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
|
||||
response.setCharacterEncoding("UTF-8");
|
||||
|
||||
// 设置文件名(处理特殊字符)
|
||||
String fileName = "subAccount_export.xlsx";
|
||||
String encodedFileName = URLEncoder.encode(fileName, "UTF-8").replace("+", "%20");
|
||||
response.setHeader("Content-Disposition", "attachment; filename*=UTF-8''" + encodedFileName);
|
||||
|
||||
// 7. 写入响应流
|
||||
OutputStream outputStream = response.getOutputStream();
|
||||
workbook.write(outputStream);
|
||||
outputStream.flush();
|
||||
} catch (IOException e) {
|
||||
log.error(e.getMessage()); // 记录异常信息
|
||||
throw new BusinessException("导出文件失败");
|
||||
} finally {
|
||||
// 确保资源关闭
|
||||
if (workbook != null) {
|
||||
try {
|
||||
workbook.close();
|
||||
} catch (IOException e) {
|
||||
log.error(e.getMessage()); // 记录异常信息
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean subAccountImport(MultipartFile file) {
|
||||
AuthPrincipalVo vo = UserContext.getUserHolder();
|
||||
@@ -3069,29 +3153,24 @@ public class AccountServiceImpl extends ServiceImpl<AccountMapper, Account> impl
|
||||
|
||||
// 示例:打印或保存
|
||||
for (SubAccountImportDTO dto : importList) {
|
||||
// 只有当前子账号数量为0时允许批量上传
|
||||
QueryWrapper<Account> qw = new QueryWrapper<>();
|
||||
qw.lambda().eq(Account::getSystemUser, 8)
|
||||
.eq(Account::getOrganizationName, parent.getOrganizationName());
|
||||
List<Account> accounts = accountMapper.selectList(qw);
|
||||
if (!accounts.isEmpty()){
|
||||
throw new BusinessException("permit.bulk.creation", ResultEnum.PROMPT.getCode());
|
||||
}
|
||||
if (importList.size() > parent.getSubAccountNum() - 1){
|
||||
throw new BusinessException("Action required: You cannot create [" +importList.size() + "] sub-accounts (Current quota: [" + (parent.getSubAccountNum() - 1) + "]).");
|
||||
}
|
||||
|
||||
Account account = new Account();
|
||||
account.setUserName(dto.getName());
|
||||
account.setUserEmail(dto.getEmail());
|
||||
account.setUserPassword(md5(dto.getPassword() + "abc"));
|
||||
account.setCreditsUsageLimit(BigDecimal.valueOf(dto.getCredisUsageLimit()));
|
||||
account.setParentId(vo.getId());
|
||||
account.setValidStartTime(parent.getValidStartTime());
|
||||
account.setValidEndTime(parent.getValidEndTime());
|
||||
account.setCreateDate(new Date());
|
||||
account.setIsTrial(0);
|
||||
account.setIsBeginner(1);
|
||||
account.setCredits(BigDecimal.valueOf(0));
|
||||
account.setLanguage(Language.ENGLISH.name());
|
||||
if (parent.getSystemUser() == 5) {
|
||||
account.setSystemUser(6);
|
||||
}
|
||||
if (parent.getSystemUser() == 7) {
|
||||
account.setSystemUser(8);
|
||||
}
|
||||
account.setOrganizationName(parent.getOrganizationName());
|
||||
account.setParentId(parent.getId());
|
||||
accountMapper.insert(account);
|
||||
AddSubAccountDTO addSubAccountDTO = new AddSubAccountDTO();
|
||||
addSubAccountDTO.setUserEmail(dto.getEmail());
|
||||
addSubAccountDTO.setUserName(dto.getEmail().substring(0, dto.getEmail().indexOf("@")));
|
||||
addSubAccountDTO.setUserPassword(md5(parent.getOrganizationName().toLowerCase() + "abc"));
|
||||
// 添加用户
|
||||
addSubAccount(addSubAccountDTO);
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -3104,7 +3183,7 @@ public class AccountServiceImpl extends ServiceImpl<AccountMapper, Account> impl
|
||||
public static String md5(String input) {
|
||||
try {
|
||||
MessageDigest md = MessageDigest.getInstance("MD5");
|
||||
byte[] messageDigest = md.digest(input.getBytes());
|
||||
byte[] messageDigest = md.digest(input.getBytes(StandardCharsets.UTF_8));
|
||||
|
||||
// 转为16进制字符串
|
||||
StringBuilder sb = new StringBuilder();
|
||||
@@ -3113,7 +3192,7 @@ public class AccountServiceImpl extends ServiceImpl<AccountMapper, Account> impl
|
||||
if (hex.length() == 1) sb.append('0'); // 补0
|
||||
sb.append(hex);
|
||||
}
|
||||
return sb.append("abc").toString();
|
||||
return sb.toString();
|
||||
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
throw new RuntimeException("MD5算法不可用", e);
|
||||
|
||||
@@ -625,6 +625,10 @@ public class CollectionElementServiceImpl extends ServiceImpl<CollectionElementM
|
||||
for (MannequinDTO mannequin : designDTO.getMannequins()) {
|
||||
if (mannequin.getType().equals("System")) {
|
||||
SysFileVO byId = sysFileService.getById(mannequin.getId());
|
||||
if (Objects.isNull(byId)){
|
||||
log.info("未知模特:{}:{}", mannequin.getId(), "System");
|
||||
throw new BusinessException("model.not.found");
|
||||
}
|
||||
// if (!StringUtils.isEmpty(byId.getLevel3Type()) && byId.getLevel2Type().equals("Female")) {
|
||||
// elementVO.setStyle(byId.getLevel3Type());
|
||||
// }
|
||||
@@ -645,7 +649,7 @@ public class CollectionElementServiceImpl extends ServiceImpl<CollectionElementM
|
||||
elementVO.setDesignLibraryModelPoint(calculateTemplatePointTemplate(modelPoint, byId.getHigh(), byId.getWidth(), byId.getUrl()));
|
||||
} else if (designDTO.getModelType().equals(ModelType.SYSTEM.getValue())) {
|
||||
SysFileVO byId = sysFileService.getById(designDTO.getTemplateId());
|
||||
if (!StringUtils.isEmpty(byId.getLevel3Type()) && byId.getLevel2Type().equals("Female")) {
|
||||
if (Objects.nonNull(byId) && !StringUtils.isEmpty(byId.getLevel3Type()) && byId.getLevel2Type().equals("Female")) {
|
||||
elementVO.setStyle(byId.getLevel3Type());
|
||||
}
|
||||
LibraryModelPoint modelPoint = libraryModelPointService.getByRelationId(byId.getId(), designDTO.getModelType());
|
||||
|
||||
@@ -178,7 +178,11 @@ public class DesignItemServiceImpl extends ServiceImpl<DesignItemMapper, DesignI
|
||||
}
|
||||
}
|
||||
SysFileVO sysFileVO = sysFileService.getById(idValue);
|
||||
return new GetNextSysElementVO(sysFileVO.getId(), level2Type, sysFileVO.getUrl());
|
||||
if (Objects.nonNull(sysFileVO)){
|
||||
return new GetNextSysElementVO(sysFileVO.getId(), level2Type, sysFileVO.getUrl());
|
||||
}else {
|
||||
return new GetNextSysElementVO();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1846,11 +1846,17 @@ public class GenerateServiceImpl extends ServiceImpl<GenerateMapper, Generate> i
|
||||
// 所有修改的图片都另存为,不覆盖原图
|
||||
if (proportionDTO.getType().equals("Library")) {
|
||||
model = libraryService.getById(proportionDTO.getId());
|
||||
if (Objects.isNull(model)){
|
||||
throw new BusinessException("model.not.found");
|
||||
}
|
||||
String url = model.getUrl();
|
||||
name = url.substring(url.indexOf("/") + 1, url.lastIndexOf("/")) + "/" + uuid;
|
||||
// gender = model.getLevel2Type();
|
||||
} else {
|
||||
SysFileVO sysModel = sysFileService.getById(proportionDTO.getId());
|
||||
if (Objects.isNull(sysModel)){
|
||||
throw new BusinessException("model.not.found");
|
||||
}
|
||||
gender = sysModel.getLevel2Type();
|
||||
name = accountId + "/models/" + gender.toLowerCase() + "/" + uuid;
|
||||
}
|
||||
|
||||
@@ -214,9 +214,12 @@ public class SysFileServiceImpl extends ServiceImpl<SysFileMapper, SysFile> impl
|
||||
SysFileVO sysFile = LocalCacheUtils.getSysFileCache(id);
|
||||
if (Objects.isNull(sysFile) || Objects.isNull(sysFile.getId())) {
|
||||
sysFile = CopyUtil.copyObject(sysFileMapper.selectById(id), SysFileVO.class);
|
||||
LocalCacheUtils.setSysFileCache(id, sysFile);
|
||||
if (Objects.nonNull(sysFile)){
|
||||
LocalCacheUtils.setSysFileCache(id, sysFile);
|
||||
return sysFile;
|
||||
}
|
||||
}
|
||||
return sysFile;
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -2642,7 +2642,7 @@ public class UserLikeGroupServiceImpl extends ServiceImpl<UserLikeGroupMapper, U
|
||||
CollectionElementRelModel collectionElementRelModel = new CollectionElementRelModel();
|
||||
collectionElementRelModel.setCollectionElementId(collectionElement.getId());
|
||||
collectionElementRelModel.setRelationId(dto.getId());
|
||||
collectionElementRelModel.setRelationType("System");
|
||||
collectionElementRelModel.setRelationType("Library");
|
||||
collectionElementRelModelMapper.insert(collectionElementRelModel);
|
||||
|
||||
}
|
||||
|
||||
@@ -158,6 +158,7 @@ this.promotion.code.is.invalid=This promotion code is invalid.
|
||||
one.time.limit.per.customer=This code has already been redeemed. Promo codes are limited to one-time use per customer.
|
||||
element.already.exists=This element already exists in the public library
|
||||
have.no.permission=Sorry, you don't have permission
|
||||
permit.bulk.creation=The system permits bulk account creation exclusively when no sub-accounts exist.
|
||||
|
||||
# 可能会报异常
|
||||
# Informative:
|
||||
|
||||
@@ -154,6 +154,7 @@ this.promotion.code.is.invalid=该促销码无效。
|
||||
one.time.limit.per.customer=该码已兑换。每个促销码每位用户仅限使用一次。
|
||||
element.already.exists=元素已存在于公共库中
|
||||
have.no.permission=您没有权限
|
||||
permit.bulk.creation=系统仅当不存在任何子账号时,才允许批量创建账号。
|
||||
|
||||
# 可能会报异常
|
||||
# Informative:
|
||||
|
||||
Reference in New Issue
Block a user