亚洲有码Av一区二区三区_国产高清啪啪免费视频_69色视频国产_国产成人人人爆出白浆_国产精品自在线拍国_一本久久伊人热热精品无码_午夜性刺激在线看免费带字幕_助力高品质欧美狂喷水_亚洲精品日韩无码_精品无码一区二区三区蜜臀_麻豆高清国产AV_熟妇人素无码中文字幕_亚洲a级片在线观看_国产欧美日韩三区_99国产成人高清在线观看

ARTICLE DETAIL

資訊詳情

深耕商務(wù)建站與企業(yè)官網(wǎng)運(yùn)營(yíng)的一線實(shí)戰(zhàn)洞察。

SpringBoot+Vue全棧實(shí)現(xiàn)自習(xí)室預(yù)約管理系統(tǒng):從需求到部署

SpringBoot+Vue全棧實(shí)現(xiàn)自習(xí)室預(yù)約管理系統(tǒng):從需求到部署 自習(xí)室預(yù)約這套題說(shuō)實(shí)話已經(jīng)被做成“畢業(yè)設(shè)計(jì)常青樹(shù)”了。但凡帶點(diǎn)管理系統(tǒng)的課設(shè)、畢設(shè)十有八九繞不開(kāi)這個(gè)選題。我這次做的就是一個(gè)基于SpringBootVue的MVC架構(gòu)自習(xí)室管理和預(yù)約系統(tǒng)技術(shù)棧落在JavaMySQLMyBatis上屬于典型的全棧分離項(xiàng)目。整個(gè)系統(tǒng)拆成用戶端和管理端兩套界面用戶在手機(jī)上或者瀏覽器里能看到自習(xí)室列表、樓層分區(qū)、座位占用情況選個(gè)座位預(yù)約一段時(shí)間管理員在后臺(tái)維護(hù)自習(xí)室、座位、預(yù)約規(guī)則還能看統(tǒng)計(jì)報(bào)表。這篇文章我就按自己做這個(gè)項(xiàng)目的完整過(guò)程來(lái)寫從需求拆解、技術(shù)選型、數(shù)據(jù)庫(kù)設(shè)計(jì)到后端接口、前端交互、部署運(yùn)行再到我實(shí)際踩過(guò)的坑都會(huì)交代清楚。適合正在做課設(shè)/畢設(shè)、想復(fù)現(xiàn)一個(gè)完整前后端分離項(xiàng)目的同學(xué)參考也適合想入門SpringBootVue全棧開(kāi)發(fā)的人照著搭一套練手。源碼層面我會(huì)把關(guān)鍵代碼片段貼出來(lái)不是那種“只給目錄不給細(xì)節(jié)”的分享。1. 項(xiàng)目到底要解決什么問(wèn)題1.1 自習(xí)室預(yù)約的核心痛點(diǎn)學(xué)?;蛘呱鐣?huì)自習(xí)室的座位資源看起來(lái)是“公共的”但實(shí)際運(yùn)營(yíng)起來(lái)全是問(wèn)題。最常見(jiàn)的場(chǎng)景就是考研季、期末周座位嚴(yán)重不夠用第二天一早門口排隊(duì)搶座甚至有人拿書占座幾天不來(lái)。反過(guò)來(lái)非高峰期大量座位空著資源閑置。自習(xí)室管理員也很頭疼紙質(zhì)登記本翻起來(lái)麻煩誰(shuí)占著座位、什么時(shí)候走完全靠人肉盯。這個(gè)系統(tǒng)的核心價(jià)值就是把“座位狀態(tài)數(shù)字化”。每一張座位在系統(tǒng)里都有明確狀態(tài)空閑、已預(yù)約、已簽到、暫離、禁用。用戶預(yù)約之前一眼看清哪些座位能用預(yù)約之后到現(xiàn)場(chǎng)簽到入座離開(kāi)時(shí)釋放座位。管理員不用再跑現(xiàn)場(chǎng)后臺(tái)就能看到實(shí)時(shí)占用率還能設(shè)置每個(gè)自習(xí)室的開(kāi)放時(shí)段、預(yù)約時(shí)長(zhǎng)上限。本質(zhì)上這就是一個(gè)帶時(shí)間維度的資源管理系統(tǒng)和會(huì)議室預(yù)約、健身房場(chǎng)地預(yù)約的邏輯是相通的。1.2 功能拆解與用戶角色設(shè)計(jì)用戶角色我分成三類普通學(xué)生用戶、管理員、超級(jí)管理員。沒(méi)有做“教師”角色因?yàn)樽粤?xí)室場(chǎng)景里教師通常只參與審批或者設(shè)備管理沒(méi)必要為了湊功能硬加。普通用戶側(cè)的關(guān)鍵功能注冊(cè)登錄、個(gè)人信息維護(hù)查看自習(xí)室列表按樓棟、區(qū)域篩選查看每個(gè)自習(xí)室的座位圖區(qū)分不同座位狀態(tài)預(yù)約座位選擇日期和起止時(shí)間簽到入座、暫離、釋放座位查看自己的預(yù)約記錄、違規(guī)記錄管理員側(cè)的關(guān)鍵功能自習(xí)室管理新增、編輯、啟停用座位管理批量生成座位、設(shè)置座位類型靠窗/普通/帶電源、禁用某個(gè)座位預(yù)約規(guī)則管理設(shè)置可預(yù)約天數(shù)、單次最長(zhǎng)時(shí)長(zhǎng)、簽到時(shí)限預(yù)約記錄查詢與統(tǒng)計(jì)導(dǎo)出表格用戶管理封禁、解封、重置密碼開(kāi)發(fā)展示中最容易被問(wèn)的就是“這個(gè)系統(tǒng)有什么亮點(diǎn)”。我當(dāng)時(shí)給出來(lái)的方案是“座位狀態(tài)實(shí)時(shí)同步預(yù)約沖突兜底”。也就是用戶在選座時(shí)看到的座位狀態(tài)是準(zhǔn)實(shí)時(shí)的提交預(yù)約時(shí)后端再做一次防沖突校驗(yàn)避免兩個(gè)人同時(shí)鎖到同一個(gè)座位。2. 技術(shù)選型與架構(gòu)設(shè)計(jì)思路2.1 為什么是SpringBootVue這套組合先說(shuō)后端。SpringBoot在這個(gè)場(chǎng)景里幾乎是無(wú)可爭(zhēng)議的選擇原因很簡(jiǎn)單內(nèi)嵌Tomcat不需要額外部署Web容器自動(dòng)配置把大量樣板代碼省掉生態(tài)成熟社區(qū)資料多遇到問(wèn)題基本都能搜到答案。相比之下如果再用傳統(tǒng)的SSHSpringStrutsHibernate那一套光是寫各種XML配置就能勸退一堆初學(xué)者。我用的版本組合比較穩(wěn)SpringBoot 2.7.x JDK 1.8 MySQL 5.7/8.0 MyBatis 2.x。為什么要鎖這個(gè)版本因?yàn)镾pringBoot 3.x強(qiáng)制要求JDK 17而且部分老項(xiàng)目用的MyBatis、PageHelper插件在3.x下需要額外適配如果你照著網(wǎng)上的教程抄作業(yè)大概率會(huì)踩版本不一致的坑。所以我的建議是除非你有明確理由否則畢設(shè)/課設(shè)別追新版本。前端選Vue就更好理解了。Vue 2.x Element UI是當(dāng)前中文社區(qū)里資料最多、最穩(wěn)定的組合Vue 3 Element Plus雖然新但有些組件用法變動(dòng)比較大網(wǎng)上的老舊教程容易誤導(dǎo)。我這次用的是Vue 2.6 Element UI 2.15配合vue-router和axios足夠支撐這種后臺(tái)管理用戶選座的場(chǎng)景。2.2 MVC分層在后端怎么落地標(biāo)題里特意提到MVC這個(gè)必須解釋清楚。MVC本身是一個(gè)設(shè)計(jì)思想不是一套固定框架。我后端的代碼結(jié)構(gòu)就是按照Controller、Service、MapperDAO三個(gè)層次來(lái)的Model用實(shí)體類和VO來(lái)表現(xiàn)。典型的調(diào)用鏈路是這樣的瀏覽器發(fā)起請(qǐng)求到Controller層Controller負(fù)責(zé)參數(shù)接收、簡(jiǎn)單校驗(yàn)然后調(diào)用Service層Service層處理業(yè)務(wù)邏輯比如校驗(yàn)預(yù)約沖突、計(jì)算座位狀態(tài)Service調(diào)用Mapper接口Mapper對(duì)應(yīng)XML里的SQLMySQL返回結(jié)果Mapper映射成實(shí)體類經(jīng)過(guò)Service組裝成VO最后由Controller返回JSON給前端這樣的分層好處很明顯至少有三點(diǎn)各層職責(zé)單一代碼可讀性好。別人拿到項(xiàng)目不需要翻完整套代碼只看Controller就知道系統(tǒng)提供了哪些接口。Service層獨(dú)立后業(yè)務(wù)規(guī)則可以單獨(dú)做單元測(cè)試。比如預(yù)約沖突檢測(cè)這種核心邏輯不依賴Controller和前端就能跑通。后期替換技術(shù)方案更方便。比如把MyBatis換成MyBatis-Plus或者把MySQL換成PostgreSQL底層影響可以被控制在Mapper層。實(shí)體類這塊我做了一個(gè)區(qū)分?jǐn)?shù)據(jù)庫(kù)表對(duì)應(yīng)的叫Entity接口返回前端的叫VO前端提交參數(shù)用DTO。之前的項(xiàng)目吃了不區(qū)分的虧查了一個(gè)用戶信息順便把密碼hash也返回了前端雖然前端不顯示但這事很不專業(yè)。2.3 前端Vue項(xiàng)目的目錄組織Vue項(xiàng)目不是簡(jiǎn)單的“一個(gè)頁(yè)面一個(gè)組件”就完了。我按功能模塊拆分成view頁(yè)面級(jí)組件和component可復(fù)用組件兩大類。src/apiaxios請(qǐng)求封裝按模塊拆分成user.js、seat.js、reservation.jssrc/router路由配置文件區(qū)分需要登錄的頁(yè)面和不需要登錄的頁(yè)面src/storeVuex存放用戶登錄信息、當(dāng)前選中的自習(xí)室狀態(tài)src/views頁(yè)面級(jí)組件比如Login.vue、SeatMap.vue、Admin/ReservationManage.vuesrc/components通用組件比如座位格子SeatItem.vue、分頁(yè)組件封裝的PaginationTable.vue實(shí)際開(kāi)發(fā)中很多初學(xué)者會(huì)把所有邏輯全部塞進(jìn)一個(gè)頁(yè)面組件幾百行代碼堆在一個(gè)Vue文件里后面想改一個(gè)選座邏輯都要翻半天。我這次強(qiáng)行把座位圖抽成了獨(dú)立組件狀態(tài)由父頁(yè)面?zhèn)魅虢换ネㄟ^(guò)事件回調(diào)這樣座位圖組件可以單獨(dú)測(cè)試也能復(fù)用到管理端的座位預(yù)覽功能里。3. 數(shù)據(jù)庫(kù)設(shè)計(jì)預(yù)約系統(tǒng)的命門3.1 核心表結(jié)構(gòu)設(shè)計(jì)數(shù)據(jù)庫(kù)設(shè)計(jì)是這種系統(tǒng)里最考驗(yàn)功力的部分。表設(shè)計(jì)不好后面寫業(yè)務(wù)代碼就是連環(huán)坑。我規(guī)劃了這幾張核心表sys_user用戶表字段包括id、username、password、real_name、role、status、create_timestudy_room自習(xí)室表字段包括id、name、location、floor、open_time、close_time、status、capacityseat座位表字段包括id、room_id、seat_no、type、position_x、position_y、statusreservation預(yù)約記錄表字段包括id、user_id、seat_id、room_id、reserve_date、start_time、end_time、statusviolation_record違規(guī)記錄表記錄超時(shí)未簽到、超時(shí)未釋放等情況用戶表里role字段我直接用的字符串USER、ADMIN、SUPER_ADMIN。也有人用int類型再在代碼里映射枚舉我個(gè)人覺(jué)得字符串更直觀查數(shù)據(jù)庫(kù)的時(shí)候一眼能看懂也不容易被數(shù)字映射搞糊涂。座位表里的position_x和position_y是干嘛的這是為了前端渲染座位圖準(zhǔn)備的。每張座位在自習(xí)室的平面圖里有一個(gè)坐標(biāo)前端拿到數(shù)據(jù)后可以直接按坐標(biāo)渲染到對(duì)應(yīng)位置比后端拼接好HTML再返回強(qiáng)多了。當(dāng)然純粹做簡(jiǎn)單系統(tǒng)也可以讓前端寫死布局但那樣教室里臨時(shí)加把椅子就得改代碼。3.2 預(yù)約時(shí)間沖突的處理思路預(yù)約系統(tǒng)的核心難點(diǎn)不是CRUD而是“同一座位同一時(shí)間段不能被兩個(gè)人預(yù)約”。這個(gè)沖突檢測(cè)我一開(kāi)始想用純SQL來(lái)做后來(lái)發(fā)現(xiàn)反而復(fù)雜干脆在Service層加鎖校驗(yàn)。邏輯是用戶提交預(yù)約時(shí)后端根據(jù)seat_id和reserve_date去查已經(jīng)存在的預(yù)約記錄只要新預(yù)約的時(shí)間段和已有記錄存在重疊就拒絕。SQL大概是這樣的select idselectConflict resultTypejava.lang.Integer SELECT COUNT(*) FROM reservation WHERE seat_id #{seatId} AND reserve_date #{reserveDate} AND status IN (BOOKED, CHECKED_IN, AWAY) AND NOT ( #{newEndTime} lt; start_time OR #{newStartTime} gt; end_time ) /select這里的時(shí)間重疊判斷就是兩個(gè)區(qū)間的交集判斷新預(yù)約開(kāi)始時(shí)間不早于已有記錄的結(jié)束時(shí)間或者新預(yù)約結(jié)束時(shí)間不晚于已有記錄的開(kāi)始時(shí)間才算不沖突。反過(guò)來(lái)只要兩個(gè)時(shí)間段存在任何交叉區(qū)域就說(shuō)明有人占用了。只做查詢校驗(yàn)還不夠。兩個(gè)請(qǐng)求同時(shí)提交理論上都能通過(guò)校驗(yàn)然后都插入成功這就產(chǎn)生了并發(fā)問(wèn)題。解決辦法一個(gè)是給座位加行鎖用SELECT ... FOR UPDATE把座位記錄鎖住再校驗(yàn)另一個(gè)是對(duì)reservation表加唯一索引配合狀態(tài)字段。我最終采用的是“事務(wù)座位行鎖”的方案這也是商用系統(tǒng)中比較穩(wěn)妥的做法。3.3 索引設(shè)計(jì)索引不是用來(lái)炫技的而是要命中實(shí)際查詢場(chǎng)景。這個(gè)系統(tǒng)里查詢頻率最高的場(chǎng)景就兩個(gè)用戶查詢自己某一時(shí)間段的預(yù)約記錄按座位查詢某個(gè)日期的預(yù)約占用情況所以我在reservation表上建了兩個(gè)復(fù)合索引idx_user_time (user_id, reserve_date, start_time)idx_seat_time (seat_id, reserve_date, start_time)建索引的理由很直接預(yù)約記錄表會(huì)越來(lái)越大沒(méi)有索引的話WHERE user_id ? AND reserve_date BETWEEN ? AND ?這種查詢就是全表掃描數(shù)據(jù)量到幾萬(wàn)條之后響應(yīng)時(shí)間會(huì)明顯變差。加了復(fù)合索引后查詢可以走索引快速定位排序也順手能利用上索引。再?gòu)?qiáng)調(diào)一個(gè)細(xì)節(jié)不要給每個(gè)字段單獨(dú)建索引那樣不但不加速反而拖慢寫入速度。MySQL的索引機(jī)制決定了復(fù)合索引的字段順序也有講究最常用的等值條件字段放前面范圍條件字段放后面。4. 后端核心實(shí)現(xiàn)與關(guān)鍵細(xì)節(jié)4.1 登錄認(rèn)證與用戶上下文登錄這塊我用的方案是JWTJSON Web Token。跟Session那套比JWT最大的好處是無(wú)狀態(tài)后端不用存儲(chǔ)會(huì)話記錄橫向擴(kuò)展的時(shí)候不用做會(huì)話同步。對(duì)畢設(shè)項(xiàng)目來(lái)說(shuō)前端拿到token后存到localStorage里每次請(qǐng)求在axios攔截器里帶上Authorization頭就行。具體實(shí)現(xiàn)上我用JWT生成token時(shí)把user_id作為payload核心字段。用戶每次請(qǐng)求受保護(hù)接口時(shí)后端攔截器解析token拿到user_id后去redis或者直接查數(shù)據(jù)庫(kù)取用戶信息放入ThreadLocal里作為本次請(qǐng)求的用戶上下文。注意我在這里沒(méi)有用Spring Security因?yàn)閷?duì)自習(xí)室預(yù)約這種場(chǎng)景來(lái)說(shuō)Spring Security的學(xué)習(xí)成本和配置成本有點(diǎn)重。自己寫一個(gè)HandlerInterceptor 自定義注解RequireRole代碼量不大邏輯還更好懂。自定義注解是這樣一個(gè)思路Target(ElementType.METHOD) Retention(RetentionPolicy.RUNTIME) public interface RequireRole { String value() default USER; }在攔截器中根據(jù)Controller方法上的注解判斷當(dāng)前用戶是否擁有對(duì)應(yīng)角色。管理端接口標(biāo)記RequireRole(ADMIN)用戶端接口標(biāo)記RequireRole(USER)超級(jí)管理員兩個(gè)角色都能訪問(wèn)。4.2 預(yù)約與取消的核心業(yè)務(wù)邏輯預(yù)約的核心邏輯我在Service里用事務(wù)包裹起來(lái)大致流程是這樣的校驗(yàn)用戶是否有預(yù)約權(quán)限是否已被封禁、是否已經(jīng)約了同一時(shí)段鎖定座位記錄SELECT ... FOR UPDATE查詢沖突預(yù)約判斷時(shí)間段是否重疊插入一條預(yù)約記錄狀態(tài)為BOOKED更新座位狀態(tài)為OCCUPIED為什么要先鎖座位再查沖突因?yàn)槿绻绘i并發(fā)場(chǎng)景下兩個(gè)人同時(shí)查到“無(wú)沖突”然后都插入成功就出現(xiàn)了超賣問(wèn)題。鎖座位雖然犧牲了一點(diǎn)并發(fā)量但對(duì)于自習(xí)室這種場(chǎng)景完全沒(méi)有壓力單把椅子一天最多也就被約幾次沒(méi)有效能瓶頸。取消預(yù)約的規(guī)則有個(gè)細(xì)節(jié)距離預(yù)約開(kāi)始時(shí)間不足30分鐘不允許用戶在線取消必須到現(xiàn)場(chǎng)找管理員操作。這個(gè)規(guī)則在管理端可以配置但默認(rèn)值我是直接寫在Service層常量里。為了這個(gè)規(guī)則我在事務(wù)里能直接判斷當(dāng)前時(shí)間是否滿足條件很快也不用額外設(shè)計(jì)提醒表。流程是刪除或標(biāo)記預(yù)約記錄為CANCELLED同時(shí)釋放座位狀態(tài)。我選擇的是保留預(yù)約記錄、把狀態(tài)改成CANCELLED而不是物理刪除。這樣保留歷史數(shù)據(jù)后面做統(tǒng)計(jì)分析比如“哪些座位最受歡迎”才有數(shù)據(jù)可用。4.3 MyBatis動(dòng)態(tài)SQL與緩存配置MyBatis在這個(gè)項(xiàng)目里承擔(dān)所有數(shù)據(jù)庫(kù)訪問(wèn)工作。我坦白說(shuō)一開(kāi)始我也糾結(jié)要不要用MyBatis-Plus因?yàn)樗娴哪苁〉舸罅繂伪鞢RUD代碼。后來(lái)考慮到很多課設(shè)答辯的老師要求“使用MyBatis實(shí)現(xiàn)”所以我保留了原生MyBatis的XML寫法把多表查詢和動(dòng)態(tài)SQL都寫清楚了。動(dòng)態(tài)SQL在預(yù)約記錄查詢里特別好用。管理端查詢預(yù)約記錄時(shí)篩選條件可能是“按日期查”“按自習(xí)室查”“按用戶姓名查”也可能全部不選查全量。這種場(chǎng)景用動(dòng)態(tài)SQL最合適select idselectReservationPage resultTypecom.example.entity.Reservation SELECT r.*, u.username, s.seat_no FROM reservation r LEFT JOIN sys_user u ON r.user_id u.id LEFT JOIN seat s ON r.seat_id s.id where if testroomId ! null AND r.room_id #{roomId} /if if testreserveDate ! null AND r.reserve_date #{reserveDate} /if if teststatus ! null and status ! AND r.status #{status} /if /where ORDER BY r.reserve_date DESC, r.start_time DESC /selectwhere標(biāo)簽會(huì)自動(dòng)處理“第一個(gè)條件前面的AND會(huì)被去掉”的問(wèn)題不用自己手動(dòng)拼接字符串避免SQL注入的同時(shí)代碼也干凈很多。MyBatis的二級(jí)緩存我也聊一下。默認(rèn)情況下MyBatis的二級(jí)緩存是關(guān)閉的我沒(méi)有在全局開(kāi)啟而是只對(duì)seat表的Mapper開(kāi)了二級(jí)緩存。原因很簡(jiǎn)單預(yù)約記錄和用戶表的實(shí)時(shí)性要求高緩存命中率低而且一旦數(shù)據(jù)變更還要考慮緩存刷新容易臟讀。座位表相對(duì)穩(wěn)定狀態(tài)變更頻率不高開(kāi)啟二級(jí)緩存后可以少打幾次數(shù)據(jù)庫(kù)。不過(guò)要注意現(xiàn)在很多項(xiàng)目直接用Spring Cache Redis做緩存MyBatis的二級(jí)緩存用得少了因?yàn)槎嗉?jí)緩存的一致性維護(hù)成本偏高。4.4 管理端功能實(shí)現(xiàn)管理端的核心功能是自習(xí)室和座位管理我用了一個(gè)比較省事的思路座位批量生成。一個(gè)自習(xí)室可能有幾十上百個(gè)座位一個(gè)個(gè)人工錄入不現(xiàn)實(shí)。我的方案是在新增自習(xí)室時(shí)讓管理員輸入“行數(shù)”和“列數(shù)”系統(tǒng)自動(dòng)生成座位編號(hào)例如A01、A02B01、B02并按照坐標(biāo)規(guī)則寫入seat表。這樣既省了管理員的工作量又保證了前端座位圖的位置數(shù)據(jù)是完整的。座位批量生成的核心代碼大致是for (int row 1; row rowCount; row) { for (int col 1; col colCount; col) { Seat seat new Seat(); seat.setRoomId(roomId); seat.setSeatNo(String.format(%s%02d, (char)(A row - 1), col)); seat.setPositionX(col); seat.setPositionY(row); seat.setStatus(FREE); seatMapper.insert(seat); } }管理端還有一個(gè)實(shí)用功能是今日統(tǒng)計(jì)。首頁(yè)展示“今日預(yù)約數(shù)”“當(dāng)前在場(chǎng)人數(shù)”“自習(xí)室占用率”。占用率的計(jì)算方式是當(dāng)前已占用座位數(shù) / 總座位數(shù)查詢時(shí)先分組查每個(gè)自習(xí)室的座位總數(shù)再查當(dāng)前狀態(tài)為OCCUPIED的座位數(shù)兩個(gè)數(shù)據(jù)在Service層合并成統(tǒng)計(jì)VO返回前端。5. 前端頁(yè)面與交互實(shí)現(xiàn)5.1 Vue路由與頁(yè)面結(jié)構(gòu)前端路由用的是Vue Router。路由設(shè)計(jì)上我分了兩層不需要登錄就能訪問(wèn)的和必須登錄才能訪問(wèn)的。不需要登錄的路由/login登錄頁(yè)/register注冊(cè)頁(yè)必須登錄的路由放在/layout父路由的children里因?yàn)檫@一部分頁(yè)面都有共同的頂部導(dǎo)航和側(cè)邊欄布局。{ path: /layout, component: Layout, redirect: /layout/home, children: [ { path: home, component: Home, meta: { title: 首頁(yè) } }, { path: rooms, component: RoomList, meta: { title: 自習(xí)室 } }, { path: seat-map, component: SeatMap, meta: { title: 選座 } }, { path: my-reservation, component: MyReservation, meta: { title: 我的預(yù)約 } } ] }管理端路由單獨(dú)建了一份掛在/admin下面比如/admin/room-manage、/admin/seat-manage、/admin/reservation-manage。這里要注意的是前端路由的權(quán)限控制只是用戶體驗(yàn)層面的真正的權(quán)限校驗(yàn)必須依賴后端接口。前端不能訪問(wèn)的頁(yè)面只是看不到入口如果直接調(diào)后端接口沒(méi)有權(quán)限后端必須返回403。路由守衛(wèi)方面我在router.beforeEach里檢查本地有沒(méi)有tokenrouter.beforeEach((to, from, next) { const token localStorage.getItem(token); if (to.meta.requiresAuth !token) { next(/login); } else { next(); } });5.2 座位選座交互選座界面是整個(gè)前端最核心的交互頁(yè)面我在設(shè)計(jì)上參考了影院選座、演唱會(huì)選座那一套一個(gè)平面圖座位格子一個(gè)個(gè)平鋪在上面用顏色區(qū)分狀態(tài)。座位狀態(tài)的配色我定的是空閑白色/淺灰色已預(yù)約黃色已簽到綠色暫離橙色禁用深灰色打叉用戶點(diǎn)擊一個(gè)空閑座位后右側(cè)彈出預(yù)約面板選擇日期和起止時(shí)間點(diǎn)擊確認(rèn)后走預(yù)約接口。這個(gè)交互邏輯我封裝在SeatMap.vue里數(shù)據(jù)來(lái)源是后端接口返回的座位列表和座位狀態(tài)列表。這里有一個(gè)交互細(xì)節(jié)用戶選中座位后要在前端本地標(biāo)記“正在選中”狀態(tài)但這個(gè)狀態(tài)不能和后端實(shí)時(shí)同步等到真正提交時(shí)才返回給后端。所以為了防止兩個(gè)用戶同時(shí)選同一座位前端顯示的狀態(tài)只能作為參考后端提交時(shí)的沖突校驗(yàn)才是兜底。座位圖渲染的模板大概是div v-forseat in seatList :keyseat.id classseat-item :classgetSeatClass(seat) :style{ left: (seat.positionX - 1) * seatSize px, top: (seat.positionY - 1) * seatSize px } clickhandleSeatClick(seat) {{ seat.seatNo }} /div座位尺寸我固定用44px×44px間距6px這樣一張A4紙寬度的屏幕能放下十幾個(gè)座位體驗(yàn)比較自然。如果自習(xí)室座位特別多還可以在右側(cè)加一個(gè)縮小比例的迷你地圖用于快速定位。5.3 Axios封裝與權(quán)限控制axios不能每個(gè)組件里單獨(dú)引一遍要統(tǒng)一封裝。我在src/api/request.js里做了以下事情創(chuàng)建axios實(shí)例設(shè)置baseURL和timeoutbaseURL指向后端接口地址比如http://localhost:8080/api請(qǐng)求攔截器里從localStorage讀取token放到請(qǐng)求頭響應(yīng)攔截器里統(tǒng)一處理HTTP狀態(tài)碼401跳轉(zhuǎn)登錄頁(yè)403提示無(wú)權(quán)限500提示服務(wù)器錯(cuò)誤把后端返回的業(yè)務(wù)狀態(tài)碼也做了統(tǒng)一處理比如code500的提示語(yǔ)統(tǒng)一用Element UI的Message組件展示這種封裝的好處是后面如果后端接口地址變了只需要改一個(gè)文件如果后端的鑒權(quán)方式變了比如改為請(qǐng)求參數(shù)攜帶token也只需要改一個(gè)攔截器組件里的業(yè)務(wù)代碼完全不用動(dòng)。6. 從零到一完整部署運(yùn)行步驟6.1 本地環(huán)境準(zhǔn)備先說(shuō)一下我本地的環(huán)境JDK 1.8如果你是JDK 17也可以跑SpringBoot 2.7但部分老插件可能報(bào)錯(cuò)Maven 3.6MySQL 5.7或8.0Node.js 14Vue 2項(xiàng)目不建議用Node 18會(huì)有兼容問(wèn)題IDE后端用IDEA前端用VS Code環(huán)境這塊我吃過(guò)虧尤其Node版本。Vue 2的老項(xiàng)目用Node 17跑npm install經(jīng)常報(bào)Error: error:0308010C:digital envelope routines::unsupported這是因?yàn)樾掳鍺ode的OpenSSL策略變了。解決辦法要么把Node降級(jí)到14/16要么在package.json的啟動(dòng)腳本里加一句NODE_OPTIONS--openssl-legacy-provider。我更推薦前者降級(jí)到Node 14一了百了。6.2 數(shù)據(jù)庫(kù)初始化數(shù)據(jù)庫(kù)這塊我用Navicat新建一個(gè)study_room_db數(shù)據(jù)庫(kù)字符集選utf8mb4為什么不用utf8因?yàn)閡tf8在MySQL里是utf8mb3不支持emoji和一些特殊字符雖然系統(tǒng)里不太用emoji但保不準(zhǔn)用戶昵稱里有特殊符號(hào)。然后直接執(zhí)行init.sql腳本里面包含建表語(yǔ)句和初始數(shù)據(jù)。初始數(shù)據(jù)至少要有一個(gè)超級(jí)管理員賬號(hào)admin/admin123兩個(gè)自習(xí)室數(shù)據(jù)每個(gè)自習(xí)室對(duì)應(yīng)的座位數(shù)據(jù)我直接用批量插入SQL寫死了幾條演示用的預(yù)約記錄方便前端展示效果關(guān)于賬號(hào)密碼我在user表里存的是MD5加密后的值。明說(shuō)一句MD5現(xiàn)在已經(jīng)不夠安全了真正商用至少要用BCrypt。我這里圖省事用了MD5但代碼里把加密算法抽成了工具類想替換成BCrypt很容易。6.3 后端啟動(dòng)后端項(xiàng)目導(dǎo)入IDEA后第一步修改application.yml里的數(shù)據(jù)庫(kù)連接配置server: port: 8080 spring: datasource: url: jdbc:mysql://localhost:3306/study_room_db?useUnicodetruecharacterEncodingutf8mb4useSSLfalseserverTimezoneAsia/Shanghai username: root password: 你的數(shù)據(jù)庫(kù)密碼 driver-class-name: com.mysql.cj.jdbc.Driver mybatis: mapper-locations: classpath:mapper/*.xml type-aliases-package: com.example.entity configuration: map-underscore-to-camel-case: truemap-underscore-to-camel-case這個(gè)配置一定要開(kāi)啟否則數(shù)據(jù)庫(kù)字段seat_no映射到Java屬性seatNo會(huì)失敗查詢結(jié)果全是null。這是個(gè)非常典型的新手問(wèn)題排錯(cuò)能排半天。配置改完后先啟動(dòng)MySQL再運(yùn)行StudyRoomApplication主類。后端啟動(dòng)后瀏覽器直接訪問(wèn)http://localhost:8080/api/health如果能返回正常結(jié)果說(shuō)明后端已經(jīng)跑起來(lái)了。6.4 前端啟動(dòng)前端項(xiàng)目打開(kāi)終端按順序執(zhí)行npm install npm run devnpm install如果速度慢可以換成淘寶鏡像源先執(zhí)行npm config set registry https://registry.npmmirror.com再裝。啟動(dòng)后開(kāi)發(fā)服務(wù)器默認(rèn)跑在http://localhost:8081我特意把端口改到8081避免和后端8080混淆。Vue開(kāi)發(fā)服務(wù)器的端口可以在vue.config.js里配置module.exports { devServer: { port: 8081, proxy: { /api: { target: http://localhost:8080, changeOrigin: true } } } }這里用proxying而不是直接寫死http://localhost:8080作為baseURL是為了避免開(kāi)發(fā)階段的跨域問(wèn)題。瀏覽器訪問(wèn)8081端口請(qǐng)求通過(guò)Vue開(kāi)發(fā)服務(wù)器轉(zhuǎn)發(fā)到8080同源策略就不會(huì)攔截了。如果不用proxy要么后端配置CORS要么前端調(diào)接口時(shí)直接帶完整地址但會(huì)被瀏覽器攔截所以這個(gè)配置很關(guān)鍵。7. 常見(jiàn)問(wèn)題與排查經(jīng)驗(yàn)7.1 端口占用與配置不一致啟動(dòng)后端時(shí)最常遇到的報(bào)錯(cuò)就是Web server failed to start. Port 8080 was already in use.端口被占用的原因五花八門可能是你自己之前啟動(dòng)過(guò)一次沒(méi)關(guān)掉也可能是其他軟件搶占了端口。排查方法Windows下用netstat -ano | findstr 8080查看占用進(jìn)程PID用taskkill /PID 進(jìn)程號(hào) /F強(qiáng)制殺掉或者在application.yml里換一個(gè)端口但我更建議換端口而不是殺進(jìn)程因?yàn)闅⒌舻倪M(jìn)程有可能是別人正在用的服務(wù)。比如你機(jī)器上已經(jīng)跑了一個(gè)Tomcat在8080你非要用8080最好還是改自己的項(xiàng)目端口。7.2 數(shù)據(jù)庫(kù)連接失敗排查數(shù)據(jù)庫(kù)相關(guān)的報(bào)錯(cuò)幾乎占了新手問(wèn)題的一半。常見(jiàn)的幾個(gè)Communications link failure這個(gè)報(bào)錯(cuò)十有八九是數(shù)據(jù)庫(kù)沒(méi)啟動(dòng)或者連接地址寫錯(cuò)。先確認(rèn)MySQL服務(wù)在系統(tǒng)服務(wù)列表里是“運(yùn)行中”然后在命令行用mysql -u root -p直接連一下確認(rèn)賬號(hào)密碼沒(méi)問(wèn)題。Unknown database study_room_db這個(gè)就是數(shù)據(jù)庫(kù)沒(méi)創(chuàng)建或者名字寫錯(cuò)了。去Navicat里看看庫(kù)名是不是和url里的一致注意大小寫。The server time zone value ?D1ú±ê×?ê±?? is unrecognized這個(gè)報(bào)錯(cuò)是因?yàn)镸ySQL時(shí)區(qū)設(shè)置問(wèn)題在url上加serverTimezoneAsia/Shanghai就能解決。如果還報(bào)錯(cuò)就在MySQL的配置文件my.ini里加上default-time-zone 08:00。7.3 跨域問(wèn)題我用了devServer的proxy方案之后開(kāi)發(fā)階段基本不會(huì)遇到跨域。但如果你把前端打包成靜態(tài)文件在Nginx里部署或者直接打開(kāi)dist/index.html跨域問(wèn)題就會(huì)冒出來(lái)。本地開(kāi)發(fā)時(shí)如果不用proxy就必須在后端加CORS配置。一個(gè)簡(jiǎn)單的做法是在Controller上或者全局配置類上加CrossOrigin或CorsFilter。CORS配置時(shí)要指定允許的來(lái)源、方法和請(qǐng)求頭不能直接寫*加允許所有請(qǐng)求頭那是懶人配置不嚴(yán)謹(jǐn)。前端部署時(shí)更推薦Nginx反向代理的方式把/api/開(kāi)頭的請(qǐng)求轉(zhuǎn)給后端服務(wù)。Nginx配置大致是location /api/ { proxy_pass http://127.0.0.1:8080; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; }7.4 MyBatis相關(guān)坑MyBatis使用中我踩過(guò)最深刻的坑就是“SQL沒(méi)有問(wèn)題但查詢結(jié)果全是null”。這個(gè)我在前面提過(guò)就是map-underscore-to-camel-case沒(méi)開(kāi)啟。如果你不喜歡全局開(kāi)這個(gè)配置也可以在XML里的resultMap里手動(dòng)映射每一列但是那樣的代碼量翻倍不推薦。另外一個(gè)坑是參數(shù)傳遞問(wèn)題。當(dāng)Mapper接口方法有兩個(gè)或以上參數(shù)時(shí)必須用Param注解標(biāo)注參數(shù)名否則MyBatis不知道#{userId}對(duì)應(yīng)哪個(gè)參數(shù)。我見(jiàn)過(guò)太多人寫這樣的代碼然后報(bào)Parameter xxx not found的錯(cuò)誤。還有MyBatis的if判斷字符串比較時(shí)寫成if teststatus BOOKED有時(shí)候不生效原因在于MyBatis解析OGNL表達(dá)式時(shí)單引號(hào)內(nèi)的內(nèi)容會(huì)被解析成字符而非字符串。正確寫法是if teststatus BOOKED外層用單引號(hào)內(nèi)層用雙引號(hào)。這個(gè)真是很陰間的細(xì)節(jié)。7.5 預(yù)約并發(fā)沖突實(shí)戰(zhàn)最后說(shuō)一個(gè)真實(shí)遇到過(guò)的業(yè)務(wù)問(wèn)題。系統(tǒng)上線模擬壓力測(cè)試時(shí)兩個(gè)用戶同時(shí)點(diǎn)預(yù)約同一個(gè)座位結(jié)果兩個(gè)都成功了。我排查后發(fā)現(xiàn)問(wèn)題出在事務(wù)邊界上我第一次把座位狀態(tài)校驗(yàn)放到了事務(wù)外等事務(wù)內(nèi)插入時(shí)才去更新座位中間丟了一個(gè)校驗(yàn)窗口。修正方案是在Service方法上加Transactional進(jìn)入事務(wù)后先執(zhí)行SELECT ... FOR UPDATE鎖定該座位記錄再執(zhí)行沖突查詢和插入操作。加上行鎖之后模擬并發(fā)請(qǐng)求就不會(huì)再出現(xiàn)超賣場(chǎng)景了。這個(gè)問(wèn)題的通用排查思路就是凡是涉及“資源唯一性”的業(yè)務(wù)座位、庫(kù)存、優(yōu)惠券都必須考慮并發(fā)。只有業(yè)務(wù)校驗(yàn)沒(méi)有數(shù)據(jù)庫(kù)鎖或者唯一約束遲早出問(wèn)題。8. 項(xiàng)目擴(kuò)展與個(gè)人心得做完這套系統(tǒng)再回頭去看我會(huì)覺(jué)得技術(shù)棧本身并不復(fù)雜真正花時(shí)間的其實(shí)是業(yè)務(wù)規(guī)則的設(shè)計(jì)和落地。預(yù)約時(shí)間沖突判斷、簽到時(shí)限、暫離時(shí)長(zhǎng)限制每一個(gè)規(guī)則邊界都需要想清楚否則上線之后運(yùn)營(yíng)人員會(huì)被各種邊界case折磨。很多人以為做一個(gè)管理系統(tǒng)就是增刪改查做完才發(fā)現(xiàn)增刪改查只是最外面一層皮真正的核心在于“狀態(tài)機(jī)怎么流轉(zhuǎn)”“并發(fā)下如何保持一致”“用戶體驗(yàn)怎么做得好”。如果你也正在做類似的系統(tǒng)我的建議是先把業(yè)務(wù)流程圖畫明白把每個(gè)狀態(tài)之間的跳轉(zhuǎn)條件和限制想清楚再動(dòng)手寫代碼。數(shù)據(jù)庫(kù)設(shè)計(jì)可以花一整天反復(fù)推敲這比代碼寫了一半再改表結(jié)構(gòu)要?jiǎng)澦愕枚唷_@個(gè)項(xiàng)目后續(xù)可以擴(kuò)展的方向也很多。比如加入一個(gè)基于WebSocket的實(shí)時(shí)座位狀態(tài)推送有人釋放座位時(shí)其他在線用戶立刻看到或者引入Redis緩存熱點(diǎn)數(shù)據(jù)減輕數(shù)據(jù)庫(kù)壓力再或者把前端升級(jí)成Vue 3 TypeScript代碼的可維護(hù)性會(huì)再上一個(gè)臺(tái)階。但這些都是增量?jī)?yōu)化核心骨架不變。最后說(shuō)一個(gè)實(shí)際開(kāi)發(fā)里的細(xì)節(jié)我在項(xiàng)目里對(duì)所有時(shí)間字段統(tǒng)一用了LocalDateTime而不是Date。這樣在做時(shí)間段比較的時(shí)候比Date要順手很多也避免了時(shí)區(qū)偏移導(dǎo)致的坑。如果你正在選型階段一開(kāi)始就統(tǒng)一用LocalDateTime能省掉后面不少麻煩。
返回列表
PREV
查看更多資訊
NEXT
返回資訊列表
夜夜精品视频一区二区| 色九九九| 欧美天天干| 国内精品999| 成人aⅴ一区二区三区| 国产不卡的视频| 日韩pv中文| 日本在线播放不卡一区| 免费岛国一级片| 亚洲综合校园春色| 国产又大又粗又长视频在线| 午夜免费福利视频一区| 中文字幕日韩人妻视频一区二区三区 | 午夜小电影在线插入淫高潮| 91色欧美| 色综九九九一区| 亚洲三级网址久久最新| 97五月天| 亚洲美乱| 伊人色综合超碰| 亚洲精品亚洲人成人网| 无遮挡猛进视频免费无限观看| 欧美色综合| sewuyueav| 综合97久久| 久久97资源 网| 日本大片日本一区二区免费高清| 亚洲欧美一区二区三区一猛片| 高清有码一区二区| 自拍偷拍亚洲熟女妇人精品| 亚洲无码?第一页| 欧美精品23| a片在线播放| 蜜臀久久99精品久久久电影| 97这里有精品| 男人的天堂va| 久久久亚洲| 精品国产乱码久久久| 天操天操夜操夜月月年年操操| 亚洲视频小说| 日韩BBN| 2020天天色综合| 欧美草草| 国产91 丝袜在线播放00-百度| 99色在线| 中文字幕熟女人妻丝袜| 91情色| 国产精品久久久久久久久久久久| 欧美高清第一页| 欧美色交| 97视频在线看| 蜜乳AV.COM| 午夜福利无毒不卡| 亚洲欧美一区二区三区一猛片| 乱伦一区二区三区‘| 芊芊操逼视频无码| 一区二区三区在线资源| 鸥美插入视频| av草草在线电影| 蜜桃午夜视频一区二区 | 免费国产电影一区二区| 日本色婷婷| 艳美熟妇先锋一二三区| 亚洲欧美日韩电影网站一区| 一卡二卡三卡| 内射小黄片| 高清无码 国产精品| 丁香六月综合激情| www老逼91| 最新中文字幕av| 2017超碰| 久久二| 亚洲成人精品在线一区| 成人免费不卡在线视频| 男人的天堂2019AV| 加勒比av官网在线| 青娱乐淫乱1314| 日本免费人成视频播放120秒| 无码高清国产AV| 国产高潮AA片免费看| 久久精精区一区二区一蜜桃一区二区| 狠色婷婷久久一区二区三区_| 91精品操美女| 人妻干天天| 国产又色又爽又舒服的三级视频 | 久久久999国产精品| 熟妇综合一区二区三区| 国产女人91精品嗷嗷嗷嗷| 色播五月丁香| 安微少妇操BBB| 中文字幕一区二区视频在线观看| 精品国产乱码久久久久久口爆网站 | 色色色综合网| 欧美九一精品久久久熟妇| 男人在线天堂| 国产精品老师| 天天综合网合集91| 精品午夜福利国产一区二区在线观看| 色色99| 久久久久久久久久久久欧美日| 国产一线二线三线av| 蜜臀无码视频在线观看| 久久黄黄| 国产午夜精品在线观看| 九九色色| 超碰人人干天天射| 亚洲女毛多水多21P| 草蕉影视亚洲无码| 国产9l 大屁股| 亚洲AV秘 精品久久老牛影视| 欧美美女啪啪视频| 91男同| 99热这里只有精| 亚洲日本天堂| 韩国黄片aaaa| 日本免费一级AAA大片器| 职场同事知名国产国产精品久久欧美日韩 | 999综合网| 婷婷激情五月天小说网| a级理论午夜日本| 成人日韩3| 久久精品区| 天天干天天拍| 91 国产丝袜在线播放-百度| 美国日韩黄片| 亚洲加勒比| 人人澡人人澡人人| 色偷偷人人玩人人舔人人操人人摸人人爽 | 欧美青青草视频| 欧美日日夜夜| 国产极品999| 欧美性猛交美女自慰91| 天天干天天干天天干| 国产亚洲精品农村妇女| 日韩中文字幕视频| 亚洲欧美日韩制服另类| 亚洲欧洲成人在线电影| 青青爽| 青青草原成人| 人妻在线臀日韩| 国产欧美伊人| 久久久久ab| 欲香欲色天天天综合和网| 精品人妻夜夜草| 九九热视频这里只有精品| 97内射偷拍| 人妻在线大香蕉| 97视频新免费| 少妇天堂| 热久久这里只有精品| A 天堂在线观看视频| 乱伦3P视频| 91精品久久综合熟女| 国产99 中文字幕日韩小视频| 日韩三级天堂在线观看| 99re6久热只有精品6在线直播| 日本一区二区三区欧美日韩中文字幕| 五月天色电影| 久久久久久综合久久伊人蜜月| 日本操逼视频免费| 国内偷自视频区视频综合| 一级性爱aaaa| 97内射偷拍| 婷婷人妻激情| 亚洲精品国产熟女久久久久久| 免费综合亚洲中文| 熟妇激情| 国内毛片婷婷六月色| 天天天天干| 强奸熟女一区二区三区| 国产欧美在线观看免费观看| 欧美精品1区2区3区| 亚热日本熟女| 在线观看高清AV| 中亚精品极乱| 久久精品国产99久久,亚洲日韩久久日本一区一区三区 | A一级色女| 97天天综合| 噜噜噜狠狠色综合| 日本无码1| 伊人影院在线理论播放| 婷婷人妻激情| 先锋激情∨在线视频播放| 久久久∴| 91搞逼视频| 亚洲欧美爆| 另类图片亚洲加勒比另类图片亚洲加勒比另类图片亚洲加勒比 | 久久内射| 麻豆2区1区天美| 激情欧美97| 亚州色图第三区| 黄色工厂这里只有精品| 99国内精品| 无码人妻精品一区二区三区99不卡| 久操操| 九九亚洲| 国产女同性恋视频| 日本理论在线| 97爱综合| 在线电影亚洲色图| 久久精品国产亚洲AV高级北京| 欧美激情一| 天天日天天插| 伊人五月天激情| 日曰骚久久精品| 青青操在线亚洲视频观看欧美在线| 人人妻人人爽 97人人看碰人免费公开视频| 一区二区首页| 亚洲精品久| 大香网站| 国产女乱淫真高清免费视频| 一区二区乱码福利| 激情欧美97| 欧美大干日韩| 青草园大香蕉| 色香伊人| 职场同事知名国产国产精品久久欧美日韩 | 中文字幕亚洲热播人妻| 啊v视频在线观看| 五月综合激情| h无码动漫在线观看| 欧美色院| 久热热| 五月天综合在线| 亚洲第一狼人丝袜美女另类 | 日韩AV一起草| 欧美日本国产日韩激情视频| 欧美日韩色综合网| 伊人五月天婷婷| 中文字幕三四五区| 果冻传媒A片麻豆熟妇人妻| 后入福利视频| 精品人妻一区二区蜜桃视频 | 欧美日韩大陆黑人少妇99| 志村玲子视频一区二区| 噜噜在线| 东京热AV男人的天堂| 色婷婷综合久久中文字幕雪峰| 99热99色| 久久久一区二区三区四曲免费听| 人妻精品视频一区二区| 97电影院超碰| 国产视频三区四区| 欧美 亚洲 综合 制服 另类| 好爽免费视频,| 日日干夜夜欢| 亚洲色图A| 人妻第一页| 亚洲无码视频免费在线观看网址!| av天堂加勒比| 欧美成人免费在线观看| 欧亚性爱啪啪| 婷婷五月综合激情| 中文久久一区| 日韩精品人妻中文字幕不卡乱码| 蜜桃臀av一区二区| 欧美综合第一页| 久久社区一区二区三区| 第四色奇米影视777| 天堂中文日本在线观看| 热久久精品| 少妇高潮喷水无套久久久久久| 日日骚av| 欧美aaaaaaa| 精品久久一区二区三区四区五区| 日日橹狠狠爱欧美超碰| 啊啊啊免费| 女人双腿搬开让男人桶| 国产精品国产自产拍高清AV| 亚洲伊人青青草| 国产精品99999| 永久免费发布性爱网| 无码9区| 综合视频91| 在线国产探花| 少妇xx精品| 99久久无色码| 欧美激情片一区二区| 久久性视频| 伦理第一页| 亚洲精品一二牛牛| 日本最新1区2区3区| 色色热| 亚洲黄网在哪免费看| 日本欧美亚洲高清在线看| 99国产在线 精品 视频| 午夜超碰| 美女诱惑久久| 色综合国产在线观看| 男人天堂电影院| 欧美黑人极品高潮喷吹熟女黑人性暴力日韩在线欧美极品一区二区老师黑人潮喷一 | 色一色综合网| 五月丁香狠狠爱| 99激情| 狠色婷婷久久一区二区三区_| 色偷偷人人玩人人舔人人操人人摸人人爽| 亚洲欧洲综合| www.久久| 男人的天堂2019AV| 婷婷五月天无码| 伊人9| 97天堂| 综合亚洲欧美精品日韩?v| 92性色国产午夜福利在线661| 日韩性爱毛片操骚逼| 99热色精品| 97超碰总站| 国产毛片片精品天天看视频| 五月婷色| 99热在线只有精品| 美女网站黄页| 老司机射| 日韩99神马视频播放片在线播放| 9 7超碰在线免费观看| 日韩无码服务区| 国产精品福利视频播放| 亚码激情| 色色97爱| 最新欧洲欧美日本激情网站| 精品高清牛人盗摄一区二区三区中文字幕A片免费在线观看 | 又摸又舔在线观看网站| 91老妇女| 思思久热在线精品66| 亚州操逼图| 综合网,亚洲,欧美| 无套后入双马尾| 中文字幕一区日韩精| 青青伊人加勒比海| 五月天婷婷基地| 美女久久久| 天美麻花大全视频| 五月天日日操夜夜操| 日韩丰满熟妇| 都市激情人妻一区二区青青操视频| 日韩本不卡视频在线观看| 成人小说视频在线精品欧美| 欧美色日本| 美国黄片aaa| 亚洲情色在线| 福利在线观看一区二区| 91亚洲情色| 色诱中文字幕| 日韩卡一卡二卡三在线| 亚州 综合 色图| 亚洲日韩美国人妻| 青女偷拍网| 亚洲精品视频在线播放| 屁股久久久久久| 一区| 欧美色图天堂在线| 免费看欧美美女黄色大片| 亚洲中文sv| 91 刺激在线| 99国产精品| 大香网伊人久久综合网eew| 免费一级黄色录像影片| 快播电影网日韩新片| 日本韩国一本产品小视频日本韩国一本产品久久久产品小视频日本韩国一本产品久 | 色色婷| 少妇熟女1区2区3区| 天天干天天中出av| 激情99| 成人性爱AV在线免费观看| 亚洲综合情色| 色女网日韩| 日韩人妻一区二区精品| 免费av高清无码| 偷拍 亚洲 欧美| 2017,超碰| 制服诱惑亚洲一区二区三区在线观看| 91女在线观看| 99热色精品| 天天躁日日躁AAA片李宗瑞| 久久久999| 青草视频人妻在线观看| 亚欧美天堂在线| 中文高清一区二区的| 天天射影院| 日本天天操| 睡产熟女乱伦| 99自拍视频| 99热18| 亚洲aV性爱| 熟女视频久久| 人妻天天夜夜爽一区二区| 婷婷大香蕉| av天堂手机版追回| 五月天婷婷综合| 99色综合| 97视频在线视频| 欧洲站一级二级三级h| 久操影视| 色偷偷超碰亚洲| 久久久久久久久久久精| 国产精品久久久 | 中出欧美| 国产精品一区二区手机看片| 亚洲91在线播放影院| 日本Xx性爱| 色欧美天天| 亚洲视频二区| 三级日韩一区二区三区| 91狼人| 偷拍 精品另类 凸凹了四区| 天天看人人操屄犊摸阴| 狠狠操狠狠燥| 亚洲色综合| 国产 亚洲 丝袜 制服| 日韩色| 99热超碰| 蜜臀久久99精品久久久久久酒店 | 久久超碰亚洲人| 婷婷激情丁香| 99e久久国产精品| 五月天激情小说| 男人天堂站| 91男人综合| 欧美性爱免费短视频| 精品久久青青草| 天天夜夜rb| 亚洲av无码成人精品国产| 97自拍一区| 成人线上超碰| 国产又黄又猛又粗又爽的网站| 黑人与人妻| 成人羞羞视频国产| 欧美色图偷拍另类| h4610国产人妻| 四虎AV影视国产精品亚洲精品| 欧美色图综合| 天美传媒AV国产在线| 欧美熟妇成人一区二区| 久草精品国产蜜臀| 国产h片在线观看视频| 我爱大香蕉| 九九九国产| 日韩pv中文| 天天干天天燥| 亚洲图片91| 涩五月婷婷| 91美女在线| 国产熟女少妇一区| 精品国产无码中文| 啊啊啊操死我了| 日本特黄f c2| 日韩在线97| www.久久制服糖| 性欧美| 天天躁日日躁AAA片李宗瑞| 校园春色美腿丝袜 | 色一射色一射| 亚洲另类欧美精品| 久热这里| 久久国模av| 婷婷丁香六月天| 天堂а√在线最新版在线| 深夜国产福利| 超碰 欧美| 天天日日本| 久久一区二区三区入口| se01国产在线视频| 67914在线兔费成人视频| 99综合| 亚州操逼网| 另类小说综合网| 色欲Av人妻精品一区二| 精品久久久av无码免费| 亚洲一区二区av| 亚热日本熟女| 999 久久久| 麻豆国产原创AV色哟哟 | 伊人久久大香蕉线AV五月天| 大香蕉九九| 久久精品国产亚洲AV无码电影| 色哟哟 日韩精品| 亚洲国产日韩精品久久久| 男人天堂无码| 久久 精品| 91狠狠综| 国产日韩无码一区二区三区久久区| 加勒比综合88| 日韩欧美亚欧在线视频| 久9re热视频这里只有精品| 97超碰超碰| 在线日韩精品一区二区三区| 91精品国产日韩欧美综合| 亚洲熟女乱综合一区二区在线-...亚洲国产日韩欧美一区二区三区,久久久久久精 | 高清成年美女黄网站免费大全| 色色毛片| 国产一区二区三区影片| 国产黄a三级三级三级av在线看| 久久大香蕉手机高清| 精品一久久久| 97操97干| 成人精品无码| 色综合久久88色综合久久天天| 日韩去日本高清在| 日本大香蕉| 日韩91网| 国产精品探花视频| 亚洲人妖网| 天天天干977| 特级特黄一级毛片免费| 牛黄色久午久| 东北操逼| 九九九精品美女| 亚洲国产奇米影视久久| 2020视频1区2区3区| 91nbbbbbb| 综合 亚洲 欧美| 精品人体无圣光凹凸| 99色视频| 欧美亚洲今日在线| 一块操欧美| 亚州九九九精品视频| 精品日韩人妻视频| 久久婷婷综合国际产色怕| 艳美熟妇先锋一二三区| 欧美色另类| 日本韩欧美在线播放a| 走光一区92下载| 91精品国产日韩欧美综合| 夜夜综合| 综合色播| 蜜臀中文字幕| 精品国产99| 欧美爱三级日韩久久| 美女97超碰| 性在久久久久久| 久湿久久| 日本韩欧美在线播放a| 91老熟女老女人国产老太| 不卡中文字幕aⅴ在线| 久久久久女教师免费一区 | 91香蕉国产尤物视频| 99re这里只有精品中心播放| 国产女同在线观看视频| 神马久久69| 日韩在线一区二区| 欧洲精品网| 无码自拍SM| 肉动漫无遮挡h在线观看| 国产久久一区二区| 99热综合| 欧美黄片免费在线观看视频| 97视频www| ?亚洲伊人伊成久久人综合网| 亚洲天堂电影网99999| 欧美综合国产精品久久丁香| 综合五月天| 亚洲老司机123专区| aaa一级黄片| CCYY草草影院地址入口| 亚洲综合射| 欧美国产日韩清纯唯美| 免费超碰97在线观看| 久热精品在线| 黄色十八禁| 人妻碰碰碰碰碰碰| 五月婷在线| 三级网色| 国产又黄又爽又刺激久久久久久| 蜜臀va69| 久综合国内精品自在自线| 无码人妻毛片丰满熟妇精品区| 国产精品久久久777| 无码色| 26uuu国产免费观看| 一区二区三| 日本道人妻久久久在线不卡色视频| 亚洲AV不卡在线观看尤物| 高凊专区人人操| 激情一区二区三区在线观看| 性开放中文AV高清无码免费看| 亚洲国产精品无码AV久久| 国产女上位好爽在线| 成功精品影院| 97操97色| 久久久内射良家| 国语精品av| 亚洲AV无码乱码| 久肏视频字幕| 蜜臀99精品国产高清在线观看| 熟女91网| 東南亚性呦成人伦理资源在线视频| 国产精品丝袜在线| 欧美大片91| 成年人网站在线免费观看| 亚洲欧美清纯| 国模私拍一区二区三区神乳| 91三级理论片播放器| 五月丁香激情综合网| 五月大香蕉| 亚洲另类综合欧美| 亚洲欧美性生活| 国产99999久久精品| 亚洲97| 亚洲伊人久久综合97| 亚洲欧美综合区自拍另类| 熟女六十路| 99啪| 欧美黑人168页欧美黑人167| 亚洲国产成人综合碰碰三级经典| 约操熟妇| 五月天婷婷色| 久久日本熟女精品一区| 黄色成年| 日韩在线观看字幕精品| 欧美一区二区传媒| 亚洲九九九| 啊灬啊灬啊灬好深灬快高潮了动漫-国产字幕国产在线观看-B049AV | 国产美女口爆吞精| 免费的黄片有限公司| 久久久免费一级黄片| 青青草吊丝| 啊啊啊啊啊舒服| 天天视频黄| 富二代亚洲精品99| 亚洲无码 国产无码| 性欧美另类高清| 友优传媒精品在线一区二区| 色成人Www精品永久观看| 亚州色国| 久精品无码av一区二免费国产在线观看| 国产偷仑| 日韩激情啪啪| 91观看 国产白丝| 亚洲av乱伦色图网站| 亚洲91射| 欧美另类色图片| 国产成人精品必看| 欧洲一区二区| 偷拍 精品另类 凸凹了四区| 欧美影院一区二区三区| 精品乱码久久久久| www99热| 草草电影院| 囯产精品强| 日韩一级免费性爱| 97欧美| 夜夜嗷嗷一区二区| 色婷婷九月天天综合| 麻豆亚洲AV成人无码久久精品| 99爱精品| 日韩欧美综合激情| 美女久久久久久久久久久| 96免费视频在线| 亚洲人人操| 亚洲色图欧美一区二区不卡| 丝袜美女诱惑 91 视频| 天堂精品在线| 日韩精品亚洲专区在线影视| 大香蕉78| 探花精品 一区二区| 亚洲欧美日韩国产丝袜自拍中文| 亚洲nv男人的天堂网| 亚洲阿v天堂无码z2018| 欧美极品美女aaaaaa级黄片| 一区二区无码视频| 神马久久啊啊| 久久久久久久久久久久久久久性生活视频| 91三级理论片播放器| 激情熟女12P| 综合网天天| 色九久| 91狠狠狠| 精品十八在线观看| 噜噜噜噜天天狠狠| 久久精品无码熟妇一区二区三区视频导航 | 狠狠色噜噜狠狠狠狠狠色综合久久| 女人综合网| 俺也射| 亚州精品丝袜-不卡成人免费| 人妻熟女一区在| 六月丁香网| 亚洲天堂色图| 麻豆区99999| 伊色综合天堂色97| AV天堂丝袜| 中文幕97| 青青草华人在线欧美在线| 99re99视频在线免费观看| 日韩伦理视频| 成人片视频| AV中文字幕三四五| 色姑娘综合网| 天天操夜夜操狠很操| 亚洲色天| 亚洲h片在线免费观看| 男女激烈网站最新| 国产麻豆一级精品视频| 亚洲欧美中文一区二区三| 黄色大片免费在线| 久久这里只精品99re66图| 69精品人人人人| 伊人精品视频| 青娱乐91| 老熟女乱子伦中文字幕一区二区| 蜜乳AV一区| www鬼畜国产男人的天堂| 欧美 亚洲 另类 综合| 91狠狠综合久久| 九七超碰| 99热最新网址| 中国的操老妇女| 中文字幕五月婷婷免费| 啊啊啊啊嗯嗯嗯用力好爽| 日韩精品熟妇| 欧美亚洲中文| 网页导航五月天免费一二三区| 欧美色五月| 国产后入内射| 天天草夜夜草高潮片| 九九热精品在线| 婷婷午夜清品久久久久久久性色视频观| 成人无码在线超碰网| 青娱乐 成人娱乐在线| 综合少妇网| 久久久久久久伊人精品| 日韩紧密久久| 在线视频 亚洲精品| 曰韩精品九九无码| 青娱乐黄色录像| 五月色网| 搡老女人老91二区| 中文字幕 一区二区 亚洲无码| 99re这里只有| 亚洲无码一二三区| 天天大干大香蕉| 亚洲91网。| 久操网无码在线| 久久久久9999妇女| 18禁免费视频| 国产人人干| 日本在线一二 | 把腿张开老子CAO烂你| 99精品久久久久久| 久久亚洲精品成人av| 国产自偷| 色五月综合| 亚洲h片在线免费观看| 欧日韩在线观看| 操美女高潮抽搐白浆| 神马九九| 五月天婷婷社区| 嗯阿好爽好紧| 欧美视频在线视频免费va| 久久久久少妇| 蜜桃精品一区二区三区ww| 操逼视频免费日韩无码| 国产一区二区二区按摩精品啪视频| 欧美亚洲激情小说| 99热这里只有精品99| 亚洲免费成人在线高清无码视频| 激情文学小说一区二区 | 99热这里只有精| 亚洲Av无码成人精品国产| 2023天天操夜夜操| 酒色综合网| 啊啊啊啊啊啊啊在线| 亚洲精品天天影视综合网 | 欧美丝袜亚洲| 色亚州人久干视频在线观看免费版| 东北夫妻性偷拍| 激激五月| 国产高潮AA片免费看| 国产成人精品日本亚洲语言| 综合免费无码中文| 欧美 日韩 亚洲 春色| 亚洲色图图片| 蜜臀99久久| 清纯唯美亚洲综合| 亚洲一区二区在线观看91| 久久最新视频免费观看| 91蜜臀在线久久久久| 五月婷婷丁香六月| 九色 人妻 大香蕉| 性性欧美| 国产日韩中文字幕欧美| 久久精品国产97欧美精品亚洲| 东京热不卡视频| 97视频在线免费| 超碰碰小说97| 成人性交午夜免费片| 亚洲另类春色| 国产熟女完整版中字| 日韩一级成人毛片免费观看 | blacked精品一区国产| 人人操人人操人人操人人操人人操人人人11.CM | 亚洲情色电影网| wwe 天天干.com| 蜜桃臀久久| 亚洲美女精品九九视频| 色综合V| 91人妻Pr| 久久久专区| 亚州欧美另类| 国产婷婷综合在线观看| 在线国产一区二区av| 久操B网| 亚洲综合夜色| 夜草网站| 五月婷丁香| 日本孕妇孕交| 岛国免费视频在线| 亚洲色五月| 日韩干B| 一类av片在线看| 青青青国产| 九九九九九精品| 伊人色综合网| 加勒比人妻综合| 99热销国产这里有精品| 婷婷午夜成人色中色| 天堂国产AV| 欧美亚洲今日在线| 免费A V在线| 日韩电影免费网站麻豆视频| 欧亚乱色熟女一区二区| 加勒比综合九九99视频在线播放| 999热这里只有精品| 69精品在线| 天天射天天操天天干天天吃2018| 婷婷色导航| 夜夜嗨一区| 操操啪| 操东北女人| 亚洲诱惑| 伊人久久综合影院| 欧美人妖内射| 久久熟妇五十路一区| 97AV在线观看| 91亚洲不卡一区| 午夜操逼不卡| 91色色综合| 精品人妻1区| 综合久久99亚洲人妻中文在线| 伊人久操| 亚洲资源站| 国产美女91视频| 无码视频黄色网战| 日本孕妇一区二区视频操逼免费看 | 人人看人人插| www.av不卡中文字幕| 国产欧美伊人| 一区二区三区高清天码| av草草在线电影| 91n美女视频| 91丝袜在线播放| B049AV在线播放| 日本精品一区二区中文字幕| 青草成人免费视频一com| 欧美大色交| 91在线综合网| 97操碰| 精品久久久久av影院| 99国产精品| 亚洲欧美91| 91精品人妻啪啪间| 午夜久久一区二区无码中出| 五月香婷婷| 欧美性爱视频免费一区一A| 男人天堂网站| 日韩有码中文字幕女同性恋| 一本一道久久综合久久| 东北女人操比视频| 久久綜合很很很| 欧美狠狠弄| 大香蕉伊人一区在线观看| 人妻人人操| 亚洲一区二区三区AV无码| 韩国黄片aaaa| 人人做天天爱| 日本高清视频xxxx| 欧美性爱第一区| 男女性感激情网站| 久久激情亚洲精品无码?V| 92午夜免费福利视频| 男人天堂站| 91丨精品丨国产丨丝袜| 岛国视频一二三区| 久久男人精品| 国产探花精品在线| 日本精品第一视频在'| 操高情无码| 探花激情视频| 东京日日夜夜| 天天日天天屌天天操| 噜噜瑟| 黄片免费日韩| 丁香婷婷九月| 中文字幕av色| 久久久久921| 99这里都是精品| 久久免费9| 中文字幕一区二区日韩网| 国产 v乱码一区二| 日本久操视频| 国内一区二区三区| 97国产超碰| 亚洲成熟国产精品美女| 天天综合色电影| 是还免费视频1727我| 日日夜夜精品视频| 国产树林里野战在线看| 色爱综合网欧美| 蜜臀久久99精品久久久久久酒店| 一本色道综合久久欧美| 大香蕉九九| 日本性一区| 性色av大全| 亚洲麻豆精品二区三区| 男人的天堂三级| 国产传媒操逼视频| 国产精品亚洲四五区在线观看| 久久久久久久综合,国产| 7777奇米影视久久| 欧美亚男人的天堂| 中文字幕欧美丝袜07资源| 日本操BAV| 97一区二区三区视频| 免费看片黄| 67194无码不卡| 青青草福利视频| 99热综合在线| 又粗又长又大国产不卡| 青青操97| 91精品亚洲内射孕妇| 96AV久久久| 日韩操逼性鲍| 男人精品区| 91足交| 中文字幕精品三级久久久| 亞洲久久直播| 欧州91高潮| 操美女人妻| 免费在线黄片视频| www.91视频网| 久久9 9 9精品| 你想操日本小逼吗| 欧美性综合| 亚洲精品a人片在线观看视| 久久久久久加勒比| 九月AV| 日韩探花精品在线视频| 欧美色图小说综合| 久久日韩毛| 欧美一级特黄淫片在线观看| 欧美操逼录像国产黄色国产| 一牛一区二区三区久久| 日本99久久| 国产无码三级视频在线观看| 久久香蕉超碰97国产精品| 亚洲五月婷| 美国aaaaa一级黄片| 蜜臀久久久99久久久久| 日日日啊啊啊| 久久激情网| 日本激情免费大片| 欧美成人性爱视频在线播放| 亚洲人妻久久久| 欧美熟女激情| 啊啊啊啊嗯嗯嗯用力好爽| 亚洲高清无码在线桃色| 九九九网站| 后入人妻无码| 九九九九九九九九九九精品视频| 日韩久久三区| 九九在线精品| 草草影院在线视频| 久99热| 九色97| 在线只有精品| 97天堂| 水澄无码AV| 精品.99999| 67194无码不卡| 青青草视频爽一爽| 裸体美女免费看网站青草| 中文字幕老熟妇黄色视频| 黄色高清无码无码破解免费暗网| 97人妻免费中文字幕| 在线观看综合精品亚洲| 亚洲美女自拍偷拍视频| 黄色大香焦1级‘′‘| 激情综合久久| 久久人妻一区二区三区高清| 青青草手机在线免费观看| 日韩激情视频| 日日摸日日碰| 欧美AB在线| 制度丝袜99| 日韩无码成人电影| 强奸少妇AV导航网| 欧美国产视频| 国产亚热在线久久| 探花视频免费观看国产专区| 亚洲伊人a线观看视频| AV在线性爱| 91足交| 蜜桃视频一区二区三区在线观看| 视频二区熟女人妻| 天天噜| 91粉嫩萝控精品福利网站_精品影音先锋国| 日本福利二区视频| 亚洲色图加勒比| 9丨久久九九九| 国产性爱在线视频一区二区| 国产精品久久久久999| 天天干天天燥| 久久婷婷国产一区二区色| 日本2020一区二区| 日韩欧美成人性爱在线| 麻豆天美久久91| 午夜精品久久久久久久第一页按摩| 国产探花日韩援交| 绯色AV粉色AV蜜臀AV| 欧美97爱| 96精品在线| 精品九区| www.狠狠操| 亚洲色电影在线| 99色在线| 蜜臀久久99精品久久久久久酒店 | 亚洲天堂一区二区久久| 东北女人| 亚洲欧美日韩二区视频| 日本最新免费韩国1区2区视频播放| 3PAV乱伦视频| 热天堂一区二区| 日韩欧美亚洲自拍偷拍| 久九九九九九九热| 国产亚洲精品农村妇女| 久久一区二区加油站| 亚欧无码在线| 97se亚洲综合自| 欧美制服网站美腿丝袜| 91性高朝久久久久久久久| 手机不卡视频不卡在线一二三区| 秋霞一集毛片观看| 国产精品肉丝自拍| 国产精品久久久久亚洲av| 加勒比av网| 狠狠干婷婷| 亚洲黄片免费在线播放| 人妻在线臀日韩| 久操不卡视频| 亚洲成a人v欧美综合天堂下载 | 欧美综合在线第一页| 性做久久久久久免费观看软件| 91成人18| 97草草| 久久超碰、| 丁香五月婷婷基地| 狠狠色伊人亚洲综合网站色| 日韩色图 一区二区| 2011国产精品| 午夜超爽| 水多多映视AV| 综合97| 欧州一区二区三区四区| 美女t无毒不卡不卡| 综合自拍| 欧美亚洲高清晰 | 欧美性爱超碰97| 九九九不卡| 国产精品熟女AV中文字幕在线播放| 人人妻人射| 欧美欧美啪啪视频| 深夜国产一区二区三区在线看| 成功精品影院| 日夜伊人网| 日本天天操| 久久专区| 久久日本熟妇熟色高清| 浪人综合网| 中国熟妇| 图色综合网| 8050午夜少妇无码| 久夜视频| 国产中文福利| 立川理惠无码一区二区| 欧美牲| 日韩精品人妻中文字幕久久久| 国产av又色又爽又黄| 亚洲日韩狠狠撸视频| 久久久久久大| 无码高清专| 午夜操一操| 人妻素股| 亚洲精品一二三四区| 波多野结衣先锋影音| 人妻精品一区二区| 99re只有精品| 综合久久婷婷| 探花一区二区三| 日曰骚久久精品| 亚州中文字幕超碰97| 五月天激情视频| av在线免费一区二区| 草草草草视频| 99日视频在线免费| 暖暖精品二区三区观看| 在线性黄高清免费视频| 波多野结衣之双飞调教在线播放| 蜜臀av中文字幕| 综合网亚| 97中文超碰| 中文字幕 国产 精品| 亚洲国产一区二区日韩专区| 99国产女人| 日韩精品影视| 九九久久国产精品| 亚洲美乱| 97人人射| 欧美精品999| 国产日韩欧美亚洲精品95| J?P?NESEHD熟女熟妇伦| 久久久久国色αv免费观看| 欧美性天天影院| 老熟女熟妇| AV天堂丝袜| 99精品无码| 中文字幕 国产 精品| 天天综合网日韩7799| 少妇熟女1区2区3区| 校园春色五月天| 蜜桃久久一区| 欧美色图自拍| 骚逼自拍99| 欧美日韩中国x| 国产成人主播| 香蕉久久精品| 亚洲网自拍| 99热免费精品| 婷婷色香| 超碰精品| 一区中文字幕二区日韩| 九一亚洲国产免费| 天天淫人人妻日日色| 日韩另类色图| 日韩AV电影网站| 91国产精品熟女| 成人在线视频二区| 91爱综合| 毛片视频白嫩| 麻豆九九九| 少妇人妻精品| 91美女在线视频| 上床不卡网站| 成人精品视频| 中文一区二区| 97操97干| 国产成人五月天丁香花| 国产视频第二页| 欧美爱爱97| heyZO天然素人无码AⅤ专区| 亚洲色图尤物视频 | 蜜臀99久久精品久久久久| 欧洲综合色|