99精品久久精品一区二区-亚洲熟妇无码?v在线播放-日本国产精品无码字幕在线观看-久久久亚洲永夜AV-亚洲一级无码一区二区一-免费国产成高清人在线视频-中文字幕乱码免费观看-国产毛片精品妇女久久久

ARTICLE DETAIL

資訊詳情

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

基于微信小程序的琴房預(yù)約管理系統(tǒng):從數(shù)據(jù)庫(kù)到?jīng)_突檢測(cè)全解析

基于微信小程序的琴房預(yù)約管理系統(tǒng):從數(shù)據(jù)庫(kù)到?jīng)_突檢測(cè)全解析 簡(jiǎn)介面向高校計(jì)算機(jī)相關(guān)專業(yè)畢業(yè)設(shè)計(jì)或課程設(shè)計(jì)場(chǎng)景這份微信小程序琴房管理系統(tǒng)項(xiàng)目包含完整源碼、說明文檔、LW及演示視頻。系統(tǒng)按學(xué)生與管理員雙角色設(shè)計(jì)學(xué)生端支持琴房查看、預(yù)約與公告瀏覽管理員端覆蓋學(xué)生信息管理、琴房公告發(fā)布及登錄注銷等操作業(yè)務(wù)鏈路完整適合需要快速理解小程序全棧開發(fā)并產(chǎn)出畢設(shè)成果的讀者。壓縮包共1105個(gè)文件大小約25.4MB以vue、js、java、class等前后端源碼文件為主輔以wxml/wxss小程序頁(yè)面、json配置、sql數(shù)據(jù)庫(kù)腳本、docx文檔以及png/svg界面素材和mp4演示視頻目錄結(jié)構(gòu)清晰、資源類型齊全。已有188人學(xué)習(xí)下載。包內(nèi)還附帶安裝/運(yùn)行/構(gòu)建的bat腳本、關(guān)鍵文件備份與常見配置說明結(jié)合演示視頻和說明文檔可幫助讀者梳理琴房預(yù)約的業(yè)務(wù)流程、接口設(shè)計(jì)及前后端交互細(xì)節(jié)便于二次開發(fā)與答辯準(zhǔn)備。1. 琴房管理系統(tǒng)怎么做這個(gè)微信小程序項(xiàng)目到底解決什么問題琴房管理在很多學(xué)校還停留在「微信群接龍 管理員人工排表」的階段學(xué)生接龍預(yù)約到了現(xiàn)場(chǎng)發(fā)現(xiàn)琴房被占用管理員每天花大量時(shí)間核對(duì)時(shí)間表、處理沖突?;谖⑿判〕绦虻那俜抗芾硐到y(tǒng)把整套流程搬到線上——學(xué)生打開小程序查看琴房實(shí)時(shí)狀態(tài)、按時(shí)間段預(yù)約管理員維護(hù)琴房、管理預(yù)約記錄。這類項(xiàng)目常出現(xiàn)在畢業(yè)設(shè)計(jì)和課程設(shè)計(jì)中因?yàn)闃I(yè)務(wù)邊界清晰又完整覆蓋了小程序前端、服務(wù)端接口、數(shù)據(jù)庫(kù)設(shè)計(jì)和定時(shí)任務(wù)幾個(gè)模塊。第一次做小程序全棧項(xiàng)目選它能把前后端基本功都練到評(píng)估它值不值得做核心就看一點(diǎn)預(yù)約沖突怎么用最少的代碼擋住。本文把這條線從頭到尾講透。2. 需求拆解與數(shù)據(jù)庫(kù)建模琴房預(yù)約的核心是時(shí)間沖突檢測(cè)做這類系統(tǒng)別急著寫代碼先把業(yè)務(wù)流程和表結(jié)構(gòu)想清楚。后臺(tái)的編排決定了預(yù)約邏輯的復(fù)雜度一旦表結(jié)構(gòu)定錯(cuò)后面改起來牽一發(fā)動(dòng)全身。琴房管理系統(tǒng)翻來覆去就那么幾個(gè)頁(yè)面但真正考驗(yàn)設(shè)計(jì)能力的是預(yù)約這件事怎么用數(shù)據(jù)模型表達(dá)出來。2.1 三種角色與核心業(yè)務(wù)流程預(yù)約、取消、簽到怎么串系統(tǒng)的角色其實(shí)就三類學(xué)生、管理員、定時(shí)任務(wù)。學(xué)生側(cè)重在鏈路上走查看琴房列表 → 選擇日期與時(shí)間段 → 提交預(yù)約 → 到琴房簽到 → 完成使用。管理員側(cè)重維護(hù)維護(hù)琴房信息、查看所有預(yù)約、異常情況下強(qiáng)制取消。定時(shí)任務(wù)做兜底把超時(shí)未簽到的預(yù)約標(biāo)記為爽約把過期預(yù)約歸檔。業(yè)務(wù)規(guī)則上我一般會(huì)按這幾條定同一琴房同一日期同一時(shí)間段只能存在一條有效預(yù)約。預(yù)約開始時(shí)間必須早于結(jié)束時(shí)間且落在琴房營(yíng)業(yè)時(shí)間內(nèi)。只能預(yù)約未來 7 天內(nèi)的時(shí)段不能預(yù)約過去的日期。取消預(yù)約必須在開始時(shí)間之前完成。預(yù)約開始后遲到 15 分鐘未簽到視為爽約。這些規(guī)則里最容易出錯(cuò)的是第 1 條——時(shí)間沖突。判斷兩個(gè)時(shí)間段是否重疊很多人第一反應(yīng)是「新預(yù)約的開始時(shí)間是否落在已有預(yù)約的區(qū)間里」這個(gè)直覺是錯(cuò)的。正確的判定公式是只要新時(shí)段的開始早于已有時(shí)段的結(jié)束且新時(shí)段的結(jié)束晚于已有時(shí)段的開始就必然重疊。這個(gè)公式貫穿整篇文章后面的 SQL 和代碼都在圍著它轉(zhuǎn)。2.2 用三張表把業(yè)務(wù)落地user、room、booking 的字段設(shè)計(jì)與索引核心就三張表字段不需要多夠用就行。下面是推薦的表結(jié)構(gòu)。-- 用戶表 CREATE TABLE sys_user ( id INT UNSIGNED NOT NULL AUTO_INCREMENT, openid VARCHAR(64) NOT NULL COMMENT 微信用戶唯一標(biāo)識(shí), nickname VARCHAR(50) DEFAULT COMMENT 昵稱, student_no VARCHAR(20) DEFAULT COMMENT 學(xué)號(hào)管理員可錄入, role TINYINT NOT NULL DEFAULT 0 COMMENT 0-學(xué)生 1-管理員, status TINYINT NOT NULL DEFAULT 1 COMMENT 0-禁用 1-正常, create_time DATETIME DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (id), UNIQUE KEY uk_openid (openid) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT用戶表; -- 琴房表 CREATE TABLE piano_room ( id INT UNSIGNED NOT NULL AUTO_INCREMENT, room_name VARCHAR(50) NOT NULL COMMENT 房間名如 A101, location VARCHAR(100) DEFAULT COMMENT 位置描述, piano_type VARCHAR(30) DEFAULT COMMENT 鋼琴類型, is_open TINYINT NOT NULL DEFAULT 1 COMMENT 0-關(guān)閉 1-開放, open_time TIME DEFAULT 08:00:00 COMMENT 營(yíng)業(yè)開始, close_time TIME DEFAULT 22:00:00 COMMENT 營(yíng)業(yè)結(jié)束, PRIMARY KEY (id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT琴房表; -- 預(yù)約表 CREATE TABLE booking ( id INT UNSIGNED NOT NULL AUTO_INCREMENT, room_id INT UNSIGNED NOT NULL COMMENT 琴房 id, user_id INT UNSIGNED NOT NULL COMMENT 用戶 id, book_date DATE NOT NULL COMMENT 預(yù)約日期, start_time TIME NOT NULL COMMENT 開始時(shí)間, end_time TIME NOT NULL COMMENT 結(jié)束時(shí)間, status TINYINT NOT NULL DEFAULT 0 COMMENT 0-已預(yù)約 1-已完成 2-已取消 3-爽約, remark VARCHAR(200) DEFAULT COMMENT 備注, create_time DATETIME DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (id), KEY idx_room_time (room_id, book_date, start_time, end_time), KEY idx_user_status (user_id, status) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT預(yù)約表;幾個(gè)設(shè)計(jì)要點(diǎn)說明。user 表的 openid 必須加唯一索引。微信小程序登錄拿到的是 openid它是用戶在當(dāng)前小程序下的唯一身份標(biāo)識(shí)每次登錄都用它做插入或更新重復(fù)插入會(huì)直接報(bào)錯(cuò)也能防止同一個(gè)微信號(hào)注冊(cè)出多個(gè)賬號(hào)。booking 表的 idx_room_time 聯(lián)合索引是沖突查詢的關(guān)鍵。沖突檢測(cè)的 SQL 會(huì)按 room_id 加 book_date 過濾再用 start_time 和 end_time 做區(qū)間比較這個(gè)索引能讓查詢走 range scan 而不是全表掃描。數(shù)據(jù)量幾千條時(shí)差別不明顯但到上萬條后有沒有這個(gè)索引就是毫秒級(jí)和秒級(jí)的差別。status 字段用 TINYINT 數(shù)字而不是字符串。畢業(yè)設(shè)計(jì)里很多人習(xí)慣存 booked、cancelled 這種字符串看著直觀但索引效率和代碼可讀性都不如數(shù)字枚舉。前后端約定好 0/1/2/3 的含義后端定義常量類統(tǒng)一使用比到處寫魔法數(shù)強(qiáng)得多。2.3 接口清單與鑒權(quán)方式小程序端和服務(wù)端怎么分工接口按資源拆RESTful 風(fēng)格就夠不需要引入復(fù)雜框架。核心接口如下。接口方法核心入?yún)⒄f明/api/auth/loginPOSTcode用 wx.login 的 code 換登錄態(tài) token/api/room/listGET無琴房列表與開放狀態(tài)/api/room/detailGETroomId琴房詳情含營(yíng)業(yè)時(shí)間與可預(yù)約時(shí)段/api/booking/createPOSTroomId、bookDate、startTime、endTime創(chuàng)建預(yù)約/api/booking/mineGET無當(dāng)前用戶的預(yù)約記錄/api/booking/cancelPOSTbookingId取消預(yù)約/api/booking/checkinPOSTbookingId到琴房簽到/api/admin/room/savePOST琴房信息管理員維護(hù)琴房鑒權(quán)有兩種常見做法。輕量一點(diǎn)的是后端生成隨機(jī) token 存到 Redis設(shè)過期時(shí)間小程序每次請(qǐng)求把 token 放在 Authorization 頭里重一點(diǎn)的是直接上 JWT登錄時(shí)簽發(fā)過期時(shí)間由服務(wù)端控制。對(duì)這個(gè)項(xiàng)目來說Redis token 方案更直觀也方便管理員端做強(qiáng)制下線我一般會(huì)用這種。后端用攔截器統(tǒng)一校驗(yàn)白名單放行登錄接口其余接口都要求攜帶有效 token管理員接口再額外查一次 role 字段。3. 小程序端實(shí)現(xiàn)登錄態(tài)、琴房列表和預(yù)約提交的關(guān)鍵代碼小程序端的核心頁(yè)面就三個(gè)琴房列表頁(yè)、預(yù)約頁(yè)、我的預(yù)約頁(yè)。這一章把代碼拆開講從登錄態(tài)到預(yù)約提交每一步給出能直接用的片段。所有請(qǐng)求都走 wx.request業(yè)務(wù)層把 url 和 data 組織好就行。3.1 微信登錄與 Token 會(huì)話管理code 換 token 的完整鏈路微信小程序的登錄鏈路是小程序調(diào)用 wx.login 拿到一次性 code后端拿 code 去微信接口換 openid 和 session_key再生成業(yè)務(wù) token 返回給小程序。code 只能用一次且有效期很短所以小程序端不能緩存 code每次啟動(dòng)都要重新調(diào)用 wx.login。// miniprogram/utils/auth.js const TOKEN_KEY token; function login() { return new Promise((resolve, reject) { wx.login({ success: (res) { if (!res.code) { reject(new Error(wx.login 未返回 code)); return; } wx.request({ url: getApp().globalData.apiBase /api/auth/login, method: POST, data: { code: res.code }, success: (resp) { if (resp.data.code 0) { const token resp.data.data.token; wx.setStorageSync(TOKEN_KEY, token); resolve(resp.data.data); } else { reject(new Error(resp.data.msg || 登錄失敗)); } }, fail: (err) reject(err) }); }, fail: (err) reject(err) }); }); } function getToken() { return wx.getStorageSync(TOKEN_KEY); } module.exports { login, getToken, TOKEN_KEY };邏輯說明wx.login 成功后拿到 code把它 POST 給后端后端用 code 換 openid 后生成 token 返回。前端把 token 放進(jìn)本地緩存后續(xù)所有請(qǐng)求從緩存取。參數(shù)上注意 apiBase 是后端服務(wù)地址開發(fā)階段指向局域網(wǎng) IP 加端口正式上線必須換成已配置 HTTPS 證書的域名。提示token 失效時(shí)后端通常會(huì)返回 401小程序端應(yīng)該封裝一個(gè)請(qǐng)求函數(shù)統(tǒng)一攔截 401 后自動(dòng)重新登錄并重放原請(qǐng)求。這個(gè)習(xí)慣能幫你省掉大量「登錄態(tài)過期」導(dǎo)致的現(xiàn)場(chǎng)翻車。關(guān)于 session_key它用于解密微信加密數(shù)據(jù)比如手機(jī)號(hào)。琴房管理系統(tǒng)如果只是用 openid 做身份識(shí)別session_key 在后端換完就可以丟棄不用存。見過不少同學(xué)把 session_key 也寫進(jìn) user 表沒有必要除非你還要做微信手機(jī)號(hào)授權(quán)。3.2 琴房列表與狀態(tài)展示拉取數(shù)據(jù)、渲染與下拉刷新琴房列表頁(yè)的要點(diǎn)是狀態(tài)展示。后端返回的 room 里帶 status 字段前端要把它翻譯成用戶能看懂的文字和顏色而不是直接把數(shù)字渲染到頁(yè)面上。// pages/room/room.js const { getToken } require(../utils/auth.js); Page({ data: { rooms: [], loading: false }, onShow() { this.fetchRooms(); }, onPullDownRefresh() { this.fetchRooms(true); }, fetchRooms(isRefresh false) { if (this.data.loading) return; this.setData({ loading: true }); wx.request({ url: getApp().globalData.apiBase /api/room/list, header: { Authorization: Bearer getToken() }, success: (res) { if (res.data.code 0) { const rooms res.data.data.map((room) ({ ...room, statusText: this.statusText(room.status), statusClass: room-status- room.status })); this.setData({ rooms }); } else { wx.showToast({ title: res.data.msg || 加載失敗, icon: none }); } }, complete: () { this.setData({ loading: false }); if (isRefresh) wx.stopPullDownRefresh(); } }); }, statusText(status) { const map { 0: 空閑, 1: 使用中, 2: 維護(hù)中 }; return map[status] || 未知; }, goBook(e) { const roomId e.currentTarget.dataset.id; wx.navigateTo({ url: /pages/book/book?roomId roomId }); } });對(duì)應(yīng)的 WXML 片段view classroom-card wx:for{{rooms}} wx:keyid view classroom-name{{item.roomName}}/view view classroom-location{{item.location}} · {{item.pianoType}}/view view classroom-status {{item.statusClass}}{{item.statusText}}/view button typeprimary sizemini bindtapgoBook>// pages/book/book.js const { getToken } require(../utils/auth.js); const SLOT_MINUTES 60; const MAX_ADVANCE_DAYS 7; Page({ data: { roomId: , room: null, dateList: [], dateIndex: 0, slotList: [], slotIndex: -1, submitting: false }, onLoad(options) { this.setData({ roomId: options.roomId }); this.buildDateList(); this.loadRoomDetail(); }, buildDateList() { const list []; const week [日, 一, 二, 三, 四, 五, 六]; for (let i 0; i MAX_ADVANCE_DAYS; i) { const d new Date(); d.setDate(d.getDate() i); const dateStr ${d.getFullYear()}-${String(d.getMonth() 1).padStart(2, 0)}-${String(d.getDate()).padStart(2, 0)}; const label i 0 ? 今天 : i 1 ? 明天 : ${d.getMonth() 1}月${d.getDate()}日 周${week[d.getDay()]}; list.push({ dateStr, label }); } this.setData({ dateList: list }); }, loadRoomDetail() { wx.request({ url: getApp().globalData.apiBase /api/room/detail, data: { roomId: this.data.roomId }, header: { Authorization: Bearer getToken() }, success: (res) { if (res.data.code 0) { this.setData({ room: res.data.data }); this.buildSlotList(); } } }); }, buildSlotList() { const room this.data.room; if (!room) return; const slots []; const openHour parseInt(room.openTime.slice(0, 2), 10); const closeHour parseInt(room.closeTime.slice(0, 2), 10); for (let h openHour; h SLOT_MINUTES / 60 closeHour; h) { const start ${String(h).padStart(2, 0)}:00:00; const end ${String(h SLOT_MINUTES / 60).padStart(2, 0)}:00:00; slots.push({ start, end, label: ${start.slice(0, 5)} - ${end.slice(0, 5)} }); } this.setData({ slotList: slots }); }, onDateChange(e) { this.setData({ dateIndex: Number(e.detail.value), slotIndex: -1 }); }, onSlotSelect(e) { this.setData({ slotIndex: Number(e.currentTarget.dataset.index) }); }, submit() { const { roomId, dateList, dateIndex, slotList, slotIndex, submitting } this.data; if (slotIndex 0) { wx.showToast({ title: 請(qǐng)選擇時(shí)間段, icon: none }); return; } if (submitting) return; this.setData({ submitting: true }); const date dateList[dateIndex].dateStr; const slot slotList[slotIndex]; wx.request({ url: getApp().globalData.apiBase /api/booking/create, method: POST, header: { Authorization: Bearer getToken() }, data: { roomId: roomId, bookDate: date, startTime: slot.start, endTime: slot.end }, success: (res) { if (res.data.code 0) { wx.showToast({ title: 預(yù)約成功, icon: success }); setTimeout(() wx.navigateBack(), 1500); } else { wx.showToast({ title: res.data.msg || 預(yù)約失敗, icon: none }); } }, complete: () { this.setData({ submitting: false }); } }); } });邏輯說明日期生成用循環(huán)加 7 天第一二天顯示「今天」「明天」后面的顯示具體日期和星期這個(gè)細(xì)節(jié)在演示時(shí)很加分。時(shí)間片按 room.openTime 和 closeTime 解析出小時(shí)數(shù)循環(huán)生成整點(diǎn)時(shí)段。submitting 標(biāo)志防止用戶重復(fù)點(diǎn)擊提交這個(gè)在預(yù)約場(chǎng)景里是必須的不然一次點(diǎn)擊發(fā)出兩個(gè)請(qǐng)求就會(huì)出現(xiàn)「我只點(diǎn)了一次怎么訂了兩條」。注意一個(gè)邊界時(shí)間片生成只考慮了整點(diǎn)如果琴房營(yíng)業(yè)時(shí)間是 08:30 到 21:30這種寫法生成的時(shí)段會(huì)不準(zhǔn)。穩(wěn)妥的做法是后端在 room/detail 接口里直接返回可預(yù)約時(shí)間片數(shù)組前端只負(fù)責(zé)渲染。這樣營(yíng)業(yè)時(shí)間、粒度、特殊日期的規(guī)則全部收斂在后端一處前端永遠(yuǎn)不用自己去推。4. 后端服務(wù)與沖突控制把預(yù)約規(guī)則寫成可執(zhí)行的代碼后端是這類系統(tǒng)的重頭戲。預(yù)約創(chuàng)建、沖突檢測(cè)、超時(shí)釋放這三塊寫好了項(xiàng)目核心邏輯就立住了。這一章以 Java Spring Boot 的寫法為例其他語言思路一致SQL 部分可以直接搬過去。4.1 預(yù)約創(chuàng)建的完整流程參數(shù)校驗(yàn)、沖突檢測(cè)與事務(wù)預(yù)約創(chuàng)建的接口不能只是簡(jiǎn)單 insert它要按順序做五件事參數(shù)校驗(yàn)、琴房校驗(yàn)、營(yíng)業(yè)時(shí)間校驗(yàn)、沖突檢測(cè)、插入。任何一步失敗都返回業(yè)務(wù)錯(cuò)誤。Transactional(rollbackFor Exception.class) public Booking createBooking(BookingDTO dto, Long userId) { // 1. 基本參數(shù)校驗(yàn) if (dto.getStartTime().compareTo(dto.getEndTime()) 0) { throw new BusinessException(開始時(shí)間必須早于結(jié)束時(shí)間); } if (dto.getBookDate().isBefore(LocalDate.now())) { throw new BusinessException(不能預(yù)約過去的日期); } // 2. 琴房存在且開放 PianoRoom room roomMapper.selectById(dto.getRoomId()); if (room null || room.getIsOpen() ! 1) { throw new BusinessException(琴房不存在或未開放); } // 3. 時(shí)間必須落在琴房營(yíng)業(yè)時(shí)間范圍內(nèi) if (dto.getStartTime().isBefore(room.getOpenTime()) || dto.getEndTime().isAfter(room.getCloseTime())) { throw new BusinessException(預(yù)約時(shí)間超出琴房營(yíng)業(yè)時(shí)間); } // 4. 行鎖 沖突檢測(cè) int conflict bookingMapper.countConflictForUpdate( dto.getRoomId(), dto.getBookDate(), dto.getStartTime(), dto.getEndTime()); if (conflict 0) { throw new BusinessException(該時(shí)間段已被預(yù)約請(qǐng)選擇其他時(shí)間); } // 5. 插入預(yù)約記錄 Booking booking new Booking(); booking.setRoomId(dto.getRoomId()); booking.setUserId(userId); booking.setBookDate(dto.getBookDate()); booking.setStartTime(dto.getStartTime()); booking.setEndTime(dto.getEndTime()); booking.setStatus(BookingStatus.BOOKED); bookingMapper.insert(booking); return booking; }邏輯說明第 1 步擋住「開始晚于結(jié)束」和「預(yù)約過去日期」兩種低級(jí)錯(cuò)誤這類請(qǐng)求根本不該進(jìn)到數(shù)據(jù)庫(kù)。第 3 步校驗(yàn)營(yíng)業(yè)時(shí)間前端選了 21:30 但琴房 21:00 關(guān)門這里直接拒絕。第 4 步是核心countConflictForUpdate 會(huì)先鎖住相關(guān)記錄再統(tǒng)計(jì)避免兩個(gè)并發(fā)請(qǐng)求同時(shí)通過檢查。第 5 步插入后事務(wù)提交整個(gè)過程要么全部成功要么全部回滾不會(huì)出現(xiàn)「沖突檢測(cè)通過了但插入失敗」的臟狀態(tài)。注意Transactional 一定要加 rollbackFor Exception.class。Spring 默認(rèn)只在 RuntimeException 時(shí)回滾拋?zhàn)远x checked 異常時(shí)事務(wù)不回滾數(shù)據(jù)就寫進(jìn)去了這個(gè)細(xì)節(jié)坑過很多人。還有一個(gè)容易踩的坑有的同學(xué)把沖突檢測(cè)拆成獨(dú)立 service 方法然后在 createBooking 里調(diào)用。如果這個(gè)方法沒有事務(wù)傳播檢查完再插入的間隙另一個(gè)請(qǐng)求可能已經(jīng)插入了同一時(shí)段。所以檢測(cè)和插入必須在同一個(gè)事務(wù)方法里這是硬要求。4.2 沖突檢測(cè) SQL 的正確寫法區(qū)間重疊判定與索引利用沖突檢測(cè)的 SQL 是全文最重要的幾行代碼。select idcountConflictForUpdate resultTypeint SELECT COUNT(*) FROM booking WHERE room_id #{roomId} AND book_date #{bookDate} AND status 0 AND start_time lt; #{endTime} AND end_time gt; #{startTime} FOR UPDATE /select邏輯說明新預(yù)約時(shí)段是 [startTime, endTime]已有預(yù)約時(shí)段是 [start_time, end_time]。兩者重疊的充要條件是新開始時(shí)間早于已有結(jié)束時(shí)間且新結(jié)束時(shí)間晚于已有開始時(shí)間。寫成 SQL 就是 start_time #{endTime} AND end_time #{startTime}。再加 book_date 限定同一天status 0 只統(tǒng)計(jì)有效預(yù)約排除已取消和已歸檔的記錄。反例值得單獨(dú)說。有同學(xué)會(huì)寫成下面這兩種-- 反例一只覆蓋「完全包含」的情況 WHERE start_time #{startTime} AND end_time #{endTime} -- 反例二只看已有預(yù)約的開始時(shí)間是否落在新時(shí)段內(nèi) WHERE start_time BETWEEN #{startTime} AND #{endTime}反例一漏掉了「新時(shí)段橫跨已有時(shí)段」的部分重疊反例二漏掉了「已有時(shí)段橫跨新時(shí)段」的場(chǎng)景。實(shí)測(cè)中這兩種寫法會(huì)各放走一批沖突預(yù)約等管理員在后臺(tái)看到記錄重了再去手工取消就很被動(dòng)。FOR UPDATE 是 MySQL InnoDB 的行鎖語法配合 idx_room_time 索引它會(huì)鎖住命中的索引區(qū)間。并發(fā)場(chǎng)景下兩個(gè)請(qǐng)求同時(shí)查同一琴房同一天的數(shù)據(jù)后到的會(huì)等先到事務(wù)提交后才繼續(xù)這樣沖突檢測(cè)就變成串行執(zhí)行不會(huì)出現(xiàn)兩人同時(shí)訂走同一時(shí)段的情況。這個(gè)鎖粒度對(duì)這個(gè)項(xiàng)目足夠沒必要上 Redis 分布式鎖。idx_room_time 聯(lián)合索引room_id, book_date, start_time, end_time覆蓋了查詢的過濾條件MySQL 會(huì)走索引 range scan數(shù)據(jù)量到十萬級(jí)也不會(huì)慢。如果這個(gè)項(xiàng)目用于期末設(shè)計(jì)這屬于「可展示的性能設(shè)計(jì)點(diǎn)」答辯時(shí)值得拿出來講。4.3 超時(shí)釋放與簽到定時(shí)任務(wù)讓預(yù)約狀態(tài)自動(dòng)流轉(zhuǎn)預(yù)約狀態(tài)不能永遠(yuǎn)停在「已預(yù)約」。到了時(shí)間沒來系統(tǒng)要自動(dòng)釋放琴房并標(biāo)記爽約當(dāng)天用完了要標(biāo)記完成。這些靠定時(shí)任務(wù)和簽到接口配合完成。Component public class BookingScheduler { Autowired private BookingMapper bookingMapper; // 每分鐘跑一次已預(yù)約但開始時(shí)間已過 15 分鐘的標(biāo)記為爽約 Scheduled(cron 0 * * * * ?) public void markNoShow() { ListBooking list bookingMapper.findExpiredNoShows(); for (Booking b : list) { b.setStatus(BookingStatus.NO_SHOW); bookingMapper.updateById(b); } } // 每天凌晨 2 點(diǎn)把前一天的記錄批量歸檔為已完成 Scheduled(cron 0 0 2 * * ?) public void archiveYesterday() { bookingMapper.archiveByDate(LocalDate.now().minusDays(1)); } }對(duì)應(yīng)的 SQL-- 找出已超時(shí)未簽到的預(yù)約 SELECT * FROM booking WHERE status 0 AND (book_date CURDATE() OR (book_date CURDATE() AND start_time DATE_SUB(CURTIME(), INTERVAL 15 MINUTE)))邏輯說明markNoShow 的判定條件是「開始時(shí)間已過去 15 分鐘且狀態(tài)仍是已預(yù)約」。這里故意留 15 分鐘緩沖學(xué)生可能因?yàn)槁飞系R晚到幾分鐘直接到點(diǎn)就釋放很容易引發(fā)投訴。archiveYesterday 是每天凌晨的兜底任務(wù)把前一天未完成的記錄批量歸檔。cron 表達(dá)式里0 * * * * ?表示每分鐘第 0 秒執(zhí)行0 0 2 * * ?表示每天凌晨 2 點(diǎn)整執(zhí)行。簽到接口單獨(dú)說一下。學(xué)生到琴房后點(diǎn)「簽到」后端要校驗(yàn)該預(yù)約屬于當(dāng)前用戶、狀態(tài)是已預(yù)約、當(dāng)前時(shí)間不早于預(yù)約開始時(shí)間然后狀態(tài)改成已完成。有個(gè)細(xì)節(jié)容易漏預(yù)約明天 10:00現(xiàn)在簽到必須拒絕預(yù)約今天 10:00 而現(xiàn)在是 10:05允許簽到。只判斷「日期相等」而忽略當(dāng)前時(shí)刻會(huì)導(dǎo)致預(yù)約還沒開始就能提前簽到的笑話邏輯。到這里系統(tǒng)核心鏈路已經(jīng)通了前端選時(shí)間、后端擋住沖突、定時(shí)任務(wù)兜底釋放。第 5 章把開發(fā)中最高發(fā)的幾個(gè)問題集中排一遍雷。5. 琴房管理系統(tǒng)避坑指南5 個(gè)高發(fā)問題與排查方法這一章按「現(xiàn)象 → 原因 → 解決」的格式寫都是這個(gè)項(xiàng)目里反復(fù)出現(xiàn)的問題每一類我都見過不止一次。你如果正在調(diào)試直接對(duì)照著查比從頭翻日志快得多。5.1 沖突檢測(cè)漏掉「部分重疊」導(dǎo)致重復(fù)預(yù)約現(xiàn)象A 同學(xué)約了 10:00-11:00B 同學(xué)竟然還能約 10:30-11:30后臺(tái)出現(xiàn)兩條重疊預(yù)約。原因沖突檢測(cè) SQL 寫成了 start_time #{startTime} AND end_time #{endTime}只判斷新時(shí)段是否完整包含在已有時(shí)段內(nèi)。B 的 10:30-11:30 和 A 的 10:00-11:00 是交叉重疊新開始 10:30 落在 A 的時(shí)段內(nèi)但新結(jié)束 11:30 超出了 A 的結(jié)束時(shí)間條件不成立于是被放行。解決改用區(qū)間重疊判定 start_time #{endTime} AND end_time #{startTime}。改完用三種用例驗(yàn)證新時(shí)段在已有時(shí)段內(nèi)部、新時(shí)段橫跨已有時(shí)段、新時(shí)段與已有時(shí)段首尾相接前兩個(gè)必須返回沖突第三個(gè)在邊界恰好相切時(shí)允許通過。我一般會(huì)把這幾個(gè)用例寫進(jìn)單元測(cè)試防止后續(xù)改動(dòng)時(shí)悄悄回歸。5.2 并發(fā)預(yù)約「超賣」同一時(shí)段被兩人同時(shí)訂走現(xiàn)象兩個(gè)學(xué)生同時(shí)間隔幾百毫秒提交同一琴房同一時(shí)段的預(yù)約兩個(gè)接口都返回成功數(shù)據(jù)庫(kù)里兩條記錄。原因沒有加鎖的「先查詢后插入」存在競(jìng)態(tài)窗口。請(qǐng)求 A 查到?jīng)_突數(shù)為 0還沒插入請(qǐng)求 B 也查到?jīng)_突數(shù)為 0接著兩個(gè)請(qǐng)求都執(zhí)行插入沖突檢測(cè)形同虛設(shè)。解決在沖突檢測(cè) SQL 末尾加 FOR UPDATE并讓檢測(cè)與插入處于同一事務(wù)中。后到的請(qǐng)求會(huì)等待先到事務(wù)提交后再執(zhí)行查詢此時(shí)沖突數(shù)變成 1預(yù)約被拒絕。如果項(xiàng)目用的是 PostgreSQL對(duì)應(yīng)語法是 FOR KEY SHARE如果不想依賴數(shù)據(jù)庫(kù)鎖可以在 booking 表加唯一索引room_id, book_date, start_time做兜底插入沖突時(shí)直接報(bào)錯(cuò)再用異常重試邏輯處理。5.3 預(yù)約時(shí)間憑空差 8 小時(shí)數(shù)據(jù)庫(kù)時(shí)區(qū)問題現(xiàn)象小程序端選了 10:00 提交數(shù)據(jù)庫(kù)里存的是 02:00管理后臺(tái)看到的預(yù)約時(shí)間全部不對(duì)。原因Java 的 LocalDateTime 和 MySQL 的 DATETIME 在時(shí)區(qū)解析上出現(xiàn)偏差。常見的是 JDBC 連接串里沒有指定 serverTimezone驅(qū)動(dòng)用了默認(rèn)時(shí)區(qū)跟服務(wù)器系統(tǒng)時(shí)區(qū)不一致導(dǎo)致時(shí)間偏移。解決在 JDBC 連接串上顯式指定時(shí)區(qū)寫成 jdbc:mysql://localhost:3306/piano?serverTimezoneAsia/Shanghai。同時(shí)約定前后端傳輸時(shí)間一律用字符串格式如 10:00:00不傳時(shí)間戳。TIME 類型本身不涉及時(shí)區(qū)換算用字符串傳遞能避開大部分時(shí)區(qū)坑。這屬于典型的「開發(fā)環(huán)境不出錯(cuò)、一換機(jī)器就翻車」的問題答辯前一定要換臺(tái)機(jī)器部署驗(yàn)證一遍。5.4 開發(fā)者工具正常、真機(jī)請(qǐng)求失敗域名與 HTTPS現(xiàn)象微信開發(fā)者工具里所有接口都通掃碼到真機(jī)上一片空白控制臺(tái)報(bào) request:fail url not in domain list。原因小程序真機(jī)環(huán)境強(qiáng)制要求后臺(tái)接口走 HTTPS且域名必須在小程序后臺(tái)配置為 request 合法域名。開發(fā)工具默認(rèn)不校驗(yàn)合法域名本地 http 接口能通但真機(jī)不認(rèn)。解決開發(fā)階段在開發(fā)者工具的詳情設(shè)置里勾選「不校驗(yàn)合法域名、TLS 版本以及 HTTPS 證書」這只解決本機(jī)調(diào)試。要真機(jī)完整跑通需要準(zhǔn)備一個(gè)已配置 HTTPS 證書的域名在小程序后臺(tái)配好 request 合法域名再把后端接口地址從局域網(wǎng) IP 換成線上域名。證書和域名校驗(yàn)是硬條件沒有捷徑。演示視頻建議在真機(jī)網(wǎng)絡(luò)通暢時(shí)錄制別在開發(fā)工具里錄兩者觀感差很多。5.5 前端選了合法時(shí)間、后端卻報(bào)「超出營(yíng)業(yè)時(shí)間」現(xiàn)象前端時(shí)間選擇器最多到 21:00但用戶改一下請(qǐng)求參數(shù)就能提交 22:00 的預(yù)約或者前端按 60 分鐘生成時(shí)間片后端允許提交 30 分鐘的時(shí)段預(yù)約粒度混亂。原因前端的時(shí)間組裝邏輯和后端校驗(yàn)規(guī)則是兩套代碼沒有統(tǒng)一。用戶只要繞過前端界面直接調(diào)接口就能提交任意時(shí)間。解決把「可預(yù)約時(shí)段」的完整定義收斂到后端。常見做法是后端 room/detail 接口直接返回該琴房可預(yù)約的時(shí)間片數(shù)組前端渲染時(shí)直接用不做二次計(jì)算后端 create 接口再做兜底校驗(yàn)即使前端被改非法時(shí)間也會(huì)被拒絕。一句話前端做體驗(yàn)后端做規(guī)則互不越界。6. 讓項(xiàng)目在答辯現(xiàn)場(chǎng)不翻車預(yù)置數(shù)據(jù)與演示路徑項(xiàng)目能跑和能演示是兩回事。很多同學(xué)代碼寫完了上臺(tái)演示時(shí)現(xiàn)場(chǎng)預(yù)約、現(xiàn)場(chǎng)等數(shù)據(jù)結(jié)果網(wǎng)絡(luò)慢、時(shí)間對(duì)不上、頁(yè)面轉(zhuǎn)圈。提前預(yù)置數(shù)據(jù)是最有效的規(guī)避手段。預(yù)置數(shù)據(jù)的核心原則讓演示路徑上的每一步都有「看起來真實(shí)」的數(shù)據(jù)支撐。下面這組 SQL 是三張表的最小演示數(shù)據(jù)集。-- 琴房 INSERT INTO piano_room (room_name, location, piano_type, is_open, open_time, close_time) VALUES (A101, 1號(hào)樓 1層, 立式鋼琴, 1, 08:00:00, 22:00:00), (A102, 1號(hào)樓 1層, 三角鋼琴, 1, 08:00:00, 22:00:00), (B201, 2號(hào)樓 2層, 電子鋼琴, 0, 09:00:00, 21:00:00); -- 用戶 INSERT INTO sys_user (openid, nickname, role, status) VALUES (demo_admin_openid, 管理員, 1, 1), (demo_student_openid, 演示學(xué)生, 0, 1); -- 預(yù)約一條待使用、一條已取消、一條已完成 INSERT INTO booking (room_id, user_id, book_date, start_time, end_time, status) VALUES (1, 2, DATE_ADD(CURDATE(), INTERVAL 1 DAY), 10:00:00, 11:00:00, 0), (1, 2, DATE_ADD(CURDATE(), INTERVAL 1 DAY), 14:00:00, 15:00:00, 2), (2, 2, DATE_ADD(CURDATE(), INTERVAL -1 DAY), 08:00:00, 09:00:00, 1);預(yù)約數(shù)據(jù)里用 DATE_ADD(CURDATE(), INTERVAL 1 DAY) 替代寫死的日期這個(gè)細(xì)節(jié)很關(guān)鍵它保證任何一天打開演示環(huán)境數(shù)據(jù)都是「明天有預(yù)約」不會(huì)因?yàn)闀r(shí)間推移全部過期。演示數(shù)據(jù)永遠(yuǎn)新鮮這是答辯演示最省心的一條技巧。演示路徑我一般按這個(gè)順序走登錄進(jìn)首頁(yè)看到三間琴房狀態(tài)各異 → 點(diǎn)開 A101 看到明天的時(shí)段列表 → 選 10:00-11:00 提交預(yù)約成功 → 切到「我的預(yù)約」看到剛剛的記錄 → 取消再重新預(yù)約 → 打開管理員視角看全部預(yù)約記錄。整條路徑覆蓋登錄、查詢、創(chuàng)建、取消、管理五個(gè)核心功能五分鐘講完節(jié)奏剛好。另一個(gè)容易忽略的點(diǎn)提前把演示用的賬號(hào)登錄態(tài)保持住別在現(xiàn)場(chǎng)等 wx.login 轉(zhuǎn)圈。正式演示前五分鐘在演示手機(jī)上完整走一遍登錄流程確認(rèn) token 有效再把小程序切到后臺(tái)待命?,F(xiàn)場(chǎng)只做操作不做登錄。做這個(gè)項(xiàng)目時(shí)我最大的教訓(xùn)是把「代碼寫完」當(dāng)成「項(xiàng)目做完」結(jié)果第一次聯(lián)調(diào)時(shí)被沖突檢測(cè)的邊界條件打臉。如果你正在做這個(gè)方向我建議把第 4 章的三種重疊用例寫進(jìn)測(cè)試跑通了再談演示。開發(fā)里多留一分敬畏答辯時(shí)就少一分慌張。希望幫到你。本文還有配套的精品資源點(diǎn)擊獲取
返回列表
PREV
查看更多資訊
NEXT
返回資訊列表
婷婷色五月激情强奸四射| 五月天六月天| 97操碰98| 超碰女人天堂| 夜夜操天天干| 久久这里只有精品无码| 五月开心婷婷极品激情| www久久久久久| 久久98| 五丁香激情综合| 538任你爽视频不一样的| www.婷婷六月天| 五月婷婷真爱激情网| 大香蕉五月丁香| 色婷青青| 人妻丰满精品一区二区A片| 日日插日日干| 日韩激情人伦人| 亚洲欧洲午夜成人精品av| 国产精品一区在线观看你懂的| 丁香五月亚综合图片| 全亚洲最大的婷婷五月天网站COM 丁香五月婷婷狠狠色 | 欧美色碰| 婷婷丁香九色| 无码成人播放器| 狠狠久久婷五月| 五月婷婷丁香狠狠撸久久| 综激情网| 91碰在线| 久久久久8888| www.五月婷婷久久.com| 丁香五月婷婷AV| 色婷婷AV在线观看| 五月婷婷综合在线视频| 精品热九九| 五月婷婷色五月| 久久人妻乱| 丁香五月成人在线| 爱操人妻| 日木狠狠干| 国产成人在线不卡AV| 99精品丁香五月| 综合激情五月天| 人妻视频在线| 强伦轩人妻一区二区电影| 亚州精品久久久久AV无码| 五月丁香六月婷婷,婷| 乱码操操| 久久这里都是精品免费| 97色色色色色色色| 国产99精品免费视频| 日本99在线视频| 色婷婷无吗| www.丁香黄色五月天人与| 激情丁香五月| 九九热123| 国产精品久久久久久久久久| 亚洲V国产V欧美V久久久久久| 99色在线| 天天爽天天操| 播丁香五月婷婷欧美| 国产做A爰片毛片A片美国| 超碰99热| 91色色色| 欧美黑人巨大性生话| 玖玖精品视频| 国外亚洲成AV人片在线观看| 丁香激情综合| 久久久噜噜噜www成人| 亚洲AV无码成人电影| 色狠狠色噜噜AV天堂五区| 国产一区二区三区影院| 热99色| www.色欲丁香婷婷| enecarbon-materials.com污K127封锁请涟系@wip1688 | 丁香婷婷欧美综合| 五月丁香趴趴| 丁香五月婷婷啪| 狼人狠狠操| 人人性久久| 久婷婷色| 五月在线婷色| 激情婷婷啪啪| 色情综合| 精品日本视频444| 神马久久五月天| 色婷婷久久9.com| 丁香八月综合激情| 国产成人av在线播放| 操逼毛片国语对白| 手机AVAV天堂看网| 大香蕉欧美在线| 五月婷婷激情性爱| 亚洲妇女熟BBW| 国产精品久久久爽爽爽麻豆色哟哟| 丁香5月啪啪| XXXX岛国| 狠狠干夜夜干| 亚洲日韩一页精品发布| 国产永久一黄| 99热这里只有精品亚洲| 涩综合婷婷| 97香蕉久久超级碰碰高清版| 香蕉AV777XXX色综合一区| 青草青草视频2免费观看| www九九免费视频| 国内在线99视频| 色婷婷88| 99成人精品| 人草人人| 天天弄天天操| 五月婷久久久| 春色激情第四色| 丁香五月婷老师| www.色综合| 精品无码久久久久久久久| 亚洲天堂色| 1024婷婷综合久久五月天| 久久永久网址| 99视频只有精品| 97色婷婷| 久操人| 噜噜狠狠| 91丨九色丨白浆秘| 99热观看| 西瓜美女a片| 婷婷五月在线视频| 五月丁香 狠狠爱| 99re免费精品视频| 久久久噜噜噜久久人妻| 色婷丁香91| 无码啪啪| 影音先锋91| 日本精品人妻无码77777| 亚洲AV另类| 五月天婷婷午夜丁香| 丁香婷婷综合激情五月色| 亚洲午夜AV| 91伦| 婷婷五月天免费| 久久久99久久| 国产免费一区二区三区三州老师F1F1.CC| 亚洲综合色网站| 五月天 婷 欧美亚洲| 玖玖在线视频| 99在线观看视频免费| 婷婷丁香人妻天天爽| 五月婷婷久久综合| 五月婷婷在线短视频| 色色网站在线| 激情五月狠狠喔| 99在线爽| 激情五月综合| 激情五月天在线观看色婷婷| 另类视频一区| 91精品久久久久久| 东京热伊人| www.99热精品99.com| 久久与婷婷| 碰碰女| 色婷综合| 淑女丝袜bi操逼123| 婷婷五月花| 婷婷月五天在线在线看| 亚洲综合激情五月久久| 丁香综合婷婷开心激情网| 五月天婷婷无码| 在线中文字幕免费视频| 亚洲色vA| 在线一起草av| 玖玖精品视频| www.婷婷,com| 欧美在线视频免费播放| 六月久久婷婷| 色婷婷成人网| 色婷婷综合网站| 色婷婷久久| 亚洲色区17| 五月开心深深爱激情综合| 亚洲成人影视在线| 国语精品探花| 色婷婷性爱| 色日本网| 伊人碰碰婷婷| 激情五月丁香五月| 日本久久综合| www.婷婷五月天| 天天舔天天插天天爱| 91婷婷| 五月婷婷五月天| 亚洲成人高清在线| 99惹在线精品免费观看| 女人高潮内射99精品| 亚洲 日韩色色| 狠狠综合网| 五月丁香久久综合| 久久大香蕉丁香| www.色擼擼.com| 久久久久久久91| 婷婷激情五月综合| 五月天婷婷基地| av狠狠操| 久久思思热视频| 日本美女97在线视频| 亚洲第一视频 久久| 视频一区二区在线| 大香蕉九操| 婷婷五月天AV| 色婷婷五月天av在线| 色色色国产| 91人人爽人人操| 日本九九视频| 日韩一区二区三区无码| 五月色婷丁香| 久热免费| www.国产色| 欧美日韩成人高清在线| 亚洲超碰在线| 五月亭亭直播| 天天日天天狠狠操| 色情婷婷久久五月天| 丁香五月五月婷婷| 人人操Av| 热九九九九| 丁香五月六月综合激情| 丁香欧美| 日韩成人电影在线播放| 99国产精品白浆在线观看免费| AⅤ色区| 欧美123区免| 97干婷婷| 大香蕉院线| 在线视频激情网站| 操操操97| 丁香五月天啪啪| www.五月天。com| 超级碰碰视频无码| 五月激情天| 婷婷五月花西瓜| 久久久久久综合88| 欧美碰碰| 激情文学综合婷婷五月天丁香花| 激情五月综合网最新| 亚洲激情av| 亚洲av另类在线观看| 久久永久视频| 狠狠做婷婷| 丁香五月天激情婷婷丁香六月| 97午夜一区二区| 九九人人操| 亚州性爱99| 综合AV在线| 岛国在线观看91| 久久草中文日韩欧美| 丁香伊人综合| 婷婷五月天播| 超碰色婷婷| 国产毛片精品一区二区色欲黄A片 99国产在线精品视频 | 99亚洲视频| 亚洲成人黄色网| 六月欧美综合色情| 婷婷在线免费| 国产婷婷综合在线免费视频| 91女人18毛片水多国产| 中文字幕乱码亚洲精品一区| 天天日天天爽| 99色在线视频| 成人网在线视频| www.99热最新视频8| 国产综合婷婷| 影音先锋91男人资源在线播放| 久久丁香五月天| 丁香五月在线| 26uu| 六月丁香五月亭亭| 秋霞午夜理论| 无码se| 超碰无码318604| 婷色五月| 五月丁香啪| 亚洲啪啪网| 五月激情五月婷婷五月天在线| 激情色中文| 狠狠爱婷婷丁香| 国产毛片操B| 夜精品无码A片一区二区蜜桃| 92久久| 99色色视频| 五月丁香六月婷婷亚洲| 亚洲精品五月| 五月综合色播播丁香婷婷| 丁香五月亭亭六月综合激情网| 日本美女上人| 九九AV在线| 丁香五月激情月| 国内自拍1区| 99ree6| 99热这里都是精品| 国产精产国品一二三在观看| 日本不卡高字幕在线2019| 99热精品在线观看| 婷婷97狠狠成人网站| 丁香五月婷婷啪啪| 五月丁香综合激情| 五月停亭六月,六月停亭的英语| 欧美色频| 久9视频| 高清视频一区| jiZZdr| 深爱开心激情| 中文字幕丰满孑伦无码专区| 伊人激情| 91大操| 奇米影视777在线_在线观看午夜_h小视频在线观看_岛国大片 | 色五月综合激情| 99久在线观看| 天天肏在线观看| 丁香五月最新地址| 国产成人+综合亚洲+天堂| 激情丁香婷婷| 六月丁香AV| 日韩久久欧亚| 丁香五月婷婷啪啪| 五月天婷婷爱丁香中文字幕| 操操操AV| www.婷婷久久五月天| 激情五月最新网址| 69久久99精品久久久久| 丁香五月天激情网址| 狠狠夜夜五月丁香| 中文字幕乱轮| 伊人久久婷婷| 亚洲偷| 在线91日韩| 激情婷婷久久| 热无码A∨| 婷婷五月天视频小说| 互月天综合| 色五月天成人| 99色视频| 丁香狠狠操| 综合AV在线| 99熟女视频| 99热精品少| 婷婷丁香五月,狠狠综合| 婷婷五月天视频亚洲| 91碰| 丁香五月色情av| 在线成人视频免费| 五月深爱婷婷| 亭亭玉月丁香| 日本人妻伦在线中文字幕| 亚洲精品99| 久草视频大香蕉99| 亚洲九九免费| 中文成人在线| 色婷婷狠狠| 五月婷婷爽爽爽| 九九www| 五月婷婷六月丁香综合视频在线| 日韩啊啊啊| 婷五月天在线草| 97韩国久久电影院| 大香蕉综合在线| 日本天堂网站99| 啪啪啪综合网| 99热这里只有精品在线| 99在线精品视频| 变态另类色图| 2020久久婷婷五月| 九九香蕉网| 欧美69久成人做爰视频| 婷婷丁香花五月天| 精品九九在线观看| 亚洲亚洲人成综合网络| 丁香五月AV| 最新激情五月天| 先锋资源婷婷| 少妇人妻人伦A片| 色婷婷综合成人| 91dy.av| 久久婷丁香五月| 天天草女人| 丁香婷婷网| 婷婷五月天干干| 第五色婷婷| HD久久精品视频| 久热这里有精品视频| 婷婷日欧美在线观看| 国产精品日本一区二区在线播放| 婷婷久久五月| 六月丁香色色| 五月丁香九九| 色五月六月| 色婷婷丁香A片区毛片区女人区| 激情综合在线观看| 亚洲男女激情| 大香蕉在线观看9| 狠狠五月天婷婷| 天天久久狠狠色综合| 99精品久久久久久久久| 五月婷婷婷自由综合| 在线你懂的亚洲欧| 日本婷婷| 五月婷婷丁香网| 九九热这里只有精品一| 中文字幕精品无码一区二区| 天天爽夜夜爽夜夜爽精| 五月激情小说| 美女亚洲五月丁香| 欧美在线视频99| 丁香五月婷婷啪啪| 色色a| 成人在线网址| 五月丁香六月香香蕉| 在线观看亚洲AV| 人人射人人高潮| 五月婷婷av在线| 亚洲综合五月天综合| 色婷婷婷婷| 手机在线日韩视频中文字幕| 大香蕉婷婷五月天| 亚洲综合99| 六月婷婷激情| 天天综合久久| 国产精品久久久久久亚洲毛片| 婷婷激情丁香五月婷婷激情丁香五月婷婷| 五月婷婷丁香| 色狠狠六月| 五月婷婷激情| 婷婷五月综合在线视频| 99热99日天天干| 中国激情网| 五月天色色色网| va亚洲中文在线| 婷婷丁香婷婷97| 婷婷金品综合视频| 大香蕉婷婷久久| 99性视频| www.国产亚洲69ty.久久久久久久久久久久| 淑女丝袜bi操逼123| 色色色色色色色色色色色色色五月天| 丁香激情网| 99九九热在线观看| 激情综合五月婷婷| 亚洲十月婷婷综合| 四川操逼站| 亚洲视频操| WWW.99热| 裸体做A爰片毛片A片免费| 五月丁香色五月| 黄色AAAA韩国guochansanji | www.五月天| 婷婷六月爽| 九月激情婷婷丁香| 亚洲99在线| 日本久久天堂| 婷婷综合中文| 操逼视频一区| 激情啪啪五月天| 日韩ww| 色播五月婷婷| 婷婷性爱网| 丁香六月婷婷| 激情五月丁香五月| 五月丁香婷婷综合视频| 免费看欧美成人A片无码| 人妻精品久久久久久| 久久婷婷激情四射五月天| 91超级碰| 伊人五月丁香| 六月丁香婷婷色狠狠久久| 狠狠干夜夜干| 色五开心五月五月深深爱| 亚洲色婷婷五月天| 激情六月天| 综合网五月天123| 九月婷婷激情| 日韩黄色影院| 五月伊人网| 伊人国产婷婷五月天| 99热国产婷婷| 中文字幕在线aⅴ免费观看| www.色婷婷.com| 色色综合色视频| 青青草99re| www.99视频| 另类激情五月天| 五月丁香A∨在线| 日韩无码色色| 激情五月天在线免费美女视频| 开心久久xxx色| 日本操B片| 天天干天天干天天操| 日本 @ va 免费| 97啪啪| 五月丁香 狠狠爱| 天天日天天干天天操| 五月情色天| 色黑鬼导航| 综合激情五月婷婷| 波多野结衣成人作品在线| 丁香五月婷婷色| 久久99美女精彩视频| 婷婷色综合| 一起草aV| 婷婷五月娱乐在线| 日韩在线观看网址| www.激情| 综合五月婷婷| 久久性爱视频久久性爱视频| 婷婷热婷婷色| 99开心五月五月丁香激情| 99热精品网| 黄桃AV无码免费一区二区三区| 婷婷性爱影院| 91婷婷丁香五月| 丁香六月情| 亚洲五月综合色播| 97五月天婷婷午夜| 五月激情五月丁香| 久久永久网址| 久久精彩免费视频精彩免费视频| 亚洲av日韩无码| 七月丁香五月婷婷在线| 99热在线播放| 日本va欧美va国产激情| 婷婷久热| 超碰人人艹| 99激情视频| 激情婷婷啪啪| 噜噜色com| site:publishdd.com| 亚洲视频丁香网va| 婷婷色系婷色| 日本成人噜噜噜噜噜| 婷婷六月丁香综合| 天天色天天爽| 激情深爱婷婷网| 久久大香蕉| 色婷婷香蕉| 久天综合| 99视频内射三四| 狠狠香蕉| 只有精品视频在线观看| 熟女激情网| 婷婷五月 丁香六月| 国内婷婷丁香社区在线播放| 少妇激情五月婷婷| 五月丁香花伦理电影| 久月丁香爱婷婷综合| 久操福利| 91碰在线| 婷婷色九月| 丁香狠狠色婷婷| 丁香五月伊人| 日本久久9| 91嫩草久久| 日本3级片一区2区| 日韩欧美一级大黄网站| 五月激情日本在线| 五月丁香婷中文字幕| 操操综合网婷婷| 99在线精品免费视频| 国产日产亚系列精品版优势| 色情综合网| 久久人妻少妇嫩草AV| 国产一级片色色| 久热re视频在线观看网站| 色色色1网址| 色婷婷色| 好好干Av| 丁香狠狠| 激情五月婷婷六月丁香| 婷婷五月天综合久久| av大香蕉| 极品精品一区二区三区在线| 无码动漫AV| 99日视频在线| 九九色色| 国产精品A片| 停婷丁五月在线| 色停停香蕉视频| 激情五月天色色网| 91人人人人人| 亚洲啪啪网| 久热这里这里有精品| 丁香五月冃欧美| 色色a| 91丨九色丨大屁股| 国产熟妇乱子伦hd| 91久久综合| 精品无码色| 婷婷五月天啪啪| 99re免费精品视频| 大香焦啪啪啪| 久久色天堂| 婷婷五月天综合蜜桃| 激情五月天婷婷丁香| 大香蕉啪啪啪| 色婷婷亚洲综合天堂| 婷婷伊人綜合| 婷婷丁香五月激情综合站_久久五月丁香激情综合_开心五月综合激情综合五月_婷 | 91xxxx九色| 丁香5月激情网| 婷婷丁香五月天在线| 婷婷丁香五月婷婷| 成人精品视频99在线观看免费| 久久九九激情五月天| 久热超碰91| 狠色狠色狠色狠色狠色网| 99热九九热| 91色色色| 久热伊人在91| 亚洲操操| 婷婷五月天视频免费在线观看| 久久ab| 9国产在线视频| 伊人色综合影院视频| 婷婷日日天天| 99久热这里只有精品| 亚洲视频另类| 天堂婷婷五月在线| 色色色五月婷| 精品九九久久| 99热啪啪| 狠狠干,狠狠操| 思思9久久| 女同激情久久av久久| 综合激情五月丁香| 激情五月综合| 男人天堂99| 黄色激情五月天| 国产欧美精品AAAAAA片| 色色婷婷丁香| 色色色干| 51成人| 色欲久久久久久综合网综合网| 丁香五月熟女| 伊人五月天婷婷| 日韩成人中文| 色五月视频无码播放| 天天日天天色| 亚洲中文字幕av| 日本美女五月天| 丁香五月激情五月| 五月综合色播播丁香婷婷| 国产人妻777人伦精品HD| 丁香婷婷五月天网站| 天天色宗合| 色婷婷亚洲| 中文色婷婷| 五月婷婷|欧美| 五月婷婷亚洲色视频| 日韩欧美性爱| 久久久久丁香婷婷五月天| 区欧美日韩成人| 日本激情五月天‘| 亚洲天堂制| 天堂草在线看www| 日本婷婷色| 精品久久艹| 亚洲成人无码免费| 99热碰碰| 大香蕉婷婷色| 97久久超碰| 一夜福利不卡| j五月香在线| 久狠日av| 婷婷丁香五月激情密臀av| 天天日天天舔| 久久久WWW| 婷婷五月天激情小说| 天堂爱爱| 综合狠久久| 六月久久狠狠| 人人九色| 人人草人人舔| A色色| 亚州激情九月| 91狠狠综合久久久| 台湾综合丁香五月蜜桃| 中日韩美欧成人一区二区精品在线| 五月天激情.com| 日本一级大片| 九九综合伊人| 五月天开心成人网| 五月天啪啪网| 91大屁股精品| 狠狠操天天操| 午夜激情四射影院| 欧美婷婷丁香五月社区| 蜜臀av无码久久久久久久久| 狠狠干.com| 六月婷婷五月丁香| 日日夜夜狠狠婷婷色| 无人区码一码二码三码医生系列| 亚洲视频图片婷婷五月| 大香蕉五月天婷婷| 婷婷情色开心五月天99| 五月精品| 日本www五月婷婷| AV网在线观看| 99热免| 婷婷五月综合在线视频| 六月丁香停| 婷色五月天| 久热网在线视频| 99精品久久久| 人人操9| 亚洲无码另类| 久久aaaa片一区二区| 色综合久久44| 岛国AAAV| 亚洲综合激情五月久久| 欧洲免费视频色| 亚洲愉拍99热成人精品| 90色免费视频| 婷婷伊人五月天| se影音资源在线观看| 99视频色在线观看| 色综合久久综合| 最近中文字幕大全免费版在线 | 狠狠人人| 日本一毛片| 国产精品电| 五月丁香激情综合网| 99爱在线视频观看| 色综合爽| 久久久精品AV| 4438全国最大视频成人网站在线观看| 91色久| 国产午夜精品一区二区| 99色 色| www久久五月com| 婷婷五月天AV在线| 91欧美日韩| 成人综合网站| 九九Av| 久久久免费精彩视频| 丁香五月骚喷水视频| 狠狠久久婷五月| 日本少妇AA一级特黄大片| 成人精品视频99在线观看免费| 欧美精品啪啪| 五月天亚洲综合网| 凹凸操Av| 99热精品综合| 色宗合,宗合网| 人妻人人操| 国产成人AV在线播放| 99网址在线观看| 欧美搡BBBBB摔BBBBB| 色色婷| A1片久久久| 丁香五月成人av| 五月婷婷网站| 色五月五月丁香| 台湾综合丁香五月蜜桃| 开心婷婷五月天综合| 热99精品视频五月| 99九九中文字幕视频| 天天色五月婷婷91久久久久久久| 亚洲中文字幕在线观看| 精品人妻伦一二三区久久| 亚洲中文字幕av| 91要啪| 五月天伊人久久久久| 五月婷婷中文字幕| 欧美α√| 色综合久久五月天| 这里只有精品在线视频在线观看| 丁香五月婷综合网| 天天日日综合| 婷婷射婷婷舔| 欧美色色色色色色色| 婷婷五月色亚洲| 丁香五月天啪啪激情综合网| 久色网五月| 思思热再线视频| 亚洲精品久久久久久久久久吃药| 夜夜骑日日夜夜| α久久| 久久这里99| 激情婷婷丁香色五月| 欧美激情2025| 五月丁香狠狠| 天天日天天日天天搞| 婷婷激情五月天在线| 久久人妻视步| 天天爽天天干| 99九九热在线观看| 很很干天天干| 色五月综合| 国产精产国品一二三在观看| 成人片黄网站色大片免费毛片| 大香蕉久久青青| 婷婷五月丁香青青草在线| 97操碰在线97| 久久9热| 九九黄色网| 婷婷久久婷婷色五月| 丁香婷婷少妇| 久久色五月天综合网| 人人操av| 色色色色色色色色综合网| 五月激情啪啪| 日本久久九| 婷婷六月综合基地| 中文字幕av在线| 色五月天天在线观看资源站| 色久五月| 能直接看的av网站| 色五月综合激情| 99精品成人无码A片观看金桔| 牛色色碰| 亚州色综合| 超碰91在线| 五月色导航| 色五月婷婷很很操| 色婷婷香蕉| 青青草国产亚洲精品久久| 91女人18毛片水多国产| 亚洲视频操| 一区二区三区四区五区| 久久五月天色| 久热超碰| 超碰cap| 日韩 中文 欧美| 婷婷丁香五月天综合网| 九热视频| 大香蕉520| 亚洲成人av在线观看| 亚洲不卡| 另类图片婷婷五月天| 五月婷婷成人| 国产成人精品一区二三区熟女在线| 色婷婷五月丁香色| 在线中文字幕视频| 俺去也在线www色官网| 久久五月天色婷婷| 国产乱子轮XXX农村| 色五月欧美| 婷婷开心青青草| 日韩黄色电影| 中文字幕无线久必| 亲子乱AV一区二区三区下载| 丁香五月亚洲综合| 久久婷婷五月综合| 精品自拍99| 色色色色热热| 色99在线| 九九综合九| 丁香婷婷网| 日韩色五月| 婷婷综合久久| 91精品久久久久久久久久久久| tingtingzonghewang| 996er热| 潮汕成人AV片在线| 精品99这里有| 久99久精品| 香蕉久久五月| 国产欧美婷婷五月| 99热这里是精品| 五月天大香蕉AV| 《》【无码】想被搞到爽AV应募而来的超M素人 西纯子 10musume-011723-01 | 六月色 亚洲| 99色啊| 婷婷激情综合| 99在线综合视频| 色情激情五月| 激情AV| AV在线大香蕉| 久久综合五月| 99热 日韩| 伍月激情天| 久久综合99| 亚洲操B视频| 天天操综合网站| 白人荫道BBWBBB大荫道| 99热国品免费| 无码啪啪| 99在线视频免费| 五月综合色播播丁香婷婷| 久久久天堂国产精品女人| 亚洲精品99| 久久婷婷丁香| 1234操逼网| 五月婷婷六月婷| 丁香五月婷婷免费视频| 婷婷综合网在线| 五月婷婷久久综合| 欧美激情综合| 久久99综合| 五月伊人网| 色综合大香蕉| 五月天婷婷伊人| 色综合天天| 久久精品天| 激情色色色| 五月婷中文娱乐综合| 婷婷五月激情在线| 狠狠色丁香乆乆| 另类国产综合| WWW色五月| 丁香五月天婷婷中文| 色五月激情五月| 五月激情网五月综合网| 性做久久久久久久免费看| 亚洲五月丁香综合网| 精品久久99码| 激情另类综合| 五月花婷婷| 一根材五月婷成人| 中文字幕日产A片在线看| 婷婷丁香午夜综合影视| 熟妇无码乱子成人精品| 《》【无码】想被搞到爽AV应募而来的超M素人 西纯子 10musume-011723-01 | tingtingjiqingwuyue| 丁香激情网| 91艹人| 99热在线观看| 狠狠色婷婷六月激情网| 激情色情五月天| 五月天激情视频| 婷婷午夜精品久久久| 色五月婷婷av| 色五月婷婷五月丁香五月激情五月视频| 亚洲激情另类| AV天堂淫乩| 久久大国产香蕉| 婷婷五月丁香手机在线视频| 91色碰| 91综合国免费久入| 中文字幕成人| 国产SUV精品一区二区6| 久热这里只有精品视频6| 婷婷五月丁香四射| 色色色99| 五月天久久久| 免费看成人AA片无码视频吃奶| 九九热短视频在线观看 | 青青福利网| 中文字幕在线不卡视频| 日韩成人中文字幕| 伍月婷婷免费视频| 丁香五月天成人| 久久久这里有精品| 久久 婷婷 五月天| 大学生高潮无套内谢视频| 激情五月天小说视频| 99色久| 色色色无码| 五月婷婷婷婷婷婷艺术| 六月丁香激情| 九九色婷婷| Www,五月天| 激情五婷网| 成人无码精品1区2区3区免费看| 在线可以看的av网址| 日韩黄色电影| 久久精品99国产精品日本| 天天天天天日| av大香蕉| 婷婷久久爱| 人妻人人操| 五月丁香六月婷婷亚洲| 国产操B视频| 性做久久久久久久免费看| 色婷婷狠狠18| 99er这里只有精品视频| 99ri6在线视频| 婷婷久久综合久| 婷婷丁香五月,狠狠综合| 亭亭色网| 久操香蕉| 色色色综合网| 99热99热99热99热| 91欧美| 国产女生爱爱AA| 五月婷婷综合在线| 天天干狠狠| 国产成人AV人人爽人人澡Va| 日本123区日韩欧美不卡在线看| 亚洲六月婷婷| 久久婷婷五月综合| 婷婷永久在线| www九九| 嫩草哈哈操| 丁香五月天啪啪| 婷婷色导航| 色综合五月婷婷狠狠干| 久草性爱| 无码人妻一区二区一牛影视| 久色网| 亚洲婷婷五月| 天天干天天叉| 九九99视频精品| 成人五月天丁香婷| 日日夜夜亚洲一区| 色色亚洲| 碰超99| 日日夜夜天天综合| 五月丁香婷婷婷婷综合网| 日韩精品999| 伊人激情网| 无码成人AAAAA毛片AI换脸| 丁香五月中文字幕| 噜噜网免费视频| 激情亚洲色图片丁香综合| 久久五月综合| 色吊丝永久访问网址| 人人操超碰| 精品一区二区三区四区五区六区| 97九色| 色婷婷五月综合| 婷婷丁香五月亚洲综合网在线视频观看| 99久久久国产大片区| 99色在线观看视频| 国产黄色大片| av网站不卡在线| 丁香五月色| 99操视频| 欧美99视频| 久久九九色| 深爱激情丁香五月| 久99久热只有精品国产99| 婷婷四月 成人 狠狠干| 六月婷婷av| 丁香五月AV| 婷婷丁香综合| 欧美婷婷色五月网| 91干99| 九九婷婷热| 丁香五月婷婷欧美性爱| 亚洲激情网| 激情五月天 婷婷| 亚洲精品乱码久久久久99| 日韩1区2区| 色综合久久99色| 婷婷五月天综合AV| 99视频在线精品| 九九这里都是精品| 一本道综合网| 国产色99| 五月天婷婷爱丁香中文字幕| 99视频在线| 婷婷五月天色| 人妻中文字幕网| 思思热99er在线视频| 婷婷婷婷色| 久久99热这里只频精品6学生| 影音先锋一区二区资源站| 久热大香蕉| 色综合天天天天做夜夜| 人人操五月天| 天综合日日夜综合7799| www.激情在线| 超碰高清在线| 精品一区二区三区免费毛片爱| 男人天堂AV在线一区二区| 日本熟女三区| 综合狠狠干| 激情小说色五月| 超碰在线看| 亚洲最大激情无码| 亚洲欧美在线观看| 亚洲最大在线| 色色色免费视频| 天天干天天干天天| 97婷婷狠狠| 色色色色色网站| 丰满人妻一区二区三区| 91超级碰在线| 五月丁香狠狠| 超碰99在线| 亚洲99综合| 五月婷综合| 色五月婷婷成人| 亚洲色9| 色婷婷综合影院| 久久免费少妇高潮99精品| 伍月婷丁香婷| 中文AV在线观看| 色五月婷婷丁香凹凸| 梁铮版蜘蛛女在线观看| 在线成人网站| 99玖玖人人| 精品无码99| 少妇真实被内射视频三四区| 99精品在线| 婷婷八月丁香激情综合| 91在线视频观看午夜福利| 色婷婷久久综合久色| 超碰人人干| 2015WWW永久免费观看播放| 国产精品激情五月天色婷婷| 99久久婷婷国产综合精品草原| 激情婷婷丁香五月天| 婷婷五月丁香六月综合网| 91碰碰视频在线观看| 日日噜噜久久婷婷五月天| www激情| 日本WWW九九九| 色色AV色色色东莞| 亚洲人操亚洲人| 激情网第四色| 丁香五月综合| 九九热99re8热免费观看 | 97碰碰人人| 99精品久久久久| 性色综合网| 五月天久久综合婷婷丁香| 一级黄在线| 国产婷婷五月中文字幕高清| 丁香五月综合| 久99热| 欧美精品999| 丁香六月婷婷久久高清| 99热只有| 視频福利乱色| 婷婷五月天天天| 久久国产高潮白浆免费观看99| 色色色国产| 这里只有精品96| 色婷婷香蕉丁丁网| 丁香五月婷婷综合啪啪| 99 这里只有精品| 97干干干丁香| 人人综合五月人人婷婷| 成人网在线观看视频| 成人网站免费sxj| 天堂婷婷综合| 欧美亚洲操逼| 婷婷五月五月丁香| 欧美激情五月| 久9热插入| 色婷婷综合视频| 精品综合爱| 久婷婷色| 99热超碰| 99亚洲综合| 国产在线aaa片一区二区99| 狠狠擼综合| 无码一区精品一区视频| 五月久久亚洲| 色色999三级片| 可似看的AV| 麻豆精品| 日本啪啪网| 婷色五月| 欧美色婷婷| 四色女婷婷| 无码字幕中文| 五月激情婷婷国产精品久久久久久| 丁香五月大香蕉AV| 婷婷色啪| 天天综合网、天天综合色| 狠狠操狠狠| 九九视频精品在线免费| 一起操最新网址| 五月天综合久久| 99热在线精品观看| 色噜噜狠狠狠狠色综合久欧美| 91婷婷丁香五月亚洲| 五月丁香六月成人| 人人操操| 激情五月丁香五月| 色婷婷五月基地在线| 日日操天堂| 噜噜国产| 色五月网址| 粉嫩AV久久一区二区三区| 日韩精品无码99| 天天干天天曰天天射| 丁香六月婷婷综合| 婷婷综合五月激情| 青青久久五月天丁香婷婷| 超碰高清在线| 久久综合这里只有精品1| 日韩黄在免| 婷婷综合在线| 亚洲性受XXXX五月丁香| 激情内射人妻1区2区3区| 欧美人人草| 久久多色| 成人国产欧美大片一区| 色五开心五月五月深深爱| 五月天婷婷操逼视频| 五月激情在线| 五月婷婷在线综合| 99熟女视频| 精品香蕉99久久久久网站| 丁婷婷五月天在线播放| 久久激情五月| 欧美色男人网站| pom538精品视频| 人人操Av| 9一精品视频观看| 婷婷六月色| 天天影视色综合网| 狠狠第四色| 青青草免费公开视频| 狠狠五月天| 激情丁香婷婷六月天| 日韩啪啪自拍| www.99视频| 欧美va欧美va差| 婷婷中文在线| 欧美性爱专区| 亚洲午夜AV| 情婷婷五月天| 操碰91| 久久99草五月婷婷| 99热这里只有精品16| 五月天精品综合| 五月天色色激情综合| 一级视频网址| 激情五月综合| 日韩1区2区| 色必久悠悠影院| 亚洲色色五月天| 精品一二三区久久AAA片| 蜜桃人妻无码AV天堂三区| 激情五月综合色婷婷| 五月丁香久久呀| 香蕉AV777XXX色综合一区| 成人电影在线免费试看| 99久久婷婷五月天| 网色99| 狠狠干狠狠操狠狠爱| 九九99精品| 99色| 天天操天天日天天操| 人妻爽爽爽久久久久久久久| 99久久五月丁香野外| 丰满少妇猛烈A片免费看观看 | 极品色丁香| 久久精彩视频18| 99无码视频| 91久久色| 亚洲色A| 秋霞午夜理论| 人人人操| 葵花AV在线| 丁香五月激动深爱欧美| 丁香五月电影| 色婷婷综合网| 天天拍久久| 五月丁香网av| 99热这里都是精品| 激情综合网站| 夂夂夂夂夂夂夂夂夂夂夂夂夂夂夂夂夂夂夂亚洲亚洲亚洲亚洲亚洲亚洲亚洲亚洲色 | 99碰碰| 夜夜谢天天干| 天天爽综合| va婷婷在线| 99久热在线精品| 婷婷五月综合网| 婷婷丁香五月天大香蕉| 狠狠五月婷婷| 另类少妇人与禽zOZZ0性伦| 夜夜夜夜夜操| 91超级碰在线视频| 噜一噜在线|