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

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

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

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

[復(fù)制鏈接]

601

主題

601

帖子

4762

積分

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

Rank: 4

積分
4762
跳轉(zhuǎn)到指定樓層
樓主
發(fā)表于 2023-6-28 12:00:00 | 只看該作者 |只看大圖 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
: X! T. c7 D/ Q4 s. W+ X
點(diǎn)擊上方藍(lán)色字體,關(guān)注我們
# F% g3 r' @( Q1 E6 C( O+ ^很多計(jì)算機(jī)專業(yè)大學(xué)生經(jīng)常和我交流:畢業(yè)設(shè)計(jì)沒(méi)思路、不會(huì)做、論文不會(huì)寫(xiě)、太難了......5 K0 C- o$ D& x% o) `! G0 ^0 I

" ~4 }4 X1 p1 `. n! W3 O針對(duì)這些問(wèn)題,決定分享一些軟、硬件項(xiàng)目的設(shè)計(jì)思路和實(shí)施方法,希望可以幫助大家,也祝愿各位學(xué)子,順利畢業(yè)!
( C3 L& N% P1 d) g! g% C4 A4 G  s3 [, k5 p
, b) E/ H5 r2 d6 e6 \" o
, Q3 Q0 R' b  V9 H3 B6 X

: `# }1 ?) Y- ~+ Z. V對(duì)計(jì)算機(jī)技術(shù)感興趣的小伙伴請(qǐng)關(guān)注公眾號(hào):美男子玩編程,公眾號(hào)優(yōu)先推送最新技術(shù)博文,創(chuàng)作不易,請(qǐng)各位朋友多多點(diǎn)贊、收藏、關(guān)注支持~
2 q8 O9 [4 k% }0 v
. z2 u6 D) i6 S9 n項(xiàng)目專欄:https://blog.csdn.net/m0_38106923/category_11085518.html
8 h- w2 L' g5 i! ]( X. j博客是互聯(lián)網(wǎng)的一種分享類(lèi)型的技術(shù)產(chǎn)物,但是如何留著用戶才是重要的,并不都是所有的功能都會(huì)涉及到“高并發(fā)”,博客的功能多樣性會(huì)增強(qiáng)用戶的體驗(yàn),讓用戶對(duì)博客的使用產(chǎn)生依賴性,利用從眾心態(tài)合理地開(kāi)發(fā)增值功能。
  U; k! {% m5 X& {4 Z7 r( }" R
4 D) d* x" _. w本次系統(tǒng)的開(kāi)發(fā)采用了主流的微服務(wù)架構(gòu)方式,所以把控每個(gè)微服務(wù)的功能相互獨(dú)立和完整是“微服務(wù)”系統(tǒng)的關(guān)鍵。由于博客的實(shí)現(xiàn)比較簡(jiǎn)單,所以只有涉及到“高并發(fā)”的時(shí)候需要斷點(diǎn)分析即可,下面將介紹博客系統(tǒng)的一些功能。! O6 Y+ @) T9 e1 f- {% [* Z
( O' Q. y1 z1 q
項(xiàng)目工程資源請(qǐng)參見(jiàn):https://download.csdn.net/download/m0_38106923/878495774 z" q( N  s7 E5 U3 T
1
. ?$ E7 h3 ~* r/ B( P8 d9 W# y項(xiàng)目功能
3 x7 B' s7 Y; s2 e& D$ T6 O. y博客基本的功都具備,例如博客的核心功能:博客的發(fā)表,刪除,瀏覽,評(píng)論,點(diǎn)贊等。除了這些,還可以每天定時(shí)簽到提升博客的等級(jí),充值會(huì)員提升使用體驗(yàn)。" `$ B8 n6 Q8 i
) N; I5 A$ L8 M& {& c
個(gè)人的安全信息也非常重要,所以我單獨(dú)劃分一個(gè)微服務(wù)中心來(lái)實(shí)現(xiàn)。同樣我在每行重要的代碼上都增加了明顯的注釋,這對(duì)于我以后的維護(hù)和擴(kuò)充博客功能可以打下堅(jiān)實(shí)的基礎(chǔ),盡可能地符合軟件設(shè)計(jì)開(kāi)發(fā)原則。
! r. ^. Z* l/ F# A+ Z  h. y1 ^4 W
1 G; c: M' w3 w- |/ a- e: c關(guān)于博客的功能一共涉及到8個(gè)微服務(wù)中心:
  • 用戶的個(gè)人中心:包含登錄、注冊(cè)、智能驗(yàn)證。
  • 用戶的安全中心:安全信息、手機(jī)與郵箱的基本功能和安全認(rèn)證的接口。
  • 用戶的博客中心:發(fā)表和管理個(gè)人的博客,游客可以瀏覽公開(kāi)的博客。
  • 用戶的文件中心:發(fā)表博客需要用到的圖片和個(gè)人用戶的頭像。
  • 用戶的簽到中心:博客的簽到累計(jì)的經(jīng)驗(yàn)值和簽到獎(jiǎng)勵(lì)。
  • 用戶的會(huì)員中心:包含普通會(huì)員和超級(jí)會(huì)員。
  • 用戶的支付中心:VIP的充值功能,個(gè)人錢(qián)包功能,賬單等。
  • 用戶的搜索中心:根據(jù)摘要或者文章標(biāo)題的關(guān)鍵字搜索指定的博客。
      u3 {" G9 V* h6 `$ B[/ol]
    3 U" f4 x2 |/ V, f5 i26 B; r5 M9 e/ u0 D; z
    項(xiàng)目架構(gòu)設(shè)計(jì)
    # D! g; S/ I! I* B 4 T: u- W  }  d3 X

    + {0 M) n- T0 ]從宏觀設(shè)計(jì)來(lái)說(shuō),各個(gè)微服務(wù)中心都是一個(gè)moudle,需要注冊(cè)到一個(gè)高可用的微服務(wù)注冊(cè)中心上保證機(jī)器信息的正確性。8 |3 d5 F2 V+ }) ~/ X
    ; U1 X; H. h+ O+ [: v3 b
    從微觀運(yùn)行來(lái)說(shuō),用戶的請(qǐng)求API都經(jīng)過(guò)Zuul,再由Zuul負(fù)載均衡分配給需要的微服務(wù)中心,所以Zuul也需要高可用保證用戶流量可以得到回應(yīng)。通過(guò)zuul網(wǎng)關(guān)后,請(qǐng)求通過(guò)Feign實(shí)現(xiàn)微服務(wù)之間數(shù)據(jù)的交互。
    0 x' g! P: M- c+ |: D  N, s
    7 K0 c* r4 g/ v/ v; P: c3 U/ t$ I3 p當(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ī)器的集群來(lái)維護(hù)系統(tǒng)的穩(wěn)定運(yùn)行。5 R# w5 O. u, I) K' x
    37 K& ^7 N; I9 f
    項(xiàng)目數(shù)據(jù)庫(kù)設(shè)計(jì)" B1 e; b% C! X! t
    對(duì)于用戶來(lái)說(shuō),需要輸入賬號(hào)和密碼,若是不存在可以注冊(cè)自己的賬號(hào)和密碼。注冊(cè)的時(shí)候提供30分鐘填寫(xiě)博客信息的有效時(shí)間,不填寫(xiě)則直接登錄。需要設(shè)置個(gè)人的手機(jī)和郵箱來(lái)綁定安全認(rèn)證,若想要開(kāi)通我的錢(qián)包則需要實(shí)名注冊(cè),同樣也包含校園認(rèn)證。丟失了個(gè)人信息,則可以用身份證申訴。每天凌晨開(kāi)始可以開(kāi)始簽到,根據(jù)會(huì)員的不同增益不同,簽到的持續(xù)天數(shù)不同經(jīng)驗(yàn)值累加也不同。會(huì)員的開(kāi)通只包含支付寶,賬單是每筆消費(fèi)的記錄。核心表是用戶博客之類(lèi)的表,文章均存在數(shù)據(jù)庫(kù),不過(guò)ElasticSearch也保存了文章的標(biāo)題和摘要。每個(gè)用戶可以評(píng)論他人的文章,私密的文章不會(huì)出現(xiàn),會(huì)員的文章會(huì)出現(xiàn)在會(huì)員專區(qū)。# S  k) m) c% l2 D
      E* Z# }' R" v, y
    博客一共含有8個(gè)主功能,所以一共涉及用戶表,用戶信息表,安全表,頭像表,簽到表,簽到獎(jiǎng)勵(lì)表(兩種獎(jiǎng)勵(lì)),會(huì)員表,錢(qián)包表,訂單表,博客表,博客分類(lèi)表,博客標(biāo)簽表,博客圖片表,博客的評(píng)論表,點(diǎn)贊表和收藏表17個(gè)表。! P/ J' K9 U) j1 q; }
    * S9 \3 s2 h. W

    9 A) m( \; J1 @( X9 J4 h* I9 F; _9 N: ]: J0 Y9 o2 S( w2 z
    4( e0 L4 l/ C* m" ^% _: ?3 I
    項(xiàng)目架構(gòu)實(shí)現(xiàn)
    1 f$ V9 B; H) L% Y; d4.1、Vue架構(gòu)的實(shí)現(xiàn)8 S7 l& B+ N8 h2 K
    前端IDE采用的是WebStorm,博客的Vue主要分布如下圖所示:4 z6 @% ], V$ i/ f
    $ o5 R' N! \- I7 m6 G
    3 e% b" X1 t( c
    $ F7 f" \) ]& t: H7 F
    Alert.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中保存的是博客所用的圖片。; P/ ]/ z7 B  E. F
    不管是用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)。$ d* o6 N0 z2 u. ?& v

    $ C, G+ D7 {+ H1 b& H% z博客項(xiàng)目中的package的完整dependencies代碼如以下所示:/ i+ v. Q1 g, E6 R
    & g9 ^% a' G6 o! t$ Q7 A: {
  • "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" }
    ' l# P. I+ S) n2 C! g+ Z, n4.2、SpringCloud架構(gòu)的實(shí)現(xiàn)- x7 a; I. y/ O, `- o! `% a
    博客Maven的整體微服務(wù)中心實(shí)現(xiàn)的結(jié)構(gòu)圖如下所示:' S/ x5 i* |# H  g" S& e

    : S! g- a8 O6 v: C! M9 v " f4 K7 `) B  g, Q# n
    # ?" O2 P6 }6 i4 D5 O$ D4 ~- L
    SpringCloud是基于Java語(yǔ)言的工具集,SpringCloud具備拿來(lái)就用的特性,可以節(jié)省開(kāi)發(fā)的配置時(shí)間,它可以在Docker等云環(huán)境中開(kāi)發(fā)和部署。SpringCloud的組件比較豐富,博客使用了Eureka,Zuul,F(xiàn)eign,Htsrrix,trubine,Zipkin微服務(wù)組件。組件可以自由地選擇,不過(guò)需要解決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)致兼容不一致。. F+ ~& z; M4 K0 X- j- P! d

    ! l: O- |! N! N0 q2 {8 x4.3、博客的高可用的實(shí)現(xiàn)' X4 @' B1 K: k3 d; _% _' \0 G
    博客使用了兩個(gè)Zuul并且注冊(cè)到高可用的服務(wù)發(fā)現(xiàn)中心來(lái)構(gòu)造Zuul高可用集群。Eureka是所有微服務(wù)的注冊(cè)中心,并且自己本身也是微服務(wù)不過(guò)需要禁止自我注冊(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è)中心圖如下圖所示:5 \9 L1 E4 `; I% g) @0 ^" C9 A
    3 Z1 o2 |9 n1 f' w4 @

    & B0 V0 y8 i* b3 ^, i8 f( N+ W' w, e/ u5 |! n' ?* S
    DS Replicas代表兩個(gè)模塊加載模擬單機(jī)代替高可用的實(shí)現(xiàn),不過(guò)需要修改本地Host來(lái)模擬真實(shí)多機(jī)高可用的效果。每個(gè)微服務(wù)都具有自己的虛擬主機(jī)名以及狀態(tài)來(lái)描繪微服務(wù)的顯示情況。每個(gè)微服務(wù)之間通過(guò)與服務(wù)注冊(cè)中心每30S心跳傳遞保證服務(wù)可用性。默認(rèn)90S沒(méi)有收到心跳則會(huì)注銷(xiāo)該微服務(wù)。EurekaServerOne與EurekaServerTwo為兩個(gè)微服務(wù)注冊(cè)中心,兩者相互注冊(cè)到對(duì)方的服務(wù)中心上來(lái)保證Eureka的高可用穩(wěn)定,從而使每一個(gè)博客的請(qǐng)求都可以得到響應(yīng)。0 x6 U6 ^8 [0 R

    1 l) s1 ~6 k7 ]5+ E* I; N4 x. F. a
    用戶的個(gè)人中心! O  Z0 K: q( d" h
    用戶的個(gè)人中心相當(dāng)于博客的大門(mén),用戶的首次流量都經(jīng)過(guò)此處,首次負(fù)載均衡調(diào)用也是基于這個(gè)中心開(kāi)始,主要涉及到用戶的登錄與注冊(cè)的基本功能,在登錄上排除惡意的攻擊與干擾,保證博客登錄的穩(wěn)定,從而保證系統(tǒng)的穩(wěn)定。這個(gè)中心核心功能就是權(quán)限驗(yàn)證,保持登錄的標(biāo)志,它是保持業(yè)務(wù)穩(wěn)定的重要因素,后續(xù)的實(shí)現(xiàn)會(huì)在以上所述的三個(gè)重要功能展開(kāi)來(lái)講。5 T7 C, X* E- ], }) K

    ; J% v2 Y* b7 a" B# g0 I5.1、登錄的智能驗(yàn)證" a# q. {+ I6 }* T
    Vue整合阿里云智能驗(yàn)證時(shí),需要注冊(cè)布局組件來(lái)動(dòng)態(tài)加載JavaScript文件,不然無(wú)法使用阿里云的智能組件,前端登錄智能驗(yàn)證的核心代碼如以下所示:; ?' i- U- D7 W

    0 [/ g) f) O. K) ]: Z
  • //動(dòng)態(tài)加載阿里云的JavaScript文件src="//g.alicdn.com/sd/nvc/1.1.112/guide.js" @loaded="initCaptcha">
    & B  |% d2 _* I9 X& {//注冊(cè)局部組件來(lái)加載阿里云的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 }                }            }        },* e+ D2 x% e" H
    //點(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# T2 a9 b2 Y0 h( w' z! |
    5.2、博客的登錄注冊(cè). T; d! P4 s3 C5 P- ~8 T# U/ y2 P
    登錄是一個(gè)系統(tǒng)的重要的功能,也是個(gè)人隱私的重要體現(xiàn),拿常見(jiàn)的登錄有郵箱,手機(jī),賬號(hào)或,語(yǔ)音或者二維碼登錄,不過(guò)不管通過(guò)哪種登錄,個(gè)人信息的安全都應(yīng)該得到保護(hù),保護(hù)個(gè)人隱私重要的是從個(gè)人做起,拒絕非法點(diǎn)擊與輸入。
    3 X2 h* T( A! s2 K1 O6 f4 U8 X1 x3 B' f  c, P) E1 i3 `1 t, I
    拿本次博客的登錄來(lái)說(shuō)只需要驗(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中提到,以便后面的博客信息的操作,超過(guò)則需要重新登錄去博客的個(gè)人中心填寫(xiě)博客信息。
    $ [, Q5 |$ h$ d8 D" L$ k博客的登錄與注冊(cè)的頁(yè)面如下圖所示:
    ; f$ A  O2 P; v& O' z6 B5 A# C; o: a- N

    3 \0 V2 l1 f5 M" U& M# J
    7 O( {$ X, i/ n# i博客登錄的用戶名需要以英文子母開(kāi)頭,用戶名和密碼均不可以超過(guò)16位,注冊(cè)保證兩次登錄密碼正確就可,在此不再貼出圖片累述。
    * ~8 e: q% l. P0 C) g4 ?$ Q7 V+ E) |8 s
    5.3、登錄的權(quán)限驗(yàn)證/ F4 n& {$ ^* n
    登陸權(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)證。
    ; ]- A- a9 d9 j+ P- K1 ?; Y$ D) H/ k2 s
    博客使用了前后端攔截器攔截Token(登錄成功的認(rèn)證碼),所以后端需要定義一個(gè)token驗(yàn)證注解,用攔截器攔截系統(tǒng)的url請(qǐng)求,再進(jìn)行攔截用戶的API請(qǐng)求,最后再驗(yàn)證傳過(guò)來(lái)的token與Redis中token值是否一致,效驗(yàn)通過(guò)才可以正常訪問(wèn)。當(dāng)用戶登錄成功博客后,后端返回token數(shù)據(jù)。token具有存在時(shí)間,如果用戶一段時(shí)間后不在線或者操作的話,則token會(huì)失效,用戶保持登錄時(shí),則不會(huì)過(guò)期。# Z- D! D' `  H) _* k; b8 L. l2 T

    : ^6 h1 z; Y5 LRedis中會(huì)以用戶的登錄賬號(hào)作為與token關(guān)聯(lián)的認(rèn)證,有效的token碼可以取出用戶的賬號(hào),然后再進(jìn)行業(yè)務(wù)邏輯。這些redis中的key都可以自行設(shè)置一些時(shí)間,不過(guò)前端只保存token值,二次登錄會(huì)覆蓋Redis中的token值。
    - V$ H6 p: M+ x* }. @  c5 e/ i" H  r% ]8 R  b# Z

    / }! T5 k  _6 d! o2 E" g0 y& x+ j2 l1 p- E' W
    權(quán)限驗(yàn)證相當(dāng)于系統(tǒng)的第一道大門(mén),如今的安全框架越來(lái)越豐富,例如SpringSecurity,Shiro,OAuth等,shiro->security->oauth的上手難度逐漸提升。若是需要對(duì)密碼加密的,可以需根據(jù)個(gè)人開(kāi)發(fā)自行配置使用對(duì)應(yīng)的安全框架。6 S' N! u. F4 G- I, q
    6
    * M3 i. ]7 C# K, D1 G+ Q" P& Z用戶的安全中心
    ) Z  f$ m  ~% c2 X) Z6.1、用戶的安全布局
    - h$ r/ v1 c4 S# ~5 C安全中心包含郵箱,手機(jī),身份證,校園認(rèn)證和其它微服務(wù)中心需要用到的認(rèn)證接口。郵箱采用QQ郵箱,開(kāi)啟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ī)。: U( M. Y% Y1 |' |4 Y& U( P( R- k
    . m3 j; J8 t4 U) k0 m
    - j' @& o* e% P2 x5 ]

    4 s! q. A# {9 X: H安全中心包括用戶的規(guī)則規(guī)章,博客旨在分享自己的動(dòng)態(tài)和經(jīng)驗(yàn)給他人,不可以辱罵他人,以及不遵守國(guó)家的法律法規(guī)。本次博客的其它微服務(wù)中心所需要的手機(jī)認(rèn)證接口均由這個(gè)微服務(wù)中心提供。, T7 w4 t9 f9 }: U$ d, l: R8 D

    " _; v0 P- d$ y4 {6.2、用戶的郵箱注冊(cè)
    6 ]' g  W" Y5 p" v' v8 f9 E博客采用的是免費(fèi)的QQ郵箱,郵箱的yml配置如下:
    $ D5 a% p# t" w  b1 H: }( B
    ) ^0 j) I; R" }; w9 F& e$ b
  • mail:    host: smtp.qq.com    port: 465或587    protocol: smtp    username: 個(gè)人的郵箱    password: 郵箱的SMTP的密碼,可在郵箱的賬戶中開(kāi)啟SMTP服務(wù)    default-encoding: UTF-8    properties:      mail:       debug: true   #控制臺(tái)開(kāi)啟運(yùn)行日志: w. c1 J) p& Q/ w* |
    QQ郵箱(郵箱與手機(jī)的六位驗(yàn)證碼共用)發(fā)送驗(yàn)證碼按鈕的原代碼如以下所示:
    - O& g* o% N- F" `
    % n/ d+ [5 _  p" y; E( P$ U- g
  • //自動(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();}
    - j5 F0 d; {& u( C) o/ r5 p綁定QQ郵箱JavaScript的代碼如以下所示:
    ; O! T+ W5 ?1 l: B/ ^! v) ^2 {9 G- a9 n! X" v1 [9 @
  • //綁定郵箱的發(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);                      }                  })              }          }
    3 ^  C! I# K/ |9 b4 x- h  J/ f; w后端發(fā)送QQ郵箱注冊(cè)的驗(yàn)證碼如以下所示:
    2 V7 s  z$ n# [6 o7 h
    + B* d- C) p- j. [+ h4 j1 X4 c6 s
  • //后端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);
    % s" Y/ a* n& l8 a. a4 \- V) |//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);) Y; U) H" b7 z+ x% Z% E
        //開(kāi)啟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);}
    # _8 z+ V/ X0 y7 y- L9 C0 J" Y6.3、用戶的手機(jī)注冊(cè)
    , o- m1 t3 V& w2 \% E. r6 ^發(fā)動(dòng)短信的前端JavaScript的代碼如以下所示:
    & g# l& Q% v; O- a* o/ q* l
  • //前端綁定手機(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);}})}}
    , A7 l: ~5 l# ~( H) p" ]( |$ k5 k2 F
    后端發(fā)送驗(yàn)證碼的代碼如以下所示:
    6 r& N! E- t9 w- }( g3 t5 G! @' K$ X! Q7 Z
  • //生成手機(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();}        //開(kāi)啟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);}
    ! Q! j3 Y8 F: m6 X6.4、用戶的安全認(rèn)證5 ?) ^: {; U; V2 h
    提供安全的認(rèn)證有身份認(rèn)證與校園認(rèn)證,當(dāng)然只是表單的提交,真實(shí)的認(rèn)證需要有關(guān)部門(mén)的配合,在此只是用來(lái)模擬,校園認(rèn)證需要與身份證的名字保持一致,否則無(wú)法通過(guò)。' r% k# _' I2 g) P6 x% t

    # R# J3 J9 I! X: ?  C 9 C6 X! D5 N1 q

      |9 Y5 v; S7 }; L* \$ ]: v( R4 m" j% @9 a5 N7 \6 g% L1 t+ _
    4 B: b2 |# H% `4 i( ~) o
    8 q) c! Y: r* Y* z- Z& j  v* v
    6.5、用戶的密碼安全
    ; V. a& `8 Z# n% b# N當(dāng)個(gè)人安全賬號(hào)發(fā)生異常,可以提供修改密碼,也可以重置密碼。# q7 `0 ]9 x% E
    8 T1 V" O# M$ f" Y7 M* Y

    ; |' S  u2 W4 _: U' Q% r& K1 B. [

    ) H/ _& ?! f$ L6 P
    ' [3 b1 [+ U* E- U/ p0 [& ?& W
    9 ?5 H) V. c# A  D  p- w0 L  u# C6.6、用戶的賬號(hào)申訴9 s& k( S# Y) n1 t+ S
    可以使用手機(jī)號(hào)重置郵箱,也可以使用舊手機(jī)號(hào)更換新手機(jī)號(hào)。如果個(gè)人博客的手機(jī)號(hào)安全信息被盜取,手機(jī)號(hào)也可以被重置,但是需要借助身份證申訴,不過(guò)一天只可以成功申訴一次。
    $ }* M& }' p/ x3 I0 i$ x  l0 M! `8 {; X+ q; A7 R. d+ d* s

    5 b! R- C* ^' [4 r
    5 l5 Q3 n4 a( Q# d76 q2 ]  ~# f3 A- a; h7 g
    用戶的文件中心& k+ g, N, o2 \6 Q
    7.1、用戶的頭像存儲(chǔ)
    0 L. e& P6 p" ^/ g當(dāng)用戶注冊(cè)的時(shí)會(huì)需要選擇個(gè)人的頭像,上傳的頭像只能是JPG格式且大小不能超過(guò)2MB,且上傳前會(huì)先查詢數(shù)據(jù)庫(kù)中的頭像圖片名是否已經(jīng)存在,存在的話直接會(huì)先刪除OSS中舊圖片,再插入新圖片,如果不存在的話,直接插入到OSS文件服務(wù)器中。頭像的存儲(chǔ)流程由前端發(fā)起file傳給后端,后端接受file頭像,利用二進(jìn)制傳給OSS文件服務(wù)器。服務(wù)器再傳過(guò)來(lái)頭像的外網(wǎng)URL地址,此時(shí)修改顯示時(shí)間為10年再返還給用戶,最后把頭像外網(wǎng)URL地址保存到自己的LocalStorage本地。& ?* \$ W: ]1 o

    # y' w( B( T( k0 ]: X 9 M6 r, P9 y/ J

    4 L% F) \2 X' X* Z/ k2 m# w) {7.2、博客的圖片存儲(chǔ)
      M- U# ]0 r1 H: R6 X7 {* `9 v發(fā)表博客時(shí)文章中會(huì)包含圖片,前端獲取后端的博客圖片url綁定在前端文章中顯示,同樣url也在文章內(nèi)容中一起保存到數(shù)據(jù)庫(kù)中。上傳圖片和上傳頭像不同,文章需要用到的圖片可以有多張,不存在覆蓋問(wèn)題。需要根據(jù)個(gè)人的文件服務(wù)器的存儲(chǔ)量來(lái)權(quán)衡上傳圖片大小。) N" q. I1 M) T9 s7 G9 Q5 h2 P
    3 r& z1 Y! x% ~  N) S2 b

    7 O% _# ]! \# G1 x. F2 ^. |# X
    . u3 @$ U9 B2 N+ @/ U% E; ^$ f
    8 l/ S3 a2 w+ O/ L" D8
    " j8 p9 x7 D$ q% d" \8 {. l$ Z用戶的簽到中心
    0 F/ E% o: ^% I  ^用戶的簽到等級(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)致不同的疊加效果。
    % X9 h, O2 N5 ]# L) F) a* N8 L  O7 f+ M
    每天0點(diǎn)之前只能簽到一次,過(guò)完0點(diǎn)后Redis中限時(shí)憑證失效既可以再次簽到,簽到的經(jīng)驗(yàn)值采用二分查找和快速排序算法進(jìn)行計(jì)算最后的排名返還給用戶。' [: I+ [9 m" K0 A" W$ o8 Z' `
    / x& B4 @7 D! i; G' o4 Z; S  O
    簽到按鈕的計(jì)算代碼如以下所示:
      R4 f: ?: j  x9 @& T. t9 ]2 b4 V! C- W' v& p7 ~: W: Z! K; Q
  • //先判定是否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中的簽到過(guò)期時(shí)間                jedis.set(id.toString(), "今天簽到已經(jīng)完成!");                jedis.expire(id.toString(), total);                return SUCCESS;            } catch (ParseException e) {                e.printStackTrace();}        }        return FAILED;3 J6 |; h, o; r/ O. I
    經(jīng)驗(yàn)值的排名的代碼如以下所示:
    % ?# o0 h# U$ J- G: j
    ' P+ z! m2 i5 m0 Z$ f: w4 s  _) m
  • //先查詢所有的經(jīng)驗(yàn)值        ListexAll=userSignMapper.selectExperience();        //先將List集合轉(zhuǎn)為L(zhǎng)ong[]數(shù)組        Long[] a=exAll.stream().toArray(Long[]::new);        //可以使用轉(zhuǎn)換工具類(lèi),也可以自己動(dòng)手寫(xiě)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;
    7 G3 P9 }( Y4 J7 `. x# U6 F+ U* M98 s3 k) C5 Y7 L* U$ X% ^
    用戶的會(huì)員中心, |, k7 }/ N! u+ K
    由于會(huì)員中心與支付中心聯(lián)系比較密切,所以兩者的中心可以結(jié)合起來(lái)看作一個(gè)中心來(lái)觀看。用戶的會(huì)員中心包括普通會(huì)員和超級(jí)會(huì)員,每種方式存在三種收益方式,年費(fèi)季費(fèi)和月費(fèi),支付成功后均由負(fù)載均衡執(zhí)行業(yè)務(wù)邏輯。由于支付不屬于這個(gè)module中,所以這個(gè)module只是由其它微服務(wù)調(diào)用直接完成業(yè)務(wù)邏輯。
    " H) _" _& Q- {+ v) t
    3 J8 z5 |- W2 k ! x; w. R" `' `' C) d7 N5 i2 f

    9 X2 t2 j: l! t- v* ~' {+ h/ h10
    % t- j+ ~6 ^  P( D* f1 x  x用戶的支付中心3 p: D( p; |3 g6 N
    未完成實(shí)名認(rèn)證時(shí)頁(yè)面會(huì)轉(zhuǎn)到實(shí)名認(rèn)證中,當(dāng)完成實(shí)名認(rèn)證時(shí),首次進(jìn)入我的錢(qián)包中心會(huì)觸發(fā)設(shè)置支付密碼,當(dāng)設(shè)置成功后,支付以及綁定個(gè)人銀行卡均需要用到支付密碼。可以用舊支付密碼修改新密碼,也可以手機(jī)重置手機(jī)密碼。還可以綁定自己的銀行卡,需要有關(guān)部門(mén)的配合。本次博客只允許建設(shè)銀行,工商銀行和中國(guó)銀行,且每張銀行卡只允許綁定一張。利用v-charts組件把個(gè)人的時(shí)間段的消費(fèi)情況以條形圖展現(xiàn)給用戶觀看。# u% k* z! W% n% g4 i& Y

    5 L/ Z' d7 n+ T6 x3 b$ I
    " j0 T" Y9 y- J! g5 j: \2 t9 L! u  H
    9 k% g: O! N0 k6 @  r, p

    % U0 g" W# }% Y% h
    + l0 N: z8 _9 j, |( k當(dāng)用戶開(kāi)通了我的錢(qián)包后,可以選擇是否進(jìn)行余額充值,賬戶余額暫時(shí)只可以用支付寶充值。所有關(guān)于金額的操作均需要在后端安全操作,前端只用來(lái)顯示數(shù)據(jù),必須使用數(shù)據(jù)庫(kù)中的金額。% B0 K* w6 L) |- S% u; Y
    : m) I; a& _" p) ^# t
    : n5 n+ I0 C) s0 b8 J& m
    7 x" U3 F8 L- d7 `; p; i6 L
    % c/ i& C7 U) ^) |5 H: _

    % b( @( U- ]$ b" f7 W* x密碼為6位有效數(shù)字,可以使用原密碼更換新支付密碼。
    6 ?$ k) u: j: t/ n0 `* C+ p9 n1 X3 R0 Y
    # Y# u& H0 D" X6 n. _2 R3 [$ T: k

    # `5 q1 s3 F+ k/ F8 p; _8 k
    6 `! D  d! v$ x6 C
    ! O$ \* u# s8 B) r- F( I' {  p; d. X, X+ u
    銀行卡姓名需要與實(shí)名認(rèn)證的姓名一致。
    # v* J% [" O2 g7 |; r' Y8 k
    ! h) g" p  W6 I  [, y9 T! Z5 r7 T2 h: O6 K& d, o7 B* U6 M

    ' Q$ N! H! e. [  C$ F3 |$ Y9 v3 _' |; D/ n' y! _) w, ?* b
    2 i2 N. s6 g! X+ B

    ! o% H( ^9 T5 {( m0 l+ B9 |
    1 H2 F% V5 y/ E) R1 \
    $ E- m+ }! Z* B2 J) P+ v4 J2 ~
    + }: v9 q. L2 O支付中心包含普通會(huì)員和超級(jí)會(huì)員,由于普通會(huì)員采用支付寶原始的方式,而超級(jí)會(huì)員采用支付寶的二維碼方式,所以兩者會(huì)在調(diào)用的時(shí)候會(huì)有所不用。
    6 n( ?4 D9 V: F4 O" I+ |' |" p4 K+ p# s7 c; k
    ; d7 i8 I0 G+ E/ @

    3 t. n9 _# \* r% E6 U) J賬單中心是分頁(yè)展示給用戶觀看,提供當(dāng)前頁(yè)面,月份和全部的賬單打印Csv。前端可以直接把后端的數(shù)據(jù)直接打包Csv,也可以自行后端打包Csv數(shù)據(jù)到本地。
    & g$ c# _6 }/ _: I0 {
    3 ~+ T$ }! T. E0 C& j, ^4 d$ O. `& I  ]- M1 _" g% y( I
    ( S2 K  E: t0 I2 f3 `) \3 ?% J& _! n1 j
    2 q3 f  d, ]/ i3 q. _! X, L

    8 H0 q0 j* d) \/ G, `1 o; u1 P, R, @# c8 m& y) f6 B3 |) w% D& F' q3 P4 A
    11
    ! i* f5 f5 U, `$ J7 \( o! `用戶的博客中心0 K, C' t! \+ L1 b' h8 Q: a" h! ?$ y5 r
    11.1、用戶的訪問(wèn)主頁(yè)
    * X. D' X2 z% g( Y" t4 a編寫(xiě)博客是一個(gè)展示自我的機(jī)會(huì),通過(guò)這個(gè)機(jī)會(huì),可以增強(qiáng)個(gè)人的表達(dá)能力,還會(huì)結(jié)識(shí)一些五湖四海的博友。通過(guò)他人文章的學(xué)習(xí),我們還可以增強(qiáng)個(gè)人的知識(shí)度和眼界。綜上所述,用戶的博客中心是博客系統(tǒng)的最核心功能。
    4 G( ?( y/ }4 |) P% W% f3 N1 S
    * ?- U7 ]$ G( h- x! [用戶可以分享自己的博客動(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ù)奈恼,做一名合格的博友?font class="jammer">8 x( U! B7 C, ~& O: I4 y0 ~
    ) y8 _, T; ]# h' N+ g$ D8 c
    當(dāng)用戶輸入賬號(hào)密碼登錄后,可以看到博客的主頁(yè)如下圖所示,主頁(yè)面可以看到發(fā)表人和發(fā)表的文章,點(diǎn)擊文章可以進(jìn)入文章的主頁(yè)面進(jìn)行學(xué)習(xí)交流。
    # i6 Q3 P* G6 e, Q1 [( I& s% i3 ^. t
    - q8 K- v. ]2 |

    1 r- g2 l4 J- ]. ^3 K0 I) q! J11.2、用戶的文章中心
    " J, o) v+ s" j用戶的文章微服務(wù)中心的功能包含發(fā)表,查看,修改,刪除,用戶可以控制自己發(fā)表過(guò)的每一篇文章。/ Q$ O# [% h% I; @
    # Y4 T* y0 J; [9 W; _

    0 H$ Z( ]% p- {: [) S
    $ A  y2 T4 X. V關(guān)于文章的增刪改會(huì)在后續(xù)標(biāo)題中得到詳解,在此只放出用戶的個(gè)人文章中心由圖可以看出是用戶發(fā)表過(guò)的全部文章,后端利用的是先分頁(yè)后List方式,最終傳送前端進(jìn)行ListItem遍歷顯示即可。
    " G8 G6 A5 N- @6 d3 A1 S
    . |/ f$ |. n0 u0 M4 R由于也使用了Elasticsearch把文章分類(lèi)作為存儲(chǔ)索引,但是重要的文章信息均放在數(shù)據(jù)庫(kù)中,在此只提一下,到后續(xù)的分類(lèi)搜索中會(huì)詳細(xì)說(shuō)明。
    ; Y0 r% a2 b$ F6 w" G  o6 Z0 H/ i7 Z
    11.3、發(fā)表個(gè)人的博客
    " A/ z9 @; }5 N0 i" d: Y' l文章的的發(fā)布有許多選擇,自己可以選擇文章的分類(lèi)和文章的標(biāo)簽,同樣也可以設(shè)置文章的可見(jiàn)性。用戶可以設(shè)置文章的標(biāo)簽,標(biāo)簽用來(lái)顯示給游客看,用來(lái)文章的標(biāo)識(shí)認(rèn)證,還可以設(shè)置文章的分類(lèi),類(lèi)型和保密性,每種文章的分類(lèi)會(huì)發(fā)布到那個(gè)分類(lèi)的專區(qū)。文章類(lèi)型有三種,若是轉(zhuǎn)載和翻譯他人的文章需要著名地址,保護(hù)他人的知識(shí)勞動(dòng)成果。只有具備會(huì)員資格才可以發(fā)送到會(huì)員專區(qū),但是轉(zhuǎn)載的文章不可以發(fā)送到會(huì)員專區(qū),發(fā)表文章時(shí)可參考紅字注意事項(xiàng)。5 E3 u* i' Y/ t0 {- @. r' N
    : |* ?& h. a: a- p' W/ j& u
    ( P; Z3 p1 j$ {+ z, {

    + ]. ^3 j" u* _9 c博客的發(fā)表的核心原代碼如以下所示:6 r7 z" S# P# _
    6 T; E. j" s3 a+ E9 x, V" ~' G8 K
  • //獲取文章的摘要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(" ", "");//將文章的分類(lèi)寫(xiě)入分類(lèi)表然后再插入整篇文章UserArticleCategory userArticleCategory=userArticleCategoryMapper.findAllByCategoryName(blogFrontPublish.getArticleCategory());if (userArticleCategory==null){    userArticleCategory=new UserArticleCategory();    userArticleCategory.setCategoryArticles("");  userArticleCategory.setCategoryName(blogFrontPublish.getArticleCategory());//返回獲取到的自增ID    userArticleCategoryMapper.insert(userArticleCategory);}//把標(biāo)簽寫(xiě)入數(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());}0 O# g. R: D! G( A( d3 N
    11.4、修改個(gè)人的博客1 v" c  S# a2 v1 s8 @$ [3 y- B
    若是需要修改個(gè)人的博客,需要進(jìn)入圖5-33的個(gè)人博客中心,查看發(fā)表的指定文章進(jìn)入到指定文章的頁(yè)面,點(diǎn)擊編輯按鈕,不是本人的文章不會(huì)出現(xiàn)編輯按鈕,博客的編輯按鈕效果圖如下圖所示:% }+ a3 N9 T9 Q+ M9 [

    ! Z" a7 P# A& P5 M! c/ a+ @% s9 l& X
    1 k1 ^3 T! `' t) T. R
    . `$ m0 M# c# f" h可以修改文章的所有的條件與內(nèi)容。
    2 o' P" m; A5 X
    : T8 b0 r1 _/ l$ T
    + y4 ^) z+ q5 n1 u( B$ @8 N4 l9 u" I0 z4 A
    文章的發(fā)表與修改的源碼不同在于要?jiǎng)h除之前的原屬文章的分類(lèi)Id與標(biāo)簽Id的關(guān)聯(lián),再進(jìn)入文章的插入,不過(guò)文章的修改也會(huì)觸發(fā)在搜索引擎上的文章信息修改,搜索引擎上的文章信息也會(huì)跟著更新,保持搜索到最新的數(shù)據(jù)。
    $ o8 l6 m& A( F& B7 X, K1 ]# a# T3 A0 T1 Q
    11.5、刪除個(gè)人的博客
    8 ^5 h: K' z1 ~# {3 S0 H% v刪除個(gè)人的博客需要?jiǎng)h除數(shù)據(jù)庫(kù)和搜索引擎上的文章,刪除文章后不可恢復(fù)。
    5 f4 s1 ?; Q/ @5 T9 q. M+ x/ |
    % n' ~: T7 w% X2 O
    + |3 m3 l1 z4 X8 p4 a6 Y4 x
    ) s. L' T9 K9 i+ v( {11.6、用戶的文章布局8 }7 m8 A* c- l$ j
    完整博客的顯示方式是采用GitHub的代碼高亮布局,可以是用戶看到自己的博客是嵌入式的面板,可以給予人一種清爽的感覺(jué)。由于采用Vue,可以不用動(dòng)態(tài)渲染html,使用v-html命令就可以把后端傳過(guò)來(lái)的數(shù)據(jù)利用showdown轉(zhuǎn)換器轉(zhuǎn)換給html直接顯示給用戶看。( f# l6 W! K7 m7 q/ o7 B- j0 t

    ; W3 d; z% ?+ p% s2 M3 q+ X. f9 b! u1 x6 @$ ~" Z) N) U" Q  x
    * ?8 R* n& b: K, v. k6 A% }5 {' V
    11.7、點(diǎn)贊用戶的文章
    , P# Y) a- w4 p互聯(lián)網(wǎng)時(shí)代每個(gè)人都或許都點(diǎn)贊過(guò)他人分享的文章,本次設(shè)計(jì)是博客所以會(huì)涉及到點(diǎn)贊,當(dāng)用戶太多時(shí)需要考慮到高并發(fā)的情況。正常情況的點(diǎn)贊并不會(huì)給后端造成多大的負(fù)載壓力,如果是熱門(mén)的文章博客,用戶點(diǎn)贊與取消點(diǎn)贊,評(píng)論,分享等,對(duì)于后端來(lái)說(shuō)這些都會(huì)帶來(lái)巨大的流量,如果后端接口支撐不住,前端得不到響應(yīng),前端無(wú)法響應(yīng)就會(huì)返回404,會(huì)導(dǎo)致用戶體驗(yàn)極差。& k0 t- n) y/ ]* {! M  M' h

    # M  @" O. m. J! J- S) d9 Y+ ]+ H; e$ B* y! a" ?* o8 ?/ y5 L0 M5 Q

    . o1 F4 M  z* S2 t  z由上圖可知,核心的模塊就是點(diǎn)贊與取消點(diǎn)贊,利用Redisson把多個(gè)用戶的請(qǐng)求利用分布式鎖分開(kāi)請(qǐng)求,利用“緩存”保護(hù)數(shù)據(jù)庫(kù)。若用戶點(diǎn)贊微博,則后端會(huì)先查詢是否存在點(diǎn)贊記錄,當(dāng)存在點(diǎn)贊記錄時(shí),分析是否是完成點(diǎn)贊還是已經(jīng)取消了點(diǎn)贊。若沒(méi)存在點(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ā)訪問(wèn),避免出現(xiàn)文章數(shù)據(jù)不一致的情況。' j# c% Y* d8 K; x9 Q
    5 Q: S. c; m2 J; h$ H% P1 P, t
    11.8、收藏用戶的文章
    " f$ O" k* W5 f9 c1 N: P用戶允許收藏自己的文章,收藏的功能也借用了Redisson的分布鎖來(lái)控制收藏的緩存,收藏與博客的點(diǎn)贊功能相似。
    % r9 V6 J) q& c# @
    2 w8 f8 b4 _  O% J' K# e. p# V% S7 y0 k+ K: G" ?2 W
    4 g3 ]6 V1 e  W# L

    ' i* B: X- h) V
    ' V# l5 ^/ n  g; h" ~1 z3 o: c5 w# Q( t1 I( b0 i$ B. O9 h7 k
    11.9、評(píng)論用戶的文章
    2 J' G2 B. G, o9 c評(píng)論的實(shí)現(xiàn)比較簡(jiǎn)單,一級(jí)評(píng)論的用戶的Id為父Id,只含有一級(jí)評(píng)論與二級(jí)評(píng)論,分頁(yè)直接查看文章的所有評(píng)論。- ?# h; q4 y7 S9 b  `: r

    9 g( f3 i% x/ y9 n9 u! ~2 o) {# E: t; I' w

    - ?4 ^( J4 h: b! _5 q! ?2 K11.10、博客的文章排行榜0 u1 Q. ?! v& F& e8 t- {0 [/ X
    文章排行榜采依舊是利用了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ì)于后端來(lái)說(shuō)控制排行榜比較簡(jiǎn)單。, G7 h# j0 w" ^! l3 g+ m% v
      A+ n8 f  O. {* T" N/ S- B
    5 E1 H; {) Q$ Q! }. w% V

    ' [! P" x5 D2 S- g% \排行榜需要保證查詢數(shù)據(jù)庫(kù)的點(diǎn)贊表的SQL正確,SQL錯(cuò)誤之后的所有操作都是白費(fèi)力氣,這個(gè)要設(shè)置一定的范圍與時(shí)間差來(lái)確保文章的間斷實(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)更新緩存中排行榜記錄。
    ; h8 \7 `8 k! I+ O  N- ~' A5 u% E/ m
    + H9 V2 q8 |+ Z* N( J+ q/ ~

    ) p7 p1 U5 Q, I2 e6 e
    , F# |( [8 w3 n8 \7 w  l12
    0 T* x3 Y% [  [  R! E# m% @博客的搜索中心
    & w3 X; j" j. P12.1、搜索引擎的應(yīng)用
    % ]- t' E' `/ \9 W6 i9 @( U8 J當(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中。' }% I0 t; \/ L# X9 S% W4 ~

    ) D7 ]2 q+ U1 R' y( y6 l( x% r
    ! Y  @+ w! ]+ t- |) L, _8 q' P  a$ F' |' b- Z: u, N# b  @
    Elasticsearch的index是文檔索引,與數(shù)據(jù)庫(kù)的“庫(kù)”相似,type是文檔類(lèi)型,與數(shù)據(jù)庫(kù)中的“表”相似,id是一個(gè)字段作為主鍵。9 x% k6 O. C$ {  k
    8 i% k0 X: P5 E/ x2 O
    12.2、博客的分類(lèi)搜索- I+ i- t1 a- \# R
    博客的搜索中心包含文章的顯示的信息,例如標(biāo)題和文章內(nèi)容的摘要,由于把文章的整篇內(nèi)容均放到數(shù)據(jù)庫(kù)中,所以搜素引擎上的文章是負(fù)載均衡保存提示的信息,用戶可以根據(jù)搜索界面的搜索框查詢Elasticsearch上文章,根據(jù)的是文章的分類(lèi)的區(qū)域和關(guān)鍵字,后端判關(guān)鍵字是否符合且存在,然后把結(jié)果傳給前端顯示。
    4 ?7 `% O0 P1 T% @8 P4 X! t  K9 o
    * {+ k; p9 L+ [2 [5 v- @( A" q

    ! N* k6 f) c3 f* }- J: m6 ?$ g7 z; O* v* a' a
    / s$ d; q  l3 R8 \: z

    , ]3 F3 e7 U- U12.3、博客的分類(lèi)主頁(yè)
    ) L9 i1 v  w, S7 z$ {博客的分類(lèi)主頁(yè)是利用Elasticsearch上的文章信息進(jìn)行遍歷,用戶發(fā)表的博客時(shí)候選擇的分類(lèi)作為Elasticsearch索引的名負(fù)載均衡到Elasticsearch,分類(lèi)中心的文章每次選擇20篇最新的文章傳給給用戶觀看。, V. Y9 E3 s- `" q3 k+ H2 ?: T

    9 x+ N/ [- ~4 {) @9 H; f2 @7 L1 ^4 Y
    / Y, c. ~1 ?3 G# ?4 ^- O
    13
    ( D, o% u1 `5 X3 \& F  ?博客的測(cè)試分析4 `( [' n, V" ?0 F
    13.1、博客的請(qǐng)求抗壓性分析
    0 ~9 v9 d: W7 ]% z博客采用的是前后端的分離模式,所以對(duì)于前端傳過(guò)來(lái)的Token,后端只要鑒定Redis中存在Token即放行API的請(qǐng)求,同時(shí)前端可以防止表單的多次提交,前端可以增加JS監(jiān)聽(tīng)Button的提交,也可以使用session鑒定請(qǐng)求的時(shí)間間隔。不過(guò)博客大多采用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è)置。$ }& E2 ^5 R( [' o
    0 f1 F1 E2 Q, A9 c* E2 d
    9 }# E7 T$ t# i5 q, ]

    3 \4 k# c7 \7 j6 i; O13.2、博客的功能擴(kuò)展性分析9 o  W: G9 T7 j" V
    博客的前端容易擴(kuò)展,由于Vue本身具有的實(shí)用的數(shù)據(jù)綁定優(yōu)勢(shì),所以前端只要時(shí)間充足就可以隨意擴(kuò)展,還有一個(gè)很重要的原因是安全是后端來(lái)控制的。博客后端的每一個(gè)微服務(wù)的中心承擔(dān)著一個(gè)功能模塊,若是發(fā)生不同功能的擴(kuò)充則需要多添加一個(gè)微服務(wù)的中心。當(dāng)功能相同只是擴(kuò)展當(dāng)前的功能,則可以直接在某個(gè)微服務(wù)中心增加代碼即可。編寫(xiě)博客時(shí)遵守了Java代碼的規(guī)范,為以后的擴(kuò)充打下堅(jiān)實(shí)的基礎(chǔ)。本次博客各個(gè)中心均遵守了Java的代碼規(guī)范,微服務(wù)中的module劃分清晰,功能擴(kuò)充方便。
    0 u  O1 L/ I/ ]+ @$ L9 b3 S3 l1 ~+ l$ b1 C
    Pom文件中的module劃分如下圖所示:
    % q; `; W% J7 e$ I$ f% Z
    / U$ o4 a' E3 {2 `+ J4 Z) l
    ! Y0 S- R/ ?3 J7 I1 [% V& O- {8 v# H1 k4 Y5 o. l
    項(xiàng)目工程資源請(qǐng)參見(jiàn):https://download.csdn.net/download/m0_38106923/87849577
    " _9 Z; g0 _0 k& |" S
    ! T7 H0 P9 x7 \0 q
    2 R5 s' N7 n- D) J1 H( a! e往期推薦畢業(yè)設(shè)計(jì)So Easy:Java MySQL智能報(bào)紙閱讀器APP應(yīng)用
    6 S: Y2 ]- Z. @' H1 w畢業(yè)設(shè)計(jì)So Easy:基于C++實(shí)現(xiàn)網(wǎng)絡(luò)掃描器
    ; r% g" g) \* r畢業(yè)設(shè)計(jì)So Easy:基于Java Web學(xué)生選課系統(tǒng)
    $ u1 ^3 P0 y) @4 L+ N畢業(yè)設(shè)計(jì)So Easy:基于Java語(yǔ)言西餐廳點(diǎn)餐系統(tǒng)
    ! b- f- o% o4 m6 O0 S畢業(yè)設(shè)計(jì)So Easy:珠穆朗瑪FM音頻電臺(tái)APP4 b3 D* _  \6 _, o$ t2 l

    + F! \# [, C1 b2 `& k# a* ]. Y6 m5 A9 X# c3 _- W8 T0 X1 \

    - o- d% c. o7 y; E1 a0 `/ f# q點(diǎn)擊閱讀原文,更精彩~
  • 發(fā)表回復(fù)

    本版積分規(guī)則


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