Merge remote-tracking branch 'origin/main'
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
package com.sdm.project.model.req;
|
||||
package com.sdm.common.entity.req.project;
|
||||
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.sdm.common.entity.resp;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
@@ -51,4 +52,8 @@ public class BaseResp {
|
||||
|
||||
@Schema(description = "所属算列id")
|
||||
private String ownRunId;
|
||||
|
||||
@Schema(description= "文件业务类型(1:模型文件 2:仿真报告、3:计算文件、4:曲线文件、5:云图文件,6:网格文件,7:计算过程文件)")
|
||||
@TableField("fileType")
|
||||
private Integer fileType;
|
||||
}
|
||||
|
||||
@@ -137,7 +137,7 @@ public class FileMetadataInfoResp extends BaseResp implements Serializable {
|
||||
private String tag9;
|
||||
private String tag10;
|
||||
|
||||
// 算列信息,前端搞了个框架,无法从第二层对象中获取,只能将索引属性放到这
|
||||
// 算列信息,前端搞了个框架,无法从第二层对象中获取,只能将算列属性放到这
|
||||
private Integer type;
|
||||
|
||||
private String taskId;
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
package com.sdm.project.model.vo;
|
||||
package com.sdm.common.entity.resp.project;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.sdm.common.entity.pojo.BaseEntity;
|
||||
import com.sdm.common.entity.resp.system.CIDUserResp;
|
||||
import com.sdm.project.model.po.TaskNodeExtraPo;
|
||||
import com.sdm.project.model.vo.SpdmTaskMemberVo;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.sdm.project.model.po;
|
||||
package com.sdm.common.entity.resp.project;
|
||||
|
||||
import com.sdm.common.entity.pojo.BaseEntity;
|
||||
import lombok.Data;
|
||||
@@ -2,8 +2,11 @@ package com.sdm.common.feign.impl.project;
|
||||
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.sdm.common.common.SdmResponse;
|
||||
import com.sdm.common.entity.req.project.GetTaskDetailReq;
|
||||
import com.sdm.common.entity.resp.project.SpdmTaskVo;
|
||||
import com.sdm.common.feign.inter.project.ISimulationTaskFeignClient;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@@ -37,4 +40,18 @@ public class SimulationTaskFeignClientImpl implements ISimulationTaskFeignClient
|
||||
return SdmResponse.failed("内部调用仿真任务难度系数统计统计失败");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public SdmResponse<SpdmTaskVo> getTaskDetail(GetTaskDetailReq req) {
|
||||
try {
|
||||
SdmResponse<SpdmTaskVo> response = simulationTaskFeignClient.getTaskDetail(req);
|
||||
if(!response.isSuccess() || ObjectUtils.isEmpty(response.getData())){
|
||||
return SdmResponse.failed("内部调用获取任务详情失败");
|
||||
}
|
||||
return response;
|
||||
} catch (Exception e) {
|
||||
log.error("内部调用获取任务详情失败", e);
|
||||
return SdmResponse.failed("内部调用获取任务详情失败");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,9 +2,13 @@ package com.sdm.common.feign.inter.project;
|
||||
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.sdm.common.common.SdmResponse;
|
||||
import com.sdm.common.entity.req.project.GetTaskDetailReq;
|
||||
import com.sdm.common.entity.req.project.SpdmReportReq;
|
||||
import com.sdm.common.entity.req.system.LaunchApproveReq;
|
||||
import com.sdm.common.entity.resp.project.SpdmTaskVo;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
@@ -29,4 +33,6 @@ public interface ISimulationTaskFeignClient {
|
||||
@GetMapping(value = "/task/getTaskDifficultStatistics")
|
||||
SdmResponse<List<JSONObject>> getTaskDifficultStatistics(@RequestParam(value = "nodeType", required = true) String nodeType);
|
||||
|
||||
@PostMapping("/getTaskDetail")
|
||||
SdmResponse<SpdmTaskVo> getTaskDetail(@RequestBody GetTaskDetailReq req);
|
||||
}
|
||||
@@ -6,6 +6,8 @@ import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import java.time.LocalDateTime;
|
||||
import java.io.Serializable;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
@@ -59,9 +61,11 @@ public class DimensionTemplate implements Serializable {
|
||||
|
||||
@Schema(description = "创建时间")
|
||||
@TableField("createdAt")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private LocalDateTime createdAt;
|
||||
|
||||
@Schema(description = "更新时间")
|
||||
@TableField("updatedAt")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private LocalDateTime updatedAt;
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ import com.sdm.common.entity.req.data.DelDirReq;
|
||||
import com.sdm.common.entity.req.data.DelFileReq;
|
||||
import com.sdm.common.entity.req.data.UploadFilesReq;
|
||||
import com.sdm.common.entity.req.project.DelNodeReq;
|
||||
import com.sdm.common.entity.req.project.GetTaskDetailReq;
|
||||
import com.sdm.common.entity.req.project.SpdmQueryRunInfoListReq;
|
||||
import com.sdm.common.entity.req.project.SpdmQueryRunListReq;
|
||||
import com.sdm.common.entity.req.system.UserQueryReq;
|
||||
@@ -20,9 +21,11 @@ import com.sdm.common.entity.resp.AllNodeByProjectIdAndTypeResp;
|
||||
import com.sdm.common.entity.resp.PageDataResp;
|
||||
import com.sdm.common.entity.resp.data.FileMetadataInfoResp;
|
||||
import com.sdm.common.entity.resp.project.SimulationRunResp;
|
||||
import com.sdm.common.entity.resp.project.SpdmTaskVo;
|
||||
import com.sdm.common.entity.resp.system.CIDUserResp;
|
||||
import com.sdm.common.feign.impl.project.SimulationNodeFeignClientImpl;
|
||||
import com.sdm.common.feign.impl.system.SysUserFeignClientImpl;
|
||||
import com.sdm.common.feign.inter.project.ISimulationTaskFeignClient;
|
||||
import com.sdm.common.utils.CidSysUserUtil;
|
||||
import com.sdm.common.utils.PageUtils;
|
||||
import com.sdm.data.convert.FileMetadataConvert;
|
||||
@@ -81,6 +84,9 @@ public class DimensionTemplateServiceImpl extends ServiceImpl<DimensionTemplateM
|
||||
@Autowired
|
||||
private FileMetadataHierarchyHelper hierarchyHelper;
|
||||
|
||||
@Autowired
|
||||
private ISimulationTaskFeignClient simulationTaskFeignClient;
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public SdmResponse saveDimensionTemplateWithHierarchies(TemplateCreationRequest request) {
|
||||
@@ -321,10 +327,28 @@ public class DimensionTemplateServiceImpl extends ServiceImpl<DimensionTemplateM
|
||||
String totalName = objectKey.substring(baseDirPath.length());
|
||||
childDto.setTotalName(totalName);
|
||||
}
|
||||
if(ObjectUtils.isNotEmpty(childDto.getOwntaskId()) &&
|
||||
ObjectUtils.isEmpty(childDto.getOwnDisciplineName())){
|
||||
GetTaskDetailReq getTaskDetailReq = new GetTaskDetailReq();
|
||||
getTaskDetailReq.setRelatedResourceUuid(childDto.getOwntaskId());
|
||||
SdmResponse<SpdmTaskVo> taskDetail = simulationTaskFeignClient.getTaskDetail(getTaskDetailReq);
|
||||
if(taskDetail.isSuccess()){
|
||||
childDto.setOwnDisciplineName(taskDetail.getData().getDisciplineName());
|
||||
}
|
||||
}
|
||||
childDto.setPermissionValue(fileUserPermissionService.getMergedPermission(fileInfo.getId(), ThreadLocalContext.getUserId()));
|
||||
children.add(childDto);
|
||||
}
|
||||
|
||||
if(ObjectUtils.isNotEmpty(dto.getOwntaskId()) &&
|
||||
ObjectUtils.isEmpty(dto.getOwnDisciplineName())){
|
||||
GetTaskDetailReq getTaskDetailReq = new GetTaskDetailReq();
|
||||
getTaskDetailReq.setRelatedResourceUuid(dto.getOwntaskId());
|
||||
SdmResponse<SpdmTaskVo> taskDetail = simulationTaskFeignClient.getTaskDetail(getTaskDetailReq);
|
||||
if(taskDetail.isSuccess()){
|
||||
dto.setOwnDisciplineName(taskDetail.getData().getDisciplineName());
|
||||
}
|
||||
}
|
||||
dto.setPermissionValue(fileUserPermissionService.getMergedPermission(baseInfo.getId(), ThreadLocalContext.getUserId()));
|
||||
dto.setMergeSameNameChildren(children);
|
||||
dto.setFileIds(children.stream().map(FileMetadataInfoResp::getId).toList());
|
||||
|
||||
@@ -289,9 +289,6 @@ public class FileMetadataHierarchyHelper {
|
||||
} else if (NodeTypeEnum.PHASE.getValue().equals(ownType)) {
|
||||
resp.getClass().getMethod("setPhaseName", String.class).invoke(resp, folder.getOriginalName());
|
||||
resp.getClass().getMethod("setPhaseId", String.class).invoke(resp, folder.getRelatedResourceUuid());
|
||||
} else if (NodeTypeEnum.DISCIPLINE.getValue().equals(ownType)) {
|
||||
resp.getClass().getMethod("setDisciplineName", String.class).invoke(resp, folder.getOriginalName());
|
||||
resp.getClass().getMethod("setDisciplineId", String.class).invoke(resp, folder.getRelatedResourceUuid());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.warn("设置SimulationTask层级信息失败", e);
|
||||
@@ -311,9 +308,6 @@ public class FileMetadataHierarchyHelper {
|
||||
} else if (NodeTypeEnum.PHASE.getValue().equals(ownType)) {
|
||||
resp.getClass().getMethod("setOwnPhaseName", String.class).invoke(resp, folder.getOriginalName());
|
||||
resp.getClass().getMethod("setOwnPhaseId", String.class).invoke(resp, folder.getRelatedResourceUuid());
|
||||
} else if (NodeTypeEnum.DISCIPLINE.getValue().equals(ownType)) {
|
||||
resp.getClass().getMethod("setOwnDisciplineName", String.class).invoke(resp, folder.getOriginalName());
|
||||
resp.getClass().getMethod("setOwnDisciplineId", String.class).invoke(resp, folder.getRelatedResourceUuid());
|
||||
} else if (NodeTypeEnum.TASK.getValue().equals(ownType)) {
|
||||
resp.getClass().getMethod("setOwntaskName", String.class).invoke(resp, folder.getOriginalName());
|
||||
resp.getClass().getMethod("setOwntaskId", String.class).invoke(resp, folder.getRelatedResourceUuid());
|
||||
@@ -334,9 +328,6 @@ public class FileMetadataHierarchyHelper {
|
||||
} else if (NodeTypeEnum.PHASE.getValue().equals(ownType)) {
|
||||
resp.getClass().getMethod("setOwnPhaseName", String.class).invoke(resp, folder.getOriginalName());
|
||||
resp.getClass().getMethod("setOwnPhaseId", String.class).invoke(resp, folder.getRelatedResourceUuid());
|
||||
} else if (NodeTypeEnum.DISCIPLINE.getValue().equals(ownType)) {
|
||||
resp.getClass().getMethod("setOwnDisciplineName", String.class).invoke(resp, folder.getOriginalName());
|
||||
resp.getClass().getMethod("setOwnDisciplineId", String.class).invoke(resp, folder.getRelatedResourceUuid());
|
||||
} else if (NodeTypeEnum.MACHINE.getValue().equals(ownType)) {
|
||||
resp.getClass().getMethod("setOwnMachineName", String.class).invoke(resp, folder.getOriginalName());
|
||||
resp.getClass().getMethod("setOwnMachineId", String.class).invoke(resp, folder.getRelatedResourceUuid());
|
||||
|
||||
@@ -1,181 +0,0 @@
|
||||
package com.sdm.data;
|
||||
|
||||
import com.sdm.data.dao.MapperCompatibilityTest;
|
||||
import com.sdm.data.dao.PostgreSQLCompatibilityTest;
|
||||
import com.sdm.data.service.ServiceCrudTest;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* 交互式测试运行器
|
||||
* 启动一次Spring容器后,可以反复执行不同的测试方法
|
||||
*
|
||||
* 使用方法:直接运行此类的main方法,然后在控制台输入测试方法编号
|
||||
*/
|
||||
public class InteractiveTestRunner {
|
||||
|
||||
private static ConfigurableApplicationContext context;
|
||||
private static final Map<String, TestMethodInfo> testMethods = new LinkedHashMap<>();
|
||||
|
||||
public static void main(String[] args) {
|
||||
System.out.println("========================================");
|
||||
System.out.println(" 交互式测试运行器 - 启动Spring容器");
|
||||
System.out.println("========================================");
|
||||
|
||||
// 启动Spring容器
|
||||
System.setProperty("spring.profiles.active", "test");
|
||||
context = SpringApplication.run(DataApplication.class, args);
|
||||
|
||||
System.out.println("\n✓ Spring容器启动成功!\n");
|
||||
|
||||
// 注册测试类和方法
|
||||
registerTestClass(MapperCompatibilityTest.class);
|
||||
registerTestClass(ServiceCrudTest.class);
|
||||
registerTestClass(PostgreSQLCompatibilityTest.class);
|
||||
|
||||
// 交互式运行
|
||||
runInteractively();
|
||||
}
|
||||
|
||||
private static void registerTestClass(Class<?> testClass) {
|
||||
for (Method method : testClass.getDeclaredMethods()) {
|
||||
if (method.isAnnotationPresent(org.junit.jupiter.api.Test.class)) {
|
||||
String key = testClass.getSimpleName() + "." + method.getName();
|
||||
testMethods.put(key, new TestMethodInfo(testClass, method));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void runInteractively() {
|
||||
Scanner scanner = new Scanner(System.in);
|
||||
|
||||
while (true) {
|
||||
printMenu();
|
||||
System.out.print("\n请输入编号 (q退出, a运行全部): ");
|
||||
String input = scanner.nextLine().trim();
|
||||
|
||||
if ("q".equalsIgnoreCase(input)) {
|
||||
System.out.println("退出测试...");
|
||||
context.close();
|
||||
break;
|
||||
}
|
||||
|
||||
if ("a".equalsIgnoreCase(input)) {
|
||||
runAllTests();
|
||||
continue;
|
||||
}
|
||||
|
||||
if ("l".equalsIgnoreCase(input)) {
|
||||
continue; // 重新显示菜单
|
||||
}
|
||||
|
||||
try {
|
||||
int index = Integer.parseInt(input);
|
||||
runTestByIndex(index);
|
||||
} catch (NumberFormatException e) {
|
||||
// 尝试按方法名匹配
|
||||
runTestByName(input);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void printMenu() {
|
||||
System.out.println("\n========== 可用测试方法 ==========");
|
||||
int index = 1;
|
||||
String currentClass = "";
|
||||
for (Map.Entry<String, TestMethodInfo> entry : testMethods.entrySet()) {
|
||||
String className = entry.getValue().testClass.getSimpleName();
|
||||
if (!className.equals(currentClass)) {
|
||||
currentClass = className;
|
||||
System.out.println("\n【" + className + "】");
|
||||
}
|
||||
System.out.printf(" %3d. %s%n", index++, entry.getValue().method.getName());
|
||||
}
|
||||
System.out.println("\n==================================");
|
||||
System.out.println("命令: [编号]执行单个 | [a]执行全部 | [l]列表 | [q]退出");
|
||||
}
|
||||
|
||||
private static void runTestByIndex(int index) {
|
||||
if (index < 1 || index > testMethods.size()) {
|
||||
System.out.println("❌ 无效编号: " + index);
|
||||
return;
|
||||
}
|
||||
|
||||
int i = 1;
|
||||
for (TestMethodInfo info : testMethods.values()) {
|
||||
if (i++ == index) {
|
||||
runTest(info);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void runTestByName(String name) {
|
||||
for (Map.Entry<String, TestMethodInfo> entry : testMethods.entrySet()) {
|
||||
if (entry.getKey().contains(name) || entry.getValue().method.getName().contains(name)) {
|
||||
runTest(entry.getValue());
|
||||
return;
|
||||
}
|
||||
}
|
||||
System.out.println("❌ 未找到匹配的测试方法: " + name);
|
||||
}
|
||||
|
||||
private static void runTest(TestMethodInfo info) {
|
||||
System.out.println("\n▶ 运行: " + info.testClass.getSimpleName() + "." + info.method.getName());
|
||||
System.out.println("----------------------------------------");
|
||||
|
||||
try {
|
||||
// 从Spring容器获取测试实例
|
||||
Object testInstance = context.getBean(info.testClass);
|
||||
|
||||
long start = System.currentTimeMillis();
|
||||
info.method.invoke(testInstance);
|
||||
long duration = System.currentTimeMillis() - start;
|
||||
|
||||
System.out.println("----------------------------------------");
|
||||
System.out.printf("✓ 测试通过! (耗时: %dms)%n", duration);
|
||||
} catch (Exception e) {
|
||||
System.out.println("----------------------------------------");
|
||||
System.out.println("✗ 测试失败!");
|
||||
Throwable cause = e.getCause() != null ? e.getCause() : e;
|
||||
System.out.println("错误: " + cause.getMessage());
|
||||
cause.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private static void runAllTests() {
|
||||
System.out.println("\n▶ 运行全部测试...");
|
||||
int passed = 0, failed = 0;
|
||||
long totalStart = System.currentTimeMillis();
|
||||
|
||||
for (TestMethodInfo info : testMethods.values()) {
|
||||
System.out.print(" " + info.method.getName() + " ... ");
|
||||
try {
|
||||
Object testInstance = context.getBean(info.testClass);
|
||||
info.method.invoke(testInstance);
|
||||
System.out.println("✓");
|
||||
passed++;
|
||||
} catch (Exception e) {
|
||||
System.out.println("✗");
|
||||
failed++;
|
||||
}
|
||||
}
|
||||
|
||||
long totalDuration = System.currentTimeMillis() - totalStart;
|
||||
System.out.println("\n========================================");
|
||||
System.out.printf("总计: %d 通过, %d 失败 (耗时: %dms)%n", passed, failed, totalDuration);
|
||||
}
|
||||
|
||||
private static class TestMethodInfo {
|
||||
Class<?> testClass;
|
||||
Method method;
|
||||
|
||||
TestMethodInfo(Class<?> testClass, Method method) {
|
||||
this.testClass = testClass;
|
||||
this.method = method;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -24,7 +24,7 @@ import static org.junit.jupiter.api.Assertions.*;
|
||||
* Mapper层兼容性测试 - MySQL转PostgreSQL验证
|
||||
* 覆盖所有Mapper接口的基础CRUD和自定义SQL方法
|
||||
*/
|
||||
@Component // 让测试类成为Spring Bean,支持交互式运行
|
||||
|
||||
@SpringBootTest
|
||||
@ActiveProfiles("test")
|
||||
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
|
||||
@@ -92,7 +92,6 @@ public class MapperCompatibilityTest {
|
||||
entity.setFileBizType(1);
|
||||
entity.setFileSize(2048L);
|
||||
entity.setCreateTime(LocalDateTime.now());
|
||||
entity.setUpdateTime(LocalDateTime.now());
|
||||
|
||||
int insertResult = fileStorageMapper.insert(entity);
|
||||
assertEquals(1, insertResult);
|
||||
@@ -104,9 +103,11 @@ public class MapperCompatibilityTest {
|
||||
assertEquals("mapper_test.txt", selected.getFileName());
|
||||
|
||||
// UPDATE
|
||||
selected.setFileName("mapper_test_updated.txt");
|
||||
selected.setFileSize(4096L);
|
||||
int updateResult = fileStorageMapper.updateById(selected);
|
||||
FileStorage updateFileStorage = new FileStorage();
|
||||
updateFileStorage.setId(selected.getId());
|
||||
updateFileStorage.setFileName("mapper_test_updated.txt");
|
||||
updateFileStorage.setFileSize(4096L);
|
||||
int updateResult = fileStorageMapper.updateById(updateFileStorage);
|
||||
assertEquals(1, updateResult);
|
||||
|
||||
// VERIFY UPDATE
|
||||
@@ -194,13 +195,16 @@ public class MapperCompatibilityTest {
|
||||
FileMetadataInfo entity = new FileMetadataInfo();
|
||||
entity.setRelatedResourceUuid("test-uuid-mapper");
|
||||
entity.setRelatedResourceUuidOwnType("node");
|
||||
entity.setBucketName("buck");
|
||||
entity.setObjectKey("objectKey");
|
||||
entity.setVersionNo(1L);
|
||||
entity.setOriginalName("mapper_metadata.txt");
|
||||
entity.setIsRoot(false);
|
||||
entity.setApproveType(1);
|
||||
entity.setDataType(2);
|
||||
entity.setIsLatest(true);
|
||||
entity.setTenantId(1L);
|
||||
entity.setCreatorId(1L);
|
||||
entity.setCreateTime(LocalDateTime.now());
|
||||
entity.setUpdateTime(LocalDateTime.now());
|
||||
|
||||
int insertResult = fileMetadataInfoMapper.insert(entity);
|
||||
assertEquals(1, insertResult);
|
||||
|
||||
@@ -31,7 +31,7 @@ import static org.junit.jupiter.api.Assertions.*;
|
||||
* 4. Boolean字段处理
|
||||
* 5. 字段名大小写敏感性
|
||||
*/
|
||||
@Component // 让测试类成为Spring Bean,支持交互式运行
|
||||
|
||||
@SpringBootTest
|
||||
@ActiveProfiles("test")
|
||||
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
|
||||
|
||||
@@ -22,7 +22,7 @@ import static org.junit.jupiter.api.Assertions.*;
|
||||
* Service层CRUD测试 - MySQL转PostgreSQL验证
|
||||
* 覆盖所有Service的基础CRUD操作
|
||||
*/
|
||||
@Component // 让测试类成为Spring Bean,支持交互式运行
|
||||
|
||||
@SpringBootTest
|
||||
@ActiveProfiles("test")
|
||||
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
|
||||
|
||||
@@ -4,7 +4,7 @@ spring:
|
||||
datasource:
|
||||
username: spdm
|
||||
password: Spdm@2026
|
||||
jdbc-url: jdbc:postgresql://192.168.65.161:25432/spdm_baseline?currentSchema=public&stringtype=unspecified
|
||||
jdbc-url: jdbc:postgresql://192.168.65.161:25432/spdm_baseline?currentSchema=public&stringtype=unspecified&TimeZone=Asia/Shanghai
|
||||
driver-class-name: org.postgresql.Driver
|
||||
hikari:
|
||||
# 设置连接池能够容纳的最大连接数。建议值:CPU核心数 * 2 + 有效磁盘I/O数。一个常见的经验值是 10-20。
|
||||
@@ -20,7 +20,7 @@ spring:
|
||||
master:
|
||||
username: spdm
|
||||
password: Spdm@2026
|
||||
jdbc-url: jdbc:postgresql://192.168.65.161:25432/spdm_baseline?currentSchema=public&stringtype=unspecified
|
||||
jdbc-url: jdbc:postgresql://192.168.65.161:25432/spdm_baseline?currentSchema=public&stringtype=unspecified&TimeZone=Asia/Shanghai
|
||||
driver-class-name: org.postgresql.Driver
|
||||
slave:
|
||||
username: root
|
||||
|
||||
@@ -3128,7 +3128,7 @@ package com.sdm.project.dao;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.sdm.common.common.SdmResponse;
|
||||
import com.sdm.project.model.entity.SimulationTask;
|
||||
import com.sdm.project.model.po.TaskNodeExtraPo;
|
||||
import com.sdm.common.entity.resp.project.TaskNodeExtraPo;
|
||||
import com.sdm.project.model.req.SpdmAnalysisTaskListReq;
|
||||
import com.sdm.project.model.req.*;
|
||||
import com.sdm.project.model.vo.*;
|
||||
@@ -4164,7 +4164,7 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.sdm.common.entity.pojo.BaseEntity;
|
||||
import com.sdm.project.model.po.ProjectNodeExtraPo;
|
||||
import com.sdm.project.model.po.TaskNodeExtraPo;
|
||||
import com.sdm.common.entity.resp.project.TaskNodeExtraPo;
|
||||
import com.sdm.project.model.po.TaskNodeMemberPo;
|
||||
import lombok.Data;
|
||||
|
||||
@@ -10821,7 +10821,7 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.sdm.common.entity.pojo.BaseEntity;
|
||||
import com.sdm.common.entity.resp.system.CIDUserResp;
|
||||
import com.sdm.project.model.po.TaskNodeExtraPo;
|
||||
import com.sdm.common.entity.resp.project.TaskNodeExtraPo;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
@@ -11586,7 +11586,7 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.sdm.common.entity.pojo.BaseEntity;
|
||||
import com.sdm.common.entity.resp.system.CIDUserResp;
|
||||
import com.sdm.project.model.po.TaskNodeExtraPo;
|
||||
import com.sdm.common.entity.resp.project.TaskNodeExtraPo;
|
||||
import com.sdm.project.model.vo.SpdmTaskMemberVo;
|
||||
import lombok.Data;
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.sdm.project.controller;
|
||||
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.sdm.common.common.SdmResponse;
|
||||
import com.sdm.common.entity.req.project.GetTaskDetailReq;
|
||||
import com.sdm.common.entity.req.task.TaskExportExcelFormat;
|
||||
import com.sdm.common.feign.inter.project.ISimulationTaskFeignClient;
|
||||
import com.sdm.common.log.annotation.SysLog;
|
||||
@@ -11,6 +12,7 @@ import com.sdm.project.model.resp.ProjectDifficultStatisticsResp;
|
||||
import com.sdm.project.model.resp.TaskCountResp;
|
||||
import com.sdm.project.model.resp.TaskWorkDaysResp;
|
||||
import com.sdm.project.model.resp.UserWorkloadResp;
|
||||
import com.sdm.common.entity.resp.project.SpdmTaskVo;
|
||||
import com.sdm.project.service.ISimulationTaskService;
|
||||
import com.sdm.project.service.ITaskService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
@@ -145,7 +147,7 @@ public class SimulationTaskController implements ISimulationTaskFeignClient {
|
||||
*/
|
||||
@PostMapping("/getTaskDetail")
|
||||
@Operation(summary = "获取任务详情", description = "获取任务详情")
|
||||
public SdmResponse getTaskDetail(@RequestBody @Validated GetTaskDetailReq req) {
|
||||
public SdmResponse<SpdmTaskVo> getTaskDetail(@RequestBody @Validated GetTaskDetailReq req) {
|
||||
return taskService.getTaskDetail(req);
|
||||
}
|
||||
|
||||
|
||||
@@ -59,7 +59,7 @@ public interface SimulationNodeMapper extends BaseMapper<SimulationNode> {
|
||||
|
||||
void deletePerformanceBatch(@Param("performanceIdList") List<Long> performanceIdList);
|
||||
|
||||
void deletePerformanceExtraBatch(@Param("performanceIdList") List<Long> performanceIdList);
|
||||
void deletePerformanceExtraBatch(@Param("performanceIdList") List<String> performanceIdList);
|
||||
|
||||
List<TaskNodePo> getTaskListByNodeIdList(@Param("deleteNodeIdList") List<String> deleteNodeIdList);
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.sdm.project.dao;
|
||||
|
||||
|
||||
import com.sdm.common.entity.resp.project.SimulationNodeResp;
|
||||
import com.sdm.common.entity.resp.project.TaskNodeExtraPo;
|
||||
import com.sdm.project.model.bo.*;
|
||||
import com.sdm.project.model.po.*;
|
||||
import com.sdm.project.model.req.ProjectTreeReq;
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
package com.sdm.project.dao;
|
||||
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.sdm.common.common.SdmResponse;
|
||||
import com.sdm.common.entity.resp.project.SpdmTaskVo;
|
||||
import com.sdm.project.model.entity.SimulationTask;
|
||||
import com.sdm.project.model.po.TaskNodeExtraPo;
|
||||
import com.sdm.common.entity.resp.project.TaskNodeExtraPo;
|
||||
import com.sdm.project.model.req.SpdmAnalysisTaskListReq;
|
||||
import com.sdm.project.model.req.*;
|
||||
import com.sdm.project.model.resp.ProjectDifficultStatisticsResp;
|
||||
import com.sdm.project.model.vo.*;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
@@ -3,9 +3,7 @@ package com.sdm.project.model.bo;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.sdm.common.entity.pojo.BaseEntity;
|
||||
import com.sdm.common.entity.resp.system.CIDUserResp;
|
||||
import com.sdm.project.model.po.ProjectNodeExtraPo;
|
||||
import com.sdm.project.model.po.TaskNodeExtraPo;
|
||||
import com.sdm.project.model.po.TaskNodeMemberPo;
|
||||
import lombok.Data;
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ package com.sdm.project.model.po;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.sdm.common.entity.pojo.BaseEntity;
|
||||
import com.sdm.common.entity.resp.project.TaskNodeExtraPo;
|
||||
import com.sdm.common.entity.resp.system.CIDUserResp;
|
||||
import lombok.Data;
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@ package com.sdm.project.model.req;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.sdm.project.model.entity.SimulationTaskExtra;
|
||||
import com.sdm.project.model.po.TaskNodeExtraPo;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -4,7 +4,7 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.sdm.common.entity.pojo.BaseEntity;
|
||||
import com.sdm.common.entity.resp.system.CIDUserResp;
|
||||
import com.sdm.project.model.po.TaskNodeExtraPo;
|
||||
import com.sdm.common.entity.resp.project.TaskNodeExtraPo;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -5,6 +5,7 @@ import com.sdm.common.common.SdmResponse;
|
||||
import com.sdm.common.entity.req.export.PerformanceAnalysisExportExcelFormat;
|
||||
import com.sdm.common.entity.req.export.RunAnalysisExportExcelFormat;
|
||||
import com.sdm.common.entity.req.export.TaskAnalysisExportExcelFormat;
|
||||
import com.sdm.common.entity.req.project.GetTaskDetailReq;
|
||||
import com.sdm.common.entity.req.task.TaskExportExcelFormat;
|
||||
import com.sdm.common.entity.req.task.TaskTreeExportExcelFormat;
|
||||
import com.sdm.project.model.bo.ModifyTaskNode;
|
||||
@@ -12,6 +13,7 @@ import com.sdm.project.model.req.*;
|
||||
import com.sdm.project.model.req.YA.SyncCidTaskReq;
|
||||
import com.sdm.project.model.resp.*;
|
||||
import com.sdm.project.model.resp.YA.BosimSaveProjectTaskRsp;
|
||||
import com.sdm.common.entity.resp.project.SpdmTaskVo;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@@ -57,7 +59,7 @@ public interface ITaskService {
|
||||
|
||||
// SdmResponse synchronizeCidTask(SpdmSyncCidTaskReq req);
|
||||
|
||||
SdmResponse getTaskDetail(GetTaskDetailReq req);
|
||||
SdmResponse<SpdmTaskVo> getTaskDetail(GetTaskDetailReq req);
|
||||
|
||||
BosimSaveProjectTaskRsp syncCidTask(SyncCidTaskReq req);
|
||||
|
||||
|
||||
@@ -18,11 +18,11 @@ import com.sdm.common.entity.req.system.SendMsgReq;
|
||||
import com.sdm.common.entity.req.system.UserQueryReq;
|
||||
import com.sdm.common.entity.req.task.DemandExportExcelFormat;
|
||||
import com.sdm.common.entity.req.task.DemandExportExcelParam;
|
||||
import com.sdm.common.entity.resp.project.SpdmTaskVo;
|
||||
import com.sdm.common.entity.resp.system.CIDUserResp;
|
||||
import com.sdm.common.feign.impl.data.DataClientFeignClientImpl;
|
||||
import com.sdm.common.feign.impl.system.MessageFeignClientImpl;
|
||||
import com.sdm.common.feign.impl.system.SysUserFeignClientImpl;
|
||||
import com.sdm.common.feign.inter.data.IDataFeignClient;
|
||||
import com.sdm.common.service.BaseService;
|
||||
import com.sdm.common.utils.RandomUtil;
|
||||
import com.sdm.common.utils.excel.ExcelUtil;
|
||||
|
||||
@@ -303,7 +303,7 @@ public class NodeServiceImpl extends ServiceImpl<SimulationNodeMapper, Simulatio
|
||||
}
|
||||
List<Long> performanceIdList = performanceNodePoList.stream().map(PerformanceNodePo::getId).toList();
|
||||
nodeMapper.deletePerformanceBatch(performanceIdList);
|
||||
nodeMapper.deletePerformanceExtraBatch(performanceIdList);
|
||||
nodeMapper.deletePerformanceExtraBatch(performanceNodePoList.stream().map(PerformanceNodePo::getUuid).toList());
|
||||
}
|
||||
List<SpdmNodeVo> childrenNodeList = nodeMapper.getNodeListByNodeIdList(deleteNodeIdList);
|
||||
if (CollectionUtils.isEmpty(childrenNodeList)) {
|
||||
|
||||
@@ -15,6 +15,7 @@ import com.sdm.common.entity.req.system.UserQueryReq;
|
||||
import com.sdm.common.entity.req.task.TaskTreeExportExcelFormat;
|
||||
import com.sdm.common.entity.req.task.TaskTreeExportExcelParam;
|
||||
import com.sdm.common.entity.resp.data.FileMetadataInfoResp;
|
||||
import com.sdm.common.entity.resp.project.TaskNodeExtraPo;
|
||||
import com.sdm.common.entity.resp.system.CIDUserResp;
|
||||
import com.sdm.common.feign.impl.data.DataClientFeignClientImpl;
|
||||
import com.sdm.common.feign.impl.system.MessageFeignClientImpl;
|
||||
|
||||
@@ -13,7 +13,6 @@ import com.sdm.common.config.FlowableConfig;
|
||||
import com.sdm.common.entity.constants.NumberConstants;
|
||||
import com.sdm.common.entity.enums.ApproveTypeEnum;
|
||||
import com.sdm.common.entity.enums.DirTypeEnum;
|
||||
import com.sdm.common.entity.enums.FileBizTypeEnum;
|
||||
import com.sdm.common.entity.enums.NodeTypeEnum;
|
||||
import com.sdm.common.entity.flowable.dto.FlowElementDTO;
|
||||
import com.sdm.common.entity.flowable.dto.ProcessDefinitionDTO;
|
||||
@@ -56,7 +55,7 @@ import com.sdm.project.model.resp.FlowInfoDto;
|
||||
import com.sdm.project.model.resp.KeyResultAndTaskInfoResp;
|
||||
import com.sdm.project.model.resp.RunVersionInfoResp;
|
||||
import com.sdm.project.model.vo.SpdmNodeVo;
|
||||
import com.sdm.project.model.vo.SpdmTaskVo;
|
||||
import com.sdm.common.entity.resp.project.SpdmTaskVo;
|
||||
import com.sdm.project.service.*;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@@ -65,7 +64,6 @@ import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.mock.web.MockMultipartFile;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
@@ -16,7 +16,7 @@ import com.sdm.project.model.entity.SimulationWork;
|
||||
import com.sdm.project.model.req.SpdmWorkListReq;
|
||||
import com.sdm.project.model.req.SpdmWorkReq;
|
||||
import com.sdm.project.model.vo.SpdmTaskMemberVo;
|
||||
import com.sdm.project.model.vo.SpdmTaskVo;
|
||||
import com.sdm.common.entity.resp.project.SpdmTaskVo;
|
||||
import com.sdm.project.service.ISimulationWorkService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
|
||||
@@ -17,6 +17,7 @@ import com.sdm.common.entity.req.data.DelDirReq;
|
||||
import com.sdm.common.entity.req.data.QueryFileReq;
|
||||
import com.sdm.common.entity.req.data.UpdatePermissionReq;
|
||||
import com.sdm.common.entity.req.export.*;
|
||||
import com.sdm.common.entity.req.project.GetTaskDetailReq;
|
||||
import com.sdm.common.entity.req.project.SimulationPerformance;
|
||||
import com.sdm.common.entity.req.system.QueryGroupDetailReq;
|
||||
import com.sdm.common.entity.req.system.SendMsgReq;
|
||||
@@ -29,13 +30,14 @@ import com.sdm.common.entity.req.task.TaskTreeExportExcelParam;
|
||||
import com.sdm.common.entity.resp.PageDataResp;
|
||||
import com.sdm.common.entity.resp.capability.FlowTemplateResp;
|
||||
import com.sdm.common.entity.resp.data.FileMetadataInfoResp;
|
||||
import com.sdm.common.entity.resp.project.SpdmTaskVo;
|
||||
import com.sdm.common.entity.resp.project.TaskNodeExtraPo;
|
||||
import com.sdm.common.entity.resp.system.CIDUserResp;
|
||||
import com.sdm.common.entity.resp.system.SysUserGroupDetailResp;
|
||||
import com.sdm.common.feign.impl.capability.SimulationFlowFeignClientImpl;
|
||||
import com.sdm.common.feign.impl.data.DataClientFeignClientImpl;
|
||||
import com.sdm.common.feign.impl.system.MessageFeignClientImpl;
|
||||
import com.sdm.common.feign.impl.system.SysUserFeignClientImpl;
|
||||
import com.sdm.common.utils.RandomUtil;
|
||||
import com.sdm.common.utils.SystemOperate;
|
||||
import com.sdm.common.utils.excel.ExcelUtil;
|
||||
import com.sdm.project.bo.ExportOperate;
|
||||
@@ -1696,7 +1698,7 @@ public class TaskServiceImpl implements ITaskService {
|
||||
// }
|
||||
|
||||
@Override
|
||||
public SdmResponse getTaskDetail(GetTaskDetailReq req) {
|
||||
public SdmResponse<SpdmTaskVo> getTaskDetail(GetTaskDetailReq req) {
|
||||
log.info("getTaskDetail参数为:{}", req);
|
||||
SpdmTaskVo taskVo = mapper.getTask(req.getRelatedResourceUuid());
|
||||
if (ObjectUtils.isEmpty(taskVo)) {
|
||||
|
||||
@@ -338,7 +338,7 @@
|
||||
SELECT * FROM simulation_node_extra WHERE nodeId=#{projectNodeId}
|
||||
</select>
|
||||
|
||||
<select id="queryProjectNodeItemExtraList" resultType="com.sdm.project.model.po.TaskNodeExtraPo">
|
||||
<select id="queryProjectNodeItemExtraList" resultType="com.sdm.common.entity.resp.project.TaskNodeExtraPo">
|
||||
SELECT * FROM simulation_task_extra WHERE nodeId=#{projectNodeId}
|
||||
</select>
|
||||
|
||||
@@ -546,7 +546,7 @@
|
||||
)
|
||||
</select>
|
||||
|
||||
<select id="queryTaskNodeExtrasByNodeIdList" resultType="com.sdm.project.model.po.TaskNodeExtraPo">
|
||||
<select id="queryTaskNodeExtrasByNodeIdList" resultType="com.sdm.common.entity.resp.project.TaskNodeExtraPo">
|
||||
select * from simulation_task_extra where task_id in (
|
||||
<foreach collection='taskIdList' item='taskId' index='index' separator=','>
|
||||
#{taskId}
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
|
||||
<select id="list" resultType="com.sdm.common.common.SdmResponse"></select>
|
||||
|
||||
<select id="getTaskList" resultType="com.sdm.project.model.vo.SpdmTaskVo">
|
||||
<select id="getTaskList" resultType="com.sdm.common.entity.resp.project.SpdmTaskVo">
|
||||
select * from simulation_task where tenant_id = #{tenantId}
|
||||
<if test="req.demandId != null and req.demandId != ''">
|
||||
and demand_id = #{req.demandId}
|
||||
@@ -172,7 +172,7 @@
|
||||
)
|
||||
</select>
|
||||
|
||||
<select id="getTaskListByDemandIdList" resultType="com.sdm.project.model.vo.SpdmTaskVo">
|
||||
<select id="getTaskListByDemandIdList" resultType="com.sdm.common.entity.resp.project.SpdmTaskVo">
|
||||
select * from simulation_task where demand_id in (
|
||||
<foreach collection='demandIdList' item='demandId' index='index' separator=','>
|
||||
#{demandId}
|
||||
@@ -180,7 +180,7 @@
|
||||
)
|
||||
</select>
|
||||
|
||||
<select id="getTask" resultType="com.sdm.project.model.vo.SpdmTaskVo">
|
||||
<select id="getTask" resultType="com.sdm.common.entity.resp.project.SpdmTaskVo">
|
||||
select * from simulation_task where uuid = #{taskId} limit 1;
|
||||
</select>
|
||||
|
||||
@@ -234,7 +234,7 @@
|
||||
</if>
|
||||
</select>
|
||||
|
||||
<select id="getTaskById" resultType="com.sdm.project.model.vo.SpdmTaskVo">
|
||||
<select id="getTaskById" resultType="com.sdm.common.entity.resp.project.SpdmTaskVo">
|
||||
select * from simulation_task where id = #{id}
|
||||
</select>
|
||||
|
||||
@@ -362,7 +362,7 @@
|
||||
</where>
|
||||
</select>
|
||||
|
||||
<select id="getTaskExtraList" resultType="com.sdm.project.model.po.TaskNodeExtraPo">
|
||||
<select id="getTaskExtraList" resultType="com.sdm.common.entity.resp.project.TaskNodeExtraPo">
|
||||
select * from simulation_task_extra where task_id in
|
||||
(
|
||||
<foreach collection='taskIdList' item='taskId' index='index' separator=','>
|
||||
@@ -371,11 +371,11 @@
|
||||
)
|
||||
</select>
|
||||
|
||||
<select id="getTaskListByDemandId" resultType="com.sdm.project.model.vo.SpdmTaskVo">
|
||||
<select id="getTaskListByDemandId" resultType="com.sdm.common.entity.resp.project.SpdmTaskVo">
|
||||
select * from simulation_task where demand_id = #{demandId}
|
||||
</select>
|
||||
|
||||
<select id="getTaskListByTag" resultType="com.sdm.project.model.vo.SpdmTaskVo">
|
||||
<select id="getTaskListByTag" resultType="com.sdm.common.entity.resp.project.SpdmTaskVo">
|
||||
select * from simulation_task task
|
||||
<where>
|
||||
task.exe_status is not null
|
||||
@@ -412,7 +412,7 @@
|
||||
</where>
|
||||
</select>
|
||||
|
||||
<select id="getTaskListByName" resultType="com.sdm.project.model.vo.SpdmTaskVo">
|
||||
<select id="getTaskListByName" resultType="com.sdm.common.entity.resp.project.SpdmTaskVo">
|
||||
select * from simulation_task where task_name in
|
||||
(
|
||||
<foreach collection='taskNameList' item='taskName' index='index' separator=','>
|
||||
|
||||
Reference in New Issue
Block a user