JavaWeb_LeadNews_Day8-后台管理系统实战

登录和网关

登录

需求

  • 用户根据用户名和密码登录
  • 密码需要手动加盐验证
  • 需要返回用户的token和用户信息
@Service
public class AdminUserServiceImpl extends ServiceImpl<AdminUserMapper, AdUser> implements AdminUserService {

    /**
     * 后台系统登录
     * @param dto
     * @return
     */
    @Override
    public ResponseResult login(AdUserDto dto) {
        // 1. 检验参数
        if(StringUtils.isBlank(dto.getName()) || StringUtils.isBlank(dto.getPassword())){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }

        // 2. 查询用户是否存在
        LambdaQueryWrapper<AdUser> query = new LambdaQueryWrapper<>();
        query.eq(AdUser::getName, dto.getName());
        AdUser adUser = getOne(query);
        if(adUser == null){
            return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST);
        }

        // 3. 比对密码, 手动加盐验证
        String password = dto.getPassword();
        String salt = adUser.getSalt();
        password = DigestUtils.md5DigestAsHex((password+salt).getBytes());
        if(password.equals(adUser.getPassword())){
            // 4. 返回数据, token和用户信息
            String token = AppJwtUtil.getToken(adUser.getId().longValue());
            Map<String, Object> map = new HashMap<>();
            map.put("token", token);
            adUser.setPassword("");
            adUser.setSalt("");
            map.put("user", adUser);
            return ResponseResult.okResult(map);
        }else{
            return ResponseResult.errorResult(AppHttpCodeEnum.LOGIN_PASSWORD_ERROR);
        }
    }
}

配置

  • bootstrap.yml
    server:
        port: 6011
    spring:
        application:
            name: leadnews-admin
        cloud:
            nacos:
            discovery:
                server-addr: 127.0.0.1:8848
                namespace: fc3009fa-ac38-4d3c-a4ea-94b8985a27e6
            config:
                server-addr: 127.0.0.1:8848
                namespace: fc3009fa-ac38-4d3c-a4ea-94b8985a27e6
                file-extension: yml
    
  • 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&allowPublicKeyRetrieval=true
            username: root
            password: 1234
    # 设置Mapper接口所对应的XML文件位置,如果你在Mapper接口中有自定义方法,需要进行该配置
    mybatis-plus:
        mapper-locations: classpath*:mapper/*.xml
        # 设置别名包扫描路径,通过该属性可以给包中的类注册别名
        type-aliases-package: com.heima.model.admin.pojos
    

网关

@Component
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是否有效
        try {
            Claims claimsBody = AppJwtUtil.getClaimsBody(token);
            //是否是过期
            int result = AppJwtUtil.verifyToken(claimsBody);
            if(result == 1 || result  == 2){
                response.setStatusCode(HttpStatus.UNAUTHORIZED);
                return response.setComplete();
            }

            // 获取用户信息
            String userId = claimsBody.get("id").toString();
            // 存储在header中
            ServerHttpRequest serverHttpRequest = request.mutate().headers(httpHeaders -> {
                httpHeaders.add("userId", userId);
            }).build();
            // 重置请求
            exchange.mutate().request(serverHttpRequest);
        } catch (Exception e) {
            e.printStackTrace();
            response.setStatusCode(HttpStatus.UNAUTHORIZED);
            return response.setComplete();
        }

        //6.放行
        return chain.filter(exchange);
    }

    /**
     * 优先级设置  值越小  优先级越高
     * @return
     */
    @Override
    public int getOrder() {
        return 0;
    }
}

配置

  • bootstrap.yml
    server:
        port: 6001
    spring:
        application:
            name: leadnews-admin-gateway
        cloud:
            nacos:
            discovery:
                server-addr: 127.0.0.1:8848
                namespace: fc3009fa-ac38-4d3c-a4ea-94b8985a27e6
            config:
                server-addr: 127.0.0.1:8848
                namespace: fc3009fa-ac38-4d3c-a4ea-94b8985a27e6
                file-extension: yml
    
  • nacos
    spring:
      cloud:
        gateway:
          globalcors:
            add-to-simple-url-handler-mapping: true
            corsConfigurations:
              '[/**]':
                allowedHeaders: "*"
                allowedOrigins: "*"
                allowedMethods:
                  - GET
                  - POST
                  - DELETE
                  - PUT
                  - OPTION
          routes:
            # 登录服务
            - id: login
              uri: lb://leadnews-admin
              predicates:
                - Path=/admin/**
              filters:
                - StripPrefix= 1
            # 频道服务
            - id: channel
              uri: lb://leadnews-wemedia
              predicates:
                - Path=/wemedia/**
              filters:
                - StripPrefix= 1
    

敏感词

新增

需求

  • 弹出的输入框,输入敏感词可直接保存
  • 已存在的敏感词则不能保存
public ResponseResult saveSensitive(WmSensitive wmSensitive) {
    // 1. 检查参数
    if(StringUtils.isBlank(wmSensitive.getSensitives())){
        return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID, "敏感词不能为空");
    }

    // 2. 判断敏感词名称是否重复
    LambdaQueryWrapper<WmSensitive> query = new LambdaQueryWrapper<>();
    query.eq(WmSensitive::getSensitives, wmSensitive.getSensitives());
    query.last("limit 1");
    WmSensitive sensitive = getOne(query);
    if(sensitive != null){
        return ResponseResult.errorResult(AppHttpCodeEnum.DATA_EXIST);
    }

    // 3. 新增敏感词
    wmSensitive.setCreatedTime(new Date());
    save(wmSensitive);
    return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
}

查询列表

需求

  • 查询需要按照创建时间倒序查询
  • 按照敏感词名称模糊查询
  • 分页查询
public ResponseResult findList(SensitiveDto dto) {
    // 1. 检查参数
    dto.checkParam();

    // 2. 分页查询
    IPage page = new Page(dto.getPage(), dto.getSize());
    LambdaQueryWrapper<WmSensitive> query = new LambdaQueryWrapper<>();
    // 2.1 按照频道名称模糊查询
    query.like(dto.getName()!=null, WmSensitive::getSensitives, dto.getName());
    // 2.2 按照创建时间倒序查询
    query.orderByDesc(WmSensitive::getCreatedTime);
    // 2.3 查询结果
    page(page, query);

    // 3. 返回结果
    PageResponseResult result = new PageResponseResult(dto.getPage(), dto.getSize(), (int) page.getTotal());
    result.setData(page.getRecords());
    return result;
}

修改

需求

  • 直接修改
public ResponseResult updateSensitive(WmSensitive wmSensitive) {
    // 1. 检查参数
    if(StringUtils.isBlank(wmSensitive.getSensitives())){
        return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
    }

    // 2. 修改敏感词
    updateById(wmSensitive);
    return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
}

删除

需求

  • 直接删除即可
public ResponseResult delSensitive(Integer id) {
    // 1. 检查参数
    if(id == null){
        return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
    }
    // 2. 根据id查询敏感词
    WmSensitive wmSensitive = getById(id);
    if(wmSensitive == null){
        return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST);
    }

    // 3. 删除敏感词
    removeById(id);
    return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
}

频道管理

新增

需求

  • 前台输入内容进行频道的保存
  • 频道名称不能重复
public ResponseResult saveChannel(WmChannel wmChannel) {
    // 1. 检查参数
    // 1.1 频道名称和描述不能为空
    if(StringUtils.isBlank(wmChannel.getName()) || StringUtils.isBlank(wmChannel.getDescription())){
        return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID, "名称和描述不能为空");
    }
    // 1.2 频道排序不能为空, 且范围为[0, 255]
    if(wmChannel.getOrd() == null || wmChannel.getOrd() < 0 || wmChannel.getOrd() > 255){
        return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID, "排序不能为空, 且范围为[0, 255]");
    }

    // 2. 判断频道名称是否重复
    LambdaQueryWrapper<WmChannel> query = new LambdaQueryWrapper<>();
    query.eq(WmChannel::getName, wmChannel.getName());
    query.last("limit 1");
    WmChannel channel = getOne(query);
    if(channel != null){
        return ResponseResult.errorResult(AppHttpCodeEnum.DATA_EXIST);
    }

    // 3. 保存频道
    wmChannel.setIsDefault(true);
    wmChannel.setCreatedTime(new Date());
    save(wmChannel);

    return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
}

查询列表

需求

  • 查询需要按照创建时间倒序查询
  • 按照频道名称模糊查询
  • 可以按照状态进行精确查找(1: 启用true, 0: 禁用false) 前端没传这个数据, 无法实现
  • 分页查询
public ResponseResult findList(ChannelDto dto) {
    // 1. 检查参数
    dto.checkParam();

    // 2. 分页查询
    IPage page = new Page(dto.getPage(), dto.getSize());
    LambdaQueryWrapper<WmChannel> query = new LambdaQueryWrapper<>();
    // 2.1 按照频道名称模糊查询
    query.like(dto.getName()!=null, WmChannel::getName, dto.getName());
    // 2.2 按照创建时间倒序查询
    query.orderByDesc(WmChannel::getCreatedTime);
    // 2.3 查询结果
    page(page, query);

    // 3. 返回结果
    PageResponseResult result = new PageResponseResult(dto.getPage(), dto.getSize(), (int) page.getTotal());
    result.setData(page.getRecords());
    return result;
}

修改

需求

  • 点击编辑后可以修改频道
  • 如果频道被引用则不能禁用
public ResponseResult updateChannel(WmChannel wmChannel) {
    // 1. 检查参数
    // 1.1 名称不能为空
    if(wmChannel.getName()!=null && StringUtils.isBlank(wmChannel.getName())){
        return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID, "名称不能为空");
    }
    // 1.2 描述不能为空
    if(wmChannel.getDescription()!=null && StringUtils.isBlank(wmChannel.getDescription())){
        return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID, "描述不能为空");
    }
    // 1.3 排序不能为空, 且范围为[0, 255]
    if(wmChannel.getOrd()!=null){
        if(wmChannel.getOrd() < 0 || wmChannel.getOrd() > 255){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID, "排序范围为[0, 255]");
        }
    }

    // 2. 如果频道被引用则不能禁用
    if(wmChannel.getStatus().equals(false)){
        // 2.1 查询频道是否被文章引用
        if (isRefer(wmChannel.getId())){
            return ResponseResult.errorResult(AppHttpCodeEnum.SERVER_ERROR, "没有文章引用的频道才可以禁用");
        }
    }

    updateById(wmChannel);

    return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
}

删除

需求

  • 只有禁用的频道可以删除
  • 频道被文章引用也不能删除
public ResponseResult delChannel(Integer id) {
    // 1. 检查参数
    if(id == null){
        return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
    }

    // 2. 根据id查询频道
    // 2.1 查询频道的状态
    WmChannel wmChannel = getById(id);
    if(wmChannel.getStatus().equals(1)){
        // 启用
        return ResponseResult.errorResult(AppHttpCodeEnum.SERVER_ERROR, "禁用的频道才可以删除");
    }

    // 2.2 查询频道是否被文章引用
    LambdaQueryWrapper<WmNews> query = new LambdaQueryWrapper<>();
    query.eq(WmNews::getChannelId, id);
    query.last("limit 1");
    WmNews wmNews = wmNewsMapper.selectOne(query);
    if(wmNews != null){
        // 有文章引用
        return ResponseResult.errorResult(AppHttpCodeEnum.SERVER_ERROR, "没有文章引用的频道才可以删除");
    }

    // 3. 删除频道
    removeById(id);
    return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
}

用户审核

查询列表

需求

  • 可根据审核状态条件查询
  • 需要分页查询
public ResponseResult findList(AdminAuthDto dto) {
    // 1. 检查参数
    dto.checkParam();

    // 2. 根据审核状态条件分页查询
    IPage page = new Page(dto.getPage(), dto.getSize());
    LambdaQueryWrapper<ApUserRealname> query = new LambdaQueryWrapper<>();
    // 2.1 根据审核状态条件查询
    query.like(dto.getStatus()!=null, ApUserRealname::getStatus, dto.getStatus());
    // 2.2 按照创建时间倒序查询
    query.orderByDesc(ApUserRealname::getCreatedTime);
    // 2.3 查询结果
    page(page, query);

    // 3. 返回结果
    PageResponseResult result = new PageResponseResult(dto.getPage(), dto.getSize(), (int) page.getTotal());
    result.setData(page.getRecords());
    return result;
}

审核成功

审核成功

public ResponseResult authPass(AdminAuthDto dto) {
    ApUserRealname apUserRealname = new ApUserRealname();
    apUserRealname.setId(dto.getId());
    apUserRealname.setStatus((short) 9);
    apUserRealname.setUpdatedTime(new Date());
    updateById(apUserRealname);
    return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
}

新增自媒体用户

  • feign
    @RestController
    public class WemediaClient implements IWemediaClient {
    
        @Autowired
        private WmUserService wmUserService;
    
        @PostMapping("/api/v1/user/save")
        @Override
        public ResponseResult saveUser(@RequestBody WmUserDto dto) {
            return wmUserService.saveUser(dto);
        }
    }
    
  • service
    public ResponseResult saveUser(WmUserDto dto) {
        WmUser wmUser = new WmUser();
        BeanUtils.copyProperties(dto, wmUser);
        wmUser.setCreatedTime(new Date());
        wmUser.setStatus(1);
        save(wmUser);
        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }
    

审核失败

public ResponseResult authFail(AdminAuthDto dto) {
    ApUserRealname apUserRealname = new ApUserRealname();
    apUserRealname.setId(dto.getId());
    apUserRealname.setStatus((short) 2);
    apUserRealname.setReason(dto.getMsg());
    apUserRealname.setUpdatedTime(new Date());
    updateById(apUserRealname);
    return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
}

自媒体文章人工审核

查询文章列表

需求

  • 分页查询自媒体文章
  • 可以按照标题模糊查询
  • 可以按照审核状态进行精确检索
  • 文章查询按照创建时间倒序查询
  • 注意:需要展示作者名称
public ResponseResult listVo(AdminNewsAuthDto dto) {
    // 1. 检验参数
    dto.checkParam();

    // 2. 分页查询文章
    IPage page = new Page(dto.getPage(), dto.getSize());
    LambdaQueryWrapper<WmNews> query = new LambdaQueryWrapper<>();
    // 2.1 按照标题模糊查询
    query.like(!StringUtils.isBlank(dto.getTitle()), WmNews::getTitle, dto.getTitle());
    // 2.2 按照审核状态查询
    query.eq(dto.getStatus()!=null, WmNews::getStatus, dto.getStatus());
    // 2.3 按照创建时间倒序查询
    query.orderByDesc(WmNews::getCreatedTime);
    // 2.4 查询结果
    page(page, query);

    List<WmNews> records = page.getRecords();
    List<AdminNewsDto> collect = records.stream().map((item) -> {

        AdminNewsDto adminNewsDto = new AdminNewsDto();
        BeanUtils.copyProperties(item, adminNewsDto);

        // 作者id
        Integer userId = item.getUserId();
        // 作者名字
        String authorName = wmUserMapper.selectById(userId).getName();

        // 设置名字
        adminNewsDto.setAuthorName(authorName);
        return adminNewsDto;
    }).collect(Collectors.toList());

    // 3. 返回结果
    PageResponseResult result = new PageResponseResult(dto.getPage(), dto.getSize(), (int) page.getTotal());
    result.setData(collect);
    return result;
}

查看文章详情

需求

  • 可以查看文章详细内容
  • 注意:需要展示作者名称
public ResponseResult adminGetNewsDetail(Integer id) {
    // 1. 检验参数
    if(id == null){
        return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
    }
    // 2. 获取文章对象
    WmNews news = getById(id);
    if(news == null){
        return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST, "文章不存在");
    }

    // 3. 设置作者名称
    AdminNewsDto adminNewsDto = new AdminNewsDto();
    BeanUtils.copyProperties(news, adminNewsDto);
    // 3.1 获取作者名称
    String authorName = wmUserMapper.selectById(news.getUserId()).getName();
    adminNewsDto.setAuthorName(authorName);

    // 4. 返回结果
    return ResponseResult.okResult(adminNewsDto);
}

文章审核失败

需求

  • 拒绝以后需要给出原因,并修改文章的状态为2
public ResponseResult authNewsFail(AdminNewsAuthDto dto) {
    if(dto.getMsg() == null){
        return ResponseResult.errorResult(AppHttpCodeEnum.SERVER_ERROR, "需要给出拒绝原因");
    }
    WmNews wmNews = new WmNews();
    wmNews.setId(dto.getId());
    wmNews.setReason(dto.getMsg());
    wmNews.setStatus(dto.getStatus().shortValue());
    updateById(wmNews);
    return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
}

文章审核成功

需求

  • 需要创建app端的文章信息,并更新自媒体文章的状态
public ResponseResult authNewsPass(AdminNewsAuthDto dto) {
    // 1. 更新自媒体文章状态
    WmNews wmNews = new WmNews();
    wmNews.setId(dto.getId());
    wmNews.setStatus(dto.getStatus().shortValue());
    updateById(wmNews);

    // 2. 创建app端的文章信息
    ArticleDto articleDto = new ArticleDto();
    // 2.1 获取自媒体端文章
    WmNews news = getById(dto.getId());
    wmNewsAutoScanService.saveAppArticle(news);
    return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
}

来源

黑马程序员. 黑马头条

Gitee

https://gitee.com/yu-ba-ba-ba/leadnews

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Y_cen

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值