電子產(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覽 |閱讀模式
1 Z! ?8 ^- m2 u: L9 j2 g
點(diǎn)擊上方藍(lán)色字體,關(guān)注我們6 _! Y, \7 t4 E6 l% c# x2 X% v
很多計(jì)算機(jī)專(zhuān)業(yè)大學(xué)生經(jīng)常和我交流:畢業(yè)設(shè)計(jì)沒(méi)思路、不會(huì)做、論文不會(huì)寫(xiě)、太難了......
  o- e5 J" J9 v  W# h/ [* t% W  C' \( Z% m
針對(duì)這些問(wèn)題,決定分享一些軟、硬件項(xiàng)目的設(shè)計(jì)思路和實(shí)施方法,希望可以幫助大家,也祝愿各位學(xué)子,順利畢業(yè)!
. F% ?5 x) Z! q" m  ]4 q; L: E" v
3 I( g8 c2 b$ x
! B4 P4 O3 X3 u5 V) q" ^1 @0 B4 l+ T/ k, }; k/ }& R! Z

, t, t+ a& N& Q* G! U( X. V對(duì)計(jì)算機(jī)技術(shù)感興趣的小伙伴請(qǐng)關(guān)注公眾號(hào):美男子玩編程,公眾號(hào)優(yōu)先推送最新技術(shù)博文,創(chuàng)作不易,請(qǐng)各位朋友多多點(diǎn)贊、收藏、關(guān)注支持~
& N+ @( u7 q6 m( O. }  |! u9 k" F: z5 \) i; Q6 r
項(xiàng)目專(zhuān)欄:https://blog.csdn.net/m0_38106923/category_11085518.html8 P9 d! _, h9 t, Q/ S" x
博客是互聯(lián)網(wǎng)的一種分享類(lèi)型的技術(shù)產(chǎn)物,但是如何留著用戶(hù)才是重要的,并不都是所有的功能都會(huì)涉及到“高并發(fā)”,博客的功能多樣性會(huì)增強(qiáng)用戶(hù)的體驗(yàn),讓用戶(hù)對(duì)博客的使用產(chǎn)生依賴(lài)性,利用從眾心態(tài)合理地開(kāi)發(fā)增值功能。. X" h; s9 q* \5 B3 \

: ?& X  d0 U! @8 [2 P+ `" X8 x本次系統(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)的一些功能。
! q, f% A1 Q: \3 G1 l
; z! h" }  j3 Z0 _( `1 T項(xiàng)目工程資源請(qǐng)參見(jiàn):https://download.csdn.net/download/m0_38106923/87849577
2 c% G0 z, P  W8 N. F18 O7 K( d3 u: [5 a4 G7 ]) D
項(xiàng)目功能: |7 k7 t( Q5 l
博客基本的功都具備,例如博客的核心功能:博客的發(fā)表,刪除,瀏覽,評(píng)論,點(diǎn)贊等。除了這些,還可以每天定時(shí)簽到提升博客的等級(jí),充值會(huì)員提升使用體驗(yàn)。# o/ n* n( d* l9 u, V6 f
9 `  Y" E  T1 b! f9 k& h! h/ E
個(gè)人的安全信息也非常重要,所以我單獨(dú)劃分一個(gè)微服務(wù)中心來(lái)實(shí)現(xiàn)。同樣我在每行重要的代碼上都增加了明顯的注釋?zhuān)@對(duì)于我以后的維護(hù)和擴(kuò)充博客功能可以打下堅(jiān)實(shí)的基礎(chǔ),盡可能地符合軟件設(shè)計(jì)開(kāi)發(fā)原則。
9 p' p5 i* B& ]) [  f/ _* d% y8 B# t" D$ Q4 _! Y
關(guān)于博客的功能一共涉及到8個(gè)微服務(wù)中心:
  • 用戶(hù)的個(gè)人中心:包含登錄、注冊(cè)、智能驗(yàn)證。
  • 用戶(hù)的安全中心:安全信息、手機(jī)與郵箱的基本功能和安全認(rèn)證的接口。
  • 用戶(hù)的博客中心:發(fā)表和管理個(gè)人的博客,游客可以瀏覽公開(kāi)的博客。
  • 用戶(hù)的文件中心:發(fā)表博客需要用到的圖片和個(gè)人用戶(hù)的頭像。
  • 用戶(hù)的簽到中心:博客的簽到累計(jì)的經(jīng)驗(yàn)值和簽到獎(jiǎng)勵(lì)。
  • 用戶(hù)的會(huì)員中心:包含普通會(huì)員和超級(jí)會(huì)員。
  • 用戶(hù)的支付中心:VIP的充值功能,個(gè)人錢(qián)包功能,賬單等。
  • 用戶(hù)的搜索中心:根據(jù)摘要或者文章標(biāo)題的關(guān)鍵字搜索指定的博客。- d, i2 C3 w& Y/ Z. t
    [/ol]  v" M6 x) F# z7 p+ }: ~, I+ f  n
    2# h7 ^4 s; @9 _4 u7 a$ X, P
    項(xiàng)目架構(gòu)設(shè)計(jì)- \2 m$ O" [' ]+ g. k

    ' q5 d) |; V) ^6 M$ C6 k: u" M3 J& p. i5 K& R) I3 M( J: ~, W
    從宏觀設(shè)計(jì)來(lái)說(shuō),各個(gè)微服務(wù)中心都是一個(gè)moudle,需要注冊(cè)到一個(gè)高可用的微服務(wù)注冊(cè)中心上保證機(jī)器信息的正確性。$ Y1 t+ b( ~! d

    " Q& {) s/ m  R從微觀運(yùn)行來(lái)說(shuō),用戶(hù)的請(qǐng)求API都經(jīng)過(guò)Zuul,再由Zuul負(fù)載均衡分配給需要的微服務(wù)中心,所以Zuul也需要高可用保證用戶(hù)流量可以得到回應(yīng)。通過(guò)zuul網(wǎng)關(guān)后,請(qǐng)求通過(guò)Feign實(shí)現(xiàn)微服務(wù)之間數(shù)據(jù)的交互。$ J6 O0 Y8 ^% b; A4 V; Y& M

    * ?" P- O. l" x+ o9 y當(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ā)用戶(hù)的補(bǔ)償機(jī)制,當(dāng)出現(xiàn)不可知的錯(cuò)誤時(shí),也可以直接管理機(jī)器的集群來(lái)維護(hù)系統(tǒng)的穩(wěn)定運(yùn)行。
    * D" L) r, R$ A* ]3& h" @7 {/ e7 `" P6 E
    項(xiàng)目數(shù)據(jù)庫(kù)設(shè)計(jì)5 u, x) o$ T' h: [/ M
    對(duì)于用戶(hù)來(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)的記錄。核心表是用戶(hù)博客之類(lèi)的表,文章均存在數(shù)據(jù)庫(kù),不過(guò)ElasticSearch也保存了文章的標(biāo)題和摘要。每個(gè)用戶(hù)可以評(píng)論他人的文章,私密的文章不會(huì)出現(xiàn),會(huì)員的文章會(huì)出現(xiàn)在會(huì)員專(zhuān)區(qū)。8 }4 G" S5 R1 \, H9 T) @2 `

    4 d/ S6 k$ @) m- T8 V博客一共含有8個(gè)主功能,所以一共涉及用戶(hù)表,用戶(hù)信息表,安全表,頭像表,簽到表,簽到獎(jiǎng)勵(lì)表(兩種獎(jiǎng)勵(lì)),會(huì)員表,錢(qián)包表,訂單表,博客表,博客分類(lèi)表,博客標(biāo)簽表,博客圖片表,博客的評(píng)論表,點(diǎn)贊表和收藏表17個(gè)表。
    $ \- |. ^( a$ Z; z
    8 G- F2 j8 U/ G* W' H) S3 ^, | 1 x8 m3 {' ]' I+ `1 Z

    $ `% g) [! s: K1 D+ n. D# m0 q4' I. u0 t( {. F& y. e, Y
    項(xiàng)目架構(gòu)實(shí)現(xiàn)- {& y. Y' t7 [2 a, g, x
    4.1、Vue架構(gòu)的實(shí)現(xiàn)
    ' q! p: J# n/ E0 A4 s) q前端IDE采用的是WebStorm,博客的Vue主要分布如下圖所示:
    2 _6 n7 N' d2 A) s# E# p7 D& A% {+ F2 u- ^% C, P

    ) }  g1 [) i" V; f$ u- k* L8 \% W+ `4 F# ^! Z. H4 M& `5 S: X5 H( T; X; c* P/ K
    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中保存的是博客所用的圖片。
    ) q  q0 G1 [' n. N$ x* C不管是用IDE創(chuàng)建的項(xiàng)目還是采用常規(guī)腳手架創(chuàng)建的vue項(xiàng)目,其項(xiàng)目都會(huì)在根目錄生成一個(gè)package.json文件,這個(gè)文件與后端的“pom”相似,這個(gè)文件包含所需要的各種包,還包含項(xiàng)目的配置的名稱(chēng)與版本對(duì)應(yīng)。
    " d2 h2 Y2 r+ C- x. a- |! }( i- {1 e% I
    博客項(xiàng)目中的package的完整dependencies代碼如以下所示:
    ! j2 c/ F5 K4 `5 ]3 N$ z" Y, ]; l! K
  • "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" }2 ~5 P3 {, f% i0 W. D
    4.2、SpringCloud架構(gòu)的實(shí)現(xiàn)
    0 h. c& I4 |- [5 N) n博客Maven的整體微服務(wù)中心實(shí)現(xiàn)的結(jié)構(gòu)圖如下所示:# a9 W8 X; i1 ~7 H: H6 g! U% d

    / T6 R4 T. L  w3 k# K8 D$ f4 [
    8 S" M7 a8 J/ Q' |0 L% f& [6 s$ F5 }2 X9 ?2 m! m
    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之間的版本依賴(lài)才能使用。博客涉及到的Java的JDK版本是1.8,SpringBoot的版本是Spring Boot 1.5.9.RELEASE,SpringCloud的版本是Edgware SR4。后端的IDE采用的是IDEA,Maven的版本為3.6.1,任何一個(gè)版本的更改都可能會(huì)導(dǎo)致兼容不一致。
    ( K& c7 e2 A& ?* `
    $ ]- z' z0 l% Q7 ?4.3、博客的高可用的實(shí)現(xiàn)" U& e, r3 U* P' v$ Z
    博客使用了兩個(gè)Zuul并且注冊(cè)到高可用的服務(wù)發(fā)現(xiàn)中心來(lái)構(gòu)造Zuul高可用集群。Eureka是所有微服務(wù)的注冊(cè)中心,并且自己本身也是微服務(wù)不過(guò)需要禁止自我注冊(cè)。Eureka注冊(cè)中心包含每個(gè)微服務(wù)的名稱(chēng),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è)中心圖如下圖所示:
    $ [% t" k3 l3 G& n
    - V! H1 U1 O; B' K 3 @2 S4 G* q/ A" f4 H7 m# e  @

    2 F8 r, \5 V" L# W7 x& KDS 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)。
    % b6 q5 {0 D% K; t2 Q' T# w; ~3 P0 s: X$ \
    54 d. O: B! p. _/ E: Z6 l; v+ q
    用戶(hù)的個(gè)人中心
    1 R. v3 q8 }+ g) n3 E9 o8 u用戶(hù)的個(gè)人中心相當(dāng)于博客的大門(mén),用戶(hù)的首次流量都經(jīng)過(guò)此處,首次負(fù)載均衡調(diào)用也是基于這個(gè)中心開(kāi)始,主要涉及到用戶(hù)的登錄與注冊(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)講。
    $ p. Q& v) W/ m$ ]. T" s
    / [5 p: x2 w. o2 J5.1、登錄的智能驗(yàn)證
    : x* S  |0 I6 r! pVue整合阿里云智能驗(yàn)證時(shí),需要注冊(cè)布局組件來(lái)動(dòng)態(tài)加載JavaScript文件,不然無(wú)法使用阿里云的智能組件,前端登錄智能驗(yàn)證的核心代碼如以下所示:
    ) _) K' j% K) d) @/ \% K( t2 ^0 t4 a2 i) Y8 f) o2 i5 t
  • //動(dòng)態(tài)加載阿里云的JavaScript文件src="//g.alicdn.com/sd/nvc/1.1.112/guide.js" @loaded="initCaptcha">
    , H' M; ]/ I( l  }" C2 L//注冊(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 }                }            }        },  Z" o% W1 ~$ O3 Z/ P
    //點(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
    , V7 v  \8 x) W: R3 \5.2、博客的登錄注冊(cè)
      P# ^5 W. v: s9 ]& z. M登錄是一個(gè)系統(tǒng)的重要的功能,也是個(gè)人隱私的重要體現(xiàn),拿常見(jiàn)的登錄有郵箱,手機(jī),賬號(hào)或,語(yǔ)音或者二維碼登錄,不過(guò)不管通過(guò)哪種登錄,個(gè)人信息的安全都應(yīng)該得到保護(hù),保護(hù)個(gè)人隱私重要的是從個(gè)人做起,拒絕非法點(diǎn)擊與輸入。
    5 t" ]6 G; t8 j8 j- Y% d3 V0 V) f- M, p8 _& O
    拿本次博客的登錄來(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ě)博客信息。5 r# I8 ~. {5 Q' G
    博客的登錄與注冊(cè)的頁(yè)面如下圖所示:
      G0 ]  j9 Y* {& j$ \/ T
    ( w5 s7 s- T( f2 D) `5 W9 U
    / T, q, n8 l/ E4 d7 L% L! c; B; Y$ V, O' ]3 Q+ F
    博客登錄的用戶(hù)名需要以英文子母開(kāi)頭,用戶(hù)名和密碼均不可以超過(guò)16位,注冊(cè)保證兩次登錄密碼正確就可,在此不再貼出圖片累述。0 D' {$ R( ]) N
    ) T( b1 T3 z$ [- z0 [
    5.3、登錄的權(quán)限驗(yàn)證7 A, B# \5 b& A% ^
    登陸權(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)證。
    2 W( B8 D. f4 k0 z; ]+ ~
    - R0 {' F1 |) c4 l博客使用了前后端攔截器攔截Token(登錄成功的認(rèn)證碼),所以后端需要定義一個(gè)token驗(yàn)證注解,用攔截器攔截系統(tǒng)的url請(qǐng)求,再進(jìn)行攔截用戶(hù)的API請(qǐng)求,最后再驗(yàn)證傳過(guò)來(lái)的token與Redis中token值是否一致,效驗(yàn)通過(guò)才可以正常訪(fǎng)問(wèn)。當(dāng)用戶(hù)登錄成功博客后,后端返回token數(shù)據(jù)。token具有存在時(shí)間,如果用戶(hù)一段時(shí)間后不在線(xiàn)或者操作的話(huà),則token會(huì)失效,用戶(hù)保持登錄時(shí),則不會(huì)過(guò)期。
    # v9 ^5 k- @& @. l* P
    0 O7 y' u' Y% S6 q: wRedis中會(huì)以用戶(hù)的登錄賬號(hào)作為與token關(guān)聯(lián)的認(rèn)證,有效的token碼可以取出用戶(hù)的賬號(hào),然后再進(jìn)行業(yè)務(wù)邏輯。這些redis中的key都可以自行設(shè)置一些時(shí)間,不過(guò)前端只保存token值,二次登錄會(huì)覆蓋Redis中的token值。
    1 U3 U) G) @4 F' C, G" L. Y+ Z* n% i' k: w  P, c' y/ A* F  S

    ; O2 ]! z! f% H" L, l  l" u$ `8 ?) m
    權(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)的安全框架。
    4 Q( }: g( Y2 [7 l1 E6, w7 s) p1 u5 P
    用戶(hù)的安全中心6 ?6 k1 I) e- }, T! v) g
    6.1、用戶(hù)的安全布局% ~. q7 Y+ \& d; l( e7 k
    安全中心包含郵箱,手機(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ī)。
    & Q$ S( o8 E! v( G! j/ j
    % H) e9 v; Q' \0 P9 i
    . A# M* U8 N# F* t( F
      L/ v" k% d# Y6 K& y% G0 g安全中心包括用戶(hù)的規(guī)則規(guī)章,博客旨在分享自己的動(dòng)態(tài)和經(jīng)驗(yàn)給他人,不可以辱罵他人,以及不遵守國(guó)家的法律法規(guī)。本次博客的其它微服務(wù)中心所需要的手機(jī)認(rèn)證接口均由這個(gè)微服務(wù)中心提供。
    ; y" Z# y- s! I2 O
    % i5 z4 O/ T; ~6.2、用戶(hù)的郵箱注冊(cè)5 k/ K" M  ^9 I6 W/ |
    博客采用的是免費(fèi)的QQ郵箱,郵箱的yml配置如下:) E$ Y; d( a3 g' p/ {% U& N& O
    ; P1 I7 N2 o1 P- f2 e4 k5 X5 [
  • mail:    host: smtp.qq.com    port: 465或587    protocol: smtp    username: 個(gè)人的郵箱    password: 郵箱的SMTP的密碼,可在郵箱的賬戶(hù)中開(kāi)啟SMTP服務(wù)    default-encoding: UTF-8    properties:      mail:       debug: true   #控制臺(tái)開(kāi)啟運(yùn)行日志
    5 {$ T" f  r6 M! uQQ郵箱(郵箱與手機(jī)的六位驗(yàn)證碼共用)發(fā)送驗(yàn)證碼按鈕的原代碼如以下所示:
    " N4 t# S7 m( m" I" F
    " c$ K5 I0 W; x5 X- q$ N, `- P7 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();}
    # P4 m0 f& a, v: m綁定QQ郵箱JavaScript的代碼如以下所示:
    1 D% N: [/ ~- E; ?& g
    ' W/ |& x+ \6 L# s  z# P/ x1 k% l
  • //綁定郵箱的發(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);                      }                  })              }          }, C5 J1 o  \1 y" c7 {
    后端發(fā)送QQ郵箱注冊(cè)的驗(yàn)證碼如以下所示:6 }5 Z8 W4 j$ [" _

    7 \( x# W, {, ]0 o; c
  • //后端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);
    * I. K' Q" Z; l' O- F" I//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);
    % [+ B! I' i0 G4 b+ E* S5 g5 W    //開(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);}
    % W4 F. v4 V# W, V6.3、用戶(hù)的手機(jī)注冊(cè)
    1 O5 n; p& c9 _5 O! Y; m; \8 y發(fā)動(dòng)短信的前端JavaScript的代碼如以下所示:( H8 c8 m9 R* x+ K9 |  l4 j
  • //前端綁定手機(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);}})}}
    & E; o3 \; \% I
    ' }2 d: G  T3 d6 C6 K  G8 X, g后端發(fā)送驗(yàn)證碼的代碼如以下所示:) k1 G% J$ ~# E+ J. w0 R- N6 a5 H3 Q
    3 B" j7 e: i2 w: G
  • //生成手機(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);}
    . @: Z! u2 D) }6.4、用戶(hù)的安全認(rèn)證( J4 P6 d0 n. {( _6 j4 z- }
    提供安全的認(rèn)證有身份認(rèn)證與校園認(rèn)證,當(dāng)然只是表單的提交,真實(shí)的認(rèn)證需要有關(guān)部門(mén)的配合,在此只是用來(lái)模擬,校園認(rèn)證需要與身份證的名字保持一致,否則無(wú)法通過(guò)。' @4 \) x4 c$ r7 y6 Q1 X9 g+ n
    " y# n+ }) T. m- q' H' F

    ( z$ `8 w( E" @2 Q0 [$ W& q
    + H9 Y7 i/ p; c9 `% k" E- k" ~
    1 N" a* |5 u$ ?  F8 k 4 q8 b% d. m' b" W/ T( A# f

    , x; V* J, P5 t6 N# K6.5、用戶(hù)的密碼安全
    7 Y! u: \6 k5 x+ J當(dāng)個(gè)人安全賬號(hào)發(fā)生異常,可以提供修改密碼,也可以重置密碼。& I3 e6 ^) u* L, K

    3 x7 Y; P( q0 `' o% G! Q; X; s
    . M+ s& `" i# ~0 C5 Q4 g% m: I3 @# M# h/ v, r) L6 g- S

    0 C/ i( g  h3 B4 [0 }. B" D   ?+ }6 g& R, J# t
    1 m' E0 N5 o# w
    6.6、用戶(hù)的賬號(hào)申訴
    : O. g1 r' X$ f4 _# u可以使用手機(jī)號(hào)重置郵箱,也可以使用舊手機(jī)號(hào)更換新手機(jī)號(hào)。如果個(gè)人博客的手機(jī)號(hào)安全信息被盜取,手機(jī)號(hào)也可以被重置,但是需要借助身份證申訴,不過(guò)一天只可以成功申訴一次。
      P" n( z% `# |! {, ^& s; x$ \, Z7 a% T" Z7 X9 }2 [; f; z
    ! [- P; V2 J+ \  M# X
    4 s  q& b+ U. W# _& `7 }
    7
    : E) B0 h3 z: D3 {( \7 H用戶(hù)的文件中心
    2 I. ?  b' ?4 |2 s" e9 {7.1、用戶(hù)的頭像存儲(chǔ)  w; Q' G! s$ U; W9 F7 Z  [
    當(dāng)用戶(hù)注冊(cè)的時(shí)會(huì)需要選擇個(gè)人的頭像,上傳的頭像只能是JPG格式且大小不能超過(guò)2MB,且上傳前會(huì)先查詢(xún)數(shù)據(jù)庫(kù)中的頭像圖片名是否已經(jīng)存在,存在的話(huà)直接會(huì)先刪除OSS中舊圖片,再插入新圖片,如果不存在的話(huà),直接插入到OSS文件服務(wù)器中。頭像的存儲(chǔ)流程由前端發(fā)起file傳給后端,后端接受file頭像,利用二進(jìn)制傳給OSS文件服務(wù)器。服務(wù)器再傳過(guò)來(lái)頭像的外網(wǎng)URL地址,此時(shí)修改顯示時(shí)間為10年再返還給用戶(hù),最后把頭像外網(wǎng)URL地址保存到自己的LocalStorage本地。2 v4 K* C( A0 g

    . j! n4 g" [- E ; q0 t. @$ _8 P

    9 Y4 j( }+ ~/ E0 X3 c7.2、博客的圖片存儲(chǔ)0 C- I1 G1 p2 J8 T9 F
    發(fā)表博客時(shí)文章中會(huì)包含圖片,前端獲取后端的博客圖片url綁定在前端文章中顯示,同樣url也在文章內(nèi)容中一起保存到數(shù)據(jù)庫(kù)中。上傳圖片和上傳頭像不同,文章需要用到的圖片可以有多張,不存在覆蓋問(wèn)題。需要根據(jù)個(gè)人的文件服務(wù)器的存儲(chǔ)量來(lái)權(quán)衡上傳圖片大小。
    1 m4 z- T, y5 [7 v
      [- s) a" Q! P1 B
    4 _. b' X) U, X" k* @
    " I; c8 n8 W% Y" k; O6 ?2 s0 T7 b0 C  C  X2 p& g
    8
    ! a  |, F# }& \3 d3 E% @( f3 T用戶(hù)的簽到中心
    & `. W" \7 S% E. }+ J# H用戶(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)致不同的疊加效果。
    % H2 [/ u. O" {( I4 e& K. n( S- _. A% y5 `1 l
    每天0點(diǎn)之前只能簽到一次,過(guò)完0點(diǎn)后Redis中限時(shí)憑證失效既可以再次簽到,簽到的經(jīng)驗(yàn)值采用二分查找和快速排序算法進(jìn)行計(jì)算最后的排名返還給用戶(hù)。
    & J! o6 f  B! t! t& X6 L/ R9 C3 M! T- }0 Q: z) v3 \
    簽到按鈕的計(jì)算代碼如以下所示:
    1 v( q$ H0 A2 j, o6 l# j
    / Y) e& ~% [  J0 e5 M) C, n; P# q+ u7 t
  • //先判定是否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;
    6 D/ x3 @* y" `' p! U) [) y. d經(jīng)驗(yàn)值的排名的代碼如以下所示:
    7 j2 e* L" U+ m2 A# ~2 q6 M! F* U2 I. p2 O
  • //先查詢(xún)所有的經(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;8 b$ L% g) t+ c( a8 P; \
    9
    , \/ I( \3 t& s1 t用戶(hù)的會(huì)員中心5 [; j+ ~: ~! n' F9 ^
    由于會(huì)員中心與支付中心聯(lián)系比較密切,所以?xún)烧叩闹行目梢越Y(jié)合起來(lái)看作一個(gè)中心來(lái)觀看。用戶(hù)的會(huì)員中心包括普通會(huì)員和超級(jí)會(huì)員,每種方式存在三種收益方式,年費(fèi)季費(fèi)和月費(fèi),支付成功后均由負(fù)載均衡執(zhí)行業(yè)務(wù)邏輯。由于支付不屬于這個(gè)module中,所以這個(gè)module只是由其它微服務(wù)調(diào)用直接完成業(yè)務(wù)邏輯。' J' ~2 E2 A( J* X9 ?$ g/ ^
    3 f6 ]# P& K. M
    7 |) c5 q; m; R6 D* o! s  ]* R- f
    ) h" v! H6 Q/ a! P4 r- `* I8 R
    10, K' \8 Z$ m- ?2 R$ v
    用戶(hù)的支付中心5 F7 ?" i& C. _' h: j! o; V& p6 Q
    未完成實(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è)人銀行卡均需要用到支付密碼?梢杂门f支付密碼修改新密碼,也可以手機(jī)重置手機(jī)密碼。還可以綁定自己的銀行卡,需要有關(guān)部門(mén)的配合。本次博客只允許建設(shè)銀行,工商銀行和中國(guó)銀行,且每張銀行卡只允許綁定一張。利用v-charts組件把個(gè)人的時(shí)間段的消費(fèi)情況以條形圖展現(xiàn)給用戶(hù)觀看。
    ' _" f4 O8 f3 M0 e- k& a/ v; ]" s+ W$ U0 k% ~
    3 t. e. `" M0 u2 b# T# K- y/ V
    " R, P& G( g3 i6 j+ r* Y/ o  K1 z% E  @! H
    " A1 C4 A) e" d2 F! k

    . H$ H' J, ]; _- n$ p! c- |8 q5 V
    當(dāng)用戶(hù)開(kāi)通了我的錢(qián)包后,可以選擇是否進(jìn)行余額充值,賬戶(hù)余額暫時(shí)只可以用支付寶充值。所有關(guān)于金額的操作均需要在后端安全操作,前端只用來(lái)顯示數(shù)據(jù),必須使用數(shù)據(jù)庫(kù)中的金額。) M9 B, }6 [( _
    1 i6 M( a( z) y) O8 x4 f9 M

    1 a/ q, f; f! |: l9 n
    ; v! f  X  x2 k- X3 f" j( ~
    , K$ w; c1 f6 B, `4 l4 `' Z4 E% }' v3 c0 j& G/ i
    密碼為6位有效數(shù)字,可以使用原密碼更換新支付密碼。9 g# m5 {" H' n3 t8 g6 C

    % }6 H, y* ?/ B5 c
    ! E- g+ Z6 l, v4 i% t* M. x
    % a3 H- a  G: h6 R2 v: C1 e1 D9 C$ o2 N! w7 B! r# H( l  X
    0 x  {+ a; X/ b9 F9 ?( [6 [( B
    7 O: f7 F! N1 [/ H3 N; R
    銀行卡姓名需要與實(shí)名認(rèn)證的姓名一致。
    ! u" ~* _6 Z/ E! K& S& \/ o* B( T* J4 b  {2 {

    , D* ^: l; y3 ]
    * k! S9 O" W8 R6 l3 N1 f4 N8 u5 K' V  \
    . W( i1 T" |# d* z0 v, q
    & }4 O) ]" I! Z9 Q% M5 ^/ L) f

    7 v: n4 V& i- b, A# c& L  n$ n) Z) k% l

    ) j0 `9 z8 s# u- r+ U$ h, u支付中心包含普通會(huì)員和超級(jí)會(huì)員,由于普通會(huì)員采用支付寶原始的方式,而超級(jí)會(huì)員采用支付寶的二維碼方式,所以?xún)烧邥?huì)在調(diào)用的時(shí)候會(huì)有所不用。; A3 h% T3 T7 I; G' U" B
    : c, e& j1 L# n

    , y  c( B9 Y. ~. C' {, Z* Z
    - }% |  Y! Q: ?8 m  `賬單中心是分頁(yè)展示給用戶(hù)觀看,提供當(dāng)前頁(yè)面,月份和全部的賬單打印Csv。前端可以直接把后端的數(shù)據(jù)直接打包Csv,也可以自行后端打包Csv數(shù)據(jù)到本地。  D+ A0 ?' t8 l6 J. h. i
    + K# Z0 z9 e, I3 D: D/ e( U3 i
    # y8 `; c( }  `1 U
    4 q4 a# m" O) M  T' L
    + o7 f7 B" c* v; m5 W$ Q8 n+ E
    ! p' g5 r9 r3 c, l4 }
    ! _( M6 t' F, s1 k* {7 M" T+ ^6 M- g
    114 i9 z' `6 m. V# ]
    用戶(hù)的博客中心* U1 ~5 G! n6 E* d7 W* D# t* W
    11.1、用戶(hù)的訪(fǎng)問(wèn)主頁(yè)6 ~0 E# E5 [" c0 k  y' B; `, p
    編寫(xiě)博客是一個(gè)展示自我的機(jī)會(huì),通過(guò)這個(gè)機(jī)會(huì),可以增強(qiáng)個(gè)人的表達(dá)能力,還會(huì)結(jié)識(shí)一些五湖四海的博友。通過(guò)他人文章的學(xué)習(xí),我們還可以增強(qiáng)個(gè)人的知識(shí)度和眼界。綜上所述,用戶(hù)的博客中心是博客系統(tǒng)的最核心功能。
    4 N' x4 X! @' `. r8 L9 Z4 f3 ~* a5 i3 n% r
    用戶(hù)可以分享自己的博客動(dòng)態(tài),博客旨在分享自己所學(xué)所知給他人,或者解決他人的困難。博客中心包含發(fā)表博客,查看個(gè)人博客,刪除博客,更新個(gè)人博客。非本人也可以觀看他人的博客,也可以評(píng)論他人的博客,所以需要用到分頁(yè)功能和輪滑加載功能配合前端展示不是私密的博客給他人觀看。每個(gè)用戶(hù)所看到的博客都是最新發(fā)的博客,可以與他人進(jìn)行學(xué)習(xí)交流。每個(gè)發(fā)表者要尊重他人的知識(shí)勞動(dòng)成果,切勿抄襲并且發(fā)表不適當(dāng)?shù)奈恼,做一名合格的博友?br /> 2 f$ j9 n7 {  G) u! B& Q1 D7 \5 A% ]
    當(dāng)用戶(hù)輸入賬號(hào)密碼登錄后,可以看到博客的主頁(yè)如下圖所示,主頁(yè)面可以看到發(fā)表人和發(fā)表的文章,點(diǎn)擊文章可以進(jìn)入文章的主頁(yè)面進(jìn)行學(xué)習(xí)交流。
    , L% E* [( t! z, N4 T9 Y5 K2 q5 p6 f( j. |, }! Z( k' v

    + d2 C) e! V- i0 `+ s) o2 R2 N* H
    " q4 B& V' Z+ f2 D9 ^2 O11.2、用戶(hù)的文章中心  `" a% N  }% y/ ^, ^/ x
    用戶(hù)的文章微服務(wù)中心的功能包含發(fā)表,查看,修改,刪除,用戶(hù)可以控制自己發(fā)表過(guò)的每一篇文章。* K3 e* r6 z. H

    5 P  ~& T6 x% _* V2 a: q( Q  W( n0 @9 _5 X# m, q' s/ V6 R5 h8 Z6 l
    2 o( n3 F9 M* i, d2 j2 c* e0 q
    關(guān)于文章的增刪改會(huì)在后續(xù)標(biāo)題中得到詳解,在此只放出用戶(hù)的個(gè)人文章中心由圖可以看出是用戶(hù)發(fā)表過(guò)的全部文章,后端利用的是先分頁(yè)后List方式,最終傳送前端進(jìn)行ListItem遍歷顯示即可。
    % s3 |! G, S% @, a. c& o2 D$ S* n1 n( h7 C5 i
    由于也使用了Elasticsearch把文章分類(lèi)作為存儲(chǔ)索引,但是重要的文章信息均放在數(shù)據(jù)庫(kù)中,在此只提一下,到后續(xù)的分類(lèi)搜索中會(huì)詳細(xì)說(shuō)明。
      l% |1 Y& G' u0 j; q3 N+ Q# U
    - Y7 J7 Z$ R( Q1 U% a3 X11.3、發(fā)表個(gè)人的博客
    : V: F/ q7 H5 w0 w文章的的發(fā)布有許多選擇,自己可以選擇文章的分類(lèi)和文章的標(biāo)簽,同樣也可以設(shè)置文章的可見(jiàn)性。用戶(hù)可以設(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)的專(zhuān)區(qū)。文章類(lèi)型有三種,若是轉(zhuǎn)載和翻譯他人的文章需要著名地址,保護(hù)他人的知識(shí)勞動(dòng)成果。只有具備會(huì)員資格才可以發(fā)送到會(huì)員專(zhuān)區(qū),但是轉(zhuǎn)載的文章不可以發(fā)送到會(huì)員專(zhuān)區(qū),發(fā)表文章時(shí)可參考紅字注意事項(xiàng)。3 U+ z; x6 Z% t2 B

    ( Q! f9 k  g) b$ O4 O7 T8 H- |" O* X0 p" V  D  f
    ( C& v) g' J" X1 [9 ]
    博客的發(fā)表的核心原代碼如以下所示:
    % L# S) w$ ?* K$ E( F, k1 `3 r2 k
    " Q9 o2 C1 Q' \, [! f# c
  • //獲取文章的摘要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());}
    / R' `5 H8 Y$ k2 e" m0 |11.4、修改個(gè)人的博客( L5 `4 y3 a. c6 S! _) L
    若是需要修改個(gè)人的博客,需要進(jìn)入圖5-33的個(gè)人博客中心,查看發(fā)表的指定文章進(jìn)入到指定文章的頁(yè)面,點(diǎn)擊編輯按鈕,不是本人的文章不會(huì)出現(xiàn)編輯按鈕,博客的編輯按鈕效果圖如下圖所示:
    # j. u8 l9 h8 i4 o' c* c( d% ?8 U, q' C
    + |. u- }: P: _" r, C
    7 F# [5 ]# x3 r3 B: Z% j; O9 k" ?/ P
    可以修改文章的所有的條件與內(nèi)容。8 O9 |  z3 A: M

    # q9 Q: d, [. g+ {1 ^  ?) E) X0 w( J  d8 u& z4 n% _% s

    / y# C! s) K5 J2 y7 M9 v文章的發(fā)表與修改的源碼不同在于要?jiǎng)h除之前的原屬文章的分類(lèi)Id與標(biāo)簽Id的關(guān)聯(lián),再進(jìn)入文章的插入,不過(guò)文章的修改也會(huì)觸發(fā)在搜索引擎上的文章信息修改,搜索引擎上的文章信息也會(huì)跟著更新,保持搜索到最新的數(shù)據(jù)。
    + ?% ^3 M) R/ u* |! t0 _: N6 B4 g: i7 a; R( ]1 t
    11.5、刪除個(gè)人的博客$ p1 _( M/ }% G$ d' R
    刪除個(gè)人的博客需要?jiǎng)h除數(shù)據(jù)庫(kù)和搜索引擎上的文章,刪除文章后不可恢復(fù)。
    ; z* [# z# v+ Q
    2 F/ r' M2 G( G4 w
    0 t/ X! b5 B  e0 f2 x5 j1 d* r8 r5 {% _7 }! \. d
    11.6、用戶(hù)的文章布局
    6 ^0 k7 C) L: B4 l7 r, _完整博客的顯示方式是采用GitHub的代碼高亮布局,可以是用戶(hù)看到自己的博客是嵌入式的面板,可以給予人一種清爽的感覺(jué)。由于采用Vue,可以不用動(dòng)態(tài)渲染html,使用v-html命令就可以把后端傳過(guò)來(lái)的數(shù)據(jù)利用showdown轉(zhuǎn)換器轉(zhuǎn)換給html直接顯示給用戶(hù)看。2 R/ }  v3 K/ ~6 k& V3 p
    9 W" y6 G9 Y" W# L5 L

    + K7 ^. B% I# C& }) x: Z0 d; _  q$ d4 C) ^# w0 P6 t$ Z; v* f: D
    11.7、點(diǎn)贊用戶(hù)的文章
    / O; J$ R% N0 z- S) y互聯(lián)網(wǎng)時(shí)代每個(gè)人都或許都點(diǎn)贊過(guò)他人分享的文章,本次設(shè)計(jì)是博客所以會(huì)涉及到點(diǎn)贊,當(dāng)用戶(hù)太多時(shí)需要考慮到高并發(fā)的情況。正常情況的點(diǎn)贊并不會(huì)給后端造成多大的負(fù)載壓力,如果是熱門(mén)的文章博客,用戶(hù)點(diǎn)贊與取消點(diǎn)贊,評(píng)論,分享等,對(duì)于后端來(lái)說(shuō)這些都會(huì)帶來(lái)巨大的流量,如果后端接口支撐不住,前端得不到響應(yīng),前端無(wú)法響應(yīng)就會(huì)返回404,會(huì)導(dǎo)致用戶(hù)體驗(yàn)極差。
    5 n: V1 [! a2 f& C+ A* M" j* ]% \9 z- T  B0 H! e9 n

    6 {- q# Z6 ?  X
    # o7 v7 L) w4 }  f: w( J+ I/ v由上圖可知,核心的模塊就是點(diǎn)贊與取消點(diǎn)贊,利用Redisson把多個(gè)用戶(hù)的請(qǐng)求利用分布式鎖分開(kāi)請(qǐng)求,利用“緩存”保護(hù)數(shù)據(jù)庫(kù)。若用戶(hù)點(diǎn)贊微博,則后端會(huì)先查詢(xún)是否存在點(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ā)多線(xiàn)程請(qǐng)求時(shí),分布式鎖就會(huì)控制資源的并發(fā)訪(fǎng)問(wèn),避免出現(xiàn)文章數(shù)據(jù)不一致的情況。
    9 ?. J' b! l% c, I
    1 p! D: X6 x5 c/ r- ~; q11.8、收藏用戶(hù)的文章& o- t2 N, `! N; D0 _' e
    用戶(hù)允許收藏自己的文章,收藏的功能也借用了Redisson的分布鎖來(lái)控制收藏的緩存,收藏與博客的點(diǎn)贊功能相似。! ~4 k5 @7 W7 f0 j

    6 T( k* ?& `& g/ w0 X. _; e6 J) N% ~6 q

    ; Y$ @; u$ j, I( }8 [5 L  _# G7 r  T( N& r
    , v4 m+ O' r9 M8 ]1 G# @

    ( u0 D, C2 R. X, t: p) c11.9、評(píng)論用戶(hù)的文章- U' `; n" k. U# U1 Z# f
    評(píng)論的實(shí)現(xiàn)比較簡(jiǎn)單,一級(jí)評(píng)論的用戶(hù)的Id為父Id,只含有一級(jí)評(píng)論與二級(jí)評(píng)論,分頁(yè)直接查看文章的所有評(píng)論。
    4 S  C- ~' l, ]0 K2 j& C, v) U8 q0 Z  O1 O0 v
    / b: V& u8 j, o4 Y
    % l, j6 ]3 ~2 c/ k
    11.10、博客的文章排行榜
    2 @; f0 D* Q+ F. u. J/ D9 L5 V文章排行榜采依舊是利用了Redisson,排行榜與標(biāo)題3-7-4的點(diǎn)贊關(guān)聯(lián)緊密,“點(diǎn)贊”會(huì)導(dǎo)致熱流,形成短時(shí)間內(nèi)的超高人氣,把文章的排行榜放給用戶(hù)看,可以增強(qiáng)用戶(hù)的體驗(yàn)。不是所有的功能都要用分布式鎖,排行榜不需要用到分布式鎖,也不需要控制非常高的高并發(fā)流量,對(duì)于后端來(lái)說(shuō)控制排行榜比較簡(jiǎn)單。, m$ H. h  ?/ L9 S- W! `; {
    * z) p/ o# D- I1 P
    - W" X5 S2 k6 |+ g' D" r+ |
    ; h/ x% {$ ^: O8 ]5 z+ H
    排行榜需要保證查詢(xún)數(shù)據(jù)庫(kù)的點(diǎn)贊表的SQL正確,SQL錯(cuò)誤之后的所有操作都是白費(fèi)力氣,這個(gè)要設(shè)置一定的范圍與時(shí)間差來(lái)確保文章的間斷實(shí)時(shí)性,最后要把數(shù)據(jù)庫(kù)中的數(shù)據(jù)放到緩存中。對(duì)于緩存的操作,用戶(hù)的點(diǎn)贊與取消點(diǎn)贊都會(huì)觸發(fā)緩存中的排行榜排序。用戶(hù)請(qǐng)求后,會(huì)查到緩存中的排行榜點(diǎn)贊數(shù)最多的前10篇文章,利用List的文章Id找到文章的信息,最后打包傳給前端顯示。排行榜算是一種實(shí)時(shí)性要求不算很高的,可以使用定時(shí)的方式主動(dòng)更新緩存中排行榜記錄。
    ! c4 C/ `: r1 r0 n' ]6 c" k& I+ X3 E9 T0 h

    - y9 O' R  f& c" Q' F, v3 d/ A' K) w% `5 U+ p4 Z& Y! ~+ T

    ( F2 x5 ?# S3 i" ], ?3 Q! z3 H128 f) A. Y: x: }: x: n/ \5 z
    博客的搜索中心: t" m% `& Y- {% R' N( k
    12.1、搜索引擎的應(yīng)用1 w6 z+ r1 r: ^; _5 L  S) b& ?
    當(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中。7 v4 R$ _1 {) g& t3 M* q, T/ ~

    % p; E7 a- }$ {2 W! T
    , _/ R/ a1 @9 `9 }; K3 ]! p1 G( @3 D- [
    Elasticsearch的index是文檔索引,與數(shù)據(jù)庫(kù)的“庫(kù)”相似,type是文檔類(lèi)型,與數(shù)據(jù)庫(kù)中的“表”相似,id是一個(gè)字段作為主鍵。  I' O) u& h  R( Q/ m/ v

    & L; c  ~) I, Q0 n% x) y0 e12.2、博客的分類(lèi)搜索7 k+ z# S! W# d
    博客的搜索中心包含文章的顯示的信息,例如標(biāo)題和文章內(nèi)容的摘要,由于把文章的整篇內(nèi)容均放到數(shù)據(jù)庫(kù)中,所以搜素引擎上的文章是負(fù)載均衡保存提示的信息,用戶(hù)可以根據(jù)搜索界面的搜索框查詢(xún)Elasticsearch上文章,根據(jù)的是文章的分類(lèi)的區(qū)域和關(guān)鍵字,后端判關(guān)鍵字是否符合且存在,然后把結(jié)果傳給前端顯示。6 a2 v; f; d' N2 F0 q4 l- ~5 n
    . @% N1 I: Q1 M& ]4 n
    ; o/ h  M  H7 J: S+ B" B4 a3 R

    ' h. I6 x  h0 e- u! J  k& l% T% J
    4 B9 Y) ?& {% N3 z- U1 E- y7 |; x8 L* m) d6 Y
    ! S* Z  j+ c- W3 U- f
    12.3、博客的分類(lèi)主頁(yè)/ X0 ~8 v( V1 @. Q4 E
    博客的分類(lèi)主頁(yè)是利用Elasticsearch上的文章信息進(jìn)行遍歷,用戶(hù)發(fā)表的博客時(shí)候選擇的分類(lèi)作為Elasticsearch索引的名負(fù)載均衡到Elasticsearch,分類(lèi)中心的文章每次選擇20篇最新的文章傳給給用戶(hù)觀看。
    5 \, ^8 d4 n) v" a8 f7 m
    5 Y0 P" S2 I* A6 r  H6 Q$ l& _* ^% _( J7 s: N& r( a

    ' c% V4 v+ w+ q1 [1 z/ x+ V/ X13
    * @5 L" N( E, P! s: Q博客的測(cè)試分析
    6 ]# P& }  `" g6 C  f) T13.1、博客的請(qǐng)求抗壓性分析* K: r, l% Z/ ~2 q' F
    博客采用的是前后端的分離模式,所以對(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)程中需要防止出現(xiàn)業(yè)務(wù)出現(xiàn)錯(cuò)誤,或者網(wǎng)絡(luò)錯(cuò)誤導(dǎo)致負(fù)載均衡出現(xiàn)中斷錯(cuò)誤,所以需要catch防止程序出現(xiàn)錯(cuò)誤,同樣還必須保存支付寶異步通知的結(jié)果防止另起線(xiàn)程中出現(xiàn)異常。對(duì)于每個(gè)用戶(hù)的請(qǐng)求,可以采用服務(wù)器的限制流量,限制的方向可由個(gè)人選擇,需要在服務(wù)器的圖形化界面中可以設(shè)置。
    2 o& V$ p( h5 E, q8 g2 k. V$ Q
    % f) l( c8 n8 \) }6 c- \7 f+ J( O5 j: X' f+ }

    / p4 @" Z* N9 ^) c4 X9 e13.2、博客的功能擴(kuò)展性分析2 M+ q" t2 ^! k* ?( \! ?
    博客的前端容易擴(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ò)充方便。
    : Q6 e8 _: m: I. i- l% p5 X0 Q8 d
    Pom文件中的module劃分如下圖所示:  I, b: D/ z* r* q
      S' N3 A, Q) @1 f

    ' H  o+ I# g  S. g/ f3 k' e$ N9 G2 ?" s
    項(xiàng)目工程資源請(qǐng)參見(jiàn):https://download.csdn.net/download/m0_38106923/87849577) @6 h' n" i1 a) B

    5 B; J6 e4 i# {  r5 p9 G( h% h8 I0 P1 H0 J. h: A. @% ~
    往期推薦畢業(yè)設(shè)計(jì)So Easy:Java MySQL智能報(bào)紙閱讀器APP應(yīng)用$ A: r6 R5 P9 o* d5 w0 e4 u
    畢業(yè)設(shè)計(jì)So Easy:基于C++實(shí)現(xiàn)網(wǎng)絡(luò)掃描器1 @4 E. m, ]6 e7 |8 c7 r; s
    畢業(yè)設(shè)計(jì)So Easy:基于Java Web學(xué)生選課系統(tǒng)1 [  \/ q8 G7 v. L. {8 K& ]9 A
    畢業(yè)設(shè)計(jì)So Easy:基于Java語(yǔ)言西餐廳點(diǎn)餐系統(tǒng)
    & _4 A  O1 M& B: [* H& c# r畢業(yè)設(shè)計(jì)So Easy:珠穆朗瑪FM音頻電臺(tái)APP9 M/ N! V4 w5 t% a; ], Y! W' k
    " N7 M3 Q- H/ o: G
      w4 [  u. `3 @% a1 x8 l; ~# _; ]; ~
    ; }7 v3 y1 A7 J3 e5 g+ g' P
    點(diǎn)擊閱讀原文,更精彩~
  • 發(fā)表回復(fù)

    本版積分規(guī)則


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