IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> 欠的债总要有人替你还 -> 正文阅读

[网络协议]欠的债总要有人替你还

项目场景:

???????这次的业务场景是以前的同事写的"假代码",业务接口就没有实现,没实现也就算了,还搞一条假数据,好像实现了一样。这都是欠的业务债啊。
???????最近,公司也是各种狗血啊。什么加班的调休有效期是一个月,然后,如果调休了就没有项目奖金;然后上班时间调整,中午你猜有多长时间吃饭休息?12:45-13:30,这是遇到的最短的中场休息了,扎扎实实日工作时间是8个小时啊,其实很多公司实际上都只7.5个小时。。。


问题描述

cha
用户一直看到这个假消息。。。。
接口跟踪看源码,原来是这么玩的。。。。


原因分析:

???????还有啥好分析的啊,就是没有实现呗。
???????产品重新设计,这块要显示工单信息、APP通知。APP通知的还好说就一个入口,工单这块有几类,而且工单节点处理了,这边也是要有新的信息的(节点处理了产生新的信息,产品没有提,我想应该是需要的,也不想后面再调,所以一次性想到了要设计)。
???????工单这块的入口、节点处理、那可是太多地方了,我可不想一个个找入口,况且,现在已经是交付期,大改危险,而且前期的工单也非我处理设计,那要找费劲啊。
???????最后想到了一个主动拉取自己的工单到消息模块的方案,感觉还不错就分享给大家。
???????这里分享给大家的其实是想让大家感受下逆向思维。既然入口不好处理,那我们就在出口做处理,一样也是可行的。


解决方案:

1、先看流程图:
在这里插入图片描述
2、思路说明:
???????其实就是逆向处理,既然在工单的多个入口处不好增加消息信息,那么在用户点击消息模块的出口这里人为的先去查询自己提的工单数据,经过转换处理后入库,然后再做查询自己的工单的消息。这里要注意的:
???????A、判断页码,只在第一页才去同步工单转换(另外一个原因是每页都同步会影响分页数据)
???????B、已存在的就注意判断更新时间字段比我这条信息的阅读时间是否晚,如果晚,那肯定是要更新读取状态为未读的(正向的入口逻辑是工单处理了需要产生一条消息记录的)
???????C、要注意数据量、注意不要太影响查询数据的接口速度
3、看核心代码

@Override
    public Result<?> pullAndQueryList(Map<String, String> param) {
        //参数校验
        Result<?> res = SuggestionUtil.checkPullAndQueryParam(param);
        if (res != null){
            return res;
        }
        //参数拆解
        Integer userId = Integer.parseInt(param.get("userId"));
        Integer subjectId = Integer.parseInt(param.get("subjectId"));
        Integer page = Integer.parseInt(param.get("page"));
        Integer size = Integer.parseInt(param.get("size"));
        //查询用户信息
        UserInfo userInfo = userInfoMapper.selectByPrimaryKey(userId);
        if (userInfo == null){
            return ResultGenerator.genFailResult(ResponseCodeI18n.USER_NOT_EXIST.getMsg());
        }

        if (page.intValue() == 1){
            //pull工单数据
            pullWorkOrderInfo(userInfo,subjectId);
        }

        //查询数据
        PageHelper.startPage(page,size);
        List<SuggestionInfoDto> ls = suggestionInfoMapper.querySuggestionDtoList(param);
        PageInfo<SuggestionInfoDto> pageInfo = new PageInfo<>(ls);

        return ResultGenerator.genSuccessResult(pageInfo);
    }

    /**
     * 拉取用户最新的工单信息
     * @param userInfo 用户信息
     * @param subjectId 项目id
     */
    private void pullWorkOrderInfo(UserInfo userInfo, Integer subjectId) {
        //suggestioninfo基础信息
        SuggestionInfo si = new SuggestionInfo();
        si.setIsDeleted(BusinessConstant.NO_DELETE);
        si.setSubjectId(subjectId);
        si.setOrgId(userInfo.getOrgId());

        //组织pull工单信息参数
        WorkOrderInfo woRecord = new WorkOrderInfo();
        //前端创建的来源=99
        woRecord.setCreateSource(99);
        //前端创建的workType=1
        woRecord.setWorkType(1);
        woRecord.setIsDeleted(BusinessConstant.NO_DELETE);
        woRecord.setOrgId(userInfo.getOrgId());
        woRecord.setSubjectId(subjectId);
        woRecord.setCreateBy(userInfo.getId());
        woRecord.setCreateTime(null);
        List<WorkOrderInfo> odList = workOrderInfoMapper.select(woRecord);
        if (CollectionUtil.isNotEmpty(odList)){
            odList.stream().forEach(d->{
                //转换为suggestioninfo信息
                SuggestionInfo tmp = new SuggestionInfo();
                BeanUtil.copyProperties(si,tmp,CopyOptions.create().setIgnoreNullValue(Boolean.TRUE));
                tmp.setMsgId(d.getId());
                tmp.setMsgType(1);
                //先查询是否存在
                List<SuggestionInfo> sgLs = suggestionInfoMapper.select(tmp);
                if (CollectionUtil.isEmpty(sgLs)){
                    tmp.setDescription(d.getWorkTitle());
                    tmp.setContent(d.getWorkContent());
                    tmp.setIsRead(0);
                    tmp.setMobile(userInfo.getMobile());
                    tmp.setCreateTime(d.getCreateTime());
                    tmp.setUpdateTime(si.getCreateTime());
                    tmp.setUserId(userInfo.getId());
                    suggestionInfoMapper.insert(tmp);
                }else {
                    SuggestionInfo sg = sgLs.get(0);
                    Integer re = sg.getIsRead();
                    if (re.intValue() == 1){
                        //已读需要根据更新时间判定
                        Date sgReadTime = sg.getReadTime();
                        Date odUpTime = d.getUpdateTime();
                        if (sgReadTime != null && odUpTime.after(sgReadTime)){
                            sg.setIsRead(0);
                        }
                        sg.setUpdateTime(d.getUpdateTime());
                        suggestionInfoMapper.updateByPrimaryKeySelective(sg);
                    }
                }
            });
        }
    }

总结:

1、逆向思维还是很有必要的
2、要注意数据量、处理好优化,否在会影响查询数据接口的性能
3、做之前一定一定要多想想设计,想多了,你就会事半功倍
4、code review很重要,要是之前就有这样的机制,这种问题其实应该不会发生,这里奇怪的是测试居然也过了。。。。
5、The debt owed by the team will always be repaid
???????好了,就写道这里,希望能开拓大家处理问题的思路。

  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2022-04-01 00:30:35  更:2022-04-01 00:31:19 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 6:01:38-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码