diff --git a/src/main/java/iet/ustb/sf/controller/TargetController.java b/src/main/java/iet/ustb/sf/controller/TargetController.java index 5ca73b9..ba293fd 100644 --- a/src/main/java/iet/ustb/sf/controller/TargetController.java +++ b/src/main/java/iet/ustb/sf/controller/TargetController.java @@ -2,8 +2,10 @@ package iet.ustb.sf.controller; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import iet.ustb.sf.common.R; import iet.ustb.sf.domain.Target; +import iet.ustb.sf.service.TableColumnService; import iet.ustb.sf.service.TargetService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; @@ -30,6 +32,9 @@ public class TargetController { @Resource private TargetService targetService; + @Resource + private TableColumnService tableColumnService; + /** * 根据分类显示指标列表 */ @@ -60,4 +65,14 @@ public class TargetController { targetService.saveTarget(params); return R.ok(); } + + @Operation(summary = "获取原子指标详情(点击进入编辑界面)") + @PostMapping("/getDetailTarget") + public R getDetailTarget(@RequestBody JSONObject params) { + JSONObject result = targetService.getDetailTarget(params); + Page list = tableColumnService.getDataByTableName(result.getJSONObject("list")); + result.put("list", list); + result.put("columnList", tableColumnService.getColumnsByTableName(result.getString("tableName"))); + return R.ok(result); + } } diff --git a/src/main/java/iet/ustb/sf/domain/TargetOption.java b/src/main/java/iet/ustb/sf/domain/TargetOption.java index 7857672..b235985 100644 --- a/src/main/java/iet/ustb/sf/domain/TargetOption.java +++ b/src/main/java/iet/ustb/sf/domain/TargetOption.java @@ -2,6 +2,8 @@ package iet.ustb.sf.domain; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableName; + +import java.io.Serializable; import java.util.Date; import lombok.AllArgsConstructor; @@ -19,7 +21,7 @@ import lombok.NoArgsConstructor; @Builder @AllArgsConstructor @NoArgsConstructor -public class TargetOption { +public class TargetOption implements Serializable { /** * 主键 */ @@ -73,6 +75,9 @@ public class TargetOption { @TableField(value = "update_time") private Date updateTime; + @TableField(exist = false) + private boolean show; + @Override public boolean equals(Object that) { if (this == that) { diff --git a/src/main/java/iet/ustb/sf/service/TargetService.java b/src/main/java/iet/ustb/sf/service/TargetService.java index 2897248..c757c75 100644 --- a/src/main/java/iet/ustb/sf/service/TargetService.java +++ b/src/main/java/iet/ustb/sf/service/TargetService.java @@ -21,4 +21,6 @@ public interface TargetService extends IService { String getResult(JSONObject params); void saveTarget(JSONObject params); + + JSONObject getDetailTarget(JSONObject params); } diff --git a/src/main/java/iet/ustb/sf/service/impl/TargetServiceImpl.java b/src/main/java/iet/ustb/sf/service/impl/TargetServiceImpl.java index bf1343d..cc07eba 100644 --- a/src/main/java/iet/ustb/sf/service/impl/TargetServiceImpl.java +++ b/src/main/java/iet/ustb/sf/service/impl/TargetServiceImpl.java @@ -6,20 +6,17 @@ import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.toolkit.SqlRunner; -import iet.ustb.sf.domain.Category; -import iet.ustb.sf.domain.Target; -import iet.ustb.sf.domain.TargetData; -import iet.ustb.sf.domain.TargetOption; +import iet.ustb.sf.domain.*; import iet.ustb.sf.exception.ErrorCode; +import iet.ustb.sf.exception.MyException; import iet.ustb.sf.exception.ThrowUtils; -import iet.ustb.sf.mapper.CategoryMapper; -import iet.ustb.sf.mapper.TargetDataMapper; +import iet.ustb.sf.mapper.*; import iet.ustb.sf.service.TargetDataService; import iet.ustb.sf.service.TargetService; -import iet.ustb.sf.mapper.TargetMapper; import iet.ustb.sf.service.UtilService; import iet.ustb.sf.util.CheckUtils; import jakarta.annotation.Resource; +import org.apache.commons.lang3.SerializationUtils; import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -51,6 +48,15 @@ public class TargetServiceImpl extends ServiceImpl @Resource private UtilService utilService; + @Resource + private TargetOptionMapper targetOptionMapper; + + @Resource + private AnalysisMapper analysisMapper; + + @Resource + private RuleMapper ruleMapper; + @Override public IPage getTargetsByCategory(JSONObject params) { int pageIndex = Optional.ofNullable(params.getInteger("pageIndex")).orElse(1); @@ -125,7 +131,6 @@ public class TargetServiceImpl extends ServiceImpl Map> optionsMap = showList.stream() .peek(option -> { - option.setTargetId(target.getId()); if (option.getCreateTime() == null) { option.setCreateTime(now); } @@ -160,8 +165,232 @@ public class TargetServiceImpl extends ServiceImpl categoryDeal(null, target); } targetMapper.insert(target); - saveDate(target); + saveData(target); + } else { + categoryDealByUpdate(target); + saveChildSql(target); + Target oldTarget = targetMapper.selectById(target.getId()); + if (!cycle.equals(oldTarget.getCycle())) { + ThrowUtils.throwIf( + hasTogeth(target.getId()), + ErrorCode.OPERATION_ERROR, + "有聚合指标使用了该指标,无法修改时间周期!" + ); + } + List analysisList = analysisMapper.selectList( + new QueryWrapper().eq("target_id", target.getId()) + ); + if (!oldTarget.getResultSql().equals(target.getResultSql())) { + ThrowUtils.throwIf( + analysisList != null && !analysisList.isEmpty(), + ErrorCode.OPERATION_ERROR, + "当前指标有图表存在,无法修改!" + ); + } + if (!cycle.equals(oldTarget.getCycle()) || !target.getUnit().equals(oldTarget.getUnit())) { + List ruleList = ruleMapper.selectList( + new QueryWrapper().eq("target_id", target.getId()) + ); + for (Rule rule : ruleList) { + if (Arrays.asList("yesterday", "nearlyWeek", "nearlyMonth").contains(cycle)) { + rule.setCycle("day"); + } else if (Arrays.asList("week", "lastWeek").contains(cycle)) { + rule.setCycle("week"); + } else { + rule.setCycle("month"); + } + rule.setUnit(target.getUnit()); + } + ruleMapper.insertOrUpdate(ruleList); + } + targetMapper.insertOrUpdate(target); } + + showList = optionsMap.values().stream().flatMap(List::stream).collect(Collectors.toList()); + + result.setTargetId(target.getId()); + if (result.getCreateTime() == null) { + result.setCreateTime(now); + } + result.setUpdateTime(now); + showList.add(result); + + targetOptionMapper.delete(new QueryWrapper().eq("target_id", target.getId())); + for (TargetOption option : showList) { + option.setTargetId(target.getId()); + } + targetOptionMapper.insertOrUpdate(showList); + } + + /** + * 判断是否有聚合指标使用当前指标 + * + * @param id 当前指标ID + * @return 结果 + */ + private boolean hasTogeth(String id) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("type", 2); + queryWrapper.like("result_sql", "%" + id + "%"); + List togethTargetList = targetMapper.selectList(queryWrapper); + return !togethTargetList.isEmpty(); + } + + /** + * 指标修改后,同步修改关联指标信息 + * + * @param target 原子指标 + */ + @Transactional(rollbackFor = Exception.class) + public void saveChildSql(Target target) { + Target old = targetMapper.selectById(target.getId()); + if (!old.getResultSql().equals(target.getResultSql())) { + detailTogetherData(target); + } + List targetList = targetMapper.selectList(new QueryWrapper().eq("parent", target.getId())); + for (Target childTarget : targetList) { + TargetOption expandOption = targetOptionMapper.selectOne( + new QueryWrapper().eq("target_id", childTarget.getId()) + ); + String searchSql = childTarget.getSearchSql().substring(0, childTarget.getSearchSql().indexOf("WHERE")); + String sql = getExpandSql(expandOption, target.getSearchSql()); + searchSql += sql.substring(sql.indexOf("WHERE")); + childTarget.setSearchSql(searchSql); + childTarget.setResultSql(getExpandSql(expandOption, target.getResultSql())); + childTarget.setUpdateTime(target.getUpdateTime()); + childTarget.setCycle(target.getCycle()); + childTarget.setUnit(target.getUnit()); + saveChildSql(childTarget); + saveData(childTarget); + } + if (!targetList.isEmpty()) { + targetMapper.insertOrUpdate(targetList); + } + } + + /** + * 衍生指标表中结果SQL + * + * @param expandOption 衍生选项 + * @param sql 衍生的原指标SQL + * @return 衍生的结果SQL + */ + private String getExpandSql(TargetOption expandOption, String sql) { + String val = expandOption.getVal(); + String resultTmpSql; + if (StringUtils.isEmpty(val)) { + resultTmpSql = sql + " AND " + expandOption.getColumnName() + " IS NULL"; + } else { + if (expandOption.getType() == 2) { + resultTmpSql = sql + " AND " + expandOption.getColumnName() + "='" + val + "'"; + } else { + try { + Double.parseDouble(val); + } catch (Exception e) { + throw new MyException(ErrorCode.SYSTEM_ERROR, val + "不是数值!"); + } + resultTmpSql = sql + " AND TO_NUMBER(" + expandOption.getColumnName() + ")=" + val; + } + } + return resultTmpSql; + } + + /** + * 处理聚合关联计算问题,重新获取数据,保证数据时间的一致性 + * + * @param target 指标 + */ + private void detailTogetherData(Target target) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("type", 2); + queryWrapper.like("result_sql", "%" + target.getId() + "%"); + List targetList = targetMapper.selectList(queryWrapper); + targetList.add(target); + targetDataMapper.deleteByIds(targetList.stream().map(Target::getId).collect(Collectors.toList())); + for (Target tmp : targetList) { + saveData(tmp); + } + } + + /** + * 指标变更时,修改分类 + * + * @param target 指标 + */ + @Transactional(rollbackFor = Exception.class) + public void categoryDealByUpdate(Target target) { + Target oldTarget = targetMapper.selectById(target.getId()); + if (oldTarget.getCategoryId() == null && target.getCategoryId() != null) { + categoryDeal(null, target); + } else if (oldTarget.getCategoryId() != null && target.getCategoryId() == null) { + categoryDeal(oldTarget, null); + } else if (oldTarget.getCategoryId() != null) { + if (!oldTarget.getCategoryId().equals(target.getCategoryId())) { + categoryDeal(oldTarget, null); + categoryDeal(null, target); + } else { + if (!oldTarget.getOrganization().equals(target.getOrganization())) { + categoryDeal(oldTarget, target); + } + } + } + } + + @Override + public JSONObject getDetailTarget(JSONObject params) { + Target target = params.getJSONObject("target").toJavaObject(Target.class); + CheckUtils.checkEmpty(target.getId(), "指标ID"); + target = targetMapper.selectById(target.getId()); + ThrowUtils.throwIf(target == null, ErrorCode.PARAMS_ERROR, "指标不存在!"); + List optionList = targetOptionMapper.selectList( + new QueryWrapper().eq("target_id", target.getId()) + ); + return getDetailTarget(optionList, target); + } + + private JSONObject getDetailTarget(List optionList, Target target) { + List show = new ArrayList<>(); + List search = new ArrayList<>(); + TargetOption result = null; + for (TargetOption option : optionList) { + String op = option.getOp(); + if (op.contains("0")) { + TargetOption tmp = SerializationUtils.clone(option); + tmp.setOp("0"); + show.add(tmp); + } + if (op.contains("1")) { + TargetOption tmp = SerializationUtils.clone(option); + tmp.setOp("1"); + tmp.setShow(false); + if (op.contains("2") && result != null) { + tmp.setShow(true); + } + search.add(tmp); + } + if (op.contains("2")) { + if (result != null) { + continue; + } + TargetOption tmp = SerializationUtils.clone(option); + tmp.setOp("2"); + result = tmp; + } + } + + String columns = show.stream().map(TargetOption::getColumnName).collect(Collectors.joining(",")); + JSONObject columnParams = new JSONObject(); + columnParams.put("columns", columns); + columnParams.put("tableName", target.getTableName()); + + JSONObject res = new JSONObject(); + res.put("target", target); + res.put("show", show); + res.put("search", search); + res.put("result", result); + res.put("list", columnParams); + res.put("tableName", target.getTableName()); + return res; } /** @@ -169,7 +398,7 @@ public class TargetServiceImpl extends ServiceImpl * * @param target 指标 */ - private void saveDate(Target target) { + private void saveData(Target target) { targetDataMapper.delete(new QueryWrapper().eq("target_id", target.getId())); String[] strArr = utilService.getCurrentCycleDataByCycle(new Date(), target.getCycle()); targetDataService.updateHistory(target, strArr, null);