文章目录
- 平台管理
- 1 前端静态资源导入
- 1.1 配置heimi-leadnews-admin.conf
- 1.2 配置nginx.conf
- 2 管理员微服务的搭建
- 2.1 创建管理员微服务
- 2.2 创建admin表
- 2.3 导入表实体类
- 2.4 创建对应实体类的mapper
- 2.5 创建启动类
- 2.6 创建配置文件bootstrap.yml
- 2.7 在nacos中配置数据库等
- 3 登录
- 3.1 接口定义
- 3.2 定义接收的Dto类
- 3.3 Controller层
- 3.4 Service
- 3.5 测试
- 4 admin网关
- 4.1 添加依赖
- 4.2 添加网关
- 4.3 创建启动类
- 4.4 创建配置文件bootstrap.yml
- 4.5 在nacos中配置
- 4.6 测试
- 4.7 前后端联调
- 5 频道管理
- 5.1 保存频道
- 5.1.1 实体类AdChannel
- 5.1.2 修改admin的Nacos网关配置
- 5.1.3 完善自媒体服务中WmChannelController
- 5.1.4 测试
- 5.2 频道名称模糊分页查询
- 5.2.1 实体类ChannelDto
- 5.2.3 完善自媒体服务中WmChannelController
- 5.2.4 Service
- 5.2.5 测试
- 5.3 更新频道
- 5.3.1 完善自媒体服务中WmChannelController
- 5.3.2 Service
- 5.3.3 测试
- 5.4 删除频道
- 5.4.1 完善自媒体服务中WmChannelController
- 5.4.2 Service
- 5.4.3 测试
- 6 敏感词管理
- 6.1 查询列表
- 6.1.1 实体类SensitiveDto
- 6.1.2 WmSensitiveController
- 6.1.3 Service
- 6.1.4 测试
- 6.2 敏感词保存
- 6.2.1 实体类AdSensitive
- 6.2.2 WmSensitiveController
- 6.2.3 Service
- 6.2.4 测试
- 6.3 更新敏感词
- 6.3.1 WmSensitiveController
- 6.3.2 Service
- 6.3.3 测试
- 6.4 删除敏感词
- 6.4.1 WmSensitiveController
- 6.4.2 Service
- 6.4.3 测试
- 7 用户审核
- 7.0 修改leadnews-admin-gateway的nacos配置
- 7.1 查询列表
- 7.1.1 实体类AuthDto
- 7.1.2 Controller
- 7.1.3 Service
- 7.1.4 测试
- 7.2 审核失败
- 7.2.1 Controller
- 7.2.2 Service
- 7.2.3 测试
- 7.3 审核成功
- 7.3.1 Controller
- 7.3.2 Service
- 7.3.3 测试
- 8 自媒体文章人工审核
- 8.1 查询文章列表
- 8.1.1 实体类NewsAuthDto
- 8.1.2 Controller
- 8.1.3 Service
- 8.2 查询文章详情
- 8.2.1 Controller
- 8.2.2 Service
- 8.3 审核失败
- 8.3.1 Controller
- 8.3.2 Service
- 8.4 审核成功
- 8.4.1 Controller
- 8.4.2 Service
- 8.4.3 修改自动审核逻辑模拟人工审核
- 8.5 综合测试
平台管理
1 前端静态资源导入
将admin-web放入项目web文件夹中
1.1 配置heimi-leadnews-admin.conf
在nginx的conf目录下的leadnews.conf目录下创建heimi-leadnews-admin.conf
nginx监听端口8803,添加service_6001路径后转发到heima-admin-gateway的端口51603,通过Nacos路由到对应的heima-leadnews-admin微服务完成访问。
静态资源存放在D:/Code/JavaCode/HeimaToutiao/web/admin-web/展示其目录下的index.html
upstream heima-admin-gateway{server localhost:51603;
}server {listen 8803;location / {root D:/Code/JavaCode/HeimaToutiao/web/admin-web/;index index.html;}location ~/service_6001/(.*) {proxy_pass http://heima-admin-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; #记录代理信息}
}
1.2 配置nginx.conf
在nginx.conf中引入
#user nobody;
worker_processes 1;events {worker_connections 1024;
}
http {include mime.types;default_type application/octet-stream;sendfile on;keepalive_timeout 65;# 引入自定义配置文件include leadnews.conf/*.conf;
}
2 管理员微服务的搭建
2.1 创建管理员微服务
在heima-leadnews-service下创建模块heima-leadnews-admin
2.2 创建admin表
添加leadnews_admin表到mysql中
2.3 导入表实体类
在heima-leadnews-model模块下创建com.heima.model.admin.pojos包
导入两个两个实体类AdUserh和ApUserRealname类
2.4 创建对应实体类的mapper
创建com.heima.admin.mapper.AdUsermapper的mapper接口
@Mapper
public interface AdUsermapper extends BaseMapper<AdUser> {
}
2.5 创建启动类
创建com.heima.admin.AdminApplication启动类
@SpringBootApplication
@EnableDiscoveryClient
@MapperScan("com.heima.admin.mapper")
public class AdminApplication {public static void main(String[] args) {SpringApplication.run(AdminApplication.class, args);}
}
2.6 创建配置文件bootstrap.yml
server:port: 51805
spring:application:name: leadnews-admincloud:nacos:discovery:server-addr: 192.168.204.129:8848config:server-addr: 192.168.204.129:8848file-extension: yml
2.7 在nacos中配置数据库等
关于数据库的等等都需要在Nacos的配置中心进行配置
spring:datasource:driver-class-name: com.mysql.jdbc.Driverurl: jdbc:mysql://localhost:3306/leadnews_admin?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC&useSSL=falseusername: rootpassword: 123sjbsjb
# 设置Mapper接口所对应的XML文件位置,如果你在Mapper接口中有自定义方法,需要进行该配置
mybatis-plus:mapper-locations: classpath*:mapper/*.xml# 设置别名包扫描路径,通过该属性可以给包中的类注册别名type-aliases-package: com.heima.model.admin.pojosminio:accessKey: miniosecretKey: minio123bucket: leadnewsendpoint: http://192.168.204.129:9000readPath: http://192.168.204.129:9000
3 登录
3.1 接口定义
接口地址:/login/in
请求方式:POST
请求数据类型:application/json
响应数据类型:*/*
接口描述:
请求示例:
{"name": "","password": ""
}
3.2 定义接收的Dto类
heima-leadnews-model模块下的com.heima.model.admin.pojos.dtos包下创建AdUserDto类
@Data
public class AdUserDto {private String name;private String password;
}
3.3 Controller层
在heima-leadnews-admin模块下创建com.heima.admin.controller.v1.AdUserLoginController类
@RestController
@RequestMapping("/login")
public class AdUserLoginController {@Autowiredprivate AdUserService adUserService;@PostMapping("/in")public ResponseResult login(@RequestBody(required=false) AdUserDto dto) {return adUserService.login(dto);}
}
3.4 Service
接口
public interface AdUserService extends IService<AdUser> {/*** 登录功能* @param dto* @return*/public ResponseResult login(AdUserDto dto);
}
实现
@Service
@Transactional
@Slf4j
public class AdUserServiceImpl extends ServiceImpl<AdUsermapper, AdUser> implements AdUserService {@Overridepublic ResponseResult login(AdUserDto dto) {//1.正常登录 用户名、密码if(StringUtils.isNotBlank(dto.getName()) && StringUtils.isNotBlank(dto.getPassword())) {//1.1 查询用户信息,根据手机号查询用户信息AdUser dbUser = getOne(Wrappers.<AdUser>lambdaQuery().eq(AdUser::getName, dto.getName()));if(dbUser == null) {return ResponseResult.errorResult(AppHttpCodeEnum.AP_USER_DATA_NOT_EXIST, "用户不存在");}//1.2 比对密码String salt = dbUser.getSalt();String password = dto.getPassword();String pwd = DigestUtils.md5DigestAsHex((password + salt).getBytes());if(!pwd.equals(dbUser.getPassword())) {return ResponseResult.errorResult(AppHttpCodeEnum.LOGIN_PASSWORD_ERROR, "密码错误");}//1.3 没问题的话,返回数据,生成jwtString token = AppJwtUtil.getToken(dbUser.getId().longValue());Map<String,Object> map=new HashMap<>();map.put("token",token);//清空敏感信息,填入需要的信息AdUser user = new AdUser();user.setId(dbUser.getId());user.setName(dbUser.getName());user.setNickname(dbUser.getNickname());user.setImage(dbUser.getImage());user.setPhone(dbUser.getPhone());user.setStatus(dbUser.getStatus());user.setEmail(dbUser.getEmail());user.setLoginTime(dbUser.getLoginTime());user.setCreatedTime(dbUser.getCreatedTime());map.put("user",user);return ResponseResult.okResult(map);}else{return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID, "用户名或密码为空");}}
}
3.5 测试
启动,Nacos的服务管理中有leadnews-admin
发送POST请求
访问成功
4 admin网关
4.1 添加依赖
<dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId></dependency><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId></dependency><dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId></dependency>
</dependencies>
4.2 添加网关
在heima-leadnews-gateway模块下创建heima-leadnews-admin-gateway模块
创建com.heima.admin.gateway.util.AppJwtUtil类,用于JWT令牌生成
public class AppJwtUtil {// TOKEN的有效期一天(S)private static final int TOKEN_TIME_OUT = 3_600;// 加密KEYprivate static final String TOKEN_ENCRY_KEY = "MDk4ZjZiY2Q0NjIxZDM3M2NhZGU0ZTgzMjYyN2I0ZjY";// 最小刷新间隔(S)private static final int REFRESH_TIME = 300;// 生产IDpublic static String getToken(Long id){Map<String, Object> claimMaps = new HashMap<>();claimMaps.put("id",id);long currentTime = System.currentTimeMillis();return Jwts.builder().setId(UUID.randomUUID().toString()).setIssuedAt(new Date(currentTime)) //签发时间.setSubject("system") //说明.setIssuer("heima") //签发者信息.setAudience("app") //接收用户.compressWith(CompressionCodecs.GZIP) //数据压缩方式.signWith(SignatureAlgorithm.HS512, generalKey()) //加密方式.setExpiration(new Date(currentTime + TOKEN_TIME_OUT * 1000)) //过期时间戳.addClaims(claimMaps) //cla信息.compact();}/*** 获取token中的claims信息** @param token* @return*/private static Jws<Claims> getJws(String token) {return Jwts.parser().setSigningKey(generalKey()).parseClaimsJws(token);}/*** 获取payload body信息** @param token* @return*/public static Claims getClaimsBody(String token) {try {return getJws(token).getBody();}catch (ExpiredJwtException e){return null;}}/*** 获取hearder body信息** @param token* @return*/public static JwsHeader getHeaderBody(String token) {return getJws(token).getHeader();}/*** 是否过期** @param claims* @return -1:有效,0:有效,1:过期,2:过期*/public static int verifyToken(Claims claims) {if(claims==null){return 1;}try {claims.getExpiration().before(new Date());// 需要自动刷新TOKENif((claims.getExpiration().getTime()-System.currentTimeMillis())>REFRESH_TIME*1000){return -1;}else {return 0;}} catch (ExpiredJwtException ex) {return 1;}catch (Exception e){return 2;}}/*** 由字符串生成加密key** @return*/public static SecretKey generalKey() {byte[] encodedKey = Base64.getEncoder().encode(TOKEN_ENCRY_KEY.getBytes());SecretKey key = new SecretKeySpec(encodedKey, 0, encodedKey.length, "AES");return key;}public static void main(String[] args) {/* Map map = new HashMap();map.put("id","11");*/System.out.println(AppJwtUtil.getToken(1102L));Jws<Claims> jws = AppJwtUtil.getJws("eyJhbGciOiJIUzUxMiIsInppcCI6IkdaSVAifQ.H4sIAAAAAAAAADWLQQqEMAwA_5KzhURNt_qb1KZYQSi0wi6Lf9942NsMw3zh6AVW2DYmDGl2WabkZgreCaM6VXzhFBfJMcMARTqsxIG9Z888QLui3e3Tup5Pb81013KKmVzJTGo11nf9n8v4nMUaEY73DzTabjmDAAAA.4SuqQ42IGqCgBai6qd4RaVpVxTlZIWC826QA9kLvt9d-yVUw82gU47HDaSfOzgAcloZedYNNpUcd18Ne8vvjQA");Claims claims = jws.getBody();System.out.println(claims.get("id"));}}
创建过滤器com.heima.admin.gateway.fliter.AuthorizeFilter类,由于token的验证
@Component
@Slf4j
public class AuthorizeFilter implements Ordered, GlobalFilter {@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {//1.获取Request对象和Response对象ServerHttpRequest request = exchange.getRequest();ServerHttpResponse response = exchange.getResponse();//2.判断当前请求是否为登录请求,如果是,直接放行if (request.getURI().getPath().contains("/login")) {//放行return chain.filter(exchange);}//3.获取当前请求的token信息String token = request.getHeaders().getFirst("token");//4.判断token是否存在if(StringUtils.isBlank(token)) {response.setStatusCode(HttpStatus.UNAUTHORIZED);return response.setComplete();}//5.判断token是否有效//5.1 解析tokentry{Claims body = AppJwtUtil.getClaimsBody(token);//5.2 判断token是否有效int result = AppJwtUtil.verifyToken(body);if(result == 1||result == 2) {//5.3 token过期response.setStatusCode(HttpStatus.UNAUTHORIZED);return response.setComplete();}//获取用户信息Integer userId = (Integer) body.get("id");//将用户信息放入到header中ServerHttpRequest serverHttpRequest = request.mutate().headers(httpHeaders -> {httpHeaders.add("userId", userId + "");}).build();//重置请求exchange.mutate().request(serverHttpRequest);}catch (Exception e) {e.printStackTrace();//5.4 token无效response.setStatusCode(HttpStatus.UNAUTHORIZED);return response.setComplete();}//6.放行return chain.filter(exchange);}/*** 过滤器的执行顺序,返回值越小,执行优先级越高* @return*/@Overridepublic int getOrder() {return 0;}
}
4.3 创建启动类
创建com.heima.admin.gateway.AdminGatewayApplication启动类
@SpringBootApplication
@EnableDiscoveryClient
public class AdminGatewayApplication {public static void main(String[] args) {SpringApplication.run(AdminGatewayApplication.class, args);}
}
4.4 创建配置文件bootstrap.yml
server:port: 51603
spring:application:name: leadnews-admin-gatewaycloud:nacos:discovery:server-addr: 192.168.204.129:8848config:server-addr: 192.168.204.129:8848file-extension: yml
4.5 在nacos中配置
新建nacos配置,配置拦截路径及转发路径
spring:cloud:gateway:globalcors:add-to-simple-url-handler-mapping: truecorsConfigurations:'[/**]':allowedHeaders: "*"allowedOrigins: "*"allowedMethods:- GET- POST- DELETE- PUT- OPTIONroutes:# 平台管理- id: adminuri: lb://leadnews-adminpredicates:- Path=/admin/**filters:- StripPrefix= 1
4.6 测试
访问http://localhost:51603/admin/login/in
测试成功
4.7 前后端联调
启动nginx
访问localhost:8803
成功登录
5 频道管理
5.1 保存频道
频道发起保存请求的http://localhost:8803/service_6001/wemedia/api/v1/channel/save
说明网关需要拦截wemedia并且转发到相应的feign调用
接口地址:/api/v1/channel/save
请求方式:POST
请求数据类型:application/json
请求参数:
参数名称 | 参数说明 | in | 是否必须 | 数据类型 | schema |
---|---|---|---|---|---|
adChannel | adChannel | body | true | AdChannel | AdChannel |
createdTime | false | string(date-time) | |||
description | false | string | |||
id | false | integer(int32) | |||
isDefault | false | boolean | |||
name | false | string | |||
ord | false | integer(int32) | |||
status | false | boolean |
5.1.1 实体类AdChannel
在heima-leadnews-model模块下创建com.heima.model.admin.pojos.AdChannel类,因为接收对象与com.heima.model.wemedia.pojos.WmChannel一模一样,所以直接继承过来
public class AdChannel extends WmChannel {}
5.1.2 修改admin的Nacos网关配置
因为保存请求的地址http://localhost:8803/service_6001/wemedia/api/v1/channel/save
网关需要拦截wemedia并且把它发送到相应的heima-leadnew-wemedia的微服务中。所以需要修改leadnews-admin-gateway的nacos配置
spring:cloud:gateway:globalcors:add-to-simple-url-handler-mapping: truecorsConfigurations:'[/**]':allowedHeaders: "*"allowedOrigins: "*"allowedMethods:- GET- POST- DELETE- PUT- OPTIONroutes:# 管理端管理- id: adminuri: lb://leadnews-adminpredicates:- Path=/admin/**filters:- StripPrefix= 1# 自媒体微服务- id: leadnews-wemediauri: lb://leadnews-wemediapredicates:- Path=/wemedia/**filters:- StripPrefix= 1
5.1.3 完善自媒体服务中WmChannelController
@PostMapping("/save")public ResponseResult save(@RequestBody AdChannel channel){WmChannel wmChannel = new WmChannel();BeanUtils.copyProperties(channel,wmChannel);if(wmChannel.getIsDefault()==null){wmChannel.setIsDefault(true);}if(wmChannel.getOrd()==null){wmChannel.setOrd(1);}if(wmChannel.getCreatedTime()==null){wmChannel.setCreatedTime(new Date());}return ResponseResult.okResult(wmChannelService.save(wmChannel));}
5.1.4 测试
查看leadnews_wemedia数据库中wm_channel表
码农探花已经加入。
5.2 频道名称模糊分页查询
接口地址:/api/v1/channel/list
请求方式:POST
请求参数:
参数名称 | 参数说明 | in | 是否必须 | 数据类型 | schema |
---|---|---|---|---|---|
dto | dto | body | true | ChannelDto | ChannelDto |
name | 频道名称 | false | string | ||
page | 当前页 | true | integer(int32) | ||
size | 每页显示条数 | true | integer(int32) |
5.2.1 实体类ChannelDto
在heima-leadnews-model模块中创建com.heima.model.admin.dtos.ChannelDto类
@Data
public class ChannelDto {private String name;private Integer page;private Integer size;
}
5.2.3 完善自媒体服务中WmChannelController
@PostMapping("/list")
public ResponseResult findListWithPage(@RequestBody ChannelDto dto){return wmChannelService.findListWithPage(dto);
}
5.2.4 Service
接口:
ResponseResult findListWithPage(ChannelDto dto);
实现:
/*** 分页查询频道列表*/
@Override
public ResponseResult findListWithPage(ChannelDto dto) {// 1.参数检查if(dto == null){return ResponseResult.errorResult(400,"参数错误");}// 2 分页查询IPage pageCheck=new Page(dto.getPage(),dto.getSize());// 3 按照不同需求查询LambdaQueryWrapper<WmChannel> lambdaQueryWrapper = new LambdaQueryWrapper<>();//3.1 关键字模糊匹配if(StringUtils.isNotBlank(dto.getName())){lambdaQueryWrapper.like(WmChannel::getName,dto.getName());}//3.2 排序lambdaQueryWrapper.orderByDesc(WmChannel::getCreatedTime);pageCheck = page(pageCheck, lambdaQueryWrapper);//4. 返回结果ResponseResult responseResult = new PageResponseResult(dto.getPage(), dto.getSize(), (int) pageCheck.getTotal());responseResult.setData(pageCheck.getRecords());return responseResult;
}
5.2.5 测试
5.3 更新频道
接口地址:/api/v1/channel/update
请求方式:POST
请求参数:
参数名称 | 参数说明 | in | 是否必须 | 数据类型 | schema |
---|---|---|---|---|---|
adChannel | adChannel | body | true | AdChannel | AdChannel |
createdTime | false | string(date-time) | |||
description | false | string | |||
id | false | integer(int32) | |||
isDefault | false | boolean | |||
name | false | string | |||
ord | false | integer(int32) | |||
status | false | boolean |
5.3.1 完善自媒体服务中WmChannelController
@PostMapping("/update")
public ResponseResult update(@RequestBody AdChannel channel){return wmChannelService.updateChannel(channel);
}
5.3.2 Service
接口
ResponseResult updateChannel(AdChannel channel);
实现
@Override
public ResponseResult updateChannel(AdChannel channel) {// 1.参数检查if(channel == null){return ResponseResult.errorResult(400,"参数错误");}// 2.更新WmChannel wmChannel = new WmChannel();BeanUtils.copyProperties(channel,wmChannel);updateById(wmChannel);return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
}
5.3.3 测试
把探花改成烧烤
查看数据库
5.4 删除频道
接口地址:/api/v1/channel/del/{id}
请求方式:GET
请求参数:
参数名称 | 参数说明 | in | 是否必须 | 数据类型 | schema |
---|---|---|---|---|---|
id | id | path | true | integer(int32) |
5.4.1 完善自媒体服务中WmChannelController
/*** 删除频道* @param id* @return*/
@GetMapping("/del/{id}")
public ResponseResult del(@PathVariable("id") Integer id){return wmChannelService.deleteChannel(id);
}
5.4.2 Service
接口
ResponseResult deleteChannel(Integer id);
实现
@Override
public ResponseResult deleteChannel(Integer id) {// 1.参数检查if(id == null){return ResponseResult.errorResult(400,"参数错误");}// 2.删除removeById(id);return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
5.4.3 测试
把码农烧烤删了去,已经没有了。
6 敏感词管理
查看list请求http://localhost:8803/service_6001/wemedia/api/v1/sensitive/list
发现还是在wemedia下进行的。所以还是在自媒体微服务里进行管理。
6.1 查询列表
接口地址:/api/v1/sensitive/list
请求方式:POST
请求参数:
参数名称 | 参数说明 | in | 是否必须 | 数据类型 | schema |
---|---|---|---|---|---|
dto | dto | body | true | SensitiveDto | SensitiveDto |
name | false | string | |||
page | 当前页 | true | integer(int32) | ||
size | 每页显示条数 | true | integer(int32) |
6.1.1 实体类SensitiveDto
在heima-leadnews-model模块中创建com.heima.model.admin.dtos.SensitiveDto类
@Data
public class SensitiveDto {private String name;private Integer page;private Integer size;
}
6.1.2 WmSensitiveController
在heima-leadnews-wemedia中创建com.heima.wemedia.controller.v1.WmSensitiveController类
@RestController
@RequestMapping("/api/v1/sensitive")
public class WmSensitiveController {@Autowiredprivate WmSensitiveService wmSensitiveService;/*** 敏感词列表*/@PostMapping("/list")public ResponseResult list(@RequestBody SensitiveDto dto){return wmSensitiveService.list(dto);}}
6.1.3 Service
接口
public interface WmSensitiveService {public ResponseResult list(SensitiveDto dto);
}
实现
@Service
@Slf4j
@Transactional
public class WmSensitiveServiceImpl extends ServiceImpl<WmSensitiveMapper, WmSensitive> implements WmSensitiveService {@Overridepublic ResponseResult list(SensitiveDto dto) {// 1.参数检查if(dto == null){return ResponseResult.errorResult(400,"参数错误");}// 2 分页查询IPage pageCheck=new Page(dto.getPage(),dto.getSize());// 3 按照不同需求查询LambdaQueryWrapper<WmSensitive> lambdaQueryWrapper = new LambdaQueryWrapper<>();//3.1 关键字模糊匹配if(StringUtils.isNotBlank(dto.getName())){lambdaQueryWrapper.like(WmSensitive::getSensitives,dto.getName());}//3.2 排序lambdaQueryWrapper.orderByDesc(WmSensitive::getCreatedTime);pageCheck = page(pageCheck, lambdaQueryWrapper);//4. 返回结果ResponseResult responseResult = new PageResponseResult(dto.getPage(), dto.getSize(), (int) pageCheck.getTotal());responseResult.setData(pageCheck.getRecords());return responseResult;}
}
6.1.4 测试
成功
6.2 敏感词保存
接口地址:/api/v1/sensitive/save
请求方式:POST
请求参数:
参数名称 | 参数说明 | in | 是否必须 | 数据类型 | schema |
---|---|---|---|---|---|
adSensitive | adSensitive | body | true | AdSensitive | AdSensitive |
createdTime | false | string(date-time) | |||
id | false | integer(int32) | |||
sensitives | false | string |
6.2.1 实体类AdSensitive
在heima-leadnews-model中添加com.heima.model.admin.pojos.AdSensitive类
public class AdSensitive extends WmSensitive {
}
6.2.2 WmSensitiveController
/*** 敏感词新增*/
@PostMapping("/save")
public ResponseResult save(@RequestBody AdSensitive dto){return wmSensitiveService.save(dto);
}
6.2.3 Service
接口
ResponseResult save(AdSensitive dto);
实现
@Override
public ResponseResult save(AdSensitive dto) {if(dto == null){return ResponseResult.errorResult(400,"参数错误");}WmSensitive wmSensitive = new WmSensitive();BeanUtils.copyProperties(dto,wmSensitive);save(wmSensitive);return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
}
6.2.4 测试
加入敏感词探花
测试成功
6.3 更新敏感词
接口地址:/api/v1/sensitive/update
请求方式:POST
请求参数:
参数名称 | 参数说明 | in | 是否必须 | 数据类型 | schema |
---|---|---|---|---|---|
adSensitive | adSensitive | body | true | AdSensitive | AdSensitive |
createdTime | false | string(date-time) | |||
id | false | integer(int32) | |||
sensitives | false | string |
6.3.1 WmSensitiveController
/*** 敏感词修改*/
@PostMapping("/update")
public ResponseResult update(@RequestBody AdSensitive dto){return wmSensitiveService.update(dto);
}
6.3.2 Service
接口
ResponseResult update(AdSensitive dto);
实现
@Override
public ResponseResult update(AdSensitive dto) {if(dto == null){return ResponseResult.errorResult(400,"参数错误");}WmSensitive wmSensitive = new WmSensitive();BeanUtils.copyProperties(dto,wmSensitive);updateById(wmSensitive);return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
}
6.3.3 测试
把探花改成烧烤
6.4 删除敏感词
接口地址:/api/v1/sensitive/del/{id}
请求方式:DELETE
请求参数:
参数名称 | 参数说明 | in | 是否必须 | 数据类型 | schema |
---|---|---|---|---|---|
id | id | path | true | integer(int32) |
6.4.1 WmSensitiveController
/*** 敏感词删除*/
@DeleteMapping("/del/{id}")
public ResponseResult delete(@PathVariable("id") Integer id){return wmSensitiveService.delete(id);
}
6.4.2 Service
接口
ResponseResult delete(Integer id);
实现
@Override
public ResponseResult delete(Integer id) {if(id == null){return ResponseResult.errorResult(400,"参数错误");}removeById(id);return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
}
6.4.3 测试
把烧烤删了
7 用户审核
发送的请求url为http://localhost:8803/service_6001/user/api/v1/auth/list,说明需要用网关转发到user
7.0 修改leadnews-admin-gateway的nacos配置
spring:cloud:gateway:globalcors:add-to-simple-url-handler-mapping: truecorsConfigurations:'[/**]':allowedHeaders: "*"allowedOrigins: "*"allowedMethods:- GET- POST- DELETE- PUT- OPTIONroutes:# 管理端管理- id: adminuri: lb://leadnews-adminpredicates:- Path=/admin/**filters:- StripPrefix= 1# 自媒体微服务- id: leadnews-wemediauri: lb://leadnews-wemediapredicates:- Path=/wemedia/**filters:- StripPrefix= 1# 用户微服务- id: leadnews-useruri: lb://leadnews-userpredicates:- Path=/user/**filters:- StripPrefix= 1
7.1 查询列表
接口地址:/api/v1/auth/list
请求方式:POST
请求参数:
参数名称 | 参数说明 | in | 是否必须 | 数据类型 | schema |
---|---|---|---|---|---|
dto | dto | body | true | AuthDto | AuthDto |
id | false | integer(int32) | |||
msg | false | string | |||
page | 当前页 | true | integer(int32) | ||
size | 每页显示条数 | true | integer(int32) | ||
status | false | integer(int32) |
7.1.1 实体类AuthDto
在heima-leadnews-model中创建com.heima.model.admin.dtos.AuthDto实体类
@Data
public class AuthDto{private Integer id;private String msg;private Integer page;private Integer size;private Integer status;
}
7.1.2 Controller
在heima-leadnews-user中创建com.heima.user.controller.v1.ApUserVerifyController
@RestController
@RequestMapping("/api/v1/auth")
public class ApUserVerifyController {@Autowiredprivate ApUserRealnameService apUserRealnameService;/*** 查询列表*/@PostMapping("/list")public ResponseResult list(@RequestBody AuthDto dto) {return apUserRealnameService.findlist(dto);}}
7.1.3 Service
接口:
public interface ApUserRealnameService extends IService<ApUserRealname> {ResponseResult findlist(AuthDto dto);
}
实现:
@Service
@Transactional
@Slf4j
public class ApUserRealnameServiceImpl extends ServiceImpl<ApRealNamemapper, ApUserRealname> implements ApUserRealnameService {@Overridepublic ResponseResult findlist(AuthDto dto) {if(dto == null) {return ResponseResult.errorResult(400, "参数错误");}// 2 分页查询IPage pageCheck=new Page(dto.getPage(),dto.getSize());// 3 按照不同需求查询LambdaQueryWrapper<ApUserRealname> lambdaQueryWrapper = new LambdaQueryWrapper<>();//3.1 状态if(dto.getStatus()!=null){lambdaQueryWrapper.eq(ApUserRealname::getStatus, dto.getStatus());}//3.2 排序lambdaQueryWrapper.orderByDesc(ApUserRealname::getCreatedTime);pageCheck = page(pageCheck, lambdaQueryWrapper);//4. 返回结果ResponseResult responseResult = new PageResponseResult(dto.getPage(), dto.getSize(), (int) pageCheck.getTotal());responseResult.setData(pageCheck.getRecords());return responseResult;}
}
7.1.4 测试
7.2 审核失败
接口地址:/api/v1/auth/authFail
请求方式:POST
请求参数:
参数名称 | 参数说明 | in | 是否必须 | 数据类型 | schema |
---|---|---|---|---|---|
dto | dto | body | true | AuthDto | AuthDto |
id | false | integer(int32) | |||
msg | false | string | |||
page | 当前页 | true | integer(int32) | ||
size | 每页显示条数 | true | integer(int32) | ||
status | false | integer(int32) |
7.2.1 Controller
/*** 审核失败*/
@PostMapping("/authFail")
public ResponseResult authFail(@RequestBody AuthDto dto) {return apUserRealnameService.authFail(dto);
}
7.2.2 Service
接口:
ResponseResult authFail(AuthDto dto);
实现:
@Override
public ResponseResult authFail(AuthDto dto) {if(dto==null || dto.getId()==null){return ResponseResult.errorResult(400,"参数错误");}ApUserRealname apUserRealname = new ApUserRealname();BeanUtils.copyProperties(dto, apUserRealname);apUserRealname.setStatus((short) 2);if(StringUtils.isBlank(dto.getMsg())){apUserRealname.setReason("审核失败");}else{apUserRealname.setReason(dto.getMsg());}apUserRealname.setUpdatedTime(new Date());updateById(apUserRealname);return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
}
7.2.3 测试
3被驳回,驳回理由,黑马探花黑马烧烤
7.3 审核成功
接口地址:/api/v1/auth/authPass
请求方式:POST
请求参数:
参数名称 | 参数说明 | in | 是否必须 | 数据类型 | schema |
---|---|---|---|---|---|
dto | dto | body | true | AuthDto | AuthDto |
id | false | integer(int32) | |||
msg | false | string | |||
page | 当前页 | true | integer(int32) | ||
size | 每页显示条数 | true | integer(int32) | ||
status | false | integer(int32) |
7.3.1 Controller
在heima-leadnews-user中创建com.heima.user.controller.v1.ApUserVerifyController
/*** 审核通过*/
@PostMapping("/authPass")
public ResponseResult authPass(@RequestBody AuthDto dto) {return apUserRealnameService.authPass(dto);
}
7.3.2 Service
接口:
ResponseResult authPass(AuthDto dto);
实现:
@Override
public ResponseResult authPass(AuthDto dto) {if(dto==null || dto.getId()==null){return ResponseResult.errorResult(400,"参数错误");}ApUserRealname apUserRealname = new ApUserRealname();BeanUtils.copyProperties(dto, apUserRealname);apUserRealname.setStatus((short) 9);apUserRealname.setUpdatedTime(new Date());updateById(apUserRealname);return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
}
7.3.3 测试
1通过
8 自媒体文章人工审核
发送的请求url为http://localhost:8803/service_6001/wemedia/api/v1/news/list_vo
8.1 查询文章列表
接口地址:/api/v1/news/list_vo
请求方式:POST
请求参数:
参数名称 | 参数说明 | in | 是否必须 | 数据类型 | schema |
---|---|---|---|---|---|
dto | dto | body | true | NewsAuthDto | NewsAuthDto |
id | false | integer(int32) | |||
msg | false | string | |||
page | 当前页 | true | integer(int32) | ||
size | 每页显示条数 | true | integer(int32) | ||
status | false | integer(int32) | |||
title | false | string |
8.1.1 实体类NewsAuthDto
在heima-leadnews-model中创建com.heima.model.admin.dtos.NewsAuthDto实体类
@Data
public class NewsAuthDto {private Integer id;private String msg;private Integer page;private Integer size;private Integer status;private String title;
}
8.1.2 Controller
为com.heima.wemedia.controller.v1.WmNewsController添加方法
@PostMapping("/list_vo")
public ResponseResult listVo(@RequestBody NewsAuthDto dto){return wmNewsService.listVo(dto);
}
8.1.3 Service
接口:
ResponseResult listVo(NewsAuthDto dto);
实现:
@Override
public ResponseResult listVo(NewsAuthDto dto) {if(dto == null){return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);}// 2 分页查询IPage pageCheck=new Page(dto.getPage(),dto.getSize());// 3 按照不同需求查询LambdaQueryWrapper<WmNews> lambdaQueryWrapper = new LambdaQueryWrapper<>();//3.1 状态if(dto.getStatus()!=null){lambdaQueryWrapper.eq(WmNews::getStatus, dto.getStatus());}//3.2 排序lambdaQueryWrapper.orderByDesc(WmNews::getCreatedTime);pageCheck = page(pageCheck, lambdaQueryWrapper);//4. 返回结果ResponseResult responseResult = new PageResponseResult(dto.getPage(), dto.getSize(), (int) pageCheck.getTotal());responseResult.setData(pageCheck.getRecords());return responseResult;
}
8.2 查询文章详情
接口地址:/api/v1/news/one_vo/{id}
请求方式:GET
请求参数:
参数名称 | 参数说明 | in | 是否必须 | 数据类型 | schema |
---|---|---|---|---|---|
id | id | path | true | integer(int32) |
8.2.1 Controller
为com.heima.wemedia.controller.v1.WmNewsController添加方法
@RestController
@RequestMapping("/api/v1/auth")
public class ApUserVerifyController {@Autowiredprivate ApUserRealnameService apUserRealnameService;/*** 查询列表*/@PostMapping("/list")public ResponseResult list(@RequestBody AuthDto dto) {return apUserRealnameService.findlist(dto);}}
8.2.2 Service
接口:
public interface ApUserRealnameService extends IService<ApUserRealname> {ResponseResult findlist(AuthDto dto);
}
实现:
@Service
@Transactional
@Slf4j
public class ApUserRealnameServiceImpl extends ServiceImpl<ApRealNamemapper, ApUserRealname> implements ApUserRealnameService {@Overridepublic ResponseResult findlist(AuthDto dto) {if(dto == null) {return ResponseResult.errorResult(400, "参数错误");}// 2 分页查询IPage pageCheck=new Page(dto.getPage(),dto.getSize());// 3 按照不同需求查询LambdaQueryWrapper<ApUserRealname> lambdaQueryWrapper = new LambdaQueryWrapper<>();//3.1 状态if(dto.getStatus()!=null){lambdaQueryWrapper.eq(ApUserRealname::getStatus, dto.getStatus());}//3.2 排序lambdaQueryWrapper.orderByDesc(ApUserRealname::getCreatedTime);pageCheck = page(pageCheck, lambdaQueryWrapper);//4. 返回结果ResponseResult responseResult = new PageResponseResult(dto.getPage(), dto.getSize(), (int) pageCheck.getTotal());responseResult.setData(pageCheck.getRecords());return responseResult;}
}
8.3 审核失败
接口地址:/api/v1/news/auth_fail
请求方式:POST
请求参数:
参数名称 | 参数说明 | in | 是否必须 | 数据类型 | schema |
---|---|---|---|---|---|
dto | dto | body | true | NewsAuthDto | NewsAuthDto |
id | false | integer(int32) | |||
msg | false | string | |||
page | 当前页 | true | integer(int32) | ||
size | 每页显示条数 | true | integer(int32) | ||
status | false | integer(int32) | |||
title | false | string |
8.3.1 Controller
为com.heima.wemedia.controller.v1.WmNewsController添加方法
@PostMapping("/auth_fail")
public ResponseResult authFail(@RequestBody NewsAuthDto dto){return wmNewsService.authFailNews(dto);
}
8.3.2 Service
接口:
ResponseResult authFailNews(NewsAuthDto dto);
实现:
@Override
public ResponseResult authFailNews(NewsAuthDto dto) {if(dto==null || dto.getId()==null){return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);}WmNews wmNews = getById(dto.getId());if(wmNews == null){return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST,"文章不存在");}wmNews.setStatus(WmNews.Status.FAIL.getCode());wmNews.setReason(dto.getMsg());updateById(wmNews);return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
}
8.4 审核成功
接口地址:/api/v1/news/auth_pass
请求方式:POST
请求参数:
参数名称 | 参数说明 | in | 是否必须 | 数据类型 | schema |
---|---|---|---|---|---|
dto | dto | body | true | NewsAuthDto | NewsAuthDto |
id | false | integer(int32) | |||
msg | false | string | |||
page | 当前页 | true | integer(int32) | ||
size | 每页显示条数 | true | integer(int32) | ||
status | false | integer(int32) | |||
title | false | string |
8.4.1 Controller
为com.heima.wemedia.controller.v1.WmNewsController添加方法
@PostMapping("/auth_pass")
public ResponseResult authPass(@RequestBody NewsAuthDto dto){return wmNewsService.authPassNews(dto);
}
8.4.2 Service
接口:
ResponseResult authPassNews(NewsAuthDto dto);
实现:
@Autowired
private WmChannelMapper wmChannelMapper;
@Autowired
private WmUserMapper wmUserMapper;
@Autowired
private RabbitTemplate rabbitTemplate;
@Override
public ResponseResult authPassNews(NewsAuthDto dto) {if(dto==null || dto.getId()==null){return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);}WmNews wmNews = getById(dto.getId());if(wmNews == null){return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST,"文章不存在");}if(wmNews.getStatus().equals(WmNews.Status.PUBLISHED.getCode())){return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID,"无需审核");}wmNews.setStatus(WmNews.Status.ADMIN_SUCCESS.getCode());wmNews.setReason(dto.getMsg());//人工审核成功保存app端的相关文章数据ArticleDto articleDto=new ArticleDto();BeanUtils.copyProperties(wmNews,articleDto);//布局articleDto.setLayout(wmNews.getType());//频道articleDto.setChannelId(wmNews.getChannelId());//频道名称WmChannel wmChannel = wmChannelMapper.selectById(wmNews.getChannelId());if(wmChannel!=null){articleDto.setChannelName(wmChannel.getName());}//作者articleDto.setAuthorId(Long.valueOf(wmNews.getUserId()));//作者名称WmUser wmUser= wmUserMapper.selectById(wmNews.getUserId());if(wmUser!=null){articleDto.setAuthorName(wmUser.getName());}//设置文章idif(wmNews.getArticleId()!=null){articleDto.setId(wmNews.getArticleId());}articleDto.setCreatedTime(new Date());//2.rabbitmq异步处理Map<String,Object> map=new HashMap<>();map.put("dto",articleDto);map.put("wmNewsId",dto.getId());rabbitTemplate.convertAndSend("article.queue", map);return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
}
8.4.3 修改自动审核逻辑模拟人工审核
创建完自媒体文章,放入task队列等待审核。修改com.heima.wemedia.service.impl.WmNewAutoScanServiceImpl#autoScanMediaNews的逻辑模拟人工审核。
//模拟人工审核
wmNews.setStatus((short) 3);
if(wmNews.getStatus().equals(WmNews.Status.ADMIN_AUTH.getCode())){wmNews.setReason("需要人工审核");wmNewsMapper.updateById(wmNews);
}
这时候该条wmNews就无法审核上架,必须前端进行审核通过点击后才行。前台点击后调用authPassNews人工审核成功发送异步调用到mq进行保存。
8.5 综合测试
启动mongodb,es,kafak,zookeeper,redis,mq,minio,nacos
启动所有网关及微服务
先在自媒体端添加一篇文章
因为8.4.3设置状态为人工审核,因此没进行自动审核。
查看数据库
打开管理员网站
查看文章详情
驳回就写个理由,直接驳回就好。没什么测试的。
通过则需要加入mq通知文章微服务进行添加。需要测试。
显示已发布。
自媒体端已显示成功。
查看用户端。
用户端也有显示。说明添加app端文章成功。