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

ARTICLE DETAIL

資訊詳情

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

Node.js+Express+MySQL寵物用品購物網(wǎng)站開發(fā)實(shí)戰(zhàn):畢業(yè)設(shè)計(jì)完整指南

Node.js+Express+MySQL寵物用品購物網(wǎng)站開發(fā)實(shí)戰(zhàn):畢業(yè)設(shè)計(jì)完整指南 簡介這是基于Node.js、Express與MySQL構(gòu)建的前后端分離寵物用品購物網(wǎng)站畢業(yè)設(shè)計(jì)源碼面向計(jì)算機(jī)專業(yè)畢業(yè)生、課程設(shè)計(jì)學(xué)生以及全棧開發(fā)入門者可完整學(xué)習(xí)后端服務(wù)搭建、數(shù)據(jù)庫設(shè)計(jì)、接口開發(fā)及前端交互的電商項(xiàng)目實(shí)踐。壓縮包共669個(gè)文件總大小12.02MB包含193個(gè)js邏輯文件路由、中間件、業(yè)務(wù)處理、39個(gè)vue頁面組件、51個(gè)css樣式、28個(gè)html頁面、1個(gè)sql數(shù)據(jù)庫腳本以及5個(gè)bat輔助啟動(dòng)腳本并配有svg、gif、jpg、png等圖片素材、字體文件及Markdown說明文檔目錄結(jié)構(gòu)完整解壓后可直接部署運(yùn)行。目前已有95人學(xué)習(xí)下載適合作為畢業(yè)設(shè)計(jì)答辯、課程作業(yè)或商城項(xiàng)目原型參考。項(xiàng)目覆蓋商品瀏覽、購物車、訂單管理、用戶注冊(cè)登錄等核心業(yè)務(wù)模塊同時(shí)涉及Node.js異步編程、Express路由與中間件、MySQL數(shù)據(jù)持久化、RESTful API設(shè)計(jì)、JWT用戶認(rèn)證、模板引擎渲染、JSON數(shù)據(jù)交互、支付接口預(yù)留以及測試部署思路等關(guān)鍵技術(shù)點(diǎn)并附帶啟動(dòng)腳本和數(shù)據(jù)庫初始化文件幫助讀者系統(tǒng)掌握全棧開發(fā)流程便于快速上手和二次擴(kuò)展。1. 畢業(yè)設(shè)計(jì)選「寵物用品購物網(wǎng)站」最怕的不是做不完而是做完講不清畢業(yè)設(shè)計(jì)選「寵物用品購物網(wǎng)站」這個(gè)題目最怕的不是功能做不完而是做完之后講不清楚里面的技術(shù)點(diǎn)?;?Node.js Express MySQL 的前后端分離實(shí)現(xiàn)恰好壓在一個(gè)很舒服的位置功能上有商品瀏覽、搜索、購物車、下單、訂單管理足夠支撐起一份完整的畢業(yè)設(shè)計(jì)或課程設(shè)計(jì)技術(shù)上沒有引入 Redis、消息隊(duì)列這類難講清楚的東西前后端之間的每一次數(shù)據(jù)交換都能畫出明確的流程圖。這套源碼不追求炫技它的價(jià)值在于讓你在兩周內(nèi)復(fù)現(xiàn)出一個(gè)能跑、能截圖、能在答辯時(shí)講明白的電商閉環(huán)。正在找設(shè)計(jì)題目的同學(xué)或者想用 Node.js 棧做項(xiàng)目實(shí)踐的開發(fā)者都可以用它作為起點(diǎn)。2. 動(dòng)手之前Node.js 版本、MySQL 8.0 初始化和建庫的完整細(xì)節(jié)2.1 為什么是 Node.js Express MySQL而不是 Spring Boot 或 PHP選擇技術(shù)棧的底層邏輯不是「哪個(gè)火選哪個(gè)」而是「答辯被追問時(shí)你有多大的把握解釋清楚」。Java Spring Boot 在畢業(yè)設(shè)計(jì)里確實(shí)主流但很多同學(xué)在答辯時(shí)會(huì)被問到「Spring 的 Bean 生命周期」「自動(dòng)配置原理」這些問題對(duì)于只做了 CRUD 的人來說很難答好。PHP 寫起來快但簡歷和項(xiàng)目呈現(xiàn)上都顯得不夠新。Node.js Express 的優(yōu)勢(shì)是語言單一前端 Vue 用的是 JavaScript后端 Express 也是 JavaScript你只需要熟練一種語法就能打通前后端。從架構(gòu)上講這套組合的請(qǐng)求鏈路非常板書友好Vue 頁面通過 axios 發(fā)起 HTTP 請(qǐng)求 → Express 路由層接收 → Controller 處理業(yè)務(wù)邏輯 → 通過 mysql2 查詢數(shù)據(jù)庫 → 返回 JSON 給前端渲染。每一步都有一個(gè)明確的「層」每一層都有對(duì)應(yīng)的目錄和文件這在答辯畫架構(gòu)圖時(shí)是天然分層的。而且 Express 的中間件機(jī)制是必考點(diǎn)——app.use(cors())、app.use(bodyParser.json())、app.use(/api/user, require(./routes/user))這三行代碼擺在黑板上就能把「洋蔥模型」「中間件執(zhí)行順序」這些概念串起來老師在這一點(diǎn)上通常愿意給高分。2.2 環(huán)境搭建Node.js 版本選擇以及 MySQL 免安裝版的血淚經(jīng)歷先說版本結(jié)論。Node.js 裝 16 或 18 的 LTS 版本不要追新裝 20 以上的奇數(shù)版本。原因很現(xiàn)實(shí)源碼包里用到的某個(gè)依賴可能在最新版 Node 上有棄用警告雖然不影響運(yùn)行但答辯演示時(shí)控制臺(tái)飄一堆警告也不太好看。MySQL 裝 8.0 系列別下載 5.7因?yàn)?8.0 對(duì) utf8mb4 字符集、JSON 函數(shù)、窗口函數(shù)的支持更完整而且現(xiàn)在的教程、踩坑記錄基本都是針對(duì) 8.0 寫的遇到問題更容易搜到答案。Windows 上安裝 Node.js 沒什么好說的官網(wǎng)下載 LTS 版本一路 Next 即可。MySQL 才是重頭戲。如果你下載的是 zip 免安裝版會(huì)踩到整個(gè)項(xiàng)目里最麻煩的一個(gè)坑——沒有data目錄。第一次啟動(dòng)net start mysql會(huì)直接失敗錯(cuò)誤日志里寫Data Dictionary initialization failed。原因是免安裝版不會(huì)自動(dòng)初始化數(shù)據(jù)目錄。我一般這樣處理# 以管理員身份打開命令行進(jìn)入解壓后的 MySQL 目錄 # 初始化數(shù)據(jù)目錄這一步會(huì)在輸出日志里生成一個(gè)臨時(shí) root 密碼 mysqld --initialize --console # 初始化完成后把 MySQL 注冊(cè)成 Windows 服務(wù) mysqld --install MySQL # 啟動(dòng)服務(wù) net start MySQLmysqld --initialize --console這條命令會(huì)把初始化過程打印到控制臺(tái)其中有一行temporary password is generated后面跟著臨時(shí)密碼第一次登錄必須用它登錄后馬上改密碼。注意如果你執(zhí)行了mysqld --initialize卻沒記下臨時(shí)密碼那只能刪掉 data 目錄重新初始化沒有后悔藥。我從那以后每次初始化都把控制臺(tái)輸出截圖保存。驗(yàn)證環(huán)境是否就緒node -v npm -v mysql -u root -p輸入密碼后能進(jìn)入mysql提示符說明 Node 和 MySQL 兩個(gè)基礎(chǔ)環(huán)境都通了。這里有一個(gè)容易被忽略的細(xì)節(jié)mysql -u root -p后面千萬不要直接跟密碼比如-p123456命令行會(huì)提示 warning說密碼暴露在命令行里不安全。2.3 建庫建表字符集選 utf8mb4 而不是 utf8以及商品表結(jié)構(gòu)設(shè)計(jì)登錄 MySQL 后建庫。建庫時(shí)字符集的選擇是第一個(gè)會(huì)實(shí)際踩到的坑CREATE DATABASE pet_shop DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; USE pet_shop; -- 用戶表 CREATE TABLE user ( id INT AUTO_INCREMENT PRIMARY KEY, username VARCHAR(50) UNIQUE NOT NULL, password VARCHAR(255) NOT NULL COMMENT 存的是 bcrypt 哈希不是明文, phone VARCHAR(20), create_time DATETIME DEFAULT CURRENT_TIMESTAMP ) ENGINEInnoDB DEFAULT CHARSETutf8mb4; -- 商品表 CREATE TABLE product ( id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(100) NOT NULL, category VARCHAR(50) NOT NULL COMMENT 貓糧、狗糧、玩具、日用品, price DECIMAL(10,2) NOT NULL, stock INT DEFAULT 0, image VARCHAR(255) COMMENT 商品主圖路徑, description TEXT COMMENT 詳情描述支持中文和表情符號(hào) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4;為什么用 utf8mb4 而不是 utf8因?yàn)?MySQL 的 utf8 實(shí)際最多存 3 字節(jié)字符而寵物用品詳情的文案里經(jīng)常有 這類 emoji它們是 4 字節(jié)的。用 utf8 建表插入 emoji 會(huì)直接報(bào)錯(cuò)Incorrect string value。這個(gè)坑早期我栽過一次后來建庫第一條命令就定死 utf8mb4。表結(jié)構(gòu)設(shè)計(jì)上有一個(gè)值得在答辯時(shí)講的點(diǎn)price為什么用DECIMAL(10,2)而不是FLOAT。因?yàn)楦↑c(diǎn)數(shù)在 MySQL 里存儲(chǔ)會(huì)丟失精度比如 19.99 在 FLOAT 存儲(chǔ)后查出來可能是 19.989999。DECIMAL 是定點(diǎn)數(shù)按字符串存儲(chǔ)不會(huì)丟精度。購物網(wǎng)站的金額計(jì)算涉及錢精度問題在答辯時(shí)是必考加分項(xiàng)。提示源碼包自帶的pet_shop.sql里已經(jīng)建好了全部表包括購物車表cart、訂單表orders、訂單明細(xì)表order_items。用mysql -u root -p pet_shop pet_shop.sql導(dǎo)入之前先確認(rèn)數(shù)據(jù)庫字符集是 utf8mb4否則導(dǎo)入后表的中文會(huì)變成亂碼。3. Express 后端實(shí)現(xiàn)路由分層、JWT 登錄和商品分頁的邊界坑3.1 入口文件與目錄分層中間件注冊(cè)順序?yàn)槭裁床荒軄y拿到源碼包后先把后端目錄結(jié)構(gòu)看清楚。這個(gè)項(xiàng)目的后端分層思路是標(biāo)準(zhǔn)的 Express 工程結(jié)構(gòu)pet-shop-server/ ├─ app.js # Express 入口 ├─ config/ │ └─ db.js # MySQL 連接配置mysql2 ├─ routes/ │ ├─ user.js # 注冊(cè)、登錄路由 │ ├─ product.js # 商品列表、搜索、詳情路由 │ └─ order.js # 下單、訂單列表路由 ├─ controllers/ │ ├─ userController.js # 業(yè)務(wù)邏輯查庫、加密、簽發(fā) token │ ├─ productController.js │ └─ orderController.js ├─ middleware/ │ └─ auth.js # JWT 鑒權(quán)中間件 └─ package.jsonroutes 只負(fù)責(zé)定義 URL 路徑真正的邏輯在 controllers 里。這個(gè)分層習(xí)慣極其重要——如果所有代碼都寫在 app.js 里前期開發(fā)快但后期調(diào)試會(huì)非常痛苦。入口文件app.js的中間件注冊(cè)順序有一點(diǎn)講究const express require(express); const cors require(cors); const bodyParser require(body-parser); const app express(); // 中間件注冊(cè)順序CORS → bodyParser → 路由 → 404 兜底 app.use(cors()); app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: true })); app.use(/api/user, require(./routes/user)); app.use(/api/product, require(./routes/product)); app.use(/api/order, require(./routes/order)); // 404 兜底必須放在所有路由之后 app.use((req, res) { res.status(404).json({ message: 接口不存在 }); }); app.listen(3000, () { console.log(server running at http://localhost:3000); });這段代碼里有三個(gè)細(xì)節(jié)要在答辯時(shí)能解釋。第一cors()必須放在最前面因?yàn)榭缬蛐r?yàn)發(fā)生在請(qǐng)求進(jìn)入業(yè)務(wù)處理之前如果寫成app.use(cors())之前還有別的中間件瀏覽器可能已經(jīng)攔截了響應(yīng)。第二bodyParser.urlencoded({ extended: true })不能省有些表單提交的 Content-Type 是application/x-www-form-urlencoded只配了json()解析器時(shí)請(qǐng)求體會(huì)變成空對(duì)象{}這是新手排查半天都找不到原因的經(jīng)典問題。第三404 兜底路由必須在所有業(yè)務(wù)路由注冊(cè)之后否則它會(huì)先捕獲所有請(qǐng)求。3.2 用 JWT 做登錄鑒權(quán)token 里該放什么、過期時(shí)間該設(shè)多長前后端分離架構(gòu)下登錄狀態(tài)不依賴 session因?yàn)榍岸撕秃蠖丝赡懿辉谕慌_(tái)服務(wù)器上session 存在服務(wù)端內(nèi)存里無法共享。標(biāo)準(zhǔn)做法是 JWT用戶登錄成功后后端用密鑰對(duì)用戶 id 簽名生成一個(gè) token 返回給前端前端存到 localStorage每次請(qǐng)求在 Header 里帶Authorization: Bearer token。// middleware/auth.js const jwt require(jsonwebtoken); const SECRET pet-shop-secret-key; // 實(shí)際項(xiàng)目放 .env module.exports function auth(req, res, next) { const header req.headers.authorization; if (!header) { return res.status(401).json({ message: 未登錄請(qǐng)先登錄 }); } // 格式約定Bearer tokensplit 后取第二部分 const token header.split( )[1]; try { const payload jwt.verify(token, SECRET); req.userId payload.id; // 最關(guān)鍵把用戶 id 掛到 req 對(duì)象上后面的路由直接用 next(); } catch (err) { return res.status(401).json({ message: token 無效或已過期 }); } };這段代碼是鑒權(quán)中間件的標(biāo)準(zhǔn)模板。jwt.verify會(huì)同時(shí)校驗(yàn)簽名和過期時(shí)間token 被篡改或過期都只會(huì)走到 catch 分支返回 401。登錄接口里簽發(fā) token 的邏輯// controllers/userController.js節(jié)選 const bcrypt require(bcryptjs); const jwt require(jsonwebtoken); const db require(../config/db); exports.login (req, res) { const { username, password } req.body; // 參數(shù)校驗(yàn)空值直接返回 400不要在 SQL 層面兜 if (!username || !password) { return res.status(400).json({ message: 用戶名和密碼不能為空 }); } // 參數(shù)占位符 ? 防止 SQL 注入 db.query(SELECT * FROM user WHERE username ?, [username], (err, results) { if (err) return res.status(500).json({ message: 服務(wù)器內(nèi)部錯(cuò)誤 }); if (results.length 0) { return res.status(400).json({ message: 用戶不存在 }); } const user results[0]; // bcrypt.compareSync 返回布爾值 const isMatch bcrypt.compareSync(password, user.password); if (!isMatch) { return res.status(400).json({ message: 密碼錯(cuò)誤 }); } // 簽發(fā) token有效期 7 天 const token jwt.sign( { id: user.id, username: user.username }, SECRET, { expiresIn: 7d } ); res.json({ token, username: user.username, message: 登錄成功 }); }); };JWT 的過期時(shí)間設(shè) 7 天這個(gè)選擇值得在答辯時(shí)解釋。管理后臺(tái)系統(tǒng)通常設(shè) 30 分鐘因?yàn)椴僮髅舾须娚糖岸擞脩舨豢赡苊堪胄r(shí)重新登錄一次7 天是「安全性和用戶體驗(yàn)的折中」。你能說出這個(gè)理由老師會(huì)覺得你不是隨便選了一個(gè)數(shù)字。另外注意bcrypt.compareSync是同步方法在真實(shí)高并發(fā)項(xiàng)目里應(yīng)該用異步的bcrypt.compare但畢業(yè)設(shè)計(jì)里同步方法足夠而且答辯時(shí)可以主動(dòng)提起「我知道有異步版本在高并發(fā)下性能更好」這是一個(gè)主動(dòng)展示知識(shí)邊界的好機(jī)會(huì)。3.3 商品分頁接口total 計(jì)數(shù)、offset 計(jì)算、LIMIT 綁定商品列表是所有用戶都能訪問的接口不需要 token。分頁接口有兩個(gè)容易踩的坑源碼里已經(jīng)處理好了但你需要知道原因。第一個(gè)坑是分頁偏移量的計(jì)算。前端傳page和pageSize后端算offset (page - 1) * pageSize。很多新手直接把page當(dāng) offset 用首頁能出數(shù)據(jù)翻到第二頁就重復(fù)了。第二個(gè)坑是 total 字段。分頁組件要算總頁數(shù)就必須知道總記錄數(shù)。所以接口返回里必須帶total否則前端只能靠「這頁是否還有數(shù)據(jù)」來猜測有沒有下一頁。源碼里的實(shí)現(xiàn)// controllers/productController.js節(jié)選 exports.list (req, res) { const page parseInt(req.query.page) || 1; const pageSize parseInt(req.query.pageSize) || 10; const category req.query.category || ; // 動(dòng)態(tài)拼接 WHERE 條件前提是 category 不是用戶可隨意構(gòu)造的復(fù)雜條件 let where ; const params []; if (category) { where WHERE category ?; params.push(category); } // 第一步查總數(shù) db.query(SELECT COUNT(*) AS total FROM product ${where}, params, (err, countResult) { if (err) return res.status(500).json({ message: 查詢失敗 }); const total countResult[0].total; const offset (page - 1) * pageSize; // 注意mysql2 舊版本在 LIMIT 子句里用 ? 占位可能會(huì)有問題 // 所以這里直接拼接數(shù)字offset 和 pageSize 都已經(jīng)通過 parseInt 轉(zhuǎn)成了整數(shù) const sql SELECT * FROM product ${where} ORDER BY id DESC LIMIT ${offset}, ${pageSize}; db.query(sql, params, (err, rows) { if (err) return res.status(500).json({ message: 查詢失敗 }); res.json({ list: rows, total: total, page: page, pageSize: pageSize }); }); }); };關(guān)于 LIMIT 子句的占位符問題補(bǔ)充一句mysql2 驅(qū)動(dòng)在 2.x 版本之后已經(jīng)支持LIMIT ?, ?綁定如果你用的驅(qū)動(dòng)版本較新可以寫成db.query(sql, [...params, offset, pageSize], cb)的形式。老驅(qū)動(dòng)在 LIMIT 里用占位符可能直接報(bào)語法錯(cuò)誤所以源碼里選擇直接拼接整數(shù)。這個(gè)細(xì)節(jié)在答辯時(shí)被問到時(shí)你可以回答「為了兼容 mysql2 舊版本的驅(qū)動(dòng)行為offset 和 pageSize 經(jīng)過 parseInt 后確認(rèn)是整數(shù)再直接拼進(jìn) SQL不存在注入風(fēng)險(xiǎn)如果驅(qū)動(dòng)版本支持占位符我會(huì)改成全綁定寫法?!?. 前端 Vue 對(duì)接axios 攔截器、購物車狀態(tài)和下單流程的先后順序4.1 前端目錄與 axios 封裝請(qǐng)求攔截器里自動(dòng)帶 token前端部分源碼用的是 Vue 2 Element UI這套組合在畢業(yè)設(shè)計(jì)里極其常見。目錄結(jié)構(gòu)如下pet-shop-web/ ├─ src/ │ ├─ api/ │ │ ├─ request.js # axios 實(shí)例 攔截器 │ │ ├─ product.js # 商品接口封裝 │ │ ├─ user.js # 登錄注冊(cè)封裝 │ │ └─ order.js # 訂單接口封裝 │ ├─ views/ │ │ ├─ Home.vue # 商品列表 │ │ ├─ Cart.vue # 購物車 │ │ ├─ Order.vue # 訂單確認(rèn) │ │ ├─ OrderList.vue # 訂單列表 │ │ └─ Login.vue # 登錄注冊(cè) │ ├─ router/index.js │ └─ App.vue └─ package.jsonaxios 封裝是整個(gè)前端最值得寫的一段代碼。新手最容易犯的錯(cuò)是在每個(gè)頁面里手動(dòng)寫請(qǐng)求頭token 字段在十幾個(gè)文件里重復(fù)出現(xiàn)項(xiàng)目一大就失控。正確做法是在請(qǐng)求攔截器里統(tǒng)一注入// src/api/request.js import axios from axios; import router from ../router; // 創(chuàng)建 axios 實(shí)例 const request axios.create({ baseURL: http://localhost:3000/api, // 后端接口前綴 timeout: 10000 // 10 秒超時(shí) }); // 請(qǐng)求攔截器在每次發(fā)請(qǐng)求前自動(dòng)帶上 token request.interceptors.request.use(config { const token localStorage.getItem(token); if (token) { // 與后端 auth.js 里的約定一致Bearer token config.headers.Authorization Bearer ${token}; } return config; }); // 響應(yīng)攔截器統(tǒng)一處理后端返回 request.interceptors.response.use( response response.data, // 直接拿到后端 JSON 的 data 部分 error { if (error.response error.response.status 401) { // token 失效清掉本地登錄態(tài)跳登錄頁 localStorage.removeItem(token); router.push(/login); } return Promise.reject(error); } ); export default request;封裝完成之后每個(gè)接口文件就非常薄。以api/product.js為例import request from ./request; // 商品列表page、pageSize、category 都是可選參數(shù) export function getProductList(params) { return request.get(/product/list, { params }); } // 商品詳情 export function getProductDetail(id) { return request.get(/product/detail/${id}); }response response.data這一行作用是省去每個(gè)組件里都寫一層res.data.data的麻煩。封裝不好的項(xiàng)目里往往會(huì)出現(xiàn)res.data.data.data這種三層嵌套就是因?yàn)?axios 默認(rèn)返回的 response 對(duì)象包了一層{ status, headers, data }。這里直接剝到業(yè)務(wù)數(shù)據(jù)層。4.2 購物車邏輯未登錄存 localStorage登錄后走后端接口購物車的設(shè)計(jì)是這個(gè)項(xiàng)目里一個(gè)很有區(qū)分度的點(diǎn)。它的設(shè)計(jì)是未登錄時(shí)購物車數(shù)據(jù)存在前端localStorage用戶登錄后購物車數(shù)據(jù)存 MySQL 的cart表。為什么要這么做因?yàn)橛脩艨赡苓€沒登錄就開始逛加了幾件商品到購物車然后去登錄登錄完成后購物車?yán)锏纳唐凡荒軄G。這個(gè)「合并購物車」的邏輯一定是在登錄接口成功的回調(diào)里執(zhí)行的。偽代碼如下// views/Login.vue 登錄成功的回調(diào)節(jié)選 async function handleLoginSuccess(token, username) { localStorage.setItem(token, token); // 1. 取出 localStorage 里未登錄時(shí)存的本地購物車 const localCart JSON.parse(localStorage.getItem(cart) || []); // 2. 本地的商品逐條加入后端購物車 for (const item of localCart) { await addToCart({ productId: item.productId, quantity: item.quantity }); } // 3. 合并完成后清空本地購物車 localStorage.removeItem(cart); // 4. 跳轉(zhuǎn)首頁 router.push(/); }這個(gè)流程的先后順序不能亂。如果先清空localStorage再合并后端購物車刷新頁面后購物車數(shù)據(jù)就丟了。如果你在答辯時(shí)把這個(gè)「先合并、后清空」的順序主動(dòng)講出來老師會(huì)覺得你處理過真實(shí)場景的邊界問題。商品列表頁的加載邏輯相對(duì)簡單核心是在onMounted里調(diào)接口// views/Home.vue import { onMounted, ref } from vue; import { getProductList } from ../api/product; const list ref([]); const total ref(0); const page ref(1); const pageSize ref(8); async function loadData() { const res await getProductList({ page: page.value, pageSize: pageSize.value }); list.value res.list; total.value res.total; } onMounted(() { loadData(); });4.3 下單流程創(chuàng)建訂單主表、扣庫存、生成明細(xì)、清空購物車的順序提交訂單這一節(jié)值得多說兩句因?yàn)檫@里的坑非常典型。前端下單邏輯如果只調(diào)一個(gè)「createOrder」接口看起來簡單但擴(kuò)展性差如果拆成四步又要面對(duì)「中間某一步失敗怎么回滾」的問題。源碼的做法是后端用 MySQL 事務(wù)把四個(gè)步驟包起來前端只調(diào)一個(gè)接口。但為了理解業(yè)務(wù)語義這里把四步拆開說明// controllers/orderController.js簡化示意真實(shí)代碼用事務(wù)包裹 exports.createOrder (req, res) { const { userId, address, items } req.body; db.beginTransaction(err { if (err) return res.status(500).json({ message: 事務(wù)開啟失敗 }); // 第一步創(chuàng)建訂單主表拿到訂單 id db.query(INSERT INTO orders (user_id, address, total_amount, status) VALUES (?, ?, ?, 0), [userId, address, items.reduce((sum, i) sum i.price * i.quantity, 0)], (err, result) { if (err) return db.rollback(() res.status(500).json({ message: 創(chuàng)建訂單失敗 })); const orderId result.insertId; // 第二步逐條扣庫存扣減前必須先查庫存是否充足 const updateStockPromises items.map(item { return new Promise((resolve, reject) { db.query( UPDATE product SET stock stock - ? WHERE id ? AND stock ?, [item.quantity, item.productId, item.quantity], (err, updateResult) { // affectedRows 0 說明庫存不足UPDATE 條件不滿足 if (updateResult.affectedRows 0) { reject(new Error(商品 ${item.productId} 庫存不足)); } else { resolve(); } } ); }); }); Promise.all(updateStockPromises).then(() { // 第三步批量插入訂單明細(xì) const detailValues items.map(i [orderId, i.productId, i.quantity, i.price]); db.query(INSERT INTO order_items (order_id, product_id, quantity, price) VALUES ?, [detailValues], (err) { if (err) return db.rollback(() res.status(500).json({ message: 訂單明細(xì)寫入失敗 })); // 第四步清空用戶購物車 db.query(DELETE FROM cart WHERE user_id ?, [userId], (err) { if (err) return db.rollback(() res.status(500).json({ message: 清空購物車失敗 })); db.commit(err { if (err) return db.rollback(() res.status(500).json({ message: 事務(wù)提交失敗 })); res.json({ orderId, message: 訂單創(chuàng)建成功 }); }); }); }); }).catch(err { db.rollback(() res.status(500).json({ message: err.message })); }); }); }); };這段代碼的核心設(shè)計(jì)點(diǎn)是UPDATE product SET stock stock - ? WHERE id ? AND stock ?這條 SQL 自帶庫存檢查。如果在業(yè)務(wù)代碼里先查庫存再更新中間有并發(fā)請(qǐng)求插進(jìn)來就會(huì)超賣把檢查放進(jìn) UPDATE 的 WHERE 條件里就是所謂「原子操作」數(shù)據(jù)庫引擎保證同一時(shí)間只有一條 SQL 在執(zhí)行。這是電商項(xiàng)目里防超賣的標(biāo)準(zhǔn)做法也是答辯時(shí)最亮眼的一個(gè)技術(shù)點(diǎn)。另外一個(gè)細(xì)節(jié)事務(wù)里任何一個(gè)步驟出錯(cuò)前面所有已執(zhí)行的操作都要回滾否則會(huì)出現(xiàn)「訂單表有記錄但商品庫存沒減」的數(shù)據(jù)不一致。所以代碼里每個(gè)出錯(cuò)分支都要調(diào)用db.rollback()。這個(gè)「要么全部成功要么全部失敗」的思想在答辯時(shí)是絕對(duì)的高頻考點(diǎn)。5. 避坑與常見問題排查環(huán)境權(quán)限、MySQL 啟動(dòng)、跨域與亂碼5.1 npm 無法加載文件PowerShell 執(zhí)行策略限制的官方解法現(xiàn)象在 Windows PowerShell 里運(yùn)行npm start報(bào)錯(cuò)npm : 無法加載文件 C:\Program Files\nodejs\npm.ps1因?yàn)樵诖讼到y(tǒng)上禁止運(yùn)行腳本。原因Windows PowerShell 的默認(rèn)執(zhí)行策略是 Restricted禁止運(yùn)行任何 .ps1 腳本而 npm 在 PowerShell 里的包裝命令恰好是npm.ps1。不是 npm 安裝壞了是系統(tǒng)安全策略攔住了。解決以管理員身份打開 PowerShell執(zhí)行# RemoteSigned允許本地腳本運(yùn)行遠(yuǎn)程下載的腳本必須帶簽名 Set-ExecutionPolicy -ExecutionPolicy RemoteSigned輸出問詢時(shí)輸入Y確認(rèn)。改完后退出 PowerShell 重新打開再執(zhí)行npm -v能返回版本號(hào)就說明問題解決了。這里要提示一句不要為了省事設(shè)成Unrestricted它會(huì)允許所有腳本運(yùn)行有安全風(fēng)險(xiǎn)。5.2 MySQL 服務(wù)啟動(dòng)失敗net start mysql 報(bào)錯(cuò)或自動(dòng)停止現(xiàn)象net start mysql提示服務(wù)正在啟動(dòng)幾秒后報(bào)「服務(wù)無法啟動(dòng)」或者服務(wù)列表里顯示運(yùn)行中但端口沒監(jiān)聽。原因最常見的是免安裝版 MySQL 沒有初始化data目錄或者my.ini配置文件里的basedir和datadir路徑寫錯(cuò)。服務(wù)啟動(dòng)時(shí)找不到數(shù)據(jù)目錄直接退出。解決按照第 2.2 節(jié)提到的方法先刪除或確認(rèn)data目錄不存在然后執(zhí)行# 重新初始化數(shù)據(jù)目錄 mysqld --initialize --console初始化完成后確認(rèn)my.ini里datadir指向的是剛生成的 data 目錄路徑。路徑里如果有中文可能會(huì)出問題建議把 MySQL 放到純英文路徑下。還有一種情況是端口被占用——用netstat -ano | findstr 3306查看 3306 端口是否被其他進(jìn)程占據(jù)常見沖突是之前在電腦上裝過 MariaDB 或者另一個(gè) MySQL 服務(wù)。5.3 前端請(qǐng)求被 CORS 攔截Network 里能看到響應(yīng)但 axios 拿不到數(shù)據(jù)現(xiàn)象前端跑在http://localhost:8080后端跑在http://localhost:3000瀏覽器控制臺(tái)報(bào)CORS policy錯(cuò)誤Network 面板里看這次請(qǐng)求其實(shí)已經(jīng)發(fā)出去了響應(yīng)也回來了但 axios 的then里拿不到數(shù)據(jù)。原因跨域是瀏覽器的安全限制兩個(gè)地址「協(xié)議 域名 端口」三者有一個(gè)不同就是跨域。瀏覽器默認(rèn)不允許頁面讀取跨域響應(yīng)。解決在app.js里用了cors()中間件后響應(yīng)頭里會(huì)加上Access-Control-Allow-Origin: *瀏覽器就不會(huì)攔截了。這里的關(guān)鍵是注冊(cè)順序app.use(cors())必須在掛載路由之前。如果你的后端沒引入 cors 包可以手動(dòng)加響應(yīng)頭app.use((req, res, next) { res.setHeader(Access-Control-Allow-Origin, *); res.setHeader(Access-Control-Allow-Headers, Content-Type, Authorization); res.setHeader(Access-Control-Allow-Methods, GET, POST, PUT, DELETE); if (req.method OPTIONS) { return res.sendStatus(204); } next(); });OPTIONS請(qǐng)求是瀏覽器在正式請(qǐng)求之前發(fā)送的「預(yù)檢」請(qǐng)求后端必須正確處理否則正式請(qǐng)求根本不會(huì)發(fā)出。前端如果使用了Authorization頭Access-Control-Allow-Headers里必須包含Authorization否則登錄后的接口全部失效。5.4 數(shù)據(jù)庫中文亂碼顯示問號(hào)或顯示成不認(rèn)識(shí)的符號(hào)現(xiàn)象商品名稱、用戶昵稱在頁面和 MySQL Workbench 里都顯示為???或亂碼。原因字符集鏈路里任何一環(huán)斷了都會(huì)亂碼。建庫用了 latin1、連接參數(shù)沒指定 charset、或者 SQL 文件導(dǎo)入時(shí)被轉(zhuǎn)碼這三者都可能。真正的問題往往出在連接串上——就算庫和表都是 utf8mb4如果 Node.js 連接 MySQL 時(shí)沒有指定字符集驅(qū)動(dòng)默認(rèn)可能用 latin1 和你通信。解決檢查config/db.js里的連接配置const mysql require(mysql2); const connection mysql.createConnection({ host: localhost, port: 3306, user: root, password: 你的密碼, database: pet_shop, charset: utf8mb4 // 必須顯式指定 }); module.exports connection;同時(shí)確認(rèn)建庫語句里字符集是 utf8mb4。如果數(shù)據(jù)已經(jīng)在數(shù)據(jù)庫里顯示亂碼改了配置也沒用因?yàn)槟鞘且呀?jīng)存在的壞數(shù)據(jù)需要?jiǎng)h掉重插。所以我寫這篇筆記時(shí)強(qiáng)調(diào)第一步建庫就要把字符集固定后面的連接參數(shù)和創(chuàng)建表語句都統(tǒng)一用 utf8mb4亂碼問題根本不會(huì)出現(xiàn)。5.5 接口報(bào) 404 但路由看起來沒問題路徑拼寫和基礎(chǔ)前綴最容易出錯(cuò)現(xiàn)象前端調(diào)http://localhost:3000/api/user/login返回 404但代碼里app.use(/api/user, require(./routes/user))和router.post(/login)都寫得沒錯(cuò)。原因這類 404 幾乎都是路徑拼接問題——前端 baseURL 寫成了http://localhost:3000但后端路由掛了/api前綴最終請(qǐng)求拼成了http://localhost:3000/user/login。或者反過來baseURL 寫成了/api但后端沒有掛/api前綴。解決把 baseURL 和后端掛載路徑拼起來驗(yàn)證一遍前端baseURL: http://localhost:3000/api后端app.use(/api/user)router.post(/login)最終請(qǐng)求路徑是/api/user/login。另外檢查路由文件里有沒有寫錯(cuò)router.post(/login/)這種情況——Express 會(huì)忽略末尾斜杠但最好統(tǒng)一風(fēng)格。排查路徑問題時(shí)打開瀏覽器的 Network 面板看實(shí)際發(fā)出的 URL 是哪一個(gè)對(duì)照后端路由表逐段核對(duì)。6. 上線前驗(yàn)證一條完整業(yè)務(wù)鏈路走通以及一個(gè)值得試的進(jìn)階部署項(xiàng)目跑通的標(biāo)準(zhǔn)不是頁面打開沒報(bào)錯(cuò)而是「從注冊(cè)到下單」這條完整鏈路能走通。我建議你在自己電腦上嚴(yán)格執(zhí)行下面這份檢查清單每過一條畫一個(gè)勾全部通過再去考慮截圖和答辯材料。先用 Postman 或 Apifox 按順序測后端接口順序操作預(yù)期結(jié)果1POST/api/user/register提交用戶名和密碼user 表新增一條記錄密碼字段是一長串 bcrypt 哈希2POST/api/user/login提交相同密碼返回token字段登錄成功3GET/api/product/list不帶 token正常返回商品列表和 total4POST/api/order/create不帶 token返回 401提示未登錄5POST/api/order/create帶Authorization: Bearer token返回 orderIdproduct 表對(duì)應(yīng)商品庫存減少第 3 步和第 4 步是對(duì)照組用來驗(yàn)證「瀏覽商品不需要登錄、下單必須登錄」的權(quán)限設(shè)計(jì)。如果第 4 步?jīng)]有攔下來說明auth中間件沒掛到訂單路由上回去檢查routes/order.js里router.use(auth)的位置。再走前端驗(yàn)證流程注冊(cè)賬號(hào) → 登錄確認(rèn) token 寫入 localStorage→ 瀏覽商品 → 切換分類篩選 → 加入購物車 → 購物車頁改數(shù)量 → 提交訂單 → 在訂單列表頁看到剛下的單。這八步全部走通項(xiàng)目功能層面就算驗(yàn)收合格。如果你有多余時(shí)間我建議試一個(gè)進(jìn)階玩法把后端部署到一臺(tái)云服務(wù)器前端打包后丟到 Nginx 里用proxy_pass把/api路徑轉(zhuǎn)發(fā)到 3000 端口的 Node 服務(wù)。這一步如果做成了簡歷上「獨(dú)立完成項(xiàng)目部署」這一欄就能理直氣壯地打鉤。核心配置只有一段server { listen 80; server_name your-domain.com; # 前端靜態(tài)文件 root /var/www/pet-shop-web/dist; location / { try_files $uri $uri/ /index.html; } # 把 /api 開頭的請(qǐng)求轉(zhuǎn)發(fā)給 Node.js location /api { proxy_pass http://127.0.0.1:3000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } }這段配置解決了「前后端分離部署」的核心問題瀏覽器訪問 Nginx 拿到靜態(tài)頁面頁面里的請(qǐng)求指向同源的/api路徑Nginx 再轉(zhuǎn)發(fā)給 Node 服務(wù)。這樣前端和后端的地址統(tǒng)一了也順手解決了跨域問題。我自己每次拿到一份源碼包第一件事永遠(yuǎn)不是讀代碼而是先跑通。跑通之后再拆結(jié)構(gòu)拆完結(jié)構(gòu)再改一個(gè)功能點(diǎn)驗(yàn)證自己是否真的理解了。從那以后我每次接到項(xiàng)目都強(qiáng)制自己先「跑一遍完整鏈路再做任何修改」。因?yàn)槟阌肋h(yuǎn)不知道這個(gè)源碼包在你的電腦上會(huì)栽在哪個(gè)版本的坑里——PowerShell 執(zhí)行策略、MySQL 臨時(shí)密碼、CORS 預(yù)檢請(qǐng)求每個(gè)人翻車的位置都不一樣。希望這篇筆記能幫你在答辯前少走幾個(gè)彎路把時(shí)間花在真正值得講清楚的技術(shù)點(diǎn)上。本文還有配套的精品資源點(diǎn)擊獲取
返回列表
PREV
查看更多資訊
NEXT
返回資訊列表
色噜噜狠狠色综合无码久久欧美| 丁香九月婷婷| 天天精品视频在线观看视频| 91夫妻网站九色| 日逼影音先锋男人资源站| 人妻VideOssS人妻| 九九大香蕉黄色影院| 婷婷五月天激情电影小说| 大香蕉婷婷婷| 欧美大片| 丁香五月成人婷婷| 激情综合5月| 成人看片网站| 伊人色综在线| 五月天亚洲最大成人| 国产精品成人AV在线观看春天| 丁香六月婷婷高清| 99热主页日本| 伊人高清无码| aaa久久| 婷婷视频网| 午夜大香蕉| 99热在线成人网站| 99性视频| 色色五月激情| 色135综合网| 玖玖热视频| 99r这里只有精品哦| 久久99久久99精品,久国产,久久精品免费,99久在线,久久久久国产精品免费网站,9 | 婷婷五月天色综合| 伊人狠狠操| 亚洲99一级无嗎特制在线| 日本成人噜噜噜| 可以免费观看的av网址| 成人网站高清无码| 婷婷日本色| 成人综合AV| 天天做夜夜爽| 色五月偷偷| 激情五月天噢美| 91色五月在线观看| 久久激情四射| 色一色综合| xx久久| 97好吊操| 久久色情综合免费网站| 黄涩毛片| 色婷婷五月天激情久久| 激情综合色| 九月综合| 色射7856五月天激情四射| Blackedraw视频一区二区| 日本久久人| 小视频久久久aaa| 开心色播色五月婷婷| 婷婷色五月大香蕉在线观看| www.9色色色| 97操操| 天天狠天天叉| 久久小视频| 五月天天天天天天天天天天天婷婷婷| 日本色色色| 热的国产,热的综合,热的有码| 色婷婷先锋| 国产综合久久久777777| 91碰操| 五月激情婷婷四射| 人人综合色| 丁香六月综合激情| 五月婷无码| 五月婷av| 久久综合婷婷| 狠狠干五码| 色噜噜狠狠插综合| 欧美婷婷成人| 婷婷色色五月| 狠狠色噜噜狠狠狠888| 停婷丁五月在线| 特级片神马电影| 无码G高清天| 五月丁香色色网| 激情综合5| 五月色婷婷影视在线电影| 午夜 外网 精品 在线| 五月婷婷中文网| xx综合网| 天天干电影| 一起草AV| 99婷婷| 激情婷婷丁香五月| 婷婷五月天久久综合88| 日韩99色| 色五月涩涩婷婷| 淫视馆aV二区一区| 丁香五月激情啪啪| 91se在线观看| 色九月婷婷| 99热这里只有精品96| 六月天丁婷婷| 一本色道久久综合狠狠躁小说| 白人荫道BBWBBB大荫道| 丁香五月激情网| 婷婷五月天色丁香| www.色婷婷.com| 韩国激情五月天综合网| 日日夜夜干| 国产精品成av人在线视午夜片| 草草色情综合网| 99色嘟嘟精品网站| 日日天天天| 五月丁香五月丁香| 亚洲色频| 日本久久99| 涩涩激情五月婷婷| www.久久五月天.com| 狠狠穞A片一區二區三區| 能看的av| 操婷婷基地| 天天综合久久| 丁香五月婷婷色| 婷婷五月婷| 免费AV播放| www.丁香六月婷婷久久天堂影院.con| 99黄色性生活| 玖玖99免费视频| 91 影音先锋| 久热 91| 秋霞影音91人妻久久| 91干视频| 伊人高清无码| 欧美va视频不用播放器的va视频网| 丁香六月婷婷激情| 丁香六月天婷婷色| 久久久久久久97| 91中文在线| 亚洲图片 丁香婷婷| 97色色色| 玖玖婷婷色五月| 99久久综合狠狠综合久久| 婷婷久久久| 无码天天操| 97碰碰人人| 超碰在线成人| 99色日本| 五月天成人在线| 九九色色| 激情小说五月天| 玖玖午夜视频| 92国产福利| 婷婷丁香六月综合激情站| 五月激情婷婷在线| 男女啪啪做爰高潮无遮挡| 变态另类色图| 五月亚洲| 久99久视频精选| 五月天激情网址| 国产67194| 国产乱妇乱子在线播视频播放网站| 岛国资源站| 色婷婷国色天香综合| 天天看A片| 五月间天堂综合| 色女伊人| 少妇搡BBBB搡BBB搡毛茸茸 | 嘿嘿视频免费看9| 5月丁香综合网| 久久综合激情| 91人人爽狠狠狠| 激情五月天 婷婷| 99九九热播在线免费视频| 伊人狠狠综合| 99操视频| ji'qing'luan'ren'lun| 99只有精品9| 伊人五月人妻精品| 婷婷五月色播天| 五月天在线视频尤物视频在线看| 久久99人人| 99亚洲欧洲| 熟女人妻视频| 337午夜福利| 丁香六月婷婷综合| 97干婷婷五月天| 国产伦亲子伦亲子视频观看| 亚洲色五月| 色综合区| 精品成人在线观看| 五月开心网| 人妻激情视频| 婷婷色六月| 综合99视频| 99re热在线视频观看| 婷婷五月色综合香五月| 五月色婷婷综合| 在线成人网站| 亚洲激情网站无码| 婷婷六久久| 激情小说五月欧美亚洲丁香| 久久33视频| 色婷婷色99国产综合精品| 99热精品99| 99在线精品视频| 99久精品| 婷婷综合视频| 激情五月网站| 五月天综合在线网| 91婷婷丁香五月| 婷婷亚洲色| 精品人妻午夜一区二区三区四区| 色婷婷综合网| 婷婷成人综合免费视频| 日hao1区| 欧美电影在线播放| 国产欧洲欧洲精品久久| 婷婷五月天激情文学小说| 日本欧美成人片AAAA| 99精品网站| 97色吧| 性色视频| 亚洲中文无码成人| 色综合视频在线| 欧美成人网99网| 性爱网五月天| 99热每日| 美日韩成人| 丁香六月爱综合| 色色色色色九九九九九| 欧美25p| 色欲香综合网| av中文在线| 亚洲成人影视在线| 五月天婷婷操逼视频| 婷婷五月丁香综合亚洲 | 久久婷婷五月天| 五月综合视频| 亚洲精品永久久久久久| 丁香五月激情综合在线观看| 六月婷婷色色色| www.色婷婷| 色五开心五月五月深深爱| 久久3p| 日本人妻伦在线中文字幕| 一起草Av| 少妇AB又爽又紧无码网站| 97丁香五月| 久久精品五月天| 五月亭亭综合五码| 《诡秘之主》在线观看| 综合日本婷婷| 狠狠精品干练久久久无码中文字幕 | 色婷婷久久| 色色色色五月| 婷婷五月综合网| 综合久久丁香婷婷,五月婷婷六月丁香,开心激情综合网,六月丁香在线观看,婷婷丁 | 五月婷婷花| 26uuu丁香婷婷五月| www.色五月| 这里只有精品视频在线| 五月婷色啪| 激情综合五| 天天综合天综合久久网| 99久久网站| 综合成人小说婷婷| 天天日,天天插| 色婷婷五月天激情| 六月丁香婷婷综合狠狠爱夜夜爱| 久久综合图片| 免费在线观看AV网站| 狠狠色狠狠| 99,色| 久re在线| 好吊兆人妻| 久草热在线视频| 五月综合视频| 性爱视频99| 噜噜噜噜噜日本视频| 丁香综合网| 在线播放成人| 激情婷婷护士激情| 亚州在线中文字幕| 欧美精品在线观看| 中文字幕日产A片在线看| 在线婷婷| 色五狠狠| 五月激情婷婷女| 激情综合国产| 激情综合色婷婷啪啪六月天| 婷婷伊人綜合| 亚洲成人AV在线| 天堂无码人妻精品AV一区| www.黄色片-久久成人国产精品在线播放-999AV | 天天久久66xxx| 91综合在线视频| 亚洲成人av在线观看 | 五月丁香激情综合网官网| 91色久| 91久久久久久| 久久久久人妻| 婷婷色色网| 九九人人操| 九九亚洲视频| 99精品在线播放| 色五月五月婷婷| 久久亚洲婷婷| 欧美色婷婷| 久久婷婷视频| 成人做爰A片免费看网站找不到了| 激情久久久| 色情五月综合婷婷| 99热这里只有精品8| 91 九色 熟女| 欧美性生交XXXXX无码小说| 五月丁香成人网| 日本乱子人伦在线视频| 热热色色五月天婷婷| 青草青草视频2免费观看| 激情综合婷婷| 亚洲天堂制| 开心婷婷五月综合| 婷婷五月天午夜激情影院| 色婷婷色五月综合| 99热综合在线| 久久超级碰视频| 日本天堂爱爱| 亚洲激情淫网| 99九九精品视频| 亚洲第79页| 日本五月天激情| 色播播五月天| 性色做爰片在线观看WW| 日本色色影院| 99精品激情| 婷婷五月天伊人在线| 色五月之第四色| 婷婷五月天成人在线视频| 丁香五月六月久久综合| 综合色色婷婷| 超碰免费大香蕉| 五月丁香狠狠爱| 99热精品在线| 亚洲天堂青草| 亚洲精品网站色视频| 九九激情视频| 看黄的网站18禁| 色天天综合色| 99综合视频| 成人短视频在线| 婷婷丁香六月| 日本 色综合| 久久总和99| 深爱婷婷基地| 欧美色性色好| 丁香五月婷婷基地| 99黄色在线视频精品熟女| 99久热这里只有精品视频删减版| 99热99热99热99热| 久热久| 婷婷婷狠狠| 五月婷婷色影院| 99re这里只有精品视频6| 激情五月亚洲| 久久久久这里只有精品| 九九色情网五月天| 久草久青福利| 婷婷五月天AV| 爱婷婷都市激情| 伊人激情| 熟妇高潮一区av| 色婷婷综合网站| 婷婷丁香视频| 婷婷五月激情网| 婷婷五月丁香激情| 99久久66| 色色色色五月天| 67194线路二在线观看| 99碰网站| 五月婷婷免费看| 99久久网站| 色婷婷文字幕| 伊人狠狠狠综合| 五月婷婷啪啪啪| 99精品丁香五月| 91色婷婷综合久久中文字幕二区| 久久色这里只有精品| 五月天婷婷基地| 狠爱婷色| 99色视频免费在线规看| 91丨九色丨43老版熟女| 超级碰碰碰97免费| 婷婷色爱| 色婷婷很很丝袜| 六月丁香花婷婷| 婷婷五月情| 超碰成人公开| 婷婷一本和五月丁香| 深爱开心激情| 大香蕉啪啪| 九九精品热| 久久久国产精品黄毛片| 亚洲精品网站色视频| 婷婷性爱网| 色吊丝av中文字幕| 欧美美美女性色视频| 青青青在线视频国产| 五月婷婷啪啪网| 天天综合在线网| www.9色色色| 97婷婷丁香五月天激情图片| 99热色精品| www久久99| 99超级碰碰| 色吊丝av中文字幕| 色婷婷综合影院| 97操男人的天堂| 五月天另类小说久久小说网| 日日操夜夜擼| 久久婷婷一级片| 婷婷的五月天另类视频| www.五月天。com| 中文字幕人成乱码在线观看| 激情黄色五月天| 日日爽夜夜爽| 激情五月激情综合网一级丸片| 亚洲综合九九| 国产日批视频| 久久久天堂国产精品女人| 久久99热这里只有精品首| 久久9精品| 色播婷婷五月天| 琪琪色五月天| av在线资源| 丁香五月Av| 伊人久久婷婷| 国产精品激情AV久久久青桔| 久久AV电影| 成人丁香婷婷| 久久五月天激情| 91精品国产色猫| 激情六月婷婷| 五月丁香综合啪啪| 九九色影院| 99热这里只有精品21| 色区久久| www,99热| www.henhenl| 中文字幕不卡+婷婷五月| 色婷婷综合综合网| 激情AV| 五月婷成人网| 在线超碰免费| 日韩成人电影在线播放| 五月丁香六月婷婷亚洲天堂网站| 中文字幕网伦射乱中文| 97色女人在线| 婷婷五月综合色中文字幕| 五月丁香综合| 五月婷婷综合潮喷| 欧美日韩成人在线网站| 另类在线| se99视频| 丁香六月激| 国产乱妇乱子在线播视频播放网站| 五月天精品综合在线| 国产精品国产| 国产亚洲色婷婷久久99精品91| 五月五丁香婷婷| 五月色婷婷夜色| 亚洲AV日韩无码| 天天色五月| 五月综合激情图片| 亚洲这里只有精品| 五月天俺去也| 性爱人人网| 激情五月天丁香| 中国激情网| 色青五月天| 99热精品在这里| 91人妻视频| 久9无码视频| 欧美成人猛片AAAAAAA| 五月六月婷| 久久亚洲婷婷| 无码人妻一区二区一牛影视| 99热国产免费| 五月激情综合网| 色综合久久五月| 丁香av网| 色999;丁香五月| 五月天精品综合| 色婷婷丁香综合中文字幕| 99热精品在线| 色婷婷五月在线| 99在线看片| 五月婷婷精品视频| 91久久精品国产91性色TV| 精品网站:999WWW| 天天五月香欧美| 99玖玖视频| 天天天天操| 色婷婷亚洲五月天| 天天婷婷天天| 综合色99| 久久免费丁香| 色婷婷精品视频在线播放| 97人妻碰碰中文无码久热丝袜| 狠狠狠狠狠操| 亚洲成人色五月天| 99操碰| 超碰99热在线观看| 激情五月四色| 极品少妇XXXX精品少妇偷拍| 玖玖综合网| 开心五月婷婷在线视频免费观看| 婷婷五月天改成什么了| 97人凄人人操人人爽| 综合色、色综合| 狠狠干婷婷| 一区视频网站| 囯产精品久久欠久久久久久九大| 亚洲精品性色| 夜夜操少妇| 3p久久| 超碰丁香五月| 夜色.cnm| 91a片爽| 国产AV一区二区三区最新精品| 深爱五月激情| 97精品综合久久| 天天干天天干天天| 色欧洲| 五月天久久综合婷婷丁香| 色了色综合| 久久婷婷六月综合资源| 婷婷五月亚洲激情| 久久五月天婷婷视频| 97碰在线视频| 五月色色色| XX久久| 欧美日韩成人高清在线| 91色碰| 色五月婷婷影视| 色色色色色色色五月| 国产精品18久久久| 色色国产| 婷婷无五月无码视频| 色婷婷基地 | 五月丁香六月婷综合成人综合| 玖玖婷婷五月天| 爱久综合| www久久久| 在线不卡视频| 中文中文在线| 婷婷五月丁香五月基地| 色婷婷色综合| 新激情综合| www,com,五月色色| 九热...av| 亚洲激情网| 色婷婷手机在线| 五月婷婷深深的爱| 色五月天中文字幕| 五月丁香在线视频观看| 5月婷婷六月丁香| 亚洲久久婷婷| 中文av网站| 日本婷婷| 六月丁香五月天| 久久思思热| 国产毛片精品一区二区色欲黄A片 欧美交换配乱吟粗大25P | 六月婷婷综合| 欧美内射AA| 婷婷开心青青草| 艾小青av| 亚洲综合五月| 婷婷午夜| 亚洲AV日韩在线观看| 超碰妻人人| 在线视频激情网站| 婷婷香香五月| 亚洲激情97五月天| 日本精品99网站| 九九热在线视频观看| 亚洲无码99| 色婷婷狠狠禁久久| 五月婷婷偷拍| 激情婷婷人妻| 夜夜躁爽日| 人人爽天天爽| 亚洲综合色成丁香五月色| 99啪视频在线观看| 色播丁香| 五月天综合在线观看视频| 久久九九爽| 极品少妇XXXX精品少妇偷拍| 国产永久一黄| 婷婷的五月天另类视频| 六月色播| 婷婷五月天网| 伊人久久大香| 欧美色骚婷婷五月天 | 亚洲成人AV高清字幕| 91亚洲免费片| 日日操夜夜爽白洁| 色色色色网站| 婷婷丁香五月综合网| 婷婷色五月天色| 天天做天天爱天天爽夜夜揉| 玖玖资源站蜜臀| 五月丁香在线| 天天操五月天| 99精品视频在线| 91久久色| 丁香久久激情俄| 天天玩天天摸| 色香欲综合| 大学生高潮无套内谢视频| 97色97干| 久久久精品人妻录| 120分钟婬片免费看| 高清国产一级婬片a免费| 亚色网站小视频| 综合一区二区三区| 国产三级在线播放| 操逼123网| 五月综合视频| 毛片新网地| 婷婷五月天资源| 99久久综合| 碰97久久| 五月天婷婷在线观看| 五月婷婷综合网| 欧美精品999| 日日综合网| 亚洲熟妇AV乱码在线观看| 久久婷婷成人| 五月丁香六月婷婷久久肏| 国产AV影片| 亚洲五月丁香综合网| 五月丁香亭亭| 丁香花成人区| 婷婷久久草| 成人午夜视频精品一区| 超碰在线人人| 九九av| 玖玖在线| 免费看成人747474九号视频在线观看| 婷婷五月天首页激情| 极品五月天| 精品香蕉99久久久久网站| 国产xxxxx在线观看| 天天狠天天叉| 婷婷五月天激情网| 亚洲国产成人在线| 五月婷婷亚洲| 婷色五月| 婷婷色激情网| 色色色网站| 免费黄色片子| 深爱激情五月天| 色情综合| 97色碰| 都市激情久久| 操人无码| 日日操,日日爽| 九九精品热| 国产日批视频| 日日躁夜夜躁狠狠久久AV| 婷婷五月欧美综合| 超碰免费人人| 欧美亚洲操逼| 久久九九99视频| 色爱终和网| 色婷婷色五月综合| 久久婷婷六月综合综合| 六月丁香六月婷婷欧美| 亚洲成人一区| 婷婷六月丁香开心深深爱| 五月丁香啪啪网| 99视频久久免费视频| 操操操97| 色婷五月天激情| 69精品人妻不卡视频| 日本五月天网站| 武则天精品久久| 97人人干| 亚洲狠狠狠色婷婷综合激情久久久| 色久综合| ss视频xx91| 天天透天天干| 国产成人AV在线| 秋霞午夜理论| 五月婷婷 激情按摩| 情婷婷五月天| 亚洲欧美国产A片免费观看| 亚洲成人AV在线播放| 久九色| 风流少妇A片一区二区蜜桃| 99热中文字幕久久| 国产成人高清| 色色五月婷| 黄页大全十八禁| 日本在线观看91| 五月婷婷久久久| 久er7久热| 色色丁香五月天社区| 激情五月天色网站| 国产裸舞福利资源在线视频| 91九色最新视频| 狠狠草在线观看| 色婷婷久久综合| 亚洲妇女熟BBW| 五月天播播| 婷婷成人网五月天| 中文AV网站| 久/久精品99看9| 五月丁花色综合网| 五月久久婷婷天堂视频| 丁香婷婷色九月| 婷婷综合五月激情| 国内久久久精品99| 九九色热| 五月天天综合| 天天射综合网天天插| 精品亚洲国产成AV人片传媒 | 激情五月丁香五月色| 色婷婷丁香五月| 婷婷丁香午夜综合影视| 欧美人久久| 一级片操逼视频| 婷婷五月天综合久久| 丁香五月婷婷激情123| 九九色之九九色之88| 青青草国产亚洲精品久久| 99热亚洲| www.ppypp| 五月婷婷黄色| 日本99视频精品免费播放| 欧美性猛交99久久久久99按摩| 超碰97免费在线| 人妻操操色| 激情综合五月婷| 久久一级免费黄色片| 夜精品无码A片一区二区蜜桃| 色五月亚洲开心网| 久久er+| 26.uuu丁香五月婷婷| 色婷婷色综合久久精品V| 99热免| 中文成人在线| 97色色色视频| 中文久久久人妻| 亚洲成人高清在线| 天堂va久久久噜噜噜久久Va| 色婷婷丁香五月| 日本精品99| 九九99热久久精品66中文字幕| 国产精品国产VA片国产| 538午夜激情| 六月丁香婷婷大香蕉| 大香蕉久久综合网| 色综合色色| 91日本在线观看| www.色综合.com| 久久人妻www| 婷婷五月天亚洲图片| 天天综合.com| 九九热这里只有精品556| 国产精品美女| 丁香五月色五月| 无码动漫AV| 色欲AVV| 99天堂在线观看免费视频| 97色在线| 五月婷久久| 97人人操人人干| 日日夜夜婷婷| 久热大香蕉| 婷婷丁香18| 婷婷激情图片| www.五月.com| 婷婷五月天成人小说| 天天爽免费视频| 六月丁香婷婷六月激情综合| 日本va视频| 亚州性爱99| 99热99热| 夜夜做夜夜愛| 综合久久五月天| 婷婷色五月天在线| 丁香桃色网| 久久久久婷| 97色97干| 综合99综合久久久久久久| 婷婷五月丁香六月| 99热99在线| 草草视频91| 国产超碰在线| 亚洲亚洲人成综合网络| 日本强伦片中文字幕免费看| 色色色色色色综合网| 五月婷A V在线| 美女久久天堂| 毛v一区二区视频| 伊人久久大香天蕉亚洲特级| 国产性爱一级| 五月婷婷在线短视频| 欧美激情五月综合| 亚洲AV激情五月综合网| 视色综合| 五月激情六月综合| 99碰网站| av九九| 超碰成人公开| 欧在线一区| 超碰99久久| aaa丁香五月天| 久久婷婷五月天| RenRenSe在线视频网站| 五月停停丁香| 五月丁香啪啪伦理电影| 丁香五月色五月| 久热免费| 99热在线播放精品| www.五月天婷婷| 人妻操逼视频。| 五月婷婷精品视频| 丁香狠狠色婷婷久久无码视频| 成人在线99| 五月婷婷基地| 色狠狠色综合久久久绯色aⅴ影视| av操B网站| YJLZZJLZZ亚洲乱熟无码| 五月天婷综合网站| 99色免费视频| 五月天另类小说| 青草视频在线播放| 激情五月婷婷她| 婷丁五月| 丁香 婷婷 亚洲 熟女| 色综合久久88色综合天天| 国产在线中文字幕| 亚洲精品一区无码A片| 性爱网五月婷婷| 婷婷五月天Av| 五月婷丁香久久久| 思思99久久| 亚洲亚洲人成综合网络| Aα在线免费观看| 美女亚洲五月丁香| 婷婷五月天六点丁香五月| 婷婷五月综合久久中文字幕| 国产精品91抖高| 色在线99| 丁香五月网| 久久久久久欧美精品se一二三四| WWW嗯嗯啊啊啊啊| 婷婷丁香激情综合色情| 久久机热这里只有精品| 色综合色综合网| av首页在线| VA婷婷| 精品人妻一区二区三区四区不卡在| av九九| 国产精品人妻在线网址| 天天人人天天爽| 亚洲午夜av| 天啪天啪天啪天啪| 久久色五月天| 99九九综合久久九九| 伊人网色婷婷五月天| 婷婷五月丁香综合亚洲 | 五月色婷婷亚洲 | 97丁香视频| 99热 在线观看| 亚洲在线操| 日韩久操婷婷| 激情网狠狠干| 天天日综合| 思思热视频| 欧美丰满熟妇BBB久久久| 激情亚洲婷婷| 五月天婷婷人妻| 99热在线观看| 婷婷香香五月| 综合一区二区三区| 看逼中文字幕| 色射婷婷五月天| 99无码黄色视频| 天色综合网| 五月WWW| 国产在线aaa片一区二区99| 天天肏夜夜肏| 婷婷的色色五月天| 丁香六月青青草| 日韩久久这里只有精品| 日日干天天爽| 日本一级特黄大片AAAAA级| 婷婷丁香五月综合激情视频| 色婷婷激情五月天丁香| 婷婷的五月天另类视频| 天天干天干| 色色五月丁香| 丁香激情四射| www.婷婷,com| 丁香五月综合AV在线| 精品久久久久成人码免费动漫| 五月噜噜噜色综合| 久久免片| 99久久久99久久91熟女| 九九热精品| 色婷婷伊人| 五月婷婷欧美| 内射综合网| 六月久久婷婷| 婷婷99狠狠躁天天| 亚洲欧洲国产精品| 亚洲天堂爱爱| 婷婷精品在线| 综合色五月| 色婷婷影院| 91狠狠色| 天天爱天天做天天操| 精品久热| 亚洲男女激情| 99r这里只有精品哦| 五月天激情四射| 久久艹99| 亚洲激情另类| 综合丁香婷婷五月天| 超碰在线99| 婷婷久久午夜网| 狠狠干婷婷| 五月婷婷精品视频| 色色婷婷综合| 久久九九免费视频| 色婷婷五月成人网| 激情丁香五月| 丁香久久| 噜噜噜噜在线| 激情婷婷网| 久久99热免费最新版| 3p久久| 五月天激情图片| 26uuu.| 任你搞免费视频观看| 亚洲五月色| 国产AV不卡福利| 欧美婷婷综合| 五月婷婷熟女| 激情婷婷护士激情| 五月丁香成人小说| 久久免费操| 日本欧美成人片AAAA| 岛国av网| 大香蕉人在线65| 婷婷99狠狠躁天天躁中| 色五月激情网| 国产成人精品一区二区三区视频| 丁香五月天综合网| 情色婷婷五月天| 丁香六月综合激情| 色播五月婷婷综合| 五月综合激情图片| 超碰9| 五月婷婷黄色视频| 99婷婷色| 日韩啪啪视频| www.六月丁香看AV| www.99热在线| 蜜桃成语时李时珍 免费| 我要看激情五月天| 97碰碰视频在线观看免费| 99在线精品观看99| 天天夜夜操| www.99久久久| 丰满少妇乱A片无码| 五月婷婷影院| 狠狠色丁香综合| 97人人干视频| 激情久久五月天| 清色五月天| www.婷婷,com| 婷婷中文字幕| 99精品国产在热久久婷婷| 五月丁香美女| 丁香五月 性爱| 天天干,夜夜爽| 日日爽天天| 另类天堂| 婷五月天| 国产真实乱了老女人视频| 婷婷五月天色播| 噜综合| 99在线视频免费| 天天日夜夜| 五月丁香啪啪综合| 婷婷丁香五月欧美人| 玖玖在线视频| ady狠狠入| 婷婷五月天av| 亚洲欧洲国产精品| 婷婷丁香激情| 色激情综合狠狠婷婷| 五月开心啪啪| 婷婷伊人五月天| 久9视频| 色五月av伊人| 国产肥白大熟妇BBBB视频| 五月天狠狠| 热99只有精品| 丁香五月婷婷基地| 丁香五月综合久久| 欧洲MV日韩MV国产| 99福利导航| 888久久久| 日本色超碰| 狠狠干综合| 区美毛片子| 99久热这里只有精品| 婷婷区日本| 天堂婷婷综合| 婷婷五月五月丁香| 婷婷丁香五月天熟女丝袜| 日本久久婷| 丁香五月婷婷无码AV| 六月天丁婷婷| 国产欧美va| 东京热伊人| 99精品国产在热久久| 色婷婷综合久久| 日本色久| 五月色婷婷亚洲| 热热久久99| 色狠狠综合网| 色五月激情五月| CAOBIBI| 99re免费在线视频| 99视频精品视频| 99re视频精品| 思思热视频| 天天射天天插天天干| 大香蕉大香蕉在线影院| 婷婷丁香社区网| 色久五月天| 婷婷九月丁香| 99在线视频网址在线观看| 91超级碰在线| a在线观看| 色婷婷激情五月天在线观看| 九热精品| 97操资源婷婷| 黄色三级日本| 婷婷五月色综合| 操操天堂| 超碰69天堂| 99九九在线| 色综合色综合网| 91色久| av人人操| 中文精品久久久久人妻不| 九九精品热| 91啪啪视频| 国产看真人毛片爱做A片| 美女激情综合| 九九热这里只有国产精品| 120分钟婬片免费看| 新激情五月天| 久久视这里只有精品| 五月天婷婷爱| 精品夜夜澡人妻无码AV| 九九色院| 战争与艾拉电影免费观看| 五月天婷婷av| 任你搞在线观看视频| 五月丁香六月婷婷啪啪综合 | 狠狠五月婷婷| 俺也去在线久久精品23欧美综合视频网站,丰满人妻一区二区三区在线视频53,丰满 | 天天操夜夜啊| 国产成人亚洲综合A∨婷婷| 一本大道熟女人妻中文字幕在线| 亚洲一区二区无遮挡A片| 色色亚卅| 99亚洲视频| 六月色激情| 色婷婷色久综| 五月婷啪| 婷婷丁香黄色| 热99这里只是精品| 欧美五月婷婷| 五月天激情婷婷| 99热偷拍| 五月丁香六月婷婷操操操| 91久久日日| 天天操天天爱天天日| 91久久色| 狠狠爱丁香婷| 色五月婷婷DVD| jiZZdr| 亚洲乱码在线观看| 夜丁香综合| 激情五月四色| 色久在| 99热国产免费| 久久婷婷五月天激情四射| 五月天啪啪| 亚洲黄网AV| 五月情婷婷五月| 99热免费在线| 婷婷五月情| 丁婷婷五月天在线播放| 影音先锋五月天婷婷丁香在线观看| 九九热九九| 99热免费| 丁香六月啪| 91超碰在线观看| 婷婷九月丁香天堂丁香天堂| 欧美日韩AAAA| 欧美性生交xXxX久久久| 丁香五月成人论坛| 99爱视频免费| 亚洲综合在线视频| 狼人婷婷久久| 99热费观看| 天天狠天天叉| 狠干综合| 人人人va亚洲视频在线| 另类丁香五月天区图| 激情的五月| 免费无码毛片一区二区A片| 欧美色色色| 五月天开心激情综合网| 五月婷婷色色网址| 亚洲综合激情五月久久| 黃色三级三级三级三级 qixing300.shrkbk.com www.jinbozs.com tianmiaosw.com | 超碰人人操人人干| 九色七七| 91丨九色丨熟女丰满| 丁香五月97视频| 丁香五月a| 在线91日韩| 五月激情小说网| 超级碰碰碰91| 婷婷成人视频| 色噜噜五月天| 超碰93在线观看| 色五月激情| 五月色婷婷中文字幕| 青青草原亚洲天堂| 生活片五区| 97碰在线视频| AV人人操| 日本色婷婷久久99精品91| 99热精品在线观看| 天天色色婷婷| 婷婷丁香色五月天| 亚洲va欧洲va国产va不卡| YW无码| 七七色色综合| 亚洲欧洲一二| aaa久久| 色婷婷五月影视| 99操逼| 色丁香久久久| 国内9l视频自拍老熟女九色| 天天摸色吧天天摸色吧| 免费观看2018www黄色操逼网站| 久久精品系列| 99狠狠色| www狠狠| www.伊人天堂偷偷婷婷| 日本色啪| 五月天婷久精视频| 狼人狠狠操| 九月丁香| 99久久这里只有精品免费官网| 五月天操逼激情| 天天做天天摸| 五月婷婷色综图片| 色婷婷成人| 五月天综合区| 九 九九九AV| 人人九色| 天天操天天爱天天日| 亚洲午夜成人av电影网| 5月婷婷6月六月丁香| 国产精品视频免费看| 婷婷91| 亚洲精| 免费人人操| 欧美日韩成人在线| 色丁香久综合在线久综合在线观看| www.色欲丁香婷婷| 综合久久9| 噜一噜免费视频| 影音先锋男人站,影音先锋男人色资源网,影音先锋AV最新资源站,影音先锋AV资源 | 超碰色综合| 五月天婷婷六月激情网| 超碰在线观看三级片| 狠狠色噜噜色狠狠狠综合久久成人波| 97热久久| 色五月av| 婷婷五月天激情在线| 91在线人| 中文字幕永久免费| 99热这里只有精品50| 中文字幕第四色.999| 高清无码网址| 五月天激情无码高清| xxxx久| 丁香五月婷婷基地| 五月婷综合| 金桔一区二区ab地址| 在线看AV| 日日爽日日| 三级大香蕉网| 成人AV在线网站| 日韩AV免费电影在线播放| 超碰爱爱爱| 天天色五月| 中文字幕,综合,91| 韩国中文字幕91| 色老久久| 日韩久久这里只有精品| 99碰| 成人 在线观看国产| 日本激情91| 五月丁香婷婷激激激综合网色播| 色欲婷婷五月天| 久久婷婷丁香花综合网| 五月天久久久| 免费视频这里只有精品| 久久婷婷五月天激情新地址| 日本成人内射| 狠狠色综合网| 天堂网啪啪| 影音先锋 91工厂| 成人av播放| 国产毛片操B| 开心深爱激情网| 五月天婷婷婷| 五月丁香婷婷国产精品综合| 久久精品4| 久久成人亚洲欧美电影| 欧美激情五月天| 色色色99| 五月婷婷激情中心| 天天爱天天日| 91视频人人做97| 五月天婷婷无码| www.色综合| 在线看片av| 五月丁香婷婷五月| 狠狠做五月婷婷| 人人操99| 国精产品一区二区三区| 婷婷五月天VI| 欧美成人精品A片免费一区99| 亚洲丁香婷婷丁香五月天激情| 久久久精久人妻| 一起草av| 色色五月天网站| 91操屁股| 久久久久久久久月丁| 99视频内射三四| 最新色色五月天| 超碰在线中文字幕|