【黑马头条】-day08平台管理-用户敏感词管理-自媒体文章人工审核


文章目录

  • 平台管理
  • 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
adChanneladChannelbodytrueAdChannelAdChannel
  createdTimefalsestring(date-time)
  descriptionfalsestring
  idfalseinteger(int32)
  isDefaultfalseboolean
  namefalsestring
  ordfalseinteger(int32)
  statusfalseboolean

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
dtodtobodytrueChannelDtoChannelDto
  name频道名称falsestring
  page当前页trueinteger(int32)
  size每页显示条数trueinteger(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
adChanneladChannelbodytrueAdChannelAdChannel
  createdTimefalsestring(date-time)
  descriptionfalsestring
  idfalseinteger(int32)
  isDefaultfalseboolean
  namefalsestring
  ordfalseinteger(int32)
  statusfalseboolean

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
ididpathtrueinteger(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
dtodtobodytrueSensitiveDtoSensitiveDto
  namefalsestring
  page当前页trueinteger(int32)
  size每页显示条数trueinteger(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
adSensitiveadSensitivebodytrueAdSensitiveAdSensitive
  createdTimefalsestring(date-time)
  idfalseinteger(int32)
  sensitivesfalsestring

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
adSensitiveadSensitivebodytrueAdSensitiveAdSensitive
  createdTimefalsestring(date-time)
  idfalseinteger(int32)
  sensitivesfalsestring

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
ididpathtrueinteger(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
dtodtobodytrueAuthDtoAuthDto
  idfalseinteger(int32)
  msgfalsestring
  page当前页trueinteger(int32)
  size每页显示条数trueinteger(int32)
  statusfalseinteger(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
dtodtobodytrueAuthDtoAuthDto
  idfalseinteger(int32)
  msgfalsestring
  page当前页trueinteger(int32)
  size每页显示条数trueinteger(int32)
  statusfalseinteger(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
dtodtobodytrueAuthDtoAuthDto
  idfalseinteger(int32)
  msgfalsestring
  page当前页trueinteger(int32)
  size每页显示条数trueinteger(int32)
  statusfalseinteger(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
dtodtobodytrueNewsAuthDtoNewsAuthDto
  idfalseinteger(int32)
  msgfalsestring
  page当前页trueinteger(int32)
  size每页显示条数trueinteger(int32)
  statusfalseinteger(int32)
  titlefalsestring

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
ididpathtrueinteger(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
dtodtobodytrueNewsAuthDtoNewsAuthDto
  idfalseinteger(int32)
  msgfalsestring
  page当前页trueinteger(int32)
  size每页显示条数trueinteger(int32)
  statusfalseinteger(int32)
  titlefalsestring

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
dtodtobodytrueNewsAuthDtoNewsAuthDto
  idfalseinteger(int32)
  msgfalsestring
  page当前页trueinteger(int32)
  size每页显示条数trueinteger(int32)
  statusfalseinteger(int32)
  titlefalsestring

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端文章成功。

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

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

相关文章

C++从入门到精通——类的6个默认成员函数之赋值运算符重载

赋值运算符重载 前言一、运算符重载定义实例注意要点 二、赋值运算符重载赋值运算符重载格式赋值运算符重载要点重载要点传值返回和传址返回要点 三、前置和后置重载 前言 类的6个默认成员函数&#xff1a;如果一个类中什么成员都没有&#xff0c;简称为空类。 空类中真的什么…

Vue3 笔记

vue3笔记 1. Vue3简介1.1. 【性能的提升】1.2.【 源码的升级】1.3. 【拥抱TypeScript】1.4. 【新的特性】 2. 创建Vue3工程2.1. 【基于 vue-cli 创建】2.2. 【基于 vite 创建】(推荐)2.3. 【一个简单的效果】 3. Vue3核心语法3.1. 【OptionsAPI 与 CompositionAPI】Options API…

记第一次踩坑Gradle

今天有个项目只能使用Gradle编译&#xff0c;没办法了&#xff0c;尝试吧。 先去下载了最新版本的Gradle&#xff0c;然后配置好了环境变量&#xff0c;可以在命令行使用gradle命令了。 然后打开项目开始操作一番&#xff0c;但是上来就傻眼了。 我白下载了&#xff0c;又重新下…

30元腾讯云服务器搭建幻兽帕鲁Palworld多人联机游戏,畅玩

幻兽帕鲁太火了&#xff0c;官方palworld服务器不稳定&#xff1f;不如自建服务器&#xff0c;基于腾讯云幻兽帕鲁服务器成本32元全自动部署幻兽帕鲁服务器&#xff0c;超简单有手就行&#xff0c;全程自动化一键部署10秒钟即可搞定&#xff0c;无需玩家手动部署幻兽帕鲁游戏程…

Hive 解决数据倾斜方法

数据倾斜问题&#xff0c; 通常是指参与计算的数据分布不均&#xff0c; 即某个 key 或者某些 key 的数据量远超其他 key&#xff0c; 导致在 shuffle 阶段&#xff0c; 大量相同 key 的数据被发往同一个 Reduce&#xff0c; 进而导致该 Reduce 所需的时间远超其他 Reduce&…

Elasticsearch可视化工具:kibana + elasticsearch-head

kibana 下载 地址&#xff1a;https://www.elastic.co/cn/downloads/kibana 下载别的版本&#xff1a;https://www.elastic.co/cn/downloads/past-releases#kibana 将Kibana安装包解压缩 进入config目录&#xff0c;在kibana.yml中添加es服务器地址。&#xff08;如果之前没…

【Unity】ScriptableObject 在游戏中的使用实例

ScriptableObject 在游戏中的使用实例 ScriptableObject 使用指南Unity 存储游戏数据的几种方法Unity ScriptableObject实例创建一个物品管理的ScriptableObject创建一个管理所有 ScriptableObject 的数据库&#xff08;ItemDBSO&#xff09; ScriptableObject 使用指南 Scrip…

UOS系统-mips架构---Java环境安装

平时都是在windows系统上安装的java环境&#xff0c;今天需要在uos系统安装java1.8的环境&#xff0c;记录一下安装过程。 &#xff08;以下均在root权限下运行&#xff09; 一、查找java1.8 jdk版本 apt search openjdkopenjdk-8-jdk/未知,未知 1.8.0.212-2deepin mips64el O…

InnoDB架构:内存篇

InnoDB架构&#xff1a;内存篇 InnoDB是MySQL数据库中默认的存储引擎&#xff0c;它为数据库提供了事务安全型&#xff08;ACID兼容&#xff09;、行级锁定和外键支持等功能。InnoDB的架构设计优化了对于读取密集和写入密集型应用的性能表现&#xff0c;是一个高度优化的存储系…

llama_factory微调QWen1.5

GitHub - hiyouga/LLaMA-Factory: Unify Efficient Fine-Tuning of 100 LLMsUnify Efficient Fine-Tuning of 100 LLMs. Contribute to hiyouga/LLaMA-Factory development by creating an account on GitHub.https://github.com/hiyouga/LLaMA-FactoryQwen1.5 介绍 | QwenGITH…

设计模式代码实战-装饰者模式

1、问题描述 小明喜欢品尝不同口味的咖啡&#xff0c;他发现每种咖啡都可以加入不同的调料&#xff0c;比如牛奶、糖和巧克力。他决定使用装饰者模式制作自己喜欢的咖啡。 请设计一个简单的咖啡制作系统&#xff0c;使用装饰者模式为咖啡添加不同的调料。系统支持两种咖啡类型…

Ollama、FastGPT大模型RAG知识库结合使用案例

参考: https://ollama.com/download/linux https://doc.fastai.site/docs/intro/ https://blog.csdn.net/m0_71142057/article/details/136738997 https://doc.fastgpt.run/docs/development/custom-models/m3e/ https://concise-eater-d47.notion.site/Ollama-Fastgpt-b170…

优惠券布局的最终方案------css属性mask

先贴图&#xff1a; 以上这些都是通过mask去实现出来&#xff1a; <!DOCTYPE html><html lang"zh-CN"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"&g…

华为配置通过流策略实现流量统计

配置通过流策略实现流量统计示例 组网图形 图1 配置流策略实现流量统计组网图 设备 接口 接口所属VLAN 对应的三层接口 IP地址 SwitchA GigabitEthernet1/0/1 VLAN 10 - - GigabitEthernet1/0/2 VLAN 20 - - GigabitEthernet1/0/3 VLAN 10、VLAN 20 - - S…

本地搭建属于你自己的AI搜索引擎 支持多家AI模型

FreeAskInternet 是一个完全免费、私有且本地运行的搜索聚合器&#xff0c;并使用 MULTI LLM 生成答案&#xff0c;无需 GPU。用户可以提出问题&#xff0c;系统将进行多引擎搜索&#xff0c;并将搜索结果合并到LLM中&#xff0c;并根据搜索结果生成答案。全部免费使用。 项目…

全排列(函数法)

全排列 1.next_permutation( ) 和 prev_permutation( ) 函数 1&#xff09;next_permutation( ) 函数 next_permutation( ) 函数用于判断当前序列是否存在按照字典序变得更大一级的下一个序列并变为它&#xff1b;此函数会按照字典序进行重新排列&#xff0c;如果存在下一个序…

数字孪生助力平交道口拆除,推动可持续交通计划

Bentley 的数字孪生技术助力优化材料的使用&#xff0c;节约时间 15%&#xff0c;降低碳排放量 30% 改变公共交通和社区的连通性 维多利亚州的平交道口拆除项目目标是到 2030 年拆除墨尔本 110 个平交道口&#xff0c;这是该州历史上最重要的铁路基础设施项目之一。该项目不仅…

面试算法-173-二叉树的直径

题目 给你一棵二叉树的根节点&#xff0c;返回该树的 直径 。 二叉树的 直径 是指树中任意两个节点之间最长路径的 长度 。这条路径可能经过也可能不经过根节点 root 。 两节点之间路径的 长度 由它们之间边数表示。 示例 1&#xff1a; 输入&#xff1a;root [1,2,3,4,…

什么是UX设计?

在这个先进的世界中&#xff0c;大城市都被称之为科技之都&#xff0c;在那里&#xff0c;你会经常发现人们在谈论各种应用程序的设计。如果你对应用程序设计有浓烈的兴趣&#xff0c;那你应该去了解一下它的两个基本方面&#xff0c;也就是 UX 设计和 UI 设计。UX 设计旨在处理…

《中医病证分类与代码》-中医疾病分类数据库

《中医病症分类与代码》由国家中医药管理局2020年底修订&#xff0c;目的是为中医疾病及证候的分类提供统一的规范。规定2021年起&#xff0c;各中医机构的临床科室及基层中医药的医师都应按照最新修订的《中医病症分类与代码》规范来填报病案及病历。 中医病证分类与代码数据库…