From 4454107e7c6f25a18e0250535a7f07ca40e5ff8a Mon Sep 17 00:00:00 2001 From: sparksfly Date: Sat, 1 Aug 2026 21:04:38 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E9=99=90=E6=97=B6?= =?UTF-8?q?=E6=8A=A2=E8=B4=AD=E5=8A=9F=E8=83=BD=E6=A8=A1=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 本次提交实现了完整的限时抢购业务: 1. 新增抢购活动列表页与详情页 2. 新增倒计时组件、抢购接口与类型定义 3. 新增抢购详情路由与全局组件注册 4. 清理了旧的js格式业务代码与生成的sourcemap文件 5. 更新了权限路由白名单适配新页面 --- web-snack/.gitignore | 2 + web-snack/src/api/auth.js | 13 - web-snack/src/api/auth.js.map | 1 - web-snack/src/api/banner.js | 12 - web-snack/src/api/banner.js.map | 1 - web-snack/src/api/cart.js | 97 --- web-snack/src/api/cart.js.map | 1 - web-snack/src/api/category.js | 12 - web-snack/src/api/category.js.map | 1 - web-snack/src/api/notice.js | 12 - web-snack/src/api/notice.js.map | 1 - web-snack/src/api/product.js | 45 -- web-snack/src/api/product.js.map | 1 - web-snack/src/api/seckill.ts | 47 ++ .../src/components/seckill/Countdown.vue | 71 ++ web-snack/src/main.js | 18 - web-snack/src/main.js.map | 1 - web-snack/src/permission.js | 35 - web-snack/src/permission.js.map | 1 - web-snack/src/permission.ts | 3 +- web-snack/src/router/index.js | 110 --- web-snack/src/router/index.js.map | 1 - web-snack/src/router/index.ts | 6 + web-snack/src/stores/index.js | 6 - web-snack/src/stores/index.js.map | 1 - web-snack/src/stores/modules/user.js | 50 -- web-snack/src/stores/modules/user.js.map | 1 - web-snack/src/types/auth.js | 2 - web-snack/src/types/auth.js.map | 1 - web-snack/src/types/banner.js | 2 - web-snack/src/types/banner.js.map | 1 - web-snack/src/types/cart.js | 2 - web-snack/src/types/cart.js.map | 1 - web-snack/src/types/category.js | 2 - web-snack/src/types/category.js.map | 1 - web-snack/src/types/components.d.ts | 1 + web-snack/src/types/notice.js | 2 - web-snack/src/types/notice.js.map | 1 - web-snack/src/types/product.js | 2 - web-snack/src/types/product.js.map | 1 - web-snack/src/types/seckill.ts | 49 ++ web-snack/src/utils/request.js | 79 -- web-snack/src/utils/request.js.map | 1 - web-snack/src/views/seckill/detail.vue | 725 ++++++++++++++++++ web-snack/src/views/seckill/index.vue | 370 ++++++++- 45 files changed, 1265 insertions(+), 528 deletions(-) delete mode 100644 web-snack/src/api/auth.js delete mode 100644 web-snack/src/api/auth.js.map delete mode 100644 web-snack/src/api/banner.js delete mode 100644 web-snack/src/api/banner.js.map delete mode 100644 web-snack/src/api/cart.js delete mode 100644 web-snack/src/api/cart.js.map delete mode 100644 web-snack/src/api/category.js delete mode 100644 web-snack/src/api/category.js.map delete mode 100644 web-snack/src/api/notice.js delete mode 100644 web-snack/src/api/notice.js.map delete mode 100644 web-snack/src/api/product.js delete mode 100644 web-snack/src/api/product.js.map create mode 100644 web-snack/src/api/seckill.ts create mode 100644 web-snack/src/components/seckill/Countdown.vue delete mode 100644 web-snack/src/main.js delete mode 100644 web-snack/src/main.js.map delete mode 100644 web-snack/src/permission.js delete mode 100644 web-snack/src/permission.js.map delete mode 100644 web-snack/src/router/index.js delete mode 100644 web-snack/src/router/index.js.map delete mode 100644 web-snack/src/stores/index.js delete mode 100644 web-snack/src/stores/index.js.map delete mode 100644 web-snack/src/stores/modules/user.js delete mode 100644 web-snack/src/stores/modules/user.js.map delete mode 100644 web-snack/src/types/auth.js delete mode 100644 web-snack/src/types/auth.js.map delete mode 100644 web-snack/src/types/banner.js delete mode 100644 web-snack/src/types/banner.js.map delete mode 100644 web-snack/src/types/cart.js delete mode 100644 web-snack/src/types/cart.js.map delete mode 100644 web-snack/src/types/category.js delete mode 100644 web-snack/src/types/category.js.map delete mode 100644 web-snack/src/types/notice.js delete mode 100644 web-snack/src/types/notice.js.map delete mode 100644 web-snack/src/types/product.js delete mode 100644 web-snack/src/types/product.js.map create mode 100644 web-snack/src/types/seckill.ts delete mode 100644 web-snack/src/utils/request.js delete mode 100644 web-snack/src/utils/request.js.map create mode 100644 web-snack/src/views/seckill/detail.vue diff --git a/web-snack/.gitignore b/web-snack/.gitignore index 1765559..08eba63 100644 --- a/web-snack/.gitignore +++ b/web-snack/.gitignore @@ -27,6 +27,8 @@ coverage *.tsbuildinfo *.vue.js *.vue.js.map +src/**/*.js +src/**/*.js.map .eslintcache diff --git a/web-snack/src/api/auth.js b/web-snack/src/api/auth.js deleted file mode 100644 index d7947a5..0000000 --- a/web-snack/src/api/auth.js +++ /dev/null @@ -1,13 +0,0 @@ -import { request } from '@/utils/request'; -/** - * 用户登录 - * POST /api/user/login - */ -export function loginApi(params) { - return request({ - url: '/api/user/login', - method: 'POST', - data: params - }); -} -//# sourceMappingURL=auth.js.map \ No newline at end of file diff --git a/web-snack/src/api/auth.js.map b/web-snack/src/api/auth.js.map deleted file mode 100644 index 7c82946..0000000 --- a/web-snack/src/api/auth.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"auth.js","sourceRoot":"","sources":["auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAA;AAGzC;;;GAGG;AACH,MAAM,UAAU,QAAQ,CAAC,MAAmB;IAC1C,OAAO,OAAO,CAAc;QAC1B,GAAG,EAAE,iBAAiB;QACtB,MAAM,EAAE,MAAM;QACd,IAAI,EAAE,MAAM;KACb,CAAC,CAAA;AACJ,CAAC"} \ No newline at end of file diff --git a/web-snack/src/api/banner.js b/web-snack/src/api/banner.js deleted file mode 100644 index 72e5317..0000000 --- a/web-snack/src/api/banner.js +++ /dev/null @@ -1,12 +0,0 @@ -import { request } from '@/utils/request'; -/** - * 获取当前生效的轮播图列表 - * GET /api/banner - */ -export function getBannersApi() { - return request({ - url: '/api/banner', - method: 'GET' - }); -} -//# sourceMappingURL=banner.js.map \ No newline at end of file diff --git a/web-snack/src/api/banner.js.map b/web-snack/src/api/banner.js.map deleted file mode 100644 index e9fa813..0000000 --- a/web-snack/src/api/banner.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"banner.js","sourceRoot":"","sources":["banner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAA;AAGzC;;;GAGG;AACH,MAAM,UAAU,aAAa;IAC3B,OAAO,OAAO,CAAe;QAC3B,GAAG,EAAE,aAAa;QAClB,MAAM,EAAE,KAAK;KACd,CAAC,CAAA;AACJ,CAAC"} \ No newline at end of file diff --git a/web-snack/src/api/cart.js b/web-snack/src/api/cart.js deleted file mode 100644 index cc37635..0000000 --- a/web-snack/src/api/cart.js +++ /dev/null @@ -1,97 +0,0 @@ -import { request } from '@/utils/request'; -/** - * 获取购物车 - * GET /api/cart(需登录) - */ -export function getCartApi() { - return request({ - url: '/api/cart', - method: 'GET' - }); -} -/** - * 添加商品到购物车 - * POST /api/cart(需登录) - */ -export function addToCartApi(data) { - return request({ - url: '/api/cart', - method: 'POST', - data - }); -} -/** - * 获取购物车数量(用于角标) - * GET /api/cart/count(需登录) - */ -export function getCartCountApi() { - return request({ - url: '/api/cart/count', - method: 'GET' - }); -} -/** - * 修改购物车商品数量 - * PUT /api/cart/quantity(需登录) - */ -export function updateCartQuantityApi(data) { - return request({ - url: '/api/cart/quantity', - method: 'PUT', - data - }); -} -/** - * 切换购物车项选中状态 - * PUT /api/cart/{skuId}/selected(需登录) - */ -export function updateCartSelectedApi(skuId, selected) { - return request({ - url: `/api/cart/${skuId}/selected`, - method: 'PUT', - params: { selected } - }); -} -/** - * 全选 / 全不选 - * PUT /api/cart/all-selected(需登录) - */ -export function updateAllCartSelectedApi(selected) { - return request({ - url: '/api/cart/all-selected', - method: 'PUT', - params: { selected } - }); -} -/** - * 删除购物车项 - * DELETE /api/cart/{skuId}(需登录) - */ -export function deleteCartItemApi(skuId) { - return request({ - url: `/api/cart/${skuId}`, - method: 'DELETE' - }); -} -/** - * 批量删除购物车项 - * DELETE /api/cart(需登录) - */ -export function batchDeleteCartApi(skuIds) { - return request({ - url: '/api/cart', - method: 'DELETE', - data: skuIds - }); -} -/** - * 清空购物车 - * DELETE /api/cart/all(需登录) - */ -export function clearCartApi() { - return request({ - url: '/api/cart/all', - method: 'DELETE' - }); -} -//# sourceMappingURL=cart.js.map \ No newline at end of file diff --git a/web-snack/src/api/cart.js.map b/web-snack/src/api/cart.js.map deleted file mode 100644 index 4d107cb..0000000 --- a/web-snack/src/api/cart.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"cart.js","sourceRoot":"","sources":["cart.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAA;AAGzC;;;GAGG;AACH,MAAM,UAAU,UAAU;IACxB,OAAO,OAAO,CAAS;QACrB,GAAG,EAAE,WAAW;QAChB,MAAM,EAAE,KAAK;KACd,CAAC,CAAA;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,IAAgB;IAC3C,OAAO,OAAO,CAAO;QACnB,GAAG,EAAE,WAAW;QAChB,MAAM,EAAE,MAAM;QACd,IAAI;KACL,CAAC,CAAA;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,eAAe;IAC7B,OAAO,OAAO,CAAS;QACrB,GAAG,EAAE,iBAAiB;QACtB,MAAM,EAAE,KAAK;KACd,CAAC,CAAA;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,qBAAqB,CAAC,IAAmB;IACvD,OAAO,OAAO,CAAO;QACnB,GAAG,EAAE,oBAAoB;QACzB,MAAM,EAAE,KAAK;QACb,IAAI;KACL,CAAC,CAAA;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,qBAAqB,CAAC,KAAa,EAAE,QAAe;IAClE,OAAO,OAAO,CAAO;QACnB,GAAG,EAAE,aAAa,KAAK,WAAW;QAClC,MAAM,EAAE,KAAK;QACb,MAAM,EAAE,EAAE,QAAQ,EAAE;KACrB,CAAC,CAAA;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,wBAAwB,CAAC,QAAe;IACtD,OAAO,OAAO,CAAO;QACnB,GAAG,EAAE,wBAAwB;QAC7B,MAAM,EAAE,KAAK;QACb,MAAM,EAAE,EAAE,QAAQ,EAAE;KACrB,CAAC,CAAA;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAAC,KAAa;IAC7C,OAAO,OAAO,CAAO;QACnB,GAAG,EAAE,aAAa,KAAK,EAAE;QACzB,MAAM,EAAE,QAAQ;KACjB,CAAC,CAAA;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAAC,MAAgB;IACjD,OAAO,OAAO,CAAO;QACnB,GAAG,EAAE,WAAW;QAChB,MAAM,EAAE,QAAQ;QAChB,IAAI,EAAE,MAAM;KACb,CAAC,CAAA;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,YAAY;IAC1B,OAAO,OAAO,CAAO;QACnB,GAAG,EAAE,eAAe;QACpB,MAAM,EAAE,QAAQ;KACjB,CAAC,CAAA;AACJ,CAAC"} \ No newline at end of file diff --git a/web-snack/src/api/category.js b/web-snack/src/api/category.js deleted file mode 100644 index aaed580..0000000 --- a/web-snack/src/api/category.js +++ /dev/null @@ -1,12 +0,0 @@ -import { request } from '@/utils/request'; -/** - * 获取启用的分类树 - * GET /api/category/tree - */ -export function getCategoryTreeApi() { - return request({ - url: '/api/category/tree', - method: 'GET' - }); -} -//# sourceMappingURL=category.js.map \ No newline at end of file diff --git a/web-snack/src/api/category.js.map b/web-snack/src/api/category.js.map deleted file mode 100644 index fcbed32..0000000 --- a/web-snack/src/api/category.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"category.js","sourceRoot":"","sources":["category.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAA;AAGzC;;;GAGG;AACH,MAAM,UAAU,kBAAkB;IAChC,OAAO,OAAO,CAAqB;QACjC,GAAG,EAAE,oBAAoB;QACzB,MAAM,EAAE,KAAK;KACd,CAAC,CAAA;AACJ,CAAC"} \ No newline at end of file diff --git a/web-snack/src/api/notice.js b/web-snack/src/api/notice.js deleted file mode 100644 index 54a4a2c..0000000 --- a/web-snack/src/api/notice.js +++ /dev/null @@ -1,12 +0,0 @@ -import { request } from '@/utils/request'; -/** - * 获取当前生效的公告列表 - * GET /api/notice/list - */ -export function getNoticesApi() { - return request({ - url: '/api/notice/list', - method: 'GET' - }); -} -//# sourceMappingURL=notice.js.map \ No newline at end of file diff --git a/web-snack/src/api/notice.js.map b/web-snack/src/api/notice.js.map deleted file mode 100644 index b8a200c..0000000 --- a/web-snack/src/api/notice.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"notice.js","sourceRoot":"","sources":["notice.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAA;AAGzC;;;GAGG;AACH,MAAM,UAAU,aAAa;IAC3B,OAAO,OAAO,CAAe;QAC3B,GAAG,EAAE,kBAAkB;QACvB,MAAM,EAAE,KAAK;KACd,CAAC,CAAA;AACJ,CAAC"} \ No newline at end of file diff --git a/web-snack/src/api/product.js b/web-snack/src/api/product.js deleted file mode 100644 index 7ce2d0f..0000000 --- a/web-snack/src/api/product.js +++ /dev/null @@ -1,45 +0,0 @@ -import { request } from '@/utils/request'; -/** - * 商品详情(用户端) - * GET /api/product/{id} - */ -export function getProductDetailApi(id) { - return request({ - url: `/api/product/${id}`, - method: 'GET' - }); -} -/** - * 热门商品 - * GET /api/product/hot - */ -export function getHotProductsApi(limit = 10) { - return request({ - url: '/api/product/hot', - method: 'GET', - params: { limit } - }); -} -/** - * 新品上市 - * GET /api/product/new - */ -export function getNewProductsApi(limit = 10) { - return request({ - url: '/api/product/new', - method: 'GET', - params: { limit } - }); -} -/** - * 分类下商品列表 - * GET /api/product/list - */ -export function getProductsByCategoryApi(categoryIds, orderBy, limit = 20) { - return request({ - url: '/api/product/list', - method: 'GET', - params: { categoryIds, orderBy, limit } - }); -} -//# sourceMappingURL=product.js.map \ No newline at end of file diff --git a/web-snack/src/api/product.js.map b/web-snack/src/api/product.js.map deleted file mode 100644 index 9c1bdab..0000000 --- a/web-snack/src/api/product.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"product.js","sourceRoot":"","sources":["product.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAA;AAGzC;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CAAC,EAAU;IAC5C,OAAO,OAAO,CAAgB;QAC5B,GAAG,EAAE,gBAAgB,EAAE,EAAE;QACzB,MAAM,EAAE,KAAK;KACd,CAAC,CAAA;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAAC,KAAK,GAAG,EAAE;IAC1C,OAAO,OAAO,CAAgB;QAC5B,GAAG,EAAE,kBAAkB;QACvB,MAAM,EAAE,KAAK;QACb,MAAM,EAAE,EAAE,KAAK,EAAE;KAClB,CAAC,CAAA;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAAC,KAAK,GAAG,EAAE;IAC1C,OAAO,OAAO,CAAgB;QAC5B,GAAG,EAAE,kBAAkB;QACvB,MAAM,EAAE,KAAK;QACb,MAAM,EAAE,EAAE,KAAK,EAAE;KAClB,CAAC,CAAA;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,wBAAwB,CAAC,WAAmB,EAAE,OAAgB,EAAE,KAAK,GAAG,EAAE;IACxF,OAAO,OAAO,CAAgB;QAC5B,GAAG,EAAE,mBAAmB;QACxB,MAAM,EAAE,KAAK;QACb,MAAM,EAAE,EAAE,WAAW,EAAE,OAAO,EAAE,KAAK,EAAE;KACxC,CAAC,CAAA;AACJ,CAAC"} \ No newline at end of file diff --git a/web-snack/src/api/seckill.ts b/web-snack/src/api/seckill.ts new file mode 100644 index 0000000..4040581 --- /dev/null +++ b/web-snack/src/api/seckill.ts @@ -0,0 +1,47 @@ +import { request } from '@/utils/request' +import type { SeckillActivity, SeckillBuyReq, SeckillResult } from '@/types/seckill' + +/** + * 获取进行中 / 即将开始的抢购活动 + * GET /api/seckill/activities + */ +export function getSeckillActivitiesApi() { + return request({ + url: '/api/seckill/activities', + method: 'GET' + }) +} + +/** + * 抢购活动详情(含商品) + * GET /api/seckill/activities/{id} + */ +export function getSeckillDetailApi(id: number) { + return request({ + url: `/api/seckill/activities/${id}`, + method: 'GET' + }) +} + +/** + * 抢购下单(需登录) + * POST /api/seckill/buy + */ +export function seckillBuyApi(data: SeckillBuyReq) { + return request<{ orderNo: string }>({ + url: '/api/seckill/buy', + method: 'POST', + data + }) +} + +/** + * 查询抢购结果(轮询) + * GET /api/seckill/result/{orderNo} + */ +export function getSeckillResultApi(orderNo: string) { + return request({ + url: `/api/seckill/result/${orderNo}`, + method: 'GET' + }) +} diff --git a/web-snack/src/components/seckill/Countdown.vue b/web-snack/src/components/seckill/Countdown.vue new file mode 100644 index 0000000..d3b0d01 --- /dev/null +++ b/web-snack/src/components/seckill/Countdown.vue @@ -0,0 +1,71 @@ + + + + + diff --git a/web-snack/src/main.js b/web-snack/src/main.js deleted file mode 100644 index 6d4f54f..0000000 --- a/web-snack/src/main.js +++ /dev/null @@ -1,18 +0,0 @@ -import { createApp } from 'vue'; -import App from './App.vue'; -// 状态管理 -import pinia from './stores'; -// 路由 -import router from './router'; -// 全局样式 -import 'element-plus/dist/index.css'; -import './styles/reset.scss'; -import 'virtual:uno.css'; -import 'nprogress/nprogress.css'; -// 权限控制 -import './permission'; -const app = createApp(App); -app.use(pinia); -app.use(router); -app.mount('#app'); -//# sourceMappingURL=main.js.map \ No newline at end of file diff --git a/web-snack/src/main.js.map b/web-snack/src/main.js.map deleted file mode 100644 index f1eb938..0000000 --- a/web-snack/src/main.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"main.js","sourceRoot":"","sources":["main.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,KAAK,CAAA;AAC/B,OAAO,GAAG,MAAM,WAAW,CAAA;AAE3B,OAAO;AACP,OAAO,KAAK,MAAM,UAAU,CAAA;AAE5B,KAAK;AACL,OAAO,MAAM,MAAM,UAAU,CAAA;AAE7B,OAAO;AACP,OAAO,6BAA6B,CAAA;AACpC,OAAO,qBAAqB,CAAA;AAC5B,OAAO,iBAAiB,CAAA;AACxB,OAAO,yBAAyB,CAAA;AAEhC,OAAO;AACP,OAAO,cAAc,CAAA;AAErB,MAAM,GAAG,GAAG,SAAS,CAAC,GAAG,CAAC,CAAA;AAE1B,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;AACd,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;AAEf,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAA"} \ No newline at end of file diff --git a/web-snack/src/permission.js b/web-snack/src/permission.js deleted file mode 100644 index 2cec4cf..0000000 --- a/web-snack/src/permission.js +++ /dev/null @@ -1,35 +0,0 @@ -import router from '@/router'; -import NProgress from 'nprogress'; -import { useUserStore } from '@/stores/modules/user'; -NProgress.configure({ showSpinner: false }); -const WHITE_LIST = ['/login', '/404']; -router.beforeEach(async (to, _from) => { - NProgress.start(); - document.title = to.meta.title || '零食商城'; - const userStore = useUserStore(); - // 白名单放行 - if (WHITE_LIST.includes(to.path)) { - if (to.path === '/login' && userStore.isLoggedIn) { - return '/'; - } - return; - } - // 不需要登录的公开页面(首页、分类、商品详情、搜索、公告、抢购) - const publicPaths = ['/', '/search', '/seckill', '/notice', '/products']; - const isPublic = publicPaths.includes(to.path) || - to.path.startsWith('/category') || - to.path.startsWith('/product') || - to.path.startsWith('/notice'); - if (isPublic) { - return; - } - // 需要登录的页面(购物车、个人中心、客服) - if (!userStore.isLoggedIn) { - NProgress.done(); - return `/login?redirect=${encodeURIComponent(to.fullPath)}`; - } -}); -router.afterEach(() => { - NProgress.done(); -}); -//# sourceMappingURL=permission.js.map \ No newline at end of file diff --git a/web-snack/src/permission.js.map b/web-snack/src/permission.js.map deleted file mode 100644 index 5483a50..0000000 --- a/web-snack/src/permission.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"permission.js","sourceRoot":"","sources":["permission.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,UAAU,CAAA;AAC7B,OAAO,SAAS,MAAM,WAAW,CAAA;AACjC,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAA;AAEpD,SAAS,CAAC,SAAS,CAAC,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC,CAAA;AAE3C,MAAM,UAAU,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAA;AAErC,MAAM,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE;IACpC,SAAS,CAAC,KAAK,EAAE,CAAA;IACjB,QAAQ,CAAC,KAAK,GAAI,EAAE,CAAC,IAAI,CAAC,KAAgB,IAAI,MAAM,CAAA;IAEpD,MAAM,SAAS,GAAG,YAAY,EAAE,CAAA;IAEhC,QAAQ;IACR,IAAI,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QACjC,IAAI,EAAE,CAAC,IAAI,KAAK,QAAQ,IAAI,SAAS,CAAC,UAAU,EAAE,CAAC;YACjD,OAAO,GAAG,CAAA;QACZ,CAAC;QACD,OAAM;IACR,CAAC;IAED,kCAAkC;IAClC,MAAM,WAAW,GAAG,CAAC,GAAG,EAAE,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,WAAW,CAAC,CAAA;IACxE,MAAM,QAAQ,GACZ,WAAW,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,CAAC;QAC7B,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC;QAC/B,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC;QAC9B,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,CAAA;IAE/B,IAAI,QAAQ,EAAE,CAAC;QACb,OAAM;IACR,CAAC;IAED,uBAAuB;IACvB,IAAI,CAAC,SAAS,CAAC,UAAU,EAAE,CAAC;QAC1B,SAAS,CAAC,IAAI,EAAE,CAAA;QAChB,OAAO,mBAAmB,kBAAkB,CAAC,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAA;IAC7D,CAAC;AACH,CAAC,CAAC,CAAA;AAEF,MAAM,CAAC,SAAS,CAAC,GAAG,EAAE;IACpB,SAAS,CAAC,IAAI,EAAE,CAAA;AAClB,CAAC,CAAC,CAAA"} \ No newline at end of file diff --git a/web-snack/src/permission.ts b/web-snack/src/permission.ts index dd59854..1954ef0 100644 --- a/web-snack/src/permission.ts +++ b/web-snack/src/permission.ts @@ -26,7 +26,8 @@ router.beforeEach(async (to, _from) => { publicPaths.includes(to.path) || to.path.startsWith('/category') || to.path.startsWith('/product') || - to.path.startsWith('/notice') + to.path.startsWith('/notice') || + to.path.startsWith('/seckill') if (isPublic) { return diff --git a/web-snack/src/router/index.js b/web-snack/src/router/index.js deleted file mode 100644 index 54b8e6b..0000000 --- a/web-snack/src/router/index.js +++ /dev/null @@ -1,110 +0,0 @@ -import { createRouter, createWebHistory } from 'vue-router'; -const router = createRouter({ - history: createWebHistory(), - scrollBehavior: () => ({ left: 0, top: 0 }), - routes: [ - // ==================== 公开路由 ==================== - { - path: '/login', - name: 'Login', - component: () => import('@/views/auth/login.vue'), - meta: { title: '登录', hidden: true } - }, - { - path: '/404', - name: 'NotFound', - component: () => import('@/views/error/404.vue'), - meta: { title: '404', hidden: true } - }, - // ==================== 首页 ==================== - { - path: '/', - name: 'Home', - component: () => import('@/views/home/index.vue'), - meta: { title: '零食商城', keepAlive: true } - }, - // ==================== 分类页(占位) ==================== - { - path: '/category/:id?', - name: 'Category', - component: () => import('@/views/category/index.vue'), - meta: { title: '商品分类' } - }, - // ==================== 全部商品 ==================== - { - path: '/products', - name: 'Products', - component: () => import('@/views/category/index.vue'), - meta: { title: '全部商品' } - }, - // ==================== 商品详情(占位) ==================== - { - path: '/product/:id', - name: 'ProductDetail', - component: () => import('@/views/product/detail.vue'), - meta: { title: '商品详情' } - }, - // ==================== 搜索(占位) ==================== - { - path: '/search', - name: 'Search', - component: () => import('@/views/product/search.vue'), - meta: { title: '搜索' } - }, - // ==================== 购物车(占位) ==================== - { - path: '/cart', - name: 'Cart', - component: () => import('@/views/cart/index.vue'), - meta: { title: '购物车' } - }, - // ==================== 确认订单(占位) ==================== - { - path: '/checkout', - name: 'Checkout', - component: () => import('@/views/checkout/index.vue'), - meta: { title: '确认订单' } - }, - // ==================== 限时抢购(占位) ==================== - { - path: '/seckill', - name: 'Seckill', - component: () => import('@/views/seckill/index.vue'), - meta: { title: '限时抢购' } - }, - // ==================== 公告中心(占位) ==================== - { - path: '/notice', - name: 'NoticeList', - component: () => import('@/views/notice/index.vue'), - meta: { title: '公告中心' } - }, - { - path: '/notice/:id', - name: 'NoticeDetail', - component: () => import('@/views/notice/detail.vue'), - meta: { title: '公告详情' } - }, - // ==================== 个人中心(占位) ==================== - { - path: '/user', - name: 'UserCenter', - component: () => import('@/views/user/index.vue'), - meta: { title: '个人中心' } - }, - // ==================== 客诉/客服(占位) ==================== - { - path: '/chat', - name: 'Chat', - component: () => import('@/views/chat/index.vue'), - meta: { title: '在线客服' } - }, - // ==================== 404 兜底 ==================== - { - path: '/:pathMatch(.*)*', - redirect: '/404' - } - ] -}); -export default router; -//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/web-snack/src/router/index.js.map b/web-snack/src/router/index.js.map deleted file mode 100644 index f4dca55..0000000 --- a/web-snack/src/router/index.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/web-snack/src/router/index.ts b/web-snack/src/router/index.ts index f2eb10a..7355196 100644 --- a/web-snack/src/router/index.ts +++ b/web-snack/src/router/index.ts @@ -81,6 +81,12 @@ const router = createRouter({ component: () => import('@/views/seckill/index.vue'), meta: { title: '限时抢购' } }, + { + path: '/seckill/:id', + name: 'SeckillDetail', + component: () => import('@/views/seckill/detail.vue'), + meta: { title: '抢购详情' } + }, // ==================== 公告中心(占位) ==================== { diff --git a/web-snack/src/stores/index.js b/web-snack/src/stores/index.js deleted file mode 100644 index f531c75..0000000 --- a/web-snack/src/stores/index.js +++ /dev/null @@ -1,6 +0,0 @@ -import { createPinia } from 'pinia'; -import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'; -const pinia = createPinia(); -pinia.use(piniaPluginPersistedstate); -export default pinia; -//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/web-snack/src/stores/index.js.map b/web-snack/src/stores/index.js.map deleted file mode 100644 index d581368..0000000 --- a/web-snack/src/stores/index.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,OAAO,CAAA;AACnC,OAAO,yBAAyB,MAAM,6BAA6B,CAAA;AAEnE,MAAM,KAAK,GAAG,WAAW,EAAE,CAAA;AAC3B,KAAK,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAA;AAEpC,eAAe,KAAK,CAAA"} \ No newline at end of file diff --git a/web-snack/src/stores/modules/user.js b/web-snack/src/stores/modules/user.js deleted file mode 100644 index 67a1c0c..0000000 --- a/web-snack/src/stores/modules/user.js +++ /dev/null @@ -1,50 +0,0 @@ -import { defineStore } from 'pinia'; -import { ref, computed } from 'vue'; -import { loginApi } from '@/api/auth'; -/** - * 用户 Store - * - * - token 通过 pinia-plugin-persistedstate 持久化到 localStorage(key: snack-user) - * - 刷新页面后自动恢复登录态 - * - 401 由 request 拦截器统一处理:清空登录态 + 跳 /login - */ -export const useUserStore = defineStore('user', () => { - const token = ref(''); - const userId = ref(0); - const nickname = ref(''); - const isLoggedIn = computed(() => !!token.value); - const displayName = computed(() => nickname.value || '用户'); - /** 登录 */ - async function login(params) { - const data = await loginApi(params); - token.value = data.token; - userId.value = data.userId; - nickname.value = data.nickname; - return data; - } - /** 登出 */ - function logout() { - clearAuth(); - } - function clearAuth() { - token.value = ''; - userId.value = 0; - nickname.value = ''; - } - return { - token, - userId, - nickname, - isLoggedIn, - displayName, - login, - logout, - clearAuth - }; -}, { - persist: { - key: 'snack-user', - pick: ['token', 'userId', 'nickname'] - } -}); -//# sourceMappingURL=user.js.map \ No newline at end of file diff --git a/web-snack/src/stores/modules/user.js.map b/web-snack/src/stores/modules/user.js.map deleted file mode 100644 index 6e3afb0..0000000 --- a/web-snack/src/stores/modules/user.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"user.js","sourceRoot":"","sources":["user.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,OAAO,CAAA;AACnC,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,KAAK,CAAA;AACnC,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAGrC;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,WAAW,CACrC,MAAM,EACN,GAAG,EAAE;IACH,MAAM,KAAK,GAAG,GAAG,CAAS,EAAE,CAAC,CAAA;IAC7B,MAAM,MAAM,GAAG,GAAG,CAAS,CAAC,CAAC,CAAA;IAC7B,MAAM,QAAQ,GAAG,GAAG,CAAS,EAAE,CAAC,CAAA;IAEhC,MAAM,UAAU,GAAG,QAAQ,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;IAChD,MAAM,WAAW,GAAG,QAAQ,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,KAAK,IAAI,IAAI,CAAC,CAAA;IAE1D,SAAS;IACT,KAAK,UAAU,KAAK,CAAC,MAAmB;QACtC,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC,CAAA;QACnC,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAA;QACxB,MAAM,CAAC,KAAK,GAAG,IAAI,CAAC,MAAM,CAAA;QAC1B,QAAQ,CAAC,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAA;QAC9B,OAAO,IAAI,CAAA;IACb,CAAC;IAED,SAAS;IACT,SAAS,MAAM;QACb,SAAS,EAAE,CAAA;IACb,CAAC;IAED,SAAS,SAAS;QAChB,KAAK,CAAC,KAAK,GAAG,EAAE,CAAA;QAChB,MAAM,CAAC,KAAK,GAAG,CAAC,CAAA;QAChB,QAAQ,CAAC,KAAK,GAAG,EAAE,CAAA;IACrB,CAAC;IAED,OAAO;QACL,KAAK;QACL,MAAM;QACN,QAAQ;QACR,UAAU;QACV,WAAW;QACX,KAAK;QACL,MAAM;QACN,SAAS;KACV,CAAA;AACH,CAAC,EACD;IACE,OAAO,EAAE;QACP,GAAG,EAAE,YAAY;QACjB,IAAI,EAAE,CAAC,OAAO,EAAE,QAAQ,EAAE,UAAU,CAAC;KACtC;CACF,CACF,CAAA"} \ No newline at end of file diff --git a/web-snack/src/types/auth.js b/web-snack/src/types/auth.js deleted file mode 100644 index 7173b2d..0000000 --- a/web-snack/src/types/auth.js +++ /dev/null @@ -1,2 +0,0 @@ -export {}; -//# sourceMappingURL=auth.js.map \ No newline at end of file diff --git a/web-snack/src/types/auth.js.map b/web-snack/src/types/auth.js.map deleted file mode 100644 index af58501..0000000 --- a/web-snack/src/types/auth.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"auth.js","sourceRoot":"","sources":["auth.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/web-snack/src/types/banner.js b/web-snack/src/types/banner.js deleted file mode 100644 index c6d99cc..0000000 --- a/web-snack/src/types/banner.js +++ /dev/null @@ -1,2 +0,0 @@ -export {}; -//# sourceMappingURL=banner.js.map \ No newline at end of file diff --git a/web-snack/src/types/banner.js.map b/web-snack/src/types/banner.js.map deleted file mode 100644 index f2729a8..0000000 --- a/web-snack/src/types/banner.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"banner.js","sourceRoot":"","sources":["banner.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/web-snack/src/types/cart.js b/web-snack/src/types/cart.js deleted file mode 100644 index 55e56a0..0000000 --- a/web-snack/src/types/cart.js +++ /dev/null @@ -1,2 +0,0 @@ -export {}; -//# sourceMappingURL=cart.js.map \ No newline at end of file diff --git a/web-snack/src/types/cart.js.map b/web-snack/src/types/cart.js.map deleted file mode 100644 index a675c3e..0000000 --- a/web-snack/src/types/cart.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"cart.js","sourceRoot":"","sources":["cart.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/web-snack/src/types/category.js b/web-snack/src/types/category.js deleted file mode 100644 index 9eeb317..0000000 --- a/web-snack/src/types/category.js +++ /dev/null @@ -1,2 +0,0 @@ -export {}; -//# sourceMappingURL=category.js.map \ No newline at end of file diff --git a/web-snack/src/types/category.js.map b/web-snack/src/types/category.js.map deleted file mode 100644 index 702ecf7..0000000 --- a/web-snack/src/types/category.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"category.js","sourceRoot":"","sources":["category.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/web-snack/src/types/components.d.ts b/web-snack/src/types/components.d.ts index a32e2fe..b363e5b 100644 --- a/web-snack/src/types/components.d.ts +++ b/web-snack/src/types/components.d.ts @@ -13,6 +13,7 @@ declare module 'vue' { export interface GlobalComponents { AppFooter: typeof import('./../components/layout/AppFooter.vue')['default'] AppHeader: typeof import('./../components/layout/AppHeader.vue')['default'] + Countdown: typeof import('./../components/seckill/Countdown.vue')['default'] ElBadge: typeof import('element-plus/es')['ElBadge'] ElButton: typeof import('element-plus/es')['ElButton'] ElCarousel: typeof import('element-plus/es')['ElCarousel'] diff --git a/web-snack/src/types/notice.js b/web-snack/src/types/notice.js deleted file mode 100644 index 3b9a048..0000000 --- a/web-snack/src/types/notice.js +++ /dev/null @@ -1,2 +0,0 @@ -export {}; -//# sourceMappingURL=notice.js.map \ No newline at end of file diff --git a/web-snack/src/types/notice.js.map b/web-snack/src/types/notice.js.map deleted file mode 100644 index 3f4865c..0000000 --- a/web-snack/src/types/notice.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"notice.js","sourceRoot":"","sources":["notice.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/web-snack/src/types/product.js b/web-snack/src/types/product.js deleted file mode 100644 index d5ff5e4..0000000 --- a/web-snack/src/types/product.js +++ /dev/null @@ -1,2 +0,0 @@ -export {}; -//# sourceMappingURL=product.js.map \ No newline at end of file diff --git a/web-snack/src/types/product.js.map b/web-snack/src/types/product.js.map deleted file mode 100644 index f13cd3e..0000000 --- a/web-snack/src/types/product.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"product.js","sourceRoot":"","sources":["product.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/web-snack/src/types/seckill.ts b/web-snack/src/types/seckill.ts new file mode 100644 index 0000000..6091199 --- /dev/null +++ b/web-snack/src/types/seckill.ts @@ -0,0 +1,49 @@ +/** 抢购活动商品(对应后端 SeckillProductVO) */ +export interface SeckillProduct { + id: number + activityId: number + productId: number + productName: string + productImage: string + skuId: number + skuName: string + originPrice: number + seckillPrice: number + discount: number + seckillStock: number + remainStock: number + soldPercent: number + perLimit: number + sort: number + sales: number +} + +/** 抢购活动(对应后端 SeckillActivityVO) */ +export interface SeckillActivity { + id: number + name: string + cover: string + startTime: string + endTime: string + status: 0 | 1 | 2 + statusText: string + countdownSeconds: number + description: string + products: SeckillProduct[] +} + +/** 抢购下单请求 */ +export interface SeckillBuyReq { + activityId: number + skuId: number + quantity?: number +} + +/** 抢购结果(对应后端 SeckillResultVO) */ +export interface SeckillResult { + orderNo: string + status: number + statusText: string + message?: string + mainOrderId?: number | null +} diff --git a/web-snack/src/utils/request.js b/web-snack/src/utils/request.js deleted file mode 100644 index b95c056..0000000 --- a/web-snack/src/utils/request.js +++ /dev/null @@ -1,79 +0,0 @@ -import axios from 'axios'; -import { ElMessage } from 'element-plus'; -import NProgress from 'nprogress'; -import { useUserStore } from '@/stores/modules/user'; -NProgress.configure({ showSpinner: false }); -/** - * baseURL 处理: - * - 开发/测试:VITE_API_BASE_URL 留空 → baseURL = '' → 请求走相对路径 - * 浏览器同源,Vite server.proxy 在 Node 端转发到后端 - * - 生产:VITE_API_BASE_URL 设为真实后端域名 - */ -const baseURL = (import.meta.env.VITE_API_BASE_URL || '').replace(/\/+$/, ''); -const service = axios.create({ - baseURL, - timeout: 15000, - withCredentials: false -}); -// 请求拦截器 -service.interceptors.request.use((config) => { - NProgress.start(); - const userStore = useUserStore(); - if (userStore.token) { - config.headers.Authorization = `Bearer ${userStore.token}`; - } - return config; -}, (error) => { - NProgress.done(); - return Promise.reject(error); -}); -// 响应拦截器 -service.interceptors.response.use((response) => { - NProgress.done(); - const { code, message, data } = response.data; - if (code === 200) { - return data; - } - // Token 过期 / 未登录 - if (code === 401) { - const userStore = useUserStore(); - userStore.clearAuth(); - import('@/router').then(({ default: router }) => { - router.push('/login'); - }); - return Promise.reject(new Error(message || '未登录或Token已过期')); - } - ElMessage.error(message || '请求失败'); - return Promise.reject(new Error(message || 'Error')); -}, (error) => { - NProgress.done(); - const status = error.response?.status; - let message = error.message; - if (status === 401) { - message = '登录已过期,请重新登录'; - const userStore = useUserStore(); - userStore.clearAuth(); - import('@/router').then(({ default: router }) => { - router.push('/login'); - }); - } - else if (status === 403) { - message = '无权限访问'; - } - else if (status === 404) { - message = '资源不存在'; - } - else if (status === 500) { - message = '服务器内部错误'; - } - ElMessage.error(message); - return Promise.reject(error); -}); -/** - * 统一请求方法封装 - */ -export function request(config) { - return service.request(config); -} -export default service; -//# sourceMappingURL=request.js.map \ No newline at end of file diff --git a/web-snack/src/utils/request.js.map b/web-snack/src/utils/request.js.map deleted file mode 100644 index 4a3d17d..0000000 --- a/web-snack/src/utils/request.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"request.js","sourceRoot":"","sources":["request.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/web-snack/src/views/seckill/detail.vue b/web-snack/src/views/seckill/detail.vue new file mode 100644 index 0000000..4bca727 --- /dev/null +++ b/web-snack/src/views/seckill/detail.vue @@ -0,0 +1,725 @@ + + + + + diff --git a/web-snack/src/views/seckill/index.vue b/web-snack/src/views/seckill/index.vue index 50e3abc..e2175a6 100644 --- a/web-snack/src/views/seckill/index.vue +++ b/web-snack/src/views/seckill/index.vue @@ -1,25 +1,379 @@