mirror of
https://codeup.aliyun.com/64f7d6b8ce01efaafef1e678/coal/coal.git
synced 2026-01-25 07:46:40 +08:00
添加工资项目
This commit is contained in:
@@ -17,11 +17,36 @@ import org.codehaus.groovy.ast.expr.VariableExpression;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@UtilityClass
|
||||
@Slf4j
|
||||
public class GroovyScriptUtils {
|
||||
|
||||
public String replaceVariable(
|
||||
String patternstr, String script, Function<String, String> mapper) {
|
||||
|
||||
Pattern pattern = Pattern.compile(patternstr);
|
||||
|
||||
// 创建 Matcher 对象
|
||||
Matcher matcher = pattern.matcher(script);
|
||||
|
||||
// 使用 Map 进行映射和替换
|
||||
StringBuffer resultString = new StringBuffer();
|
||||
while (matcher.find()) {
|
||||
String replacement = mapper.apply(matcher.group(matcher.groupCount()));
|
||||
matcher.appendReplacement(
|
||||
resultString,
|
||||
replacement != null ? Matcher.quoteReplacement(replacement) : matcher.group());
|
||||
}
|
||||
matcher.appendTail(resultString);
|
||||
|
||||
return resultString.toString();
|
||||
}
|
||||
|
||||
public static void validate(String formula) {
|
||||
if (StringUtils.isEmpty(formula)) {
|
||||
return;
|
||||
|
||||
@@ -10,6 +10,7 @@ import cn.lihongjie.coal.organization.dto.UpdateOrganizationDto;
|
||||
import cn.lihongjie.coal.organization.entity.OrganizationEntity;
|
||||
import cn.lihongjie.coal.organization.mapper.OrganizationMapper;
|
||||
import cn.lihongjie.coal.organization.repository.OrganizationRepository;
|
||||
import cn.lihongjie.coal.salaryItem.service.SalaryItemService;
|
||||
import cn.lihongjie.coal.user.dto.CreateOrgAdminDto;
|
||||
import cn.lihongjie.coal.user.service.UserService;
|
||||
|
||||
@@ -37,7 +38,7 @@ public class OrganizationService extends BaseService<OrganizationEntity, Organiz
|
||||
|
||||
@Autowired CoalParameterDefService coalParameterDefService;
|
||||
|
||||
|
||||
@Autowired SalaryItemService salaryItemService;
|
||||
|
||||
@PostConstruct
|
||||
public void init() {}
|
||||
@@ -54,7 +55,7 @@ public class OrganizationService extends BaseService<OrganizationEntity, Organiz
|
||||
dto.setPassword(request.getOrgAdminPassword());
|
||||
userService.createOrgAdmin(dto);
|
||||
coalParameterDefService.initDefault(entity.getId());
|
||||
|
||||
salaryItemService.initOrgDefault(entity.getId());
|
||||
return getById(entity.getId());
|
||||
}
|
||||
|
||||
|
||||
@@ -14,6 +14,8 @@ public class SalaryItemDto extends OrgCommonDto {
|
||||
@Comment("上级名称")
|
||||
private String parentName;
|
||||
|
||||
private String fullName;
|
||||
|
||||
@Comment("工资项目类型")
|
||||
private String itemType;
|
||||
|
||||
|
||||
@@ -18,6 +18,9 @@ public class SalaryItemEntity extends OrgCommonEntity {
|
||||
@Comment("上级名称")
|
||||
private String parentName;
|
||||
|
||||
@Formula("(CONCAT(parentName,'-' ,name))")
|
||||
private String fullName;
|
||||
|
||||
@Comment("工资项目类型")
|
||||
private String itemType;
|
||||
|
||||
@@ -52,4 +55,7 @@ public class SalaryItemEntity extends OrgCommonEntity {
|
||||
|
||||
@Comment("依赖项目")
|
||||
private List<String> dependOn;
|
||||
|
||||
@Comment("优先级")
|
||||
private Integer priority;
|
||||
}
|
||||
|
||||
@@ -5,5 +5,9 @@ import cn.lihongjie.coal.salaryItem.entity.SalaryItemEntity;
|
||||
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Repository
|
||||
public interface SalaryItemRepository extends BaseRepository<SalaryItemEntity> {}
|
||||
public interface SalaryItemRepository extends BaseRepository<SalaryItemEntity> {
|
||||
List<SalaryItemEntity> findByOrganizationIdAndStatus(String organizationId, Integer status);
|
||||
}
|
||||
|
||||
@@ -2,7 +2,10 @@ package cn.lihongjie.coal.salaryItem.service;
|
||||
|
||||
import cn.lihongjie.coal.base.dto.CommonQuery;
|
||||
import cn.lihongjie.coal.base.dto.IdRequest;
|
||||
import cn.lihongjie.coal.base.entity.CommonEntity;
|
||||
import cn.lihongjie.coal.base.service.BaseService;
|
||||
import cn.lihongjie.coal.common.GroovyScriptUtils;
|
||||
import cn.lihongjie.coal.exception.BizException;
|
||||
import cn.lihongjie.coal.salaryItem.dto.CreateSalaryItemDto;
|
||||
import cn.lihongjie.coal.salaryItem.dto.SalaryItemDto;
|
||||
import cn.lihongjie.coal.salaryItem.dto.UpdateSalaryItemDto;
|
||||
@@ -12,6 +15,10 @@ import cn.lihongjie.coal.salaryItem.repository.SalaryItemRepository;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.jgrapht.graph.DefaultDirectedGraph;
|
||||
import org.jgrapht.graph.DefaultEdge;
|
||||
import org.jgrapht.traverse.TopologicalOrderIterator;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.data.domain.Page;
|
||||
@@ -19,6 +26,13 @@ import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
@Slf4j
|
||||
public class SalaryItemService extends BaseService<SalaryItemEntity, SalaryItemRepository> {
|
||||
@@ -31,16 +45,122 @@ public class SalaryItemService extends BaseService<SalaryItemEntity, SalaryItemR
|
||||
public SalaryItemDto create(CreateSalaryItemDto request) {
|
||||
SalaryItemEntity entity = mapper.toEntity(request);
|
||||
|
||||
updateField(entity);
|
||||
// 校验公式
|
||||
this.repository.save(entity);
|
||||
syncFormula(entity);
|
||||
return getById(entity.getId());
|
||||
}
|
||||
|
||||
private void updateField(SalaryItemEntity entity) {
|
||||
List<SalaryItemEntity> allItems =
|
||||
repository.findByOrganizationIdAndStatus(entity.getOrganizationId(), 1);
|
||||
|
||||
Map<String, SalaryItemEntity> nameMap =
|
||||
allItems.stream()
|
||||
.collect(
|
||||
Collectors.toMap(
|
||||
e -> String.format("【%s】", e.getFullName()), e -> e));
|
||||
|
||||
Set<String> dependsOn = new HashSet<>();
|
||||
|
||||
Function<String, String> mapper =
|
||||
(String s) -> {
|
||||
if (nameMap.containsKey(s)) {
|
||||
String code = nameMap.get(s).getCode();
|
||||
dependsOn.add(code);
|
||||
return code;
|
||||
}
|
||||
throw new BizException("公式中的依赖项 {} 不存在", s);
|
||||
};
|
||||
// 生成公式
|
||||
|
||||
String formula =
|
||||
GroovyScriptUtils.replaceVariable("【(.*?)】", entity.getFormulaShow(), mapper);
|
||||
|
||||
entity.setDependOn(dependsOn.stream().toList());
|
||||
|
||||
entity.setFormula(formula);
|
||||
|
||||
try {
|
||||
|
||||
GroovyScriptUtils.variables(formula);
|
||||
} catch (Exception e) {
|
||||
throw new BizException("无效的公式");
|
||||
}
|
||||
}
|
||||
|
||||
private void syncFormula(SalaryItemEntity entity) {
|
||||
|
||||
DefaultDirectedGraph<Object, DefaultEdge> graph =
|
||||
new DefaultDirectedGraph<>(DefaultEdge.class);
|
||||
List<SalaryItemEntity> all =
|
||||
repository.findByOrganizationIdAndStatus(entity.getOrganizationId(), 1);
|
||||
|
||||
Set<String> enabledCode =
|
||||
all.stream().map(sie -> sie.getCode()).collect(Collectors.toSet());
|
||||
|
||||
for (SalaryItemEntity def : all) {
|
||||
|
||||
if (StringUtils.equalsIgnoreCase(def.getInputType(), "1")) {
|
||||
|
||||
Iterable<String> dependents = def.getDependOn();
|
||||
|
||||
for (String d : dependents) {
|
||||
if (!enabledCode.contains(d)) {
|
||||
throw new BizException("公式中的依赖项 {} 不存在", d);
|
||||
}
|
||||
graph.addVertex(def.getCode());
|
||||
graph.addVertex(d);
|
||||
|
||||
graph.addEdge(d, def.getCode());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, SalaryItemEntity> codeMap =
|
||||
all.stream().collect(Collectors.toMap(CommonEntity::getCode, e -> e));
|
||||
|
||||
Function<String, String> mapper =
|
||||
(String s) -> {
|
||||
if (codeMap.containsKey(s)) {
|
||||
return "【" + codeMap.get(s).getFullName() + "】";
|
||||
}
|
||||
throw new BizException("公式中的依赖项 {} 不存在", s);
|
||||
};
|
||||
// 生成公式
|
||||
|
||||
TopologicalOrderIterator<Object, DefaultEdge> iterator =
|
||||
new TopologicalOrderIterator<>(graph);
|
||||
|
||||
int order = 0;
|
||||
while (iterator.hasNext()) {
|
||||
Object next = iterator.next();
|
||||
|
||||
for (var item : all) {
|
||||
|
||||
if (StringUtils.equalsIgnoreCase(item.getCode(), next + "")) {
|
||||
item.setPriority(order++);
|
||||
item.setFormulaShow(
|
||||
GroovyScriptUtils.replaceVariable(
|
||||
"item\\d+", entity.getFormula(), mapper));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
this.repository.saveAll(all);
|
||||
}
|
||||
|
||||
public SalaryItemDto update(UpdateSalaryItemDto request) {
|
||||
SalaryItemEntity entity = this.repository.get(request.getId());
|
||||
|
||||
|
||||
this.mapper.updateEntity(entity, request);
|
||||
|
||||
updateField(entity);
|
||||
this.repository.save(entity);
|
||||
|
||||
syncFormula(entity);
|
||||
return getById(entity.getId());
|
||||
}
|
||||
|
||||
@@ -65,4 +185,20 @@ public class SalaryItemService extends BaseService<SalaryItemEntity, SalaryItemR
|
||||
|
||||
return page.map(this.mapper::toDto);
|
||||
}
|
||||
|
||||
public void initOrgDefault(String organizationId) {
|
||||
|
||||
for (int i = 0; i < 50; i++) {
|
||||
|
||||
SalaryItemEntity item = new SalaryItemEntity();
|
||||
item.setCode("item" + i);
|
||||
item.setInputType("1");
|
||||
item.setItemType("1");
|
||||
item.setStatus(0);
|
||||
|
||||
item.setOrganizationId(organizationId);
|
||||
|
||||
this.repository.save(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
package cn.lihongjie.coal.common;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
class GroovyScriptUtilsTest {
|
||||
|
||||
@Test
|
||||
void test() {
|
||||
|
||||
assertEquals("1", GroovyScriptUtils.replaceVariable("\\【(.+?)\\】", "【a】", (s) -> "1"));
|
||||
assertEquals(
|
||||
"1 + 1", GroovyScriptUtils.replaceVariable("\\【(.+?)\\】", "【a】 + 【b】", (s) -> "1"));
|
||||
assertEquals(
|
||||
"1 + 1", GroovyScriptUtils.replaceVariable("\\【(.+?)\\】", "1 + 1", (s) -> "1"));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user