基于Vue+SpringBoot+MySQL的海南旅游推荐系统,基于协同推荐算法,包括用户网页和管理后台,包含景点类型模块、旅游景点模块、行程推荐模块、美食推荐模块、景点排名模块,还包含系统自带的用户管理、部门管理、角色管理、菜单管理、日志管理、数据字典管理、文件管理、图表展示等基础模块,海南旅游推荐系统基于角色的访问控制,给景点管理员、游客使用,可将权限精确到按钮级别,您可以自定义角色并分配权限,系统适合设计精确的权限约束需求。
项目编号: S 023 ,源码已在 B i l i b i l i 中上架,需要的朋友请自行下载。 \color{red}{项目编号:S023,源码已在 Bilibili 中上架,需要的朋友请自行下载。} 项目编号:S023,源码已在Bilibili中上架,需要的朋友请自行下载。
https://gf.bilibili.com/item/detail/1104039029
为了帮助小白入门 Java,博主录制了本项目配套的《项目手把手启动教程》,希望能给同学们带来帮助。
@RequestMapping(value = "/getRecommendList2OnWeb", method = RequestMethod.GET)
@ApiOperation(value = "查询推荐的景点")
public Result<List<ScenicSpot>> getRecommendList2(){
List<ScenicSpot> spotList = iScenicSpotService.list();
int[] arr = new int[spotList.size()];
for(int i = 1; i < spotList.size(); i ++) {
arr[i - 1] = i;
}
int[] ints = selectM(arr, 10);
List<ScenicSpot> ans = new ArrayList<>();
for (int i : ints) {
ans.add(spotList.get(i));
}
return new ResultUtil<List<ScenicSpot>>().setData(ans);
}
public static int[] selectM(int[] arr,int m){
int len=arr.length;
if(m>arr.length) {
throw new RuntimeException("xxxxx");
}
int[] res=new int[m];
for(int i=0;i<m;i++){
int randomIndex=len-1-new Random().nextInt(len-i);
res[i]=arr[randomIndex];
int tmp=arr[randomIndex];
arr[randomIndex]=arr[i];
arr[i]=tmp;
}
return res;
}
@RequestMapping(value = "/addEvaluate", method = RequestMethod.GET)
@ApiOperation(value = "新增评价")
public Result<Evaluate> addEvaluate(@RequestParam String id, @RequestParam BigDecimal level, @RequestParam String message){
ScenicSpot ss = iScenicSpotService.getById(id);
if(ss == null) {
return ResultUtil.error("景点不存在");
}
User currUser = securityUtil.getCurrUser();
QueryWrapper<Evaluate> qw = new QueryWrapper<>();
qw.eq("spot_id",ss.getId());
qw.eq("user_id",currUser.getId());
qw.last("limit 1");
Evaluate evaluate = iEvaluateService.getOne(qw);
if(evaluate == null) {
evaluate = new Evaluate();
evaluate.setSpotId(ss.getId());
evaluate.setSpotName(ss.getTitle());
evaluate.setUserId(currUser.getId());
evaluate.setUserName(currUser.getNickname());
}
evaluate.setLevel(level);
evaluate.setMessage(message);
evaluate.setTime(DateUtil.now());
iEvaluateService.saveOrUpdate(evaluate);
return ResultUtil.success();
}
@Scheduled(cron = "0 0/1 * * * ?")
@ApiOperation(value = "景点数据更新")
public void job(){
List<ScenicSpot> spotList = iScenicSpotService.list();
for (ScenicSpot vo : spotList) {
Long evaluateSum = 0L;
QueryWrapper<Evaluate> evalQw = new QueryWrapper<>();
evalQw.eq("spot_id",vo.getId());
List<Evaluate> evaluateList = iEvaluateService.list(evalQw);
for (Evaluate evaluate : evaluateList) {
evaluateSum += evaluate.getLevel().longValue();
}
// 收藏 10分
QueryWrapper<Collection> coQw = new QueryWrapper<>();
coQw.eq("spot_id",vo.getId());
evaluateSum += iCollectionService.count(coQw);
// 浏览 1分
String viewStr = redisTemplate.get("SPOT_VIEW:" + vo.getId());
if(!ZwzNullUtils.isNull(viewStr)) {
try {
long viewNumber = Long.parseLong(viewStr);
evaluateSum += viewNumber;
} catch (Exception e) {}
}
vo.setValue(evaluateSum);
}
Collections.sort(spotList, new Comparator<ScenicSpot>() {
@Override
public int compare(ScenicSpot o1, ScenicSpot o2) {
return (int)(o2.getValue() - o1.getValue());
}
});
if(spotList.size() > 10) {
spotList = spotList.subList(0,10);
}
for (ScenicSpot vo1 : spotList) {
// 评分
BigDecimal evaluateSum = BigDecimal.ZERO;
QueryWrapper<Evaluate> evalQw = new QueryWrapper<>();
evalQw.eq("spot_id",vo1.getId());
List<Evaluate> evaluateList = iEvaluateService.list(evalQw);
for (Evaluate evaluate : evaluateList) {
evaluateSum = evaluateSum.add(evaluate.getLevel());
}
if(evaluateList.size() > 0) {
vo1.setStar(evaluateSum.divide(BigDecimal.valueOf(evaluateList.size()),2, RoundingMode.DOWN));
} else {
vo1.setStar(BigDecimal.valueOf(-1));
}
// 收藏
QueryWrapper<Collection> coQw = new QueryWrapper<>();
coQw.eq("spot_id",vo1.getId());
vo1.setCollection(iCollectionService.count(coQw));
}
redisTemplate.set("SPOT_JOB_DATA", JSON.toJSONString(spotList));
System.out.println("缓存完毕!");
}
@RequestMapping(value = "/loginOnWeb", method = RequestMethod.GET)
@ApiOperation(value = "网站前台登陆")
public Result<String> loginOnWeb(@RequestParam String userName, @RequestParam String password){
QueryWrapper<User> qw = new QueryWrapper<>();
qw.eq("username",userName);
List<User> userList = iUserService.list(qw);
if(userList.size() < 1) {
return ResultUtil.error("用户不存在");
}
User user = userList.get(0);
if(!new BCryptPasswordEncoder().matches(password, user.getPassword())){
return ResultUtil.error("密码不正确");
}
String accessToken = securityUtil.getToken(user.getUsername(), true);
UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(new SecurityUserDetails(user), null, null);
SecurityContextHolder.getContext().setAuthentication(authentication);
return new ResultUtil<String>().setData(accessToken);
}
@RequestMapping(value = "/getByPage", method = RequestMethod.GET)
@ApiOperation(value = "查询美食")
public Result<IPage<DeliciousFood>> getByPage(@ModelAttribute DeliciousFood deliciousFood ,@ModelAttribute PageVo page){
QueryWrapper<DeliciousFood> qw = new QueryWrapper<>();
if(!ZwzNullUtils.isNull(deliciousFood.getTitle())) {
qw.like("title",deliciousFood.getTitle());
}
if(!ZwzNullUtils.isNull(deliciousFood.getContent())) {
qw.like("content",deliciousFood.getContent());
}
if(!ZwzNullUtils.isNull(deliciousFood.getSpotId())) {
qw.eq("spot_id",deliciousFood.getSpotId());
}
IPage<DeliciousFood> data = iDeliciousFoodService.page(PageUtil.initMpPage(page),qw);
return new ResultUtil<IPage<DeliciousFood>>().setData(data);
}
下载本系统代码或使用本系统的用户,必须同意以下内容,否则请勿下载!