package iet.ustb.sf.util; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.extension.toolkit.SqlRunner; import iet.ustb.sf.domain.Target; import iet.ustb.sf.domain.TargetOption; import iet.ustb.sf.exception.ErrorCode; import iet.ustb.sf.exception.MyException; import iet.ustb.sf.exception.ThrowUtils; import iet.ustb.sf.mapper.TargetMapper; import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Component; import java.math.BigDecimal; import java.math.RoundingMode; import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; /** * CheckUtils * * @author huangge1199 * @since 2025/8/5 12:43:14 */ @Component public class CheckUtils { /** * 字符串空值验证 * * @param str 字符串 * @param name 中文名 */ public static void checkEmpty(String str, String name) { ThrowUtils.throwIf(StringUtils.isEmpty(str), ErrorCode.NULL_ERROR, name + "不能为空!"); } /** * 表名验证 * * @param tableName 表名 */ public static void checkTableName(String tableName) { checkEmpty(tableName, "表名"); String sql = "SELECT COUNT(1) FROM information_schema.tables " + "WHERE table_schema = 'dwops_extension' AND table_name = '" + tableName + "'"; long cnt = SqlRunner.db().selectCount(sql); ThrowUtils.throwIf(cnt <= 0, new RuntimeException("表" + tableName + "不存在!")); } /** * 列名验证 * * @param columns 列名(多个列表以逗号分割) * @param tableName 表名 */ public static void checkColumns(String columns, String tableName) { checkEmpty(columns, "列名"); String sql = "SELECT " + columns + " FROM " + tableName + " limit 5"; SqlRunner.db().selectList(sql); } /** * 条件指标验证 * * @param optionList 条件指标集合 * @param tableName 表名 */ public static void checkSearchOption(List optionList, String tableName) { String columns = optionList.stream().map(TargetOption::getColumnName).collect(Collectors.joining(",")); checkColumns(columns, tableName); for (TargetOption option : optionList) { checkSingleOption(option); } } /** * 单个条件指标 * * @param option 指标 */ public static void checkSingleOption(TargetOption option) { String columns = option.getColumnName(); checkEmpty(columns, "列名"); List typeList = Arrays.asList(1, 2, 3); ThrowUtils.throwIf( !typeList.contains(option.getType()), ErrorCode.PARAMS_ERROR, columns + ":指标中的类型不对!" ); List funList; switch (option.getType()) { case 1: ThrowUtils.throwIf( StringUtils.isEmpty(option.getFun()), ErrorCode.PARAMS_ERROR, columns + ":日期类型的指标,日期选项不能为空!" ); funList = Arrays.asList("yesterday", "week", "nearlyWeek", "lastWeek", "month", "lastMonth", "nearlyMonth", "product", "lastProduct"); ThrowUtils.throwIf( !funList.contains(option.getFun()), ErrorCode.PARAMS_ERROR, columns + ":日期类型的指标,日期选项不对!" ); break; case 2: break; case 3: ThrowUtils.throwIf( StringUtils.isEmpty(option.getFun()), ErrorCode.PARAMS_ERROR, columns + ":数值类型的指标,符号不能为空!" ); funList = Arrays.asList(">", ">=", "<", "<=", "=", "!=", "between"); ThrowUtils.throwIf( !funList.contains(option.getFun()), ErrorCode.PARAMS_ERROR, columns + ":数值类型的指标,符号不对!" ); ThrowUtils.throwIf( StringUtils.isEmpty(option.getVal()), ErrorCode.PARAMS_ERROR, columns + ":数值类型的指标,值不能为空!" ); if ("between".equals(option.getFun())) { String[] nums = option.getVal().split(","); ThrowUtils.throwIf( nums.length != 2, ErrorCode.PARAMS_ERROR, columns + "范围条件请输入两个数值!" ); try { if (Double.parseDouble(nums[0]) > Double.parseDouble(nums[1])) { throw new MyException(ErrorCode.PARAMS_ERROR, columns + ":范围条件请确保前面的值小于等于后面的值!"); } } catch (Exception e) { throw new MyException(ErrorCode.PARAMS_ERROR, columns + ":请传入两个数值!"); } } break; } } /** * 结果指标验证 * * @param option 结果指标 * @param tableName 表名 */ public static void checkResultOption(TargetOption option, String tableName) { String fun = option.getFun(); checkEmpty(fun, "函数"); List funList = Arrays.asList("SUM", "AVG", "MAX", "MIN", "MEDIAN", "COUNT"); ThrowUtils.throwIf(!funList.contains(fun), ErrorCode.PARAMS_ERROR, "方法错误!"); checkColumns(option.getColumnName(), tableName); } /** * 保留指定位小数 * * @param value 传入值 * @param round 保留位数 * @return 结果值 */ public static double roundToDecimalPlaces(Double value, int round) { BigDecimal bd = new BigDecimal(value); bd = bd.setScale(round, RoundingMode.HALF_UP); return bd.doubleValue(); } /** * 验证指标名称是否重复 * @param targetMapper mapper类 * @param target 指标 */ public static void checkTargetNameExist(TargetMapper targetMapper, Target target) { QueryWrapper query = new QueryWrapper<>(); query.eq("name", target.getName()); Target nameCheck = targetMapper.selectOne(query); boolean bl = nameCheck != null && (target.getId() == null || !nameCheck.getId().equals(target.getId())); ThrowUtils.throwIf(bl, ErrorCode.PARAMS_ERROR, "指标名称不能重复!"); } }