项目——旅游攻略页面
一、排行

**实现排行效果,我们先看页面的请求,对应哪个接口,这三个不同的请求,分别对应着页面上的海外(1),国内(2),热门(3)

前端需要这两个数据

写后端对应接口

我们查排名,用最新数据,所以查询最大的时间
根据statisnum排名,只取前十条数据

二、定时更新排行数据

我们需要用定时任务来实现定时更新,所以让我们先写通流程,再写业务
(一)流程

第一步,现在controller写一个接口,我们不需要返回数据,所以类型写个R<?>

service先写一个测试数据,我们现在先不写业务
定时任务:
在主表远程调用任务表,

写完远程调用,记得写fallback降级页面

在job模组引入,


去后台管理员界面,增加一个定时任务,strategyTask.statisRank调用方法名是模块名.方法名

然后我们就可以在页面上开启这个定时任务了,看后台控制台有没有打印出测试信息
(二)业务
在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);
}
三、主题显示


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

写controller

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;
}
四、导航标签

实现导航效果,我们先看页面的请求,是哪个接口,这三个不同的请求,分别对应着页面上的国外(1),国内(2),主题(3)

对应后端的这个controller,我们写出该请求对应的controller方法

用mp高级查询代替了原始的sql语句,select * from ta_strategy_condition
where statis_time in (select max(statis_time) from ta_strategy_condition)
and type=?;
我们查最新数据,所以时间取最大值,type的值是根据前端传回来的请求值,

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


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


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);
}

浙公网安备 33010602011771号