【開源】基于Vue.js的海南旅游景點推薦系統的設計和實現

在這里插入圖片描述
項目編號: S 023 ,文末獲取源碼。 \color{red}{項目編號:S023,文末獲取源碼。} 項目編號:S023,文末獲取源碼。


目錄

  • 一、摘要
    • 1.1 項目介紹
    • 1.2 項目錄屏
  • 二、功能模塊
    • 2.1 用戶端
    • 2.2 管理員端
  • 三、系統展示
  • 四、核心代碼
    • 4.1 隨機景點推薦
    • 4.2 景點評價
    • 4.3 協同推薦算法
    • 4.4 網站登錄
    • 4.5 查詢景點美食
  • 五、免責說明


一、摘要

1.1 項目介紹

基于Vue+SpringBoot+MySQL的海南旅游推薦系統,基于協同推薦算法,包括用戶網頁和管理后臺,包含景點類型模塊、旅游景點模塊、行程推薦模塊、美食推薦模塊、景點排名模塊,還包含系統自帶的用戶管理、部門管理、角色管理、菜單管理、日志管理、數據字典管理、文件管理、圖表展示等基礎模塊,海南旅游推薦系統基于角色的訪問控制,給景點管理員、游客使用,可將權限精確到按鈕級別,您可以自定義角色并分配權限,系統適合設計精確的權限約束需求。

1.2 項目錄屏

源碼下載


二、功能模塊

2.1 用戶端

  1. 景點推薦:根據用戶個性化偏好給用戶推薦感興趣的景點
    【景點信息包含:景點名稱、景點類型、評分、收藏量、門票價格、門票預訂(提供購買鏈接,用戶可以通過點擊鏈接到其他平臺購買門票)、開放時間、景區地址(所在市區、詳細地址)、景點介紹】
  2. 景點篩選:用戶可通過設置自己想要的景點類型、景點門票價格范圍、景區地址(海口市、三亞市、儋州市、三沙市等)來篩選滿足自身需求的景點
    篩選:【注:若用戶只設置了一個篩選條件則只需滿足一個篩選條件就推薦給用戶,若設置兩個以上,則需都滿足才給用戶推薦】
  3. 旅游攻略:用戶可以通過搜索景點名稱來獲取景點周邊美食以及行程路線的相關信息
    (1)交通指南:起點、終點、交通方式、行程路線
    (2)周邊美食:美食圖片、名稱、類型、簡介、人均消費
  4. 景點數據:景點數據可視化
    (1)好評度排名:管理員可以看到好評度高的前十個景點【排名、景點名稱、好評度】
    (2)景點收藏量:管理員可以看到收藏量排名前十的景點【排名、景點名稱、收藏量】
  5. 個人中心:
    (1)個人信息:賬號、姓名、聯系方式、身份證號(用戶可以更新個人信息、退出登錄)
    (2)景點收藏:用戶可以查看、取消收藏過的景點

2.2 管理員端

  1. 個人中心:管理員個人信息
  2. 景點信息管理:
    (1)查詢:可通過搜索景點名稱、地址、景點類型來獲取需要的景點數據(搜索到需要的景點數據后可進行查看、修改、刪除景點信息操作)
    (2)添加:可以添加新的景點信息
  3. 用戶信息管理:
    (1)查詢:可通過搜索用戶賬號來查詢需要的用戶(查詢到需要的用戶后可對用戶信息進行查看、修改、刪除操作)
    (2)添加:可添加新用戶信息
  4. 行程信息管理:
    (1)查詢:可通搜索景點地址來獲取景點行程路線信息(查詢到需要的行程信息后可對其進行查看、修改、刪除操作)
    (2)添加:可添加信息
  5. 美食信息管理:
    (1)查詢:可通搜索景點地址來獲取景點周邊美食信息(查詢到需要的信息后可對其進行查看、修改、刪除操作)
    (2)添加:可添加新的美食信息
  6. 景點數據:景點數據可視化(同用戶端的景點數據可視化)
    (1)好評度排名:管理員可以看到好評度高的前十個景點【排名、景點名稱、好評度】
    (2)景點收藏量:管理員可以看到收藏量排名前十的景點【排名、景點名稱、收藏量】

三、系統展示

在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述


四、核心代碼

4.1 隨機景點推薦

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

4.2 景點評價

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

4.3 協同推薦算法

@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>() {@Overridepublic 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("緩存完畢!");
}

4.4 網站登錄

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

4.5 查詢景點美食

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

五、免責說明

  • 本項目僅供個人學習使用,商用授權請聯系博主,否則后果自負。
  • 博主擁有本軟件構建后的應用系統全部內容所有權及獨立的知識產權,擁有最終解釋權。
  • 如有問題,歡迎在倉庫 Issue 留言,看到后會第一時間回復,相關意見會酌情考慮,但沒有一定被采納的承諾或保證。

下載本系統代碼或使用本系統的用戶,必須同意以下內容,否則請勿下載!

  1. 出于自愿而使用/開發本軟件,了解使用本軟件的風險,且同意自己承擔使用本軟件的風險。
  2. 利用本軟件構建的網站的任何信息內容以及導致的任何版權糾紛和法律爭議及后果和博主無關,博主對此不承擔任何責任。
  3. 在任何情況下,對于因使用或無法使用本軟件而導致的任何難以合理預估的損失(包括但不僅限于商業利潤損失、業務中斷與業務信息丟失),博主概不承擔任何責任。
  4. 必須了解使用本軟件的風險,博主不承諾提供一對一的技術支持、使用擔保,也不承擔任何因本軟件而產生的難以預料的問題的相關責任。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/165016.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/165016.shtml
英文地址,請注明出處:http://en.pswp.cn/news/165016.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

CSS特效017:球體漲水的效果

CSS常用示例100專欄目錄 本專欄記錄的是經常使用的CSS示例與技巧&#xff0c;主要包含CSS布局&#xff0c;CSS特效&#xff0c;CSS花邊信息三部分內容。其中CSS布局主要是列出一些常用的CSS布局信息點&#xff0c;CSS特效主要是一些動畫示例&#xff0c;CSS花邊是描述了一些CSS…

前端錯誤處理與調試

** javascript錯誤處理 ** 由于javascript本身是動態語言&#xff0c;而且沒有固定的開發工具&#xff0c;因此他普遍認為是最難以調試的語言&#xff0c;在ECMAScript3新增了try-catch和throw以及一些錯誤類型&#xff0c;讓開發人員能適當的處理錯誤&#xff0c;緊接著web瀏…

多tab頁表單校驗如何做

多tab頁表單校驗如何做 在多tab頁表單中進行校驗&#xff0c;可以按照以下步驟進行&#xff1a; 創建一個表單對象&#xff0c;用于存儲表單數據和校驗規則。 分為多個tab頁&#xff0c;每個tab頁對應一個表單頁面。 定義每個tab頁中的表單字段及其相應的校驗規則。 在切換…

PHP 賦值、算數和比較運算符 學習資料

PHP 賦值、算數和比較運算符 在 PHP 中&#xff0c;賦值、算數和比較運算符用于對變量進行賦值、進行數學運算和比較操作。以下是對這些運算符的介紹和示例&#xff1a; 賦值運算符 賦值運算符用于給變量賦值。常用的賦值運算符有 、、-、*、/ 等。 示例&#xff1a; $a …

芯能轉債上市價格預測

芯能轉債-113679 基本信息 轉債名稱&#xff1a;芯能轉債&#xff0c;評級&#xff1a;AA-&#xff0c;發行規模&#xff1a;8.8億元。 正股名稱&#xff1a;芯能科技&#xff0c;今日收盤價&#xff1a;12.63元&#xff0c;轉股價格&#xff1a;13.1元。 當前轉股價值 轉債面…

基于遺傳優化的多屬性判決5G-Wifi網絡切換算法matlab仿真

目錄 1.算法運行效果圖預覽 2.算法運行軟件版本 3.部分核心程序 4.算法理論概述 5.算法完整程序工程 1.算法運行效果圖預覽 2.算法運行軟件版本 MATLAB2022a 3.部分核心程序 .......................................................................... %接收功率、網…

數字孿生智慧校園 Web 3D 可視化監測

當今&#xff0c;智慧校園發展階段亟需推動信息可視化建設與發展&#xff0c;將大數據、云計算、可視化等高新技術相融合&#xff0c;為校園師生創造科學智能的學習環境&#xff0c;并實現教學資源最大化和信息服務智能化。幫助學校更好地應用校園可視化技術&#xff0c;提升校…

原型模式 (Prototype Pattern)

定義&#xff1a; 原型模式&#xff08;Prototype Pattern&#xff09;是一種創建型設計模式&#xff0c;它用于創建重復的對象&#xff0c;同時保持性能。這種模式的核心思想是通過復制一個已存在的實例來創建新的實例&#xff0c;而不是新建實例并對其進行初始化。原型模式適…

jetson xavier NX深度學習環境配置

文章目錄 jetson xavier NX深度學習環境配置1. SD卡系統燒錄1.1 材料1.2 軟件配置1.3 格式化SD卡1.4 系統鏡像燒錄 2. 環境配置2.1 cuda環境配置2.2 安裝依賴庫2.3 安裝python及依賴環境2.4 安裝pytorch環境 jetson xavier NX深度學習環境配置 1. SD卡系統燒錄 1.1 材料 SD …

面試題 —— 前端精選(1)

文章目錄 前言 闡述 JS 的事件循環 JS 中的計時器能做到精確計時嗎&#xff1f;為什么&#xff1f; 如何理解 JS 的異步&#xff1f; 前言 本文章介紹三道圍繞 JavaScript 的精選面試題 闡述 JS 的事件循環 事件循環?叫做消息循環&#xff0c;是瀏覽器渲染主線程的?作?式…

CentOS虛擬機重置賬號密碼

虛擬機忘記密碼了 一般來說&#xff0c;虛擬機的賬號密碼&#xff0c;工作中都會有文檔記錄&#xff0c;如果忘記了可以查看文檔。但是也有特例&#xff0c;虛擬機的密碼沒有記錄到文檔中&#xff0c;嘗試了很多次依然登錄失敗&#xff0c;這時候就只能重置賬號密碼了。 1.重…

upload-labs關卡13(基于白名單的0x00截斷繞過)通關思路

文章目錄 前言一、回顧上一關知識點二、靶場第十三關通關思路1、看源代碼2、bp進行0x00截斷繞過3、蟻劍連接 總結 前言 此文章只用于學習和反思鞏固文件上傳漏洞知識&#xff0c;禁止用于做非法攻擊。注意靶場是可以練習的平臺&#xff0c;不能隨意去尚未授權的網站做滲透測試…

nginx中proxy_pass的配置

Nginx的官網將proxy_pass分為兩種類型&#xff1a; 不帶URI方式&#xff1a;只包含IP和端口號的&#xff0c;不帶uri&#xff08;單個/也算uri&#xff09;&#xff0c;比如proxy_pass http://localhost:8080&#xff1b;帶URI方式&#xff1a;在端口號之后有其他路徑的&#…

思維模型 潘多拉效應

本系列文章 主要是 分享 思維模型 &#xff0c;涉及各個領域&#xff0c;重在提升認知。越是禁止&#xff0c;越是好奇。 1 潘多拉效應的應用 1.1 潘多拉效應在管理中的應用 通用電氣公司曾經推出了一項名為“六西格瑪”的管理方法&#xff0c;該方法旨在通過優化業務流程和提…

Linux終端和命令行

文章目錄 學習Linux終端和命令行一、常用Linux命令的基本使用&#xff08;一&#xff09;放大/縮小終端窗口的字體顯示&#xff08;二&#xff09;自動補全 二、軟件安裝三、文件和目錄常用命令&#xff08;一&#xff09;ls&#xff1a;查看目錄內容1.ls命令說明2.Linux下文件…

Peter算法小課堂—前綴和數組的應用

桶 相當于計數排序&#xff0c;看一個視頻 桶排序 太戈編程1620題 算法解析 #include <bits/stdc.h> using namespace std; const int R11; int cnt[R];//cnt[t]代表第t天新增幾人 int s[R];//s[]數組是cnt[]數組的前綴和數組 int n,t; int main(){cin>>n;for(…

flutter 輸入框組件 高度問題

使用的組件名字為 TestField 組件 TestField 配置 占位文字 設置 decoration 屬性 InputDecoration 中hintText去掉輸入到 輸入框的間距 InputDecoration 中contentPadding EdgeInsets.zero去掉邊框中的間距 InputDecoration 中 使用 isDense:true設置輸入框內文字的顏色 …

Android 11.0 SystemUI 去掉狀態欄wifi流量上下行圖標功能實現

1.概述 在11.0系統定制rom開發中,在關于systemui的定制功能總,在SystemUI 狀態欄上顯示時鐘,電池電量 wifi圖標,在顯示wifi圖標時,網絡實時更新時,但是會時不時顯示上下行圖標 顯得很不美觀,客戶需求要求不顯示上下行圖標,所以需要去掉上下行圖標功能,接下來實現相關功能…

MATLAB算法實戰應用案例精講-【圖像處理】計算機視覺(基礎篇)(二)

目錄 知識儲備 opencv基礎知識 01 什么OpenCV 02 如何部署OpenCV? 03 OpenCV模塊簡介 04 OpenCV基本數據結構

Shell循環:for(一)

語法結構&#xff1a; for 變量名 [ in 取值列表] do 循環體 done 示例1&#xff1a; 1、需求&#xff1a;自動循環創建10個用戶 2、演示&#xff1a; [rootlocalhost ~]# vim for.sh #腳本編寫 #!/bin/bash for i in {1..10} do useradd "user$…