Merge branch 'main' of http://192.168.65.198:3000/toolchaintechnologycenter/spdm-backend
This commit is contained in:
@@ -38,7 +38,7 @@ public class CIDUserResp implements Serializable{
|
||||
private String email;
|
||||
|
||||
@Schema(description = "用户状态(0-正常,1-冻结;默认值为0,确保新用户默认正常)")
|
||||
private Boolean status;
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "身份证号(18位,符合身份证格式,可选,建议唯一)")
|
||||
private String idCard;
|
||||
@@ -56,10 +56,10 @@ public class CIDUserResp implements Serializable{
|
||||
private LocalDate birthDate;
|
||||
|
||||
@Schema(description = "性别(0-未知,1-男性,2-女性;默认值为0)")
|
||||
private Boolean sex;
|
||||
private Integer sex;
|
||||
|
||||
@Schema(description = "是否有员工账号(0-无,1-有;布尔类型映射为tinyint,默认0)")
|
||||
private Boolean noSysStaff;
|
||||
private Integer noSysStaff;
|
||||
|
||||
@Schema(description = "用户所属租户ID(多租户场景下的租户标识,可选)")
|
||||
private Long tenantId;
|
||||
|
||||
@@ -5,6 +5,7 @@ import com.sdm.data.model.req.*;
|
||||
import com.sdm.data.service.IModelService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
@@ -14,7 +15,8 @@ import java.io.IOException;
|
||||
* 模型训练控制器
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/modelTraning")
|
||||
@RequestMapping("/modelTraining")
|
||||
@Tag(name = "模型训练")
|
||||
public class ModelTraningController {
|
||||
@Autowired
|
||||
private IModelService modelService;
|
||||
@@ -28,6 +30,41 @@ public class ModelTraningController {
|
||||
return modelService.addModel(addModelReq);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除模型
|
||||
*/
|
||||
@GetMapping("/deleteModel")
|
||||
@Operation(summary = "删除模型", description = "删除模型")
|
||||
public SdmResponse deleteModel(@RequestParam Integer modelId) {
|
||||
return modelService.deleteModel(modelId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取模型列表
|
||||
*/
|
||||
@PostMapping("/getModelList")
|
||||
@Operation(summary = "获取模型列表", description = "获取模型列表")
|
||||
public SdmResponse getModelList(@RequestBody BaseReq baseReq) {
|
||||
return modelService.getModelList(baseReq);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取模型详情
|
||||
*/
|
||||
@GetMapping("/getModelDetail")
|
||||
@Operation(summary = "获取模型详情", description = "获取模型详情")
|
||||
public SdmResponse getModelDetail(@RequestParam Integer modelId) {
|
||||
return modelService.getModelDetail(modelId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改模型
|
||||
*/
|
||||
@PostMapping("/updateModel")
|
||||
@Operation(summary = "修改模型", description = "修改模型")
|
||||
public SdmResponse updateModel(@RequestBody AddModelReq addModelReq) {
|
||||
return modelService.updateModel(addModelReq);
|
||||
}
|
||||
/**
|
||||
* 调用python脚本处理导入数据
|
||||
*
|
||||
@@ -74,6 +111,15 @@ public class ModelTraningController {
|
||||
return modelService.submitTraining(algorithmParamReq);
|
||||
}
|
||||
|
||||
/**
|
||||
* 停止模型训练
|
||||
*/
|
||||
@GetMapping("/stopTraining")
|
||||
@Operation(summary = "停止模型训练", description = "停止模型训练")
|
||||
public SdmResponse stopTraining(@RequestParam Integer modelId) {
|
||||
return modelService.stopTraining(modelId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取训练曲线和训练日志
|
||||
*
|
||||
|
||||
@@ -8,6 +8,9 @@ import java.time.LocalDateTime;
|
||||
|
||||
@Data
|
||||
public class AddModelReq {
|
||||
@Schema(description = "模型ID")
|
||||
private Integer modelId;
|
||||
|
||||
@Schema(description = "模型名称")
|
||||
private String modelName;
|
||||
|
||||
|
||||
@@ -12,6 +12,26 @@ public interface IModelService {
|
||||
*/
|
||||
SdmResponse addModel(AddModelReq addModelReq);
|
||||
|
||||
/**
|
||||
* 删除模型
|
||||
*/
|
||||
SdmResponse deleteModel(Integer modelId);
|
||||
|
||||
/**
|
||||
* 获取模型列表
|
||||
*/
|
||||
SdmResponse getModelList(BaseReq baseReq);
|
||||
|
||||
/**
|
||||
* 获取模型详情
|
||||
*/
|
||||
SdmResponse getModelDetail(Integer modelId);
|
||||
|
||||
/**
|
||||
* 修改模型
|
||||
*/
|
||||
SdmResponse updateModel(AddModelReq addModelReq);
|
||||
|
||||
/**
|
||||
* 调用python脚本处理导入数据
|
||||
*/
|
||||
@@ -38,6 +58,13 @@ public interface IModelService {
|
||||
*/
|
||||
SdmResponse submitTraining(AlgorithmParamReq algorithmParamReq);
|
||||
|
||||
/**
|
||||
* 停止模型训练
|
||||
* @param modelId 模型ID
|
||||
* @return 模型训练结果
|
||||
*/
|
||||
SdmResponse stopTraining(Integer modelId);
|
||||
|
||||
/**
|
||||
* 模型训练结果查询
|
||||
* @param modelId 模型ID
|
||||
|
||||
@@ -2,7 +2,10 @@ package com.sdm.data.service.impl;
|
||||
|
||||
import com.alibaba.fastjson2.JSONArray;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.github.pagehelper.PageHelper;
|
||||
import com.github.pagehelper.PageInfo;
|
||||
import com.sdm.common.common.SdmResponse;
|
||||
import com.sdm.common.utils.PageUtils;
|
||||
import com.sdm.data.model.entity.FileMetadataInfo;
|
||||
import com.sdm.data.model.entity.TrainingModel;
|
||||
import com.sdm.data.model.entity.TrainingModelAlgorithmParam;
|
||||
@@ -22,7 +25,9 @@ import java.io.OutputStream;
|
||||
import java.nio.file.Files;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
@Service
|
||||
@Slf4j
|
||||
@@ -100,6 +105,8 @@ public class ModelServiceImpl implements IModelService {
|
||||
*/
|
||||
private static final String PYTHON_SCRIPT_PARAM_FILE_NAME = "param.json";
|
||||
|
||||
// 用于存储正在运行的训练进程
|
||||
private final Map<Integer, Process> runningProcesses = new ConcurrentHashMap<>();
|
||||
|
||||
@Autowired
|
||||
IDataFileService dataFileService;
|
||||
@@ -133,6 +140,41 @@ public class ModelServiceImpl implements IModelService {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public SdmResponse deleteModel(Integer modelId) {
|
||||
// 删除 training_model 和 training_model_algorithm_param 表数据
|
||||
trainingModelService.removeById(modelId);
|
||||
trainingModelAlgorithmParamService.lambdaUpdate().eq(TrainingModelAlgorithmParam::getModelId, modelId).remove();
|
||||
return SdmResponse.success("删除训练模型成功");
|
||||
}
|
||||
|
||||
@Override
|
||||
public SdmResponse getModelList(BaseReq baseReq) {
|
||||
PageHelper.startPage(baseReq.getCurrent(), baseReq.getSize());
|
||||
List<TrainingModel> models = trainingModelService.list();
|
||||
PageInfo<TrainingModel> page = new PageInfo<>(models);
|
||||
return PageUtils.getJsonObjectSdmResponse(models,page);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SdmResponse getModelDetail(Integer modelId) {
|
||||
TrainingModel model = trainingModelService.getById(modelId);
|
||||
if (model != null) {
|
||||
return SdmResponse.success(model);
|
||||
}
|
||||
return SdmResponse.success();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SdmResponse updateModel(AddModelReq addModelReq) {
|
||||
trainingModelService.lambdaUpdate()
|
||||
.set(TrainingModel::getModelName, addModelReq.getModelName())
|
||||
.set(TrainingModel::getDescription, addModelReq.getDescription())
|
||||
.eq(TrainingModel::getId, addModelReq.getModelId()).update();
|
||||
return SdmResponse.success("更新训练模型成功");
|
||||
}
|
||||
|
||||
@Override
|
||||
public SdmResponse<String> handleLoadData(HandleLoadDataReq handleLoadDataReq) {
|
||||
try {
|
||||
@@ -489,50 +531,49 @@ public class ModelServiceImpl implements IModelService {
|
||||
}
|
||||
}
|
||||
|
||||
private void callPythonScript(String pythonScriptPath, String paramJsonPath) {
|
||||
try {
|
||||
// 直接拼接完整命令(注意空格分隔)
|
||||
String command = String.format(
|
||||
"python %s --param %s",
|
||||
pythonScriptPath,
|
||||
paramJsonPath
|
||||
);
|
||||
private Process callPythonScript(String pythonScriptPath, String paramJsonPath) throws Exception {
|
||||
// 直接拼接完整命令(注意空格分隔)
|
||||
String command = String.format(
|
||||
"python %s --param %s",
|
||||
pythonScriptPath,
|
||||
paramJsonPath
|
||||
);
|
||||
|
||||
// 打印执行的命令(便于调试)
|
||||
log.info("执行的Python命令: {}", command);
|
||||
// 打印执行的命令(便于调试)
|
||||
log.info("执行的Python命令: {}", command);
|
||||
|
||||
// 使用Runtime执行命令
|
||||
Process process = Runtime.getRuntime().exec(command);
|
||||
|
||||
// 读取输出流
|
||||
// 使用Runtime执行命令
|
||||
Process process = Runtime.getRuntime().exec(command);
|
||||
|
||||
// 异步读取输出流,避免阻塞
|
||||
Thread outputThread = new Thread(() -> {
|
||||
try (BufferedReader reader = new BufferedReader(
|
||||
new InputStreamReader(process.getInputStream()))) {
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
log.info("Python脚本输出: {}", line);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
log.error("读取Python脚本输出异常", e);
|
||||
}
|
||||
|
||||
// 读取错误流(单独处理错误输出,避免阻塞)
|
||||
});
|
||||
outputThread.start();
|
||||
|
||||
// 异步读取错误流,避免阻塞
|
||||
Thread errorThread = new Thread(() -> {
|
||||
try (BufferedReader errorReader = new BufferedReader(
|
||||
new InputStreamReader(process.getErrorStream()))) {
|
||||
String errorLine;
|
||||
while ((errorLine = errorReader.readLine()) != null) {
|
||||
log.error("Python脚本错误输出: {}", errorLine);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
log.error("读取Python脚本错误输出异常", e);
|
||||
}
|
||||
});
|
||||
errorThread.start();
|
||||
|
||||
// 等待执行完成
|
||||
int exitCode = process.waitFor();
|
||||
if (exitCode == 0) {
|
||||
log.info("Python 脚本执行成功");
|
||||
} else {
|
||||
log.error("Python 脚本执行失败,退出码: {}", exitCode);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("调用Python脚本失败", e);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return process;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -606,27 +647,63 @@ public class ModelServiceImpl implements IModelService {
|
||||
*/
|
||||
private void trainModelAsync(String paramJsonPath, Integer modelId, String exportFormat) {
|
||||
new Thread(() -> {
|
||||
Process process = null;
|
||||
try {
|
||||
long startTime = System.currentTimeMillis();
|
||||
log.info("开始执行Python脚本, 训练模型ID: {}", modelId);
|
||||
// 调用python脚本进行训练
|
||||
callPythonScript(TRAINING_PYTHON_SCRIPTPATH, paramJsonPath);
|
||||
process = callPythonScript(TRAINING_PYTHON_SCRIPTPATH, paramJsonPath);
|
||||
|
||||
// 将进程添加到运行进程映射中
|
||||
runningProcesses.put(modelId, process);
|
||||
|
||||
// 等待进程执行完成
|
||||
int exitCode = process.waitFor();
|
||||
|
||||
long endTime = System.currentTimeMillis();
|
||||
long duration = endTime - startTime;
|
||||
log.info("Python脚本执行完成, 训练模型ID: {}, 耗时: {} ms", modelId, duration);
|
||||
|
||||
// 根据退出码判断具体执行结果
|
||||
if (exitCode == 0) {
|
||||
log.info("Python脚本执行完成, 训练模型ID: {}, 耗时: {} ms", modelId, duration);
|
||||
} else if (exitCode == 137) {
|
||||
// 退出码137表示进程被SIGKILL信号强制终止(如调用destroyForcibly())
|
||||
log.warn("Python脚本执行被强制终止,退出码: {}, 训练模型ID: {}, 耗时: {} ms", exitCode, modelId, duration);
|
||||
} else {
|
||||
log.error("Python脚本执行失败,退出码: {}, 训练模型ID: {}, 耗时: {} ms", exitCode, modelId, duration);
|
||||
}
|
||||
|
||||
// 从运行进程映射中移除已完成的进程
|
||||
runningProcesses.remove(modelId);
|
||||
|
||||
// 将训练生成的生成 training.json、training.log、模型文件,上传到minio
|
||||
Integer trainingDataResultFileId = uploadResultFileToMinio(TANING_MODEL_BASE_DIR_PATH + MODEL_ID + modelId + "/" + TRAIN_RESULT_DIR_PATH + TRAINING_JSON_FILE_NAME);
|
||||
Integer trainingDataLogFileId = uploadResultFileToMinio(TANING_MODEL_BASE_DIR_PATH + MODEL_ID + modelId + "/" + TRAIN_RESULT_DIR_PATH + TRAINING_LOG_FILE_NAME);
|
||||
Integer trainingDataExportModelFileId = uploadResultFileToMinio(TANING_MODEL_BASE_DIR_PATH + MODEL_ID + modelId + "/" + TRAIN_RESULT_DIR_PATH + TRAINING_MODEL_PERFIX_NAME + exportFormat);
|
||||
// 只有在训练成功时才上传结果文件到minio
|
||||
Integer trainingDataResultFileId = null;
|
||||
Integer trainingDataLogFileId = null;
|
||||
Integer trainingDataExportModelFileId = null;
|
||||
|
||||
if (exitCode == 0) {
|
||||
// 将训练生成的生成 training.json、training.log、模型文件,上传到minio
|
||||
trainingDataResultFileId = uploadResultFileToMinio(TANING_MODEL_BASE_DIR_PATH + MODEL_ID + modelId + "/" + TRAIN_RESULT_DIR_PATH + TRAINING_JSON_FILE_NAME);
|
||||
trainingDataLogFileId = uploadResultFileToMinio(TANING_MODEL_BASE_DIR_PATH + MODEL_ID + modelId + "/" + TRAIN_RESULT_DIR_PATH + TRAINING_LOG_FILE_NAME);
|
||||
trainingDataExportModelFileId = uploadResultFileToMinio(TANING_MODEL_BASE_DIR_PATH + MODEL_ID + modelId + "/" + TRAIN_RESULT_DIR_PATH + TRAINING_MODEL_PERFIX_NAME + exportFormat);
|
||||
|
||||
log.info("模型训练完成,结果文件: training.json文件ID: {}、training.log文件ID: {}、导出model文件ID: {}文件上传成功", trainingDataResultFileId, trainingDataLogFileId, trainingDataExportModelFileId);
|
||||
log.info("模型训练完成,结果文件: training.json文件ID: {}、training.log文件ID: {}、导出model文件ID: {}文件上传成功", trainingDataResultFileId, trainingDataLogFileId, trainingDataExportModelFileId);
|
||||
}
|
||||
|
||||
// 根据退出码设置训练状态
|
||||
String trainingStatus;
|
||||
if (exitCode == 0) {
|
||||
trainingStatus = "成功";
|
||||
} else if (exitCode == 137) {
|
||||
trainingStatus = "已终止";
|
||||
} else {
|
||||
trainingStatus = "失败";
|
||||
}
|
||||
|
||||
// 更新模型状态为训练完成
|
||||
trainingModelService.lambdaUpdate()
|
||||
.eq(TrainingModel::getId, modelId)
|
||||
.set(TrainingModel::getTrainingStatus, "成功")
|
||||
.set(TrainingModel::getTrainingStatus, trainingStatus)
|
||||
.set(TrainingModel::getTrainingTime, new Date())
|
||||
.set(TrainingModel::getTrainingDuration, duration)
|
||||
.set(TrainingModel::getTrainingDataResultFileId, trainingDataResultFileId)
|
||||
@@ -636,6 +713,9 @@ public class ModelServiceImpl implements IModelService {
|
||||
|
||||
log.info("模型训练完成,模型ID: {}", modelId);
|
||||
} catch (Exception e) {
|
||||
// 从运行进程映射中移除失败的进程
|
||||
runningProcesses.remove(modelId);
|
||||
|
||||
log.error("模型训练失败,模型ID: {}", modelId, e);
|
||||
// 更新模型状态为训练失败
|
||||
trainingModelService.lambdaUpdate()
|
||||
@@ -718,8 +798,8 @@ public class ModelServiceImpl implements IModelService {
|
||||
if (trainingModel == null) {
|
||||
return SdmResponse.failed("模型不存在");
|
||||
}
|
||||
if (trainingModel.getTrainingStatus().equals("失败")) {
|
||||
return SdmResponse.failed("模型训练失败,请查看日志详情");
|
||||
if (trainingModel.getTrainingStatus().equals("失败") || trainingModel.getTrainingStatus().equals("已终止") ) {
|
||||
return SdmResponse.failed("模型训练失败或已终止,请查看日志详情");
|
||||
}
|
||||
|
||||
if (trainingModel.getTrainingStatus().equals("待开始") || trainingModel.getTrainingStatus().equals("训练中")) {
|
||||
@@ -828,8 +908,8 @@ public class ModelServiceImpl implements IModelService {
|
||||
|
||||
String predDirPath = TANING_MODEL_BASE_DIR_PATH + MODEL_ID + trainingModel.getId() + "/" + PRED_RESULT_DIR_PATH;
|
||||
// 创建预测用的param.json文件
|
||||
String predParamJsonFile = createPredParamJsonFile(modelPredictReq, trainingModel, trainingModelAlgorithmParam,predDirPath);
|
||||
|
||||
String predParamJsonFile = createPredParamJsonFile(modelPredictReq, trainingModel, trainingModelAlgorithmParam, predDirPath);
|
||||
|
||||
// 执行预测
|
||||
try {
|
||||
long startTime = System.currentTimeMillis();
|
||||
@@ -845,13 +925,13 @@ public class ModelServiceImpl implements IModelService {
|
||||
// 读取预测生成的结果文件并保存到数据库
|
||||
String predResultPath = predDirPath + "/" + PRED_RESULT_FILE_NAME;
|
||||
File predResultFile = new File(predResultPath);
|
||||
|
||||
|
||||
if (predResultFile.exists()) {
|
||||
try {
|
||||
// 读取预测结果文件内容
|
||||
String predResultJson = new String(Files.readAllBytes(predResultFile.toPath()));
|
||||
predResultObject = JSONObject.parseObject(predResultJson);
|
||||
|
||||
|
||||
// 将预测结果保存到数据库
|
||||
trainingModelService.lambdaUpdate()
|
||||
.eq(TrainingModel::getId, modelId)
|
||||
@@ -869,20 +949,20 @@ public class ModelServiceImpl implements IModelService {
|
||||
} catch (Exception e) {
|
||||
log.error("模型预测失败,模型ID: {}", modelId, e);
|
||||
}
|
||||
|
||||
|
||||
return SdmResponse.success(predResultObject);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建预测参数param.json文件
|
||||
*
|
||||
* @param modelPredictReq 预测请求参数
|
||||
* @param trainingModel 训练模型
|
||||
* @param modelPredictReq 预测请求参数
|
||||
* @param trainingModel 训练模型
|
||||
* @param trainingModelAlgorithmParam 训练模型算法参数
|
||||
* @param predDirPath 预测目录路径
|
||||
* @param predDirPath 预测目录路径
|
||||
* @return param.json文件路径
|
||||
*/
|
||||
private String createPredParamJsonFile(ModelPredictReq modelPredictReq, TrainingModel trainingModel, TrainingModelAlgorithmParam trainingModelAlgorithmParam,String predDirPath) {
|
||||
private String createPredParamJsonFile(ModelPredictReq modelPredictReq, TrainingModel trainingModel, TrainingModelAlgorithmParam trainingModelAlgorithmParam, String predDirPath) {
|
||||
try {
|
||||
// 确保目录存在
|
||||
File predDir = new File(predDirPath);
|
||||
@@ -908,18 +988,18 @@ public class ModelServiceImpl implements IModelService {
|
||||
modelParams.put("inputSize", trainingModel.getInputSize());
|
||||
modelParams.put("outputSize", trainingModel.getOutputSize());
|
||||
modelParams.put("normalizerType", trainingModelAlgorithmParam.getDisposeMethod());
|
||||
|
||||
|
||||
// 添加归一化参数
|
||||
if (trainingModel.getNormalizerMax() != null) {
|
||||
JSONArray normalizerMaxArray = JSONArray.parseArray(trainingModel.getNormalizerMax());
|
||||
modelParams.put("normalizerMax", normalizerMaxArray);
|
||||
}
|
||||
|
||||
|
||||
if (trainingModel.getNormalizerMin() != null) {
|
||||
JSONArray normalizerMinArray = JSONArray.parseArray(trainingModel.getNormalizerMin());
|
||||
modelParams.put("normalizerMin", normalizerMinArray);
|
||||
}
|
||||
|
||||
|
||||
paramJson.put("modelParams", modelParams);
|
||||
|
||||
// 添加输入数据
|
||||
@@ -948,6 +1028,34 @@ public class ModelServiceImpl implements IModelService {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 终止指定模型的训练进程
|
||||
*
|
||||
* @param modelId 模型ID
|
||||
* @return 是否成功终止
|
||||
*/
|
||||
public SdmResponse stopTraining(Integer modelId) {
|
||||
Process process = runningProcesses.get(modelId);
|
||||
if (process != null) {
|
||||
// 强制终止进程
|
||||
process.destroyForcibly();
|
||||
|
||||
// 从映射中移除
|
||||
runningProcesses.remove(modelId);
|
||||
|
||||
// 更新数据库状态
|
||||
trainingModelService.lambdaUpdate()
|
||||
.eq(TrainingModel::getId, modelId)
|
||||
.set(TrainingModel::getTrainingStatus, "已终止")
|
||||
.update();
|
||||
|
||||
log.info("模型训练已终止,模型ID: {}", modelId);
|
||||
} else {
|
||||
log.warn("未找到正在运行的模型训练进程,模型ID: {}", modelId);
|
||||
}
|
||||
return SdmResponse.success();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SdmResponse getModelPredictResult(Integer modelId) {
|
||||
JSONObject result = new JSONObject();
|
||||
|
||||
@@ -184,4 +184,13 @@ public class SimulationNodeController implements ISimuluationNodeFeignClient {
|
||||
return nodeService.getCommonCompleteStatistics(req);
|
||||
}
|
||||
|
||||
/**
|
||||
* 工位评审通过统计查询
|
||||
*/
|
||||
@PostMapping("/getWorkstationReviewStatistics")
|
||||
@Operation(summary = "工位评审通过统计查询", description = "工位评审通过统计查询")
|
||||
public SdmResponse getWorkstationReviewStatistics(@RequestBody GetWorkstationApproveStatusReq req) {
|
||||
return nodeService.getWorkstationReviewStatistics(req);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -83,4 +83,6 @@ public interface SimulationNodeMapper extends BaseMapper<SimulationNode> {
|
||||
|
||||
List<CommonGetCompleteFromPerformanceVo> getCommonCompleteStatisticsFromPerformance(@Param("req")CommonGetCompleteStatisticsReq req);
|
||||
|
||||
List<WorkstationApproveStatusVo> getWorkstationApproveStatus(@Param("req") GetWorkstationApproveStatusReq req);
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
package com.sdm.project.model.req;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class GetWorkstationApproveStatusReq {
|
||||
@Schema(description = "数据返回Tag类型: tag1、tag2,tag3,tag4,tag5,tag6,tag7,tag8,tag9,tag10")
|
||||
@NotNull
|
||||
private String resultTagType;
|
||||
|
||||
@Schema(description = "标签1")
|
||||
private String tag1;
|
||||
|
||||
@Schema(description = "标签2")
|
||||
private String tag2;
|
||||
|
||||
@Schema(description = "标签3")
|
||||
private String tag3;
|
||||
|
||||
@Schema(description = "标签4")
|
||||
private String tag4;
|
||||
|
||||
@Schema(description = "标签5")
|
||||
private String tag5;
|
||||
|
||||
@Schema(description = "标签6")
|
||||
private String tag6;
|
||||
|
||||
@Schema(description = "标签7")
|
||||
private String tag7;
|
||||
|
||||
@Schema(description = "标签8")
|
||||
private String tag8;
|
||||
|
||||
@Schema(description = "标签9")
|
||||
private String tag9;
|
||||
|
||||
@Schema(description = "标签10")
|
||||
private String tag10;
|
||||
}
|
||||
@@ -6,7 +6,7 @@ import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@Data
|
||||
public class CommonCompleteStatisticsVo {
|
||||
public class CommonStatisticsVo {
|
||||
private String name;
|
||||
private Map<String, Integer> statusCount = new HashMap<>();
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.sdm.project.model.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class WorkstationApproveStatusVo {
|
||||
private String tag;
|
||||
private String nodeName;
|
||||
private String approvalStatus;
|
||||
}
|
||||
@@ -39,4 +39,7 @@ public interface INodeService extends IService<SimulationNode> {
|
||||
|
||||
SdmResponse getCommonCompleteStatistics(CommonGetCompleteStatisticsReq req);
|
||||
|
||||
// 工位评审通过统计查询
|
||||
SdmResponse getWorkstationReviewStatistics(GetWorkstationApproveStatusReq req);
|
||||
|
||||
}
|
||||
|
||||
@@ -817,13 +817,13 @@ public class NodeServiceImpl extends ServiceImpl<SimulationNodeMapper, Simulatio
|
||||
List<CommonGetCompleteFromTaskVo> commonCompleteStatisticsFromTask = this.baseMapper.getCommonCompleteStatisticsFromTask(req);
|
||||
|
||||
// 按tag分组统计任务状态
|
||||
Map<String, CommonCompleteStatisticsVo> taskStatisticsMap = new HashMap<>();
|
||||
Map<String, CommonStatisticsVo> taskStatisticsMap = new HashMap<>();
|
||||
|
||||
// 统计每个tag的各种状态任务数量
|
||||
for (CommonGetCompleteFromTaskVo item : commonCompleteStatisticsFromTask) {
|
||||
String name = item.getNodeName();
|
||||
|
||||
CommonCompleteStatisticsVo stat = taskStatisticsMap.getOrDefault(name, new CommonCompleteStatisticsVo());
|
||||
CommonStatisticsVo stat = taskStatisticsMap.getOrDefault(name, new CommonStatisticsVo());
|
||||
stat.setName(name);
|
||||
|
||||
Map<String, Integer> statusCount = stat.getStatusCount();
|
||||
@@ -839,7 +839,7 @@ public class NodeServiceImpl extends ServiceImpl<SimulationNodeMapper, Simulatio
|
||||
}
|
||||
|
||||
// 转换为列表返回
|
||||
List<CommonCompleteStatisticsVo> taskResult = new ArrayList<>(taskStatisticsMap.values());
|
||||
List<CommonStatisticsVo> taskResult = new ArrayList<>(taskStatisticsMap.values());
|
||||
JSONObject resultResponse = new JSONObject();
|
||||
resultResponse.put("allExeStatus", allExeStatus);
|
||||
resultResponse.put("result", taskResult);
|
||||
@@ -849,13 +849,13 @@ public class NodeServiceImpl extends ServiceImpl<SimulationNodeMapper, Simulatio
|
||||
List<CommonGetCompleteFromPerformanceVo> commonCompleteStatisticsFromPerformance = this.baseMapper.getCommonCompleteStatisticsFromPerformance(req);
|
||||
|
||||
// 按tag分组统计指标状态
|
||||
Map<String, CommonCompleteStatisticsVo> performanceStatisticsMap = new HashMap<>();
|
||||
Map<String, CommonStatisticsVo> performanceStatisticsMap = new HashMap<>();
|
||||
|
||||
// 统计每个tag的各种状态指标数量
|
||||
for (CommonGetCompleteFromPerformanceVo item : commonCompleteStatisticsFromPerformance) {
|
||||
String nodeName = item.getNodeName();
|
||||
|
||||
CommonCompleteStatisticsVo stat = performanceStatisticsMap.getOrDefault(nodeName, new CommonCompleteStatisticsVo());
|
||||
CommonStatisticsVo stat = performanceStatisticsMap.getOrDefault(nodeName, new CommonStatisticsVo());
|
||||
stat.setName(nodeName);
|
||||
|
||||
Map<String, Integer> statusCount = stat.getStatusCount();
|
||||
@@ -872,7 +872,7 @@ public class NodeServiceImpl extends ServiceImpl<SimulationNodeMapper, Simulatio
|
||||
}
|
||||
|
||||
// 转换为列表返回
|
||||
List<CommonCompleteStatisticsVo> performanceResult = new ArrayList<>(performanceStatisticsMap.values());
|
||||
List<CommonStatisticsVo> performanceResult = new ArrayList<>(performanceStatisticsMap.values());
|
||||
JSONObject resultResponse = new JSONObject();
|
||||
resultResponse.put("allExeStatus", allExeStatus);
|
||||
resultResponse.put("result", performanceResult);
|
||||
@@ -880,4 +880,41 @@ public class NodeServiceImpl extends ServiceImpl<SimulationNodeMapper, Simulatio
|
||||
}
|
||||
return SdmResponse.success(new ArrayList<>());
|
||||
}
|
||||
|
||||
@Override
|
||||
public SdmResponse getWorkstationReviewStatistics(GetWorkstationApproveStatusReq req) {
|
||||
List<WorkstationApproveStatusVo> workstationApproveStatus = this.baseMapper.getWorkstationApproveStatus(req);
|
||||
|
||||
// 按tag分组统计审批状态
|
||||
Map<String, CommonStatisticsVo> reviewStatisticsMap = new HashMap<>();
|
||||
|
||||
// 所有审批状态
|
||||
Set<String> allApprovalStatus = new HashSet<>();
|
||||
|
||||
// 统计每个tag的各种审批状态数量
|
||||
for (WorkstationApproveStatusVo item : workstationApproveStatus) {
|
||||
String nodeName = item.getNodeName();
|
||||
|
||||
CommonStatisticsVo stat = reviewStatisticsMap.getOrDefault(nodeName, new CommonStatisticsVo());
|
||||
stat.setName(nodeName);
|
||||
|
||||
Map<String, Integer> statusCount = stat.getStatusCount();
|
||||
if (statusCount == null) {
|
||||
statusCount = new HashMap<>();
|
||||
stat.setStatusCount(statusCount);
|
||||
}
|
||||
|
||||
String approvalStatus = item.getApprovalStatus();
|
||||
allApprovalStatus.add(approvalStatus);
|
||||
statusCount.put(approvalStatus, statusCount.getOrDefault(approvalStatus, 0) + 1);
|
||||
reviewStatisticsMap.put(nodeName, stat);
|
||||
}
|
||||
|
||||
// 转换为列表返回
|
||||
List<CommonStatisticsVo> result = new ArrayList<>(reviewStatisticsMap.values());
|
||||
JSONObject resultResponse = new JSONObject();
|
||||
resultResponse.put("allApprovalStatus", allApprovalStatus);
|
||||
resultResponse.put("result", result);
|
||||
return SdmResponse.success(resultResponse);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -541,4 +541,48 @@
|
||||
</if>
|
||||
</where>
|
||||
</select>
|
||||
|
||||
<select id="getWorkstationApproveStatus"
|
||||
parameterType="com.sdm.project.model.req.GetWorkstationApproveStatusReq"
|
||||
resultType="com.sdm.project.model.vo.WorkstationApproveStatusVo">
|
||||
select
|
||||
task.${req.resultTagType} as tag,
|
||||
node.nodeName,
|
||||
task.approval_status as approvalStatus
|
||||
from simulation_task task
|
||||
left join simulation_node node on task.${req.resultTagType} = node.uuid
|
||||
<where>
|
||||
1=1 and task.approval_status is not null
|
||||
<if test="req.tag1 != null and req.tag1 !='' ">
|
||||
and task.tag1 = #{req.tag1}
|
||||
</if>
|
||||
<if test="req.tag2 != null and req.tag2 !='' ">
|
||||
and task.tag2 = #{req.tag2}
|
||||
</if>
|
||||
<if test="req.tag3 != null and req.tag3 !='' ">
|
||||
and task.tag3 = #{req.tag3}
|
||||
</if>
|
||||
<if test="req.tag4 != null and req.tag4 !='' ">
|
||||
and task.tag4 = #{req.tag4}
|
||||
</if>
|
||||
<if test="req.tag5 != null and req.tag5 !='' ">
|
||||
and task.tag5 = #{req.tag5}
|
||||
</if>
|
||||
<if test="req.tag6 != null and req.tag6 !='' ">
|
||||
and task.tag6 = #{req.tag6}
|
||||
</if>
|
||||
<if test="req.tag7 != null and req.tag7 !='' ">
|
||||
and task.tag7 = #{req.tag7}
|
||||
</if>
|
||||
<if test="req.tag8 != null and req.tag8 !='' ">
|
||||
and task.tag8 = #{req.tag8}
|
||||
</if>
|
||||
<if test="req.tag9 != null and req.tag9 !='' ">
|
||||
and task.tag9 = #{req.tag9}
|
||||
</if>
|
||||
<if test="req.tag10 != null and req.tag10 !='' ">
|
||||
and task.tag10 = #{req.tag10}
|
||||
</if>
|
||||
</where>
|
||||
</select>
|
||||
</mapper>
|
||||
@@ -114,12 +114,22 @@ public class UserController implements ISysUserFeignClient {
|
||||
* @param req
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary = "更新用户角色", description = "更新用户角色接口,用于修改用户角色信息")
|
||||
@Operation(summary = "更新用户角色", description = "更新用户角色,用于修改用户角色信息")
|
||||
@PostMapping("/updateUserRole")
|
||||
public SdmResponse updateUserRole(@Parameter(description = "用户角色更新请求参数") @RequestBody @Validated UpdateUserRoleReq req) {
|
||||
public SdmResponse updateUserRole(@Parameter(description = "更新用户角色请求参数") @RequestBody UpdateUserRole req) {
|
||||
return ISysUserService.updateUserRole(req);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询用户角色
|
||||
* @param userId
|
||||
*/
|
||||
@Operation(summary = "查询用户角色", description = "查询用户角色接口,用于查询指定用户的角色列表")
|
||||
@GetMapping("/queryUserRole")
|
||||
public SdmResponse queryUserRole(@Parameter(description = "用户角色查询请求参数") @RequestParam("userId") Integer userId) {
|
||||
return ISysUserService.queryUserRole(userId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增用户组
|
||||
*
|
||||
|
||||
@@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
@@ -64,7 +65,7 @@ public class SysUser implements Serializable {
|
||||
|
||||
@Schema(description = "用户状态(0-正常,1-冻结;默认值为0,确保新用户默认正常)")
|
||||
@TableField("status")
|
||||
private Boolean status;
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "身份证号(18位,符合身份证格式,可选,建议唯一)")
|
||||
@TableField("id_card")
|
||||
@@ -88,11 +89,11 @@ public class SysUser implements Serializable {
|
||||
|
||||
@Schema(description = "性别(0-未知,1-男性,2-女性;默认值为0)")
|
||||
@TableField("sex")
|
||||
private Boolean sex;
|
||||
private Integer sex;
|
||||
|
||||
@Schema(description = "是否有员工账号(0-无,1-有;布尔类型映射为tinyint,默认0)")
|
||||
@TableField("no_sys_staff")
|
||||
private Boolean noSysStaff;
|
||||
private Integer noSysStaff;
|
||||
|
||||
@Schema(description = "用户所属租户ID(多租户场景下的租户标识,可选)")
|
||||
@TableField("tenant_id")
|
||||
@@ -104,11 +105,11 @@ public class SysUser implements Serializable {
|
||||
|
||||
@Schema(description = "记录创建时间(默认取当前时间,无需手动插入)")
|
||||
@TableField("create_time")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
|
||||
private LocalDateTime createTime;
|
||||
|
||||
@Schema(description = "记录更新时间(每次更新数据时自动刷新)")
|
||||
@TableField("update_time")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
|
||||
private LocalDateTime updateTime;
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
@@ -43,10 +44,12 @@ public class SysUserGroup implements Serializable {
|
||||
|
||||
@Schema(description = "创建时间")
|
||||
@TableField("createdTime")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
|
||||
private LocalDateTime createdTime;
|
||||
|
||||
@Schema(description = "更新时间")
|
||||
@TableField("updatedTime")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
|
||||
private LocalDateTime updatedTime;
|
||||
|
||||
|
||||
|
||||
@@ -71,7 +71,7 @@ public class Tenant implements Serializable {
|
||||
|
||||
@Schema(description = "状态")
|
||||
@TableField("status")
|
||||
private String status;
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "创建时间")
|
||||
@TableField("createTime")
|
||||
|
||||
@@ -44,7 +44,7 @@ public class TenantReq implements Serializable {
|
||||
private String endTime;
|
||||
|
||||
@Schema(description = "状态")
|
||||
private String status;
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "创建时间")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.sdm.system.model.req.user;
|
||||
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import lombok.Data;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
|
||||
@Schema(description = "用户角色更新请求参数")
|
||||
@Data
|
||||
public class UpdateUserRole {
|
||||
@Schema(description = "角色id", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private Integer roleId;
|
||||
|
||||
@Schema(description = "用户id", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private Integer userId;
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
package com.sdm.system.model.req.user;
|
||||
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import lombok.Data;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
|
||||
@Schema(description = "用户角色更新请求参数")
|
||||
@Data
|
||||
public class UpdateUserRoleReq {
|
||||
|
||||
@NotBlank(message = "role不能为空")
|
||||
@Schema(description = "角色", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private String role;
|
||||
|
||||
@NotBlank(message = "jobNumber不能为空")
|
||||
@Schema(description = "工号", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private String jobNumber;
|
||||
|
||||
@NotBlank(message = "company不能为空")
|
||||
@Schema(description = "公司", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private String company;
|
||||
}
|
||||
@@ -33,7 +33,7 @@ public class UserUpdateReq {
|
||||
private String email;
|
||||
|
||||
@Schema(description = "用户状态(0-正常,1-冻结;默认值为0,确保新用户默认正常)")
|
||||
private Boolean status;
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "身份证号(18位,符合身份证格式,可选,建议唯一)")
|
||||
private String idCard;
|
||||
@@ -51,10 +51,10 @@ public class UserUpdateReq {
|
||||
private LocalDate birthDate;
|
||||
|
||||
@Schema(description = "性别(0-未知,1-男性,2-女性;默认值为0)")
|
||||
private Boolean sex;
|
||||
private Integer sex;
|
||||
|
||||
@Schema(description = "是否有员工账号(0-无,1-有;布尔类型映射为tinyint,默认0)")
|
||||
private Boolean noSysStaff;
|
||||
private Integer noSysStaff;
|
||||
|
||||
@Schema(description = "用户所属租户ID(多租户场景下的租户标识,可选)")
|
||||
private Integer tenantId;
|
||||
|
||||
@@ -28,7 +28,9 @@ public interface ISysUserService extends IService<SysUser> {
|
||||
|
||||
SdmResponse getUserImage();
|
||||
|
||||
SdmResponse updateUserRole(UpdateUserRoleReq req);
|
||||
SdmResponse updateUserRole(UpdateUserRole req);
|
||||
|
||||
SdmResponse queryUserRole(Integer userId);
|
||||
|
||||
SdmResponse addGroup(GroupAddReq req);
|
||||
|
||||
|
||||
@@ -117,7 +117,12 @@ public class CIDISysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser>
|
||||
}
|
||||
|
||||
@Override
|
||||
public SdmResponse updateUserRole(UpdateUserRoleReq req) {
|
||||
public SdmResponse updateUserRole(UpdateUserRole req) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SdmResponse queryUserRole(Integer userId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -11,19 +11,16 @@ import com.sdm.common.entity.req.system.UserQueryReq;
|
||||
import com.sdm.common.entity.resp.PageDataResp;
|
||||
import com.sdm.common.utils.PageUtils;
|
||||
import com.sdm.system.dao.SysUserMapper;
|
||||
import com.sdm.system.model.entity.SysUser;
|
||||
import com.sdm.system.model.entity.SysUserGroup;
|
||||
import com.sdm.system.model.entity.SysUserGroupRelation;
|
||||
import com.sdm.system.model.entity.*;
|
||||
import com.sdm.system.model.req.user.*;
|
||||
import com.sdm.common.entity.resp.system.CIDUserResp;
|
||||
import com.sdm.system.model.resp.SysUserGroupResp;
|
||||
import com.sdm.system.service.ISysUserGroupRelationService;
|
||||
import com.sdm.system.service.ISysUserGroupService;
|
||||
import com.sdm.system.service.ISysUserService;
|
||||
import com.sdm.system.service.*;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
@@ -43,6 +40,13 @@ public class LocalUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> im
|
||||
@Autowired
|
||||
private ISysUserGroupRelationService sysUserGroupRelationService;
|
||||
|
||||
@Autowired
|
||||
private ISysUserRoleRelationService sysUserRoleRelationService;
|
||||
|
||||
@Autowired
|
||||
@Qualifier("roleService")
|
||||
private ISysRoleService sysRoleService;
|
||||
|
||||
@Override
|
||||
public String getType() {
|
||||
return type;
|
||||
@@ -138,8 +142,30 @@ public class LocalUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> im
|
||||
}
|
||||
|
||||
@Override
|
||||
public SdmResponse updateUserRole(UpdateUserRoleReq req) {
|
||||
return SdmResponse.success();
|
||||
public SdmResponse updateUserRole(UpdateUserRole req) {
|
||||
SysUserRoleRelation userRoleRelation = sysUserRoleRelationService.lambdaQuery().eq(SysUserRoleRelation::getUserId, req.getUserId()).one();
|
||||
if (userRoleRelation == null) {
|
||||
userRoleRelation = new SysUserRoleRelation();
|
||||
userRoleRelation.setUserId(req.getUserId());
|
||||
userRoleRelation.setRoleId(req.getRoleId());
|
||||
sysUserRoleRelationService.save(userRoleRelation);
|
||||
}else {
|
||||
userRoleRelation.setRoleId(req.getRoleId());
|
||||
sysUserRoleRelationService.lambdaUpdate()
|
||||
.eq(SysUserRoleRelation::getUserId, req.getUserId())
|
||||
.set(SysUserRoleRelation::getRoleId, req.getRoleId()).update();
|
||||
}
|
||||
return SdmResponse.success("更新用户角色成功");
|
||||
}
|
||||
|
||||
@Override
|
||||
public SdmResponse queryUserRole(Integer userId) {
|
||||
SysUserRoleRelation userRoleRelation = sysUserRoleRelationService.lambdaQuery().eq(SysUserRoleRelation::getUserId, userId).one();
|
||||
if (userRoleRelation == null) {
|
||||
return SdmResponse.failed("用户角色不存在");
|
||||
}
|
||||
SysRole role = sysRoleService.getById(userRoleRelation.getRoleId());
|
||||
return SdmResponse.success(role);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user