結對作業二
這個作業屬于哪個課程 | 2021春軟體工程實踐|S班 |
---|---|
這個作業要求在哪裡 | |
結對學号 | 221801214、221801225 |
這個作業的目标 | fork git倉庫、原型設計實作 |
其他參考文獻 | CSDN、百度、b站 |
目錄
-
- 一.Github倉庫位址
- 項目github位址:https://github.com/Leizhenkang/PairProject
- 代碼規範: https://github.com/Leizhenkang/PairProject/blob/dev/221801214_221801225/codestyle.md
- 二、PSP表格
- 1、PSP表格
- 三、項目通路連結
- 項目通路連結:
- 四、成品展示
- 五、結對讨論過程描述
- 結對的過程遇到的困難和解決方法:
- 六.設計實作過程
- 項目技術:采用前後端分離Vue+SpringBoot
- 功能結構圖
- 設計思路:
- 七.關鍵代碼展示
- 八.心路曆程與評價
- 1、心路曆程與收獲
- 2.結對評價
- 一.Github倉庫位址
PSP | Personal Software Process Stages | 預估耗時(分鐘) | 實際耗時(分鐘) |
---|---|---|---|
Planning | 計劃 | 60 | 50 |
• Estimate | • 估計這個任務需要多少時間 | 30 | 20 |
Development | 開發 | 1000 | 1200 |
• Analysis | • 需求分析 (包括學習新技術) | 1800 | 2000 |
• Team Communication | • 結對讨論 | 360 | 420 |
• Design | • 界面原型設計 | 10 | |
Reporting | 報告 | ||
• Test Repor | • 測試報告 | ||
• Size Measurement | • 計算工作量 | ||
• Postmortem & Process Improvement Plan | • 事後總結, 并提出過程改進計 | 120 | 240 |
合計 | 3380 | 4070 |
1.論文清單的展示: 每頁包含五篇論文,可通過點選上下頁檢視不同論文,點選檢視可顯示文章具體資訊
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLChTJCJUJ0UUJwgTJFFUJ3UUJ4EUJxEUJ4UUJ3kTJ4gTJ1UUJ3gTJ2kTJ2UUJBJUJFFUJ4UUJvwVN2MDN2YzLcN3ZvxmYvw1clxWam9CXt92YuM3ZvxmYuNmLjlGdhR3ctc2bsJ2Lc9CX6MHc0RHaiojIsJye.gif)
2.論文清單題目搜尋:可通過标題搜尋論文,當論文标題不完整時,則會使用模糊搜尋來查詢結果,傳回結果以論文編号來進行排序
3.論文清單摘要搜尋:通過摘要對論文進行查找(也可實作模糊搜尋)
4.論文清單關鍵詞搜尋:通過關鍵詞來查找論文
5.關鍵詞圖譜:展示了論文清單中出現次數最多的關鍵詞,點選關鍵詞可展開相關論文。
6.頂會論文-年份走勢圖:趨勢圖反應三大會議不同時間送出論文數量
- 結對作業二在返校之後,因為我們在同一個宿舍,是以本次作業的交流大部分都是面對面進行的
- 第一次讨論,主要配置設定了本次結對的任務,決定使用前後端分離的Vue+Springboot來完成項目
- 在對各自負責部分有稍微的了解後,又讨論了資料庫如何建立的初次方案,以下是曾在ipad做過的記錄(精簡).
- 由于結對過程中兩個人都不太熟悉github的操作,是以很多時候都是互傳代碼或項目來實作互動的,有些後悔,應該在一開始之前,就先學習git使用的...以緻後面的commit次數有些集中且不足.
結對作業二 -
- 項目不熟悉,知識欠缺 --------花了很多時間進行學習,看視訊(可見b站網頁曆史記錄一排下來的Springboot 和Vue.....)
- 對爬蟲技術的不了解 ------- 用助教爬取的資料建立資料庫
- 前端界面沒有使用元件,常常因為樣式是否美觀,合理而重新設計,最後在不斷地改變之後,與我們第一次的原型設計稍微有些偏差。
- 後端在寫關鍵詞搜尋的時候沒有找到合适的算法,效率低下。 ------自學以及請教大佬。
- 資料庫:資料庫表實作較為簡單,分為paper論文表,存儲論文清單所需相關資訊;keyword表,當中存儲關鍵詞内容,以及關鍵詞id和論文paper_id,多對多關系;還有一張keyword_count記錄改關鍵詞出現次數,以供關鍵詞圖譜功能實作的便利。
結對作業二 結對作業二 結對作業二 - .前端項目結構圖: Addpaper.vue 檢視頁面的元件, Echartstest.vue 熱詞分析圖譜的元件 ,HdView.vue 導航欄元件 , Laa.vue Element-Ui引入的下拉選擇框元件 , PaperItem.vue顯示單篇文章的元件 ,ShowView顯示一頁文章的元件以及換頁等方法 , Trend.vue 趨勢圖元件,折線圖 , index,js 路由配置 , App.vue 渲染首頁面
結對作業二 - 後端項目結構圖:按照接口要求設計, 1.建立實體類(entity),跟資料庫表字段保持一緻 。 2. 2.建立mapper接口,定義要操作資料庫的動作 。 3.建立mapper的xml檔案,寫具體的sql語句 。 4.建立service類,處理業務邏輯 5.在controller類展示處理的結果 。 不過由于對整個SpingBoot不是很了解,寫到後面對資料庫進行操作的時候就按原生方式寫了,熟悉之後會元件按照這個接口設計來寫接口的。
-
結對作業二
- 利用axios get方法調用後端接口,并且處理後端資料,利用循環将取出的最多十個關鍵字存儲到前端并且渲染
mounted() {
const _this = this;
axios({
url: "http://localhost:8080/keyword",
}).then((res) => {
for (let i = 0; i < 10; i++) {
// console.log(res.data[i].count);
// console.log(res)
_this.data2[i] = res.data[i].count;
_this.data1[i] = res.data[i].content;
}
console.log(_this.data1);
console.log(_this.data2);
this.drawLine();
});
// this.$nextTick(this.drawLine());
},
- 導航欄的html,利用了vue.js的路由連結
<template> <div class="header"> <div class="logo"> <img src="https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=4090351118,2973307229&fm=26&gp=0.jpg" alt="" /> <div class="text">論文系統</div> </div> <div class="nav"> <router-link to="/show">論文清單</router-link> <router-link to="/echar">熱詞分析</router-link> <router-link to="/trend">趨勢圖</router-link> </div> </div> </template>
- 用$router.relace跳轉頁面,點選檢視按鈕可以檢視單獨一篇文章,傳遞目前循環的參數進去,以便渲染檢視頁面
methods: {
deleted() {
location.reload();
},
See(e) {
window.location.href = e;
},
change: function () {
this.$router.replace("/add");
this.$nextTick(() => {
eventVue.$emit("aa", this.itemObj);
});
},
mounted() {
eventVue.$on("ak", (message) => {
this.itemObj = message;
console.log(this.itemObj);
});
},
},
- 滾動事件的綁定,實作換頁自動滾動到頭部
mounted() { //此處true 需要加上 不加滾動事件可能綁定不成功 window.addEventListener("scroll", this.handleScroll, true); if (this.searchtext != null) { this.searchtext = this.$route.params.id; } }, handleScroll() { let scrolltop = document.documentElement.scrolltop || document.body.scrollTop; scrolltop > 30 ? (this.gotop = true) : (this.gotop = false); },
- 渲染清單頁面的參數接受和資料導入,判斷是否從熱詞分析點選事件過來,接受熱詞點選頁面的參數,可以用來實作熱詞分析中點選關鍵詞直接跳轉到展示頁面并且搜尋該關鍵詞的論文
created() { axios({ url: "http://localhost:8080/changepage", }).then((res) => { this.listArr2 = res.data; this.listArr1 = this.listArr2.slice(0, 5); if (this.searchtext != null) { this.value = "關鍵詞"; this.selectwhat = 3; this.search1(); } else { this.selectwhat = 1; } }); }
- 查找和搜尋的功能實作,使用過濾器實作模糊搜尋,直接使用前端實作.使用slice函數取出一頁的資料來實作換頁,首次加載頁面的時候取出所有的内容放在一個data裡,每次分頁調取另外五條内容
search1() { this.current = 1; console.log(this.value); if (this.value == "題目") { this.selectwhat = 2; this.listArr1 = this.listArr2 .filter((item, index) => item.title.includes(this.searchtext)) .slice(0, 5); } else if (this.value == "摘要") { this.selectwhat = 3; this.listArr1 = this.listArr2 .filter((item, index) => item.abstracted.includes(this.searchtext)) .slice(0, 5); } else if (this.value == "關鍵詞") { console.log(this.value); this.selectwhat = 4; this.listArr1 = this.listArr2 .filter((item, index) => item.keyword.indexOf(this.searchtext) > -1) .slice(0, 5); } }, nextpage() { let top = document.documentElement.scrollTop || document.body.scrollTop; //實作滾動效果 const timeTop = setInterval(() => { document.body.scrollTop = document.documentElement.scrollTop = top -= 50; if (top <= 0) { clearInterval(timeTop); } }, 10); this.current++; if (this.selectwhat == 1) { this.listArr1 = this.listArr2.slice( this.current * 5 - 5, this.current * 5 ); } else if (this.selectwhat == 2) { this.listArr1 = this.listArr2 .filter((item, index) => item.title.includes(this.searchtext)) .slice(this.current * 5 - 5, this.current * 5); } else if (this.selectwhat == 3) { this.listArr1 = this.listArr2 .filter((item, index) => item.abstracted.includes(this.searchtext)) .slice(this.current * 5 - 5, this.current * 5); } else { this.listArr1 = this.listArr2 .filter((item, index) => item.keyword.indexOf(this.searchtext) > -1) .slice(this.current * 5 - 5, this.current * 5); } },
- 接收參數來構造年份趨勢圖的折線圖
mounted() { const _this = this; axios({ url: "http://localhost:8080/magazine", }).then((res) => { let j = 0; let m = 0; let l = 0; for (let i = 1; i < 36; i++) { if (res.data[i].magezine == "ICCV") { _this.data2[j] = res.data[i].publication_year - 0; _this.data1[j] = res.data[i].number; j++; } else if (res.data[i].magezine == "ECCV") { _this.data3[m] = res.data[i].number; _this.data4[m] = res.data[i].publication_year - 0; m++; } else if (res.data[i].magezine == "CVPR") { _this.data5[l] = res.data[i].number; _this.data6[l] = res.data[i].publication_year - 0; l++; } _this.datax = _this.data6; _this.datay = _this.data5; } console.log(_this.data5); console.log(_this.data6); this.$nextTick(function () { this.drawLine("main"); }); }); },
- 點選切換不同會議的折線圖曲線
clickEC() { this.datax = this.data4; this.datay = this.data3; this.msg="ECCV論文年份趨勢圖"; this.$nextTick(function () { this.drawLine("main"); }); }, clickIC() { this.datax = this.data2; this.datay = this.data1; this.msg="ICCV論文年份趨勢圖"; this.$nextTick(function () { this.drawLine("main"); }); }, clickPR() { this.datax = this.data6; this.datay = this.data5; this.msg="CVPR論文年份趨勢圖"; this.$nextTick(function () { this.drawLine("main"); }); }, },
- 熱詞分析的接口,keyword_count表中存放了每個關鍵字的數量,利用sql語句進行排序,可以擷取前十個(也可以使用limit直接擷取)
@CrossOrigin(origins = "*",maxAge = 3600) @RequestMapping("keyword") public List<Keyword> getKeyword(){ return keywordService.findTopten(); <select id="findTopten" resultType="jiekou.demo.entity.Keyword"> SELECT keyword_count_id,keyword,count FROM keyword_count ORDER BY count DESC </select>
- 趨勢圖接口, 傳回三個參數的List清單,使用資料庫group by
@CrossOrigin(origins = "*",maxAge = 3600) @RequestMapping("/magazine") public List<Magazine> getMagezineAll(){ return magazineService.findmagazine(); @CrossOrigin(origins = "*",maxAge = 3600) @RequestMapping("/paperkey") public List<Paperkey> getPaperkey() { return paperkeyService.findAll(); } <select id="findmagazine" resultType="jiekou.demo.entity.Magazine"> select magazine,count(*) as number,publication_year from paper group by magazine,publication_year ORDER BY publication_year ASC <select>
- 傳回所有關鍵詞以及對應的論文id
@CrossOrigin(origins = "*",maxAge = 3600) @RequestMapping("/paperkey") public List<Paperkey> getPaperkey() { return paperkeyService.findAll(); }
- 傳回所有文章
@RequestMapping("/paper") public List<Paper> getPaper(){ return paperService.findAll(); }
- 傳回所有文章内容接口
@CrossOrigin(origins = "*",maxAge = 3600) @GetMapping("/changepage") public List<PaperKeyword> getPaging(){ List<Paperkey> paperkeys=paperkeyService.findAll(); List<Paper> papers=paperService.findAll(); List<PaperKeyword> paperKeywords=new ArrayList<>(); Paper paper=new Paper(); int q=0; for(int i=0;i<papers.size(); i++){ List<String> s=new ArrayList<>(); paper=papers.get(i); while(paper.getPaper_id()==paperkeys.get(q).getPaper_id()){ s.add(paperkeys.get(q).getWord()); q++; } PaperKeyword paperKeyword=new PaperKeyword(paper.getPaper_id(),paper.getTitle(),paper.getLink(),paper.getPublication_year(),paper.getMagazine(),paper.getAbstracted(),s); paperKeywords.add(paperKeyword); } return paperKeywords; }
雷振康的感受: 首先感受就是之前掌握的東西太少了,這次結對作業先是去學習了vue.js架構的應用,然後看着視訊學了幾天開始寫這次的前端,一開始隻覺得vue.js架構隻是對dom操作的一些簡化,并沒有感覺很好用,然後寫一半的時候發現了可以利用element ui來實作一些功能,會更加的友善,然後就是後端的學習,因為在團隊作業中我負責的是後端,是以也學習了一些後端的東西,就是感覺配置maven有點問題,會經常一直下載下傳同一些jar包,導緻項目導不進去,然後springboot的資料庫操作我不是特别熟練,不知道多表連接配接應該如何去建立一個實體類,這次時間不太夠,下次團隊作業應該就會學習好這些操作了。
李進明的感受:對這次結對作業最大的感受是無力,之前并沒有參與過前後端分離開發項目,在作業釋出初期對整個項目束手無策。在項目開發過程中,得一邊學習新的知識,一邊運用知識,在這個部分體會到對一個知識點要做到依葫蘆畫瓢,必須要掌握基礎知識點,這又讓我覺得大一大二的時光過得太輕松,以至于許多比較基礎的知識都沒能運用起來。不過很感謝這次能有一個結對夥伴,在他進行自己任務比較順利的時候,能抽出空來幫助我,這讓我再次感受到結對作業的作用。整次的結對作業下來,我對後端開發有了比較初步的了解,同時明白了笨鳥還得先飛,在自己基礎比較差的情況下,就得更先一步去學習别人已經掌握的知識,這樣才能在整個團隊協作中不總是掉隊,拖後腿。
雷振康對李進明的評價; 因為是舍友,是以這次結對程式設計比較友善,可以在淩晨兩三點還在一起打代碼,然後可以起到一些督促的作用,可以叫他起來學習,并且修改前後端的接口的時候也比較友善,随時更改需求。
李進明對雷振康的評價:很感謝夥伴在這次結對作業對我的幫助,如果有一個詞說明在這次結對作業中振康的角色,那就是“全棧開發者”。在這次結對作業中,振康很勤奮,能比我早進行項目的開發,還有着比我更紮實的基礎,有些我這邊出現bug的時候都是振康幫忙調試出來的。一方面,如果可以的話,我希望振康能在這次結對作業中拿到更高的分數占比,感謝他在這次結對的辛苦付出。另一方面,振康有時也會說玩笑話刺激我,顯著起到了督促我的作用。在這裡,我希望能有一天,我能做得更好,對着振康說“你求我,我就教你”(doge)。