diff --git a/Plain.text b/Plain.text index fe6b1a7..81d910b 100644 --- a/Plain.text +++ b/Plain.text @@ -5,39 +5,39 @@ e:\TaoTaoWang\pc-frontend\ │ └── favicon.ico # 网站图标 └── src/ ├── pages/ - │ ├── _app.js # 应用入口 - │ ├── _document.js # 文档模板 - │ ├── index.js # 首页 - │ ├── login.js # 登录页面 - │ ├── register.js # 注册页面 + │ ├── _app.ts # 应用入口 + │ ├── _document.ts # 文档模板 + │ ├── index.ts # 首页 + │ ├── login.ts # 登录页面 + │ ├── register.ts # 注册页面 │ ├── products/ # 商品相关页面 - │ │ ├── [id].js # 商品详情 - │ │ └── list.js # 商品列表 - │ ├── cart.js # 购物车页面 - │ ├── checkout.js # 结算页面 - │ ├── payment.js # 支付页面 + │ │ ├── [id].ts # 商品详情 + │ │ └── list.ts # 商品列表 + │ ├── cart.ts # 购物车页面 + │ ├── checkout.ts # 结算页面 + │ ├── payment.ts # 支付页面 │ └── user/ # 用户中心 - │ ├── index.js # 用户中心首页 - │ ├── orders.js # 订单列表 - │ └── profile.js # 个人信息 + │ ├── index.ts # 用户中心首页 + │ ├── orders.ts # 订单列表 + │ └── profile.ts # 个人信息 ├── components/ │ ├── common/ # 通用组件 │ ├── layout/ # 布局组件 │ └── business/ # 业务组件 - ├── api/ - │ ├── index.js # API基础配置 - │ ├── auth.js # 认证相关API - │ ├── product.js # 商品相关API - │ └── order.js # 订单相关API + ├── service/ + │ ├── api.ts # API基础配置 + │ ├── auth.ts # 认证相关API + │ ├── product.ts # 商品相关API + │ └── order.ts # 订单相关API ├── store/ - │ ├── index.js # Redux配置 + │ ├── index.ts # Redux配置 │ └── slices/ - │ ├── userSlice.js # 用户状态切片 - │ ├── productSlice.js # 商品状态切片 - │ └── cartSlice.js # 购物车状态切片 + │ ├── userSlice.ts # 用户状态切片 + │ ├── productSlice.ts # 商品状态切片 + │ └── cartSlice.ts # 购物车状态切片 ├── utils/ - │ ├── request.js # 请求工具 - │ └── auth.js # 认证工具 + │ ├── request.ts # 请求工具 + │ └── auth.ts # 认证工具 └── assets/ ├── css/ # 样式文件 └── images/ # 图片资源 \ No newline at end of file diff --git a/src/App.vue b/src/App.vue index 191f89a..049f4fb 100644 --- a/src/App.vue +++ b/src/App.vue @@ -1,13 +1,11 @@ diff --git a/src/Views/Home.vue b/src/Component/layout/Home.vue similarity index 60% rename from src/Views/Home.vue rename to src/Component/layout/Home.vue index a4656fd..ec10ad1 100644 --- a/src/Views/Home.vue +++ b/src/Component/layout/Home.vue @@ -5,6 +5,6 @@ diff --git a/src/Component/layout/MainLayout.vue b/src/Component/layout/MainLayout.vue new file mode 100644 index 0000000..36182a6 --- /dev/null +++ b/src/Component/layout/MainLayout.vue @@ -0,0 +1,18 @@ + + + \ No newline at end of file diff --git a/src/Route/route.ts b/src/Route/route.ts index 5bc6d46..f5dd181 100644 --- a/src/Route/route.ts +++ b/src/Route/route.ts @@ -1,58 +1,105 @@ import { createRouter, createWebHistory } from 'vue-router' // 导入组件 -import Home from '../Views/Home.vue' -import Login from '../Views/Login.vue' -import Search from '../Views/Search.vue' -import ProductDetail from '../Views/product/productdetil.vue' -import Cart from '../Views/Cart.vue' -import User from '../Views/User/User.vue' -import Chat from '../Views/Chat.vue' +const Home = () => import('../Component/layout/Home.vue') +const Login = () => import('../views/Login.vue') +const Search = () => import('../views/Search.vue') +const ProductDetail = () => import('../views/product/productdetil.vue') +const Cart = () => import('../views/Cart.vue') +const User = () => import('../views/User/User.vue') +const Chat = () => import('../views/Chat.vue') +const MainLayout = () => import('../Component/layout/MainLayout.vue') const routes = [ - { - path: '/', - name: 'home', - component: Home - }, - { - path: '/search', - name: 'search', - component: Search - }, - { - path: '/product', - name: 'productDetail', - component: ProductDetail - }, + // 重定向 + { path: '/', redirect: '/home' }, + // 登录路由 { path: '/login', name: 'login', - component: Login + component: Login, + meta: { + requiresAuth: false, + component: Login + } }, { - path: '/cart', - name: 'cart', - component: Cart + path: '', + name: 'mainLayout', + component: MainLayout, + children: [ + { + path: '/home', + name: 'home', + component: Home, + meta: { + title: '首页' + } + }, + + { + path: '/search', + name: 'search', + component: Search + }, + { + path: '/product', + name: 'productDetail', + component: ProductDetail + }, + { + path: '/cart', + name: 'cart', + component: Cart + }, + { + path: '/user', + name: 'user', + meta: { + requiresAuth: true, + title: '用户中心' + }, + component: User + }, + { + path: '/chat', + name: 'chat', + component: Chat + }, + ] }, + // 404页面 - 匹配所有未定义的路由 { - path: '/user', - name: 'user', - component: User - }, - { - path: '/chat', - name: 'chat', - component: Chat - }, - + path: '/:pathMatch(.*)*', + name: 'not-found', + component: () => import('../views/404/index.vue'), + meta: { + requiresAuth: false, + title: '页面不存在' + } + } ] const router = createRouter({ history: createWebHistory(import.meta.env.BASE_URL), routes }) +// 路由守卫 - 检查是否需要登录 +// 如果需要登录,且没有登录,重定向到登录页 +// 如果没有登录,继续导航 +// 如果需要登录,且已登录,继续导航 +router.beforeEach((to, from, next) => { + if (to.meta.requiresAuth) { + if (!localStorage.getItem('token')) { + next({ name: 'login' }) + } else { + next() + } + } else { + next() + } +}) export default router diff --git a/src/Service/ApiService.ts b/src/Service/ApiService.ts index 1c360c1..0c97495 100644 --- a/src/Service/ApiService.ts +++ b/src/Service/ApiService.ts @@ -25,7 +25,7 @@ api.interceptors.request.use( api.interceptors.response.use( (response) => { // 返回响应数据 - return response.data + return response }, (error) => { // 处理响应错误 diff --git a/src/Service/OrderService.ts b/src/Service/OrderService.ts new file mode 100644 index 0000000..3131878 --- /dev/null +++ b/src/Service/OrderService.ts @@ -0,0 +1,77 @@ +import api from "./ApiService"; +import type { Order, OrderRequest, ApiResponse, PageRequest } from "@/Util/Type"; + +class OrderService { + // 获取订单详情 + getOrderInfo(orderId: number, userId: number) { + return api.post>('/orders/getorderinfo', { + id: orderId, + userId: userId + }) + } + + // 创建订单 + createOrder(params: OrderRequest) { + return api.post>('/orders/create', params) + } + + // 更新订单信息 + updateOrder(params: OrderRequest) { + return api.post>('/orders/update', params) + } + + // 删除订单 + deleteOrder(orderId: number, shopId: number) { + return api.post>('/orders/delete', { + id: orderId, + shopId: shopId + }) + } + + // 分页查询订单 + listOrdersByPage(page: number = 1, size: number = 10) { + return api.post>('/orders/list', { + page: page, + size: size + }) + } + + // 根据用户ID查询订单 + getOrdersByUser(userId: number, page: number = 1, size: number = 10) { + return api.post>('/orders/byuser', { + userId: userId, + page: page, + size: size + }) + } + + // 根据店铺ID查询订单 + getOrdersByShop(shopId: number, page: number = 1, size: number = 10) { + return api.post>('/orders/byshop', { + shopId: shopId, + page: page, + size: size + }) + } + + // 根据订单状态查询订单 + getOrdersByStatus(status: number, shopId: number, page: number = 1, size: number = 10) { + return api.post>('/orders/bystatus', { + orderStatus: status, + shopId: shopId, + page: page, + size: size + }) + } + + // 更新订单状态 + updateOrderStatus(orderId: number, status: number, shopId: number) { + return api.post>('/orders/updatestatus', { + id: orderId, + orderStatus: status, + shopId: shopId + }) + } +} + +export default new OrderService() \ No newline at end of file diff --git a/src/Service/ProductService.ts b/src/Service/ProductService.ts new file mode 100644 index 0000000..fa36c98 --- /dev/null +++ b/src/Service/ProductService.ts @@ -0,0 +1,56 @@ +import api from "./ApiService"; +import type { Product, ProductRequest, ApiResponse, PageRequest } from "@/Util/Type"; + +class ProductService { + // 获取商品详情 + getProductInfo(productId: number) { + return api.post>('/products/getproductinfo', { + id: productId + }) + } + + // 删除商品 + deleteProduct(productId: number) { + return api.post>('/products/delete', { + id: productId + }) + } + + // 分页查询商品 + listProductsByPage(page: number = 1, size: number = 10) { + return api.post>('/products/list', { + page: page, + size: size + }) + } + + // 根据分类ID查询商品 + getProductsByCategory(categoryId: number, page: number = 1, size: number = 10) { + return api.post>('/products/bycategory', { + categoryId: categoryId, + page: page, + size: size + }) + } + + // 根据店铺ID查询商品 + getProductsByShop(shopId: number, page: number = 1, size: number = 10) { + return api.post>('/products/byshop', { + shopId: shopId, + page: page, + size: size + }) + } + + // 搜索商品 + searchProducts(keyword: string, page: number = 1, size: number = 10) { + return api.post>('/products/search', { + keyword: keyword, + page: page, + size: size + }) + } + +} + +export default new ProductService() \ No newline at end of file diff --git a/src/Service/ShopService.ts b/src/Service/ShopService.ts new file mode 100644 index 0000000..3c9dce6 --- /dev/null +++ b/src/Service/ShopService.ts @@ -0,0 +1,26 @@ +import api from "./ApiService"; +import type { Shop, ShopRequest, ShopResponse, ApiResponse } from "@/Util/Type"; + +class ShopService { + // 获取店铺信息 + getShopInfo(shopId: number) { + return api.post>('/shop/info', { + id: shopId + }) + } + // 根据店铺Id获取店铺信息 + getShopInfoById(shopId: number) { + return api.post>('/shop/info', { + id: shopId + }) + } + // 分页查询店铺 + getShopsPage(page: number = 1, size: number = 10) { + return api.post>('/shop/page', { + page: page, + size: size + }) + } +} + +export default new ShopService() \ No newline at end of file diff --git a/src/Service/UserService.ts b/src/Service/UserService.ts index a2f6b81..1669b84 100644 --- a/src/Service/UserService.ts +++ b/src/Service/UserService.ts @@ -1,12 +1,54 @@ import api from "./ApiService"; import router from '../Route/route' -import type { Login } from "@/Util/Type"; +import type { Login, User, UserRequest, LoginResponse, ApiResponse } from "@/Util/Type"; + class UserService { + // 登录 login(params: Login) { - return api.post('/auth/login', { - username: params.username, - password: params.password - }) + return api.post>('/auth/login', { + username: params.username, + password: params.password + }) + } + + // 获取用户信息 + getUserInfo(userId: number) { + return api.post>('/user/getuserinfo', { + id: userId + }) + } + + // 更新用户信息 + updateUserInfo(params: UserRequest) { + return api.post>('/user/info', params) + } + + // 注销登录 + logout(userId: number, status: number = 2) { + return api.post>('/user/logout', { + id: userId, + status: status + }) + } + + // 重置密码 + resetPassword(userId: number, newPassword: string) { + return api.post>('/user/resetpassword', { + id: userId, + password: newPassword + }) + } + + // 注册用户 + register(params: { + username: string + password: string + email?: string + phone?: string + avatar?: string + }) { + return api.post>('/user/register', params) } } + export default new UserService() \ No newline at end of file diff --git a/src/Util/Type.ts b/src/Util/Type.ts index 6b5fa30..5f0cd8b 100644 --- a/src/Util/Type.ts +++ b/src/Util/Type.ts @@ -1,44 +1,194 @@ // 项目中使用的类型定义 +// 响应结果类型 +export type ApiResponse = { + code: number + message: string + data: T +} + +// 登录响应类型 +export type LoginResponse = { + id: number + username: string + roles: string[] + permissions: string[] + token: string + tokenType: string +} + +// 用户响应类型 +export type UserResponse = { + users: User + roles: string[] + permissions: string[] +} + +// 用户类型 +export type User = { + id: number + username: string + password?: string + email?: string + phone?: string + avatar?: string + status?: number + createTime?: string + updateTime?: string +} + +// 用户请求类型 +export type UserRequest = { + id: number + username?: string + password?: string + email?: string + phone?: string + avatar?: string + status?: number +} + +// 商品类型 +export type Product = { + id: number + productName: string + shopId: number + categoryId: number + description: string + originalPrice: number + currentPrice: number + stock: number + status: number + mainImage: string + salesCount: number + createTime?: string + updateTime?: string +} + +// 商品响应类型 +export type ProductsResponse = { + products: Product + models?: ProductModel[] + images?: ProductImage[] +} + +// 商品型号 +export type ProductModel = { + id: number + productId: number + modelName: string + modelPrice: number + modelStock: number + modelStatus: number + modelImage: string +} + +// 商品img +export type ProductImage = { + id: number + productId: number + imageUrl: string + sort: number + isMain: number +} + +// 商品属性值 +export type AttributeValues = { + id: number + attributeId: number + attributeValue: string +} + +// 商品请求类型 +export type ProductRequest = { + id?: number + productName?: string + shopId?: number + categoryId?: number + description?: string + originalPrice?: number + currentPrice?: number + status?: number + mainImage?: string + keyword?: string + page?: number + size?: number + ids?: number[] +} + + + + // 商品详情类型 export type ProductDetail = { - id: string - name: string - price: string - img: string + product: Product + models: ProductModel[] + shop: Shop } + + +// 店铺类型 +export type Shop = { + id: number + shopName: string + shopOwner: number + shopDescription: string + shopLogo: string + status: number +} + // 店铺详情类型 export type ShopDetail = { id: string name: string img: string } -// 购物车类型 -export type Cart = { - id: string - name: string - price: string - img: string - count: number + +// 店铺请求类型 +export type ShopRequest = { + id?: number + page?: number + size?: number } -// 商品类型 -export type Product = { - id: string - name: string; // 商品名称 - description: string; // 商品描述 - price: number; // 商品价格 - quantity: number; // 商品数量 - image: string; // 商品图片 - model: string; // 商品型号 +// 店铺响应类型 +export type ShopResponse = { + shop: Shop + products: ProductsResponse[] } + // 订单商品类型 -export type OrderProduct = { - productId: string | number // 商品 ID - quantity: number // 商品数量 - // 其他待补充字段,如型号、颜色等 +export type OrderItem = { + id?: number + orderId: number + productId: number + quantity: number + price: number + productName: string + productImage: string } + // 订单类型 +export type Order = { + id: number + orderNo: string + userId: number + shopId: number + totalAmount: number + actualAmount: number + shippingFee: number + orderStatus: number + shippingAddress: string + receiverName: string + receiverPhone: string + paymentMethod: string + paymentTime?: string + createTime?: string + updateTime?: string + remark?: string +} + +// 订单详情类型 export type OrderDetail = { id: string // 订单 ID shopName: string // 店铺名称 @@ -51,18 +201,56 @@ export type OrderDetail = { paymentMethod: string // 支付方式 goods: Product[] // 商品列表 } + +// 订单请求类型 +export type OrderRequest = { + id?: number + orderNo?: string + userId?: number + shopId?: number + totalAmount?: number + actualAmount?: number + shippingFee?: number + orderStatus?: number + shippingAddress?: string + receiverName?: string + receiverPhone?: string + paymentMethod?: string + remark?: string + page?: number + size?: number + orderItems?: OrderItem[] +} + +// 分页请求类型 +export type PageRequest = { + page: number + size: number +} + +// 购物车类型 +export type Cart = { + id: string + name: string + price: string + img: string + count: number +} + // 注册类型 export type Register = { username: string password: string confirmPassword: string } + // 登录类型 export type Login = { username: string password: string rememberMe: boolean } + // 地址类型 export type Address = { id: number; // 修改时有 ID,新增时无 diff --git a/src/Views/404/index.vue b/src/Views/404/index.vue new file mode 100644 index 0000000..ee6b391 --- /dev/null +++ b/src/Views/404/index.vue @@ -0,0 +1,119 @@ + + + + + \ No newline at end of file diff --git a/src/Style/App.css b/src/Views/App.css similarity index 98% rename from src/Style/App.css rename to src/Views/App.css index fb69a0e..3c3f5fe 100644 --- a/src/Style/App.css +++ b/src/Views/App.css @@ -2,7 +2,6 @@ body { height: 100%; padding: 0 var(--spacing-lg); - background-color: var(--bg-color); font-family: var(--font-family); font-size: var(--font-size-base); color: var(--text-primary); diff --git a/src/Views/Cart.vue b/src/Views/Cart.vue index 0a69433..ad3b0d3 100644 --- a/src/Views/Cart.vue +++ b/src/Views/Cart.vue @@ -92,7 +92,7 @@ import { ref, computed, watch } from 'vue' import { useRouter } from 'vue-router' import { Button } from 'ant-design-vue' -import ProductModal from '@/Views/product/productmodal.vue' +import ProductModal from '@/views/product/productmodal.vue' import type { Product } from '@/Util/Type' const router = useRouter() @@ -119,16 +119,20 @@ const productmodal = ref([ { id: '1', name: 'BenQ 明基投影仪 商务办公会议培训用 1080P高清智能投影机', - price: '999', - img: 'https://picsum.photos/id/237/800/300', - model: 'X500' + price: 999, + image: 'https://picsum.photos/id/237/800/300', + model: 'X500', + description: '这是一个高分辨率的投影仪,支持1080P高清视频播放。', + quantity: 100 }, { id: '2', name: '明基投影仪 商务办公会议培训用 高清智能投影机', - price: '1299', - img: 'https://picsum.photos/id/238/800/300', - model: 'W600' + price: 1299, + image: 'https://picsum.photos/id/238/800/300', + model: 'W600', + description: '这是一个高分辨率的投影仪,支持1080P高清视频播放。', + quantity: 100 }, ]) const cartList = ref([ diff --git a/src/Views/Login.vue b/src/Views/Login.vue index 540af85..759a33a 100644 --- a/src/Views/Login.vue +++ b/src/Views/Login.vue @@ -78,17 +78,18 @@ const login = async () => { try { isLoading.value = true - const userLoginResponse = await userService.login(loginform.value) + const userLoginResponse = await userService.login(loginform.value).then(res => res.data) + console.log(userLoginResponse) // 注意:根据响应拦截器,userLoginResponse已经是response.data - if (userLoginResponse.data.code === 200) { + if (userLoginResponse.code === 200) { // 登录成功后,跳转到首页 router.push({ name: 'home' }) // 登录成功后,将token存储到全局状态管理中 useGlobalStore().setToken(userLoginResponse.data.token) } else { // 登录失败后,显示错误信息给用户 - errorMessage.value = userLoginResponse.data.msg || '登录失败,请检查用户名和密码' + errorMessage.value = userLoginResponse.message || '登录失败,请检查用户名和密码' } } catch (error: any) { console.error('登录失败:', error) diff --git a/src/Views/Search.vue b/src/Views/Search.vue index c23a868..98c5dbf 100644 --- a/src/Views/Search.vue +++ b/src/Views/Search.vue @@ -7,34 +7,20 @@ diff --git a/src/Views/Shop.vue b/src/Views/Shop.vue index 8d2fe6b..e1216c4 100644 --- a/src/Views/Shop.vue +++ b/src/Views/Shop.vue @@ -1,7 +1,7 @@ diff --git a/src/Views/footer.vue b/src/Views/footer.vue index a53e6ab..6ae2d8f 100644 --- a/src/Views/footer.vue +++ b/src/Views/footer.vue @@ -24,49 +24,21 @@