微服务项目收获和总结---第4天(文章审核和保存)

news2024/11/24 7:41:20

文章审核以及APP端保存文章

业务流程: 

App端保存接口:

数据库表详情

文章的基本信息表:id,标题,作者id,频道id......

文章的权限/配置表:存储文章是否可以评论,是否上架,是否转发,是否下架

文章的内容表:为文章的内容数据量大,所以被分库分表出来,记录文章的内容 

分布式ID的技术选型:雪花算法

 

MybatisPlus中已经集成了雪花算法,所以只需要在id上配置类型为id_worker。并且可以在配置文件中配置机器id和服务id 

@TableId(value = "id",type = IdType.ID_WORKER)
private Long id;

 

业务流程

①首先将文章的信息作为参数传过来,然后判断文章是否已经存在,因为不知道是保存新的文章还是修改之前的文章。②然后如果是新的文章,就要保存文章,保存文章的配置和保存文章的内容。③如果是修改已经存在的文章,则先把文章修改成新的数据,然后再保存文章的内容。

第一步:在heima-leadnews-fegin-api中定义Feign的接口
@FeignClient(value = "leadnews_article")
public interface IArticleClient {

    @PostMapping("/api/v1/article/save")
    public ResponseResult saveArticle(@RequestBody ArticleDto dto);
}
第二步:在heima-leadnews-article中实现Feign的接口
@RestController
public class ArticleClient implements IArticleClient {

    @Autowired
    private ApArticleService apArticleService;

    @PostMapping("/api/v1/article/save")
    @Override
    public ResponseResult saveArticle(@RequestBody ArticleDto dto) {
        return apArticleService.saveArticle(dto);
    }
}
第三步:实现类,保存文章的内容,包括配置和内容
    @Autowired
    private ApArticleConfigMapper apArticleConfigMapper;
    @Autowired
    private ApArticleContentMapper apArticleContentMapper;
    /**
     * 保存app端的文章
     * @param dto
     * @return
     */
    @Override
    public ResponseResult saveArticle(ArticleDto dto) {
        //检查参数
        if(dto == null){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        //创建文章的对象,并且拷贝过来
        ApArticle article = new ApArticle();
        BeanUtils.copyProperties(dto,article);

        //判断是否文章是否存在id
        if(dto.getId() == null){
            //不存在id 则需要保存文章
            save(article);

            //保存配置
            ApArticleConfig apArticleConfig = new ApArticleConfig(article.getId());
            apArticleConfigMapper.insert(apArticleConfig);

            //保存内容
            ApArticleContent apArticleContent = new ApArticleContent();
            apArticleContent.setArticleId(article.getId());
            apArticleContent.setContent(dto.getContent());
            apArticleContentMapper.insert(apArticleContent);

        }else{
            //存在id 修改 文章 文章内容
            updateById(article);

            //修改文章内容
            ApArticleContent apArticleContent = apArticleContentMapper.selectOne(Wrappers.<ApArticleContent>lambdaQuery().eq(ApArticleContent::getArticleId, dto.getId()));
            apArticleContent.setContent(dto.getContent());
            apArticleContentMapper.updateById(apArticleContent);
        }

        //结果返回 文章id
        return ResponseResult.okResult(article.getId());
    }

 

文章内容审核:

数据库表详情

status字段:0 草稿 1 待审核 2 审核失败 3 人工审核 4 人工审核通过 8 审核通过(待发布) 9 已发布

业务流程

首先根据传过来的参数去查询文章,如果文章不存在则会报错,如果存在则将文章并且判断文章是处于待审核状态。就把内容中的图片和文本提取出来。再把图片和文本通过阿里官方接口进行审核,并且修改文章的状态,设置审核失败或者需要人工审核。当所有的准备都完成后就可以远程调用Fegin接口去实现文章审核通过保存文章的操作

media微服务要远程调用article微服务,需要在启动类上添加扫描类

@Service
@Transactional
@Slf4j
public class WmNewsAutoScanServiceimpl implements WmNewsAutoScanService {


    @Autowired
    private WmNewsMapper wmNewsMapper;

    /**
     * 自媒体文章审核
     * @param id 参数是文章的id
     */
    @Override
    public void autoScanWmnews(Integer id) {
        //1.查询目标文章
        WmNews wmNews = wmNewsMapper.selectById(id);
        if(wmNews == null){
            throw new RuntimeException("文章不存在");
        }
        //判断文章是否处于待审核阶段,如果在就进行内容审核
        if(wmNews.getStatus().equals(WmNews.Status.SUBMIT.getCode())){

            //调用方法从内容中提取纯文本内容和图片,去用于审核
            Map<String,Object> textAndImages = handleTextAndImages(wmNews);

            //2.审核文本内容  //直接默认通过,不使用阿里云的验证

            //3.审核图片     //直接默认通过,不使用阿里云的验证

            //4.审核成功调用方法去保存APP端的相关数据
            ResponseResult responseResult = saveAppArticle(wmNews);
            if(!responseResult.getCode().equals(200)){
                throw new RuntimeException("文章审核保存app端失败");
            }

            //回填articleid
            wmNews.setArticleId((Long) responseResult.getData());

            //状态设置成功状态
            updateWmNews(wmNews, (short) 9,"审核成功");
        }
    }

    @Autowired
    private IArticleClient iArticleClient;
    @Autowired
    private WmChannelMapper wmChannelMapper;
    @Autowired
    private WmUserMapper wmUserMapper;

    //更新文章的状态
    private void updateWmNews(WmNews wmNews, short status, String reason) {
        wmNews.setStatus(status);
        wmNews.setReason(reason);
        wmNewsMapper.updateById(wmNews);
    }

    //保存app端相关的文章数据
    private ResponseResult saveAppArticle(WmNews wmNews) {

        //创建对象
        ArticleDto articleDto = new ArticleDto();
        BeanUtils.copyProperties(wmNews,articleDto);
        //设置文章布局
        articleDto.setLayout(wmNews.getType());
        //设置频道信息
        WmChannel wmChannel = wmChannelMapper.selectById(wmNews.getChannelId());
        if(wmChannel != null){
            articleDto.setChannelName(wmChannel.getName());
        }
        //设置作者信息
        articleDto.setAuthorId(wmNews.getUserId().longValue());
        WmUser wmUser = wmUserMapper.selectById(wmNews.getUserId());
        if(wmUser != null){
            articleDto.setAuthorName(wmUser.getName());
        }
        //设置文章id
        if(wmNews.getArticleId() != null){
            articleDto.setId(wmNews.getArticleId());
        }
        //设置时间
        articleDto.setCreatedTime(new Date());

        //远程调用
        ResponseResult responseResult = iArticleClient.saveArticle(articleDto);
        //返回数据
        return responseResult;
    }

    //从文章内容中提取文章内容和图片
    private Map<String, Object> handleTextAndImages(WmNews wmNews) {

        //存储纯文本内容
        StringBuilder stringBuilder = new StringBuilder();
        //存储图片信息
        List<String> images = new ArrayList<>();
        //当亲内容不为空
        if(StringUtils.isNotBlank(wmNews.getContent())){
            List<Map> maps = JSONArray.parseArray(wmNews.getContent(), Map.class);
            for (Map map : maps) {
                if(map.get("type").equals("text")){
                    stringBuilder.append(map.get("value"));
                }

                if(map.get("type").equals("images")){
                    images.add((String) map.get("value"));
                }
            }
        }

        //提取封面图片
        if(StringUtils.isNotBlank(wmNews.getImages())){
            String[] split = wmNews.getImages().split(",");
            images.addAll(Arrays.asList(split));
        }

        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("content",stringBuilder.toString());
        resultMap.put("images",images);

        return resultMap;
    }
}
Fegin远程调用服务降级

由于上级的微服务的服务异常不可用,最终会蔓延到下游所有的服务,导致下游的服务都崩掉,所以这里使用hystrix实现降级

 文章审核的异步调用

 第一步:

    @Override
    @Async //表名方法为异步方法
    public void autoScanWmnews(Integer id) 

 第二步:

        //保存文章封面图片与素材的关系
        saveRelativeInfoForCover(dto,wmNews,materials);

        //审核文章
        wmNewsAutoScanService.autoScanWmnews(wmNews.getId());

第三步:

@SpringBootApplication
@EnableDiscoveryClient
@MapperScan("com.heima.wemedia.mapper")
@EnableFeignClients(basePackages = "com.heima.apis")
@EnableAsync//开启异步调用
public class WemediaApplication {

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1690959.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

eclipse配置JDK和Tomcat

eclipse配置JDK jdk配置 配置JDK&#xff1a; 首先&#xff0c;确保JDK已经安装并配置了环境变量。这包括设置JAVA_HOME环境变量&#xff0c;指向JDK的安装目录&#xff0c;以及更新CLASSPATH和PATH环境变量以包含JDK的bin目录。 在Eclipse中&#xff0c;通过Window > Pre…

【设计模式深度剖析】【4】【创建型】【建造者模式】| 类比选购汽车的过程,加深理解

&#x1f448;️上一篇:抽象工厂模式 | 下一篇:原型模式&#x1f449;️ 目录 建造者模式概览定义英文原话直译如何理解呢&#xff1f;建造者模式将对象的建造过程给抽象出来了类比选购汽车 4个角色UML类图1. 抽象建造者&#xff08;Builder&#xff09;角色2. 具体建造者…

02.爬虫---HTTP基本原理

02.HTTP基本原理 1.URI 和 URL 的区别2.HTTP 和 HTTPS 的区别3.请求过程 1.URI 和 URL 的区别 URL&#xff08;Uniform Resource Locator&#xff09;即-统一资源定位符 URL是用来定位和访问互联网上资源的独特标识&#xff0c;它包括了资源的位置&#xff08;如IP地址或域名&a…

Docker-制作镜像的两种方式=》基于容器制作基于Dockerfile制作

本文主要是基于Docker如何制作一个Java镜像&#xff0c;而一个Java镜像想要运行需要系统环境&#xff0c;JDK。所以我们要先有一个系统环境&#xff0c;本文使用的是centos7&#xff0c;JDK选择版本是8&#xff0c;而我使用的Java程序是一个简易的springBoot项目&#xff0c;你…

详细分析Vue按钮间距的优化方式(附Demo)

目录 前言1. 按钮间距2. 垂直间距 前言 正常间距如下&#xff1a; 其Demo如下&#xff1a; <el-table-column label"操作" align"center"><template #default"scope"><el-buttonlinktype"primary"click"openFor…

Node.js —— 前后端的身份认证 之用 express 实现 JWT 身份认证

JWT的认识 什么是 JWT JWT&#xff08;英文全称&#xff1a;JSON Web Token&#xff09;是目前最流行的跨域认证解决方案。 JWT 的工作原理 总结&#xff1a;用户的信息通过 Token 字符串的形式&#xff0c;保存在客户端浏览器中。服务器通过还原 Token 字符串的形式来认证用…

Mysql注入详细讲解

特殊字符 0x3a:0x7e~0x23# 注入基础 联合查询注入(union) :::tips 页面将SQL查询内容显示出来&#xff0c;即为有回显&#xff0c;可以尝试联合查询注入 利用关键字union &#xff0c;union all 拼接恶意SQL语句 ::: 注入流程 有报错&#xff0c;可以利用报错。如&#xff…

[datawhale202405]从零手搓大模型实战:TinyAgent

结论速递 TinyAgent项目实现了一个简单的Agent智能体&#xff0c;主要是实现了ReAct策略&#xff08;推理调用工具的能力&#xff09;&#xff0c;及封装了一个Tool。 项目实现有一定的疏漏。为了正确运行代码&#xff0c;本次对代码Agent部分进行了简单修改&#xff08;完善…

VBA语言専攻每周通知20240524

通知20240524 各位学员∶本周MF系列VBA技术资料增加611-615讲&#xff0c;T3学员看到通知后请免费领取,领取时间5月24日晚上18:00-5月26日晚上18:00。本次增加内容&#xff1a; MF611:用InputBox录入日期 MF612:信息提示10秒后关自动关闭 MF613:只是信息提示10秒 MF614:显…

Zynq-Linux移植学习笔记之68- 国产ZYNQ添加用户自定义版本信息

1、背景介绍 在使用复旦微zynq时&#xff0c;有时候虽然针对uboot源码进行了改动&#xff0c;但由于uboot基线版本只有一个&#xff08;2018-07-fmsh&#xff09;&#xff0c;导致无法区分版本信息&#xff0c;虽然可以通过编译时间来区分&#xff0c;但没有版本号直观。内核也…

【Numpy】深入解析numpy中的ravel方法

NumPy中的ravel方法&#xff1a;一维化数组的艺术 &#x1f308; 欢迎莅临我的个人主页&#x1f448;这里是我深耕Python编程、机器学习和自然语言处理&#xff08;NLP&#xff09;领域&#xff0c;并乐于分享知识与经验的小天地&#xff01;&#x1f387; &#x1f393; 博主简…

香港服务器负载过高的原因和应对办法

保持网站正常运行看似简单&#xff0c;但事实上&#xff0c;有许多问题会影响网站和应用程序的性能&#xff0c;并可能导致停机。其中一个问题就是服务器过载。而香港服务器作为一种常见的服务器类型&#xff0c;有时会出现负载过高的情况。为了帮助您确保在香港服务器过载不会…

AI应用案例:电能量异常分析智能诊断系统

窃电和计量装置故障造成漏收、少收电费使电力系统利益受损。一般情况主要通过定期巡检、定期校验电表、用户举报窃电等手段来发现窃电或计量装置故障。对人的依赖性太强&#xff0c;抓窃查漏的目标不明确。利用电力系统中逐步积累下来的海量真实数据&#xff0c;采用数据挖掘技…

C++多生产者,多消费者模型

C11实现多生产者&#xff0c;多消费者模型 在C标准库中实现多生产者多消费者模型&#xff0c;可以使用std::thread、std::queue、互斥锁(std::mutex)、条件变量(std::condition_variable)等组件。下面是一个简单的示例&#xff0c;展示如何创建多生产者和多消费者模型&#xf…

构建智能化的语言培训教育技术架构:挑战与机遇

随着全球化的发展和人们对语言学习需求的增长&#xff0c;语言培训教育行业正面临着越来越多的挑战和机遇。在这个背景下&#xff0c;构建智能化的语言培训教育技术架构成为提升服务质量和效率的重要手段。本文将探讨语言培训教育行业的技术架构设计与实践。 一、智能化教学平台…

Jupyter Notebook的三个使用场景:网页端、PyCharm专业版和VScode

说明&#xff0c;以下都是我个人的摸索感悟和总结&#xff0c;自己理解和猜测的是这样&#xff0c;欢迎指正。 Jupyter Notebook的三个常用使用地方&#xff08;网页端、PyCharm专业版、VScode&#xff09;&#xff1a; 总结一句话&#xff1a;网页端、PyCharm中和VScode中三…

Python使用multiprocessing实现多进程

大家好&#xff0c;当我们工作中涉及到处理大量数据、并行计算或并发任务时&#xff0c;Python的multiprocessing模块是一个强大而实用的工具。通过它&#xff0c;我们可以轻松地利用多核处理器的优势&#xff0c;将任务分配给多个进程并同时执行&#xff0c;从而提高程序的性能…

ROCm上情感分析:使用循环神经网络

15.2. 情感分析&#xff1a;使用循环神经网络 — 动手学深度学习 2.0.0 documentation (d2l.ai) 代码 import torch from torch import nn from d2l import torch as d2lbatch_size 64 train_iter, test_iter, vocab d2l.load_data_imdb(batch_size)class BiRNN(nn.Module):…

躺赚零撸项目,看广告赚红包,零门槛提现,秒到账,单机每日100+

这个项目是跟广告商直接对接的&#xff0c;跟以前小游戏看广告差不多&#xff0c;看完广告得金币5000个兑换5毛钱。 不过这个是可以直接提现&#xff0c;而是无门槛就可以提&#xff0c;有设备就可以操作&#xff0c;有空边看连续剧边刷也是挺香的&#xff0c;单机可以达到100…

组网智能是啥?

组网智能是一种基于穿透技术的远程连接解决方案&#xff0c;它为用户提供了操作简单、跨平台应用、无网络要求和独创的安全加速方案等优势。由于这些特点&#xff0c;组网智能已经被几十万用户广泛应用&#xff0c;解决了各行业客户的远程连接需求。 跨平台应用 组网智能具备跨…