项目——旅游攻略页面

一、排行

image
**实现排行效果,我们先看页面的请求,对应哪个接口,这三个不同的请求,分别对应着页面上的海外(1),国内(2),热门(3)
image
前端需要这两个数据
image
写后端对应接口
image
我们查排名,用最新数据,所以查询最大的时间
根据statisnum排名,只取前十条数据
image

二、定时更新排行数据

image
我们需要用定时任务来实现定时更新,所以让我们先写通流程,再写业务
(一)流程
image
第一步,现在controller写一个接口,我们不需要返回数据,所以类型写个R<?>
image
service先写一个测试数据,我们现在先不写业务
定时任务:
在主表远程调用任务表,
image
写完远程调用,记得写fallback降级页面
image
在job模组引入,
image
image
去后台管理员界面,增加一个定时任务,strategyTask.statisRank调用方法名是模块名.方法名
image
然后我们就可以在页面上开启这个定时任务了,看后台控制台有没有打印出测试信息

(二)业务
在service层,写业务代码,我们从主表中根据viewnum查到观看数最多的10条数据,在service层,写业务代码,我们从主表中根据viewnum查到观看数最多的10条数据,把它放到数组里.
调用这三个请求都通用的方法addRank()

循环遍历查到主表数据的数组,给创建的strategyRank对象赋值把这个对象放回到去,引入strategyRankService,调用批量存储

@Override
    public void statisRank() {
        //除了时间,剩下的字段都可以在主表查到
        Date now = new Date();

        //查国外
        List<Strategy> abroadList = lambdaQuery().eq(Strategy::getIsabroad, 1)
                .orderByDesc(Strategy::getViewnum)
                .last("limit 10")
                .list();
        List<StrategyRank> abroadRank = new ArrayList<>();
        addRank(abroadList, now, abroadRank, 1L);

        //查国内
        List<Strategy> chinaList = lambdaQuery().eq(Strategy::getIsabroad, 0)
                .orderByDesc(Strategy::getViewnum)
                .last("limit 10")
                .list();
        List<StrategyRank> chinaRank = new ArrayList<>();
        addRank(chinaList, now, chinaRank, 2L);

        //查热门
        List<Strategy> hotList = lambdaQuery()
                .orderByDesc(Strategy::getViewnum)
                .last("limit 10")
                .list();
        List<StrategyRank> hotRank = new ArrayList<>();
        addRank(hotList, now, hotRank, 3L);
    }

    private void addRank(List<Strategy> List, Date now, List<StrategyRank> rankList, Long type) {
        //循环遍历出刚才查到的满足上述条件的数组,把他们每一条循环遍历出来,取我要的属性,赋值,把存满值得对象添加到我的列表里
        for (Strategy strategy : List) {
            StrategyRank rank = new StrategyRank();
            rank.setDestId(strategy.getDestId());
            rank.setDestName(strategy.getDestName());
            rank.setStatisTime(now);
            rank.setStatisnum(strategy.getViewnum());
            rank.setStrategyId(strategy.getId());
            rank.setStrategyTitle(strategy.getTitle());
            rank.setType(type);
            rankList.add(rank);
        }
        //为什么用service,不用mapper,因为service1能批量存
        strategyRankService.saveBatch(rankList);
    }

三、主题显示

image
image
看前端发现要传的数据,是一个String和一个List,我们没有这个实体类,所以创建一个VO
image
写controller
image

service一共有两种写法:一是写两个sql语句查,二是分组查
两个sql查

    @Override
    public List<ThemeVO> queryTheme() {
//创建一个新VO对象
        List<ThemeVO> vos = new ArrayList<>();
//查询主表,去重theme_name
        List<Strategy> list = query().select("distinct theme_name").list();

        for (Strategy strategy : list) {
//拿到主题名字
            String themeName = strategy.getThemeName();
//根据主题名字再去查主表,去重dest_name,dest_id
            List<Strategy> strategies = query().select("distinct dest_name,dest_id")
                    .eq("theme_name", themeName)
                    .list();
//创建新Destination列表对象
            List<Destination> dests=new ArrayList<>();
//这个赋的是我们vo里的那个list
            for (Strategy strategy1 : strategies) {
                Destination destination = new Destination();
                destination.setId(strategy1.getDestId());
                destination.setName(strategy1.getDestName());
                dests.add(destination);
            }
//创建一个新vo对象
//把他填到我们要返回去的大vos里
            ThemeVO vo = new ThemeVO(themeName, dests);
            vos.add(vo);
        }
        return vos;
    }

分组查:

 @Override
    public List<ThemeVO> queryTheme() {
        QueryWrapper<Strategy> wrapper = new QueryWrapper<>();
//按照theme_name分组
        wrapper.groupBy("theme_name");
查询theme_name,去重后的dest_name,dest_id,因为分组,所以前面要用函数
        wrapper.select(" theme_name themeName, GROUP_CONCAT(DISTINCT dest_name) names,GROUP_CONCAT(DISTINCT dest_id) ids");
        List<Map<String, Object>> list = baseMapper.selectMaps(wrapper);
        List<ThemeVO> vos = new ArrayList<>();

//循环遍历数组,把ids,names以逗号分割
        for (Map<String, Object> map : list) {
            String themeName = (String) map.get("themeName");
            String ids = (String) map.get("ids");
            String names = (String) map.get("names");
            String[] idArr = ids.split(",");
            String[] nameArr = names.split(",");

            List<Destination> dests = new ArrayList<>();
//循环遍历分割后的id数组,,做到id,名对应存上
            for (int i = 0; i < idArr.length; i++) {
                Long id = Long.valueOf(idArr[i]);
                String name = nameArr[i];
//给destination赋值
                Destination destination = new Destination();
                destination.setId(id);
                destination.setName(name);
                dests.add(destination);
            }
            ThemeVO themeVO = new ThemeVO(themeName, dests);
            vos.add(themeVO);
        }
        return vos;
    }

image

四、导航标签

image
实现导航效果,我们先看页面的请求,是哪个接口,这三个不同的请求,分别对应着页面上的国外(1),国内(2),主题(3)
image
对应后端的这个controller,我们写出该请求对应的controller方法
image
用mp高级查询代替了原始的sql语句,select * from ta_strategy_condition
where statis_time in (select max(statis_time) from ta_strategy_condition)
and type=?;
我们查最新数据,所以时间取最大值,type的值是根据前端传回来的请求值,
image

五、根据导航标签高级查询

image
image
看到前端请求,写controller接口方法,请求以type和refid为参数,所以我们写了一个qo
image
image
service层

    @Override
    public IPage<Strategy> queryPage(StrategyQuery qo) {
        IPage<Strategy> page = new Page<>(qo.getCurrentPage(), qo.getPageSize());
//mq只能返回list对象,这个分页返回page所以用不了
        LambdaQueryWrapper<Strategy> wrapper = new LambdaQueryWrapper<>();
//当第一次刷新,用户没有点导航标签的时候,这个就为空,不用管
        if (qo.getType() != null) {
//当类型为1或者2时,是国外或者国内
//dest_id=refid
            if (qo.getType() == 1 || qo.getType() == 2) {
                wrapper.eq(Strategy::getDestId, qo.getRefid());
            } else {
//当类型为3时,是主题
//theme_id=refid
                wrapper.eq(Strategy::getThemeId, qo.getRefid());
            }
        }
        return baseMapper.selectPage(page, wrapper);
    }
posted @ 2026-08-10 21:33  Jennifer_F  阅读(5)  评论(0)    收藏  举报