├── 项目代码 ├── server │ ├── public │ │ └── robots.txt │ ├── src │ │ ├── modules │ │ │ ├── signToken.js │ │ │ ├── email.js │ │ │ ├── getAllRouter.js │ │ │ └── auth.js │ │ ├── db │ │ │ └── index.js │ │ ├── routes │ │ │ ├── index.js │ │ │ ├── store │ │ │ │ ├── password.js │ │ │ │ ├── detail.js │ │ │ │ ├── update-state.js │ │ │ │ ├── auth │ │ │ │ │ ├── info.js │ │ │ │ │ └── sign.js │ │ │ │ ├── list.js │ │ │ │ ├── update.js │ │ │ │ └── create.js │ │ │ ├── commodity │ │ │ │ ├── update-state.js │ │ │ │ ├── detail.js │ │ │ │ ├── store-id.js │ │ │ │ ├── list.js │ │ │ │ ├── create.js │ │ │ │ ├── update.js │ │ │ │ ├── recommend.js │ │ │ │ └── search.js │ │ │ ├── user │ │ │ │ ├── user-info.js │ │ │ │ ├── data.js │ │ │ │ ├── sign.js │ │ │ │ ├── sign-up.js │ │ │ │ ├── update.js │ │ │ │ └── list.js │ │ │ ├── deliveryman │ │ │ │ ├── info.js │ │ │ │ ├── sign.js │ │ │ │ ├── update-state.js │ │ │ │ ├── update.js │ │ │ │ ├── detail.js │ │ │ │ ├── list.js │ │ │ │ ├── create.js │ │ │ │ ├── data.js │ │ │ │ └── update-me.js │ │ │ ├── banner │ │ │ │ ├── list.js │ │ │ │ ├── delete.js │ │ │ │ ├── update.js │ │ │ │ └── create.js │ │ │ ├── admin │ │ │ │ ├── user-info.js │ │ │ │ ├── update.js │ │ │ │ └── sign.js │ │ │ ├── collection │ │ │ │ ├── info.js │ │ │ │ ├── delete.js │ │ │ │ ├── create.js │ │ │ │ └── list.js │ │ │ ├── address │ │ │ │ ├── list.js │ │ │ │ ├── delete.js │ │ │ │ ├── detail.js │ │ │ │ ├── update.js │ │ │ │ └── create.js │ │ │ ├── order │ │ │ │ ├── finish.js │ │ │ │ ├── detail.js │ │ │ │ ├── task │ │ │ │ │ ├── order-deliveryman.js │ │ │ │ │ ├── list.js │ │ │ │ │ └── task.js │ │ │ │ ├── list-store.js │ │ │ │ ├── list.js │ │ │ │ └── create.js │ │ │ ├── delivery_record │ │ │ │ ├── delete.js │ │ │ │ ├── create.js │ │ │ │ └── list.js │ │ │ ├── notice │ │ │ │ ├── delete.js │ │ │ │ ├── create.js │ │ │ │ └── list.js │ │ │ ├── upload.js │ │ │ ├── cart │ │ │ │ ├── delete.js │ │ │ │ ├── list.js │ │ │ │ ├── create.js │ │ │ │ └── update.js │ │ │ ├── message │ │ │ │ ├── list.js │ │ │ │ ├── list-store.js │ │ │ │ ├── list-user.js │ │ │ │ └── create.js │ │ │ ├── comment │ │ │ │ ├── list.js │ │ │ │ ├── delete.js │ │ │ │ └── create.js │ │ │ ├── tools │ │ │ │ ├── location.js │ │ │ │ ├── data.js │ │ │ │ └── order-search.js │ │ │ └── notice-history │ │ │ │ └── create.js │ │ ├── utils │ │ │ └── id.js │ │ ├── index.js │ │ └── socket │ │ │ └── index.js │ └── package.json ├── 图片3.png ├── admin │ ├── src │ │ ├── style │ │ │ └── index.scss │ │ ├── assets │ │ │ ├── blue-v.png │ │ │ ├── empty.png │ │ │ ├── logo.jpg │ │ │ ├── user.png │ │ │ └── custom-empty-image.png │ │ ├── utils │ │ │ └── showImg.js │ │ ├── pages │ │ │ ├── store │ │ │ │ ├── index.vue │ │ │ │ ├── message │ │ │ │ │ ├── [id].vue │ │ │ │ │ └── index.vue │ │ │ │ ├── commodity │ │ │ │ │ ├── create.vue │ │ │ │ │ └── [id].vue │ │ │ │ └── sign.vue │ │ │ ├── index.vue │ │ │ ├── 404.vue │ │ │ ├── client │ │ │ │ ├── search │ │ │ │ │ └── index.vue │ │ │ │ ├── order │ │ │ │ │ └── success.vue │ │ │ │ ├── address │ │ │ │ │ ├── index.vue │ │ │ │ │ ├── create.vue │ │ │ │ │ └── [id].vue │ │ │ │ ├── user │ │ │ │ │ └── index.vue │ │ │ │ ├── message │ │ │ │ │ └── index.vue │ │ │ │ ├── index.vue │ │ │ │ ├── sign.vue │ │ │ │ ├── comment │ │ │ │ │ └── [id].vue │ │ │ │ ├── sign-up.vue │ │ │ │ ├── set │ │ │ │ │ └── index.vue │ │ │ │ └── store │ │ │ │ │ └── [id].vue │ │ │ ├── admin │ │ │ │ ├── store │ │ │ │ │ ├── create.vue │ │ │ │ │ ├── [id].vue │ │ │ │ │ └── list.vue │ │ │ │ ├── deliveryman │ │ │ │ │ ├── create.vue │ │ │ │ │ ├── [id].vue │ │ │ │ │ └── list.vue │ │ │ │ ├── password │ │ │ │ │ └── index.vue │ │ │ │ ├── index.vue │ │ │ │ ├── user │ │ │ │ │ └── index.vue │ │ │ │ ├── notice │ │ │ │ │ ├── create.vue │ │ │ │ │ └── index.vue │ │ │ │ ├── sign.vue │ │ │ │ └── banner │ │ │ │ │ └── index.vue │ │ │ └── deliveryman │ │ │ │ ├── sign.vue │ │ │ │ ├── user.vue │ │ │ │ ├── index copy.vue │ │ │ │ └── set.vue │ │ ├── store │ │ │ └── useUserData.js │ │ ├── App.vue │ │ ├── components │ │ │ ├── user │ │ │ │ ├── Navigate.vue │ │ │ │ └── List.vue │ │ │ ├── deliveryman │ │ │ │ └── Navigate.vue │ │ │ ├── VantUpload.vue │ │ │ ├── store │ │ │ │ ├── Navigate.vue │ │ │ │ └── ArticleEdit │ │ │ │ │ └── Edit.vue │ │ │ ├── Upload.vue │ │ │ ├── admin │ │ │ │ ├── StoreForm.vue │ │ │ │ ├── Navigate.vue │ │ │ │ ├── Deliveryman.vue │ │ │ │ └── BannerDialog │ │ │ │ │ └── index.vue │ │ │ └── MultipleUpload.vue │ │ ├── plugin │ │ │ └── axios.js │ │ ├── layouts │ │ │ ├── client-empty.vue │ │ │ ├── deliveryman.vue │ │ │ ├── client.vue │ │ │ ├── store.vue │ │ │ └── admin.vue │ │ ├── main.js │ │ └── hooks │ │ │ └── useFetch.js │ ├── postcss.config.cjs │ ├── tailwind.config.cjs │ ├── index.html │ ├── package.json │ └── vite.config.js ├── dev.bat ├── intall.bat └── start.bat ├── 任务书模板.doc ├── 开题报告.doc ├── 刘益维(手册).doc ├── 答辩PPT.pptx ├── .gitattributes ├── ~$维-22201011814-基于Node.js的“大维”体育商城的设计与实现(论文1).doc ├── .gitignore └── README.md /项目代码/server/public/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Disallow:/ -------------------------------------------------------------------------------- /任务书模板.doc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lrunlin/sport-mall/HEAD/任务书模板.doc -------------------------------------------------------------------------------- /开题报告.doc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lrunlin/sport-mall/HEAD/开题报告.doc -------------------------------------------------------------------------------- /刘益维(手册).doc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lrunlin/sport-mall/HEAD/刘益维(手册).doc -------------------------------------------------------------------------------- /答辩PPT.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lrunlin/sport-mall/HEAD/答辩PPT.pptx -------------------------------------------------------------------------------- /项目代码/图片3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lrunlin/sport-mall/HEAD/项目代码/图片3.png -------------------------------------------------------------------------------- /项目代码/admin/src/style/index.scss: -------------------------------------------------------------------------------- 1 | // @tailwind base; 2 | @tailwind utilities; 3 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /项目代码/dev.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | start cmd /k "cd server&&yarn dev" 3 | start cmd /k "cd admin&&yarn dev" 4 | -------------------------------------------------------------------------------- /项目代码/admin/postcss.config.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | tailwindcss: {}, 4 | }, 5 | }; 6 | -------------------------------------------------------------------------------- /项目代码/intall.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | start cmd /k "cd server&&yarn&& exit" 3 | start cmd /k "cd admin&&yarn&& exit" 4 | -------------------------------------------------------------------------------- /项目代码/admin/src/assets/blue-v.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lrunlin/sport-mall/HEAD/项目代码/admin/src/assets/blue-v.png -------------------------------------------------------------------------------- /项目代码/admin/src/assets/empty.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lrunlin/sport-mall/HEAD/项目代码/admin/src/assets/empty.png -------------------------------------------------------------------------------- /项目代码/admin/src/assets/logo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lrunlin/sport-mall/HEAD/项目代码/admin/src/assets/logo.jpg -------------------------------------------------------------------------------- /项目代码/admin/src/assets/user.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lrunlin/sport-mall/HEAD/项目代码/admin/src/assets/user.png -------------------------------------------------------------------------------- /项目代码/admin/src/utils/showImg.js: -------------------------------------------------------------------------------- 1 | import axios from "axios"; 2 | export default url => axios.defaults.baseURL + url; 3 | -------------------------------------------------------------------------------- /项目代码/admin/src/assets/custom-empty-image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lrunlin/sport-mall/HEAD/项目代码/admin/src/assets/custom-empty-image.png -------------------------------------------------------------------------------- /~$维-22201011814-基于Node.js的“大维”体育商城的设计与实现(论文1).doc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lrunlin/sport-mall/HEAD/~$维-22201011814-基于Node.js的“大维”体育商城的设计与实现(论文1).doc -------------------------------------------------------------------------------- /项目代码/start.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | start cmd /k "npm config set registry https://registry.npmmirror.com/&&npm i yarn vite nodemon -g&&yarn config set registry https://registry.npmmirror.com/" 3 | -------------------------------------------------------------------------------- /项目代码/server/src/modules/signToken.js: -------------------------------------------------------------------------------- 1 | let jwt = require("jsonwebtoken"); 2 | function sign(obj) { 3 | const token = jwt.sign(obj, "key", { expiresIn: "365d" }); 4 | return token; 5 | } 6 | module.exports = sign; 7 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | **/node_modules/**/* 2 | 3 | dist 4 | .next 5 | .idea 6 | .vscode 7 | .DS_Store 8 | *.local 9 | 论文.doc 10 | /**/public/**/*.avif 11 | /**/public/**/*.jpg 12 | /**/public/**/*.png 13 | /**/public/**/*.webp -------------------------------------------------------------------------------- /项目代码/admin/src/pages/store/index.vue: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | -------------------------------------------------------------------------------- /项目代码/admin/src/pages/store/message/[id].vue: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | -------------------------------------------------------------------------------- /项目代码/admin/src/pages/store/message/index.vue: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | -------------------------------------------------------------------------------- /项目代码/server/src/db/index.js: -------------------------------------------------------------------------------- 1 | const mysql = require("mysql2/promise"); 2 | const connection = mysql.createPool({ 3 | host: "localhost", 4 | user: "root", 5 | database: "shop_store", 6 | password: "123456", 7 | }); 8 | module.exports = connection; 9 | -------------------------------------------------------------------------------- /项目代码/admin/src/pages/index.vue: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | -------------------------------------------------------------------------------- /项目代码/server/src/routes/index.js: -------------------------------------------------------------------------------- 1 | let Router = require("koa-router"); 2 | let router = new Router(); 3 | 4 | router.get("/", async ctx => { 5 | ctx.body = ` 6 | 7 |

8 | Koa server 9 |

10 | `; 11 | }); 12 | module.exports = router; 13 | -------------------------------------------------------------------------------- /项目代码/admin/tailwind.config.cjs: -------------------------------------------------------------------------------- 1 | /** @type {import('tailwindcss').Config} */ 2 | module.exports = { 3 | corePlugins: { 4 | preflight: false 5 | }, 6 | content: ["./index.html", "./src/**/*.vue"], 7 | theme: { 8 | extend: { 9 | colors: { 10 | } 11 | } 12 | } 13 | }; 14 | -------------------------------------------------------------------------------- /项目代码/admin/src/store/useUserData.js: -------------------------------------------------------------------------------- 1 | import { defineStore } from "pinia"; 2 | import { ref } from "vue"; 3 | 4 | export const useUserData = defineStore("user-data", () => { 5 | const userData = ref(null); 6 | function set(val) { 7 | userData.value = val; 8 | } 9 | return { userData, set }; 10 | }); 11 | -------------------------------------------------------------------------------- /项目代码/admin/src/App.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 16 | -------------------------------------------------------------------------------- /项目代码/admin/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vite + Vue + TS 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /项目代码/admin/src/pages/404.vue: -------------------------------------------------------------------------------- 1 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /项目代码/server/src/routes/store/password.js: -------------------------------------------------------------------------------- 1 | const Router = require("koa-router"); 2 | const db = require("@/db"); 3 | const auth = require("@/modules/auth"); 4 | const router = new Router(); 5 | 6 | router.put("/store/password", auth(), async ctx => { 7 | const { password } = ctx.request.body; 8 | const [result] = await db.query(`UPDATE store SET password = ? WHERE id = ?`, [password, ctx.id]); 9 | 10 | ctx.body = { 11 | success: !!result?.affectedRows, 12 | }; 13 | }); 14 | 15 | module.exports = router; 16 | -------------------------------------------------------------------------------- /项目代码/admin/src/components/user/Navigate.vue: -------------------------------------------------------------------------------- 1 | 9 | 12 | 13 | -------------------------------------------------------------------------------- /项目代码/admin/src/components/deliveryman/Navigate.vue: -------------------------------------------------------------------------------- 1 | 8 | 12 | 13 | -------------------------------------------------------------------------------- /项目代码/server/src/routes/store/detail.js: -------------------------------------------------------------------------------- 1 | const Router = require("koa-router"); 2 | const db = require("@/db"); 3 | const router = new Router(); 4 | 5 | router.get("/store/:id", async ctx => { 6 | const [result] = await db.query( 7 | `SELECT 8 | id, 9 | email, 10 | cover, 11 | name, 12 | create_time, 13 | state 14 | FROM 15 | store where id=${ctx.params.id||''}; 16 | ` 17 | ); 18 | 19 | ctx.body = { 20 | success: !!result.length, 21 | data: result[0], 22 | }; 23 | }); 24 | 25 | module.exports = router; 26 | -------------------------------------------------------------------------------- /项目代码/server/src/routes/store/update-state.js: -------------------------------------------------------------------------------- 1 | const Router = require("koa-router"); 2 | const db = require("@/db"); 3 | const auth = require("@/modules/auth"); 4 | const router = new Router(); 5 | 6 | router.put("/store/state/:id", auth(), async ctx => { 7 | const id = ctx.params.id; 8 | const { state } = ctx.request.body; 9 | const [result] = await db.query(`UPDATE store SET state = ? WHERE id = ?`, [state, id]); 10 | 11 | ctx.body = { 12 | success: !!result?.affectedRows, 13 | }; 14 | }); 15 | 16 | module.exports = router; 17 | -------------------------------------------------------------------------------- /项目代码/server/src/routes/commodity/update-state.js: -------------------------------------------------------------------------------- 1 | const Router = require("koa-router"); 2 | const db = require("@/db"); 3 | const auth = require("@/modules/auth"); 4 | const router = new Router(); 5 | 6 | router.put("/commodity/state/:id", auth(), async ctx => { 7 | const id = ctx.params.id; 8 | const { state } = ctx.request.body; 9 | const [result] = await db.query(`UPDATE commodity SET state = ? WHERE id = ?`, [state, id]); 10 | 11 | ctx.body = { 12 | success: !!result?.affectedRows, 13 | }; 14 | }); 15 | 16 | module.exports = router; 17 | -------------------------------------------------------------------------------- /项目代码/server/src/routes/user/user-info.js: -------------------------------------------------------------------------------- 1 | let Router = require("koa-router"); 2 | let db = require("@/db"); 3 | let auth = require("@/modules/auth"); 4 | let router = new Router(); 5 | 6 | router.get("/user/info", auth(), async ctx => { 7 | try { 8 | let [res] = await db.query(`select * from user where id=?`, [ctx.id]); 9 | ctx.body = { 10 | success: !!res.length, 11 | data: { id: res[0]?.id, name: res[0]?.name, avatar: res[0]?.avatar }, 12 | }; 13 | } catch (error) { 14 | ctx.body = { success: false }; 15 | } 16 | }); 17 | module.exports = router; 18 | -------------------------------------------------------------------------------- /项目代码/server/src/routes/user/data.js: -------------------------------------------------------------------------------- 1 | let Router = require("koa-router"); 2 | let db = require("@/db"); 3 | let auth = require("@/modules/auth"); 4 | let router = new Router(); 5 | 6 | router.get("/user", auth(), async ctx => { 7 | try { 8 | let [res] = await db.query(`select * from user where id=?`, [ctx.id]); 9 | if (res[0]) { 10 | delete res[0].password; 11 | } 12 | ctx.body = { 13 | success: !!res.length, 14 | data: res[0], 15 | }; 16 | } catch (error) { 17 | ctx.body = { success: false }; 18 | } 19 | }); 20 | module.exports = router; 21 | -------------------------------------------------------------------------------- /项目代码/server/src/routes/store/auth/info.js: -------------------------------------------------------------------------------- 1 | let Router = require("koa-router"); 2 | let db = require("@/db"); 3 | let auth = require("@/modules/auth"); 4 | let router = new Router(); 5 | 6 | router.get("/store/info", auth(), async ctx => { 7 | try { 8 | let [res] = await db.query(`select * from store where id=?`, [ctx.id]); 9 | ctx.body = { 10 | success: !!res.length, 11 | data: { id: res[0]?.id, username: res[0]?.username, state: res[0]?.state }, 12 | }; 13 | } catch (error) { 14 | ctx.body = { success: false }; 15 | } 16 | }); 17 | module.exports = router; 18 | -------------------------------------------------------------------------------- /项目代码/server/src/routes/deliveryman/info.js: -------------------------------------------------------------------------------- 1 | let Router = require("koa-router"); 2 | let db = require("@/db"); 3 | let auth = require("@/modules/auth"); 4 | let router = new Router(); 5 | 6 | router.get("/deliveryman-info", auth(), async ctx => { 7 | try { 8 | let [res] = await db.query(`select * from deliveryman where id=?`, [ctx.id]); 9 | ctx.body = { 10 | success: !!res.length, 11 | data: { id: res[0]?.id, name: res[0]?.name, avatar: res[0]?.avatar }, 12 | }; 13 | } catch (error) { 14 | ctx.body = { success: false }; 15 | } 16 | }); 17 | module.exports = router; 18 | -------------------------------------------------------------------------------- /项目代码/server/src/routes/banner/list.js: -------------------------------------------------------------------------------- 1 | const Router = require("koa-router"); 2 | const db = require("@/db"); 3 | const router = new Router(); 4 | 5 | router.get("/banner", async ctx => { 6 | try { 7 | const [result] = await db.query(`select * from banner;`); 8 | 9 | ctx.body = { 10 | success: true, 11 | message: "查询Banner列表", 12 | data: result, 13 | }; 14 | } catch (error) { 15 | console.log(error); 16 | ctx.body = { 17 | success: false, 18 | error: error.message, 19 | message: "查询失败", 20 | }; 21 | } 22 | }); 23 | 24 | module.exports = router; 25 | -------------------------------------------------------------------------------- /项目代码/server/src/routes/admin/user-info.js: -------------------------------------------------------------------------------- 1 | let Router = require("koa-router"); 2 | const sign = require("@/modules/signToken"); 3 | let db = require("@/db"); 4 | let auth = require("@/modules/auth"); 5 | let router = new Router(); 6 | 7 | router.get("/admin/info", auth(), async ctx => { 8 | try { 9 | let [res] = await db.query(`select * from admin where id=?`, [ctx.id]); 10 | ctx.body = { 11 | success: !!res.length, 12 | data: { id: res[0]?.id, username: res[0]?.username }, 13 | }; 14 | } catch (error) { 15 | ctx.body = { success: false }; 16 | } 17 | }); 18 | module.exports = router; 19 | -------------------------------------------------------------------------------- /项目代码/server/src/routes/commodity/detail.js: -------------------------------------------------------------------------------- 1 | const Router = require("koa-router"); 2 | const db = require("@/db"); 3 | const router = new Router(); 4 | 5 | router.get("/commodity/:id", async ctx => { 6 | const [result] = await db.query(`select * from commodity where id=?;`, [ctx.params.id]); 7 | if (result.length) { 8 | const [store] = await db.query(`select * from store where id=?;`, [result[0].store_id]); 9 | delete store[0].password; 10 | result[0].store_data = store[0]; 11 | } 12 | 13 | ctx.body = { 14 | success: result.length, 15 | data: result[0], 16 | }; 17 | }); 18 | 19 | module.exports = router; 20 | -------------------------------------------------------------------------------- /项目代码/admin/src/pages/client/search/index.vue: -------------------------------------------------------------------------------- 1 | 5 | 17 | 18 | -------------------------------------------------------------------------------- /项目代码/server/src/routes/banner/delete.js: -------------------------------------------------------------------------------- 1 | const Router = require("koa-router"); 2 | const db = require("@/db"); 3 | const router = new Router(); 4 | 5 | router.delete("/banner/:id", async ctx => { 6 | try { 7 | const bannerId = ctx.params.id; 8 | 9 | const [result] = await db.query(`DELETE FROM banner WHERE id = ?`, [bannerId]); 10 | 11 | ctx.body = { 12 | success: !!result?.affectedRows, 13 | message: "删除成功", 14 | }; 15 | } catch (error) { 16 | console.log(error); 17 | ctx.body = { 18 | success: false, 19 | error: error.message, 20 | message: "删除失败", 21 | }; 22 | } 23 | }); 24 | 25 | module.exports = router; 26 | -------------------------------------------------------------------------------- /项目代码/admin/src/plugin/axios.js: -------------------------------------------------------------------------------- 1 | import axios from "axios"; 2 | import cookie from "js-cookie"; 3 | 4 | axios.defaults.baseURL = "http://localhost:3000/"; 5 | 6 | function tokenKey() { 7 | let hash = window.location.hash.split("/")[1]; 8 | let keys = ["admin", "client", "deliveryman", "store"]; 9 | let token = keys.find(item => item == hash); 10 | 11 | return token + "_token"; 12 | } 13 | axios.interceptors.request.use( 14 | function (config) { 15 | // 在发送请求之前做些什么 16 | config.headers.authorization = cookie.get(tokenKey()); 17 | return config; 18 | }, 19 | function (error) { 20 | // 对请求错误做些什么 21 | return Promise.reject(error); 22 | } 23 | ); 24 | -------------------------------------------------------------------------------- /项目代码/server/src/routes/store/list.js: -------------------------------------------------------------------------------- 1 | const Router = require("koa-router"); 2 | const db = require("@/db"); 3 | const router = new Router(); 4 | 5 | router.get("/store", async ctx => { 6 | const [result] = await db.query( 7 | ctx.query.state 8 | ? `SELECT 9 | id, 10 | email, 11 | cover, 12 | name, 13 | create_time, 14 | state 15 | FROM 16 | store where state=${ctx.query.state}; 17 | ` 18 | : `SELECT 19 | id, 20 | email, 21 | cover, 22 | name, 23 | create_time, 24 | state 25 | FROM 26 | store; 27 | ` 28 | ); 29 | 30 | ctx.body = { 31 | success: true, 32 | data: result, 33 | }; 34 | }); 35 | 36 | module.exports = router; 37 | -------------------------------------------------------------------------------- /项目代码/server/src/utils/id.js: -------------------------------------------------------------------------------- 1 | function random(min, max) { 2 | return Math.floor(Math.random() * (max - min + 1)) + min; 3 | } 4 | 5 | const WorkerID = Math.min( 6 | process.env.NODE_APP_INSTANCE ? +process.env.NODE_APP_INSTANCE : random(0, 9), 7 | 9 8 | ); 9 | 10 | const BaseTime = +new Date("2023-12-27"); 11 | 12 | let lastTimeTick; 13 | 14 | let lastRandomNumberTick = random(1, 3); 15 | 16 | function id() { 17 | let timestamp = +new Date() - BaseTime; 18 | lastRandomNumberTick = timestamp == lastTimeTick ? ++lastRandomNumberTick : random(0, 3); 19 | lastTimeTick = timestamp; 20 | 21 | return +`${timestamp}${WorkerID}${lastRandomNumberTick}`; 22 | } 23 | 24 | 25 | module.exports = id; 26 | 27 | -------------------------------------------------------------------------------- /项目代码/server/src/routes/commodity/store-id.js: -------------------------------------------------------------------------------- 1 | const Router = require("koa-router"); 2 | const db = require("@/db"); 3 | const auth = require("@/modules/auth"); 4 | const router = new Router(); 5 | 6 | router.get("/commodity/store/:id", auth(), async ctx => { 7 | try { 8 | let query = `SELECT * FROM commodity WHERE store=${ctx.params.id}`; 9 | 10 | // 执行数据库查询 11 | const [result] = await db.query(query); 12 | 13 | ctx.body = { 14 | success: true, 15 | data: result, 16 | message: "查询成功", 17 | }; 18 | } catch (error) { 19 | console.log(error); 20 | ctx.body = { 21 | success: false, 22 | error: error.message, 23 | message: "查询失败", 24 | }; 25 | } 26 | }); 27 | 28 | module.exports = router; 29 | -------------------------------------------------------------------------------- /项目代码/server/src/routes/user/sign.js: -------------------------------------------------------------------------------- 1 | let Router = require("koa-router"); 2 | const sign = require("@/modules/signToken"); 3 | let db = require("@/db"); 4 | let router = new Router(); 5 | 6 | router.post("/user/sign", async ctx => { 7 | try { 8 | let [res] = await db.query(`select * from user where email=? and password=?`, [ 9 | ctx.request.body.email, 10 | ctx.request.body.password, 11 | ]); 12 | 13 | ctx.body = { 14 | success: !!res.length, 15 | data: { id: res[0]?.id, name: res[0]?.name, avatar: res[0]?.avatar }, 16 | token: sign({ id: res[0]?.id, username: res[0]?.name, type: "user" }), 17 | }; 18 | } catch (error) { 19 | ctx.body = { success: false }; 20 | } 21 | }); 22 | module.exports = router; 23 | -------------------------------------------------------------------------------- /项目代码/server/src/routes/admin/update.js: -------------------------------------------------------------------------------- 1 | const Router = require("koa-router"); 2 | const db = require("@/db"); // 你的数据库模块 3 | const auth = require("@/modules/auth"); // 你的权限验证模块 4 | 5 | const router = new Router(); 6 | 7 | router.put("/admin/password", auth(), async ctx => { 8 | try { 9 | const { id } = ctx; 10 | const { password } = ctx.request.body; 11 | 12 | await db.query("UPDATE admin SET password = ? WHERE id = ?", [password, id]); 13 | 14 | ctx.body = { 15 | success: true, 16 | message: "密码修改成功", 17 | }; 18 | } catch (error) { 19 | console.error(error); 20 | ctx.body = { 21 | success: false, 22 | message: "密码修改失败", 23 | error: error.message, 24 | }; 25 | } 26 | }); 27 | 28 | module.exports = router; 29 | -------------------------------------------------------------------------------- /项目代码/server/src/routes/collection/info.js: -------------------------------------------------------------------------------- 1 | const Router = require("koa-router"); 2 | const db = require("@/db"); 3 | const auth = require("@/modules/auth"); 4 | const router = new Router(); 5 | 6 | router.get("/collection/:id", auth(), async ctx => { 7 | try { 8 | // 查询是否收藏 9 | const result = await db.query( 10 | "SELECT COUNT(*) AS count FROM collection WHERE user_id = ? AND item_id = ?", 11 | [ctx.id, ctx.params.id] 12 | ); 13 | 14 | ctx.body = { 15 | success: true, 16 | data: result[0][0]?.count > 0, 17 | }; 18 | } catch (error) { 19 | console.error(error); 20 | ctx.body = { 21 | success: false, 22 | message: "查询收藏状态失败", 23 | error: error.message, 24 | }; 25 | } 26 | }); 27 | 28 | module.exports = router; 29 | -------------------------------------------------------------------------------- /项目代码/server/src/routes/admin/sign.js: -------------------------------------------------------------------------------- 1 | let Router = require("koa-router"); 2 | const sign = require("@/modules/signToken"); 3 | let db = require("@/db"); 4 | let auth = require("@/modules/auth"); 5 | let router = new Router(); 6 | 7 | router.post("/admin/sign", async ctx => { 8 | try { 9 | let [res] = await db.query(`select * from admin where username=? and password=?`, [ 10 | ctx.request.body.username, 11 | ctx.request.body.password, 12 | ]); 13 | ctx.body = { 14 | success: !!res.length, 15 | data: { id: res[0]?.id, username: res[0]?.username }, 16 | token: sign({ id: res[0]?.id, username: res[0]?.username, type: "admin" }), 17 | }; 18 | } catch (error) { 19 | ctx.body = { success: false }; 20 | } 21 | }); 22 | module.exports = router; 23 | -------------------------------------------------------------------------------- /项目代码/server/src/routes/banner/update.js: -------------------------------------------------------------------------------- 1 | const Router = require("koa-router"); 2 | const db = require("@/db"); 3 | const router = new Router(); 4 | 5 | router.put("/banner/:id", async ctx => { 6 | try { 7 | const bannerId = ctx.params.id; 8 | const { url, cover } = ctx.request.body; 9 | 10 | const [result] = await db.query(`UPDATE banner SET url = ?, cover = ? WHERE id = ?`, [ 11 | url, 12 | cover, 13 | bannerId, 14 | ]); 15 | 16 | ctx.body = { 17 | success: !!result?.affectedRows, 18 | message: "修改成功", 19 | }; 20 | } catch (error) { 21 | console.log(error); 22 | ctx.body = { 23 | success: false, 24 | error: error.message, 25 | message: "修改失败", 26 | }; 27 | } 28 | }); 29 | 30 | module.exports = router; 31 | -------------------------------------------------------------------------------- /项目代码/server/src/routes/deliveryman/sign.js: -------------------------------------------------------------------------------- 1 | let Router = require("koa-router"); 2 | const sign = require("@/modules/signToken"); 3 | let db = require("@/db"); 4 | let router = new Router(); 5 | 6 | router.post("/deliveryman/sign", async ctx => { 7 | try { 8 | let [res] = await db.query( 9 | `select * from deliveryman where phone=? and password=? and state=1`, 10 | [ctx.request.body.phone, ctx.request.body.password] 11 | ); 12 | 13 | ctx.body = { 14 | success: !!res.length, 15 | data: { id: res[0]?.id, name: res[0]?.name, avatar: res[0]?.avatar }, 16 | token: sign({ id: res[0]?.id, name: res[0]?.name, type: "deliveryman" }), 17 | }; 18 | } catch (error) { 19 | ctx.body = { success: false }; 20 | } 21 | }); 22 | module.exports = router; 23 | -------------------------------------------------------------------------------- /项目代码/server/src/routes/store/update.js: -------------------------------------------------------------------------------- 1 | const Router = require("koa-router"); 2 | const db = require("@/db"); 3 | const auth = require("@/modules/auth"); 4 | const router = new Router(); 5 | 6 | router.put("/store/:id", auth(), async ctx => { 7 | try { 8 | const id = ctx.params.id; 9 | const { email, cover, name, address } = ctx.request.body; 10 | 11 | const result = await db.query(`UPDATE store SET email = ?, cover = ?, name = ? WHERE id = ?`, [ 12 | email, 13 | cover, 14 | name, 15 | id, 16 | ]); 17 | 18 | ctx.body = { 19 | success: !!result[0]?.affectedRows, 20 | }; 21 | } catch (error) { 22 | console.log(error); 23 | ctx.body = { success: false, error: error.message }; 24 | } 25 | }); 26 | 27 | module.exports = router; 28 | -------------------------------------------------------------------------------- /项目代码/admin/src/layouts/client-empty.vue: -------------------------------------------------------------------------------- 1 | 4 | 34 | -------------------------------------------------------------------------------- /项目代码/server/src/modules/email.js: -------------------------------------------------------------------------------- 1 | const nodemailer = require("nodemailer"); 2 | 3 | const transporter = nodemailer.createTransport({ 4 | service: "qq", 5 | port: 587, 6 | secure: false, 7 | auth: { 8 | user: `1974109227@qq.com `, 9 | pass: `xogjwbswikrwfddf`, 10 | }, 11 | }); 12 | 13 | function sendEmail(params) { 14 | return new Promise((resolve, reject) => { 15 | const mailOptions = { 16 | from: `1974109227@qq.com `, 17 | to: params.target, 18 | subject: params.subject, 19 | html: params.content, 20 | }; 21 | transporter.sendMail(mailOptions, (error, info) => { 22 | if (error) { 23 | reject(error); 24 | } else { 25 | resolve(); 26 | } 27 | }); 28 | }); 29 | } 30 | 31 | module.exports = sendEmail; 32 | -------------------------------------------------------------------------------- /项目代码/server/src/routes/store/create.js: -------------------------------------------------------------------------------- 1 | const Router = require("koa-router"); 2 | const db = require("@/db"); 3 | const auth = require("@/modules/auth"); 4 | const id = require("@/utils/id"); 5 | const router = new Router(); 6 | 7 | router.post("/store", auth(), async ctx => { 8 | try { 9 | const { email, cover, name } = ctx.request.body; 10 | 11 | const result = await db.query( 12 | `INSERT INTO store (id,email,cover, name, create_time,password) VALUES (?, ?, ?, ?, NOW(),?)`, 13 | [id(), email, cover, name, email] 14 | ); 15 | 16 | ctx.body = { 17 | success: !!result[0]?.affectedRows, 18 | }; 19 | } catch (error) { 20 | console.log(error); 21 | ctx.body = { success: false, error: error.message }; 22 | } 23 | }); 24 | 25 | module.exports = router; 26 | -------------------------------------------------------------------------------- /项目代码/admin/src/layouts/deliveryman.vue: -------------------------------------------------------------------------------- 1 | 4 | 34 | -------------------------------------------------------------------------------- /项目代码/server/src/routes/deliveryman/update-state.js: -------------------------------------------------------------------------------- 1 | const Router = require("koa-router"); 2 | const db = require("@/db"); 3 | const auth = require("@/modules/auth"); 4 | const router = new Router(); 5 | 6 | router.put("/deliveryman/state/:id", auth(), async ctx => { 7 | try { 8 | const { id } = ctx.params; 9 | const { state } = ctx.request.body; 10 | 11 | // 更新配送员状态 12 | const result = await db.query("UPDATE deliveryman SET state = ? WHERE id = ?", [state, id]); 13 | 14 | ctx.body = { 15 | success: true, 16 | message: "配送员状态更新成功", 17 | }; 18 | } catch (error) { 19 | console.error(error); 20 | ctx.body = { 21 | success: false, 22 | message: "配送员状态更新失败", 23 | error: error.message, 24 | }; 25 | } 26 | }); 27 | 28 | module.exports = router; 29 | -------------------------------------------------------------------------------- /项目代码/admin/src/pages/store/commodity/create.vue: -------------------------------------------------------------------------------- 1 | 6 | 26 | 27 | -------------------------------------------------------------------------------- /项目代码/server/src/routes/address/list.js: -------------------------------------------------------------------------------- 1 | const Router = require("koa-router"); 2 | const db = require("@/db"); 3 | const auth = require("@/modules/auth"); 4 | const router = new Router(); 5 | 6 | // 查询用户地址接口 7 | router.get("/address", auth(), async ctx => { 8 | try { 9 | // 使用用户ID查询地址信息 10 | const [result] = await db.query(` 11 | SELECT * FROM address WHERE user_id = ${ctx.id} and state=1 order by isDefault desc; 12 | `); 13 | 14 | ctx.body = { 15 | success: true, 16 | data: result.map(item => ({ ...item, isDefault: !!item.isDefault })), 17 | }; 18 | } catch (error) { 19 | console.error(error); 20 | ctx.body = { 21 | success: false, 22 | message: "查询用户地址失败", 23 | error: error.message, 24 | }; 25 | } 26 | }); 27 | 28 | module.exports = router; 29 | -------------------------------------------------------------------------------- /项目代码/server/src/routes/collection/delete.js: -------------------------------------------------------------------------------- 1 | const Router = require("koa-router"); 2 | const db = require("@/db"); 3 | const auth = require("@/modules/auth"); 4 | const router = new Router(); 5 | 6 | router.delete("/collection/:id", auth(), async ctx => { 7 | try { 8 | // 删除收藏记录 9 | const result = await db.query("DELETE FROM collection WHERE user_id = ? AND item_id = ?", [ 10 | ctx.id, 11 | ctx.params.id, 12 | ]); 13 | 14 | ctx.body = { 15 | success: !!result[0]?.affectedRows, 16 | message: !!result[0]?.affectedRows ? "取消成功" : "取消错误", 17 | }; 18 | } catch (error) { 19 | console.error(error); 20 | ctx.body = { 21 | success: false, 22 | message: "取消商品收藏失败", 23 | error: error.message, 24 | }; 25 | } 26 | }); 27 | 28 | module.exports = router; 29 | -------------------------------------------------------------------------------- /项目代码/server/src/routes/order/finish.js: -------------------------------------------------------------------------------- 1 | const Router = require("koa-router"); 2 | const db = require("@/db"); 3 | const router = new Router(); 4 | const auth = require("@/modules/auth"); 5 | 6 | router.put("/order/finish/:id", auth(), async ctx => { 7 | try { 8 | const orderId = ctx.params.id; // 获取订单ID 9 | 10 | // 更新订单状态为已完成 11 | const updateQuery = ` 12 | UPDATE orders 13 | SET state = 2 14 | WHERE id = ${orderId} 15 | `; 16 | await db.query(updateQuery); 17 | 18 | ctx.body = { 19 | success: true, 20 | message: "订单状态已更新为已完成", 21 | }; 22 | } catch (error) { 23 | console.error(error); 24 | ctx.body = { 25 | success: false, 26 | message: "更新订单状态失败", 27 | error: error.message, 28 | }; 29 | } 30 | }); 31 | 32 | module.exports = router; 33 | -------------------------------------------------------------------------------- /项目代码/server/src/routes/delivery_record/delete.js: -------------------------------------------------------------------------------- 1 | const Router = require("koa-router"); 2 | const db = require("@/db"); 3 | const router = new Router(); 4 | const auth = require("@/modules/auth"); 5 | 6 | router.delete("/delivery/:id", auth(), async ctx => { 7 | try { 8 | const deliveryId = ctx.params.id; // 获取物流记录ID 9 | 10 | // 执行删除操作 11 | const query = ` 12 | DELETE FROM delivery_record 13 | WHERE id = ${deliveryId} 14 | `; 15 | const [result] = await db.query(query); 16 | 17 | ctx.body = { 18 | success: true, 19 | message: "物流记录删除成功", 20 | }; 21 | } catch (error) { 22 | console.error(error); 23 | ctx.body = { 24 | success: false, 25 | message: "删除物流记录失败", 26 | error: error.message, 27 | }; 28 | } 29 | }); 30 | 31 | module.exports = router; 32 | -------------------------------------------------------------------------------- /项目代码/admin/src/main.js: -------------------------------------------------------------------------------- 1 | import { createApp } from "vue"; 2 | import App from "./App.vue"; 3 | import { createRouter, createWebHistory, createWebHashHistory } from "vue-router"; 4 | 5 | import "@/style/index.scss"; 6 | import "@/plugin/axios"; 7 | import { createPinia } from "pinia"; 8 | import Vant from "vant"; 9 | import "vant/lib/index.css"; 10 | import "moment/dist/locale/zh-cn"; 11 | const app = createApp(App); 12 | 13 | import ElementPlus from "element-plus"; 14 | import "element-plus/dist/index.css"; 15 | 16 | import { setupLayouts } from "virtual:generated-layouts"; 17 | import pages from "~pages"; 18 | 19 | const routes = setupLayouts(pages); 20 | const router = createRouter({ 21 | history: createWebHashHistory(), 22 | routes, 23 | }); 24 | 25 | app.use(router).use(createPinia()).use(Vant).use(ElementPlus).mount("#app"); 26 | -------------------------------------------------------------------------------- /项目代码/server/src/routes/banner/create.js: -------------------------------------------------------------------------------- 1 | const Router = require("koa-router"); 2 | const db = require("@/db"); 3 | const router = new Router(); 4 | const id = require("@/utils/id"); 5 | 6 | router.post("/banner", async ctx => { 7 | try { 8 | const { url, cover } = ctx.request.body; 9 | 10 | const [result] = await db.query( 11 | `INSERT INTO banner (id, url, cover, create_time) VALUES (?, ?, ?, NOW())`, 12 | [id(), /^[\s\S]*.*[^\s][\s\S]*$/.test(url) ? url : null, cover] 13 | ); 14 | 15 | ctx.body = { 16 | success: !!result?.affectedRows, 17 | message: "添加成功", 18 | }; 19 | } catch (error) { 20 | console.log(error); 21 | ctx.body = { 22 | success: false, 23 | error: error.message, 24 | message: "添加失败", 25 | }; 26 | } 27 | }); 28 | 29 | module.exports = router; 30 | -------------------------------------------------------------------------------- /项目代码/server/src/routes/notice/delete.js: -------------------------------------------------------------------------------- 1 | const Router = require("koa-router"); 2 | const db = require("@/db"); 3 | const auth = require("@/modules/auth"); 4 | const router = new Router(); 5 | 6 | router.delete("/notice/:id", auth(), async ctx => { 7 | try { 8 | const noticeId = ctx.params.id; 9 | 10 | // 删除 notice_history 记录 11 | await db.query(`DELETE FROM notice_history WHERE notice_id = ${noticeId}`); 12 | 13 | // 删除 notice 记录 14 | await db.query(`DELETE FROM notice WHERE id = ${noticeId}`); 15 | 16 | ctx.body = { 17 | success: true, 18 | message: "公告删除成功", 19 | }; 20 | } catch (error) { 21 | console.error(error); 22 | ctx.body = { 23 | success: false, 24 | message: "公告删除失败", 25 | error: error.message, 26 | }; 27 | } 28 | }); 29 | 30 | module.exports = router; 31 | -------------------------------------------------------------------------------- /项目代码/admin/src/pages/admin/store/create.vue: -------------------------------------------------------------------------------- 1 | 6 | 30 | 31 | -------------------------------------------------------------------------------- /项目代码/server/src/routes/upload.js: -------------------------------------------------------------------------------- 1 | let Router = require("koa-router"); 2 | let multer = require("@koa/multer"); 3 | let fs = require("fs"); 4 | let { v4 } = require("uuid"); 5 | let router = new Router(); 6 | 7 | let uploadOption = multer({ 8 | storage: multer.memoryStorage(), 9 | limits: { 10 | files: 1, 11 | fileSize: 1024 * 1024 * 10, //5MB 12 | }, 13 | }); 14 | router.post("/static", uploadOption.single("image"), async ctx => { 15 | try { 16 | let buffer = ctx.file.buffer; 17 | let fileName = `${v4().replace(/-/g, "")}.${ctx.file.originalname.split(".").slice(-1)[0]}`; 18 | fs.writeFileSync(`public/${fileName}`, buffer); 19 | ctx.body = { success: true, message: "上传成功", data: fileName }; 20 | } catch (error) { 21 | ctx.body = { success: false, message: "上传错误" }; 22 | } 23 | }); 24 | module.exports = router; 25 | -------------------------------------------------------------------------------- /项目代码/server/src/routes/order/detail.js: -------------------------------------------------------------------------------- 1 | const Router = require("koa-router"); 2 | const db = require("@/db"); 3 | const router = new Router(); 4 | const auth = require("@/modules/auth"); 5 | 6 | router.get("/order/:orderId",auth(), async ctx => { 7 | try { 8 | const orderId = ctx.params.orderId; 9 | 10 | const [result] = await db.query(`SELECT * FROM orders WHERE id = ?`, [orderId]); 11 | 12 | if (result.length === 0) { 13 | ctx.body = { 14 | success: false, 15 | message: "订单不存在", 16 | }; 17 | } else { 18 | ctx.body = { 19 | success: true, 20 | data: result[0], 21 | }; 22 | } 23 | } catch (error) { 24 | ctx.body = { 25 | success: false, 26 | message: "查询订单信息失败", 27 | error: error.message, 28 | }; 29 | } 30 | }); 31 | 32 | module.exports = router; 33 | -------------------------------------------------------------------------------- /项目代码/server/src/routes/address/delete.js: -------------------------------------------------------------------------------- 1 | const Router = require("koa-router"); 2 | const db = require("@/db"); 3 | const auth = require("@/modules/auth"); 4 | 5 | const router = new Router(); 6 | 7 | router.delete("/address/:id", auth(), async ctx => { 8 | try { 9 | const { id } = ctx.params; 10 | 11 | if (!id) { 12 | ctx.body = { 13 | success: false, 14 | message: "缺少必要的参数", 15 | }; 16 | return; 17 | } 18 | 19 | // 更新地址状态为 0,表示已删除 20 | await db.query("UPDATE address SET state = 0 WHERE id = ? and user_id=?", [id, ctx.id]); 21 | 22 | ctx.body = { 23 | success: true, 24 | message: "地址删除成功", 25 | }; 26 | } catch (error) { 27 | console.error(error); 28 | ctx.body = { 29 | success: false, 30 | message: "地址删除失败", 31 | }; 32 | } 33 | }); 34 | 35 | module.exports = router; 36 | -------------------------------------------------------------------------------- /项目代码/server/src/routes/deliveryman/update.js: -------------------------------------------------------------------------------- 1 | const Router = require("koa-router"); 2 | const db = require("@/db"); 3 | const auth = require("@/modules/auth"); 4 | const router = new Router(); 5 | 6 | router.put("/deliveryman/:id", auth(), async ctx => { 7 | try { 8 | const { id } = ctx.params; 9 | const { name, phone, avatar } = ctx.request.body; 10 | 11 | // 更新配送员信息 12 | const result = await db.query( 13 | "UPDATE deliveryman SET name = ?, phone = ?, avatar = ? WHERE id = ?", 14 | [name, phone, avatar, id] 15 | ); 16 | 17 | ctx.body = { 18 | success: true, 19 | message: "配送员信息更新成功", 20 | }; 21 | } catch (error) { 22 | console.error(error); 23 | ctx.body = { 24 | success: false, 25 | message: "配送员信息更新失败", 26 | error: error.message, 27 | }; 28 | } 29 | }); 30 | 31 | module.exports = router; 32 | -------------------------------------------------------------------------------- /项目代码/admin/src/pages/admin/deliveryman/create.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /项目代码/server/src/routes/order/task/order-deliveryman.js: -------------------------------------------------------------------------------- 1 | const Router = require("koa-router"); 2 | const db = require("@/db"); 3 | const router = new Router(); 4 | const auth = require("@/modules/auth"); 5 | 6 | router.put("/orders/deliveryman/:orderId", auth(), async ctx => { 7 | try { 8 | const orderId = ctx.params.orderId; // 获取订单 ID 9 | const deliverymanId = ctx.id; // 获取配送员 ID 10 | 11 | const query = ` 12 | UPDATE orders 13 | SET deliveryman_id = ${deliverymanId},state=1 14 | WHERE id = ${orderId} 15 | `; 16 | await db.query(query); 17 | 18 | ctx.body = { 19 | success: true, 20 | message: "确认成功", 21 | }; 22 | } catch (error) { 23 | console.error(error); 24 | ctx.body = { 25 | success: false, 26 | message: "订单配送人修改失败", 27 | error: error.message, 28 | }; 29 | } 30 | }); 31 | 32 | module.exports = router; 33 | -------------------------------------------------------------------------------- /项目代码/server/src/routes/address/detail.js: -------------------------------------------------------------------------------- 1 | const Router = require("koa-router"); 2 | const db = require("@/db"); 3 | const auth = require("@/modules/auth"); 4 | const router = new Router(); 5 | 6 | // 根据地址ID查询用户地址接口 7 | router.get("/address/:id", auth(), async ctx => { 8 | try { 9 | // 使用用户ID查询地址信息 10 | const [result] = await db.query( 11 | ` 12 | SELECT * FROM address WHERE user_id = ${ctx.id} and state=1 and id=? order by isDefault desc; 13 | `, 14 | [ctx.params.id] 15 | ); 16 | 17 | if (result.length) { 18 | result[0].isDefault = !!result[0].isDefault; 19 | } 20 | 21 | ctx.body = { 22 | success: true, 23 | data: result[0], 24 | }; 25 | } catch (error) { 26 | console.error(error); 27 | ctx.body = { 28 | success: false, 29 | message: "查询用户地址失败", 30 | error: error.message, 31 | }; 32 | } 33 | }); 34 | 35 | module.exports = router; 36 | -------------------------------------------------------------------------------- /项目代码/server/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "server", 3 | "version": "1.0.0", 4 | "main": "index.js", 5 | "license": "MIT", 6 | "scripts": { 7 | "dev": "nodemon ./src/index.js" 8 | }, 9 | "dependencies": { 10 | "@koa/cors": "^4.0.0", 11 | "@koa/multer": "^3.0.2", 12 | "axios": "^1.6.5", 13 | "cheerio": "^1.0.0-rc.10", 14 | "cookie": "^0.6.0", 15 | "cross-env": "^7.0.3", 16 | "jsonwebtoken": "^8.5.1", 17 | "koa": "^2.13.4", 18 | "koa-bodyparser": "^4.4.1", 19 | "koa-router": "^10.1.1", 20 | "koa-static": "^5.0.0", 21 | "lru-cache": "^7.10.1", 22 | "module-alias": "^2.2.2", 23 | "moment": "^2.29.1", 24 | "morgan": "^1.10.0", 25 | "multer": "^1.4.4", 26 | "mysql2": "^3.6.2", 27 | "nodemailer": "^6.9.8", 28 | "nodemon": "^2.0.14", 29 | "qs": "^6.11.2", 30 | "socket.io": "^4.7.4", 31 | "uuid": "^9.0.1" 32 | }, 33 | "devDependencies": {} 34 | } 35 | -------------------------------------------------------------------------------- /项目代码/server/src/index.js: -------------------------------------------------------------------------------- 1 | // 变量别名 2 | const moduleAlias = require("module-alias"); 3 | moduleAlias.addAlias("@", __dirname); 4 | let Koa = require("koa"); 5 | const app = new Koa(); 6 | let staticFiles = require("koa-static"); 7 | let Body = require("koa-bodyparser"); 8 | let cors = require("@koa/cors"); 9 | app.use(staticFiles("public")); 10 | app.use(cors()); 11 | app.use(Body()); 12 | 13 | let getAllRouter = require("@/modules/getAllRouter"); 14 | (async () => { 15 | // console.log((await getAllRouter()).length); 16 | (await getAllRouter()).forEach(item => { 17 | app.use(require(item).routes()); 18 | }); 19 | })(); 20 | 21 | const port = 3000; 22 | 23 | const http = require("http"); 24 | const server = http.createServer(app.callback()); //包装app保证http和socket监听同一端口 25 | module.exports = { 26 | server, 27 | }; 28 | require("@/socket/index"); 29 | 30 | server.listen(port, function () { 31 | console.log(`项目运行于: ${port} 端口`); 32 | }); 33 | -------------------------------------------------------------------------------- /项目代码/server/src/routes/deliveryman/detail.js: -------------------------------------------------------------------------------- 1 | const Router = require("koa-router"); 2 | const db = require("@/db"); 3 | const auth = require("@/modules/auth"); 4 | const router = new Router(); 5 | 6 | router.get(["/deliveryman/detail-user", "/deliveryman/:id"], auth(), async ctx => { 7 | try { 8 | const { id } = ctx.params; 9 | 10 | // 查询配送员信息 11 | const [result] = await db.query("SELECT * FROM deliveryman WHERE id = ?", [id || ctx.id]); 12 | 13 | if (result.length == 0) { 14 | ctx.body = { 15 | success: false, 16 | message: "未找到配送员信息", 17 | }; 18 | } else { 19 | ctx.body = { 20 | success: true, 21 | data: result[0], 22 | }; 23 | } 24 | } catch (error) { 25 | console.error(error); 26 | ctx.body = { 27 | success: false, 28 | message: "查询配送员信息失败", 29 | error: error.message, 30 | }; 31 | } 32 | }); 33 | 34 | module.exports = router; 35 | -------------------------------------------------------------------------------- /项目代码/server/src/routes/cart/delete.js: -------------------------------------------------------------------------------- 1 | const Router = require("koa-router"); 2 | const db = require("@/db"); 3 | const router = new Router(); 4 | const auth = require("@/modules/auth"); 5 | const qs = require("qs"); 6 | 7 | router.delete("/cart", auth(), async ctx => { 8 | try { 9 | const cartIds = qs.parse(ctx.request.query).id; //数组 10 | 11 | if (!cartIds || !Array.isArray(cartIds) || cartIds.length === 0) { 12 | ctx.body = { 13 | success: false, 14 | message: "参数需要是数组", 15 | }; 16 | return; 17 | } 18 | const query = "DELETE FROM cart WHERE id IN (?)"; 19 | const [result] = await db.query(query, [cartIds]); 20 | 21 | ctx.body = { 22 | success: true, 23 | message: `删除成功`, 24 | }; 25 | } catch (error) { 26 | console.log(error); 27 | ctx.body = { 28 | success: false, 29 | message: "删除错误s", 30 | error: error.message, 31 | }; 32 | } 33 | }); 34 | 35 | module.exports = router; 36 | -------------------------------------------------------------------------------- /项目代码/admin/src/hooks/useFetch.js: -------------------------------------------------------------------------------- 1 | import { ref, reactive, watchEffect } from "vue"; 2 | import axios from "axios"; 3 | 4 | function useFetch(url, options = { method: "get" }, manual = false) { 5 | const data = ref(null); 6 | const error = ref(null); 7 | const isLoading = ref(!manual); 8 | 9 | const fetchData = async () => { 10 | isLoading.value = true; 11 | 12 | try { 13 | const response = await axios({ 14 | url, 15 | ...options, 16 | }); 17 | data.value = response.data; 18 | } catch (error) { 19 | error.value = error; 20 | } finally { 21 | isLoading.value = false; 22 | } 23 | }; 24 | 25 | if (!manual) { 26 | watchEffect(() => { 27 | fetchData(); 28 | }); 29 | } 30 | 31 | const refetch = () => { 32 | fetchData(); 33 | }; 34 | 35 | return { 36 | data, 37 | error, 38 | isLoading, 39 | refetch, 40 | }; 41 | } 42 | 43 | export default useFetch; 44 | -------------------------------------------------------------------------------- /项目代码/server/src/modules/getAllRouter.js: -------------------------------------------------------------------------------- 1 | const fs=require('fs') 2 | const path = require("path"); 3 | 4 | async function fileDisplay(filePath) { 5 | let fileList = []; 6 | function _fileDisplay(filePath) { 7 | let files = fs.readdirSync(filePath); 8 | for (let index = 0; index < files.length; index++) { 9 | let filename = files[index]; 10 | let filedir = path.join(filePath, filename); //拼接路径用于app.use 11 | let stats = fs.statSync(filedir); 12 | let isFile = stats.isFile(); 13 | let isDir = stats.isDirectory(); 14 | if (isFile) { 15 | fileList.push(filedir); 16 | } 17 | if (isDir) { 18 | _fileDisplay(filedir); 19 | } 20 | } 21 | } 22 | _fileDisplay(filePath); 23 | return fileList; 24 | } 25 | let src = path.join(__dirname, "../routes"); 26 | async function getAllRouter() { 27 | let fileList = await fileDisplay(src); 28 | return fileList; 29 | } 30 | module.exports = getAllRouter; 31 | -------------------------------------------------------------------------------- /项目代码/server/src/routes/message/list.js: -------------------------------------------------------------------------------- 1 | const Router = require("koa-router"); 2 | const db = require("@/db"); 3 | const auth = require("@/modules/auth"); 4 | 5 | const router = new Router(); 6 | 7 | router.get("/message", auth(), async ctx => { 8 | try { 9 | const { store_id, user_id } = ctx.query; 10 | const [messages] = await db.query( 11 | ` 12 | SELECT m.*, u.name AS user_name, s.name AS store_name,s.cover AS store_cover,u.avatar AS user_avatar 13 | FROM message m 14 | LEFT JOIN user u ON m.user_id = u.id 15 | LEFT JOIN store s ON m.store_id = s.id 16 | WHERE m.store_id = ? AND m.user_id = ? 17 | ORDER BY m.create_time DESC 18 | `, 19 | [store_id || ctx.id, user_id || ctx.id] 20 | ); 21 | 22 | ctx.body = { success: false, data: messages }; 23 | } catch (error) { 24 | console.error(error); 25 | ctx.body = { success: false, data: [] }; 26 | } 27 | }); 28 | 29 | module.exports = router; 30 | -------------------------------------------------------------------------------- /项目代码/server/src/routes/store/auth/sign.js: -------------------------------------------------------------------------------- 1 | let Router = require("koa-router"); 2 | const sign = require("@/modules/signToken"); 3 | let db = require("@/db"); 4 | let router = new Router(); 5 | 6 | router.post("/store/sign", async ctx => { 7 | try { 8 | let [res] = await db.query(`select * from store where email=? and password=?`, [ 9 | ctx.request.body.email, 10 | ctx.request.body.password, 11 | ]); 12 | 13 | if (!res.length) { 14 | ctx.body = { 15 | success: false, 16 | message: "账号或密码错误", 17 | }; 18 | return; 19 | } 20 | ctx.body = { 21 | success: !!res.length, 22 | data: { id: res[0]?.id, username: res[0]?.username, state: res[0]?.state }, 23 | message: "登录成功", 24 | token: sign({ id: res[0]?.id, username: res[0]?.username, type: "store" }), 25 | }; 26 | } catch (error) { 27 | console.log(error); 28 | ctx.body = { success: false, message: "登录失败" }; 29 | } 30 | }); 31 | module.exports = router; 32 | -------------------------------------------------------------------------------- /项目代码/server/src/modules/auth.js: -------------------------------------------------------------------------------- 1 | let jwt = require("jsonwebtoken"); 2 | 3 | async function verify(token) { 4 | return new Promise((resolve, reject) => { 5 | jwt.verify(token, "key", async function (err, decoded) { 6 | if (err) { 7 | reject(); 8 | } else { 9 | resolve(decoded); 10 | } 11 | }); 12 | }); 13 | } 14 | 15 | function auth(isAdmin) { 16 | return async (ctx, next) => { 17 | let token = ctx.headers.authorization; 18 | if (!token) { 19 | ctx.status = 401; 20 | return; 21 | } 22 | 23 | await verify(token) 24 | .then(async decoded => { 25 | if (isAdmin && decoded.type != "admin") { 26 | ctx.status = 401; 27 | } else { 28 | ctx.id = decoded.id; 29 | ctx.auth = decoded.type; 30 | ctx.username = decoded.username; 31 | await next(); 32 | } 33 | }) 34 | .catch(err => { 35 | ctx.status = 401; 36 | }); 37 | }; 38 | } 39 | module.exports = auth; 40 | -------------------------------------------------------------------------------- /项目代码/server/src/routes/deliveryman/list.js: -------------------------------------------------------------------------------- 1 | const Router = require("koa-router"); 2 | const db = require("@/db"); 3 | const auth = require("@/modules/auth"); 4 | const router = new Router(); 5 | 6 | router.get("/deliveryman", auth(), async ctx => { 7 | try { 8 | // 查询配送员列表信息,同时关联orders表,展示订单状态 9 | const query = ` 10 | SELECT 11 | d.*, 12 | COUNT(CASE WHEN o.state = 0 THEN 1 END) AS ongoing_orders, 13 | COUNT(CASE WHEN o.state = 1 THEN 1 END) AS completed_orders 14 | FROM 15 | deliveryman d 16 | LEFT JOIN 17 | orders o ON d.id = o.deliveryman_id 18 | GROUP BY 19 | d.id; 20 | `; 21 | const [result] = await db.query(query); 22 | 23 | ctx.body = { 24 | success: true, 25 | data: result, 26 | }; 27 | } catch (error) { 28 | console.error(error); 29 | ctx.body = { 30 | success: false, 31 | message: "查询配送员列表失败", 32 | error: error.message, 33 | }; 34 | } 35 | }); 36 | 37 | module.exports = router; 38 | -------------------------------------------------------------------------------- /项目代码/admin/src/pages/client/order/success.vue: -------------------------------------------------------------------------------- 1 | 21 | 31 | -------------------------------------------------------------------------------- /项目代码/server/src/routes/delivery_record/create.js: -------------------------------------------------------------------------------- 1 | const Router = require("koa-router"); 2 | const db = require("@/db"); 3 | const router = new Router(); 4 | const auth = require("@/modules/auth"); 5 | const id = require("@/utils/id"); 6 | 7 | router.post("/delivery-record", auth(), async ctx => { 8 | try { 9 | const orderId = ctx.request.body.order_id; // 获取订单ID 10 | const content = ctx.request.body.content; // 获取物流内容 11 | const deliverymanId = ctx.id; // 获取当前用户ID作为配送员ID 12 | 13 | // 插入物流记录 14 | const insertQuery = ` 15 | INSERT INTO delivery_record (id,deliveryman_id, order_id, content, create_time) 16 | VALUES (${id()},${deliverymanId}, ${orderId}, '${content}', NOW()) 17 | `; 18 | await db.query(insertQuery); 19 | 20 | ctx.body = { 21 | success: true, 22 | message: "物流信息添加成功", 23 | }; 24 | } catch (error) { 25 | console.error(error); 26 | ctx.body = { 27 | success: false, 28 | message: "添加物流信息失败", 29 | error: error.message, 30 | }; 31 | } 32 | }); 33 | 34 | module.exports = router; 35 | -------------------------------------------------------------------------------- /项目代码/server/src/routes/message/list-store.js: -------------------------------------------------------------------------------- 1 | const Router = require("koa-router"); 2 | const db = require("@/db"); 3 | const auth = require("@/modules/auth"); 4 | 5 | const router = new Router(); 6 | 7 | // 店铺聊天页面左侧栏信息 8 | router.get("/message/store/list", auth(), async ctx => { 9 | try { 10 | const [messages] = await db.query( 11 | ` 12 | SELECT m.*, u.name AS user_name, s.name AS store_name,s.cover AS store_cover,u.avatar AS user_avatar 13 | FROM message m 14 | LEFT JOIN user u ON m.user_id = u.id 15 | LEFT JOIN store s ON m.store_id = s.id 16 | WHERE m.store_id = ? 17 | ORDER BY m.create_time DESC 18 | `, 19 | [ctx.id] 20 | ); 21 | let list = []; 22 | messages.forEach(item => { 23 | if (!list.some(el => el.user_id == item.user_id)) { 24 | list.push(item); 25 | } 26 | }); 27 | 28 | ctx.body = { success: true, data: list }; 29 | } catch (error) { 30 | console.error(error); 31 | ctx.body = { success: false, data: [] }; 32 | } 33 | }); 34 | 35 | module.exports = router; 36 | -------------------------------------------------------------------------------- /项目代码/server/src/routes/message/list-user.js: -------------------------------------------------------------------------------- 1 | const Router = require("koa-router"); 2 | const db = require("@/db"); 3 | const auth = require("@/modules/auth"); 4 | 5 | const router = new Router(); 6 | 7 | // 用户聊天页面列表 8 | router.get("/message/user/list", auth(), async ctx => { 9 | try { 10 | const [messages] = await db.query( 11 | ` 12 | SELECT m.*, u.name AS user_name, s.name AS store_name,s.cover AS store_cover,u.avatar AS user_avatar 13 | FROM message m 14 | LEFT JOIN user u ON m.user_id = u.id 15 | LEFT JOIN store s ON m.store_id = s.id 16 | WHERE m.user_id = ? 17 | ORDER BY m.create_time DESC 18 | `, 19 | [ctx.id] 20 | ); 21 | let list = []; 22 | messages.forEach(item => { 23 | if (!list.some(el => el.store_id == item.store_id)) { 24 | list.push(item); 25 | } 26 | }); 27 | 28 | ctx.body = { success: true, data: list }; 29 | } catch (error) { 30 | console.error(error); 31 | ctx.body = { success: false, data: [] }; 32 | } 33 | }); 34 | 35 | module.exports = router; 36 | -------------------------------------------------------------------------------- /项目代码/server/src/routes/delivery_record/list.js: -------------------------------------------------------------------------------- 1 | const Router = require("koa-router"); 2 | const db = require("@/db"); 3 | const router = new Router(); 4 | const auth = require("@/modules/auth"); 5 | 6 | router.get("/delivery-record/:order_id", auth(), async ctx => { 7 | try { 8 | const orderId = ctx.params.order_id; // 获取订单ID 9 | 10 | // 查询物流信息 11 | const query = ` 12 | SELECT delivery_record.*, deliveryman.name AS deliveryman_name, deliveryman.phone AS deliveryman_phone,deliveryman.avatar AS deliveryman_avatar 13 | FROM delivery_record 14 | LEFT JOIN deliveryman ON delivery_record.deliveryman_id = deliveryman.id 15 | WHERE delivery_record.order_id = ${orderId} order by create_time desc; 16 | `; 17 | 18 | const [result] = await db.query(query); 19 | 20 | ctx.body = { 21 | success: true, 22 | data: result, 23 | }; 24 | } catch (error) { 25 | console.error(error); 26 | ctx.body = { 27 | success: false, 28 | message: "查询物流信息失败", 29 | error: error.message, 30 | }; 31 | } 32 | }); 33 | 34 | module.exports = router; 35 | -------------------------------------------------------------------------------- /项目代码/server/src/routes/user/sign-up.js: -------------------------------------------------------------------------------- 1 | const Router = require("koa-router"); 2 | const db = require("@/db"); 3 | const router = new Router(); 4 | const id = require("@/utils/id"); 5 | 6 | router.post("/user", async ctx => { 7 | try { 8 | const { name, email, password, avatar } = ctx.request.body; 9 | 10 | const [repeat] = await db.query(`select count(id) from user where email=?`, [email]); 11 | if (repeat[0]["count(id)"]) { 12 | ctx.body = { 13 | success: false, 14 | message: "已有重复邮箱", 15 | }; 16 | return; 17 | } 18 | 19 | const result = await db.query( 20 | `INSERT INTO user (id,name, email, password,avatar, create_time) VALUES (?, ?, ?,?,?, NOW())`, 21 | [id(), name, email, password, avatar] 22 | ); 23 | 24 | ctx.body = { 25 | success: !!result[0]?.affectedRows, 26 | message: "注册成功", 27 | }; 28 | } catch (error) { 29 | console.log(error); 30 | ctx.body = { 31 | success: false, 32 | error: error.message, 33 | message: "注册失败", 34 | }; 35 | } 36 | }); 37 | 38 | module.exports = router; 39 | -------------------------------------------------------------------------------- /项目代码/admin/src/layouts/client.vue: -------------------------------------------------------------------------------- 1 | 9 | 47 | -------------------------------------------------------------------------------- /项目代码/admin/src/components/VantUpload.vue: -------------------------------------------------------------------------------- 1 | 9 | 43 | 44 | -------------------------------------------------------------------------------- /项目代码/server/src/routes/order/list-store.js: -------------------------------------------------------------------------------- 1 | const Router = require("koa-router"); 2 | const db = require("@/db"); 3 | const auth = require("@/modules/auth"); 4 | const router = new Router(); 5 | 6 | router.get("/order/list/store", auth(), async ctx => { 7 | try { 8 | let query = ` 9 | SELECT 10 | o.*, 11 | u.id AS user_id, 12 | u.name AS user_name, 13 | u.avatar AS user_avatar 14 | FROM 15 | orders o 16 | LEFT JOIN 17 | user u ON o.user_id = u.id 18 | WHERE 19 | JSON_CONTAINS(o.commodity_data, JSON_OBJECT('store_id', ${ctx.id}), "$") 20 | `; 21 | 22 | if (ctx.query.id) { 23 | query += ` and o.id=${ctx.query.id}`; 24 | } 25 | 26 | query += ` ORDER BY o.create_time DESC;`; 27 | 28 | const [result] = await db.query(query); 29 | 30 | ctx.body = { 31 | success: true, 32 | data: result, 33 | }; 34 | } catch (error) { 35 | console.error(error); 36 | ctx.body = { 37 | success: false, 38 | message: "订单查询失败", 39 | error: error.message, 40 | }; 41 | } 42 | }); 43 | 44 | module.exports = router; 45 | -------------------------------------------------------------------------------- /项目代码/server/src/routes/comment/list.js: -------------------------------------------------------------------------------- 1 | const Router = require("koa-router"); 2 | const db = require("@/db"); 3 | const router = new Router(); 4 | 5 | router.get("/comment/:commodity_id", async ctx => { 6 | try { 7 | const commodity_id = ctx.params.commodity_id; 8 | 9 | // 查询商品的全部评论并关联用户信息 10 | const [result] = await db.query( 11 | ` 12 | SELECT 13 | comment.id AS comment_id, 14 | comment.content, 15 | comment.score, 16 | comment.create_time, 17 | user.id AS user_id, 18 | user.name AS user_name, 19 | user.avatar AS user_avatar 20 | FROM 21 | comment 22 | INNER JOIN 23 | user ON comment.user_id = user.id 24 | WHERE 25 | comment.commodity_id = ? 26 | ORDER BY 27 | comment.create_time DESC 28 | `, 29 | [commodity_id] 30 | ); 31 | 32 | ctx.body = { 33 | success: true, 34 | data: result, 35 | }; 36 | } catch (error) { 37 | ctx.body = { 38 | success: false, 39 | message: "查询评论失败", 40 | error: error.message, 41 | }; 42 | } 43 | }); 44 | 45 | module.exports = router; 46 | -------------------------------------------------------------------------------- /项目代码/server/src/routes/commodity/list.js: -------------------------------------------------------------------------------- 1 | const Router = require("koa-router"); 2 | const db = require("@/db"); 3 | const auth = require("@/modules/auth"); 4 | const router = new Router(); 5 | 6 | router.get("/commodity", auth(), async ctx => { 7 | try { 8 | let query = `SELECT * FROM commodity WHERE 1=1`; 9 | 10 | // 如果是 store,要求 store_id 是 ctx.id 11 | if (ctx.auth === "store" || ctx.query.store_id) { 12 | query += ` AND store_id = ${ctx.query.store_id || ctx.id}`; 13 | } 14 | // 如果存在 ctx.query.state,要求 state 是 ctx.query.state 15 | if (ctx.query.state !== undefined) { 16 | query += ` AND state = ${ctx.query.state}`; 17 | } 18 | // 要求必须有库存 19 | if (ctx.query.inventory !== undefined) { 20 | query += ` AND inventory >0`; 21 | } 22 | 23 | // 执行数据库查询 24 | const [result] = await db.query(query); 25 | 26 | ctx.body = { 27 | success: true, 28 | data: result, 29 | }; 30 | } catch (error) { 31 | console.log(error); 32 | ctx.body = { 33 | success: false, 34 | error: error.message, 35 | message: "查询失败", 36 | }; 37 | } 38 | }); 39 | 40 | module.exports = router; 41 | -------------------------------------------------------------------------------- /项目代码/admin/src/pages/store/commodity/[id].vue: -------------------------------------------------------------------------------- 1 | 14 | 34 | 35 | -------------------------------------------------------------------------------- /项目代码/server/src/routes/commodity/create.js: -------------------------------------------------------------------------------- 1 | const Router = require("koa-router"); 2 | const db = require("@/db"); 3 | const auth = require("@/modules/auth"); 4 | const router = new Router(); 5 | const id = require("@/utils/id"); 6 | 7 | router.post("/commodity", auth(), async ctx => { 8 | try { 9 | const { name, description, cover, banner, price, configuration, inventory } = 10 | ctx.request.body; 11 | 12 | const result = await db.query( 13 | `INSERT INTO commodity (id,name, description, cover, banner, price, configuration, inventory, store_id, create_time, state) VALUES (?,?,?, ?, ?, ?, ?, ?,?, NOW(), 1)`, 14 | [ 15 | id(), 16 | name, 17 | description, 18 | cover, 19 | JSON.stringify(banner), 20 | price, 21 | JSON.stringify(configuration), 22 | inventory, 23 | ctx.id, 24 | ] 25 | ); 26 | 27 | ctx.body = { 28 | success: !!result[0]?.affectedRows, 29 | message: "添加成功", 30 | }; 31 | } catch (error) { 32 | console.log(error); 33 | ctx.body = { 34 | success: false, 35 | error: error.message, 36 | message: "添加失败", 37 | }; 38 | } 39 | }); 40 | 41 | module.exports = router; 42 | -------------------------------------------------------------------------------- /项目代码/server/src/routes/order/list.js: -------------------------------------------------------------------------------- 1 | const Router = require("koa-router"); 2 | const db = require("@/db"); 3 | const auth = require("@/modules/auth"); 4 | const router = new Router(); 5 | 6 | router.get("/order", auth(), async ctx => { 7 | try { 8 | const { auth, id } = ctx; 9 | let query = ` 10 | SELECT 11 | o.*, 12 | u.id AS user_id, 13 | u.name AS user_name, 14 | u.avatar AS user_avatar 15 | FROM 16 | orders o 17 | LEFT JOIN 18 | user u ON o.user_id = u.id 19 | WHERE`; 20 | 21 | if (auth === "user") { 22 | query += ` o.user_id = ${id}`; 23 | } else if (auth === "admin") { 24 | query += ` 1=1`; // 占位 25 | } 26 | 27 | if (ctx.query.id) { 28 | query += ` AND o.id = ${ctx.query.id}`; 29 | } 30 | 31 | query += ` ORDER BY o.create_time DESC`; 32 | 33 | const [result] = await db.query(query); 34 | 35 | ctx.body = { 36 | success: true, 37 | data: result, 38 | }; 39 | } catch (error) { 40 | console.error(error); 41 | ctx.body = { 42 | success: false, 43 | message: "订单查询失败", 44 | error: error.message, 45 | }; 46 | } 47 | }); 48 | 49 | module.exports = router; 50 | -------------------------------------------------------------------------------- /项目代码/admin/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "site", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "vite build", 9 | "preview": "vite preview" 10 | }, 11 | "dependencies": { 12 | "@vant/area-data": "^1.5.1", 13 | "@vueuse/head": "^1.0.22", 14 | "@wangeditor/editor": "^5.1.23", 15 | "@wangeditor/editor-for-vue": "^5.1.12", 16 | "axios": "^1.2.1", 17 | "copy-to-clipboard": "^3.3.3", 18 | "echarts": "^5.4.3", 19 | "element-plus": "^2.4.1", 20 | "js-cookie": "^3.0.5", 21 | "moment": "^2.30.1", 22 | "pinia": "^2.0.28", 23 | "socket.io-client": "^4.7.4", 24 | "unplugin-auto-import": "^0.17.3", 25 | "vant": "4.8.4", 26 | "vue": "^3.2.45", 27 | "vue-countup-v3": "^1.4.1", 28 | "vue-router": "^4.1.6", 29 | "vue-waterfall-plugin-next": "^2.3.1" 30 | }, 31 | "devDependencies": { 32 | "@types/node": "^18.11.17", 33 | "@vitejs/plugin-vue": "^4.0.0", 34 | "cssnano": "^5.1.14", 35 | "postcss": "^8.4.20", 36 | "sass": "^1.57.1", 37 | "tailwindcss": "3.3.2", 38 | "vite": "^4.0.0", 39 | "vite-plugin-pages": "^0.32.0", 40 | "vite-plugin-vue-layouts": "^0.11.0" 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /项目代码/server/src/routes/comment/delete.js: -------------------------------------------------------------------------------- 1 | const Router = require("koa-router"); 2 | const db = require("@/db"); 3 | const auth = require("@/modules/auth"); 4 | const router = new Router(); 5 | 6 | router.delete("/comment/:id", auth(), async ctx => { 7 | try { 8 | const id = ctx.params.id; 9 | 10 | let IDList = [+id]; //被删除的ID数组 11 | async function fun(id) { 12 | const [result] = await db.query(`select id from comment where reply=?`, [id]); 13 | if (result.length) { 14 | for (let index = 0; index < result.length; index++) { 15 | const item = result[index]; 16 | IDList.push(item.id); 17 | await fun(item.id); 18 | } 19 | } 20 | } 21 | await fun(id); 22 | const [result] = await db.query( 23 | ` 24 | DELETE FROM comment 25 | WHERE id IN (?); 26 | `, 27 | [IDList] 28 | ); 29 | ctx.body = { 30 | success: !!result?.affectedRows, 31 | message: !!result?.affectedRows ? "删除成功" : "删除", 32 | }; 33 | } catch (error) { 34 | console.error(error); 35 | ctx.body = { 36 | success: false, 37 | message: "删除失败", 38 | error: error.message, 39 | }; 40 | } 41 | }); 42 | 43 | module.exports = router; 44 | -------------------------------------------------------------------------------- /项目代码/server/src/routes/tools/location.js: -------------------------------------------------------------------------------- 1 | const Router = require("koa-router"); 2 | const axios = require("axios"); 3 | 4 | function getClientIP(req) { 5 | let ip = 6 | req.headers["x-forwarded-for"] || 7 | req.ip || 8 | req.connection.remoteAddress || 9 | req.socket.remoteAddress || 10 | req.connection.socket.remoteAddress || 11 | ""; 12 | if (ip) { 13 | ip = ip.replace("::ffff:", ""); 14 | } 15 | return ip; 16 | } 17 | 18 | let router = new Router(); 19 | 20 | router.get("/location", async ctx => { 21 | try { 22 | const response = await axios.get("https://api.map.baidu.com/location/ip", { 23 | params: { 24 | coor: "bd09ll", 25 | ak: `E1xIzplbXNHbqehCW36mGK5oiDPec4Mq`, 26 | ip: getClientIP(ctx.req), 27 | }, 28 | }); 29 | const address_detail = response.data?.content?.address_detail; 30 | 31 | ctx.body = { 32 | success: true, 33 | message: "查询成功", 34 | data: { city: address_detail.city || null, province: address_detail.province || null }, 35 | }; 36 | } catch (error) { 37 | ctx.body = { 38 | success: true, 39 | message: "查询成功", 40 | data: { city: "大连市", province: "辽宁省" }, 41 | }; 42 | } 43 | }); 44 | 45 | module.exports = router; 46 | -------------------------------------------------------------------------------- /项目代码/admin/src/pages/client/address/index.vue: -------------------------------------------------------------------------------- 1 | 20 | 36 | 37 | 38 | { 39 | "meta": { 40 | "layout": "client-empty" 41 | } 42 | } 43 | 44 | -------------------------------------------------------------------------------- /项目代码/server/src/routes/notice/create.js: -------------------------------------------------------------------------------- 1 | const Router = require("koa-router"); 2 | const db = require("@/db"); // 假设有一个 db 模块用于执行数据库操作 3 | const auth = require("@/modules/auth"); 4 | const router = new Router(); 5 | const id = require("@/utils/id"); 6 | 7 | router.post("/notice", auth(), async ctx => { 8 | try { 9 | const { title, target, content, isTop } = ctx.request.body; 10 | 11 | // 检查参数是否完整 12 | if (!title || !target || !content) { 13 | ctx.body = { 14 | success: false, 15 | message: "参数不完整", 16 | }; 17 | return; 18 | } 19 | 20 | // 在数据库中插入通知记录 21 | const insertNoticeQuery = ` 22 | INSERT INTO notice (id,title, target, content, isTop, create_time) 23 | VALUES (?,?, ?, ?, ?, NOW()) 24 | `; 25 | const [insertResult] = await db.query(insertNoticeQuery, [ 26 | id(), 27 | title, 28 | JSON.stringify(target), 29 | content, 30 | isTop, 31 | ]); 32 | 33 | ctx.body = { 34 | success: true, 35 | message: "通知添加成功", 36 | }; 37 | } catch (error) { 38 | console.error(error); 39 | ctx.body = { 40 | success: false, 41 | message: "通知添加失败", 42 | error: error.message, 43 | }; 44 | } 45 | }); 46 | 47 | module.exports = router; 48 | -------------------------------------------------------------------------------- /项目代码/server/src/routes/collection/create.js: -------------------------------------------------------------------------------- 1 | const Router = require("koa-router"); 2 | const db = require("@/db"); 3 | const auth = require("@/modules/auth"); 4 | const id = require("@/utils/id"); 5 | const router = new Router(); 6 | 7 | router.post("/collection", auth(), async ctx => { 8 | try { 9 | const { item_id, type } = ctx.request.body; 10 | 11 | // 检查是否已经收藏 12 | const existingCollection = await db.query( 13 | "SELECT id FROM collection WHERE user_id = ? AND item_id = ?", 14 | [ctx.id, item_id] 15 | ); 16 | 17 | if (existingCollection[0]?.length > 0) { 18 | ctx.body = { 19 | success: false, 20 | message: "商品已经被收藏过了", 21 | }; 22 | return; 23 | } 24 | 25 | // 插入收藏到数据库 26 | const result = await db.query( 27 | "INSERT INTO collection (id, user_id, item_id,type, create_time) VALUES (?, ?, ?,?, NOW())", 28 | [id(), ctx.id, item_id, type] 29 | ); 30 | 31 | ctx.body = { 32 | success: !!result[0]?.affectedRows, 33 | message: "商品收藏成功", 34 | }; 35 | } catch (error) { 36 | console.error(error); 37 | ctx.body = { 38 | success: false, 39 | message: "商品收藏失败", 40 | error: error.message, 41 | }; 42 | } 43 | }); 44 | 45 | module.exports = router; 46 | -------------------------------------------------------------------------------- /项目代码/admin/src/pages/admin/store/[id].vue: -------------------------------------------------------------------------------- 1 | 14 | 40 | 41 | -------------------------------------------------------------------------------- /项目代码/server/src/routes/deliveryman/create.js: -------------------------------------------------------------------------------- 1 | const Router = require("koa-router"); 2 | const db = require("@/db"); 3 | const auth = require("@/modules/auth"); 4 | const router = new Router(); 5 | const id = require("@/utils/id"); 6 | 7 | router.post("/deliveryman", auth(), async ctx => { 8 | try { 9 | const { name, phone, avatar } = ctx.request.body; 10 | 11 | // 检查配送员是否已存在 12 | const [existingDeliveryman] = await db.query("SELECT * FROM deliveryman WHERE phone = ?", [ 13 | phone, 14 | ]); 15 | 16 | if (existingDeliveryman.length) { 17 | ctx.body = { 18 | success: false, 19 | message: "该配送员已存在", 20 | }; 21 | return; 22 | } 23 | 24 | // 插入新的配送员信息 25 | const [result] = await db.query( 26 | "INSERT INTO deliveryman (id,name, phone, avatar, create_time,password) VALUES (?,?, ?, ?, ?,?)", 27 | [id(), name, phone, avatar, new Date(), 12345678] 28 | ); 29 | 30 | ctx.body = { 31 | success: true, 32 | message: "配送员添加成功", 33 | deliverymanId: result.insertId, 34 | }; 35 | } catch (error) { 36 | console.error(error); 37 | ctx.body = { 38 | success: false, 39 | message: "添加配送员失败", 40 | error: error.message, 41 | }; 42 | } 43 | }); 44 | 45 | module.exports = router; 46 | -------------------------------------------------------------------------------- /项目代码/admin/src/pages/client/address/create.vue: -------------------------------------------------------------------------------- 1 | 15 | 38 | 39 | 40 | { 41 | "meta": { 42 | "layout": "client-empty" 43 | } 44 | } 45 | 46 | -------------------------------------------------------------------------------- /项目代码/server/src/routes/address/update.js: -------------------------------------------------------------------------------- 1 | const Router = require("koa-router"); 2 | const db = require("@/db"); 3 | const id = require("@/utils/id"); 4 | const auth = require("@/modules/auth"); 5 | 6 | const router = new Router(); 7 | 8 | router.put("/address/:id", auth(), async ctx => { 9 | try { 10 | const { phone, address, name, isDefault } = ctx.request.body; 11 | 12 | if (!ctx.params.id || !phone || !address || !name || isDefault === undefined) { 13 | ctx.body = { 14 | success: false, 15 | message: "缺少必要的参数", 16 | }; 17 | return; 18 | } 19 | 20 | // 更新旧地址的状态为 0 21 | await db.query("UPDATE address SET state = 0 WHERE id = ?", [ctx.params.id]); 22 | 23 | let _id = id(); 24 | // 插入新的地址数据 25 | const result = await db.query( 26 | "INSERT INTO address (id, name, phone, address, isDefault,user_id) VALUES (?, ?, ?, ?, ?,?)", 27 | [_id, name, phone, address, isDefault, ctx.id] 28 | ); 29 | 30 | ctx.body = { 31 | success: true, 32 | message: "地址修改成功", 33 | data: _id, 34 | }; 35 | } catch (error) { 36 | console.error(error); 37 | ctx.body = { 38 | success: false, 39 | message: "地址修改失败", 40 | error: error.message, 41 | }; 42 | } 43 | }); 44 | 45 | module.exports = router; 46 | -------------------------------------------------------------------------------- /项目代码/server/src/routes/notice-history/create.js: -------------------------------------------------------------------------------- 1 | const Router = require("koa-router"); 2 | const db = require("@/db"); // 你的数据库模块 3 | const auth = require("@/modules/auth"); // 你的权限验证模块 4 | const id = require("@/utils/id"); 5 | 6 | const router = new Router(); 7 | 8 | router.post("/notice/history", auth(), async ctx => { 9 | try { 10 | const { id: storeId } = ctx; 11 | const { noticeId } = ctx.request.body; 12 | 13 | const [existingHistory] = await db.query( 14 | "SELECT * FROM notice_history WHERE store_id = ? AND notice_id = ?", 15 | [storeId, noticeId] 16 | ); 17 | 18 | if (existingHistory.length === 0) { 19 | await db.query("INSERT INTO notice_history (id,store_id, notice_id) VALUES (?,?, ?)", [ 20 | id(), 21 | storeId, 22 | noticeId, 23 | ]); 24 | 25 | ctx.body = { 26 | success: true, 27 | message: "成功添加通知历史记录", 28 | }; 29 | } else { 30 | ctx.body = { 31 | success: true, 32 | message: "通知历史记录已存在", 33 | }; 34 | } 35 | } catch (error) { 36 | console.error(error); 37 | ctx.status = 500; 38 | ctx.body = { 39 | success: false, 40 | message: "添加通知历史记录失败", 41 | error: error.message, 42 | }; 43 | } 44 | }); 45 | 46 | module.exports = router; 47 | -------------------------------------------------------------------------------- /项目代码/server/src/routes/commodity/update.js: -------------------------------------------------------------------------------- 1 | const Router = require("koa-router"); 2 | const db = require("@/db"); 3 | const auth = require("@/modules/auth"); 4 | const router = new Router(); 5 | 6 | router.put("/commodity/:id", auth(), async ctx => { 7 | try { 8 | const commodityId = ctx.params.id; 9 | const { name, description, cover, banner, price, configuration, inventory } = ctx.request.body; 10 | 11 | // 构建 SQL 更新语句 12 | const updateQuery = ` 13 | UPDATE commodity 14 | SET 15 | name = ?, 16 | description = ?, 17 | cover = ?, 18 | banner = ?, 19 | price = ?, 20 | configuration = ?, 21 | inventory = ? 22 | WHERE id = ? 23 | `; 24 | 25 | // 执行数据库更新操作 26 | const result = await db.query(updateQuery, [ 27 | name, 28 | description, 29 | cover, 30 | JSON.stringify(banner), 31 | price, 32 | JSON.stringify(configuration), 33 | inventory, 34 | commodityId, 35 | ]); 36 | 37 | ctx.body = { 38 | success: !!result[0]?.affectedRows, 39 | message: "更新成功", 40 | }; 41 | } catch (error) { 42 | console.log(error); 43 | ctx.body = { 44 | success: false, 45 | error: error.message, 46 | message: "更新失败", 47 | }; 48 | } 49 | }); 50 | 51 | module.exports = router; 52 | -------------------------------------------------------------------------------- /项目代码/server/src/routes/address/create.js: -------------------------------------------------------------------------------- 1 | const Router = require("koa-router"); 2 | const db = require("@/db"); 3 | const auth = require("@/modules/auth"); 4 | const router = new Router(); 5 | const id = require("@/utils/id"); 6 | 7 | // 创建用户地址接口 8 | router.post("/address", auth(), async ctx => { 9 | try { 10 | // 获取用户ID,你的认证模块可能提供了用户信息 11 | const userId = ctx.id; 12 | 13 | // 从请求体中获取地址相关信息,根据实际情况修改字段名 14 | const { name, phone, address, isDefault } = ctx.request.body; 15 | 16 | // 如果新地址的 isDefault 为 true,先将用户其他地址的 isDefault 修改为 false 17 | if (isDefault) { 18 | await db.query(` 19 | UPDATE address 20 | SET isDefault = false 21 | WHERE user_id = ${userId} AND isDefault = true; 22 | `); 23 | } 24 | 25 | // 插入新地址信息 26 | const result = await db.query(` 27 | INSERT INTO address (id,user_id, name, phone, address, isDefault) 28 | VALUES (${id()},${userId}, '${name}', '${phone}', '${address}', ${isDefault ? 1 : 0}); 29 | `); 30 | 31 | ctx.body = { 32 | success: true, 33 | message: "用户地址创建成功", 34 | data: result, 35 | }; 36 | } catch (error) { 37 | console.error(error); 38 | ctx.body = { 39 | success: false, 40 | message: "创建用户地址失败", 41 | error: error.message, 42 | }; 43 | } 44 | }); 45 | 46 | module.exports = router; 47 | -------------------------------------------------------------------------------- /项目代码/admin/src/layouts/store.vue: -------------------------------------------------------------------------------- 1 | 13 | 54 | -------------------------------------------------------------------------------- /项目代码/admin/src/layouts/admin.vue: -------------------------------------------------------------------------------- 1 | 13 | 55 | -------------------------------------------------------------------------------- /项目代码/server/src/routes/cart/list.js: -------------------------------------------------------------------------------- 1 | const Router = require("koa-router"); 2 | const db = require("@/db"); 3 | const router = new Router(); 4 | const auth = require("@/modules/auth"); 5 | const qs = require("qs"); 6 | 7 | router.get("/cart", auth(), async ctx => { 8 | const id = qs.parse(ctx.request.query)?.id; //数组 9 | 10 | try { 11 | const userId = ctx.id; 12 | let query = `SELECT 13 | c.id AS cart_id, 14 | c.count, 15 | cm.id AS commodity_id, 16 | cm.name AS commodity_name, 17 | cm.cover AS commodity_cover, 18 | cm.inventory AS commodity_inventory, 19 | cm.price AS commodity_price, 20 | cm.description AS commodity_description 21 | FROM 22 | cart c 23 | INNER JOIN 24 | commodity cm ON c.commodity_id = cm.id 25 | WHERE 26 | c.user_id = ?`; 27 | 28 | const params = [userId]; 29 | if (id && Array.isArray(id) && id.length > 0) { 30 | query += ` AND c.id IN (?)`; 31 | params.push(id); 32 | } 33 | 34 | query += " ORDER BY c.id DESC"; 35 | 36 | const [result] = await db.query(query, params); 37 | 38 | ctx.body = { 39 | success: true, 40 | data: result, 41 | }; 42 | } catch (error) { 43 | ctx.body = { 44 | success: false, 45 | message: "查询错误", 46 | error: error.message, 47 | }; 48 | } 49 | }); 50 | 51 | module.exports = router; 52 | -------------------------------------------------------------------------------- /项目代码/server/src/routes/collection/list.js: -------------------------------------------------------------------------------- 1 | const Router = require("koa-router"); 2 | const db = require("@/db"); 3 | const auth = require("@/modules/auth"); 4 | const router = new Router(); 5 | 6 | router.get("/collection", auth(), async ctx => { 7 | try { 8 | const userId = ctx.id; 9 | 10 | let [store] = await db.query( 11 | ` 12 | SELECT c.*, 13 | s.name AS store_name, 14 | s.cover AS store_cover, 15 | s.email AS store_email 16 | FROM collection c 17 | LEFT JOIN store s ON c.item_id = s.id 18 | WHERE c.user_id = ? and c.type='store'; 19 | `, 20 | [userId] 21 | ); 22 | let [commodity] = await db.query( 23 | ` 24 | SELECT c.*, 25 | com.name AS commodity_name, 26 | com.cover AS commodity_cover, 27 | com.price AS commodity_price, 28 | com.description AS commodity_description 29 | FROM collection c 30 | LEFT JOIN commodity com ON c.item_id = com.id 31 | WHERE c.user_id = ? and c.type='commodity' 32 | `, 33 | [userId] 34 | ); 35 | 36 | ctx.body = { 37 | success: true, 38 | data: [...store, ...commodity], 39 | }; 40 | } catch (error) { 41 | console.error(error); 42 | ctx.body = { 43 | success: false, 44 | message: "查询失败", 45 | error: error.message, 46 | }; 47 | } 48 | }); 49 | 50 | module.exports = router; 51 | -------------------------------------------------------------------------------- /项目代码/admin/src/components/store/Navigate.vue: -------------------------------------------------------------------------------- 1 | 35 | 49 | 50 | -------------------------------------------------------------------------------- /项目代码/server/src/routes/comment/create.js: -------------------------------------------------------------------------------- 1 | const Router = require("koa-router"); 2 | const db = require("@/db"); 3 | const router = new Router(); 4 | const id = require("@/utils/id"); 5 | const auth = require("@/modules/auth"); 6 | 7 | router.post("/comment/:orderId", auth(), async ctx => { 8 | try { 9 | const orderId = ctx.params.orderId; 10 | const { comment } = ctx.request.body; 11 | 12 | const [orderResult] = await db.query(`SELECT * FROM orders WHERE id = ? and is_reviewed=0`, [ 13 | orderId, 14 | ]); 15 | if (orderResult.length === 0) { 16 | ctx.body = { 17 | success: false, 18 | message: "订单不存在", 19 | }; 20 | return; 21 | } 22 | 23 | await Promise.all( 24 | comment.map(async item => { 25 | await db.query( 26 | `INSERT INTO comment (id,content, user_id, commodity_id, create_time, score,order_id) VALUES (?,?, ?, ?, NOW(), ?,?)`, 27 | [id(), item.message || "", ctx.id, item.commodity_id, item.score, orderId] 28 | ); 29 | }) 30 | ); 31 | 32 | ctx.body = { 33 | success: true, 34 | message: "评论添加成功", 35 | }; 36 | 37 | await db.query(`UPDATE orders SET is_reviewed = true WHERE id = ?`, [orderId]); 38 | } catch (error) { 39 | console.log(error); 40 | ctx.body = { 41 | success: false, 42 | message: "添加评论失败", 43 | error: error.message, 44 | }; 45 | } 46 | }); 47 | 48 | module.exports = router; 49 | -------------------------------------------------------------------------------- /项目代码/admin/src/pages/admin/deliveryman/[id].vue: -------------------------------------------------------------------------------- 1 | 19 | 20 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /项目代码/admin/vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from "vite"; 2 | import vue from "@vitejs/plugin-vue"; 3 | import path from "path"; 4 | import Pages from "vite-plugin-pages"; 5 | import Layouts from "vite-plugin-vue-layouts"; 6 | import AutoImport from "unplugin-auto-import/vite"; 7 | 8 | export default defineConfig({ 9 | resolve: { 10 | alias: { 11 | "@": path.resolve(__dirname, "./src"), 12 | }, 13 | extensions: [".js", ".vue"], 14 | }, 15 | base: "./", 16 | server: { 17 | proxy: {}, 18 | port: 8080, 19 | }, 20 | plugins: [ 21 | vue(), 22 | Pages({ 23 | dirs: "src/pages", 24 | extensions: ["vue"], 25 | extendRoute(route) { 26 | if (route.path.startsWith("/admin") && !route.path.includes("sign")) { 27 | route.meta = Object.assign(route.meta || {}, { layout: "admin" }); 28 | } 29 | 30 | if (route.path.startsWith("/store") && !route.path.includes("sign")) { 31 | route.meta = Object.assign(route.meta || {}, { layout: "store" }); 32 | } 33 | if (route.path.startsWith("/deliveryman") && !route.path.includes("sign")) { 34 | route.meta = Object.assign(route.meta || {}, { layout: "deliveryman" }); 35 | } 36 | return route; 37 | }, 38 | }), 39 | Layouts(), 40 | AutoImport({ 41 | imports: ["vue", "vue-router", "vuex"], 42 | dts: "src/auto-import.d.ts", 43 | // include: [/\.[tj]sx?$/, /\.vue$/, /\.vue\?vue/], 44 | }), 45 | ], 46 | }); 47 | -------------------------------------------------------------------------------- /项目代码/admin/src/pages/client/user/index.vue: -------------------------------------------------------------------------------- 1 | 23 | 40 | 41 | 42 | { 43 | "meta": { 44 | "layout": "client" 45 | } 46 | } 47 | 48 | -------------------------------------------------------------------------------- /项目代码/server/src/routes/commodity/recommend.js: -------------------------------------------------------------------------------- 1 | const Router = require("koa-router"); 2 | const db = require("@/db"); 3 | const auth = require("@/modules/auth"); 4 | const router = new Router(); 5 | 6 | router.get("/commodity/recommend/list", auth(), async ctx => { 7 | try { 8 | const [result] = await db.query( 9 | `SELECT 10 | c.*, 11 | ( 12 | SELECT COUNT(o.id) 13 | FROM orders o 14 | WHERE JSON_CONTAINS(o.commodity_data, JSON_OBJECT('id', c.id), "$") 15 | ) AS orderCount, 16 | ( 17 | SELECT MAX(o.create_time) 18 | FROM orders o 19 | WHERE JSON_CONTAINS(o.commodity_data, JSON_OBJECT('id', c.id), "$") 20 | ) AS lastOrderTime, 21 | COUNT(co.id) AS commentCount, 22 | MAX(co.create_time) AS lastCommentTime 23 | FROM 24 | commodity c 25 | LEFT JOIN 26 | orders o ON JSON_CONTAINS(o.commodity_data, JSON_OBJECT('id', c.id), "$") 27 | LEFT JOIN 28 | comment co ON c.id = co.commodity_id 29 | WHERE 30 | c.state = 1 AND c.inventory > 0 31 | GROUP BY 32 | c.id 33 | ORDER BY 34 | c.create_time DESC, orderCount DESC, lastOrderTime DESC, commentCount DESC, lastCommentTime DESC; 35 | ` 36 | ); 37 | 38 | ctx.body = { 39 | success: true, 40 | data: result, 41 | }; 42 | } catch (error) { 43 | console.error(error); 44 | ctx.body = { 45 | success: false, 46 | message: "查询失败", 47 | error: error.message, 48 | }; 49 | } 50 | }); 51 | 52 | module.exports = router; 53 | 54 | module.exports = router; 55 | -------------------------------------------------------------------------------- /项目代码/server/src/routes/order/task/list.js: -------------------------------------------------------------------------------- 1 | const Router = require("koa-router"); 2 | const db = require("@/db"); 3 | const router = new Router(); 4 | const auth = require("@/modules/auth"); 5 | 6 | // 当前用户的任务列表 7 | router.get("/deliveryman/list/task/user", auth(), async ctx => { 8 | try { 9 | const [orders] = await db.query(`SELECT * FROM orders WHERE deliveryman_id=?;`, [ctx.id]); 10 | 11 | for (let index = 0; index < orders.length; index++) { 12 | const item = orders[index]; 13 | // 绑定店铺信息 14 | for (let index = 0; index < item.commodity_data.length; index++) { 15 | const commodity = item.commodity_data[index]; 16 | const [store] = await db.query(`SELECT * FROM store WHERE id=?;`, [commodity.store_id]); 17 | delete store[0].password; 18 | item.commodity_data[index].store_data = store[0]; 19 | } 20 | // 绑定用户信息 21 | const [user] = await db.query(`SELECT * FROM user WHERE id=?;`, [item.user_id]); 22 | delete user[0].password; 23 | orders[index].user_data = user[0]; 24 | //地址信息 25 | const [address] = await db.query(`SELECT * FROM address WHERE id=?;`, [item.address_id]); 26 | orders[index].address_data = address[0]; 27 | } 28 | 29 | ctx.body = { 30 | success: true, 31 | data: orders, 32 | }; 33 | } catch (error) { 34 | console.error(error); 35 | ctx.body = { 36 | success: false, 37 | message: "查询订单列表失败", 38 | error: error.message, 39 | }; 40 | } 41 | }); 42 | 43 | module.exports = router; 44 | -------------------------------------------------------------------------------- /项目代码/server/src/routes/deliveryman/data.js: -------------------------------------------------------------------------------- 1 | const Router = require("koa-router"); 2 | const db = require("@/db"); 3 | const router = new Router(); 4 | const auth = require("@/modules/auth"); 5 | 6 | router.get("/deliveryman/orders/completion", auth(), async ctx => { 7 | try { 8 | // 获取配送人员 ID 9 | const deliverymanId = ctx.id; 10 | 11 | // 查询总订单数 12 | const totalOrdersQuery = ` 13 | SELECT COUNT(*) AS totalOrders 14 | FROM orders 15 | WHERE deliveryman_id = ?; 16 | `; 17 | const [totalOrdersResult] = await db.query(totalOrdersQuery, [deliverymanId]); 18 | const totalOrders = totalOrdersResult[0].totalOrders; 19 | 20 | // 查询已完成订单数 21 | const completedOrdersQuery = ` 22 | SELECT COUNT(*) AS completedOrders 23 | FROM orders 24 | WHERE deliveryman_id = ? AND state = 2; 25 | `; 26 | const [completedOrdersResult] = await db.query(completedOrdersQuery, [deliverymanId]); 27 | const completedOrders = completedOrdersResult[0].completedOrders; 28 | 29 | // 计算未完成订单数 30 | const pendingOrders = totalOrders - completedOrders; 31 | 32 | ctx.body = { 33 | success: true, 34 | data: { 35 | totalOrders: totalOrders, 36 | completedOrders: completedOrders, 37 | pendingOrders: pendingOrders, 38 | }, 39 | }; 40 | } catch (error) { 41 | console.error(error); 42 | ctx.body = { 43 | success: false, 44 | message: "查询订单完成数量失败", 45 | error: error.message, 46 | }; 47 | } 48 | }); 49 | 50 | module.exports = router; 51 | -------------------------------------------------------------------------------- /项目代码/server/src/routes/order/task/task.js: -------------------------------------------------------------------------------- 1 | const Router = require("koa-router"); 2 | const db = require("@/db"); 3 | const router = new Router(); 4 | const auth = require("@/modules/auth"); 5 | 6 | router.get("/deliveryman/list/task", auth(), async ctx => { 7 | try { 8 | const [orders] = await db.query( 9 | `SELECT * FROM orders WHERE state = 0 and deliveryman_id is null;` 10 | ); 11 | 12 | for (let index = 0; index < orders.length; index++) { 13 | const item = orders[index]; 14 | // 绑定店铺信息 15 | for (let index = 0; index < item.commodity_data.length; index++) { 16 | const commodity = item.commodity_data[index]; 17 | const [store] = await db.query(`SELECT * FROM store WHERE id=?;`, [commodity.store_id]); 18 | delete store[0].password; 19 | item.commodity_data[index].store_data = store[0]; 20 | } 21 | // 绑定用户信息 22 | const [user] = await db.query(`SELECT * FROM user WHERE id=?;`, [item.user_id]); 23 | delete user[0].password; 24 | orders[index].user_data = user[0]; 25 | //地址信息 26 | const [address] = await db.query(`SELECT * FROM address WHERE id=?;`, [item.address_id]); 27 | orders[index].address_data = address[0]; 28 | } 29 | 30 | ctx.body = { 31 | success: true, 32 | data: orders, 33 | }; 34 | } catch (error) { 35 | console.error(error); 36 | ctx.body = { 37 | success: false, 38 | message: "查询订单列表失败", 39 | error: error.message, 40 | }; 41 | } 42 | }); 43 | 44 | module.exports = router; 45 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 基于 Node.js 的“大维”体育商城的设计与实现 2 | 3 | ## 系统说明 4 | 5 | **系统包含论文 1 篇付费提供** 6 | 7 | ## 功能 8 | 9 | 参照文件夹中的答辩 PPT、开题报告、和毕设手册 10 | 系统内四个权限:店家、用户、配送人员、管理员共 15 个数据表。可以使用 webscoket 在线聊天,系统可以为其他商城,只需替换上传内容即可。无需限制为体育商城。 11 | 可以修改为其他商品的商城。 12 | 13 | ![演示视频](./项目代码/图片3.png "功能") 14 | 15 | [演示视频](https://disk.blogweb.cn/video/%E5%9F%BA%E4%BA%8ENode.js%E7%9A%84%E2%80%9C%E5%A4%A7%E7%BB%B4%E2%80%9D%E4%BD%93%E8%82%B2%E5%95%86%E5%9F%8E%E7%9A%84%E8%AE%BE%E8%AE%A1%E4%B8%8E%E5%AE%9E%E7%8E%B0.mp4 "演示视频") 16 | 17 | ## 相关技术 18 | 19 | 前端:Vue.js、Vite、Tailwind CSS、Element Plus、Vant UI 20 | 服务端:Koa2、socket.io 21 | 数据库:MySQL 22 | 23 | ## 其他版本 24 | 25 | 付费提供部分其他毕设程序、论文的成品,同时可以定制和讲解毕设,联系下方联系方式即可 26 | 27 | 可联系 QQ:1974109227 微信:webzhizhuo 28 | 29 | 可以开发其他项目、毕业设计、毕业论文等 30 | 31 |
32 | QQ 33 | 微信 34 |
35 | 36 | ### 启动 37 | 38 | #### 环境 39 | 40 | 1. Node.js 20+ 41 | 2. MySQL 8.x 42 | 43 | #### 启动步骤 44 | 45 | 1. 如果项目代码中有 start.bat 则双击执行 46 | 47 | 否则运行以下命令安装 yarn 以及部分插件同时进行换源 48 | 49 | ```bash 50 | npm config set registry https://registry.npmmirror.com/&&npm i yarn vite nodemon -g&&yarn config set registry https://registry.npmmirror.com/ 51 | ``` 52 | 53 | 2. 如果项目代码中有 install.bat 则双击运行否则 54 | 55 | 通常 admin/font 是前端,server/api 是服务端,cd 进入前端或者服务器文件夹,文件夹名称并不固定 56 | 57 | ```bash 58 | cd server 59 | 60 | yarn 61 | ``` 62 | 63 | ```bash 64 | cd admin 65 | 66 | yarn 67 | ``` 68 | 69 | 3. 如果有 dev.bat 则双击运行,否则 cd 进入文件夹都使用`yarn dev`运行 70 | -------------------------------------------------------------------------------- /项目代码/server/src/routes/cart/create.js: -------------------------------------------------------------------------------- 1 | const Router = require("koa-router"); 2 | const db = require("@/db"); 3 | const auth = require("@/modules/auth"); 4 | const id = require("@/utils/id"); 5 | const router = new Router(); 6 | 7 | // 加入购物车接口 8 | router.post("/cart", auth(), async ctx => { 9 | try { 10 | const user_id = ctx.id; // 从认证中间件中获取用户ID 11 | const commodity_id = ctx.request.body.commodity_id; 12 | 13 | // 先检查购物车中是否已经存在该商品,存在则更新数量,否则插入新记录 14 | const [existingCart] = await db.query( 15 | ` 16 | SELECT * FROM cart WHERE user_id = ? AND commodity_id = ?; 17 | `, 18 | [user_id, commodity_id] 19 | ); 20 | 21 | let existingCartItem = existingCart[0]; 22 | 23 | if (existingCartItem) { 24 | // 如果购物车已存在该商品,则更新数量 25 | await db.query( 26 | ` 27 | UPDATE cart SET count = ? WHERE user_id = ? AND commodity_id = ?; 28 | `, 29 | [existingCartItem.count + 1, user_id, commodity_id] 30 | ); 31 | } else { 32 | // 如果购物车中不存在该商品,则插入新记录 33 | await db.query( 34 | ` 35 | INSERT INTO cart (id,user_id, commodity_id, count, create_time) 36 | VALUES (?,?, ?, 1, NOW()); 37 | `, 38 | [id(), user_id, commodity_id] 39 | ); 40 | } 41 | 42 | ctx.body = { 43 | success: true, 44 | message: "商品成功加入购物车", 45 | }; 46 | } catch (error) { 47 | console.error(error); 48 | ctx.body = { 49 | success: false, 50 | message: "加入购物车失败", 51 | error: error.message, 52 | }; 53 | } 54 | }); 55 | 56 | module.exports = router; 57 | -------------------------------------------------------------------------------- /项目代码/server/src/routes/cart/update.js: -------------------------------------------------------------------------------- 1 | const Router = require("koa-router"); 2 | const db = require("@/db"); 3 | const router = new Router(); 4 | 5 | router.put("/cart/:id", async ctx => { 6 | try { 7 | const cartId = ctx.params.id; 8 | const { type } = ctx.request.body; 9 | 10 | if (type !== "add" && type !== "less") { 11 | ctx.body = { 12 | success: false, 13 | message: "未知的操作类型", 14 | }; 15 | return; 16 | } 17 | 18 | let updateQuery = ""; 19 | let affectedRows = 0; 20 | 21 | if (type === "add") { 22 | updateQuery = "UPDATE cart SET count = count + 1 WHERE id = ?"; 23 | } else if (type === "less") { 24 | const [cartResult] = await db.query("SELECT count FROM cart WHERE id = ?", [cartId]); 25 | const currentCount = cartResult[0].count; 26 | 27 | if (currentCount > 1) { 28 | updateQuery = "UPDATE cart SET count = count - 1 WHERE id = ?"; 29 | } else { 30 | updateQuery = "DELETE FROM cart WHERE id = ?"; 31 | } 32 | } 33 | 34 | const [result] = await db.query(updateQuery, [cartId]); 35 | affectedRows = result.affectedRows; 36 | 37 | if (affectedRows === 0) { 38 | ctx.body = { 39 | success: false, 40 | message: "购物车商品未找到", 41 | }; 42 | return; 43 | } 44 | 45 | ctx.body = { 46 | success: true, 47 | message: "购物车商品已成功更新", 48 | }; 49 | } catch (error) { 50 | ctx.body = { 51 | success: false, 52 | message: "更新购物车商品时出错", 53 | error: error.message, 54 | }; 55 | } 56 | }); 57 | 58 | module.exports = router; 59 | -------------------------------------------------------------------------------- /项目代码/server/src/routes/commodity/search.js: -------------------------------------------------------------------------------- 1 | const Router = require("koa-router"); 2 | const db = require("@/db"); 3 | const auth = require("@/modules/auth"); 4 | const router = new Router(); 5 | 6 | router.get("/search", auth(), async ctx => { 7 | try { 8 | const { keyword } = ctx.query; 9 | 10 | const [result] = await db.query( 11 | ` 12 | SELECT 13 | c.*, 14 | ( 15 | SELECT COUNT(o.id) 16 | FROM orders o 17 | WHERE JSON_CONTAINS(o.commodity_data, JSON_OBJECT('id', c.id), "$") 18 | ) AS orderCount, 19 | ( 20 | SELECT MAX(o.create_time) 21 | FROM orders o 22 | WHERE JSON_CONTAINS(o.commodity_data, JSON_OBJECT('id', c.id), "$") 23 | ) AS lastOrderTime, 24 | COUNT(co.id) AS commentCount, 25 | MAX(co.create_time) AS lastCommentTime 26 | FROM 27 | commodity c 28 | LEFT JOIN 29 | orders o ON JSON_CONTAINS(o.commodity_data, JSON_OBJECT('id', c.id), "$") 30 | LEFT JOIN 31 | comment co ON c.id = co.commodity_id 32 | WHERE 33 | c.state = 1 AND c.inventory > 0 AND (c.description LIKE ? OR c.name LIKE ?) 34 | GROUP BY 35 | c.id 36 | ORDER BY 37 | c.create_time DESC, orderCount DESC, lastOrderTime DESC, commentCount DESC, lastCommentTime DESC; 38 | 39 | `, 40 | [`%${keyword + ""}%`, `%${keyword + ""}%`] 41 | ); 42 | ctx.body = { 43 | success: true, 44 | data: result, 45 | }; 46 | } catch (error) { 47 | console.error(error); 48 | ctx.body = { 49 | success: false, 50 | message: "查询失败", 51 | error: error.message, 52 | }; 53 | } 54 | }); 55 | 56 | module.exports = router; -------------------------------------------------------------------------------- /项目代码/server/src/routes/tools/data.js: -------------------------------------------------------------------------------- 1 | const Router = require("koa-router"); 2 | const db = require("@/db"); 3 | 4 | let router = new Router(); 5 | 6 | router.get("/statistics", async ctx => { 7 | try { 8 | const [totalStores] = await db.query("SELECT COUNT(*) AS totalStores FROM store"); 9 | const [totalUsers] = await db.query("SELECT COUNT(*) AS totalUsers FROM user"); 10 | const [totalCommodities] = await db.query("SELECT COUNT(*) AS totalCommodities FROM commodity"); 11 | const [totalOrders] = await db.query("SELECT COUNT(*) AS totalOrders FROM orders"); 12 | const [totalDeliverymen] = await db.query( 13 | "SELECT COUNT(*) AS totalDeliverymen FROM deliveryman" 14 | ); 15 | 16 | const [ordersLast7Days] = await db.query(` 17 | SELECT 18 | DATE(create_time) AS orderDate, 19 | COUNT(*) AS orderCount 20 | FROM 21 | orders 22 | WHERE 23 | create_time >= NOW() - INTERVAL 7 DAY 24 | GROUP BY 25 | orderDate 26 | ORDER BY 27 | orderDate 28 | `); 29 | 30 | ctx.body = { 31 | success: true, 32 | data: { 33 | totalStores: totalStores[0].totalStores, 34 | totalUsers: totalUsers[0].totalUsers, 35 | totalCommodities: totalCommodities[0].totalCommodities, 36 | totalOrders: totalOrders[0].totalOrders, 37 | totalDeliverymen: totalDeliverymen[0].totalDeliverymen, 38 | ordersLast7Days, 39 | }, 40 | }; 41 | } catch (error) { 42 | ctx.body = { 43 | success: false, 44 | message: "查询统计信息失败", 45 | error: error.message, 46 | }; 47 | } 48 | }); 49 | 50 | module.exports = router; 51 | -------------------------------------------------------------------------------- /项目代码/server/src/routes/message/create.js: -------------------------------------------------------------------------------- 1 | const Router = require("koa-router"); 2 | const db = require("@/db"); // Assuming your database module is in './db' 3 | const id = require("@/utils/id"); 4 | const io = require("@/socket/index"); 5 | const auth = require("@/modules/auth"); 6 | 7 | const router = new Router(); 8 | 9 | router.post("/message", auth(), async ctx => { 10 | try { 11 | const { user_id, store_id, content, picture } = ctx.request.body; 12 | 13 | let _id = id(); 14 | const result = await db.query( 15 | "INSERT INTO message (id,user_id, store_id, content, picture,sender, create_time) VALUES (?,?, ?, ?, ?,?, NOW())", 16 | [ 17 | _id, 18 | ctx.auth == "user" ? ctx.id : user_id, 19 | ctx.auth == "store" ? ctx.id : store_id, 20 | picture ? "" : content, 21 | picture || null, 22 | ctx.auth, 23 | ] 24 | ); 25 | 26 | const [insertedMessage] = await db.query( 27 | `SELECT m.*, u.name AS user_name, s.name AS store_name,s.cover AS store_cover,u.avatar AS user_avatar 28 | FROM message m 29 | LEFT JOIN user u ON m.user_id = u.id 30 | LEFT JOIN store s ON m.store_id = s.id 31 | WHERE m.id = ?`, 32 | [_id] 33 | ); 34 | 35 | ctx.body = { success: true, message: "发送成功", data: insertedMessage[0] }; 36 | if (ctx.auth == "user") { 37 | io.to(store_id).emit("message", insertedMessage[0]); 38 | } else { 39 | io.to(user_id).emit("message", insertedMessage[0]); 40 | } 41 | } catch (error) { 42 | console.error(error); 43 | ctx.body = { success: false, message: "发送失败" }; 44 | } 45 | }); 46 | 47 | module.exports = router; 48 | -------------------------------------------------------------------------------- /项目代码/server/src/routes/user/update.js: -------------------------------------------------------------------------------- 1 | const Router = require("koa-router"); 2 | const db = require("@/db"); 3 | const auth = require("@/modules/auth"); 4 | const router = new Router(); 5 | 6 | router.put("/user", auth(), async ctx => { 7 | try { 8 | const { name, email, avatar, password } = ctx.request.body; 9 | 10 | // 构建 SQL 语句 11 | let updateFields = []; 12 | let values = []; 13 | 14 | if (name) { 15 | updateFields.push("name = ?"); 16 | values.push(name); 17 | } 18 | 19 | if (email) { 20 | updateFields.push("email = ?"); 21 | values.push(email); 22 | } 23 | 24 | if (avatar) { 25 | updateFields.push("avatar = ?"); 26 | values.push(avatar); 27 | } 28 | 29 | if (password) { 30 | updateFields.push("password = ?"); 31 | values.push(password); 32 | } 33 | 34 | if (updateFields.length === 0) { 35 | ctx.body = { 36 | success: false, 37 | message: "未提供任何要修改的字段", 38 | }; 39 | return; 40 | } 41 | 42 | const userId = ctx.id; 43 | 44 | const result = await db.query(`UPDATE user SET ${updateFields.join(", ")} WHERE id = ?`, [ 45 | ...values, 46 | userId, 47 | ]); 48 | 49 | if (result[0]?.affectedRows > 0) { 50 | ctx.body = { 51 | success: true, 52 | message: "用户信息修改成功", 53 | }; 54 | } else { 55 | ctx.body = { 56 | success: false, 57 | message: "未找到匹配的用户记录或无权限修改", 58 | }; 59 | } 60 | } catch (error) { 61 | ctx.body = { 62 | success: false, 63 | message: "用户信息修改失败", 64 | error: error.message, 65 | }; 66 | } 67 | }); 68 | 69 | module.exports = router; 70 | -------------------------------------------------------------------------------- /项目代码/server/src/socket/index.js: -------------------------------------------------------------------------------- 1 | const { server } = require("@/index"); 2 | const { Server } = require("socket.io"); 3 | const Cookie = require("cookie"); 4 | const jwt = require("jsonwebtoken"); 5 | const db = require("@/db"); // 假设你的数据库操作模块是在 './db' 中 6 | 7 | const io = new Server(server, { 8 | path: "/online-message", 9 | cors: "*", 10 | }); 11 | 12 | io.use((socket, next) => { 13 | let cookie = Cookie.parse(socket.handshake.headers.cookie || ""); 14 | let token = cookie.token || ""; 15 | jwt.verify(token, "key", async function (err, decoded) { 16 | if (err) { 17 | } else { 18 | socket.id = decoded.id; 19 | next(); 20 | } 21 | }); 22 | next(); 23 | }); 24 | // 监听连接事件 25 | io.on("connection", socket => { 26 | socket.on("chat message", async msg => { 27 | console.log("message: " + msg); 28 | 29 | try { 30 | const result = await db.query( 31 | "INSERT INTO message (user_id, store_id, content, create_time) VALUES (?, ?, ?, NOW())", 32 | [msg.user_id, msg.store_id, msg.content] 33 | ); 34 | 35 | // 获取接收消息的用户的 socket.id 36 | const receiverSocketId = await db.query("SELECT socket_id FROM user WHERE id = ?", [ 37 | msg.receiver_user_id, 38 | ]); 39 | 40 | // 向发送消息的客户端发送确认消息 41 | io.to(socket.id).emit("chat message", "Message sent successfully"); 42 | 43 | // 向接收消息的用户发送实时消息提醒 44 | io.to(receiverSocketId).emit("message notification", "You have a new message"); 45 | } catch (error) { 46 | console.error(error); 47 | // 向发送消息的客户端发送错误消息 48 | io.to(socket.id).emit("chat message", "Failed to send message"); 49 | } 50 | }); 51 | 52 | // 监听断开连接事件 53 | socket.on("disconnect", () => {}); 54 | }); 55 | module.exports = io; 56 | -------------------------------------------------------------------------------- /项目代码/server/src/routes/tools/order-search.js: -------------------------------------------------------------------------------- 1 | const Router = require("koa-router"); 2 | const db = require("@/db"); 3 | const router = new Router(); 4 | const auth = require("@/modules/auth"); 5 | 6 | router.get("/order/create/search", auth(), async ctx => { 7 | try { 8 | const { type, keyword } = ctx.query; 9 | 10 | if (!type || !keyword) { 11 | ctx.body = { 12 | success: false, 13 | message: "缺少必要的参数", 14 | }; 15 | return; 16 | } 17 | 18 | let result; 19 | 20 | if (type === "user") { 21 | // 搜索用户 22 | result = await searchUser(keyword); 23 | } else if (type === "commodity") { 24 | // 搜索商品 25 | result = await searchCommodity(keyword, ctx.id); 26 | } else { 27 | ctx.body = { 28 | success: false, 29 | message: "无效的搜索类型", 30 | }; 31 | return; 32 | } 33 | 34 | ctx.body = { 35 | success: true, 36 | data: result, 37 | }; 38 | } catch (error) { 39 | console.log(error); 40 | ctx.body = { 41 | success: false, 42 | message: "搜索失败", 43 | error: error.message, 44 | }; 45 | } 46 | }); 47 | 48 | // 搜索用户 49 | async function searchUser(keyword) { 50 | const result = await db.query( 51 | "SELECT id, name, email, avatar FROM user WHERE id = ? OR email LIKE ?", 52 | [keyword, `%${keyword}%`] 53 | ); 54 | return result[0]; 55 | } 56 | 57 | // 搜索商品 58 | async function searchCommodity(keyword, id) { 59 | const result = await db.query( 60 | "SELECT id, name, description,cover FROM commodity WHERE id = ? OR name LIKE ? OR description LIKE ? and store_id=? and state=1 and inventory>0", 61 | [keyword, `%${keyword}%`, `%${keyword}%`, id] 62 | ); 63 | return result[0]; 64 | } 65 | 66 | module.exports = router; 67 | -------------------------------------------------------------------------------- /项目代码/admin/src/components/Upload.vue: -------------------------------------------------------------------------------- 1 | 14 | 35 | 36 | 43 | 44 | 66 | -------------------------------------------------------------------------------- /项目代码/admin/src/pages/client/message/index.vue: -------------------------------------------------------------------------------- 1 | 38 | 49 | 50 | 51 | { 52 | "meta": { 53 | "layout": "client" 54 | } 55 | } 56 | 57 | -------------------------------------------------------------------------------- /项目代码/admin/src/components/admin/StoreForm.vue: -------------------------------------------------------------------------------- 1 | 24 | 56 | 57 | -------------------------------------------------------------------------------- /项目代码/server/src/routes/deliveryman/update-me.js: -------------------------------------------------------------------------------- 1 | const Router = require("koa-router"); 2 | const db = require("@/db"); 3 | const auth = require("@/modules/auth"); 4 | const router = new Router(); 5 | 6 | router.put(["/deliveryperson", "/deliveryperson/:id"], auth(), async ctx => { 7 | try { 8 | const { id, name, phone, avatar, password, sex } = ctx.request.body; 9 | 10 | // 构建 SQL 语句 11 | let updateFields = []; 12 | let values = []; 13 | 14 | if (name) { 15 | updateFields.push("name = ?"); 16 | values.push(name); 17 | } 18 | 19 | if (phone) { 20 | updateFields.push("phone = ?"); 21 | values.push(phone); 22 | } 23 | 24 | if (avatar) { 25 | updateFields.push("avatar = ?"); 26 | values.push(avatar); 27 | } 28 | 29 | if (password) { 30 | updateFields.push("password = ?"); 31 | values.push(password); 32 | } 33 | 34 | if (sex) { 35 | updateFields.push("sex = ?"); 36 | values.push(sex); 37 | } 38 | 39 | if (updateFields.length === 0) { 40 | ctx.body = { 41 | success: false, 42 | message: "未提供任何要修改的字段", 43 | }; 44 | return; 45 | } 46 | 47 | const query = `UPDATE deliveryman SET ${updateFields.join(", ")} WHERE id = ?`; 48 | values.push(id || ctx.id); 49 | 50 | const result = await db.query(query, values); 51 | 52 | if (result[0]?.affectedRows > 0) { 53 | ctx.body = { 54 | success: true, 55 | message: "配送人员信息修改成功", 56 | }; 57 | } else { 58 | ctx.body = { 59 | success: false, 60 | message: "未找到匹配的配送人员记录或无权限修改", 61 | }; 62 | } 63 | } catch (error) { 64 | ctx.body = { 65 | success: false, 66 | message: "配送人员信息修改失败", 67 | error: error.message, 68 | }; 69 | } 70 | }); 71 | 72 | module.exports = router; 73 | -------------------------------------------------------------------------------- /项目代码/admin/src/pages/client/index.vue: -------------------------------------------------------------------------------- 1 | 25 | 44 | 54 | 55 | { 56 | "meta": { 57 | "layout": "client" 58 | } 59 | } 60 | 61 | -------------------------------------------------------------------------------- /项目代码/server/src/routes/user/list.js: -------------------------------------------------------------------------------- 1 | const Router = require("koa-router"); 2 | const db = require("@/db"); 3 | const auth = require("@/modules/auth"); 4 | const router = new Router(); 5 | 6 | router.get("/user-list", auth(), async ctx => { 7 | try { 8 | const query = ` 9 | SELECT 10 | u.id AS user_id, 11 | u.name AS user_name, 12 | u.email AS user_email, 13 | u.avatar AS user_avatar, 14 | o.id AS order_id, 15 | o.create_time AS order_create_time, 16 | o.notes AS order_notes, 17 | o.commodity_data AS commodity_data, 18 | o.payment_method AS order_payment_method 19 | FROM 20 | user u 21 | LEFT JOIN 22 | orders o ON u.id = o.user_id 23 | ORDER BY u.id, o.create_time DESC; 24 | `; 25 | 26 | const [result] = await db.query(query); 27 | 28 | const userList = []; 29 | let currentUser = null; 30 | 31 | for (const row of result) { 32 | if (!currentUser || currentUser.id !== row.user_id) { 33 | // 新的用户 34 | currentUser = { 35 | id: row.user_id, 36 | name: row.user_name, 37 | email: row.user_email, 38 | avatar: row.user_avatar, 39 | orders: [], 40 | }; 41 | userList.push(currentUser); 42 | } 43 | 44 | if (row.order_id) { 45 | // 用户的订单 46 | const order = { 47 | id: row.order_id, 48 | create_time: row.order_create_time, 49 | notes: row.order_notes, 50 | commodity_data: row.commodity_data, 51 | payment_method: row.order_payment_method, 52 | }; 53 | currentUser.orders.push(order); 54 | } 55 | } 56 | 57 | ctx.body = { 58 | success: true, 59 | data: userList, 60 | }; 61 | } catch (error) { 62 | console.error(error); 63 | ctx.body = { 64 | success: false, 65 | message: "查询用户列表失败", 66 | error: error.message, 67 | }; 68 | } 69 | }); 70 | 71 | module.exports = router; 72 | -------------------------------------------------------------------------------- /项目代码/admin/src/pages/deliveryman/sign.vue: -------------------------------------------------------------------------------- 1 | 36 | 64 | 65 | -------------------------------------------------------------------------------- /项目代码/admin/src/components/admin/Navigate.vue: -------------------------------------------------------------------------------- 1 | 54 | 70 | 71 | -------------------------------------------------------------------------------- /项目代码/admin/src/components/MultipleUpload.vue: -------------------------------------------------------------------------------- 1 | 20 | 72 | 79 | -------------------------------------------------------------------------------- /项目代码/admin/src/components/admin/Deliveryman.vue: -------------------------------------------------------------------------------- 1 | 30 | 31 | 71 | 72 | 73 | -------------------------------------------------------------------------------- /项目代码/admin/src/components/user/List.vue: -------------------------------------------------------------------------------- 1 | 47 | 70 | 71 | -------------------------------------------------------------------------------- /项目代码/admin/src/pages/admin/password/index.vue: -------------------------------------------------------------------------------- 1 | 26 | 27 | 78 | -------------------------------------------------------------------------------- /项目代码/admin/src/pages/client/address/[id].vue: -------------------------------------------------------------------------------- 1 | 23 | 77 | 78 | 79 | { 80 | "meta": { 81 | "layout": "client-empty" 82 | } 83 | } 84 | 85 | -------------------------------------------------------------------------------- /项目代码/admin/src/pages/admin/deliveryman/list.vue: -------------------------------------------------------------------------------- 1 | 46 | 66 | 67 | -------------------------------------------------------------------------------- /项目代码/server/src/routes/notice/list.js: -------------------------------------------------------------------------------- 1 | const Router = require("koa-router"); 2 | const db = require("@/db"); 3 | const auth = require("@/modules/auth"); 4 | const router = new Router(); 5 | 6 | router.get("/notice", auth(), async ctx => { 7 | try { 8 | const { auth, id } = ctx; 9 | 10 | let query = ` 11 | SELECT 12 | n.id, n.title, n.target, n.content, n.isTop, n.create_time 13 | FROM 14 | notice n 15 | WHERE`; 16 | 17 | if (auth === "admin") { 18 | query += ` 1=1`; // 查询全部 19 | query += ` ORDER BY n.create_time DESC`; 20 | } else if (auth === "store") { 21 | query += ` (JSON_CONTAINS(n.target, '${id}') OR JSON_LENGTH(n.target) = 0)`; 22 | query += ` ORDER BY n.isTop DESC, n.create_time DESC`; 23 | } 24 | 25 | const [notices] = await db.query(query); 26 | 27 | // 管理员查询时。插入通知的store列表信息 28 | if (auth == "admin") { 29 | const storeIds = notices.reduce((ids, notice) => { 30 | return ids.concat(notice.target); 31 | }, []); 32 | 33 | if (storeIds.length > 0) { 34 | // 查询 store 信息 35 | const [stores] = await db.query( 36 | `SELECT id, name, cover FROM store WHERE id IN (${storeIds.join(",")})` 37 | ); 38 | 39 | // 将 store 信息插入到通知列表中的 store_list 字段 40 | notices.forEach(notice => { 41 | notice.store_list = stores.filter(store => notice.target.includes(store.id)); 42 | }); 43 | } 44 | } 45 | // store查询时判断每条信息是否被查询并且排序 46 | if (auth == "store") { 47 | for (let index = 0; index < notices.length; index++) { 48 | const item = notices[index]; 49 | const [exist] = await db.query( 50 | `select * from notice_history where store_id=? and notice_id=?;`, 51 | [ctx.id, item.id] 52 | ); 53 | notices[index].isRead = !!exist.length; 54 | } 55 | // 排序 56 | notices.sort((a, b) => { 57 | // 首先按照isTop降序排列 58 | if (b.isTop - a.isTop !== 0) { 59 | return b.isTop - a.isTop; 60 | } 61 | // 然后按照isRead升序排列 62 | return a.isRead - b.isRead; 63 | }); 64 | } 65 | ctx.body = { 66 | success: true, 67 | data: notices, 68 | }; 69 | } catch (error) { 70 | console.error(error); 71 | ctx.body = { 72 | success: false, 73 | message: "查询通知列表失败", 74 | error: error.message, 75 | }; 76 | } 77 | }); 78 | 79 | module.exports = router; 80 | -------------------------------------------------------------------------------- /项目代码/admin/src/pages/client/sign.vue: -------------------------------------------------------------------------------- 1 | 42 | 75 | 76 | -------------------------------------------------------------------------------- /项目代码/admin/src/pages/client/comment/[id].vue: -------------------------------------------------------------------------------- 1 | 44 | 80 | 81 | 82 | { 83 | "meta": { 84 | "layout": "client-empty" 85 | } 86 | } 87 | 88 | -------------------------------------------------------------------------------- /项目代码/admin/src/pages/admin/store/list.vue: -------------------------------------------------------------------------------- 1 | 61 | 80 | 81 | -------------------------------------------------------------------------------- /项目代码/admin/src/pages/admin/index.vue: -------------------------------------------------------------------------------- 1 | 32 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /项目代码/admin/src/components/store/ArticleEdit/Edit.vue: -------------------------------------------------------------------------------- 1 | 19 | 98 | 106 | -------------------------------------------------------------------------------- /项目代码/admin/src/components/admin/BannerDialog/index.vue: -------------------------------------------------------------------------------- 1 | 34 | 35 | 76 | 83 | 84 | 108 | -------------------------------------------------------------------------------- /项目代码/server/src/routes/order/create.js: -------------------------------------------------------------------------------- 1 | const Router = require("koa-router"); 2 | const db = require("@/db"); 3 | const id = require("@/utils/id"); 4 | const auth = require("@/modules/auth"); 5 | const router = new Router(); 6 | 7 | router.post("/order", auth(), async ctx => { 8 | try { 9 | const { commodity_data, payment, address_id, notes } = ctx.request.body; 10 | let user_id = ctx.id; 11 | // 查询商品信息 12 | const [commodityQuery] = await db.query("SELECT * FROM commodity WHERE id in (?)", [ 13 | commodity_data.map(item => item.id), 14 | ]); 15 | 16 | if (!commodityQuery?.length) { 17 | ctx.body = { 18 | success: false, 19 | message: "未找到对应的商品信息", 20 | }; 21 | return; 22 | } 23 | 24 | // if (commodityQuery.some(item => item.inventory <= 0)) { 25 | // ctx.body = { 26 | // success: false, 27 | // message: "部分商品库存不足", 28 | // }; 29 | // return; 30 | // } 31 | 32 | if ( 33 | commodityQuery.some( 34 | item => 35 | item.inventory < commodity_data.find(el => el.id == item.id).count || item.state != 1 36 | ) 37 | ) { 38 | ctx.body = { 39 | success: false, 40 | message: "部分商品库存不足", 41 | }; 42 | return; 43 | } 44 | 45 | // 构建订单数据 46 | const orderData = { 47 | id: id(), 48 | user_id: user_id, 49 | commodity_data: JSON.stringify( 50 | commodityQuery.map(item => { 51 | return { ...item, count: commodity_data.find(_item => _item.id == item.id).count || 1 }; 52 | }) 53 | ), 54 | payment_method: `${payment}:${id()}`, 55 | address_id: address_id, 56 | notes: notes, 57 | create_time: new Date(), 58 | }; 59 | 60 | // 插入订单到数据库 61 | const result = await db.query( 62 | "INSERT INTO orders (id, user_id, commodity_data, payment_method, notes,address_id, create_time) VALUES (?, ?, ?, ?, ?, ?, ?)", 63 | [ 64 | orderData.id, 65 | orderData.user_id, 66 | orderData.commodity_data, 67 | orderData.payment_method, 68 | orderData.notes, 69 | orderData.address_id, 70 | orderData.create_time, 71 | ] 72 | ); 73 | 74 | ctx.body = { 75 | success: !!result[0]?.affectedRows, 76 | message: "订单添加成功", 77 | }; 78 | 79 | // // 商品库存-1 80 | // db.query( 81 | // `UPDATE commodity 82 | // SET inventory = inventory - 1 83 | // WHERE id in (?); 84 | // `, 85 | // [commodity_data.map(item => item.id)] 86 | // ); 87 | 88 | // 商品库存-1 89 | for (let index = 0; index < commodity_data.length; index++) { 90 | const item = commodity_data[index]; 91 | db.query( 92 | `UPDATE commodity 93 | SET inventory = inventory - ${item.count} 94 | WHERE id=${item.id}; 95 | ` 96 | ); 97 | } 98 | 99 | // 如果是购物车商品就删除对应的购物车 100 | 101 | if (ctx.request.body.cart_id) { 102 | await db.query(`DELETE FROM cart WHERE id in (?)`, [ctx.request.body.cart_id]); 103 | } 104 | } catch (error) { 105 | console.error(error); 106 | ctx.body = { 107 | success: false, 108 | message: "订单添加失败", 109 | error: error.message, 110 | }; 111 | } 112 | }); 113 | 114 | module.exports = router; 115 | -------------------------------------------------------------------------------- /项目代码/admin/src/pages/client/sign-up.vue: -------------------------------------------------------------------------------- 1 | 64 | 99 | 100 | -------------------------------------------------------------------------------- /项目代码/admin/src/pages/deliveryman/user.vue: -------------------------------------------------------------------------------- 1 | 26 | 105 | 106 | 107 | { 108 | "meta": { 109 | "layout": "client" 110 | } 111 | } 112 | 113 | -------------------------------------------------------------------------------- /项目代码/admin/src/pages/admin/user/index.vue: -------------------------------------------------------------------------------- 1 | 63 | 84 | 85 | -------------------------------------------------------------------------------- /项目代码/admin/src/pages/client/set/index.vue: -------------------------------------------------------------------------------- 1 | 61 | 106 | 107 | 108 | { 109 | "meta": { 110 | "layout": "client-empty" 111 | } 112 | } 113 | 114 | -------------------------------------------------------------------------------- /项目代码/admin/src/pages/admin/notice/create.vue: -------------------------------------------------------------------------------- 1 | 50 | 109 | 110 | -------------------------------------------------------------------------------- /项目代码/admin/src/pages/deliveryman/index copy.vue: -------------------------------------------------------------------------------- 1 | 60 | 89 | 90 | -------------------------------------------------------------------------------- /项目代码/admin/src/pages/store/sign.vue: -------------------------------------------------------------------------------- 1 | 32 | 33 | 77 | 78 | 123 | -------------------------------------------------------------------------------- /项目代码/admin/src/pages/admin/sign.vue: -------------------------------------------------------------------------------- 1 | 32 | 33 | 77 | 78 | 123 | -------------------------------------------------------------------------------- /项目代码/admin/src/pages/client/store/[id].vue: -------------------------------------------------------------------------------- 1 | 48 | 102 | 103 | 104 | 105 | { 106 | "meta": { 107 | "layout": "client-empty" 108 | } 109 | } 110 | 111 | -------------------------------------------------------------------------------- /项目代码/admin/src/pages/admin/banner/index.vue: -------------------------------------------------------------------------------- 1 | 60 | 113 | 114 | -------------------------------------------------------------------------------- /项目代码/admin/src/pages/admin/notice/index.vue: -------------------------------------------------------------------------------- 1 | 72 | 101 | 102 | -------------------------------------------------------------------------------- /项目代码/admin/src/pages/deliveryman/set.vue: -------------------------------------------------------------------------------- 1 | 70 | 71 | 122 | 123 | 124 | --------------------------------------------------------------------------------