自定义文案设计记录

设计目标:尽量灵活的文案配置化

设计方案:

  1. 占位符支持更多的取值逻辑。
  2. 文案进行拆分,当取不到值时可以使用默认文案。

${}:占位符
英文",“:取值优先级。eg:${area,city,province} 先取区,区没有再取市,以此类推。
英文”.“:子属性。eg:${area.code} 取区编码
英文”:":设置默认值,可为空串 ${area:未知区域} 取区信息,没有展示“未知区域”

文案取值没有取到,就展示默认文案。
eg:
正常文案:尊敬的用户,您的服务即将到期,距离过期时间只有${remainingTime}天,请及时续费。

默认文案:尊敬的用户,您的服务即将到期,距离过期时间不足10天,请及时续费。

表设计
type:类型(用于支持不同业务)
code :文案编码(同一文案使用同样的文案编码)
desc:文案描述(文案说明,编码可使用)
priority 优先级(若顺序相同,则根据优先级和替换占位符结果,决定对外展示文案)
order 顺序(子文案顺序)
subTemplate:子文案

核心代码块:


    public static final Pattern PLACEHOLDER = Pattern.compile("\\$\\{.[^$]*}");

    private static <T> String replace(List<Template> templates, T data) {
        StringBuilder finalTemplate = new StringBuilder();
        Map<Integer, List<Template>> classflyMap = ListUtils.classflyMap(templates, Template::getOrder);
        Set<Integer> orders = classflyMap.keySet();
        List<Integer> orderList = orders.stream().sorted().collect(Collectors.toList());
        for (Integer order : orderList) {
            List<Template> value = classflyMap.get(order);
            value.sort(Comparator.comparing(Template::getPriority));
            for (Template template : value) {
                String subTemplate = replace(template.getSubTemplate(), data);
                if (subTemplate == null) {
                    continue;
                }
                finalTemplate.append(subTemplate);
                break;
            }

        }
        return finalTemplate.toString();
    }


    private static <T> String replace(String template, T data) {
        Matcher matcher = PLACEHOLDER.matcher(template);
        while (matcher.find()) {
            String holder = matcher.group();
            String paramsStr = holder.substring(2, holder.length() - 1);
            String[] params = paramsStr.split(",");
            String value = null;
            for (String param : params) {
                value = getValue(data, param);
                if (value != null) {
                    break;
                }
            }
            if (value == null) {
                return null;
            }
            template = template.replace(holder, value);
        }
        return template;
    }
    
    private static <T> String getValue(T data, String param) {
        if (param.contains(":")) {
            String defaultValue = "";
            String[] splits = param.split(":", 2);
            if (splits.length == 2) {
                defaultValue = splits[1];
            }
            param = splits[0];
            String value = getValue(param, data);
            if (value == null) {
                return defaultValue;
            } else {
                return value;
            }
        }
        return getValue(param, data);
    }

    private static <T> String getValue(String fieldName, T data) {
        if (data == null) {
            return null;
        }
        Class<?> aClass = data.getClass();
        try {
            String[] splits = fieldName.split("\\.");
            Field declaredField = null;
            Object obj = data;
            for (String split : splits) {
                if (declaredField == null) {
                    declaredField = aClass.getDeclaredField(split);
                } else {
                    declaredField = declaredField.getType().getDeclaredField(split);
                }
                declaredField.setAccessible(true);
                obj = declaredField.get(obj);
                if (obj == null) {
                    return null;
                }
            }
            return String.valueOf(obj);
        } catch (Exception e) {
            System.out.println(e);
            return null;
        }
    }

测试:

    @Data
    public static class Template {
        private String type;
        private String code;
        private String desc;
        private Integer order;
        private Integer priority;
        private String subTemplate;
        public Template(String type, String code, String desc, Integer order, Integer priority, String subTemplate) {
            this.type = type;
            this.code = code;
            this.desc = desc;
            this.order = order;
            this.priority = priority;
            this.subTemplate = subTemplate;
        }
    }
    @Data
    public static class data {
        private String weather;
        private Area area;
        private String direction;
        private String power;
    }
    @Data
    public static class Area {
        private String city;
        private String province;
        public Area(String city, String province) {
            this.city = city;
            this.province = province;
        }
    }
    
    public static List<Template> testData() {
        ArrayList<Template> templates = new ArrayList<>();
        templates.add(new Template("type", "code", "测试", 1, 1, "今日天气:${weather:-},气温最低${area.city,area.province:-},最高${area.city,area.province:-}。"));
        templates.add(new Template("type", "code", "测试", 2, 1, "今日风向:${direction},风力${power}。请酌情增减衣物"));
        templates.add(new Template("type", "code", "测试", 2, 2, "请酌情增减衣物"));
        return templates;
    }
    
    public static void main(String[] args) {
        data data = new data();
        data.setWeather("晴");
        data.setArea(new Area("4", "10"));
        data.setPower("3");
        data.setDirection("west");
        System.out.println(replace(testData(), data));
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值