周报/朋友圈简单@功能实现(java)

周报/朋友圈简单@功能实现(java)

1. 项目背景

	最近公司在开发周报系统,周报中需要像朋友圈一样具有@ 人的功能,在周保中可以输入@XXX,发布后需要给XXX发送消息提醒(xxx在某周周报中@ 了您,请点击链接查看)

2. 设计思路

	使用jsoup获取前端页面自定义标签属性
	前端在监控到需要输入“@” 符号并输入内容的时候发起suggest,查询可能需要@的人,查询到目标人后,前端在此处添加约定的标签属性,编辑发布完周报后,后端解析前端的区域内容(富文本,为保证编辑的格式),解析所有的内容,过滤需要的标签属性,获取该周报中的所有@记录,判断该份周报中是否为首次@,是发送消息提醒
	标签解析弊端:
	1. 前端富文本中如果输入了你需要匹配的自定义标签,并赋值,也会被解析工具解析,在一个完整的富文本标签里,该解析工具有可能无法区别,导致业务代码错误处理

3. 代码实现

  1. 前端代码展示片段展示
<p data-uuid="6d568da9-9142-44b3-8b5f-59bf82ff4453">这是我的测试区域
  <span class="slate-editor-ait" data-ait-text="李伟" data-ait-id="bb420577-8dab-4a3b-889a-343233d763f1" data-ait-value="00111">@李伟</span>,看到效果了吧
</p>
  1. 后端代码实现
		<!-- maven依赖 -->
		<dependency>
            <groupId>org.jsoup</groupId>
            <artifactId>jsoup</artifactId>
            <version>1.11.3</version>
        </dependency>

标签解析

	/**
     * 处理json中包含特殊需要处理的标签,并收集对用的value
     *
     * @param object
     *
     * @return
     */
    private List<AteLabelData> parseHtmlLabel(Object object, String areaCode) {

        if (ObjectUtils.isEmpty(object)) {
            return new ArrayList<>();
        }
        String html = JSONObject.toJSONString(object);

        // 将转移后的 json 字符串 反转义解析(ps: 去除 \" )
        html = StringEscapeUtils.unescapeJava(html);
        log.debug("区域{},周报解析转义后的数据:{}", areaCode, html);
        Document doc = Jsoup.parse(html);
        Elements s = doc.getElementsByAttribute(BizConstants.SpecialLabel.DATA_ATE_ID);
        List<AteLabelData> list = new ArrayList<>();
        for (Element e : s) {
            log.debug("-----------------------------");
            String ateFlag = e.attr(BizConstants.SpecialLabel.DATA_ATE_ID);
            log.debug("data-ate-id 标签的值:{}", ateFlag);
            String userId = e.attr(BizConstants.SpecialLabel.DATA_ATE_USER_ID);
            log.debug("data-ate-user-id 标签的值:{}", userId);
            log.debug("-----------------------------");
            if (StringUtils.isBlank(ateFlag) || StringUtils.isBlank(userId)) {
                continue;
            }
            AteLabelData labelData = new AteLabelData();
            labelData.setAteFlag(ateFlag);
            labelData.setUserId(Long.parseLong(userId));
            labelData.setAreaCode(areaCode);
            list.add(labelData);
        }
        return list;
    }
    

业务数据处理


	@Override
    public void selectAteRecord(ReportViewVO reportViewVO, ReportMain reportMain, HcmUser hcmUser) {

        if (reportMain == null || reportViewVO == null) {
            return;
        }
        log.debug("{}的周报,mainId:{},vo:{}", reportMain.getOwnerId(), reportMain.getMainId(), reportViewVO);
        List<AteLabelData> dataList = new ArrayList<>();

        /**
         * .......其他区域处理
         */
        // planReport
        if (reportViewVO.getPlanReportInfoVO() != null) {
            List<AteLabelData> labelList = parseHtmlLabel(reportViewVO.getPlanReportInfoVO(),
                    BizConstants.ReportTemplateAreaCode.PLAN_REPORT);
            if (CollectionUtils.isNotEmpty(labelList)) {
                dataList.addAll(labelList);
            }
        }

        if (CollectionUtils.isEmpty(dataList)) {
            return;
        }
        // 处理ate表数据
        dealAteDataFormLabel(dataList, reportMain, hcmUser, reportViewVO);

    }
    
	/**
     * 处理ate数据
     *
     * @param dataList
     * @param reportViewVO
     * @param hcmUser
     * @param reportMain
     */
    private void dealAteDataFormLabel(List<AteLabelData> dataList, ReportMain reportMain,
                                      HcmUser hcmUser, ReportViewVO reportViewVO) {

        ReportAteExample ateExample = new ReportAteExample();
        ateExample.createCriteria().andMainIdEqualTo(reportMain.getMainId())
                .andEnabledEqualTo(BizConstants.YesOrNot.YES);
        List<ReportAte> reportAteList = selectByExample(ateExample);
        if (CollectionUtils.isEmpty(reportAteList)) {
            dealFirstAteData(dataList, reportMain, hcmUser, reportViewVO);
        } else {
            dealHaveAteData(dataList, reportAteList, reportMain, hcmUser, reportViewVO);
        }
    }
    
	 /**
     * 处理本次周报提交前没有ate过
     *
     * @param dataList
     * @param reportMain
     * @param hcmUser
     */
    private void dealFirstAteData(List<AteLabelData> dataList, CuxOkrReportMain reportMain,
                                  HcmUser hcmUser, OkrReportViewVO reportViewVO) {
                      // 具体的业务逻辑
                                  
	}
	/**
     * 处理本次周报提交前已有ate过数据的
     *
     * @param dataList
     * @param reportMain
     * @param hcmUser
     */
	private void dealHaveAteData(List<AteLabelData> dataList, List<CuxOkrReportAte> reportAteList,
                                 CuxOkrReportMain reportMain, HcmUser hcmUser, OkrReportViewVO reportViewVO) {
                                   // 具体的业务逻辑
	}

参考文档

  1. https://blog.csdn.net/mashuai720/article/details/80563848
  2. https://www.jianshu.com/p/fd5caaaa950d
  3. https://www.open-open.com/jsoup/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值