前言
本期項(xiàng)目是宿舍管理系統(tǒng)矛绘,主要包括數(shù)據(jù)監(jiān)控大盤、宿舍樓管理刃永、宿舍管理货矮、宿舍成員管理、借用管理斯够、衛(wèi)生管理囚玫、繳費(fèi)管理喧锦、保修管理、日志管理抓督、用戶管理燃少、角色管理以及各個(gè)模塊的導(dǎo)出功能。以企業(yè)級(jí)的開發(fā)標(biāo)準(zhǔn)來完成整個(gè)前后端代碼铃在,無論是用來作為畢業(yè)設(shè)計(jì)還是拿來學(xué)習(xí)阵具,相信對(duì)初學(xué)者都會(huì)有很大幫助。
(想要源碼和視頻教程的同學(xué)私信我~~~)
工程架構(gòu)
應(yīng)用分層
上面的分層架構(gòu)摘自阿里巴巴java開發(fā)手冊(cè)定铜,我對(duì)此做了一些調(diào)整阳液,實(shí)際分層結(jié)構(gòu)如下:
領(lǐng)域模型
DO(DataObject):與數(shù)據(jù)庫(kù)表結(jié)構(gòu)一一對(duì)應(yīng),通過DAO層向上傳輸數(shù)據(jù)源對(duì)象
BO(BusinessObject):業(yè)務(wù)對(duì)象揣炕。由Service層輸出的封裝業(yè)務(wù)邏輯的對(duì)象
-
VO(View Object):顯示層對(duì)象帘皿,通常是Web向模板渲染引擎層傳輸?shù)膶?duì)象
BO和VO領(lǐng)域模型又分為BoRequest(輸入模型)、BoResponse(輸出模型)畸陡、VoRequest(輸入模型)鹰溜、VoResponse(輸出模型)
技術(shù)棧
前端:vue + element
后端:jdk1.8 + springboot + redis + mysql
系統(tǒng)設(shè)計(jì)
接口設(shè)計(jì)
整個(gè)項(xiàng)目接口采用的目前互聯(lián)網(wǎng)比較流行的restful風(fēng)格設(shè)計(jì),每個(gè)接口罩锐、每個(gè)參數(shù)都有詳細(xì)的文檔說明奉狈。因?yàn)槠髽I(yè)中開發(fā)必然是團(tuán)隊(duì)協(xié)作,必然前后端分離的開發(fā)模式涩惑,你得先把接口定義出來,然后前端可以和后端同步開發(fā)桑驱。還有一種就是對(duì)外提供接口竭恬,比如你們隔壁團(tuán)隊(duì)也想調(diào)用你這個(gè)服務(wù)的接口,但是你兩排期是同一周熬的,這時(shí)候你得先把接口定義出來給人家痊硕,然后大家同步開發(fā),開發(fā)完了之后再進(jìn)行聯(lián)調(diào)押框。
運(yùn)行效果
系統(tǒng)登錄
dashboard
首頁(yè)數(shù)據(jù)大盤岔绸,按最近7天餅圖占比、最近30天折線圖走勢(shì)橡伞、最近一年柱狀圖分析盒揉、最近7天各個(gè)時(shí)間段占比分析全方位可視化分析數(shù)據(jù)。
宿舍樓管理
宿舍管理
宿舍成員管理
借用管理
衛(wèi)生管理
宿舍長(zhǎng)可以對(duì)寢室值日人員進(jìn)行排班兑徘,每人值日一天刚盈,便于衛(wèi)生管理。
繳費(fèi)管理
保修管理
Excel導(dǎo)出
所有模塊都支持?jǐn)?shù)據(jù)導(dǎo)出Excel挂脑,方便進(jìn)行數(shù)據(jù)分析
借用記錄導(dǎo)出
保修單導(dǎo)出
日志管理
日志管理默認(rèn)是開給管理員的藕漱,在系統(tǒng)中的所有操作都會(huì)被記錄欲侮,在系統(tǒng)出現(xiàn)異常時(shí)也便于管理員進(jìn)行問題排查。
用戶管理
默認(rèn)也是只有管理員擁有用戶管理菜單的權(quán)限肋联,可以新建/編輯用戶威蕉、分配用戶角色、禁用/啟用等操作
編輯用戶信息
角色管理
極其靈活的權(quán)限管理橄仍,系統(tǒng)中的所有按鈕都可以單獨(dú)分配權(quán)限韧涨,你可以給A角色只分配了查詢和導(dǎo)出權(quán)限,也可以給B角色分配查詢沙兰、編輯氓奈、新建權(quán)限,還可以給C角色只分配查詢權(quán)限鼎天∫蹋可以滿足幾乎所有的業(yè)務(wù)需求,大家可以自由發(fā)揮定義權(quán)限組合斋射。
默認(rèn)有‘管理員角色’育勺、‘寢室長(zhǎng)角色’、‘普通用戶角色’
頁(yè)面不存在時(shí)提示頁(yè)面
個(gè)人信息修改
密碼修改
管理員創(chuàng)建完用戶之后的默認(rèn)密碼是“123456”罗岖,用戶可以登錄系統(tǒng)自己修改密碼
權(quán)限設(shè)計(jì)
權(quán)限基于security和spring-session實(shí)現(xiàn)涧至。權(quán)限可以分為認(rèn)證和授權(quán),認(rèn)證其實(shí)就是登錄桑包,用戶登錄時(shí)會(huì)進(jìn)行賬號(hào)密碼的校驗(yàn)南蓬,校驗(yàn)成功后會(huì),會(huì)把session存入redis中哑了。授權(quán)指的是用戶是否擁有訪問后端資源的權(quán)限赘方,每個(gè)新用戶在創(chuàng)建后都會(huì)分配角色,角色其實(shí)就是一個(gè)權(quán)限集合弱左,這里的權(quán)限可以理解為訪問后端一個(gè)個(gè)接口(資源)的權(quán)限窄陡。
這里權(quán)限設(shè)計(jì)的非常靈活,細(xì)粒度到按鈕級(jí)別拆火,比如新增跳夭、刪除、修改们镜、查詢币叹、借閱動(dòng)作,普通用戶可能就只有查詢權(quán)限憎账,管理員則擁有新增套硼、刪除、修改的權(quán)限胞皱。普通用戶即使通過接口直接訪問后端的修改或者刪除接口邪意,后端也會(huì)返回授權(quán)失敗錯(cuò)誤九妈,因?yàn)楹蠖嗣總€(gè)需要權(quán)限的接口都打了權(quán)限標(biāo)識(shí),只有擁有資源權(quán)限用戶才能訪問雾鬼。
比如下面的車輛修改接口萌朱,只有擁有“CAR_UPDATE”這個(gè)權(quán)限標(biāo)識(shí)的用戶才能訪問這個(gè)接口,否則返回“未授權(quán)”的錯(cuò)誤策菜。
<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="java" cid="n77" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--font-monospace); font-size: 0.85rem; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248) !important; position: relative !important; width: inherit; border: 1px solid rgb(244, 244, 244); -webkit-font-smoothing: initial; line-height: 1.43rem; border-radius: 2px; overflow-wrap: normal; margin: 0.8rem 0px !important; padding: 0.3rem 0px !important; color: rgb(52, 73, 94); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">@PutMapping("/{id}")
@PreAuthorize("hasAuthority(T(com.senior.book.console.api.security.Authority).BOOK_UPDATE.name())")
public Result<Boolean> update(@PathVariable("id") Long id, @Valid @RequestBody BookUpdateVoRequest request) {
}</pre>
日志方案
日志采用lombok注解+slf4j+log4j2的實(shí)現(xiàn)方案晶疼,基于profile實(shí)現(xiàn)了多環(huán)境的日志配置,因?yàn)椴煌h(huán)境的日志打印策略是不一樣又憨,比如開發(fā)環(huán)境我可能需要打印到console控制臺(tái)翠霍,需要debug級(jí)別的日志以便于本地開發(fā)調(diào)試,測(cè)試環(huán)境可能就需要打印到日志文件里蠢莺,線上環(huán)境可能需要打印到文件的同時(shí)將日志發(fā)送到kafka然后收集到es中寒匙,這樣當(dāng)線上部署了多臺(tái)機(jī)器后我們查日志不用一臺(tái)一臺(tái)機(jī)器去查日志了,因?yàn)槎际占絜s了躏将,我們只需要登錄kibana去搜索锄弱,這樣就非常方便。這里說到的kafka+es+kibana這樣一套日志解決方案也是目前互聯(lián)網(wǎng)公司比較常用的一套解決方案祸憋。如果你動(dòng)手能力夠強(qiáng)会宪,你可以本地搭一套kafka、es蚯窥、kibana掸鹅,然后只需要在配置文件中加入幾行配置就實(shí)現(xiàn)了這么一套企業(yè)級(jí)的日志解決方案(默認(rèn)是輸出到日志文件)。
下面是部分關(guān)鍵配置拦赠,如果要配置kafka河劝,只需要在<Appenders>標(biāo)簽中配置<Kafka>配置即可
<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="xml" cid="n81" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--font-monospace); font-size: 0.85rem; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248) !important; position: relative !important; width: inherit; border: 1px solid rgb(244, 244, 244); -webkit-font-smoothing: initial; line-height: 1.43rem; border-radius: 2px; overflow-wrap: normal; margin: 0.8rem 0px !important; padding: 0.3rem 0px !important; color: rgb(52, 73, 94); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"> <?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN" xmlns:xi="http://www.w3.org/2001/XInclude">
<Properties>
<Property name="LOG_FILE">system.log</Property>
<Property name="LOG_PATH">./logs</Property>
<Property name="PID">????</Property>
<Property name="LOG_EXCEPTION_CONVERSION_WORD">%xwEx</Property>
<Property name="LOG_LEVEL_PATTERN">%5p</Property>
<Property name="LOG_DATE_FORMAT_PATTERN">yyyy-MM-dd HH:mm:ss.SSS</Property>
<Property name="CONSOLE_LOG_PATTERN">%clr{%d{{LOG_LEVEL_PATTERN}} %clr{{sys:LOG_EXCEPTION_CONVERSION_WORD}
</Property>
<Property name="FILE_LOG_PATTERN">%d{{LOG_LEVEL_PATTERN} {sys:LOG_EXCEPTION_CONVERSION_WORD}
</Property>
</Properties>
<Appenders>
<xi:include href="log4j2/file-appender.xml"/>
</Appenders>
<Loggers>
<logger name="com.senior.park" level="info"/>
<Root level="info">
<AppenderRef ref="FileAppender"/>
</Root>
</Loggers>
</Configuration></pre>