文章目录
平台管理
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; # 记录真实发出请求的客户端IP
proxy_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-admin
cloud:
nacos:
discovery:
server-addr: 192.168.204.129:8848
config:
server-addr: 192.168.204.129:8848
file-extension: yml
2.7 在nacos中配置数据库等
关于数据库的等等都需要在Nacos的配置中心进行配置
spring:
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/leadnews_admin?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC&useSSL=false
username: root
password: 123sjbsjb
# 设置Mapper接口所对应的XML文件位置,如果你在Mapper接口中有自定义方法,需要进行该配置
mybatis-plus:
mapper-locations: classpath*:mapper/*.xml
# 设置别名包扫描路径,通过该属性可以给包中的类注册别名
type-aliases-package: com.heima.model.admin.pojos
minio:
accessKey: minio
secretKey: minio123
bucket: leadnews
endpoint: http://192.168.204.129:9000
readPath: 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 {
@Autowired
private 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 {
@Override
public 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 没问题的话,返回数据,生成jwt
String 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;
// 加密KEY
private static final String TOKEN_ENCRY_KEY = "MDk4ZjZiY2Q0NjIxZDM3M2NhZGU0ZTgzMjYyN2I0ZjY";
// 最小刷新间隔(S)
private static final int REFRESH_TIME = 300;
// 生产ID
public 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());
// 需要自动刷新TOKEN
if((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 {
@Override
public 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 解析token
try{
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
*/
@Override
public 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-gateway
cloud:
nacos:
discovery:
server-addr: 192.168.204.129:8848
config:
server-addr: 192.168.204.129:8848
file-extension: yml
4.5 在nacos中配置
新建nacos配置,配置拦截路径及转发路径
spring:
cloud:
gateway:
globalcors:
add-to-simple-url-handler-mapping: true
corsConfigurations:
'[/**]':
allowedHeaders: "*"
allowedOrigins: "*"
allowedMethods:
- GET
- POST
- DELETE
- PUT
- OPTION
routes:
# 平台管理
- id: admin
uri: lb://leadnews-admin
predicates:
- 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: true
corsConfigurations:
'[/**]':
allowedHeaders: "*"
allowedOrigins: "*"
allowedMethods:
- GET
- POST
- DELETE
- PUT
- OPTION
routes:
# 管理端管理
- id: admin
uri: lb://leadnews-admin
predicates:
- Path=/admin/**
filters:
- StripPrefix= 1
# 自媒体微服务
- id: leadnews-wemedia
uri: lb://leadnews-wemedia
predicates:
- 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 {
@Autowired
private 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 {
@Override
public 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: true
corsConfigurations:
'[/**]':
allowedHeaders: "*"
allowedOrigins: "*"
allowedMethods:
- GET
- POST
- DELETE
- PUT
- OPTION
routes:
# 管理端管理
- id: admin
uri: lb://leadnews-admin
predicates:
- Path=/admin/**
filters:
- StripPrefix= 1
# 自媒体微服务
- id: leadnews-wemedia
uri: lb://leadnews-wemedia
predicates:
- Path=/wemedia/**
filters:
- StripPrefix= 1
# 用户微服务
- id: leadnews-user
uri: lb://leadnews-user
predicates:
- 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 {
@Autowired
private 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 {
@Override
public 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添加方法
@GetMapping("/one/{id}")
public ResponseResult findWmNewsById(@PathVariable("id") Integer id){
return wmNewsService.findWmNewsById(id);
8.2.2 Service
接口:
@Override
public ResponseResult findWmNewsById(Integer id) {
// 1.参数检查
if(id == null){
return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID,"文章id不能为空");
}
// 2.查询文章
WmNews wmNews = getById(id);
if(wmNews == null){
return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST,"文章不存在");
}
// 3.返回结果
return ResponseResult.okResult(wmNews);
}
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());
}
//设置文章id
if(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端文章成功。