异常返回问题修复

This commit is contained in:
zjh 2025-12-04 10:59:30 +08:00
parent 7645274ead
commit 4baec85078
18 changed files with 477 additions and 170 deletions

View File

@ -28,52 +28,6 @@ import java.util.stream.Collectors;
public class DeleteController { public class DeleteController {
@Resource @Resource
private BusinessDatabase bd; private BusinessDatabase bd;
@Autowired
private ApaasMyTokenFeign apaasMyTokenFeign;
@PostMapping("/uploadFile")
public Response uploadFile(@RequestPart("file") MultipartFile file) {
Map<String, Object> map = new HashMap<>();
AppTokenDTO token = apaasMyTokenFeign.getAppToken(
"client_credentials",
"2b5b3de8-e7fd-406a-a59a-d5568457b1f4",
"94bddc6a-27a4-4204-885b-b075812ec535"
);
map.put("appToken", token);
log.info("loginVo token:{}", token);
UserTokenDT0 userToken = apaasMyTokenFeign.getUserToken(
token.getAccess_token(),
"100771325212057665536"
);
map.put("userToken", userToken);
log.info("loginVo userToken:{}", userToken);
String uploadId = new ObjectId().toHexString();
FileUploadDTO fileUploadDTO = apaasMyTokenFeign.uploadFile(
"Bearer " + userToken.getAccess_token(),
"application/x-www-form-urlencoded",
file,
uploadId,
"223770822127386625",
"100771325212057665536"
);
map.put("fileUploadDTO", fileUploadDTO);
log.info("loginVo fileUploadDTO:{}", fileUploadDTO);
return Response.ok().data(map);
}
@GetMapping("/downloadFile")
public Response downloadFile(
@RequestParam String url
) {
Map<String, String> map = new HashMap<>();
map.put("xdaptenantid", "223770822127386625");
cn.hutool.json.JSON json = JSONUtil.parse(map);
String token = Base64.encode(json.toString());
String realUrl = url +"&download=download&token="+token;
return Response.ok().data(realUrl);
}
@GetMapping("getAll") @GetMapping("getAll")
public Response getAll() { public Response getAll() {
@ -93,44 +47,53 @@ public class DeleteController {
@GetMapping("/deleteAll") @GetMapping("/deleteAll")
@Transactional @Transactional
public Response deleteAll(@RequestParam String templateRowId) { public Response deleteAll(@RequestParam String version) {
Template template = bd.getBusinessDatabase().rowid("id", templateRowId).doQueryFirst(Template.class); List<Template> templates = bd.getBusinessDatabase()
List<TemplateAndParameter> templateAndParameters = bd.getBusinessDatabase() .eq("version", version)
.eq("template_id", template.getId()) .doQuery(Template.class);
.doQuery(TemplateAndParameter.class);
List<String> ids = templateAndParameters.stream()
.map(TemplateAndParameter::getId)
.collect(Collectors.toList());
List<String> parameterIds = templateAndParameters.stream()
.map(TemplateAndParameter::getParameterId)
.collect(Collectors.toList());
List<RevisionRecord> revisionRecords = bd.getBusinessDatabase()
.eq("template_id", template.getId())
.doQuery(RevisionRecord.class);
List<String> rIds = revisionRecords.stream()
.map(RevisionRecord::getId)
.collect(Collectors.toList());
if (!parameterIds.isEmpty()) { for (Template template : templates) {
bd.getBusinessDatabase() List<TemplateAndParameter> templateAndParameters = bd.getBusinessDatabase()
.in("id", parameterIds) .eq("template_id", template.getId())
.doDelete(Parameter.class); .doQuery(TemplateAndParameter.class);
}
if (!ids.isEmpty()) {
bd.getBusinessDatabase()
.in("id", ids)
.doDelete(TemplateAndParameter.class);
}
if (template.getId() != null) { List<String> ids = templateAndParameters.stream()
bd.getBusinessDatabase() .map(TemplateAndParameter::getId)
.eq("id", template.getId()) .collect(Collectors.toList());
.doDelete(Template.class);
} List<String> parameterIds = templateAndParameters.stream()
if (!rIds.isEmpty()) { .map(TemplateAndParameter::getParameterId)
bd.getBusinessDatabase() .collect(Collectors.toList());
.in("id", rIds)
.doDelete(RevisionRecord.class); List<RevisionRecord> revisionRecords = bd.getBusinessDatabase()
.eq("template_id", template.getId())
.doQuery(RevisionRecord.class);
List<String> rIds = revisionRecords.stream()
.map(RevisionRecord::getId)
.collect(Collectors.toList());
if (!parameterIds.isEmpty()) {
bd.getBusinessDatabase()
.in("id", parameterIds)
.doDelete(Parameter.class);
}
if (!ids.isEmpty()) {
bd.getBusinessDatabase()
.in("id", ids)
.doDelete(TemplateAndParameter.class);
}
if (template.getId() != null) {
bd.getBusinessDatabase()
.eq("id", template.getId())
.doDelete(Template.class);
}
if (!rIds.isEmpty()) {
bd.getBusinessDatabase()
.in("id", rIds)
.doDelete(RevisionRecord.class);
}
} }
return Response.ok(); return Response.ok();
} }

View File

@ -1,10 +1,86 @@
package com.xdap.self_development.controller; package com.xdap.self_development.controller;
import org.springframework.web.bind.annotation.RequestMapping; import com.definesys.mpaas.common.http.Response;
import org.springframework.web.bind.annotation.RestController; import com.definesys.mpaas.query.db.PageQueryResult;
import com.xdap.self_development.controller.form.InsertRoleForm;
import com.xdap.self_development.controller.form.UpdateRoleForm;
import com.xdap.self_development.controller.form.UserRoleAndPermissionPageForm;
import com.xdap.self_development.exception.CommonException;
import com.xdap.self_development.pojo.Permission;
import com.xdap.self_development.pojo.view.UserRoleAndPermissionView;
import com.xdap.self_development.service.PermissionService;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import java.util.List;
@RestController @RestController
@RequestMapping("/custom/permission") @RequestMapping("/custom/permission")
public class PermissionController { public class PermissionController {
// 查看 @Resource
private PermissionService permissionService;
// 查询所有权限
@GetMapping("/getAllPermission")
public Response getAllPermission() {
List<Permission> list = permissionService.getAllPermission();
return Response.ok().data(list);
}
// 查看全部角色的用户和权限
@GetMapping("/getUserRoleAndPermission")
public Response getUserRoleAndPermission(
@Valid UserRoleAndPermissionPageForm form,
BindingResult bindingResult
) {
if (bindingResult.hasErrors()) {
bindingResult.getFieldErrors().forEach(error -> {
throw new CommonException(error.getDefaultMessage());
});
}
PageQueryResult<UserRoleAndPermissionView> list = permissionService.getUserRoleAndPermission(form);
return Response.ok().data(list);
}
// 新增角色
@PostMapping("/insertRole")
public Response insertRole(
@Valid @RequestBody InsertRoleForm form,
BindingResult bindingResult
) {
if (bindingResult.hasErrors()) {
bindingResult.getFieldErrors().forEach(error -> {
throw new CommonException(error.getDefaultMessage());
});
}
permissionService.insertRole(form);
return Response.ok().setMessage("新增角色成功");
}
// 修改角色
@PostMapping("updateRole")
public Response updateRole(
@Valid @RequestBody UpdateRoleForm form,
BindingResult bindingResult
) {
if (bindingResult.hasErrors()) {
bindingResult.getFieldErrors().forEach(error -> {
throw new CommonException(error.getDefaultMessage());
});
}
permissionService.updateRole(form);
return Response.ok().setMessage("修改角色成功");
}
// 删除角色
@GetMapping("/deleteRole")
public Response deleteRole(
@NotBlank String roleId
) {
permissionService.deleteRole(roleId);
return Response.ok().setMessage("删除角色成功");
}
} }

View File

@ -78,7 +78,7 @@ public class TemplateController {
MyResponse templateImportProblemView = templateService.importTemplate(file, templateRowId, createBy); MyResponse templateImportProblemView = templateService.importTemplate(file, templateRowId, createBy);
if (templateImportProblemView.getFlag()) { if (templateImportProblemView.getFlag()) {
return Response.error("导入失败").data(templateImportProblemView); return Response.error("导入异常").data(templateImportProblemView);
} else { } else {
return Response.ok().setMessage("导入成功"); return Response.ok().setMessage("导入成功");
} }

View File

@ -0,0 +1,17 @@
package com.xdap.self_development.controller.form;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotEmpty;
import java.util.List;
@Data
public class InsertRoleForm {
@NotBlank(message = "角色名不能为空")
private String roleName;
@NotEmpty(message = "至少选择一个用户")
private List<String> users;
@NotEmpty(message = "至少选择以一个权限")
private List<String> permissions;
}

View File

@ -33,6 +33,5 @@ public class ParameterForm {
private String remarks; private String remarks;
@NotNull(message = "操作不能为null")
private String operation; private String operation;
} }

View File

@ -1,14 +0,0 @@
package com.xdap.self_development.controller.form;
import lombok.Data;
import java.sql.Timestamp;
@Data
public class TodoResponse {
private Long flowId;
private Long templateId;
private String templateName;
private String currentNode;
private Timestamp createTime;
}

View File

@ -0,0 +1,15 @@
package com.xdap.self_development.controller.form;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import java.util.List;
@Data
public class UpdateRoleForm {
@NotBlank(message = "请选择修改的用户")
private String roleId;
private String roleName;
private List<String> users;
private List<String> permissions;
}

View File

@ -0,0 +1,17 @@
package com.xdap.self_development.controller.form;
import lombok.Data;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
@Data
public class UserRoleAndPermissionPageForm {
@NotNull(message = "页码不能为空")
@Min(value = 1, message = "页码不能小于1")
private Integer pageNumber;
@NotNull(message = "每页条数不能为空")
@Min(value = 1, message = "每页条数不能小于1")
private Integer pageSize;
}

View File

@ -10,7 +10,7 @@ import lombok.EqualsAndHashCode;
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
@Data @Data
@Table("yfsjglpt_model_permissions") @Table("yfsjglpt_model_permissions")
public class Permissions extends MpaasBasePojo { public class Permission extends MpaasBasePojo {
@RowID(value = "permissions_s", type = RowIDType.UUID) @RowID(value = "permissions_s", type = RowIDType.UUID)
private String id; private String id;
private String permissionName; private String permissionName;

View File

@ -4,9 +4,13 @@ import com.definesys.mpaas.query.annotation.RowID;
import com.definesys.mpaas.query.annotation.RowIDType; import com.definesys.mpaas.query.annotation.RowIDType;
import com.definesys.mpaas.query.annotation.Table; import com.definesys.mpaas.query.annotation.Table;
import com.definesys.mpaas.query.model.MpaasBasePojo; import com.definesys.mpaas.query.model.MpaasBasePojo;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import org.bouncycastle.util.Times;
import java.sql.Timestamp;
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
@Data @Data
@ -21,13 +25,19 @@ public class RevisionRecord extends MpaasBasePojo {
private String modifyDetails; private String modifyDetails;
private String templateId; private String templateId;
private String preTemplateId; private String preTemplateId;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Timestamp createdTime;
public RevisionRecord(String templateName, Integer version, Integer parameterNumber, String modifyDetails, String templateId, String preTemplateId) { public RevisionRecord(String templateName, Integer version,
Integer parameterNumber, String modifyDetails,
String templateId, String preTemplateId,
Timestamp createdTime) {
this.templateName = templateName; this.templateName = templateName;
this.version = version; this.version = version;
this.parameterNumber = parameterNumber; this.parameterNumber = parameterNumber;
this.modifyDetails = modifyDetails; this.modifyDetails = modifyDetails;
this.templateId = templateId; this.templateId = templateId;
this.preTemplateId = preTemplateId; this.preTemplateId = preTemplateId;
this.createdTime = createdTime;
} }
} }

View File

@ -8,7 +8,7 @@ import lombok.Data;
@SQL(view = "getUserByDepartment", @SQL(view = "getUserByDepartment",
sql = "SELECT u.id AS \"userId\", u.username AS \"username\", u.user_number AS \"userNumber\", d.id AS \"departmentId\", d.name AS \"department\" FROM xdap_users u LEFT JOIN xdap_dept_users du ON du.user_id = u.id LEFT JOIN xdap_departments d ON d.id = du.department_id WHERE u.exit_status = 'ENABLE' and d.id = #departmentId"), sql = "SELECT u.id AS \"userId\", u.username AS \"username\", u.user_number AS \"userNumber\", d.id AS \"departmentId\", d.name AS \"department\" FROM xdap_users u LEFT JOIN xdap_dept_users du ON du.user_id = u.id LEFT JOIN xdap_departments d ON d.id = du.department_id WHERE u.exit_status = 'ENABLE' and d.id = #departmentId"),
@SQL(view = "getUserAndDept", @SQL(view = "getUserAndDept",
sql = "SELECT u.id AS \"userId\", u.username AS \"username\", d.name AS \"department\" FROM xdap_users u LEFT JOIN xdap_dept_users du ON u.id = du.user_id LEFT JOIN xdap_departments d ON d.id = du.department_id") sql = "SELECT u.id AS \"userId\", u.username AS \"username\", u.user_number AS \"userNumber\", d.name AS \"department\" FROM xdap_users u LEFT JOIN xdap_dept_users du ON u.id = du.user_id LEFT JOIN xdap_departments d ON d.id = du.department_id")
}) })
@Data @Data

View File

@ -0,0 +1,19 @@
package com.xdap.self_development.pojo.view;
import com.definesys.mpaas.query.annotation.SQL;
import com.definesys.mpaas.query.annotation.SQLQuery;
import lombok.Data;
import java.util.List;
@SQLQuery(value = {
@SQL(view = "getAllRoleUserAndPerm",
sql = "SELECT r.id as roleId, r.role_name as roleName, GROUP_CONCAT(DISTINCT u.username) AS userNames , GROUP_CONCAT(DISTINCT p.permission_name) AS permissionNames FROM yfsjglpt_model_roles r LEFT JOIN yfsjglpt_model_user_roles ur ON r.id = ur.role_id LEFT JOIN yfsjglpt_model_role_permissions rp ON r.id = rp.role_id LEFT JOIN yfsjglpt_model_permissions p ON rp.permission_id = p.id LEFT JOIN xdap_users u ON u.id = ur.user_id GROUP BY r.id, r.role_name, r.description ORDER BY r.role_name")
})
@Data
public class UserRoleAndPermissionView {
private String roleId;
private String roleName;
private String userNames;
private String permissionNames;
}

View File

@ -0,0 +1,24 @@
package com.xdap.self_development.service;
import com.definesys.mpaas.query.db.PageQueryResult;
import com.xdap.self_development.controller.form.InsertRoleForm;
import com.xdap.self_development.controller.form.UpdateRoleForm;
import com.xdap.self_development.controller.form.UserRoleAndPermissionPageForm;
import com.xdap.self_development.pojo.Permission;
import com.xdap.self_development.pojo.view.UserRoleAndPermissionView;
import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import java.util.List;
public interface PermissionService {
PageQueryResult<UserRoleAndPermissionView> getUserRoleAndPermission(@Valid UserRoleAndPermissionPageForm form);
void insertRole(@Valid InsertRoleForm form);
List<Permission> getAllPermission();
void updateRole(@Valid UpdateRoleForm form);
void deleteRole(@NotBlank String roleId);
}

View File

@ -21,6 +21,7 @@ import com.xdap.self_development.pojo.view.ApprovalFlowView;
import com.xdap.self_development.pojo.view.ApprovalNodeView; import com.xdap.self_development.pojo.view.ApprovalNodeView;
import com.xdap.self_development.pojo.view.TodoAndReportView; import com.xdap.self_development.pojo.view.TodoAndReportView;
import com.xdap.self_development.service.BenchmarkingReportService; import com.xdap.self_development.service.BenchmarkingReportService;
import com.xdap.self_development.utils.RedisLockUtil;
import org.bson.types.ObjectId; import org.bson.types.ObjectId;
import org.springframework.beans.BeanUtils; import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@ -46,6 +47,8 @@ public class BenchmarkingReportServiceImpl implements BenchmarkingReportService
private RuntimeAppContextService runtimeAppContextService; private RuntimeAppContextService runtimeAppContextService;
@Autowired @Autowired
private ApaasMyTokenFeign apaasMyTokenFeign; private ApaasMyTokenFeign apaasMyTokenFeign;
@Resource
private RedisLockUtil redisLockUtil;
@Value("${apaas.token.clientId}") @Value("${apaas.token.clientId}")
private String clientId; private String clientId;
@ -56,7 +59,7 @@ public class BenchmarkingReportServiceImpl implements BenchmarkingReportService
private static final String TODO_PREFIX = "report:todo:"; private static final String TODO_PREFIX = "report:todo:";
private static final String NODE_PROCESSED_PREFIX = "report:node:processed:"; private static final String NODE_PROCESSED_PREFIX = "report:node:processed:";
private static final String FLOW_LOCK_PREFIX = "report:lock:"; private static final String FLOW_LOCK_PREFIX = "report:lock:";
private static final int FLOW_LOCK_EXPIRE_SECONDS = 5; private static final int FLOW_LOCK_EXPIRE_SECONDS = 15;
@Override @Override
@Transactional(rollbackFor = CommonException.class) @Transactional(rollbackFor = CommonException.class)
@ -201,26 +204,28 @@ public class BenchmarkingReportServiceImpl implements BenchmarkingReportService
if (!"COUNTERSIGN".equals(currentNode)) { if (!"COUNTERSIGN".equals(currentNode)) {
String lockKey = FLOW_LOCK_PREFIX + flow.getId() + ":" + currentNode; String lockKey = FLOW_LOCK_PREFIX + flow.getId() + ":" + currentNode;
Boolean lock = redisTemplate.opsForValue().setIfAbsent(lockKey, "1", FLOW_LOCK_EXPIRE_SECONDS, TimeUnit.SECONDS); String lockValue = UUID.randomUUID().toString();
if (Boolean.FALSE.equals(lock)) { boolean lockAcquired = redisLockUtil
.tryLock(lockKey, lockValue, FLOW_LOCK_EXPIRE_SECONDS, TimeUnit.SECONDS);
if (!lockAcquired) {
throw new CommonException("当前节点正在处理,请稍后重试"); throw new CommonException("当前节点正在处理,请稍后重试");
} }
try { try {
// 校验抢签节点是否已被处理
String processedKey = NODE_PROCESSED_PREFIX + flow.getId() + ":" + currentNode; String processedKey = NODE_PROCESSED_PREFIX + flow.getId() + ":" + currentNode;
long result = Optional.ofNullable(redisTemplate.opsForSet().size(processedKey)) long processedCount = Optional.ofNullable(redisTemplate.opsForSet().size(processedKey))
.orElse(0L); .orElse(0L);
if (result > 0) { if (processedCount > 0) {
throw new CommonException("此节点已被他人处理"); throw new CommonException("此节点已被他人处理");
} }
processApprovalLogic(flow, request, currentNode); processApprovalLogic(flow, request, currentNode);
} finally { } finally {
redisTemplate.delete(lockKey); redisLockUtil.unlock(lockKey, lockValue);
} }
} else { } else {
processApprovalLogic(flow, request, currentNode); processApprovalLogic(flow, request, currentNode);
} }
} }
@Override @Override

View File

@ -67,34 +67,49 @@ public class ParameterServiceImpl implements ParameterService {
} }
} }
}); });
// 获取基准模板和最新模板 // 获取基准模板和最新模板
TemplateBenchmark benchmark = getTemplateBenchmark(form.getTemplateRowId()); TemplateBenchmark benchmark = getTemplateBenchmark(form.getTemplateRowId());
// 创建新版本模板
Template newTemplate; Template newVersionTemplate;
if (benchmark.getParameters().isEmpty()) { // 如果当前修改的模板为最新版并且为草稿状态就不需要新建版本
newTemplate = benchmark.getBaseTemplate(); if (Objects.equals(benchmark.getLastTemplate().getId(), benchmark.getBaseTemplate().getId())
} else { && Objects.equals(benchmark.getBaseTemplate().getStatus(), "DRAFT")
newTemplate = new Template( && Objects.equals(benchmark.getLastTemplate().getStatus(), "DRAFT")) {
if (!benchmark.getParameters().isEmpty()) {
// 清除原来的关联关系
bd.getBusinessDatabase().eq("template_id", benchmark.getBaseTemplate().getId()).doDelete(TemplateAndParameter.class);
List<String> parameterIds = benchmark.getParameters().stream().map(Parameter::getId).collect(Collectors.toList());
bd.getBusinessDatabase().in("id", parameterIds).doDelete(Parameter.class);
}
newVersionTemplate = benchmark.getBaseTemplate();
}
// 否则创建新版本
else {
newVersionTemplate = new Template(
benchmark.getLastTemplate().getTemplateName(), calculateNextVersion(benchmark.getLastTemplate().getVersion()), benchmark.getLastTemplate().getTemplateName(), calculateNextVersion(benchmark.getLastTemplate().getVersion()),
"DRAFT", Timestamp.valueOf(LocalDateTime.now()), null, form.getCreateBy() "DRAFT", Timestamp.valueOf(LocalDateTime.now()), null, form.getCreateBy()
); );
// 保存新模板 // 保存新模板
bd.getBusinessDatabase().doInsert(newTemplate); bd.getBusinessDatabase().doInsert(newVersionTemplate);
} }
// 4. 处理参数变更 // 4. 处理参数变更
ParameterProcessingResult processingResult = processParameters( ParameterProcessingResult processingResult = processParameters(
form.getParameterForms(), form.getParameterForms(),
benchmark.getParameters(), benchmark.getParameters(),
benchmark.getBaseTemplate(), benchmark.getBaseTemplate(),
newTemplate newVersionTemplate
); );
// 5. 保存所有数据 // 5. 保存所有数据
saveAllData(newTemplate, processingResult); saveAllData(newVersionTemplate, processingResult);
TemplateInfoView result = new TemplateInfoView(); TemplateInfoView result = new TemplateInfoView();
result.setTemplateRowId(newTemplate.getRowId());
result.setVersion(newTemplate.getVersion()); result.setTemplateRowId(newVersionTemplate.getRowId());
result.setVersion(newVersionTemplate.getVersion());
return result; return result;
} }
@ -253,7 +268,8 @@ public class ParameterServiceImpl implements ParameterService {
newParameter.getParameterNumber(), newParameter.getParameterNumber(),
"新增参数", "新增参数",
newTemplate.getId(), newTemplate.getId(),
null null,
Timestamp.valueOf(LocalDateTime.now())
)); ));
} }
@ -282,39 +298,41 @@ public class ParameterServiceImpl implements ParameterService {
newTemplate.getTemplateName(), newTemplate.getTemplateName(),
newTemplate.getVersion(), newTemplate.getVersion(),
form.getParameterNumber(), form.getParameterNumber(),
"更新参数:" + detail, detail,
newTemplate.getId(), newTemplate.getId(),
null baseTemplate.getId(),
Timestamp.valueOf(LocalDateTime.now())
)); ));
} }
private String getParameterChange(Parameter originalParameter, Parameter updatedParameter) { private String getParameterChange(Parameter originalParameter, Parameter updatedParameter) {
StringBuilder sb = new StringBuilder(); return handleParameterChange("参数名", originalParameter.getParameterName(), updatedParameter.getParameterName()) +
if (!Objects.equals(originalParameter.getParameterName(), updatedParameter.getParameterName())) { handleParameterChange("参数类型", originalParameter.getParameterType(), updatedParameter.getParameterType()) +
sb.append("参数名:'").append(originalParameter.getParameterName()).append("'变更到'").append(updatedParameter.getParameterName()).append("'\n"); handleParameterChange("子系统", originalParameter.getSubsystemName(), updatedParameter.getSubsystemName()) +
} handleParameterChange("部件名", originalParameter.getPartsName(), updatedParameter.getPartsName()) +
if (!Objects.equals(originalParameter.getParameterType(), updatedParameter.getParameterType())) { handleParameterChange("单位名", originalParameter.getUnit(), updatedParameter.getUnit()) +
sb.append("参数类型:'").append(originalParameter.getParameterType()).append("'变更到'").append(updatedParameter.getParameterType()).append("'\n"); handleParameterChange("参数来源", originalParameter.getParameterSource(), updatedParameter.getParameterSource()) +
} handleParameterChange("公式或编号", originalParameter.getNumberOrFormula(), updatedParameter.getNumberOrFormula()) +
if (!Objects.equals(originalParameter.getSubsystemName(), updatedParameter.getSubsystemName())) { handleParameterChange("部门名", originalParameter.getDepartment(), updatedParameter.getDepartment());
sb.append("子系统:'").append(originalParameter.getSubsystemName()).append("'变更到'").append(updatedParameter.getSubsystemName()).append("'\n"); }
}
if (!Objects.equals(originalParameter.getPartsName(), updatedParameter.getPartsName())) {
sb.append("部件名:'").append(originalParameter.getPartsName()).append("'变更到'").append(updatedParameter.getPartsName()).append("'\n");
}
if (!Objects.equals(originalParameter.getUnit(), updatedParameter.getUnit())) {
sb.append("单位名:'").append(originalParameter.getUnit()).append("'变更到'").append(updatedParameter.getUnit()).append("'\n");
}
if (!Objects.equals(originalParameter.getParameterSource(), updatedParameter.getParameterSource())) {
sb.append("参数来源:'").append(originalParameter.getParameterSource()).append("'变更到'").append(updatedParameter.getParameterSource()).append("'\n");
}
if (!Objects.equals(originalParameter.getNumberOrFormula(), updatedParameter.getNumberOrFormula())) {
sb.append("公式或编号:'").append(originalParameter.getNumberOrFormula()).append("'变更到'").append(updatedParameter.getNumberOrFormula()).append("'\n");
}
if (!Objects.equals(originalParameter.getDepartment(), updatedParameter.getDepartment())) {
sb.append("部门名:'").append(originalParameter.getDepartment()).append("'变更到'").append(updatedParameter.getDepartment()).append("'\n");
}
private String handleParameterChange(String name, String originalParameter, String updatedParameter) {
StringBuilder sb = new StringBuilder();
if (!Objects.equals(originalParameter, updatedParameter)) {
if (originalParameter == null || originalParameter.isEmpty()) {
if (updatedParameter == null || updatedParameter.isEmpty()) {
sb.append(name).append(": ").append("变更为空值").append("\n");
} else {
sb.append(name).append(": ").append("变更为: '").append(updatedParameter).append("' ").append("\n");
}
} else {
if (updatedParameter == null || updatedParameter.isEmpty()) {
sb.append(name).append(": '").append(originalParameter).append("' 变更为 空值").append("\n");
} else {
sb.append(name).append(": '").append(originalParameter).append("' 变更为 '").append(updatedParameter).append("'\n");
}
}
}
return sb.toString(); return sb.toString();
} }
@ -335,7 +353,8 @@ public class ParameterServiceImpl implements ParameterService {
form.getParameterNumber(), form.getParameterNumber(),
"删除参数", "删除参数",
newTemplate.getId(), newTemplate.getId(),
baseTemplate.getId() baseTemplate.getId(),
Timestamp.valueOf(LocalDateTime.now())
)); ));
} }
} }

View File

@ -0,0 +1,143 @@
package com.xdap.self_development.service.impl;
import com.definesys.mpaas.query.db.PageQueryResult;
import com.xdap.self_development.config.BusinessDatabase;
import com.xdap.self_development.controller.form.InsertRoleForm;
import com.xdap.self_development.controller.form.UpdateRoleForm;
import com.xdap.self_development.controller.form.UserRoleAndPermissionPageForm;
import com.xdap.self_development.exception.CommonException;
import com.xdap.self_development.pojo.Permission;
import com.xdap.self_development.pojo.Role;
import com.xdap.self_development.pojo.RoleAndPermissions;
import com.xdap.self_development.pojo.UserAndRoles;
import com.xdap.self_development.pojo.view.UserRoleAndPermissionView;
import com.xdap.self_development.service.PermissionService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
@Service
public class PermissionServiceImpl implements PermissionService {
@Resource
private BusinessDatabase bd;
@Override
public PageQueryResult<UserRoleAndPermissionView> getUserRoleAndPermission(UserRoleAndPermissionPageForm form) {
return bd.getBusinessDatabase()
.viewQueryMode(true)
.view("getAllRoleUserAndPerm")
.doPageQuery(form.getPageNumber(), form.getPageSize(), UserRoleAndPermissionView.class);
}
@Override
@Transactional(rollbackFor = CommonException.class)
public void insertRole(InsertRoleForm form) {
// 查询角色是否重复
List<Role> roles = bd.getBusinessDatabase()
.eq("role_name", form.getRoleName())
.doQuery(Role.class);
if (!roles.isEmpty()) {
throw new CommonException("该角色已创建");
}
// 新增角色
Role role = new Role();
role.setRoleName(form.getRoleName());
role.setDescription("");
bd.getBusinessDatabase().doInsert(role);
// 新增角色和用户角色和权限的关联
List<UserAndRoles> userAndRoles = new ArrayList<>();
for (String userId : form.getUsers()) {
UserAndRoles userAndRole = new UserAndRoles();
userAndRole.setUserId(userId);
userAndRole.setRoleId(role.getId());
userAndRoles.add(userAndRole);
}
List<RoleAndPermissions> roleAndPermissions = new ArrayList<>();
for (String permissionId : form.getPermissions()) {
RoleAndPermissions roleAndPermission = new RoleAndPermissions();
roleAndPermission.setRoleId(role.getId());
roleAndPermission.setPermissionId(permissionId);
roleAndPermissions.add(roleAndPermission);
}
bd.getBusinessDatabase().doBatchInsert(userAndRoles);
bd.getBusinessDatabase().doBatchInsert(roleAndPermissions);
}
@Override
public List<Permission> getAllPermission() {
return bd.getBusinessDatabase().doQuery(Permission.class);
}
@Override
@Transactional(rollbackFor = CommonException.class)
public void updateRole(UpdateRoleForm form) {
Role role = bd.getBusinessDatabase()
.eq("id", form.getRoleId())
.doQueryFirst(Role.class);
// 先更新角色名
if (form.getRoleName() != null && !form.getRoleName().isEmpty()) {
bd.getBusinessDatabase()
.rowid("id", role.getRowId())
.update("role_name", form.getRoleName())
.doUpdate(Role.class);
}
// 先清空所有关联关系
List<String> userAndRoleIds = bd.getBusinessDatabase()
.eq("role_id", role.getId())
.doQuery(UserAndRoles.class).stream().map(UserAndRoles::getId).collect(Collectors.toList());
List<String> roleAndPermissionIds = bd.getBusinessDatabase()
.eq("role_id", role.getId())
.doQuery(RoleAndPermissions.class).stream().map(RoleAndPermissions::getId).collect(Collectors.toList());
bd.getBusinessDatabase().in("id", userAndRoleIds).doDelete(UserAndRoles.class);
bd.getBusinessDatabase().in("id", roleAndPermissionIds).doDelete(RoleAndPermissions.class);
// 添加新的关联关系
List<UserAndRoles> userAndRoles = new ArrayList<>();
List<RoleAndPermissions> roleAndPermissions = new ArrayList<>();
if (!form.getUsers().isEmpty()) {
for (String userId : form.getUsers()) {
UserAndRoles userAndRole = new UserAndRoles();
userAndRole.setUserId(userId);
userAndRole.setRoleId(role.getId());
userAndRoles.add(userAndRole);
}
}
if (!form.getPermissions().isEmpty()) {
for (String permissionId : form.getPermissions()) {
RoleAndPermissions roleAndPermission = new RoleAndPermissions();
roleAndPermission.setRoleId(role.getId());
roleAndPermission.setPermissionId(permissionId);
roleAndPermissions.add(roleAndPermission);
}
}
bd.getBusinessDatabase().doBatchInsert(userAndRoles);
bd.getBusinessDatabase().doBatchInsert(roleAndPermissions);
}
@Override
@Transactional(rollbackFor = CommonException.class)
public void deleteRole(String roleId) {
// 先清空所有关联关系
List<String> userAndRoleIds = bd.getBusinessDatabase()
.eq("role_id", roleId)
.doQuery(UserAndRoles.class).stream().map(UserAndRoles::getId).collect(Collectors.toList());
List<String> roleAndPermissionIds = bd.getBusinessDatabase()
.eq("role_id", roleId)
.doQuery(RoleAndPermissions.class).stream().map(RoleAndPermissions::getId).collect(Collectors.toList());
bd.getBusinessDatabase().in("id", userAndRoleIds).doDelete(UserAndRoles.class);
bd.getBusinessDatabase().in("id", roleAndPermissionIds).doDelete(RoleAndPermissions.class);
// 删除角色
bd.getBusinessDatabase().eq("id", roleId).doDelete(Role.class);
}
}

View File

@ -12,6 +12,7 @@ import com.xdap.self_development.pojo.view.ApprovalNodeView;
import com.xdap.self_development.pojo.view.TemplateChangeView; import com.xdap.self_development.pojo.view.TemplateChangeView;
import com.xdap.self_development.pojo.view.TodoAndTemplateView; import com.xdap.self_development.pojo.view.TodoAndTemplateView;
import com.xdap.self_development.service.TemplateApprovalService; import com.xdap.self_development.service.TemplateApprovalService;
import com.xdap.self_development.utils.RedisLockUtil;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils; import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@ -24,6 +25,7 @@ import java.sql.Timestamp;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.*; import java.util.*;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
@Service @Service
@Slf4j @Slf4j
@ -34,6 +36,8 @@ public class TemplateApprovalServiceImpl implements TemplateApprovalService {
private BusinessDatabase bd; private BusinessDatabase bd;
@Resource @Resource
private RuntimeDatasourceService runtimeDatasourceService; private RuntimeDatasourceService runtimeDatasourceService;
@Resource
private RedisLockUtil redisLockUtil;
// 待办标志: userId -> flowId集合 // 待办标志: userId -> flowId集合
private static final String TODO_PREFIX = "approval:todo:"; private static final String TODO_PREFIX = "approval:todo:";
@ -42,7 +46,7 @@ public class TemplateApprovalServiceImpl implements TemplateApprovalService {
// 分布式锁标志 // 分布式锁标志
private static final String FLOW_LOCK_PREFIX = "approval:lock:"; private static final String FLOW_LOCK_PREFIX = "approval:lock:";
// 分布式锁有效时间 // 分布式锁有效时间
private static final int FLOW_LOCK_EXPIRE_SECONDS = 5; private static final int FLOW_LOCK_EXPIRE_SECONDS = 15;
@Override @Override
@Transactional @Transactional
@ -59,12 +63,20 @@ public class TemplateApprovalServiceImpl implements TemplateApprovalService {
throw new CommonException("非草稿不允许发起审批"); throw new CommonException("非草稿不允许发起审批");
} }
List<ApprovalFlow> templateFlows = bd.getBusinessDatabase() List<Template> templates = bd.getBusinessDatabase()
.eq("template_id", template.getId()) .eq("template_name", template.getTemplateName())
.eq("flow_type", 1) .orderBy("version", "asc").doQuery(Template.class);
.doQuery(ApprovalFlow.class); boolean approving = templates.stream().map(Template::getStatus)
if (templateFlows != null && !templateFlows.isEmpty()) { .collect(Collectors.toList()).contains("APPROVING");
throw new CommonException("模板已发起审批"); if (approving) {
throw new CommonException("同名模板已在审核中");
}
List<TemplateAndParameter> templateAndParameters = bd.getBusinessDatabase()
.eq("template_id", template.getId()).doQuery(TemplateAndParameter.class);
if (templateAndParameters.isEmpty()) {
throw new CommonException("空参数模板不允许发起审批");
} }
// 2. 创建审批流程 // 2. 创建审批流程
@ -170,21 +182,24 @@ public class TemplateApprovalServiceImpl implements TemplateApprovalService {
if (!"COUNTERSIGN".equals(currentNode)) { if (!"COUNTERSIGN".equals(currentNode)) {
String lockKey = FLOW_LOCK_PREFIX + flow.getId() + ":" + currentNode; String lockKey = FLOW_LOCK_PREFIX + flow.getId() + ":" + currentNode;
Boolean lock = redisTemplate.opsForValue().setIfAbsent(lockKey, "1", FLOW_LOCK_EXPIRE_SECONDS, TimeUnit.SECONDS); String lockValue = UUID.randomUUID().toString();
if (Boolean.FALSE.equals(lock)) { boolean lockAcquired = redisLockUtil
.tryLock(lockKey, lockValue, FLOW_LOCK_EXPIRE_SECONDS, TimeUnit.SECONDS);
if (!lockAcquired) {
throw new CommonException("当前节点正在处理,请稍后重试"); throw new CommonException("当前节点正在处理,请稍后重试");
} }
try { try {
// 校验抢签节点是否已被处理
String processedKey = NODE_PROCESSED_PREFIX + flow.getId() + ":" + currentNode; String processedKey = NODE_PROCESSED_PREFIX + flow.getId() + ":" + currentNode;
long result = Optional.ofNullable(redisTemplate.opsForSet().size(processedKey)) long processedCount = Optional.ofNullable(redisTemplate.opsForSet().size(processedKey))
.orElse(0L); .orElse(0L);
if (result > 0) { if (processedCount > 0) {
throw new CommonException("此节点已被他人处理"); throw new CommonException("此节点已被他人处理");
} }
processApprovalLogic(flow, request, currentNode); processApprovalLogic(flow, request, currentNode);
} finally { } finally {
redisTemplate.delete(lockKey); redisLockUtil.unlock(lockKey, lockValue);
} }
} else { } else {
processApprovalLogic(flow, request, currentNode); processApprovalLogic(flow, request, currentNode);
@ -237,7 +252,7 @@ public class TemplateApprovalServiceImpl implements TemplateApprovalService {
.setVar("templateId", item.getPreTemplateId()) .setVar("templateId", item.getPreTemplateId())
.eq("parameter_number", item.getParameterNumber()) .eq("parameter_number", item.getParameterNumber())
.doQueryFirst(Parameter.class); .doQueryFirst(Parameter.class);
BeanUtils.copyProperties(item, parameter); BeanUtils.copyProperties(parameter, item);
} }
}); });

View File

@ -1,16 +1,15 @@
package com.xdap.self_development.utils; package com.xdap.self_development.utils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@Component @Component
public class RedisLockUtil { public class RedisLockUtil {
private final StringRedisTemplate redisTemplate;
public RedisLockUtil(StringRedisTemplate redisTemplate) { @Autowired
this.redisTemplate = redisTemplate; private StringRedisTemplate redisTemplate;
}
/** /**
* 获取分布式锁 * 获取分布式锁