河南网站备案地址,网站空间的参数,物流公司怎么做,做外贸兼职的网站有哪些❤ 作者主页#xff1a;欢迎来到我的技术博客#x1f60e; ❀ 个人介绍#xff1a;大家好#xff0c;本人热衷于Java后端开发#xff0c;欢迎来交流学习哦#xff01;(#xffe3;▽#xffe3;)~* #x1f34a; 如果文章对您有帮助#xff0c;记得关注、点赞、收藏、… ❤ 作者主页欢迎来到我的技术博客 ❀ 个人介绍大家好本人热衷于Java后端开发欢迎来交流学习哦(▽)~* 如果文章对您有帮助记得关注、点赞、收藏、评论⭐️⭐️⭐️ 您的支持将是我创作的动力让我们一起加油进步吧 文章目录 自媒体文章发布1、自媒体前后端搭建1.1 后台搭建1.2 前台搭建 2、自媒体素材管理2.1 素材上传2.1.1 需求分析2.1.2 素材管理-图片上传-表结构2.1.3 实现思路2.2.4 接口定义2.1.5 自媒体微服务集成heima-file-starter2.1.6 具体实现 2.2 素材列表查询2.2.1 接口定义2.2.2 功能实现 3、自媒体文章管理3.1 查询所有频道3.1.1 需求分析3.1.2 表结构3.1.3 接口定义3.1.4 功能实现3.1.5 测试 3.2 查询自媒体文章3.2.1 需求说明3.2.2 表结构分析3.2.3 接口定义3.2.4 功能实现3.2.5 测试 3.3 文章发布3.3.1 需求分析3.3.2 表结构分析3.3.3 实现思路分析3.3.4 接口定义3.3.5 功能实现3.3.6 测试 自媒体文章发布
1、自媒体前后端搭建
1.1 后台搭建 ①资料中找到heima-leadnews-wemedia.zip解压
拷贝到heima-leadnews-service工程下并指定子模块
执行leadnews-wemedia.sql脚本
添加对应的nacos配置
spring:datasource:driver-class-name: com.mysql.jdbc.Driverurl: jdbc:mysql://localhost:3306/leadnews_wemedia?useUnicodetruecharacterEncodingUTF-8serverTimezoneUTCusername: rootpassword: root
# 设置Mapper接口所对应的XML文件位置如果你在Mapper接口中有自定义方法需要进行该配置
mybatis-plus:mapper-locations: classpath*:mapper/*.xml# 设置别名包扫描路径通过该属性可以给包中的类注册别名type-aliases-package: com.heima.model.media.pojos②资料中找到heima-leadnews-wemedia-gateway.zip解压
拷贝到heima-leadnews-gateway工程下并指定子模块
添加对应的nacos配置
spring:cloud:gateway:globalcors:cors-configurations:[/**]: # 匹配所有请求allowedOrigins: * #跨域处理 允许所有的域allowedMethods: # 支持的方法- GET- POST- PUT- DELETEroutes:# 平台管理- id: wemediauri: lb://leadnews-wemediapredicates:- Path/wemedia/**filters:- StripPrefix 1③在资料中找到类文件夹
拷贝wemedia文件夹到heima-leadnews-model模块下的com.heima.model 1.2 前台搭建 通过nginx的虚拟主机功能使用同一个nginx访问多个项目。 搭建步骤
①资料中找到wemedia-web.zip解压
②在nginx中leadnews.conf目录中新增heima-leadnews-wemedia.conf文件 网关地址修改localhost:51602 前端项目目录修改wemedia-web解压的目录 访问端口修改(8802)
upstream heima-wemedia-gateway{server localhost:51602;
}server {listen 8802;location / {root D:/workspace/wemedia-web/;index index.html;}location ~/wemedia/MEDIA/(.*) {proxy_pass http://heima-wemedia-gateway/$1;proxy_set_header HOST $host; # 不改变源请求头的值proxy_pass_request_body on; #开启获取请求体proxy_pass_request_headers on; #开启获取请求头proxy_set_header X-Real-IP $remote_addr; # 记录真实发出请求的客户端IPproxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; #记录代理信息}
}③启动nginx启动自媒体微服务和对应网关
④联调测试登录功能 2、自媒体素材管理
2.1 素材上传
2.1.1 需求分析 图片上传的页面首先是展示素材信息可以点击图片上传弹窗后可以上传图片。 2.1.2 素材管理-图片上传-表结构
媒体图文素材信息表wm_material
对应实体类
package com.heima.model.wemedia.pojos;import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;import java.io.Serializable;
import java.util.Date;/*** p* 自媒体图文素材信息表* /p** author itheima*/
Data
TableName(wm_material)
public class WmMaterial implements Serializable {private static final long serialVersionUID 1L;/*** 主键*/TableId(value id, type IdType.AUTO)private Integer id;/*** 自媒体用户ID*/TableField(user_id)private Integer userId;/*** 图片地址*/TableField(url)private String url;/*** 素材类型0 图片1 视频*/TableField(type)private Short type;/*** 是否收藏*/TableField(is_collection)private Short isCollection;/*** 创建时间*/TableField(created_time)private Date createdTime;}2.1.3 实现思路 ①前端发送上传图片请求类型为MultipartFile
②网关进行token解析后把解析后的用户信息存储到header中
//获得token解析后中的用户信息
Object userId claimsBody.get(id);
//在header中添加新的信息
ServerHttpRequest serverHttpRequest request.mutate().headers(httpHeaders - {httpHeaders.add(userId, userId );
}).build();
//重置header
exchange.mutate().request(serverHttpRequest).build();③自媒体微服务使用拦截器获取到header中的的用户信息并放入到threadlocal中
在heima-leadnews-utils中新增工具类
注意需要从资料中找出WmUser实体类拷贝到model工程下
package com.heima.utils.thread;import com.heima.model.wemedia.pojos.WmUser;public class WmThreadLocalUtil {private final static ThreadLocalWmUser WM_USER_THREAD_LOCAL new ThreadLocal();/*** 添加用户* param wmUser*/public static void setUser(WmUser wmUser){WM_USER_THREAD_LOCAL.set(wmUser);}/*** 获取用户*/public static WmUser getUser(){return WM_USER_THREAD_LOCAL.get();}/*** 清理用户*/public static void clear(){WM_USER_THREAD_LOCAL.remove();}
}在heima-leadnews-wemedia中新增拦截器:
package com.heima.wemedia.interceptor;import com.heima.model.wemedia.pojos.WmUser;
import com.heima.utils.thread.WmThreadLocalUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Optional;Slf4j
public class WmTokenInterceptor implements HandlerInterceptor {Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {//得到header中的信息String userId request.getHeader(userId);OptionalString optional Optional.ofNullable(userId);if(optional.isPresent()){//把用户id存入threadloacl中WmUser wmUser new WmUser();wmUser.setId(Integer.valueOf(userId));WmThreadLocalUtils.setUser(wmUser);log.info(wmTokenFilter设置用户信息到threadlocal中...);}return true;}Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {log.info(清理threadlocal...);WmThreadLocalUtils.clear();}
}配置使拦截器生效拦截所有的请求
package com.heima.wemedia.config;import com.heima.wemedia.interceptor.WmTokenInterceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;Configuration
public class WebMvcConfig implements WebMvcConfigurer {Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new WmTokenInterceptor()).addPathPatterns(/**);}
}④先把图片上传到minIO中获取到图片请求的路径——2.2.5查看具体功能实现
⑤把用户id和图片上的路径保存到素材表中——2.2.5查看具体功能实现 2.2.4 接口定义
说明接口路径/api/v1/material/upload_picture请求方式POST参数MultipartFile响应结果ResponseResult
MultipartFile Springmvc指定的文件接收类型
ResponseResult
成功需要回显图片返回素材对象
{host:null,code:200,errorMessage:操作成功,data:{id:52,userId:1102,url:http://192.168.200.130:9000/leadnews/2021/04/26/a73f5b60c0d84c32bfe175055aaaac40.jpg,type:0,isCollection:0,createdTime:2021-01-20T16:49:48.4430000}
}失败
参数失效文章上传失败 2.1.5 自媒体微服务集成heima-file-starter
①导入heima-file-starter
dependenciesdependencygroupIdcom.heima/groupIdartifactIdheima-file-starter/artifactIdversion1.0-SNAPSHOT/version/dependency
/dependencies②在自媒体微服务的配置中心添加以下配置
minio:accessKey: miniosecretKey: minio123bucket: leadnewsendpoint: http://192.168.200.130:9000readPath: http://192.168.200.130:90002.1.6 具体实现
①创建WmMaterialController
RestController
RequestMapping(/api/v1/material)
public class WmMaterialController {PostMapping(/upload_picture)public ResponseResult uploadPicture(MultipartFile multipartFile){return null;}}②mapper
package com.heima.wemedia.mapper;import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.heima.model.wemedia.pojos.WmMaterial;
import org.apache.ibatis.annotations.Mapper;Mapper
public interface WmMaterialMapper extends BaseMapperWmMaterial {
}③业务层
package com.heima.wemedia.service;public interface WmMaterialService extends IServiceWmMaterial {/*** 图片上传* param multipartFile* return*/public ResponseResult uploadPicture(MultipartFile multipartFile);}业务层实现类
package com.heima.wemedia.service.impl;import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.heima.file.service.FileStorageService;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.wemedia.pojos.WmMaterial;
import com.heima.utils.thread.WmThreadLocalUtil;
import com.heima.wemedia.mapper.WmMaterialMapper;
import com.heima.wemedia.service.WmMaterialService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;import java.io.IOException;
import java.util.Date;
import java.util.UUID;Slf4j
Service
Transactional
public class WmMaterialServiceImpl extends ServiceImplWmMaterialMapper, WmMaterial implements WmMaterialService {Autowiredprivate FileStorageService fileStorageService;/*** 图片上传* param multipartFile* return*/Overridepublic ResponseResult uploadPicture(MultipartFile multipartFile) {//1.检查参数if(multipartFile null || multipartFile.getSize() 0){return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);}//2.上传图片到minIO中String fileName UUID.randomUUID().toString().replace(-, );//aa.jpgString originalFilename multipartFile.getOriginalFilename();String postfix originalFilename.substring(originalFilename.lastIndexOf(.));String fileId null;try {fileId fileStorageService.uploadImgFile(, fileName postfix, multipartFile.getInputStream());log.info(上传图片到MinIO中fileId:{},fileId);} catch (IOException e) {e.printStackTrace();log.error(WmMaterialServiceImpl-上传文件失败);}//3.保存到数据库中WmMaterial wmMaterial new WmMaterial();wmMaterial.setUserId(WmThreadLocalUtil.getUser().getId());wmMaterial.setUrl(fileId);wmMaterial.setIsCollection((short)0);wmMaterial.setType((short)0);wmMaterial.setCreatedTime(new Date());save(wmMaterial);//4.返回结果return ResponseResult.okResult(wmMaterial);}}④控制器
RestController
RequestMapping(/api/v1/material)
public class WmMaterialController {Autowiredprivate WmMaterialService wmMaterialService;PostMapping(/upload_picture)public ResponseResult uploadPicture(MultipartFile multipartFile){return wmMaterialService.uploadPicture(multipartFile);}}⑤测试
启动自媒体微服务和自媒体网关使用前端项目进行测试 2.2 素材列表查询
2.2.1 接口定义
说明接口路径/api/v1/material/list请求方式POST参数WmMaterialDto响应结果ResponseResult
WmMaterialDto
Data
public class WmMaterialDto extends PageRequestDto {/*** 1 收藏* 0 未收藏*/private Short isCollection;
}ResponseResult :
{host:null,code:200,errorMessage:操作成功,data:[{id:52,userId:1102,url:http://192.168.200.130:9000/leadnews/2021/04/26/ec893175f18c4261af14df14b83cb25f.jpg,type:0,isCollection:0,createdTime:2021-01-20T16:49:48.0000000},....],currentPage:1,size:20,total:0
}2.2.2 功能实现
①在WmMaterialController类中新增方法
PostMapping(/list)
public ResponseResult findList(RequestBody WmMaterialDto dto){return null;
}②mapper已定义
③业务层
在WmMaterialService中新增方法
/*** 素材列表查询* param dto* return*/
public ResponseResult findList( WmMaterialDto dto);实现方法
/*** 素材列表查询* param dto* return*/
Override
public ResponseResult findList(WmMaterialDto dto) {//1.检查参数dto.checkParam();//2.分页查询IPage page new Page(dto.getPage(),dto.getSize());LambdaQueryWrapperWmMaterial lambdaQueryWrapper new LambdaQueryWrapper();//是否收藏if(dto.getIsCollection() ! null dto.getIsCollection() 1){lambdaQueryWrapper.eq(WmMaterial::getIsCollection,dto.getIsCollection());}//按照用户查询lambdaQueryWrapper.eq(WmMaterial::getUserId,WmThreadLocalUtil.getUser().getId());//按照时间倒序lambdaQueryWrapper.orderByDesc(WmMaterial::getCreatedTime);page page(page,lambdaQueryWrapper);//3.结果返回ResponseResult responseResult new PageResponseResult(dto.getPage(),dto.getSize(),(int)page.getTotal());responseResult.setData(page.getRecords());return responseResult;
}④控制器
PostMapping(/list)
public ResponseResult findList(RequestBody WmMaterialDto dto){return wmMaterialService.findList(dto);
}⑤在自媒体引导类中天mybatis-plus的分页拦截器
Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {MybatisPlusInterceptor interceptor new MybatisPlusInterceptor();interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));return interceptor;
}3、自媒体文章管理
3.1 查询所有频道
3.1.1 需求分析 3.1.2 表结构
wm_channel 频道信息表
对应实体类
package com.heima.model.wemedia.pojos;import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;import java.io.Serializable;
import java.util.Date;/*** p* 频道信息表* /p** author itheima*/
Data
TableName(wm_channel)
public class WmChannel implements Serializable {private static final long serialVersionUID 1L;TableId(value id, type IdType.AUTO)private Integer id;/*** 频道名称*/TableField(name)private String name;/*** 频道描述*/TableField(description)private String description;/*** 是否默认频道* 1默认 true* 0非默认 false*/TableField(is_default)private Boolean isDefault;/*** 是否启用* 1启用 true* 0禁用 false*/TableField(status)private Boolean status;/*** 默认排序*/TableField(ord)private Integer ord;/*** 创建时间*/TableField(created_time)private Date createdTime;}3.1.3 接口定义
说明接口路径/api/v1/channel/channels请求方式POST参数无响应结果ResponseResult
ResponseResult
{host: null,code: 0,errorMessage: 操作成功,data: [{id: 4,name: java,description: java,isDefault: true,status: false,ord: 3,createdTime: 2019-08-16T10:55:41.0000000},Object { ... },Object { ... }]
}3.1.4 功能实现
接口定义
package com.heima.wemedia.controller.v1;import com.heima.model.common.dtos.ResponseResult;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;RestController
RequestMapping(/api/v1/channel)
public class WmchannelController {GetMapping(/channels)public ResponseResult findAll(){return null;}
}mapper
package com.heima.wemedia.mapper;import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.heima.model.wemedia.pojos.WmChannel;
import org.apache.ibatis.annotations.Mapper;Mapper
public interface WmChannelMapper extends BaseMapperWmChannel {
}service
package com.heima.wemedia.service;import com.baomidou.mybatisplus.extension.service.IService;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.wemedia.pojos.WmChannel;public interface WmChannelService extends IServiceWmChannel {/*** 查询所有频道* return*/public ResponseResult findAll();}实现类
package com.heima.wemedia.service.impl;import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.wemedia.pojos.WmChannel;
import com.heima.wemedia.mapper.WmChannelMapper;
import com.heima.wemedia.service.WmChannelService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;Service
Transactional
Slf4j
public class WmChannelServiceImpl extends ServiceImplWmChannelMapper, WmChannel implements WmChannelService {/*** 查询所有频道* return*/Overridepublic ResponseResult findAll() {return ResponseResult.okResult(list());}
}控制层
package com.heima.wemedia.controller.v1;import com.heima.model.common.dtos.ResponseResult;
import com.heima.wemedia.service.WmChannelService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;RestController
RequestMapping(/api/v1/channel)
public class WmchannelController {Autowiredprivate WmChannelService wmChannelService;GetMapping(/channels)public ResponseResult findAll(){return wmChannelService.findAll();}
}3.1.5 测试 3.2 查询自媒体文章
3.2.1 需求说明 3.2.2 表结构分析
wm_news 自媒体文章表 对应实体类
package com.heima.model.wemedia.pojos;import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import org.apache.ibatis.type.Alias;import java.io.Serializable;
import java.util.Date;/*** p* 自媒体图文内容信息表* /p*/
Data
TableName(wm_news)
public class WmNews implements Serializable {private static final long serialVersionUID 1L;/*** 主键*/TableId(value id, type IdType.AUTO)private Integer id;/*** 自媒体用户ID*/TableField(user_id)private Integer userId;/*** 标题*/TableField(title)private String title;/*** 图文内容*/TableField(content)private String content;/*** 文章布局0 无图文章1 单图文章3 多图文章*/TableField(type)private Short type;/*** 图文频道ID*/TableField(channel_id)private Integer channelId;TableField(labels)private String labels;/*** 创建时间*/TableField(created_time)private Date createdTime;/*** 提交时间*/TableField(submited_time)private Date submitedTime;/*** 当前状态0 草稿1 提交待审核2 审核失败3 人工审核4 人工审核通过8 审核通过待发布9 已发布*/TableField(status)private Short status;/*** 定时发布时间不定时则为空*/TableField(publish_time)private Date publishTime;/*** 拒绝理由*/TableField(reason)private String reason;/*** 发布库文章ID*/TableField(article_id)private Long articleId;/*** //图片用逗号分隔*/TableField(images)private String images;TableField(enable)private Short enable;//状态枚举类Alias(WmNewsStatus)public enum Status{NORMAL((short)0),SUBMIT((short)1),FAIL((short)2),ADMIN_AUTH((short)3),ADMIN_SUCCESS((short)4),SUCCESS((short)8),PUBLISHED((short)9);short code;Status(short code){this.code code;}public short getCode(){return this.code;}}}3.2.3 接口定义
说明接口路径/api/v1/news/list请求方式POST参数WmNewsPageReqDto响应结果ResponseResult
WmNewsPageReqDto :
package com.heima.model.wemedia.dtos;import com.heima.model.common.dtos.PageRequestDto;
import lombok.Data;import java.util.Date;Data
public class WmNewsPageReqDto extends PageRequestDto {/*** 状态*/private Short status;/*** 开始时间*/private Date beginPubDate;/*** 结束时间*/private Date endPubDate;/*** 所属频道ID*/private Integer channelId;/*** 关键字*/private String keyword;
}ResponseResult :
{host: null,code: 0,errorMessage: 操作成功,data: [Object { ... },Object { ... },Object { ... }],currentPage:1,size:10,total:21
}3.2.4 功能实现
①新增WmNewsController
package com.heima.wemedia.controller.v1;import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.wemedia.dtos.WmNewsPageReqDto;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;RestController
RequestMapping(/api/v1/news)
public class WmNewsController {PostMapping(/list)public ResponseResult findAll(RequestBody WmNewsPageReqDto dto){return null;}}②新增WmNewsMapper
package com.heima.wemedia.mapper;import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.heima.model.wemedia.pojos.WmNews;
import org.apache.ibatis.annotations.Mapper;Mapper
public interface WmNewsMapper extends BaseMapperWmNews {}③新增WmNewsService
package com.heima.wemedia.service;import com.baomidou.mybatisplus.extension.service.IService;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.wemedia.dtos.WmNewsPageReqDto;
import com.heima.model.wemedia.pojos.WmNews;public interface WmNewsService extends IServiceWmNews {/*** 查询文章* param dto* return*/public ResponseResult findAll(WmNewsPageReqDto dto);}实现类
package com.heima.wemedia.service.impl;import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.heima.model.common.dtos.PageResponseResult;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.wemedia.dtos.WmNewsPageReqDto;
import com.heima.model.wemedia.pojos.WmNews;
import com.heima.model.wemedia.pojos.WmUser;
import com.heima.utils.thread.WmThreadLocalUtil;
import com.heima.wemedia.mapper.WmNewsMapper;
import com.heima.wemedia.service.WmNewsService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;Service
Slf4j
Transactional
public class WmNewsServiceImpl extends ServiceImplWmNewsMapper, WmNews implements WmNewsService {/*** 查询文章* param dto* return*/Overridepublic ResponseResult findAll(WmNewsPageReqDto dto) {//1.检查参数if(dto null){return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);}//分页参数检查dto.checkParam();//获取当前登录人的信息WmUser user WmThreadLocalUtil.getUser();if(user null){return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);}//2.分页条件查询IPage page new Page(dto.getPage(),dto.getSize());LambdaQueryWrapperWmNews lambdaQueryWrapper new LambdaQueryWrapper();//状态精确查询if(dto.getStatus() ! null){lambdaQueryWrapper.eq(WmNews::getStatus,dto.getStatus());}//频道精确查询if(dto.getChannelId() ! null){lambdaQueryWrapper.eq(WmNews::getChannelId,dto.getChannelId());}//时间范围查询if(dto.getBeginPubDate()!null dto.getEndPubDate()!null){lambdaQueryWrapper.between(WmNews::getPublishTime,dto.getBeginPubDate(),dto.getEndPubDate());}//关键字模糊查询if(StringUtils.isNotBlank(dto.getKeyword())){lambdaQueryWrapper.like(WmNews::getTitle,dto.getKeyword());}//查询当前登录用户的文章lambdaQueryWrapper.eq(WmNews::getUserId,user.getId());//发布时间倒序查询lambdaQueryWrapper.orderByDesc(WmNews::getCreatedTime);page page(page,lambdaQueryWrapper);//3.结果返回ResponseResult responseResult new PageResponseResult(dto.getPage(),dto.getSize(),(int)page.getTotal());responseResult.setData(page.getRecords());return responseResult;}}④控制器
package com.heima.wemedia.controller.v1;import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.wemedia.dtos.WmNewsPageReqDto;
import com.heima.wemedia.service.WmNewsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;RestController
RequestMapping(/api/v1/news)
public class WmNewsController {Autowiredprivate WmNewsService wmNewsService;PostMapping(/list)public ResponseResult findAll(RequestBody WmNewsPageReqDto dto){return wmNewsService.findAll(dto);}}3.2.5 测试
启动后端自媒体微服务和自媒体网关微服务测试文章列表查询 3.3 文章发布
3.3.1 需求分析 3.3.2 表结构分析
保存文章除了需要wm_news表以外还需要另外两张表
wm_material 素材表 wm_news_material 文章素材关系表
其中wm_material和wm_news表的实体类已经导入到了项目中下面是wm_news_material表对应的实体类
package com.heima.model.wemedia.pojos;import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;import java.io.Serializable;/*** p* 自媒体图文引用素材信息表* /p*/
Data
TableName(wm_news_material)
public class WmNewsMaterial implements Serializable {private static final long serialVersionUID 1L;/*** 主键*/TableId(value id, type IdType.AUTO)private Integer id;/*** 素材ID*/TableField(material_id)private Integer materialId;/*** 图文ID*/TableField(news_id)private Integer newsId;/*** 引用类型0 内容引用1 主图引用*/TableField(type)private Short type;/*** 引用排序*/TableField(ord)private Short ord;}3.3.3 实现思路分析 前端提交发布或保存为草稿 后台判断请求中是否包含了文章id 如果不包含id,则为新增 3.1 执行新增文章的操作 3.2 关联文章内容图片与素材的关系 3.3 关联文章封面图片与素材的关系 如果包含了id则为修改请求 4.1 删除该文章与素材的所有关系 4.2 执行修改操作 4.3 关联文章内容图片与素材的关系 4.4 关联文章封面图片与素材的关系 3.3.4 接口定义
说明接口路径/api/v1/channel/submit请求方式POST参数WmNewsDto响应结果ResponseResult
WmNewsDto
package com.heima.model.wemedia.dtos;import lombok.Data;import java.util.Date;
import java.util.List;Data
public class WmNewsDto {private Integer id;/*** 标题*/private String title;/*** 频道id*/private Integer channelId;/*** 标签*/private String labels;/*** 发布时间*/private Date publishTime;/*** 文章内容*/private String content;/*** 文章封面类型 0 无图 1 单图 3 多图 -1 自动*/private Short type;/*** 提交时间*/private Date submitedTime; /*** 状态 提交为1 草稿为0*/private Short status;/*** 封面图片列表 多张图以逗号隔开*/private ListString images;
}前端给传递过来的json数据格式为
{title:黑马头条项目背景,type:1,//这个 0 是无图 1 是单图 3 是多图 -1 是自动labels:黑马头条,publishTime:2020-03-14T11:35:49.000Z,channelId:1,images:[http://192.168.200.130/group1/M00/00/00/wKjIgl5swbGATaSAAAEPfZfx6Iw790.png],status:1,content:[{type:text,value:随着智能手机的普及人们更加习惯于通过手机来看新闻。由于生活节奏的加快很多人只能利用碎片时间来获取信息因此对于移动资讯客户端的需求也越来越高。黑马头条项目正是在这样背景下开发出来。黑马头条项目采用当下火热的微服务大数据技术架构实现。本项目主要着手于获取最新最热新闻资讯通过大数据分析用户喜好精确推送咨询新闻},{type:image,value:http://192.168.200.130/group1/M00/00/00/wKjIgl5swbGATaSAAAEPfZfx6Iw790.png}
]
}ResponseResult:
{“code”:501,“errorMessage”:“参数失效
}{“code”:200,“errorMessage”:“操作成功
}{“code”:501,“errorMessage”:“素材引用失效
}3.3.5 功能实现
①在新增WmNewsController中新增方法
PostMapping(/submit)
public ResponseResult submitNews(RequestBody WmNewsDto dto){return null;
}②新增WmNewsMaterialMapper类文章与素材的关联关系需要批量保存索引需要定义mapper文件和对应的映射文件
package com.heima.wemedia.mapper;import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.heima.model.wemedia.pojos.WmNewsMaterial;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;import java.util.List;Mapper
public interface WmNewsMaterialMapper extends BaseMapperWmNewsMaterial {void saveRelations(Param(materialIds) ListInteger materialIds,Param(newsId) Integer newsId, Param(type)Short type);
}WmNewsMaterialMapper.xml
?xml version1.0 encodingUTF-8?
!DOCTYPE mapper PUBLIC -//mybatis.org//DTD Mapper 3.0//EN http://mybatis.org/dtd/mybatis-3-mapper.dtd
mapper namespacecom.heima.wemedia.mapper.WmNewsMaterialMapperinsert idsaveRelationsinsert into wm_news_material (material_id,news_id,type,ord)valuesforeach collectionmaterialIds indexord itemmid separator,(#{mid},#{newsId},#{type},#{ord})/foreach/insert/mapper③常量类准备
package com.heima.common.constants;public class WemediaConstants {public static final Short COLLECT_MATERIAL 1;//收藏public static final Short CANCEL_COLLECT_MATERIAL 0;//取消收藏public static final String WM_NEWS_TYPE_IMAGE image;public static final Short WM_NEWS_NONE_IMAGE 0;public static final Short WM_NEWS_SINGLE_IMAGE 1;public static final Short WM_NEWS_MANY_IMAGE 3;public static final Short WM_NEWS_TYPE_AUTO -1;public static final Short WM_CONTENT_REFERENCE 0;public static final Short WM_COVER_REFERENCE 1;
}④在WmNewsService中新增方法
/*** 发布文章或保存草稿* param dto* return*/
public ResponseResult submitNews(WmNewsDto dto);实现方法
/*** 发布修改文章或保存为草稿* param dto* return*/
Override
public ResponseResult submitNews(WmNewsDto dto) {//0.条件判断if(dto null || dto.getContent() null){return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);}//1.保存或修改文章WmNews wmNews new WmNews();//属性拷贝 属性名词和类型相同才能拷贝BeanUtils.copyProperties(dto,wmNews);//封面图片 list--- stringif(dto.getImages() ! null dto.getImages().size() 0){//[1dddfsd.jpg,sdlfjldk.jpg]-- 1dddfsd.jpg,sdlfjldk.jpgString imageStr StringUtils.join(dto.getImages(), ,);wmNews.setImages(imageStr);}//如果当前封面类型为自动 -1if(dto.getType().equals(WemediaConstants.WM_NEWS_TYPE_AUTO)){wmNews.setType(null);}saveOrUpdateWmNews(wmNews);//2.判断是否为草稿 如果为草稿结束当前方法if(dto.getStatus().equals(WmNews.Status.NORMAL.getCode())){return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);}//3.不是草稿保存文章内容图片与素材的关系//获取到文章内容中的图片信息ListString materials ectractUrlInfo(dto.getContent());saveRelativeInfoForContent(materials,wmNews.getId());//4.不是草稿保存文章封面图片与素材的关系如果当前布局是自动需要匹配封面图片saveRelativeInfoForCover(dto,wmNews,materials);return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);}/*** 第一个功能如果当前封面类型为自动则设置封面类型的数据* 匹配规则* 1如果内容图片大于等于1小于3 单图 type 1* 2如果内容图片大于等于3 多图 type 3* 3如果内容没有图片无图 type 0** 第二个功能保存封面图片与素材的关系* param dto* param wmNews* param materials*/
private void saveRelativeInfoForCover(WmNewsDto dto, WmNews wmNews, ListString materials) {ListString images dto.getImages();//如果当前封面类型为自动则设置封面类型的数据if(dto.getType().equals(WemediaConstants.WM_NEWS_TYPE_AUTO)){//多图if(materials.size() 3){wmNews.setType(WemediaConstants.WM_NEWS_MANY_IMAGE);images materials.stream().limit(3).collect(Collectors.toList());}else if(materials.size() 1 materials.size() 3){//单图wmNews.setType(WemediaConstants.WM_NEWS_SINGLE_IMAGE);images materials.stream().limit(1).collect(Collectors.toList());}else {//无图wmNews.setType(WemediaConstants.WM_NEWS_NONE_IMAGE);}//修改文章if(images ! null images.size() 0){wmNews.setImages(StringUtils.join(images,,));}updateById(wmNews);}if(images ! null images.size() 0){saveRelativeInfo(images,wmNews.getId(),WemediaConstants.WM_COVER_REFERENCE);}}/*** 处理文章内容图片与素材的关系* param materials* param newsId*/
private void saveRelativeInfoForContent(ListString materials, Integer newsId) {saveRelativeInfo(materials, newsId, WemediaConstants.WM_CONTENT_REFERENCE);
}Autowired
private WmMaterialMapper wmMaterialMapper;/*** 保存文章图片与素材的关系到数据库中* param materials* param newsId* param type*/
private void saveRelativeInfo(ListString materials, Integer newsId, Short type) {if(materials!null !materials.isEmpty()){//通过图片的url查询素材的idListWmMaterial dbMaterials wmMaterialMapper.selectList(Wrappers.WmMateriallambdaQuery().in(WmMaterial::getUrl, materials));//判断素材是否有效if(dbMaterialsnull || dbMaterials.size() 0){//手动抛出异常 第一个功能能够提示调用者素材失效了第二个功能进行数据的回滚throw new CustomException(AppHttpCodeEnum.MATERIASL_REFERENCE_FAIL);}if(materials.size() ! dbMaterials.size()){throw new CustomException(AppHttpCodeEnum.MATERIASL_REFERENCE_FAIL);}ListInteger idList dbMaterials.stream().map(WmMaterial::getId).collect(Collectors.toList());//批量保存wmNewsMaterialMapper.saveRelations(idList,newsId,type);}}/*** 提取文章内容中的图片信息* param content* return*/
private ListString ectractUrlInfo(String content) {ListString materials new ArrayList();ListMap maps JSON.parseArray(content, Map.class);for (Map map : maps) {if(map.get(type).equals(image)){String imgUrl (String) map.get(value);materials.add(imgUrl);}}return materials;
}Autowired
private WmNewsMaterialMapper wmNewsMaterialMapper;/*** 保存或修改文章* param wmNews*/
private void saveOrUpdateWmNews(WmNews wmNews) {//补全属性wmNews.setUserId(WmThreadLocalUtil.getUser().getId());wmNews.setCreatedTime(new Date());wmNews.setSubmitedTime(new Date());wmNews.setEnable((short)1);//默认上架if(wmNews.getId() null){//保存save(wmNews);}else {//修改//删除文章图片与素材的关系wmNewsMaterialMapper.delete(Wrappers.WmNewsMateriallambdaQuery().eq(WmNewsMaterial::getNewsId,wmNews.getId()));updateById(wmNews);}}④控制器
PostMapping(/submit)
public ResponseResult submitNews(RequestBody WmNewsDto dto){return wmNewsService.submitNews(dto);
}3.3.6 测试
重新启动项目后进行测试即可。 非常感谢您阅读到这里如果这篇文章对您有帮助希望能留下您的点赞 关注 分享 留言thanks