電子產(chǎn)業(yè)一站式賦能平臺(tái)

PCB聯(lián)盟網(wǎng)

搜索
查看: 36|回復(fù): 0
收起左側(cè)

畢業(yè)設(shè)計(jì)So Easy:Java Vue SpringCloud實(shí)現(xiàn)博客系統(tǒng)

[復(fù)制鏈接]

660

主題

660

帖子

4567

積分

四級(jí)會(huì)員

Rank: 4

積分
4567
跳轉(zhuǎn)到指定樓層
樓主
發(fā)表于 2023-6-28 12:00:00 | 只看該作者 |只看大圖 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式

, ]. V4 V# x6 r4 \" m- F( [% Y2 w' [點(diǎn)擊上方藍(lán)色字體,關(guān)注我們" w. ?  W$ S1 G( H
很多計(jì)算機(jī)專業(yè)大學(xué)生經(jīng)常和我交流:畢業(yè)設(shè)計(jì)沒思路、不會(huì)做、論文不會(huì)寫、太難了......
& }" E5 h: Y2 ?6 z% P3 X: [8 Q1 o+ y; c, Y
" w, H7 w% z% u6 i" z4 M3 J針對(duì)這些問題,決定分享一些軟、硬件項(xiàng)目的設(shè)計(jì)思路和實(shí)施方法,希望可以幫助大家,也祝愿各位學(xué)子,順利畢業(yè)!
+ L6 q/ p$ d6 Z$ v* d8 a/ L1 @; _* @) a$ ]2 I$ X- `
" x6 h, |; g' F! W1 p- u

, P8 t. @" ?3 m  h5 K% r9 F, k
% O* \  V" ]8 \: P2 D對(duì)計(jì)算機(jī)技術(shù)感興趣的小伙伴請(qǐng)關(guān)注公眾號(hào):美男子玩編程,公眾號(hào)優(yōu)先推送最新技術(shù)博文,創(chuàng)作不易,請(qǐng)各位朋友多多點(diǎn)贊、收藏、關(guān)注支持~
' o1 Q2 C' i, P3 B( ?3 S3 k: `5 O/ B2 e0 a* v( I
項(xiàng)目專欄:https://blog.csdn.net/m0_38106923/category_11085518.html* O% j3 n) z# o& R( f
博客是互聯(lián)網(wǎng)的一種分享類型的技術(shù)產(chǎn)物,但是如何留著用戶才是重要的,并不都是所有的功能都會(huì)涉及到“高并發(fā)”,博客的功能多樣性會(huì)增強(qiáng)用戶的體驗(yàn),讓用戶對(duì)博客的使用產(chǎn)生依賴性,利用從眾心態(tài)合理地開發(fā)增值功能。# f6 j: G+ U) ?2 m5 i5 Q, j# Q$ c
3 g, J( q9 `1 |2 U$ a
本次系統(tǒng)的開發(fā)采用了主流的微服務(wù)架構(gòu)方式,所以把控每個(gè)微服務(wù)的功能相互獨(dú)立和完整是“微服務(wù)”系統(tǒng)的關(guān)鍵。由于博客的實(shí)現(xiàn)比較簡(jiǎn)單,所以只有涉及到“高并發(fā)”的時(shí)候需要斷點(diǎn)分析即可,下面將介紹博客系統(tǒng)的一些功能。
& e! a4 v" w* r) G" c
# p/ k' k2 b/ c0 P' @& B" Z項(xiàng)目工程資源請(qǐng)參見:https://download.csdn.net/download/m0_38106923/878495778 v& V# H) N) [8 X
1
2 S: w, W; ?$ B- G項(xiàng)目功能
+ x- w9 `) \" W( E4 F6 Z博客基本的功都具備,例如博客的核心功能:博客的發(fā)表,刪除,瀏覽,評(píng)論,點(diǎn)贊等。除了這些,還可以每天定時(shí)簽到提升博客的等級(jí),充值會(huì)員提升使用體驗(yàn)。3 q! l0 t) Y0 A, k" ?$ H( [
; J% O( t8 v' J- a* T$ q
個(gè)人的安全信息也非常重要,所以我單獨(dú)劃分一個(gè)微服務(wù)中心來實(shí)現(xiàn)。同樣我在每行重要的代碼上都增加了明顯的注釋,這對(duì)于我以后的維護(hù)和擴(kuò)充博客功能可以打下堅(jiān)實(shí)的基礎(chǔ),盡可能地符合軟件設(shè)計(jì)開發(fā)原則。, X3 C+ _& Q8 [% y

& t6 Q, V% x& {' k關(guān)于博客的功能一共涉及到8個(gè)微服務(wù)中心:
  • 用戶的個(gè)人中心:包含登錄、注冊(cè)、智能驗(yàn)證。
  • 用戶的安全中心:安全信息、手機(jī)與郵箱的基本功能和安全認(rèn)證的接口。
  • 用戶的博客中心:發(fā)表和管理個(gè)人的博客,游客可以瀏覽公開的博客。
  • 用戶的文件中心:發(fā)表博客需要用到的圖片和個(gè)人用戶的頭像。
  • 用戶的簽到中心:博客的簽到累計(jì)的經(jīng)驗(yàn)值和簽到獎(jiǎng)勵(lì)。
  • 用戶的會(huì)員中心:包含普通會(huì)員和超級(jí)會(huì)員。
  • 用戶的支付中心:VIP的充值功能,個(gè)人錢包功能,賬單等。
  • 用戶的搜索中心:根據(jù)摘要或者文章標(biāo)題的關(guān)鍵字搜索指定的博客。
      n9 R, m; o# R$ n. W" x[/ol]1 ]0 q3 C& A: T- b1 \( K3 M
    23 @- b6 m' m+ Z" M" \2 M, d3 l0 [2 ^
    項(xiàng)目架構(gòu)設(shè)計(jì)
    5 A/ O6 C. G% `! L
    - e3 H! u1 J$ m" H0 r- `
    / B' f) v' N4 d+ G7 P+ R& W" C從宏觀設(shè)計(jì)來說,各個(gè)微服務(wù)中心都是一個(gè)moudle,需要注冊(cè)到一個(gè)高可用的微服務(wù)注冊(cè)中心上保證機(jī)器信息的正確性。
    8 [) A: T. [( X9 z) D4 n" S, u% [. Z- ]6 p$ l
    從微觀運(yùn)行來說,用戶的請(qǐng)求API都經(jīng)過Zuul,再由Zuul負(fù)載均衡分配給需要的微服務(wù)中心,所以Zuul也需要高可用保證用戶流量可以得到回應(yīng)。通過zuul網(wǎng)關(guān)后,請(qǐng)求通過Feign實(shí)現(xiàn)微服務(wù)之間數(shù)據(jù)的交互。
    5 I& D5 @- ~8 L8 g: Y1 K8 @1 p$ D
      s) t  X8 l( v( h6 V7 p2 ^! n) [當(dāng)發(fā)生錯(cuò)誤運(yùn)行時(shí),利用Hystrix的回退機(jī)制保護(hù)系統(tǒng)的穩(wěn)定運(yùn)行,不會(huì)發(fā)生級(jí)聯(lián)占用效應(yīng),保證每一個(gè)請(qǐng)求API都可以得到響應(yīng)。當(dāng)發(fā)生網(wǎng)絡(luò)不可用的情況下,需要觸發(fā)用戶的補(bǔ)償機(jī)制,當(dāng)出現(xiàn)不可知的錯(cuò)誤時(shí),也可以直接管理機(jī)器的集群來維護(hù)系統(tǒng)的穩(wěn)定運(yùn)行。+ Y; R& X& Y. Z! M( }4 K3 t
    3
    " z3 M& Q) o4 U& M項(xiàng)目數(shù)據(jù)庫(kù)設(shè)計(jì)
    / N; e, C( b( a' r+ b9 @: H4 P對(duì)于用戶來說,需要輸入賬號(hào)和密碼,若是不存在可以注冊(cè)自己的賬號(hào)和密碼。注冊(cè)的時(shí)候提供30分鐘填寫博客信息的有效時(shí)間,不填寫則直接登錄。需要設(shè)置個(gè)人的手機(jī)和郵箱來綁定安全認(rèn)證,若想要開通我的錢包則需要實(shí)名注冊(cè),同樣也包含校園認(rèn)證。丟失了個(gè)人信息,則可以用身份證申訴。每天凌晨開始可以開始簽到,根據(jù)會(huì)員的不同增益不同,簽到的持續(xù)天數(shù)不同經(jīng)驗(yàn)值累加也不同。會(huì)員的開通只包含支付寶,賬單是每筆消費(fèi)的記錄。核心表是用戶博客之類的表,文章均存在數(shù)據(jù)庫(kù),不過ElasticSearch也保存了文章的標(biāo)題和摘要。每個(gè)用戶可以評(píng)論他人的文章,私密的文章不會(huì)出現(xiàn),會(huì)員的文章會(huì)出現(xiàn)在會(huì)員專區(qū)。7 {# K& k$ k" C
    1 E. q2 I5 ~) f6 w: T9 ^! x
    博客一共含有8個(gè)主功能,所以一共涉及用戶表,用戶信息表,安全表,頭像表,簽到表,簽到獎(jiǎng)勵(lì)表(兩種獎(jiǎng)勵(lì)),會(huì)員表,錢包表,訂單表,博客表,博客分類表,博客標(biāo)簽表,博客圖片表,博客的評(píng)論表,點(diǎn)贊表和收藏表17個(gè)表。
    # B. n5 O  b; `
    $ Z% \# n  m8 Y  c# y" d 9 }. z4 B8 M( _& I

    8 e% B4 P. L' v4! k% q& W3 ?) x' P
    項(xiàng)目架構(gòu)實(shí)現(xiàn)* m8 `+ j! \# p; D& B
    4.1、Vue架構(gòu)的實(shí)現(xiàn); b4 g+ a. ]$ T8 q
    前端IDE采用的是WebStorm,博客的Vue主要分布如下圖所示:. A2 C" c4 j3 n- T' D, l

    + ~" c( U6 A7 \( g- s: I$ g' Q7 _8 x
    ) Z8 o# q) u1 I  X* {+ d
    . p3 Z) d* P+ J* {5 BAlert.js是自定義重構(gòu)代碼的漂亮提示框。axios.js是封裝好的axios請(qǐng)求HTTP函數(shù),components是Vue文件存儲(chǔ)位置,也是Vue的組件,index.js是管理前端路由url的跳轉(zhuǎn),利用components組件與url的控制。store.js是組件狀態(tài)管理的文件,由于采用的LocalStorage本地存儲(chǔ)所以并不是主用。main.js是全局文件也是最重要的文件,管理Vue的全局配置。static/img中保存的是博客所用的圖片。
    6 b5 |% m6 v6 c! u* h* [) d. V不管是用IDE創(chuàng)建的項(xiàng)目還是采用常規(guī)腳手架創(chuàng)建的vue項(xiàng)目,其項(xiàng)目都會(huì)在根目錄生成一個(gè)package.json文件,這個(gè)文件與后端的“pom”相似,這個(gè)文件包含所需要的各種包,還包含項(xiàng)目的配置的名稱與版本對(duì)應(yīng)。
    ( U5 [+ l; @5 U3 Y8 S5 O3 r( z% B* T
    博客項(xiàng)目中的package的完整dependencies代碼如以下所示:
    0 B% @9 e9 _: f2 N
    - |3 S) ~; a1 B* H5 G3 I2 T# H
  • "dependencies": {    "axios": "^0.19.0",    "bootstrap": "^3.3.7",    "echarts": "^4.6.0",    "element-ui": "^2.12.0",    "font-awesome": "^4.7.0",    "github-markdown-css": "^4.0.0",    "highlight.js": "^9.18.1",    "jquery": "^3.4.1",    "marked": "^0.8.0",    "mavon-editor": "^2.7.7",    "popper.js": "^1.12.5",    "showdown": "^1.9.1",    "v-charts": "^1.19.0",    "view-design": "^4.0.2",    "vue": "^2.5.2",    "vue-drag-verify": "^1.0.6",    "vue-nocaptcha": "^0.2.8",    "vue-puzzle-vcode": "^1.1.2",    "vue-qr": "^2.2.1",    "vue-router": "^3.0.1",    "vue-schart": "^2.0.0",    "vue-splitpane": "^1.0.6",    "vuex": "^3.1.2" }4 ?1 g2 D( ~3 c
    4.2、SpringCloud架構(gòu)的實(shí)現(xiàn); _2 d7 k$ Y9 J0 K
    博客Maven的整體微服務(wù)中心實(shí)現(xiàn)的結(jié)構(gòu)圖如下所示:
    0 R) C8 P4 M. x! B
    & q, \. L% e' |4 ^
    : r0 a" S3 O" d# Q( D+ c6 e* |2 E# Y7 J& U0 A  ]
    SpringCloud是基于Java語(yǔ)言的工具集,SpringCloud具備拿來就用的特性,可以節(jié)省開發(fā)的配置時(shí)間,它可以在Docker等云環(huán)境中開發(fā)和部署。SpringCloud的組件比較豐富,博客使用了Eureka,Zuul,F(xiàn)eign,Htsrrix,trubine,Zipkin微服務(wù)組件。組件可以自由地選擇,不過需要解決SpringBoot與SpringCloud之間的版本依賴才能使用。博客涉及到的Java的JDK版本是1.8,SpringBoot的版本是Spring Boot 1.5.9.RELEASE,SpringCloud的版本是Edgware SR4。后端的IDE采用的是IDEA,Maven的版本為3.6.1,任何一個(gè)版本的更改都可能會(huì)導(dǎo)致兼容不一致。
    ) J- ]. O8 @4 q/ X4 q& b/ e3 v- m( n0 X4 T1 s2 l. g, \
    4.3、博客的高可用的實(shí)現(xiàn)
    $ O4 D; s" \! p% Y1 T) b博客使用了兩個(gè)Zuul并且注冊(cè)到高可用的服務(wù)發(fā)現(xiàn)中心來構(gòu)造Zuul高可用集群。Eureka是所有微服務(wù)的注冊(cè)中心,并且自己本身也是微服務(wù)不過需要禁止自我注冊(cè)。Eureka注冊(cè)中心包含每個(gè)微服務(wù)的名稱,IP,端口等,由于因?yàn)榈膯蝹(gè)節(jié)點(diǎn)的微服務(wù)可能會(huì)發(fā)生不可用的情況下導(dǎo)致系統(tǒng)發(fā)生停機(jī),所以采用高可用的微服務(wù)注冊(cè)中心。讓兩個(gè)(多個(gè))服務(wù)發(fā)現(xiàn)組件相互注冊(cè)以達(dá)到可以保持其它微服務(wù)的調(diào)用,維持整個(gè)系統(tǒng)的高可用性,整個(gè)博客的Eureka服務(wù)注冊(cè)中心圖如下圖所示:
    4 G0 ?/ j: g8 k8 D4 Y+ i7 Z$ U2 z" r9 l
    7 r& B9 z# h- r- P  c
    4 S. R+ g& }% @  Y  _: _
    DS Replicas代表兩個(gè)模塊加載模擬單機(jī)代替高可用的實(shí)現(xiàn),不過需要修改本地Host來模擬真實(shí)多機(jī)高可用的效果。每個(gè)微服務(wù)都具有自己的虛擬主機(jī)名以及狀態(tài)來描繪微服務(wù)的顯示情況。每個(gè)微服務(wù)之間通過與服務(wù)注冊(cè)中心每30S心跳傳遞保證服務(wù)可用性。默認(rèn)90S沒有收到心跳則會(huì)注銷該微服務(wù)。EurekaServerOne與EurekaServerTwo為兩個(gè)微服務(wù)注冊(cè)中心,兩者相互注冊(cè)到對(duì)方的服務(wù)中心上來保證Eureka的高可用穩(wěn)定,從而使每一個(gè)博客的請(qǐng)求都可以得到響應(yīng)。6 `2 A1 Q. W6 m- g2 w
    " P5 K8 R6 w3 H
    5
    , f2 y" i9 b) R用戶的個(gè)人中心  j1 Z" v, o3 v0 d
    用戶的個(gè)人中心相當(dāng)于博客的大門,用戶的首次流量都經(jīng)過此處,首次負(fù)載均衡調(diào)用也是基于這個(gè)中心開始,主要涉及到用戶的登錄與注冊(cè)的基本功能,在登錄上排除惡意的攻擊與干擾,保證博客登錄的穩(wěn)定,從而保證系統(tǒng)的穩(wěn)定。這個(gè)中心核心功能就是權(quán)限驗(yàn)證,保持登錄的標(biāo)志,它是保持業(yè)務(wù)穩(wěn)定的重要因素,后續(xù)的實(shí)現(xiàn)會(huì)在以上所述的三個(gè)重要功能展開來講。
    / h) M5 _, }3 o6 @$ ?  }$ \7 @+ ]7 L& M" G
    5.1、登錄的智能驗(yàn)證
    3 X  ^8 C: V- W9 M- IVue整合阿里云智能驗(yàn)證時(shí),需要注冊(cè)布局組件來動(dòng)態(tài)加載JavaScript文件,不然無法使用阿里云的智能組件,前端登錄智能驗(yàn)證的核心代碼如以下所示:
    - @) N5 _* n9 }2 V. x( F4 b
    7 r- a# j& T4 {
  • //動(dòng)態(tài)加載阿里云的JavaScript文件src="//g.alicdn.com/sd/nvc/1.1.112/guide.js" @loaded="initCaptcha">
    + B% \" V! B. D7 a//注冊(cè)局部組件來加載阿里云的JavaScript文件components: {            "remote-js": {                render(createElement) {                    const self = this;                    return createElement("script", {                        attrs: { type: "text/javascript", src: this.src },                        on: {                            load() {                                self.$emit("loaded");                            }                        }                    });                },                props: {                    src: { type: String, required: true }                }            }        },
    % ]8 L( S2 k3 o) u( K//點(diǎn)擊智能驗(yàn)證的封裝函數(shù)            initCaptcha() {                let _this=this;                let ic = new smartCaptcha({                    renderTo: '#sc',                    width: 350,                    height: 42,                    default_txt: "請(qǐng)點(diǎn)擊驗(yàn)證按鈕",                    success_txt: "博客登錄驗(yàn)證成功",                    fail_txt: "點(diǎn)擊按鈕重新刷新登錄驗(yàn)證",                    scaning_txt: "智能檢測(cè)中",                    success: function (data) {                        console.log(NVC_Opt.token);                        console.log(data.sessionId);                        console.log(data.sig);                        _this.aliToken=NVC_Opt.token;                        _this.sessionId=data.sessionId;                        _this.sig=data.sig;                    },                });                ic.init(); },/remote-js
    7 w: K- m( F+ p3 P8 t' c1 g6 ^5.2、博客的登錄注冊(cè)) p. T9 k0 n- `, p. b4 g9 c
    登錄是一個(gè)系統(tǒng)的重要的功能,也是個(gè)人隱私的重要體現(xiàn),拿常見的登錄有郵箱,手機(jī),賬號(hào)或,語(yǔ)音或者二維碼登錄,不過不管通過哪種登錄,個(gè)人信息的安全都應(yīng)該得到保護(hù),保護(hù)個(gè)人隱私重要的是從個(gè)人做起,拒絕非法點(diǎn)擊與輸入。
    5 U2 K. F* V7 n% i1 G; z
    7 g4 _! s, Z$ y拿本次博客的登錄來說只需要驗(yàn)證賬號(hào)和密碼就行,個(gè)人登錄是不會(huì)進(jìn)行權(quán)限驗(yàn)證。注冊(cè)成功會(huì)保持30分鐘的權(quán)限驗(yàn)證,關(guān)于權(quán)限驗(yàn)證會(huì)在標(biāo)題5-2-3中提到,以便后面的博客信息的操作,超過則需要重新登錄去博客的個(gè)人中心填寫博客信息。; R8 g: j/ J) C9 p& u0 u
    博客的登錄與注冊(cè)的頁(yè)面如下圖所示:
    / H" x  |2 G) X  y& v' i  G, P. |. S# s4 A" i

    6 ]' t) E5 |, a# y2 k, @+ w1 n
    ! m2 y. z# h3 ]( V博客登錄的用戶名需要以英文子母開頭,用戶名和密碼均不可以超過16位,注冊(cè)保證兩次登錄密碼正確就可,在此不再貼出圖片累述。
    0 }* w, V! \0 S7 _  ?4 s, T' I8 m, ^4 I
    5.3、登錄的權(quán)限驗(yàn)證; ^$ B) J5 Y7 r# @
    登陸權(quán)限控制是每個(gè)系統(tǒng)都應(yīng)必備的功能,是保持登錄狀態(tài)的重要實(shí)現(xiàn)。微服務(wù)所有的權(quán)限驗(yàn)證均在一個(gè)module上,Token消時(shí)則直接回退給前端status 404失敗碼,成功則是執(zhí)行對(duì)應(yīng)的業(yè)務(wù)邏輯,注意登錄的博客是不需要權(quán)限驗(yàn)證。
    - H. _. t4 @. A# b+ a: E4 v6 Q3 ^
    博客使用了前后端攔截器攔截Token(登錄成功的認(rèn)證碼),所以后端需要定義一個(gè)token驗(yàn)證注解,用攔截器攔截系統(tǒng)的url請(qǐng)求,再進(jìn)行攔截用戶的API請(qǐng)求,最后再驗(yàn)證傳過來的token與Redis中token值是否一致,效驗(yàn)通過才可以正常訪問。當(dāng)用戶登錄成功博客后,后端返回token數(shù)據(jù)。token具有存在時(shí)間,如果用戶一段時(shí)間后不在線或者操作的話,則token會(huì)失效,用戶保持登錄時(shí),則不會(huì)過期。% `8 k7 X7 W  g
    7 ]8 X# L; ?! S, ~" W; b7 b
    Redis中會(huì)以用戶的登錄賬號(hào)作為與token關(guān)聯(lián)的認(rèn)證,有效的token碼可以取出用戶的賬號(hào),然后再進(jìn)行業(yè)務(wù)邏輯。這些redis中的key都可以自行設(shè)置一些時(shí)間,不過前端只保存token值,二次登錄會(huì)覆蓋Redis中的token值。
    * k+ i, u" t/ |  p# `3 Z( A4 U6 f) j  h# L+ M. G. B- A
    ' k2 ~* h6 y2 n# z
    9 N2 d7 {2 X5 s5 g; b0 _4 k
    權(quán)限驗(yàn)證相當(dāng)于系統(tǒng)的第一道大門,如今的安全框架越來越豐富,例如SpringSecurity,Shiro,OAuth等,shiro->security->oauth的上手難度逐漸提升。若是需要對(duì)密碼加密的,可以需根據(jù)個(gè)人開發(fā)自行配置使用對(duì)應(yīng)的安全框架。: H$ U' p2 H9 l( Y
    6
    / P1 @* D7 Q6 c用戶的安全中心
    : w+ q& v7 D! F6.1、用戶的安全布局. c+ W7 ~3 v$ s3 C: `* j
    安全中心包含郵箱,手機(jī),身份證,校園認(rèn)證和其它微服務(wù)中心需要用到的認(rèn)證接口。郵箱采用QQ郵箱,開啟smtP 587端口發(fā)送郵箱驗(yàn)證碼。手機(jī)采用阿里云短信API服務(wù)。兩者的驗(yàn)證碼存在的時(shí)間均為1次失效且存在10分鐘。身份證需要手機(jī)號(hào)的驗(yàn)證。校園認(rèn)證的名字需要和身份證的名字一致。除了綁定一些安全的服務(wù),還包括三種修改密碼的方式,原始密碼修改新密碼,郵箱重置密碼,手機(jī)重置密碼,身份證重置密碼。個(gè)人申述包括手機(jī)號(hào)重置郵箱,舊手機(jī)更換新手機(jī),身份證重置手機(jī)。
    ) n! N0 J7 R6 r- l: i. ^  x: L
    7 b6 t% c. A; |2 b/ I6 d2 z& A
    ; X( G1 I! @! m, y
    0 H0 C. H5 M, [+ T# a# m! c3 F安全中心包括用戶的規(guī)則規(guī)章,博客旨在分享自己的動(dòng)態(tài)和經(jīng)驗(yàn)給他人,不可以辱罵他人,以及不遵守國(guó)家的法律法規(guī)。本次博客的其它微服務(wù)中心所需要的手機(jī)認(rèn)證接口均由這個(gè)微服務(wù)中心提供。
    1 K0 ]2 T! b. F' c, W: d: {( a3 D" D. r7 b% W" `
    6.2、用戶的郵箱注冊(cè)" n2 `4 w+ _& U1 [8 Y9 Z
    博客采用的是免費(fèi)的QQ郵箱,郵箱的yml配置如下:5 v4 L3 h+ d2 E: E
    : J# g1 M5 T% y& e
  • mail:    host: smtp.qq.com    port: 465或587    protocol: smtp    username: 個(gè)人的郵箱    password: 郵箱的SMTP的密碼,可在郵箱的賬戶中開啟SMTP服務(wù)    default-encoding: UTF-8    properties:      mail:       debug: true   #控制臺(tái)開啟運(yùn)行日志4 P/ T8 T2 w0 p& y/ C/ X% {
    QQ郵箱(郵箱與手機(jī)的六位驗(yàn)證碼共用)發(fā)送驗(yàn)證碼按鈕的原代碼如以下所示:
    - t( {9 D7 C9 r5 `1 A! j
    , @! s  I- @' g4 B) x
  • //自動(dòng)生成的驗(yàn)證碼,驗(yàn)證碼的位數(shù)可以自己設(shè)定    public static String generateVerifyCode(int verifySize, String sources){        if(sources == null || sources.length() == 0){            sources = EMAIL_CODES;}        int codesLen = sources.length();        Random rand = new Random(System.currentTimeMillis());        StringBuilder verifyCode = new StringBuilder(verifySize);        for(int i = 0; i             verifyCode.append(sources.charAt(rand.nextInt(codesLen - 1)));}        return verifyCode.toString();}! R* Y  A9 h; I- G( L5 O; {% o
    綁定QQ郵箱JavaScript的代碼如以下所示:2 V. l+ S) d9 Q% C
    , Q' I& Q% [+ q# |
  • //綁定郵箱的發(fā)送registerEmail(){let emailPatter=/[\w!#$%&'*+/=?^_`{|}~-]+(?:\.[\w!#$%&'*+/=?^_`{|}~-]+)*@(?:[\w](?:[\w-]*[\w])?\.)+[\w](?:[\w-]*[\w])?/;if (this.email=== '' || !emailPatter.test(this.email) || this.emailYzm === ''){this.$message.error('輸入內(nèi)容不能為空且郵箱要符合格式')              }else {      this.$http.post('/whc/blog-customer-user/emailButtonRegister',{                      email: this.email,                      emailYzm: this.emailYzm,                  }).then(res=>{                      console.log(res);                      if (res.data.success === true){                          this.$notify({                              title: '成功',                              message: '郵箱綁定成功',                              type: 'success',                          });                  window.localStorage.setItem('myEmail',res.data.message);                          this.reload();                          //this.$router.go(0);                      }else {                          this.$message.error(res.data.message);                      }                  })              }          }
      _( ~. l, Z+ m  G! W5 \后端發(fā)送QQ郵箱注冊(cè)的驗(yàn)證碼如以下所示:
    / u7 ^1 n- V6 z* F4 ?
    * ~/ l+ U0 {! J. d" {# b0 W' X7 o
  • //后端QQ郵箱發(fā)送驗(yàn)證碼的按鈕服務(wù)@Override@Transactional(isolation = Isolation.READ_COMMITTED, propagation = Propagation.REQUIRED)public void sendEmailCode(String email) {    //生成郵箱隨機(jī)的6位驗(yàn)證碼    String emailYzm= generateVerifyCode(6, EMAIL_CODES);$ o. e, k! h+ E0 y
    //From-to,主題和信息.    SimpleMailMessage simpleMailMessage = new SimpleMailMessage();    simpleMailMessage.setFrom(FORM);    simpleMailMessage.setTo(email);    simpleMailMessage.setSubject(SUBJECT);    simpleMailMessage.setText("你的郵箱驗(yàn)證碼是: "+emailYzm+"本次驗(yàn)證碼    會(huì)在10分鐘后失效,請(qǐng)立馬使用。");    //發(fā)送郵箱驗(yàn)證碼       javaMailSender.send(simpleMailMessage);
    . w) u. @; S; s/ h% |9 E5 d  |- ]    //開啟Redis存入email和yzm    Jedis jedisEmail = new Jedis("localhost", 6379);    //設(shè)置郵箱(key)-驗(yàn)證碼(value)的綁定,秒為單位,存在時(shí)間為10分鐘。    jedisEmail.set(email,emailYzm);    jedisEmail.expire(email,600);    //設(shè)置驗(yàn)證碼(key)-郵箱(value)的綁定,秒為單位,存在時(shí)間為10分鐘。(雙向綁定可以判斷失敗存入的驗(yàn)證碼,雙向保險(xiǎn))    jedisEmail.set(emailYzm,email);    jedisEmail.expire(emailYzm,600);}
    % w; J! @* y* K4 {. C) x/ ?! d6.3、用戶的手機(jī)注冊(cè)( V* |# A# u2 \3 Q
    發(fā)動(dòng)短信的前端JavaScript的代碼如以下所示:
    8 w2 p8 W2 `( i1 P
  • //前端綁定手機(jī)phoneRegister(){ let phonePatterRegister=/^1([38][0-9]|4[579]|5[0-3,5-9]|6[6]|7[0135678]|9[89])\d{8}$/;             if (this.phone === '' || this.phoneYzm === '' || !phonePatterRegister.test(this.phone)){                  this.$message.error('手機(jī)或者驗(yàn)證碼不符合規(guī)則');              }else {                  this.$http.post('/whc/blog-customer-user/phoneRegisterButton',{                      phone: this.phone,                      phoneYzm: this.phoneYzm,                  }).then(res =>{                      console.log(res);                      if (res.data.success === true){                          this.$notify({                              title: '成功',                              message: '手機(jī)綁定成功',                              type: 'success',});                         window.localStorage.setItem('myPhone',res.data.message);                          this.reload();                          //this.$router.go(0);                      }else {                          this.$message.error(res.data.message);}})}}
    ; b" [6 C  r: e. E3 }" `4 k8 Z' T8 q! P9 B8 W2 p# E8 m& E
    后端發(fā)送驗(yàn)證碼的代碼如以下所示:8 e& E; C+ w7 h2 Y. u

    3 w0 D0 j, ?: f* @$ h! d
  • //生成手機(jī)的驗(yàn)證碼        String phoneYzm= generateVerifyCode(6, EMAIL_CODES);        //阿里云發(fā)送短信的API        DefaultProfile profile = DefaultProfile.getProfile("cn-hangzhou", "個(gè)人隱私",                "個(gè)人隱私");        IAcsClient client = new DefaultAcsClient(profile);        CommonRequest request = new CommonRequest();        request.setMethod(MethodType.POST);        request.setDomain("dysmsapi.aliyuncs.com");        request.setVersion("2017-05-25");        request.setAction("SendSms");        request.putQueryParameter("RegionId", "cn-hangzhou");        request.putQueryParameter("PhoneNumbers", phone);        request.putQueryParameter("SignName", "個(gè)人隱私");        request.putQueryParameter("TemplateCode", "個(gè)人隱私");        request.putQueryParameter("TemplateParam", "{\"codeab\":\""+phoneYzm+"\"}");        //發(fā)送注冊(cè)手機(jī)的驗(yàn)證碼        try { CommonResponse response = client.getCommonResponse(request);            System.out.println(response.getData());        } catch (ServerException e) {            e.printStackTrace();        } catch (ClientException e) {            e.printStackTrace();}        //開啟Redis存入phone和yzm        Jedis jedisPhone = new Jedis("localhost", 6379);        //設(shè)置手機(jī)(key)-驗(yàn)證碼(value)的綁定,秒為單位,存在時(shí)間為10分鐘。        jedisPhone.set(phone,phoneYzm);        jedisPhone.expire(phone,600);        //設(shè)置驗(yàn)證碼(key)-手機(jī)(value)的綁定,秒為單位,存在時(shí)間為10分鐘。(雙向綁定可以判斷失敗存入的驗(yàn)證碼,雙向保險(xiǎn))        jedisPhone.set(phoneYzm,phone);        jedisPhone.expire(phoneYzm,600);}
    4 E8 ^! d7 |- [6 Y# _8 t6.4、用戶的安全認(rèn)證7 Z% S2 {3 J0 c
    提供安全的認(rèn)證有身份認(rèn)證與校園認(rèn)證,當(dāng)然只是表單的提交,真實(shí)的認(rèn)證需要有關(guān)部門的配合,在此只是用來模擬,校園認(rèn)證需要與身份證的名字保持一致,否則無法通過。* {1 y! X! ]  \+ I: x  }# I
    0 A  I6 a3 P8 n4 {

    ! K6 o- z0 J) @7 Y$ `: F
    # Z8 r& A4 P$ k  \  e) ?9 k& |+ ]
    % N" y- R" w: }$ p 5 U$ h% q) t8 h; I, r$ I" A! ?
    ' ?1 e1 T1 q' W3 z( c/ |& i+ h# C9 ~
    6.5、用戶的密碼安全- j; T: C2 w1 u1 Z" b- g
    當(dāng)個(gè)人安全賬號(hào)發(fā)生異常,可以提供修改密碼,也可以重置密碼。
    8 }/ J( v4 F2 H* O! d: j* C. H6 _9 d3 K, C
    1 o8 S, d% Z& J& I% a" O

    " S3 o- N6 a8 ?, t8 ^, [  G* m
    3 k; E5 Y! x+ _. @
    ' F/ z) f5 t" m5 g4 O% m" q" w
    : _1 ^, D0 K: J5 {! p6.6、用戶的賬號(hào)申訴
    # {3 _+ u6 X' u$ A5 [: y& R可以使用手機(jī)號(hào)重置郵箱,也可以使用舊手機(jī)號(hào)更換新手機(jī)號(hào)。如果個(gè)人博客的手機(jī)號(hào)安全信息被盜取,手機(jī)號(hào)也可以被重置,但是需要借助身份證申訴,不過一天只可以成功申訴一次。
    - q& ]; \% U( Z! W, U  ], F, Y1 E5 t! ?! t: E
    3 |) o9 B2 }; v. J# r# \
    3 m! w1 Y7 g5 Z2 U# U
    75 B0 Q, [  t" b! D
    用戶的文件中心
    ! Q  [' K: P: D; Y. c7.1、用戶的頭像存儲(chǔ)
    % H. R: N6 o% t3 u當(dāng)用戶注冊(cè)的時(shí)會(huì)需要選擇個(gè)人的頭像,上傳的頭像只能是JPG格式且大小不能超過2MB,且上傳前會(huì)先查詢數(shù)據(jù)庫(kù)中的頭像圖片名是否已經(jīng)存在,存在的話直接會(huì)先刪除OSS中舊圖片,再插入新圖片,如果不存在的話,直接插入到OSS文件服務(wù)器中。頭像的存儲(chǔ)流程由前端發(fā)起file傳給后端,后端接受file頭像,利用二進(jìn)制傳給OSS文件服務(wù)器。服務(wù)器再傳過來頭像的外網(wǎng)URL地址,此時(shí)修改顯示時(shí)間為10年再返還給用戶,最后把頭像外網(wǎng)URL地址保存到自己的LocalStorage本地。
    % e$ V) c1 D; B3 b+ {" @
    / s$ ?  d+ X* ]3 a
    . U6 f" R& ^4 l
    ( e/ w7 O, w) p& ?7.2、博客的圖片存儲(chǔ)6 N( e# U" Q* K# e8 ~% u3 w# [; Z; r
    發(fā)表博客時(shí)文章中會(huì)包含圖片,前端獲取后端的博客圖片url綁定在前端文章中顯示,同樣url也在文章內(nèi)容中一起保存到數(shù)據(jù)庫(kù)中。上傳圖片和上傳頭像不同,文章需要用到的圖片可以有多張,不存在覆蓋問題。需要根據(jù)個(gè)人的文件服務(wù)器的存儲(chǔ)量來權(quán)衡上傳圖片大小。
    - b2 R5 W+ P5 @5 \. N, |& _
    # U9 x3 O2 i+ ?7 b, {1 y% i + M; f+ \8 F6 A* ]: f

    2 H  z7 r# h! \9 a1 p1 g2 v& n2 C- `: C" y* Q5 A
    8
    + l1 `9 h3 _- m! s* b: y/ W% |7 c用戶的簽到中心
    8 y  s; F% _0 q  ^) V' H用戶的簽到等級(jí)代表用的可以使用的權(quán)限,當(dāng)簽到累計(jì)天數(shù)和連續(xù)天數(shù)達(dá)到獎(jiǎng)勵(lì)階段時(shí)觸發(fā)一鍵領(lǐng)取獎(jiǎng)勵(lì)按鈕,每次獎(jiǎng)勵(lì)每個(gè)賬號(hào)只可以領(lǐng)取一次。整個(gè)簽到的等級(jí)由經(jīng)驗(yàn)值決定,但是每天獲得經(jīng)驗(yàn)值為1500。簽到的經(jīng)驗(yàn)值還會(huì)進(jìn)行快速排序排名返還給前端,提升競(jìng)爭(zhēng)效果,同時(shí)會(huì)員增益機(jī)制也會(huì)導(dǎo)致不同的疊加效果。
    1 `! N% B, r! w5 e  H9 ]; M5 V# V$ K1 W$ E
    每天0點(diǎn)之前只能簽到一次,過完0點(diǎn)后Redis中限時(shí)憑證失效既可以再次簽到,簽到的經(jīng)驗(yàn)值采用二分查找和快速排序算法進(jìn)行計(jì)算最后的排名返還給用戶。% N# h$ T/ T- b% N9 {

    1 w/ V3 \& }% n4 i簽到按鈕的計(jì)算代碼如以下所示:" e: H$ u+ Y, t/ G( F5 A
    : n  k9 v( b8 c
  • //先判定是否redis中是否存在限時(shí)憑證        Jedis jedis = new Jedis("localhost", 6379);        if (jedis.get(id.toString()) == null) {            //獲取明天0點(diǎn)的時(shí)間并且設(shè)置限時(shí)憑證            try {                SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//設(shè)置日期格式                Calendar cal = Calendar.getInstance();                cal.add(Calendar.DATE, 1);//這里改為1                Date time = cal.getTime();                String tomorrow = new SimpleDateFormat("yyyy-MM-dd 00:00:00").format(time);                String now = df.format(new Date());                Date d1 = df.parse(now);                Date d2 = df.parse(tomorrow);                //小時(shí)和分鐘和秒相減                Long hour = ((d2.getTime() - d1.getTime()) / (60 * 60 * 1000));                Long minute = ((d2.getTime() - d1.getTime()) / (1000 * 60));                Long second = ((d2.getTime() - d1.getTime()) / 1000);                //最后存在的秒時(shí)間        int total = (hour.intValue()) * 3600 + (minute.intValue()) * 60 + second.intValue();                //控制臺(tái)觀看                logger.info(tomorrow + "/n" + now + "/n" + total);                //設(shè)置redis中的簽到過期時(shí)間                jedis.set(id.toString(), "今天簽到已經(jīng)完成!");                jedis.expire(id.toString(), total);                return SUCCESS;            } catch (ParseException e) {                e.printStackTrace();}        }        return FAILED;; t; u9 j. I  b+ J: T, j# D7 M
    經(jīng)驗(yàn)值的排名的代碼如以下所示:
    8 J% E" q4 O( c3 Y1 f) Y0 V0 X; W4 q1 [
  • //先查詢所有的經(jīng)驗(yàn)值        ListexAll=userSignMapper.selectExperience();        //先將List集合轉(zhuǎn)為L(zhǎng)ong[]數(shù)組        Long[] a=exAll.stream().toArray(Long[]::new);        //可以使用轉(zhuǎn)換工具類,也可以自己動(dòng)手寫Long數(shù)組的轉(zhuǎn)換        long[] quickSort = ArrayUtils.toPrimitive(a);        //快速排序排序成從小到大的順序        sortService.quickSort(quickSort,0,quickSort.length-1);        //利用二分查找算法查找經(jīng)驗(yàn)值所在的索引位置        int position=sortService.binarySearch(quickSort,myExperience);        //最終排名,倒序輸出。        int lastPosition=quickSort.length-position;        //控制條輸出你的排名        logger.info("你在經(jīng)驗(yàn)值排行榜中的名次是:"+lastPosition);        //返回給前端的排名        return lastPosition;( k! [! S9 e3 C( |  U) S3 V
    9
    / r: A( o7 Y! e5 M! z/ |( q用戶的會(huì)員中心
    8 Z3 F9 V1 K. w由于會(huì)員中心與支付中心聯(lián)系比較密切,所以兩者的中心可以結(jié)合起來看作一個(gè)中心來觀看。用戶的會(huì)員中心包括普通會(huì)員和超級(jí)會(huì)員,每種方式存在三種收益方式,年費(fèi)季費(fèi)和月費(fèi),支付成功后均由負(fù)載均衡執(zhí)行業(yè)務(wù)邏輯。由于支付不屬于這個(gè)module中,所以這個(gè)module只是由其它微服務(wù)調(diào)用直接完成業(yè)務(wù)邏輯。
    9 \* Y5 X' _- ?
    + G9 ^# i# n/ Y5 G/ ?+ n- S6 K- ^
    ' n. q5 U1 N+ Z- X5 }7 q# o
    * h) |: T, F9 @- {" u" V  b10
    ( l' s) S1 Y( ^+ q& m用戶的支付中心
    4 l& _: j& t4 |* |5 v未完成實(shí)名認(rèn)證時(shí)頁(yè)面會(huì)轉(zhuǎn)到實(shí)名認(rèn)證中,當(dāng)完成實(shí)名認(rèn)證時(shí),首次進(jìn)入我的錢包中心會(huì)觸發(fā)設(shè)置支付密碼,當(dāng)設(shè)置成功后,支付以及綁定個(gè)人銀行卡均需要用到支付密碼。可以用舊支付密碼修改新密碼,也可以手機(jī)重置手機(jī)密碼。還可以綁定自己的銀行卡,需要有關(guān)部門的配合。本次博客只允許建設(shè)銀行,工商銀行和中國(guó)銀行,且每張銀行卡只允許綁定一張。利用v-charts組件把個(gè)人的時(shí)間段的消費(fèi)情況以條形圖展現(xiàn)給用戶觀看。
    & O+ ^4 t/ V9 ~2 X( t2 b2 K+ l7 a* Y* f) U- c" d1 M) X0 l
    $ }8 u  ^* d" ?9 v
      w2 l: @7 [) T0 Z1 ]  V
    ! t& G9 j. G6 ~" y
    0 m  ]% G2 O, W# ?6 Y& ?5 T! M

    9 c" Z* |* P3 B+ O) p4 ^) k+ g當(dāng)用戶開通了我的錢包后,可以選擇是否進(jìn)行余額充值,賬戶余額暫時(shí)只可以用支付寶充值。所有關(guān)于金額的操作均需要在后端安全操作,前端只用來顯示數(shù)據(jù),必須使用數(shù)據(jù)庫(kù)中的金額。
    ) A. T3 W. O$ Z
    6 C' X# g& @3 d+ J) A- U( W
    " n9 Z; ^0 A3 Y% L  |9 w1 P
    3 O. Z; x* s; U: e6 Z# g2 c2 h" F1 r/ L, J
    6 e8 l" }! L7 i8 J
    密碼為6位有效數(shù)字,可以使用原密碼更換新支付密碼。
    ; ~! R7 v2 ~4 J- I4 o% b6 ?, K6 h3 U7 ~
    + O9 ~2 K6 y* n% k

    3 Q9 c% \/ j) b  e0 r2 n) ^, x8 R; _5 O  G0 I. _7 M

    . q6 }& L/ S- ]! t" C! Z; N% [7 W  K- w% v
    銀行卡姓名需要與實(shí)名認(rèn)證的姓名一致。
    # V& J# F: ~4 F5 O3 Q1 Y3 ~# `+ O0 v, U( d1 o1 z, ^: ?9 ^

    3 T/ D  Q/ c1 f1 r+ g5 J- r) ]8 H- S4 Q

    $ C6 }$ Q1 C, z5 r3 h. h) x; d' ~: k+ h% G; P! m3 {' E

    4 t$ n( r" B4 r/ y1 R4 _
    9 K5 }: [4 X4 |6 i) }/ Z" h* J; J& W, L5 s1 {4 E: M7 A

    ! z. r. Z- K2 z' h' _" L9 o支付中心包含普通會(huì)員和超級(jí)會(huì)員,由于普通會(huì)員采用支付寶原始的方式,而超級(jí)會(huì)員采用支付寶的二維碼方式,所以兩者會(huì)在調(diào)用的時(shí)候會(huì)有所不用。
    / S3 F* B6 k) t
    % }% c( ]6 h( e7 b3 M9 A2 `( X. o) H% O9 v4 h: M& {# J! p
    ; N" i6 C* [% `8 Z: m  L3 F
    賬單中心是分頁(yè)展示給用戶觀看,提供當(dāng)前頁(yè)面,月份和全部的賬單打印Csv。前端可以直接把后端的數(shù)據(jù)直接打包Csv,也可以自行后端打包Csv數(shù)據(jù)到本地。- ^' T1 w4 O( `$ M: d3 c

    ! i+ `; }# ^" b2 D0 h6 H6 f8 \
      I0 `. z7 M8 c+ A* O+ _) i3 Y( O: h' ]$ {# t* d' S7 u

    / A; s' E# }3 I. o9 e
    ; z; o1 w! D0 i. b. Z
    * A( Y  z0 _: c, I: F/ ?1 i11$ S- a6 U# y! {6 V: w
    用戶的博客中心
    . k! V/ x! i! |: n- U11.1、用戶的訪問主頁(yè)3 O8 F" ?# v8 S3 O% S
    編寫博客是一個(gè)展示自我的機(jī)會(huì),通過這個(gè)機(jī)會(huì),可以增強(qiáng)個(gè)人的表達(dá)能力,還會(huì)結(jié)識(shí)一些五湖四海的博友。通過他人文章的學(xué)習(xí),我們還可以增強(qiáng)個(gè)人的知識(shí)度和眼界。綜上所述,用戶的博客中心是博客系統(tǒng)的最核心功能。8 f' s6 K6 N- G! w$ u+ L( s

    # b& P, l" J) B9 ]. K* |; C+ ?* G用戶可以分享自己的博客動(dòng)態(tài),博客旨在分享自己所學(xué)所知給他人,或者解決他人的困難。博客中心包含發(fā)表博客,查看個(gè)人博客,刪除博客,更新個(gè)人博客。非本人也可以觀看他人的博客,也可以評(píng)論他人的博客,所以需要用到分頁(yè)功能和輪滑加載功能配合前端展示不是私密的博客給他人觀看。每個(gè)用戶所看到的博客都是最新發(fā)的博客,可以與他人進(jìn)行學(xué)習(xí)交流。每個(gè)發(fā)表者要尊重他人的知識(shí)勞動(dòng)成果,切勿抄襲并且發(fā)表不適當(dāng)?shù)奈恼拢鲆幻细竦牟┯选?br /> + Y8 h/ t/ B/ A$ D" n; z% |
    8 R4 c4 x/ }( s, N8 Y6 t當(dāng)用戶輸入賬號(hào)密碼登錄后,可以看到博客的主頁(yè)如下圖所示,主頁(yè)面可以看到發(fā)表人和發(fā)表的文章,點(diǎn)擊文章可以進(jìn)入文章的主頁(yè)面進(jìn)行學(xué)習(xí)交流。9 s" K7 T5 S: }3 o+ D
    + n0 c' G- N: O. G

    2 f8 S& I6 C% }$ Q+ G' j  k  @. t
    # ]6 ]. T& h0 b11.2、用戶的文章中心2 e2 o; W5 B& D$ w% V
    用戶的文章微服務(wù)中心的功能包含發(fā)表,查看,修改,刪除,用戶可以控制自己發(fā)表過的每一篇文章。
    ; O! ~. x8 h: K8 m+ N3 G2 y1 w+ u4 C8 H% s
    6 M* i  z. J, B/ K$ P; r

    ! w+ |& a, |! V5 N9 {0 [0 @- O關(guān)于文章的增刪改會(huì)在后續(xù)標(biāo)題中得到詳解,在此只放出用戶的個(gè)人文章中心由圖可以看出是用戶發(fā)表過的全部文章,后端利用的是先分頁(yè)后List方式,最終傳送前端進(jìn)行ListItem遍歷顯示即可。
    / Y9 v$ D" o! t  j* S/ n4 q
    ' f* ?9 |$ d' |5 W. F' e由于也使用了Elasticsearch把文章分類作為存儲(chǔ)索引,但是重要的文章信息均放在數(shù)據(jù)庫(kù)中,在此只提一下,到后續(xù)的分類搜索中會(huì)詳細(xì)說明。1 y, ?! \2 [. r
    ( m: s/ `1 ~* ~" I* T: P
    11.3、發(fā)表個(gè)人的博客8 r" `4 e& K& I) l+ O
    文章的的發(fā)布有許多選擇,自己可以選擇文章的分類和文章的標(biāo)簽,同樣也可以設(shè)置文章的可見性。用戶可以設(shè)置文章的標(biāo)簽,標(biāo)簽用來顯示給游客看,用來文章的標(biāo)識(shí)認(rèn)證,還可以設(shè)置文章的分類,類型和保密性,每種文章的分類會(huì)發(fā)布到那個(gè)分類的專區(qū)。文章類型有三種,若是轉(zhuǎn)載和翻譯他人的文章需要著名地址,保護(hù)他人的知識(shí)勞動(dòng)成果。只有具備會(huì)員資格才可以發(fā)送到會(huì)員專區(qū),但是轉(zhuǎn)載的文章不可以發(fā)送到會(huì)員專區(qū),發(fā)表文章時(shí)可參考紅字注意事項(xiàng)。
    9 q! M4 e( \# h5 H, b+ [8 b. x# `* `
    0 t# a5 r5 G; r2 z4 B. O
    5 R+ u, D& O- N( @3 @1 k
    博客的發(fā)表的核心原代碼如以下所示:
    8 ]$ [. {# v) G2 V5 u1 O0 a$ d7 O+ k; @; J3 i
  • //獲取文章的摘要markdown格式-html-summaryString words= StringFromHtmlUtil.getString(MDTool.markdown2Html(blogFrontPublish.getArticleContent()));//獲取文章的摘要且摘要長(zhǎng)度為255個(gè)字符String summary = words.length() > 240 ? words.substring(0, 240) + "......" : words;//去除轉(zhuǎn)換后存在的空格String tagTar = blogFrontPublish.getArticleTag().replaceAll(" ", "");//將文章的分類寫入分類表然后再插入整篇文章UserArticleCategory userArticleCategory=userArticleCategoryMapper.findAllByCategoryName(blogFrontPublish.getArticleCategory());if (userArticleCategory==null){    userArticleCategory=new UserArticleCategory();    userArticleCategory.setCategoryArticles("");  userArticleCategory.setCategoryName(blogFrontPublish.getArticleCategory());//返回獲取到的自增ID    userArticleCategoryMapper.insert(userArticleCategory);}//把標(biāo)簽寫入數(shù)據(jù)庫(kù)for (String tag :tagTar.split(",")) {    if (tag.replaceAll(" ", "").length() == 0) {        //單個(gè)標(biāo)簽只含空格        continue;}    UserArticleTag userArticleTag = userArticleTagMapper.findAllByTagName(tag);    if (userArticleTag==null){        userArticleTag=new UserArticleTag();        userArticleTag.setTagName(tag);        userArticleTag.setTagArticles("");        userArticleTagMapper.insert(userArticleTag);}//轉(zhuǎn)換后的值再更新得到文章表的主鍵   userArticleTag.setTagArticles(userArticleTag.getTagArticles()+userArticle.getId()+",");  userArticle.setArticleTagsId(userArticle.getArticleTagsId()+userArticleTag.getId()+",");   userArticleTagMapper.updateTagNameAndTagArticlesById(userArticleTag.getTagName(),userArticleTag.getTagArticles(),userArticleTag.getId());}- U, M$ `$ p+ n3 s! S. x$ B$ v) }
    11.4、修改個(gè)人的博客6 g2 u1 z$ i* p0 U& o, V- M# k
    若是需要修改個(gè)人的博客,需要進(jìn)入圖5-33的個(gè)人博客中心,查看發(fā)表的指定文章進(jìn)入到指定文章的頁(yè)面,點(diǎn)擊編輯按鈕,不是本人的文章不會(huì)出現(xiàn)編輯按鈕,博客的編輯按鈕效果圖如下圖所示:5 s: P5 P3 R/ p) [! L

    & h  p; ~% u$ P, D! N- i3 {0 d6 m' [2 z: V4 q( ]

    ! B) J/ }& |8 h# Y1 j' r可以修改文章的所有的條件與內(nèi)容。
    1 R; ?( X3 k4 Q: g, V0 b% v3 a" P. ?% L  v& j8 w$ R; r# |4 D

    8 y- S# R5 ~3 ?( }8 Q0 j& c& `. k/ d, Y- e- }& |1 T/ e
    文章的發(fā)表與修改的源碼不同在于要?jiǎng)h除之前的原屬文章的分類Id與標(biāo)簽Id的關(guān)聯(lián),再進(jìn)入文章的插入,不過文章的修改也會(huì)觸發(fā)在搜索引擎上的文章信息修改,搜索引擎上的文章信息也會(huì)跟著更新,保持搜索到最新的數(shù)據(jù)。, e7 d1 }$ ?$ K! _

    0 A3 r4 T( g; D1 U$ }; x11.5、刪除個(gè)人的博客
    % E! v, x; Y( ~- b& D: l刪除個(gè)人的博客需要?jiǎng)h除數(shù)據(jù)庫(kù)和搜索引擎上的文章,刪除文章后不可恢復(fù)。! l5 h  }4 ~2 S9 ^4 y+ _

    ; r1 J7 Q9 `$ [! A# ^: ]5 P
    & u/ i3 k1 F& Q) c/ C" ]; S2 F3 ]7 {& X+ s2 t( \5 [. j
    11.6、用戶的文章布局6 K/ x% t& o9 K+ x. t8 u9 X% A
    完整博客的顯示方式是采用GitHub的代碼高亮布局,可以是用戶看到自己的博客是嵌入式的面板,可以給予人一種清爽的感覺。由于采用Vue,可以不用動(dòng)態(tài)渲染html,使用v-html命令就可以把后端傳過來的數(shù)據(jù)利用showdown轉(zhuǎn)換器轉(zhuǎn)換給html直接顯示給用戶看。
    ' F' Y: Y# o: c" x0 A% r
    ' Q4 j4 U! U# s" h! c8 V4 x* u8 p' c* F8 u9 N4 w# Z3 i5 \- r

    . Q8 y4 s8 n  s+ U. N11.7、點(diǎn)贊用戶的文章) F9 W' S# Y+ f0 x
    互聯(lián)網(wǎng)時(shí)代每個(gè)人都或許都點(diǎn)贊過他人分享的文章,本次設(shè)計(jì)是博客所以會(huì)涉及到點(diǎn)贊,當(dāng)用戶太多時(shí)需要考慮到高并發(fā)的情況。正常情況的點(diǎn)贊并不會(huì)給后端造成多大的負(fù)載壓力,如果是熱門的文章博客,用戶點(diǎn)贊與取消點(diǎn)贊,評(píng)論,分享等,對(duì)于后端來說這些都會(huì)帶來巨大的流量,如果后端接口支撐不住,前端得不到響應(yīng),前端無法響應(yīng)就會(huì)返回404,會(huì)導(dǎo)致用戶體驗(yàn)極差。5 q- X1 B, b+ S6 J# r* x5 o
    2 P: Y/ E/ X/ K; l+ A2 O

    4 b) d2 m7 j" @5 Y4 H% n1 y# j# Z! g: A+ p  _' ?$ m) b* {
    由上圖可知,核心的模塊就是點(diǎn)贊與取消點(diǎn)贊,利用Redisson把多個(gè)用戶的請(qǐng)求利用分布式鎖分開請(qǐng)求,利用“緩存”保護(hù)數(shù)據(jù)庫(kù)。若用戶點(diǎn)贊微博,則后端會(huì)先查詢是否存在點(diǎn)贊記錄,當(dāng)存在點(diǎn)贊記錄時(shí),分析是否是完成點(diǎn)贊還是已經(jīng)取消了點(diǎn)贊。若沒存在點(diǎn)贊記錄,則完成數(shù)據(jù)庫(kù)中的點(diǎn)贊記錄更新,再把點(diǎn)贊結(jié)果“緩存”到Redis中,若是取消點(diǎn)贊,則直接會(huì)在“緩存”中刪除,更新數(shù)據(jù)庫(kù)中的結(jié)果。每一篇文章的點(diǎn)贊總數(shù)都是利用“緩存”計(jì)算得到一篇文章的結(jié)果發(fā)送給前端顯示。前面的操作都是利用Redisson操作的,所以當(dāng)高并發(fā)多線程請(qǐng)求時(shí),分布式鎖就會(huì)控制資源的并發(fā)訪問,避免出現(xiàn)文章數(shù)據(jù)不一致的情況。. D( K1 G) }' z0 h4 H" R( K
    " F+ @8 C. k  J% H
    11.8、收藏用戶的文章
    # u& m# i+ B: w' {3 _用戶允許收藏自己的文章,收藏的功能也借用了Redisson的分布鎖來控制收藏的緩存,收藏與博客的點(diǎn)贊功能相似。$ A# r* d8 ^' g# B+ T3 v. S
    ' u$ ^8 j' d8 h# l6 f. q

    ( F/ G  U3 {2 c. u8 L/ c+ A- y
    6 \2 K$ a; v' N" w& u# Y* Q! q; G( T; _/ M, ^; A% p0 M
    8 n. E+ F: t0 `( Z6 Z& N

    8 }8 g6 b* i5 Z: r3 o6 q2 H! {7 H11.9、評(píng)論用戶的文章5 {& X& N$ Z% {* b
    評(píng)論的實(shí)現(xiàn)比較簡(jiǎn)單,一級(jí)評(píng)論的用戶的Id為父Id,只含有一級(jí)評(píng)論與二級(jí)評(píng)論,分頁(yè)直接查看文章的所有評(píng)論。- c2 _0 E6 O$ `" @8 j  a3 ]8 X

    ; V6 x8 R9 j; n' n$ U* e' ^7 u
    # X0 u5 b% A: V% t1 {; x3 R3 C" t6 g
    11.10、博客的文章排行榜
    ) a! n  I% n1 x* _5 S( c文章排行榜采依舊是利用了Redisson,排行榜與標(biāo)題3-7-4的點(diǎn)贊關(guān)聯(lián)緊密,“點(diǎn)贊”會(huì)導(dǎo)致熱流,形成短時(shí)間內(nèi)的超高人氣,把文章的排行榜放給用戶看,可以增強(qiáng)用戶的體驗(yàn)。不是所有的功能都要用分布式鎖,排行榜不需要用到分布式鎖,也不需要控制非常高的高并發(fā)流量,對(duì)于后端來說控制排行榜比較簡(jiǎn)單。3 s$ X5 o2 s  x# V4 A: w
    / S) x( l. n5 e& {
    ) w$ U( @' m9 m9 O$ q8 A0 @2 G

    # @4 L* w) H3 z0 o. W% }, S8 J排行榜需要保證查詢數(shù)據(jù)庫(kù)的點(diǎn)贊表的SQL正確,SQL錯(cuò)誤之后的所有操作都是白費(fèi)力氣,這個(gè)要設(shè)置一定的范圍與時(shí)間差來確保文章的間斷實(shí)時(shí)性,最后要把數(shù)據(jù)庫(kù)中的數(shù)據(jù)放到緩存中。對(duì)于緩存的操作,用戶的點(diǎn)贊與取消點(diǎn)贊都會(huì)觸發(fā)緩存中的排行榜排序。用戶請(qǐng)求后,會(huì)查到緩存中的排行榜點(diǎn)贊數(shù)最多的前10篇文章,利用List的文章Id找到文章的信息,最后打包傳給前端顯示。排行榜算是一種實(shí)時(shí)性要求不算很高的,可以使用定時(shí)的方式主動(dòng)更新緩存中排行榜記錄。: w4 W: d" J) S; d

    * U! y" G% r* k' C0 g* z: W8 k/ P5 R8 p$ ?2 s0 H$ N

    * ~5 b! n& v' i9 g
    5 Q$ K$ e; V9 Q1 u+ K& I& g+ k$ \( _4 G12
    # V9 }( L1 W3 G- h# ~. }博客的搜索中心
    6 C5 U" ]# K5 a2 V6 p12.1、搜索引擎的應(yīng)用
      J0 x% C/ M; H/ x6 X0 S當(dāng)微服務(wù)整合Zipkin時(shí),運(yùn)行系統(tǒng)會(huì)產(chǎn)生大量的API運(yùn)行指標(biāo),而Elasticsearch(ES)作為一種存儲(chǔ)方式,可以把那些運(yùn)行API指標(biāo)存儲(chǔ)到ES中。1 a$ v: B" y( h
    % Y) n8 Z  r- m& G( A0 I! k
    " k9 U4 ?8 y, \) X+ U  a! O9 e

    . O2 A  d, b% ]$ j3 T3 eElasticsearch的index是文檔索引,與數(shù)據(jù)庫(kù)的“庫(kù)”相似,type是文檔類型,與數(shù)據(jù)庫(kù)中的“表”相似,id是一個(gè)字段作為主鍵。% w& G# J$ u' Q. ~6 J6 q
    3 c! k2 n' ~, q
    12.2、博客的分類搜索
    ; }* O  j7 r$ v+ G! G博客的搜索中心包含文章的顯示的信息,例如標(biāo)題和文章內(nèi)容的摘要,由于把文章的整篇內(nèi)容均放到數(shù)據(jù)庫(kù)中,所以搜素引擎上的文章是負(fù)載均衡保存提示的信息,用戶可以根據(jù)搜索界面的搜索框查詢Elasticsearch上文章,根據(jù)的是文章的分類的區(qū)域和關(guān)鍵字,后端判關(guān)鍵字是否符合且存在,然后把結(jié)果傳給前端顯示。# ?& }2 r% M( r" n. D% y
    ( P+ G/ T% f; f7 C# }1 K/ d8 H6 h
    & `( Y' Y. J& l- r9 K6 R; K4 J" e
    * t' ]8 {+ |- W3 Z3 D$ H% X

    ) P) T+ L& e9 Z- \
    6 T; n, x; D& U, v
    " J9 |7 p. r( r( x12.3、博客的分類主頁(yè); N: D% F" T/ n
    博客的分類主頁(yè)是利用Elasticsearch上的文章信息進(jìn)行遍歷,用戶發(fā)表的博客時(shí)候選擇的分類作為Elasticsearch索引的名負(fù)載均衡到Elasticsearch,分類中心的文章每次選擇20篇最新的文章傳給給用戶觀看。
    " s$ ^" B! e; l5 F% b
    / T1 ]' N: {( k( L3 k/ p5 i( g; K- A% i
    6 u1 |* J2 C6 T# _& v& C
    13
      B( ?" o, p8 {' w9 y% F6 D博客的測(cè)試分析7 F+ O: L* X4 C
    13.1、博客的請(qǐng)求抗壓性分析, J! y5 I0 G; D
    博客采用的是前后端的分離模式,所以對(duì)于前端傳過來的Token,后端只要鑒定Redis中存在Token即放行API的請(qǐng)求,同時(shí)前端可以防止表單的多次提交,前端可以增加JS監(jiān)聽Button的提交,也可以使用session鑒定請(qǐng)求的時(shí)間間隔。不過博客大多采用Axios的異步提交,http成功時(shí)可以把Button設(shè)置為true或者直接局部刷新網(wǎng)頁(yè)重置數(shù)據(jù)。對(duì)于博客中的支付中心,另起線程中需要防止出現(xiàn)業(yè)務(wù)出現(xiàn)錯(cuò)誤,或者網(wǎng)絡(luò)錯(cuò)誤導(dǎo)致負(fù)載均衡出現(xiàn)中斷錯(cuò)誤,所以需要catch防止程序出現(xiàn)錯(cuò)誤,同樣還必須保存支付寶異步通知的結(jié)果防止另起線程中出現(xiàn)異常。對(duì)于每個(gè)用戶的請(qǐng)求,可以采用服務(wù)器的限制流量,限制的方向可由個(gè)人選擇,需要在服務(wù)器的圖形化界面中可以設(shè)置。
    9 V" Q; y9 X' _3 P1 s' C$ w* D9 `. v# ?4 k. u: T: g2 W

    2 }( @% V+ ], h0 w* j# T7 Y* u$ o% B! Q% L9 n% W5 Y
    13.2、博客的功能擴(kuò)展性分析1 t/ t& s6 d/ W( L
    博客的前端容易擴(kuò)展,由于Vue本身具有的實(shí)用的數(shù)據(jù)綁定優(yōu)勢(shì),所以前端只要時(shí)間充足就可以隨意擴(kuò)展,還有一個(gè)很重要的原因是安全是后端來控制的。博客后端的每一個(gè)微服務(wù)的中心承擔(dān)著一個(gè)功能模塊,若是發(fā)生不同功能的擴(kuò)充則需要多添加一個(gè)微服務(wù)的中心。當(dāng)功能相同只是擴(kuò)展當(dāng)前的功能,則可以直接在某個(gè)微服務(wù)中心增加代碼即可。編寫博客時(shí)遵守了Java代碼的規(guī)范,為以后的擴(kuò)充打下堅(jiān)實(shí)的基礎(chǔ)。本次博客各個(gè)中心均遵守了Java的代碼規(guī)范,微服務(wù)中的module劃分清晰,功能擴(kuò)充方便。# D( Y2 H! z' N6 z
    ( O" I5 l: ^5 s! ~
    Pom文件中的module劃分如下圖所示:
    : O+ Z- I7 Q' S4 S/ s2 {1 U. Y0 c* u/ J! P* ~" l5 O. l9 w
    : N  Q' W+ l! k8 A3 R, ]0 f5 I% i
    ; G0 E! Y* `$ @$ [  G- z5 O7 a
    項(xiàng)目工程資源請(qǐng)參見:https://download.csdn.net/download/m0_38106923/87849577
    8 M! v* F4 o/ c% O  ~3 P+ N( b+ ^$ g+ g
    $ a+ I( ^+ e5 x2 S3 V
    往期推薦畢業(yè)設(shè)計(jì)So Easy:Java MySQL智能報(bào)紙閱讀器APP應(yīng)用
    . x/ P8 Y9 j# b! Y畢業(yè)設(shè)計(jì)So Easy:基于C++實(shí)現(xiàn)網(wǎng)絡(luò)掃描器% l+ W4 t6 K- M+ s1 E
    畢業(yè)設(shè)計(jì)So Easy:基于Java Web學(xué)生選課系統(tǒng)
    , h2 U3 v& @5 r& w* ?畢業(yè)設(shè)計(jì)So Easy:基于Java語(yǔ)言西餐廳點(diǎn)餐系統(tǒng)
    0 K! k, V) `- N& A8 \0 k. M畢業(yè)設(shè)計(jì)So Easy:珠穆朗瑪FM音頻電臺(tái)APP, x+ h- O4 |$ @  `$ l
    $ ^. d- G( X8 K

    , X1 u  n- _; f0 t4 a* V. L. X  n" ^- I
    8 P( @7 I4 \; A! B3 X7 d" R點(diǎn)擊閱讀原文,更精彩~
  • 發(fā)表回復(fù)

    本版積分規(guī)則


    聯(lián)系客服 關(guān)注微信 下載APP 返回頂部 返回列表