diff --git a/AI_ASSISTANT_README.md b/AI_ASSISTANT_README.md deleted file mode 100644 index 0810c26..0000000 --- a/AI_ASSISTANT_README.md +++ /dev/null @@ -1,162 +0,0 @@ -# PC DIY 商店 AI 助手使用说明 - -## 功能概述 - -AI 助手集成了 Anthropic 的 Claude AI,可以帮助用户: - -1. **查询配件信息** - 按类型、品牌、价格范围搜索配件 -2. **获取配件类型** - 查看所有可用的配件类型 -3. **智能推荐** - 基于用户需求提供配件推荐 -4. **价格对比** - 帮助用户比较不同配件的价格和性能 - -## 环境配置 - -### 1. 安装依赖 - -确保已安装 Anthropic SDK: - -```bash -bun add @anthropic-ai/sdk -``` - -### 2. 环境变量 - -在 `.env.local` 文件中添加: - -```env -ANTHROPIC_API_KEY=your_anthropic_api_key_here -NEXT_PUBLIC_APP_URL=http://localhost:3000 -``` - -### 3. 获取 Anthropic API Key - -1. 访问 [Anthropic Console](https://console.anthropic.com/) -2. 注册/登录账户 -3. 创建 API Key -4. 将 API Key 添加到环境变量中 - -## API 使用 - -### 发送查询请求 - -```javascript -const response = await fetch('/api/ai', { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ - query: '推荐一些价格在1000-2000元的显卡' - }), -}); - -const data = await response.json(); -console.log(data.response); -``` - -### 支持的工具调用 - -#### 1. query-components -查询配件信息,支持以下参数: - -- `type`: 配件类型ID -- `brand`: 品牌名称 -- `minPrice`: 最低价格 -- `maxPrice`: 最高价格 -- `search`: 搜索关键词 -- `page`: 页码(默认1) -- `limit`: 每页数量(默认12) - -#### 2. get-component-types -获取所有配件类型列表,无需参数。 - -## 使用示例 - -### 示例查询 - -1. **查询配件类型** - ``` - "显示所有配件类型" - "有哪些配件类型可以选择?" - ``` - -2. **搜索特定配件** - ``` - "推荐一些价格在1000-2000元的显卡" - "查找华硕品牌的主板" - "有什么高性能的CPU推荐" - ``` - -3. **价格筛选** - ``` - "500元以下的内存条有哪些" - "3000元左右的显卡推荐" - ``` - -4. **品牌筛选** - ``` - "华硕的所有配件" - "英特尔的CPU产品" - ``` - -### 页面访问 - -访问 `/ai-assistant` 页面可以使用图形界面与 AI 助手交互。 - -## 技术架构 - -### 文件结构 - -``` -lib/ - ai-assistant.ts # AI 助手核心逻辑 -app/ - api/ai/route.ts # AI API 端点 - ai-assistant/page.tsx # AI 助手前端页面 -components/ - Navbar.tsx # 导航栏(已添加AI助手链接) -``` - -### 核心组件 - -1. **MCPClient 类** - 封装 Anthropic API 调用 -2. **工具调用处理** - 处理 AI 对数据库的查询需求 -3. **消息处理** - 管理对话上下文和工具结果 - -## 注意事项 - -1. **API Key 安全** - 确保 API Key 不要提交到版本控制系统 -2. **错误处理** - AI 助手包含完整的错误处理机制 -3. **费用控制** - Anthropic API 按 token 计费,建议设置使用限制 -4. **网络依赖** - 需要稳定的网络连接到 Anthropic 服务 - -## 故障排除 - -### 常见问题 - -1. **API Key 错误** - - 检查环境变量是否正确设置 - - 确认 API Key 是否有效 - -2. **网络连接问题** - - 检查网络连接 - - 确认 Anthropic 服务是否可访问 - -3. **数据库连接问题** - - 确保数据库正常运行 - - 检查 Prisma 配置 - -### 调试方法 - -1. 查看浏览器控制台错误 -2. 检查服务器端日志 -3. 验证 API 响应格式 - -## 后续扩展 - -可以考虑添加: - -1. **用户偏好记忆** - 记住用户的配件偏好 -2. **配置推荐** - 根据预算推荐完整的装机配置 -3. **性能对比** - 添加配件性能参数对比功能 -4. **库存提醒** - 监控配件库存状态 diff --git a/app/ai-assistant/page.tsx b/app/ai-assistant/page.tsx index 034c04f..c4dca53 100644 --- a/app/ai-assistant/page.tsx +++ b/app/ai-assistant/page.tsx @@ -2,7 +2,7 @@ import { useState, useEffect, useRef, useCallback } from 'react' -import MarkdownItCjs from "markdown-it/dist/markdown-it.js"; +const MarkdownItCjs = require("markdown-it/dist/markdown-it.js"); import { ComponentCard } from '@/components/ComponentCard'; import { Component } from '@prisma/client'; import { nextTick } from 'process'; diff --git a/app/api/ai/conversations/[id]/route.ts b/app/api/ai/conversations/[id]/route.ts index 9191eb8..1f5b673 100644 --- a/app/api/ai/conversations/[id]/route.ts +++ b/app/api/ai/conversations/[id]/route.ts @@ -90,7 +90,7 @@ export async function GET( export async function DELETE( request: NextRequest, - { params }: { params: { id: string } } + { params }: { params: Promise<{ id: string }> } ) { try { // 验证用户身份 @@ -103,7 +103,7 @@ export async function DELETE( } const client = new AIClient() - const success = await client.deleteConversation(params.id, user.id) + const success = await client.deleteConversation((await params).id, user.id) if (!success) { return NextResponse.json( @@ -125,7 +125,7 @@ export async function DELETE( export async function PATCH( request: NextRequest, - { params }: { params: { id: string } } + { params }: { params: Promise<{ id: string }> } ) { try { // 验证用户身份 @@ -146,7 +146,7 @@ export async function PATCH( } const client = new AIClient() - const success = await client.updateConversationTitle(params.id, user.id, title) + const success = await client.updateConversationTitle((await params).id, user.id, title) if (!success) { return NextResponse.json( diff --git a/app/cart/page.tsx b/app/cart/page.tsx index dc02753..18727f5 100644 --- a/app/cart/page.tsx +++ b/app/cart/page.tsx @@ -310,7 +310,7 @@ export default function CartPage() {
- s
+
-
+ {/*

测试账号:admin@pcdiy.com,密码:admin123

-
+
*/}
diff --git a/docs/在线电脑DIY系统.assets/image-20250624224433427.png b/docs/在线电脑DIY系统.assets/image-20250624224433427.png new file mode 100644 index 0000000..9307539 Binary files /dev/null and b/docs/在线电脑DIY系统.assets/image-20250624224433427.png differ diff --git a/docs/在线电脑DIY系统.assets/image-20250624224518152.png b/docs/在线电脑DIY系统.assets/image-20250624224518152.png new file mode 100644 index 0000000..9f78b9c Binary files /dev/null and b/docs/在线电脑DIY系统.assets/image-20250624224518152.png differ diff --git a/docs/在线电脑DIY系统.assets/image-20250624224540798.png b/docs/在线电脑DIY系统.assets/image-20250624224540798.png new file mode 100644 index 0000000..b5bf40a Binary files /dev/null and b/docs/在线电脑DIY系统.assets/image-20250624224540798.png differ diff --git a/docs/在线电脑DIY系统.assets/image-20250624224542337.png b/docs/在线电脑DIY系统.assets/image-20250624224542337.png new file mode 100644 index 0000000..b5bf40a Binary files /dev/null and b/docs/在线电脑DIY系统.assets/image-20250624224542337.png differ diff --git a/docs/在线电脑DIY系统.assets/image-20250624224618803.png b/docs/在线电脑DIY系统.assets/image-20250624224618803.png new file mode 100644 index 0000000..2ba5344 Binary files /dev/null and b/docs/在线电脑DIY系统.assets/image-20250624224618803.png differ diff --git a/docs/在线电脑DIY系统.assets/image-20250624224741394.png b/docs/在线电脑DIY系统.assets/image-20250624224741394.png new file mode 100644 index 0000000..51e4538 Binary files /dev/null and b/docs/在线电脑DIY系统.assets/image-20250624224741394.png differ diff --git a/docs/在线电脑DIY系统.assets/image-20250624224758346.png b/docs/在线电脑DIY系统.assets/image-20250624224758346.png new file mode 100644 index 0000000..51e4538 Binary files /dev/null and b/docs/在线电脑DIY系统.assets/image-20250624224758346.png differ diff --git a/docs/在线电脑DIY系统.assets/image-20250624224823525.png b/docs/在线电脑DIY系统.assets/image-20250624224823525.png new file mode 100644 index 0000000..0f9b7e6 Binary files /dev/null and b/docs/在线电脑DIY系统.assets/image-20250624224823525.png differ diff --git a/docs/在线电脑DIY系统.assets/image-20250624224906899-1750777204806-1.png b/docs/在线电脑DIY系统.assets/image-20250624224906899-1750777204806-1.png new file mode 100644 index 0000000..bf1a6c3 Binary files /dev/null and b/docs/在线电脑DIY系统.assets/image-20250624224906899-1750777204806-1.png differ diff --git a/docs/在线电脑DIY系统.assets/image-20250624224906899.png b/docs/在线电脑DIY系统.assets/image-20250624224906899.png new file mode 100644 index 0000000..bf1a6c3 Binary files /dev/null and b/docs/在线电脑DIY系统.assets/image-20250624224906899.png differ diff --git a/docs/在线电脑DIY系统.assets/image-20250624224919550.png b/docs/在线电脑DIY系统.assets/image-20250624224919550.png new file mode 100644 index 0000000..0815503 Binary files /dev/null and b/docs/在线电脑DIY系统.assets/image-20250624224919550.png differ diff --git a/docs/在线电脑DIY系统.assets/image-20250624225019124.png b/docs/在线电脑DIY系统.assets/image-20250624225019124.png new file mode 100644 index 0000000..bb8f1e7 Binary files /dev/null and b/docs/在线电脑DIY系统.assets/image-20250624225019124.png differ diff --git a/docs/在线电脑DIY系统.assets/image-20250624225113890.png b/docs/在线电脑DIY系统.assets/image-20250624225113890.png new file mode 100644 index 0000000..7e0b158 Binary files /dev/null and b/docs/在线电脑DIY系统.assets/image-20250624225113890.png differ diff --git a/docs/在线电脑DIY系统.assets/image-20250624225136254.png b/docs/在线电脑DIY系统.assets/image-20250624225136254.png new file mode 100644 index 0000000..d57da1b Binary files /dev/null and b/docs/在线电脑DIY系统.assets/image-20250624225136254.png differ diff --git a/docs/在线电脑DIY系统.assets/image-20250624225307836.png b/docs/在线电脑DIY系统.assets/image-20250624225307836.png new file mode 100644 index 0000000..27d4fb6 Binary files /dev/null and b/docs/在线电脑DIY系统.assets/image-20250624225307836.png differ diff --git a/docs/在线电脑DIY系统.assets/image-20250624225459858.png b/docs/在线电脑DIY系统.assets/image-20250624225459858.png new file mode 100644 index 0000000..8919a35 Binary files /dev/null and b/docs/在线电脑DIY系统.assets/image-20250624225459858.png differ diff --git a/docs/在线电脑DIY系统.assets/image-20250624225805038.png b/docs/在线电脑DIY系统.assets/image-20250624225805038.png new file mode 100644 index 0000000..b7cf31c Binary files /dev/null and b/docs/在线电脑DIY系统.assets/image-20250624225805038.png differ diff --git a/docs/在线电脑DIY系统.assets/image-20250624225832652.png b/docs/在线电脑DIY系统.assets/image-20250624225832652.png new file mode 100644 index 0000000..39251fc Binary files /dev/null and b/docs/在线电脑DIY系统.assets/image-20250624225832652.png differ diff --git a/docs/在线电脑DIY系统.assets/image-20250624230700395.png b/docs/在线电脑DIY系统.assets/image-20250624230700395.png new file mode 100644 index 0000000..c4a6344 Binary files /dev/null and b/docs/在线电脑DIY系统.assets/image-20250624230700395.png differ diff --git a/docs/在线电脑DIY系统.assets/image-20250624230801501.png b/docs/在线电脑DIY系统.assets/image-20250624230801501.png new file mode 100644 index 0000000..133025a Binary files /dev/null and b/docs/在线电脑DIY系统.assets/image-20250624230801501.png differ diff --git a/docs/在线电脑DIY系统.assets/image-20250624232606606.png b/docs/在线电脑DIY系统.assets/image-20250624232606606.png new file mode 100644 index 0000000..1b1485c Binary files /dev/null and b/docs/在线电脑DIY系统.assets/image-20250624232606606.png differ diff --git a/docs/在线电脑DIY系统.assets/image-20250624232701990.png b/docs/在线电脑DIY系统.assets/image-20250624232701990.png new file mode 100644 index 0000000..69697fb Binary files /dev/null and b/docs/在线电脑DIY系统.assets/image-20250624232701990.png differ diff --git a/docs/在线电脑DIY系统.md b/docs/在线电脑DIY系统.md new file mode 100644 index 0000000..47dafc7 --- /dev/null +++ b/docs/在线电脑DIY系统.md @@ -0,0 +1,2910 @@ +## 第一章 概述 + +### 1.1 课程设计目的 + +通过本课程设计的准备与总结,复习、领会、巩固和运用课堂上所学的软件开发方法和知识,为学生综合应用本专业所学习的多门课程知识创造实践机会,使每个学生了解软件工具与环境对于项目开发的重要性,并且重点深入掌握好几种较新或较流行的软件工具或计算机应用技术,提高学生今后参与开发稍大规模实际软件项目和探索未知领域的能力和自信心。 + +本次课程设计通过开发一个完整的在线电脑DIY系统,让学生深入掌握现代Web开发技术栈,包括前端框架、后端开发、数据库设计、API设计等核心技能。 + +### 1.2 课程设计任务 + +本课程设计的主要任务是开发一个功能完整、用户友好的在线电脑DIY系统。 + +#### 1.2.1 基础功能要求 + +系统需要实现以下基础功能: + +1. **首页展示功能**:企业介绍和电脑配件(CPU、内存、硬盘、主板、显卡、机箱)的详情展示,无需登录即可浏览 +2. **多品牌配件管理**:每种配件支持多个品牌,不同价格层次满足用户需求 +3. **用户权限管理**:包含管理员和普通用户两种角色,需要登录后才能进行核心操作 +4. **管理员功能模块**: + + 配件类型管理、商品信息管理、用户信息浏览、订单查看和管理 +5. **用户功能模块**: + + 用户注册和登录、个人信息修改、配件选购和购物车管理、装机单配置(每种配件选择1个)、订单提交和结算(模拟付款)、个人订单查看 +6. **数据统计功能**: + - 按消费金额倒排的前十用户列表 + - 按销售量倒排序的前十配件列表 + - 统计结果的图形化展示 + +#### 1.2.2 创新功能实现 + +在满足基础要求的基础上,本系统还实现了以下创新功能: + +1. **AI智能助手**: + - 集成Claude AI模型,提供专业的配件咨询服务 + - 支持自然语言查询配件信息 + - 智能推荐适合的配件组合 + - 基于预算和需求的个性化建议 +2. **Tool工具调用系统**: + - 实现了query-components工具,支持按类型、品牌、价格等条件智能查询 + - 实现了show-components工具,以卡片形式展示配件详情 + - 支持流式响应,提供实时的交互体验 + +### 1.3 使用技术及开发环境 + +#### 1.3.1 技术栈概述 + +本项目采用了现代化的全栈开发技术栈,充分体现了当前软件开发的最佳实践和技术趋势。 + +##### 前端技术栈 + +- **Next.js 15**:作为核心React框架,提供服务端渲染(SSR)、静态站点生成(SSG)、文件系统路由等现代化特性 +- **React 19**:最新版本的React库,提供组件化开发和状态管理 +- **TypeScript 5**:提供类型安全和更好的开发体验 +- **Tailwind CSS 4:原子化CSS框架,快速构建现代化UI界面 + +##### 后端技术栈 + +- **Next.js API Routes**:基于Next.js的API路由系统,实现RESTful API +- **Prisma 6.10.1**:现代化的数据库ORM工具,提供类型安全的数据库操作 +- **PostgreSQL**:关系型数据库,存储用户、商品、订单等核心数据 +- **JSON Web Token (JWT)**:用户身份认证和授权机制 +- **bcryptjs 3.0.2**:密码加密和验证 + +##### AI集成技术 + +- **Anthropic Claude API**:集成Claude AI模型,提供智能对话功能 +- **@anthropic-ai/sdk 0.54.0**:Anthropic官方SDK,处理AI API调用 + +##### 开发工具和环境 + +- **Bun**:高性能的JavaScript运行时和包管理器 +- **Visual Studio Code**:主要开发IDE + +## 第二章 需求分析 + +### 2.1 功能分析 + +#### 2.1.1 系统概述 + +在线电脑DIY系统是一个面向电脑爱好者和DIY玩家的综合性电商平台。系统不仅提供传统的商品浏览、购买功能,更创新性地集成了AI智能助手,为用户提供专业的配件选择建议和装机指导。系统采用B2C模式,支持多角色用户管理,具备完整的商品管理、订单处理、数据统计等功能模块。 + +#### 2.1.3 功能模块详细分析 + +##### 2.1.3.1 用户管理模块 + +**基础功能:** + +- **用户注册**:支持邮箱注册,验证用户名唯一性 +- **用户登录**:基于JWT的安全认证机制 +- **个人信息管理**:用户可修改个人资料、联系方式 +- **密码管理**:安全的密码修改功能 + +**技术实现特点:** +- 采用bcrypt加密存储密码,确保数据安全 +- JWT无状态认证,支持分布式部署 +- 前端表单验证与后端数据校验双重保障 + +##### 2.1.3.2 商品管理模块 + +**配件分类管理:** +- **配件类型**:CPU、内存、硬盘、主板、显卡、机箱六大类 +- **品牌管理**:每类配件支持多品牌,如Intel、AMD、NVIDIA等 +- **规格参数**:详细的技术规格和兼容性信息 + +**库存管理:** + +- **实时库存**:支持库存数量的实时更新 + +##### 2.1.3.3 购物车与订单模块 + +**购物车功能:** +- **商品添加**:支持快速添加配件到购物车 +- **数量调整**:灵活的数量增减操作 +- **实时计算**:动态显示总价和优惠信息 +- **持久化存储**:登录用户购物车数据持久保存 + +**订单处理流程:** +- **订单创建**:从购物车生成订单,分配唯一订单号 +- **库存扣减**:下单时自动扣减库存,防止超卖 +- **订单状态管理**:待确认 → 已确认 → 处理中 → 已发货 → 已送达 +- **订单取消**:支持用户主动取消和管理员取消 + +**装机单功能:** +- **配件选择约束**:确保每种配件类型只能选择一个 +- **兼容性检查**:AI助手提供兼容性建议 +- **价格统计**:实时显示装机单总价 +- **一键下单**:将完整装机单转换为订单 + +##### 2.1.3.4 AI智能助手模块 + +**核心对话引擎:** +- **自然语言理解**:理解用户的配件需求和预算 +- **多轮对话**:支持上下文保持的连续对话 +- **专业知识库**:内置丰富的硬件知识和兼容性信息 + +**工具调用系统:** +- **query-components工具**:支持按类型、品牌、价格范围查询配件 +- **show-components工具**:以卡片形式展示配件详细信息 + +**对话管理:** + +- **对话历史**:完整记录用户与AI的对话内容 +- **对话分类**:按时间和主题自动分类 +- **对话导出**:支持对话记录的导出和分享 + +##### 2.1.3.5 管理后台模块 + +**数据统计分析:** + +- **用户排行榜**:按消费金额排序的前十用户 +- **商品排行榜**:按销售量排序的前十配件 +- **销售趋势**:时间维度的销售数据分析 +- **图表展示**:使用柱状图、饼图等可视化数据 + +**订单管理:** + +- **订单列表**:分页显示所有订单信息 +- **订单详情**:查看订单的详细配件和用户信息 +- **状态更新**:批量或单个订单状态修改 +- **订单搜索**:按订单号、用户、状态等条件筛选 + +**商品管理:** + +- **商品CRUD**:完整的商品增删改查功能 +- **批量导入**:支持Excel/CSV格式的批量数据导入 +- **图片管理**:商品图片的上传和管理 +- **分类管理**:配件分类的维护和调整 + +#### 2.1.4 功能结构图 + +```mermaid +graph LR + A[在线电脑DIY系统] --> B[用户管理模块] + A --> C[商品管理模块] + A --> D[购物车订单模块] + A --> E[AI智能助手模块] + A --> F[管理后台模块] + + B --> B1[用户注册登录] + B --> B2[个人信息管理] + B --> B3[权限控制] + + C --> C1[配件分类管理] + C --> C2[商品信息管理] + C --> C3[库存管理] + C --> C4[价格管理] + + D --> D1[购物车功能] + D --> D2[订单处理] + D --> D3[装机单配置] + D --> D4[支付结算] + + E --> E1[自然语言对话] + E --> E2[配件查询工具] + E --> E3[配件展示工具] + E --> E4[对话历史管理] + + F --> F1[数据统计分析] + F --> F2[订单管理] + F --> F3[商品管理] + F --> F4[用户管理] +``` + +
系统功能结构图
+ +### 2.2 概念模型分析 + +#### 2.2.1 实体识别 + +通过对系统需求的深入分析,识别出以下主要实体: + +##### 2.2.1.1 核心业务实体 + +**用户实体(User)** +- **属性**:用户ID、用户名、邮箱、密码、姓名、电话、地址、是否管理员、创建时间、更新时间 +- **业务意义**:系统的核心参与者,包括普通用户和管理员 + +**配件类型实体(ComponentType)** +- **属性**:类型ID、类型名称、描述 +- **业务意义**:配件的分类标准,如CPU、内存、硬盘等 + +**配件实体(Component)** +- **属性**:配件ID、名称、品牌、型号、价格、描述、图片URL、库存数量、规格参数、创建时间、更新时间 +- **业务意义**:系统中的商品实体,用户购买的对象 + +**订单实体(Order)** +- **属性**:订单ID、订单号、总金额、状态、创建时间、更新时间 +- **业务意义**:用户购买行为的记录 + +**订单项实体(OrderItem)** +- **属性**:项目ID、数量、价格 +- **业务意义**:订单中具体的商品项 + +**购物车项实体(CartItem)** +- **属性**:项目ID、数量、创建时间、更新时间 +- **业务意义**:用户临时存放待购买商品的容器 + +**对话实体(Conversation)** + +- **属性**:对话ID、标题、消息内容(JSON)、创建时间、更新时间 +- **业务意义**:用户与AI助手的对话记录 + +#### 2.2.2 实体关系分析 + +##### 2.2.2.1 用户相关关系 + +1. **用户-订单关系(1:N)** + - 一个用户可以有多个订单 + - 一个订单只属于一个用户 + - 关系属性:下单时间 + +2. **用户-购物车项关系(1:N)** + - 一个用户可以有多个购物车项 + - 一个购物车项只属于一个用户 + - 约束:同一用户对同一商品只能有一个购物车记录 + +3. **用户-对话关系(1:N)** + - 一个用户可以有多个AI对话记录 + - 一个对话记录只属于一个用户 + +##### 2.2.2.2 商品相关关系 + +1. **配件类型-配件关系(1:N)** + - 一个配件类型下可以有多个配件 + - 一个配件只属于一个配件类型 + +2. **配件-订单项关系(1:N)** + - 一个配件可以出现在多个订单项中 + - 一个订单项只对应一个配件 + +3. **配件-购物车项关系(1:N)** + - 一个配件可以被多个用户加入购物车 + - 一个购物车项只对应一个配件 + +##### 2.2.2.3 订单相关关系 + +1. **订单-订单项关系(1:N)** + - 一个订单可以包含多个订单项 + - 一个订单项只属于一个订单 + - 级联删除:删除订单时同时删除所有订单项 + +#### 2.2.3 ER图设计 + +```mermaid +erDiagram + User ||--o{ Order : "下单" + User ||--o{ CartItem : "添加到购物车" + User ||--o{ Conversation : "进行对话" + + ComponentType ||--o{ Component : "分类" + + Component ||--o{ OrderItem : "被订购" + Component ||--o{ CartItem : "被加入购物车" + + Order ||--o{ OrderItem : "包含" + + User { + string id PK + string email UK + string username UK + string password + string name + string phone + string address + boolean isAdmin + datetime createdAt + datetime updatedAt + } + + ComponentType { + string id PK + string name UK + string description + } + + Component { + string id PK + string name + string brand + string model + float price + string description + string imageUrl + int stock + string specifications + string componentTypeId FK + datetime createdAt + datetime updatedAt + } + + Order { + string id PK + string orderNumber UK + float totalAmount + enum status + string userId FK + datetime createdAt + datetime updatedAt + } + + OrderItem { + string id PK + int quantity + float price + string orderId FK + string componentId FK + } + + CartItem { + string id PK + int quantity + string userId FK + string componentId FK + datetime createdAt + datetime updatedAt + } + + Conversation { + string id PK + string title + string messages + string userId FK + datetime createdAt + datetime updatedAt + } +``` + +
系统 ER 图
+ +## 第三章 系统设计 + +### 3.1 数据库设计 + +#### 3.1.1 数据库设计概述 + +本系统采用PostgreSQL作为主数据库,通过Prisma ORM进行数据访问。数据库设计遵循第三范式(3NF),确保数据的一致性和完整性,同时兼顾查询性能和扩展性。数据库设计充分考虑了AI助手功能的特殊需求,包括对话历史的存储和快速检索。 + +#### 3.1.2 数据表详细设计 + +##### 3.1.2.1 用户管理相关表 + +**用户表(users)** + +| 字段名 | 数据类型 | 约束条件 | 说明 | +|--------|----------|----------|------| +| id | VARCHAR(25) | PRIMARY KEY | CUID主键,全局唯一标识符 | +| email | VARCHAR(255) | UNIQUE NOT NULL | 用户邮箱,用于登录和通知 | +| username | VARCHAR(50) | UNIQUE NOT NULL | 用户名,用于显示和登录 | +| password | VARCHAR(255) | NOT NULL | 加密后的密码,使用bcrypt加密 | +| name | VARCHAR(100) | NULL | 真实姓名,可选填写 | +| phone | VARCHAR(20) | NULL | 联系电话,用于订单配送 | +| address | TEXT | NULL | 收货地址,支持多行地址 | +| isAdmin | BOOLEAN | DEFAULT FALSE | 是否为管理员,控制系统权限 | +| createdAt | TIMESTAMP | DEFAULT NOW() | 注册时间,自动记录 | +| updatedAt | TIMESTAMP | DEFAULT NOW() | 最后更新时间,自动维护 | + +**索引设计:** +```sql +-- 邮箱唯一索引(用于登录查询) +CREATE UNIQUE INDEX idx_users_email ON users(email); + +-- 用户名唯一索引(用于登录查询) +CREATE UNIQUE INDEX idx_users_username ON users(username); + +-- 管理员查询索引 +CREATE INDEX idx_users_isAdmin ON users(isAdmin); + +-- 注册时间索引(用于用户增长分析) +CREATE INDEX idx_users_createdAt ON users(createdAt); +``` + +##### 3.1.2.2 商品管理相关表 + +**配件类型表(component_types)** + +| 字段名 | 数据类型 | 约束条件 | 说明 | +|--------|----------|----------|------| +| id | VARCHAR(25) | PRIMARY KEY | 类型唯一标识符 | +| name | VARCHAR(50) | UNIQUE NOT NULL | 类型名称(CPU、内存、硬盘等) | +| description | TEXT | NULL | 类型描述信息 | + +**配件表(components)** + +| 字段名 | 数据类型 | 约束条件 | 说明 | +|--------|----------|----------|------| +| id | VARCHAR(25) | PRIMARY KEY | 配件唯一标识符 | +| name | VARCHAR(255) | NOT NULL | 配件名称 | +| brand | VARCHAR(100) | NOT NULL | 品牌名称 | +| model | VARCHAR(100) | NOT NULL | 型号信息 | +| price | DECIMAL(10,2) | NOT NULL CHECK(price > 0) | 价格,精确到分 | +| description | TEXT | NULL | 详细描述 | +| imageUrl | VARCHAR(500) | NULL | 产品图片URL | +| stock | INTEGER | DEFAULT 0 CHECK(stock >= 0) | 库存数量 | +| specifications | TEXT | NULL | 规格参数(JSON格式) | +| componentTypeId | VARCHAR(25) | NOT NULL | 外键,关联配件类型 | +| createdAt | TIMESTAMP | DEFAULT NOW() | 创建时间 | +| updatedAt | TIMESTAMP | DEFAULT NOW() | 更新时间 | + +**外键约束:** +```sql +ALTER TABLE components +ADD CONSTRAINT fk_components_componentType +FOREIGN KEY (componentTypeId) REFERENCES component_types(id); +``` + +**索引设计:** +```sql +-- 配件类型查询索引 +CREATE INDEX idx_components_typeId ON components(componentTypeId); + +-- 品牌查询索引 +CREATE INDEX idx_components_brand ON components(brand); + +-- 价格范围查询索引 +CREATE INDEX idx_components_price ON components(price); + +-- 库存查询索引 +CREATE INDEX idx_components_stock ON components(stock); + +-- 全文搜索索引 +CREATE INDEX idx_components_search ON components +USING gin(to_tsvector('simple', name || ' ' || brand || ' ' || model)); + +-- 复合索引(类型+价格,常用查询组合) +CREATE INDEX idx_components_type_price ON components(componentTypeId, price); +``` + +##### 3.1.2.3 订单管理相关表 + +**订单表(orders)** + +| 字段名 | 数据类型 | 约束条件 | 说明 | +|--------|----------|----------|------| +| id | VARCHAR(25) | PRIMARY KEY | 订单唯一标识符 | +| orderNumber | VARCHAR(50) | UNIQUE NOT NULL | 订单号,用户可见 | +| totalAmount | DECIMAL(10,2) | NOT NULL CHECK(totalAmount > 0) | 订单总金额 | +| status | order_status_enum | DEFAULT 'PENDING' | 订单状态枚举 | +| userId | VARCHAR(25) | NOT NULL | 外键,关联用户 | +| createdAt | TIMESTAMP | DEFAULT NOW() | 下单时间 | +| updatedAt | TIMESTAMP | DEFAULT NOW() | 状态更新时间 | + +**订单状态枚举:** +```sql +CREATE TYPE order_status_enum AS ENUM ( + 'PENDING', -- 待确认 + 'CONFIRMED', -- 已确认 + 'PROCESSING', -- 处理中 + 'SHIPPED', -- 已发货 + 'DELIVERED', -- 已送达 + 'CANCELLED' -- 已取消 +); +``` + +**订单项表(order_items)** + +| 字段名 | 数据类型 | 约束条件 | 说明 | +|--------|----------|----------|------| +| id | VARCHAR(25) | PRIMARY KEY | 订单项唯一标识符 | +| quantity | INTEGER | DEFAULT 1 CHECK(quantity > 0) | 购买数量 | +| price | DECIMAL(10,2) | NOT NULL CHECK(price > 0) | 下单时的价格 | +| orderId | VARCHAR(25) | NOT NULL | 外键,关联订单 | +| componentId | VARCHAR(25) | NOT NULL | 外键,关联配件 | + +**外键约束:** +```sql +ALTER TABLE orders +ADD CONSTRAINT fk_orders_user +FOREIGN KEY (userId) REFERENCES users(id); + +ALTER TABLE order_items +ADD CONSTRAINT fk_order_items_order +FOREIGN KEY (orderId) REFERENCES orders(id) ON DELETE CASCADE; + +ALTER TABLE order_items +ADD CONSTRAINT fk_order_items_component +FOREIGN KEY (componentId) REFERENCES components(id); +``` + +##### 3.1.2.4 购物车相关表 + +**购物车项表(cart_items)** + +| 字段名 | 数据类型 | 约束条件 | 说明 | +|--------|----------|----------|------| +| id | VARCHAR(25) | PRIMARY KEY | 购物车项唯一标识符 | +| quantity | INTEGER | DEFAULT 1 CHECK(quantity > 0) | 商品数量 | +| userId | VARCHAR(25) | NOT NULL | 外键,关联用户 | +| componentId | VARCHAR(25) | NOT NULL | 外键,关联配件 | +| createdAt | TIMESTAMP | DEFAULT NOW() | 添加时间 | +| updatedAt | TIMESTAMP | DEFAULT NOW() | 更新时间 | + +**唯一约束:** +```sql +-- 确保同一用户对同一商品只有一个购物车记录 +ALTER TABLE cart_items +ADD CONSTRAINT uk_cart_items_user_component +UNIQUE (userId, componentId); +``` + +##### 3.1.2.5 AI对话相关表 + +**对话表(conversations)** + +| 字段名 | 数据类型 | 约束条件 | 说明 | +|--------|----------|----------|------| +| id | VARCHAR(25) | PRIMARY KEY | 对话唯一标识符 | +| title | VARCHAR(255) | NULL | 对话标题,可自动生成 | +| messages | TEXT | NOT NULL | 对话消息JSON数据 | +| userId | VARCHAR(25) | NOT NULL | 外键,关联用户 | +| createdAt | TIMESTAMP | DEFAULT NOW() | 对话创建时间 | +| updatedAt | TIMESTAMP | DEFAULT NOW() | 最后消息时间 | + +**对话消息JSON结构:** +```typescript +interface MessageParam { + role: "user" | "assistant" | "system"; + content: string | ToolUseContent[]; +} + +interface ToolUseContent { + type: "text" | "tool_use" | "tool_result"; + text?: string; + id?: string; + name?: string; + input?: any; + tool_use_id?: string; +} +``` + +### 3.2 模块设计 + +#### 3.2.1 系统架构设计 + +##### 3.2.1.1 总体架构 + +本系统采用现代化的三层架构设计,结合微服务理念,实现了高内聚、低耦合的模块化设计。系统架构如下: + +```mermaid +graph LR + subgraph "前端层" + A[Next.js React应用] + B[响应式UI组件] + C[状态管理] + D[路由管理] + end + + subgraph "API网关层" + E[Next.js API Routes] + F[认证中间件] + G[权限控制] + H[请求验证] + end + + subgraph "业务逻辑层" + I[用户服务] + J[商品服务] + K[订单服务] + L[AI助手服务] + M[统计分析服务] + end + + subgraph "数据访问层" + N[Prisma ORM] + O[数据库连接池] + P[缓存层Redis] + end + + subgraph "外部服务层" + Q[Anthropic Claude API] + R[OpenAI API] + S[文件存储服务] + end + + subgraph "数据存储层" + T[PostgreSQL主数据库] + U[Redis缓存数据库] + end + + A --> E + B --> E + C --> E + D --> E + + E --> I + E --> J + E --> K + E --> L + E --> M + + F --> E + G --> E + H --> E + + I --> N + J --> N + K --> N + L --> N + M --> N + + L --> Q + L --> R + + N --> T + O --> T + P --> U +``` + +
系统总体架构图
+ +##### 3.2.1.2 技术架构特点 + +**前端架构特点:** +- **Server-Side Rendering (SSR)**:提升首屏加载速度和SEO效果 +- **Client-Side Rendering (CSR)**:动态页面的流畅交互体验 +- **Static Site Generation (SSG)**:静态页面的极致性能 +- **Incremental Static Regeneration (ISR)**:静态页面的增量更新 + +**后端架构特点:** +- **API-First设计**:前后端分离,支持多端复用 +- **无状态设计**:基于JWT的无状态认证,支持水平扩展 +- **微服务化**:按业务领域划分服务,便于维护和扩展 +- **函数式编程**:利用Next.js API Routes的函数式特性 + +#### 3.2.2 核心模块设计 + +##### 3.2.2.1 用户认证与权限模块 + +**模块职责:** +- 用户注册、登录、注销 +- JWT令牌生成和验证 +- 权限检查和访问控制 +- 密码安全管理 + +**核心流程设计:** + +```mermaid +flowchart TD + A[用户登录请求] --> B[验证用户名/邮箱] + B --> C{用户是否存在?} + C -->|否| D[返回用户不存在错误] + C -->|是| E[验证密码] + E --> F{密码是否正确?} + F -->|否| G[返回密码错误] + F -->|是| H[生成JWT令牌] + H --> I[返回用户信息和令牌] + I --> J[前端存储令牌] + J --> K[后续请求携带令牌] + K --> L[中间件验证令牌] + L --> M{令牌是否有效?} + M -->|否| N[返回401未授权] + M -->|是| O[解析用户信息] + O --> P[检查访问权限] + P --> Q{权限是否足够?} + Q -->|否| R[返回403禁止访问] + Q -->|是| S[处理业务请求] +``` + +
用户认证流程图
+ +**技术实现细节:** + +```typescript +// JWT令牌生成 +export function generateToken(user: User): string { + const payload = { + userId: user.id, + email: user.email, + isAdmin: user.isAdmin, + iat: Math.floor(Date.now() / 1000), + exp: Math.floor(Date.now() / 1000) + (7 * 24 * 60 * 60) // 7天过期 + } + + return jwt.sign(payload, process.env.JWT_SECRET!) +} + +// 权限验证中间件 +export function requireAuth(request: NextRequest): TokenPayload { + const authHeader = request.headers.get('authorization') + if (!authHeader || !authHeader.startsWith('Bearer ')) { + throw new AuthError('请先登录') + } + + const token = authHeader.substring(7) + const decoded = verifyToken(token) + if (!decoded) { + throw new AuthError('登录已过期') + } + + return decoded +} + +// 管理员权限检查 +export async function requireAdmin(request: NextRequest): Promise { + const decoded = requireAuth(request) + if (!decoded.isAdmin) { + throw new AuthError('权限不足') + } +} +``` + +##### 3.2.2.2 商品管理模块 + +**模块职责:** +- 配件分类管理 +- 商品信息CRUD操作 +- 库存管理和控制 +- 批量数据导入导出 +- 商品搜索和筛选 + +**商品查询流程设计:** + +```mermaid +flowchart TD + A[商品查询请求] --> B[解析查询参数] + B --> C[构建查询条件] + C --> D{是否有缓存?} + D -->|是| E[返回缓存数据] + D -->|否| F[查询数据库] + F --> G[应用过滤条件] + G --> H[执行分页查询] + H --> I[计算统计信息] + I --> J[格式化返回数据] + J --> K[更新缓存] + K --> L[返回查询结果] +``` + +
商品查询流程图
+ +**核心服务实现:** + +```typescript +export class ComponentService { + // 智能商品查询 + static async queryComponents(params: ComponentQueryParams): Promise { + const { + type, typeId, brand, minPrice, maxPrice, search, page = 1, limit = 12 + } = params + + // 构建动态查询条件 + const where: any = {} + + // 配件类型筛选 + if (typeId) { + where.componentTypeId = typeId + } else if (type) { + const componentType = await prisma.componentType.findFirst({ + where: { name: { contains: type, mode: 'insensitive' } } + }) + if (componentType) { + where.componentTypeId = componentType.id + } + } + + // 品牌筛选 + if (brand) { + where.brand = { contains: brand, mode: 'insensitive' } + } + + // 价格范围筛选 + if (minPrice || maxPrice) { + where.price = {} + if (minPrice) where.price.gte = minPrice + if (maxPrice) where.price.lte = maxPrice + } + + // 全文搜索 + if (search) { + where.OR = [ + { name: { contains: search, mode: 'insensitive' } }, + { brand: { contains: search, mode: 'insensitive' } }, + { model: { contains: search, mode: 'insensitive' } }, + { description: { contains: search, mode: 'insensitive' } } + ] + } + + // 并行查询数据和总数 + const [components, total] = await Promise.all([ + prisma.component.findMany({ + where, + include: { componentType: true }, + orderBy: { createdAt: 'desc' }, + skip: (page - 1) * limit, + take: limit + }), + prisma.component.count({ where }) + ]) + + return { + components: components.map(formatComponent), + pagination: { + page, limit, total, + totalPages: Math.ceil(total / limit), + hasNext: page < Math.ceil(total / limit), + hasPrev: page > 1 + } + } + } + + // 批量导入商品 + static async batchImport(components: ComponentImportData[]): Promise { + const results = [] + let successful = 0 + let failed = 0 + let newTypesCreated = 0 + + for (const item of components) { + try { + // 检查或创建配件类型 + let componentType = await prisma.componentType.findFirst({ + where: { name: item.typeName } + }) + + if (!componentType) { + componentType = await prisma.componentType.create({ + data: { name: item.typeName, description: `${item.typeName}配件` } + }) + newTypesCreated++ + } + + // 创建配件 + const component = await prisma.component.create({ + data: { + name: item.name, + brand: item.brand, + model: item.model, + price: item.price, + description: item.description, + imageUrl: item.imageUrl, + stock: item.stock, + specifications: item.specifications, + componentTypeId: componentType.id + } + }) + + results.push({ success: true, item, component }) + successful++ + } catch (error) { + results.push({ success: false, item, error: error.message }) + failed++ + } + } + + return { + summary: { successful, failed, total: components.length, newTypesCreated }, + results + } + } +} +``` + +##### 3.2.2.3 订单管理模块 + +**模块职责:** +- 购物车管理 +- 订单创建和处理 +- 库存扣减和恢复 +- 订单状态管理 +- 订单统计分析 + +**订单处理流程设计:** + +```mermaid +flowchart TD + A[用户提交订单] --> B[验证用户身份] + B --> C[验证商品信息] + C --> D[检查库存充足性] + D --> E{库存是否充足?} + E -->|否| F[返回库存不足错误] + E -->|是| G[开始数据库事务] + G --> H[创建订单记录] + H --> I[创建订单项记录] + I --> J[扣减商品库存] + J --> K[清空购物车] + K --> L[提交事务] + L --> M[发送订单确认] + M --> N[返回订单信息] + + O[订单取消请求] --> P[验证订单状态] + P --> Q{状态是否允许取消?} + Q -->|否| R[返回状态错误] + Q -->|是| S[开始数据库事务] + S --> T[更新订单状态为已取消] + T --> U[恢复商品库存] + U --> V[提交事务] + V --> W[发送取消通知] +``` + +
订单处理流程图
+ +##### 3.2.2.4 AI助手模块 + +**模块职责:** +- AI对话管理 +- 工具调用处理 +- 流式响应处理 +- 对话历史存储 +- 上下文管理 + +**AI交互流程设计:** + +```mermaid +flowchart TD + A[用户发送消息] --> B[创建或加载对话] + B --> C[构建消息历史] + C --> D[调用AI模型API] + D --> E[处理流式响应] + E --> F{是否包含工具调用?} + F -->|否| G[直接返回AI回复] + F -->|是| H[解析工具调用参数] + H --> I[执行工具调用] + I --> J{工具类型判断} + J -->|查询配件| K[调用商品服务查询] + J -->|展示配件| L[格式化配件信息] + K --> M[返回查询结果给AI] + L --> M + M --> N[AI处理工具结果] + N --> O[生成最终回复] + O --> P[保存对话历史] + P --> Q[返回给用户] + G --> P +``` + +
AI交互流程图
+ +**AI助手核心实现:** + +```typescript +// 见5.1.2 +``` + +##### 3.2.2.5 数据统计分析模块 + +**模块职责:** +- 用户消费统计 +- 商品销售统计 +- 趋势分析 +- 数据可视化 +- 报表生成 + +**统计分析流程设计:** + +```mermaid +flowchart TD + A[统计请求] --> B[验证管理员权限] + B --> C[解析统计参数] + C --> D[并行执行多个统计查询] + D --> E[用户消费排行] + D --> F[商品销量排行] + D --> G[总体数据统计] + D --> H[最近订单查询] + E --> I[数据格式化] + F --> I + G --> I + H --> I + I --> J[构建响应数据] + J --> K[返回统计结果] +``` + +
数据统计流程图
+ +**统计服务实现:** + +```typescript +export class StatsService { + // 管理员数据统计 + static async getAdminStats(): Promise { + // 并行执行多个统计查询,提升性能 + const [ + topUsersBySpending, + topComponentsBySales, + overviewStats, + recentOrders + ] = await Promise.all([ + this.getTopUsersBySpending(), + this.getTopComponentsBySales(), + this.getOverviewStats(), + this.getRecentOrders() + ]) + + return { + overview: overviewStats, + topUsers: topUsersBySpending, + topComponents: topComponentsBySales, + recentOrders + } + } + + // 用户消费排行榜 + private static async getTopUsersBySpending() { + const users = await prisma.user.findMany({ + where: { + isAdmin: false, + orders: { some: {} } + }, + select: { + id: true, + username: true, + name: true, + email: true, + orders: { + where: { + status: { in: ['CONFIRMED', 'SHIPPED', 'DELIVERED'] } + }, + select: { totalAmount: true } + } + }, + take: 50 // 先取更多数据,再排序截取 + }) + + return users + .map(user => ({ + id: user.id, + username: user.username, + name: user.name || user.username, + email: user.email, + totalSpending: user.orders.reduce((sum, order) => sum + order.totalAmount, 0), + orderCount: user.orders.length + })) + .sort((a, b) => b.totalSpending - a.totalSpending) + .slice(0, 10) + } + + // 商品销量排行榜 + private static async getTopComponentsBySales() { + const components = await prisma.component.findMany({ + select: { + id: true, + name: true, + brand: true, + price: true, + componentType: { select: { name: true } }, + orderItems: { + where: { + order: { + status: { in: ['CONFIRMED', 'SHIPPED', 'DELIVERED'] } + } + }, + select: { quantity: true } + } + } + }) + + return components + .map(component => ({ + id: component.id, + name: component.name, + brand: component.brand, + price: component.price, + typeName: component.componentType.name, + totalSales: component.orderItems.reduce((sum, item) => sum + item.quantity, 0), + totalRevenue: component.orderItems.reduce((sum, item) => sum + (item.quantity * component.price), 0) + })) + .sort((a, b) => b.totalSales - a.totalSales) + .slice(0, 10) + } + + // 总体统计数据 + private static async getOverviewStats() { + const [totalUsers, totalOrders, totalComponents, totalRevenue] = await Promise.all([ + prisma.user.count({ where: { isAdmin: false } }), + prisma.order.count(), + prisma.component.count(), + prisma.order.aggregate({ + where: { + status: { in: ['CONFIRMED', 'SHIPPED', 'DELIVERED'] } + }, + _sum: { totalAmount: true } + }) + ]) + + return { + totalUsers, + totalOrders, + totalComponents, + totalRevenue: totalRevenue._sum.totalAmount || 0 + } + } +} +``` + +#### 3.2.3 模块间通信设计 + +##### 3.2.3.1 API设计规范 + +**RESTful API设计原则:** +- **资源命名**:使用名词表示资源,复数形式 +- **HTTP方法**:GET(查询)、POST(创建)、PUT(更新)、DELETE(删除) +- **状态码**:200(成功)、201(创建成功)、400(请求错误)、401(未授权)、403(禁止访问)、404(未找到)、500(服务器错误) +- **统一响应格式**:成功和错误都有统一的数据结构 + +**API路由设计:** +``` +/api/auth/ + POST /login # 用户登录 + POST /register # 用户注册 + +/api/components/ + GET / # 获取配件列表 + GET /:id # 获取配件详情 + POST /batch # 批量导入配件 + +/api/orders/ + GET / # 获取订单列表 + POST / # 创建订单 + GET /:id # 获取订单详情 + PUT /:id # 更新订单状态 + +/api/cart/ + GET / # 获取购物车 + POST / # 添加到购物车 + PUT /:id # 更新购物车项 + DELETE /:id # 删除购物车项 + +/api/ai/ + POST / # AI对话 + GET /conversations # 获取对话列表 + GET /conversations/:id # 获取对话详情 + +/api/admin/ + GET /stats # 管理员统计数据 + GET /orders # 管理员订单管理 + GET /components # 管理员商品管理 +``` + +这种模块化设计确保了系统的高内聚、低耦合特性,每个模块都有明确的职责边界,模块间通过标准化的API进行通信,便于维护、测试和扩展。同时,完善的错误处理和数据验证机制保证了系统的稳定性和安全性。 + +## 第四章 系统实现 + +### 4.1 项目介绍 + +#### 4.1.1 项目整体架构 + +本在线电脑DIY系统采用现代化的全栈Web开发架构,基于Next.js 15.3.4框架构建,实现了前后端一体化的开发模式。系统不仅满足了课程设计的基本要求,更在此基础上集成了AI智能助手功能,为用户提供专业的配件咨询和推荐服务。 + +系统采用三层架构设计: +- **表现层(Presentation Layer)**:基于React 19.0.0和Tailwind CSS 4.x构建的现代化用户界面 +- **业务逻辑层(Business Logic Layer)**:Next.js API Routes实现的RESTful API服务 +- **数据访问层(Data Access Layer)**:Prisma ORM + PostgreSQL数据库 + +#### 4.1.2 项目目录结构详解 + +基于文件系统的分析,本项目采用Next.js 13+的App Router架构,具有清晰的模块化组织结构: + +``` +pc-diy-store/ +├── app/ # Next.js 13+ App Router核心目录 +│ ├── globals.css # 全局样式文件 +│ ├── layout.tsx # 根布局组件 +│ ├── page.tsx # 首页组件 +│ ├── favicon.ico # 网站图标 +│ │ +│ ├── api/ # API路由目录 +│ │ ├── auth/ # 认证相关API +│ │ │ ├── login/route.ts # 用户登录接口 +│ │ │ └── register/route.ts # 用户注册接口 +│ │ ├── admin/ # 管理员专用API +│ │ │ ├── components/route.ts # 配件管理接口 +│ │ │ ├── orders/route.ts # 订单管理接口 +│ │ │ └── stats/route.ts # 统计数据接口 +│ │ ├── ai/ # AI助手API +│ │ │ ├── route.ts # AI对话接口 +│ │ │ └── conversations/ # 对话管理 +│ │ │ ├── route.ts # 对话列表接口 +│ │ │ └── [id]/route.ts # 单个对话接口 +│ │ ├── components/ # 配件相关API +│ │ │ ├── route.ts # 配件查询/创建接口 +│ │ │ ├── [id]/route.ts # 单个配件操作接口 +│ │ │ └── batch/route.ts # 批量操作接口 +│ │ ├── cart/ # 购物车API +│ │ │ ├── route.ts # 购物车操作接口 +│ │ │ └── [id]/route.ts # 购物车项操作接口 +│ │ ├── orders/ # 订单API +│ │ │ ├── route.ts # 订单操作接口 +│ │ │ └── [id]/route.ts # 单个订单接口 +│ │ ├── user/ # 用户API +│ │ │ ├── profile/route.ts # 用户资料接口 +│ │ │ ├── stats/route.ts # 用户统计接口 +│ │ │ └── change-password/route.ts # 密码修改接口 +│ │ └── component-types/route.ts # 配件类型接口 +│ │ +│ ├── admin/ # 管理后台页面 +│ │ ├── page.tsx # 管理后台首页 +│ │ ├── components/page.tsx # 配件管理页面 +│ │ └── orders/page.tsx # 订单管理页面 +│ │ +│ ├── ai-assistant/ # AI助手页面 +│ │ └── page.tsx # AI对话界面 +│ │ +│ ├── build/ # 装机配置页面 +│ │ └── page.tsx # 装机配置界面 +│ │ +│ ├── cart/ # 购物车页面 +│ │ └── page.tsx # 购物车界面 +│ │ +│ ├── components/ # 配件浏览页面 +│ │ ├── page.tsx # 配件列表页面 +│ │ └── [id]/page.tsx # 配件详情页面 +│ │ +│ ├── login/ # 用户登录页面 +│ │ └── page.tsx # 登录界面 +│ │ +│ ├── register/ # 用户注册页面 +│ │ └── page.tsx # 注册界面 +│ │ +│ ├── orders/ # 订单管理页面 +│ │ ├── page.tsx # 订单列表页面 +│ │ └── [id]/page.tsx # 订单详情页面 +│ │ +│ └── profile/ # 个人中心页面 +│ └── page.tsx # 用户资料界面 +│ +├── components/ # 可复用React组件 +│ ├── Navbar.tsx # 导航栏组件 +│ ├── ComponentCard.tsx # 配件卡片组件 +│ ├── AddToCartButton.tsx # 添加购物车按钮组件 +│ └── admin/ # 管理员专用组件 +│ └── AdminAuth.tsx # 管理员认证组件 +│ +├── lib/ # 工具库和服务 +│ ├── prisma.ts # Prisma数据库客户端 +│ ├── auth.ts # 认证工具函数 +│ ├── admin-auth.ts # 管理员认证工具 +│ ├── ai-assistant.ts # AI助手核心逻辑(Anthropic Claude) +│ ├── ai-assistant-openai.ts # AI助手备用实现(OpenAI) +│ ├── markdown-it.ts # Markdown渲染工具 +│ └── services/ # 业务服务层 +│ ├── component-service.ts # 配件业务逻辑 +│ └── conversation-service.ts # 对话管理业务逻辑 +│ +├── prisma/ # 数据库相关 +│ ├── schema.prisma # 数据库模式定义 +│ └── migrations/ # 数据库迁移文件 +│ ├── migration_lock.toml # 迁移锁定文件 +│ ├── 20250621121352_init/ # 初始数据库结构 +│ ├── 20250622010446_add_cart_items/ # 购物车功能 +│ └── 20250623095809_add_ai_conversations_json/ # AI对话功能 +│ +├── public/ # 静态资源 +│ ├── next.svg # Next.js logo +│ ├── vercel.svg # Vercel logo +│ └── [其他静态文件] +│ +├── package.json # 项目配置和依赖 +├── next.config.ts # Next.js配置 +├── tsconfig.json # TypeScript配置 +├── postcss.config.mjs # PostCSS配置 +├── bun.lock # Bun包管理器锁定文件 +└── seed.ts # 数据库种子数据 +``` + +#### 4.1.3 核心文件功能详解 + +##### 4.1.3.1 应用入口文件 + +**app/layout.tsx - 根布局组件** + +```typescript +export default function RootLayout({ + children, +}: Readonly<{ + children: React.ReactNode; +}>) { + return ( + + + +
+ {children} +
+ + + ); +} +``` + +该文件是整个应用的根布局,负责: +- 设置HTML文档的基本结构和语言 +- 加载全局字体和样式 +- 渲染全局导航栏组件 +- 为页面内容提供滚动容器 + +![image-20250624224433427](./%E5%9C%A8%E7%BA%BF%E7%94%B5%E8%84%91DIY%E7%B3%BB%E7%BB%9F.assets/image-20250624224433427.png) + +
Layout 说明
+ +**app/page.tsx - 系统首页** +首页实现了项目要求的企业介绍和配件展示功能: + +- 企业品牌宣传区域 +- 各类配件的分类展示 +- 响应式设计适配多种设备 +- 无需登录即可浏览所有配件信息 + +##### 4.1.3.2 API路由系统 + +**认证系统 (app/api/auth/)** + +- `login/route.ts`: 实现用户登录验证,包括密码加密验证和JWT Token生成 +- `register/route.ts`: 处理用户注册,包括数据验证、密码加密存储 + +**配件管理系统 (app/api/components/)** +- `route.ts`: 提供配件的CRUD操作,支持分页查询、条件筛选 +- `[id]/route.ts`: 单个配件的详细操作 +- `batch/route.ts`: 批量导入配件数据,支持CSV和JSON格式 + +**AI助手系统 (app/api/ai/)** +- `route.ts`: 核心AI对话接口,实现流式响应 +- `conversations/`: 对话历史管理,支持创建、查询、删除对话 + +##### 4.1.3.3 前端页面组件 + +**配件浏览系统 (app/components/)** + +```typescript +// 配件列表页面支持高级筛选功能 +const [filters, setFilters] = useState({ + search: '', + type: '', + brand: '', + minPrice: '', + maxPrice: '' +}) +``` + +实现功能: +- 多条件筛选(类型、品牌、价格区间、关键词) +- 分页展示 +- 响应式网格布局 +- 实时搜索 + +![image-20250624224518152](./%E5%9C%A8%E7%BA%BF%E7%94%B5%E8%84%91DIY%E7%B3%BB%E7%BB%9F.assets/image-20250624224518152.png) + +
配件商城 - 支持筛选与搜索
+ +**装机配置系统 (app/build/)** +独特的装机配置功能,允许用户: + +- 从每种配件类型中选择一个配件 +- 实时计算总价 +- 配置进度跟踪 +- 一键添加到购物车 + +![image-20250624224542337](./%E5%9C%A8%E7%BA%BF%E7%94%B5%E8%84%91DIY%E7%B3%BB%E7%BB%9F.assets/image-20250624224542337.png) + +
整机配置界面
+ +**AI助手界面 (app/ai-assistant/)** +创新的AI对话功能: +- 对话历史侧边栏 +- 流式打字机效果 +- 配件卡片展示 +- 多轮对话支持 + +![image-20250624224618803](./%E5%9C%A8%E7%BA%BF%E7%94%B5%E8%84%91DIY%E7%B3%BB%E7%BB%9F.assets/image-20250624224618803.png) + +
AI 助手协助分析需求、搜索配件
+ +##### 4.1.3.4 业务逻辑层 + +**lib/services/component-service.ts - 配件服务** +核心业务逻辑封装: + +```typescript +export class ComponentService { + static async queryComponents(params: ComponentQueryParams): Promise { + // 复杂查询逻辑 + const where: any = {} + + // 类型筛选 + if (typeId) { + where.componentTypeId = typeId + } else if (type) { + const componentType = await prisma.componentType.findFirst({ + where: { name: { contains: type, mode: 'insensitive' } } + }) + if (componentType) { + where.componentTypeId = componentType.id + } + } + + // 价格范围筛选 + if (minPrice || maxPrice) { + where.price = {} + if (minPrice) where.price.gte = minPrice + if (maxPrice) where.price.lte = maxPrice + } + + // 多字段模糊搜索 + if (search) { + where.OR = [ + { name: { contains: search, mode: 'insensitive' } }, + { brand: { contains: search, mode: 'insensitive' } }, + { model: { contains: search, mode: 'insensitive' } }, + { description: { contains: search, mode: 'insensitive' } } + ] + } + + // 并行查询数据和总数 + const [components, total] = await Promise.all([ + prisma.component.findMany({ + where, + include: { componentType: true }, + orderBy: { createdAt: 'desc' }, + skip: (page - 1) * limit, + take: limit + }), + prisma.component.count({ where }) + ]) + + return { + components: formatComponents(components), + pagination: calculatePagination(page, limit, total) + } + } +} +``` + +**lib/services/conversation-service.ts - 对话服务** +AI对话管理的完整实现: +- 对话创建和初始化 +- 消息历史的JSON存储和检索 +- 对话标题自动生成 +- 对话删除和清理 + +##### 4.1.3.5 AI助手核心实现 + +**lib/ai-assistant.ts - AI助手引擎** +本系统的最大亮点是完整实现的AI助手功能: + +```typescript +export class AIClient { + private anthropic: Anthropic; + private tools: Tool[] = [ + { + name: "query-components", + description: "查询PC配件信息,支持按类型、品牌、价格范围、关键词等条件搜索", + input_schema: { + type: "object", + properties: { + type: { type: "string", enum: ["CPU", "内存", "硬盘", "主板", "显卡", "机箱"] }, + brand: { type: "string", description: "品牌名称" }, + minPrice: { type: "number", description: "最低价格" }, + maxPrice: { type: "number", description: "最高价格" }, + search: { type: "string", description: "搜索关键词" } + } + } + }, + { + name: "show-components", + description: "向用户以卡片形式展示一个或多个具体型号的配件", + input_schema: { + type: "object", + properties: { + component_ids: { + type: "array", + items: { type: "string" }, + description: "要展示的配件ID数组" + } + } + } + } + ]; + + async *processQuery(query: string, userId: string, conversationId?: string): AsyncGenerator { + // 流式AI响应处理 + // 工具调用处理 + // 对话历史管理 + // 具体分析见 5.1.2 + } +} +``` + +AI助手的核心特性: +1. **工具调用能力**:AI可以主动调用系统API查询实时数据 +2. **流式响应**:实现打字机效果的实时对话体验 +3. **多轮对话**:支持上下文保持的连续对话 + +##### 4.1.3.6 数据库层 + +**prisma/schema.prisma - 数据模型定义** +完整的数据库模式设计,包括: +- 用户和权限管理 +- 配件和分类管理 +- 购物车和订单系统 +- AI对话历史存储 + +### 4.2 系统功能实现 + +#### 4.2.1 用户界面展示与功能实现 + +##### 4.2.1.1 系统首页实现 + +**功能概述:** +系统首页完全满足课程设计要求,实现了企业介绍和配件展示功能,无需登录即可浏览所有配件信息。 + +**核心实现代码:** + +```typescript +// app/page.tsx - 首页实现 +export default async function Home() { + // 获取每种配件类型的前几个商品 + const componentTypes = await prisma.componentType.findMany({ + include: { + components: { + take: 6, + orderBy: { createdAt: 'desc' } + } + } + }) + + return ( +
+ {/* Hero Section - 企业介绍 */} +
+
+

+ 欢迎来到PC DIY商城 +

+

+ 专业的电脑配件在线选购平台,让您轻松打造梦想主机 +

+
+
+ + {/* 配件分类展示 */} +
+
+

热门配件

+ {componentTypes.map((type) => ( +
+
+

{type.name}

+ + 查看更多 → + +
+
+ {type.components.map((component) => ( + + ))} +
+
+ ))} +
+
+
+ ) +} +``` + +**页面功能特点:** +1. **企业品牌展示**:渐变背景的Hero区域,突出品牌形象 +2. **配件分类展示**:按照CPU、内存、硬盘、主板、显卡、机箱分类展示 +3. **响应式设计**:适配桌面、平板、手机等多种设备 +4. **快速导航**:每个分类都有"查看更多"链接,方便用户深入浏览 + +![image-20250624224758346](./%E5%9C%A8%E7%BA%BF%E7%94%B5%E8%84%91DIY%E7%B3%BB%E7%BB%9F.assets/image-20250624224758346.png) + +
系统首页 - 上
+ +![image-20250624224823525](./%E5%9C%A8%E7%BA%BF%E7%94%B5%E8%84%91DIY%E7%B3%BB%E7%BB%9F.assets/image-20250624224823525.png) + +
系统首页 - 下
+ +##### 4.2.1.2 用户认证系统实现 + +**用户注册功能:** + +```typescript +// app/register/page.tsx - 注册页面核心逻辑 +const handleSubmit = async (e: React.FormEvent) => { + e.preventDefault() + + if (formData.password !== formData.confirmPassword) { + setError('两次密码输入不一致') + return + } + + try { + const response = await fetch('/api/auth/register', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ + email: formData.email, + username: formData.username, + password: formData.password, + name: formData.name + }) + }) + + if (response.ok) { + router.push('/login?message=注册成功,请登录') + } else { + const data = await response.json() + setError(data.message || '注册失败') + } + } catch (error) { + setError('网络错误,请稍后重试') + } +} +``` + +![image-20250624224919550](./%E5%9C%A8%E7%BA%BF%E7%94%B5%E8%84%91DIY%E7%B3%BB%E7%BB%9F.assets/image-20250624224919550.png) + +
用户注册
+ +**用户登录功能:** + +```typescript +// app/api/auth/login/route.ts - 登录API实现 +export async function POST(request: NextRequest) { + try { + const { identifier, password } = await request.json() + + // 支持邮箱或用户名登录 + const user = await prisma.user.findFirst({ + where: { + OR: [ + { email: identifier }, + { username: identifier } + ] + } + }) + + if (!user) { + return NextResponse.json( + { message: '用户不存在' }, + { status: 401 } + ) + } + + // 验证密码 + const isValidPassword = await verifyPassword(password, user.password) + if (!isValidPassword) { + return NextResponse.json( + { message: '密码错误' }, + { status: 401 } + ) + } + + // 生成JWT Token + const token = generateToken({ + userId: user.id, + email: user.email, + username: user.username, + isAdmin: user.isAdmin + }) + + return NextResponse.json({ + message: '登录成功', + token, + user: { + id: user.id, + email: user.email, + username: user.username, + name: user.name, + isAdmin: user.isAdmin + } + }) + } catch (error) { + return NextResponse.json( + { message: '登录失败' }, + { status: 500 } + ) + } +} +``` + +![image-20250624224906899](./%E5%9C%A8%E7%BA%BF%E7%94%B5%E8%84%91DIY%E7%B3%BB%E7%BB%9F.assets/image-20250624224906899-1750777204806-1.png) + +
用户登录
+ +**认证功能特点:** + +1. **双重登录支持**:支持邮箱或用户名登录 +2. **密码安全**:使用bcrypt加密存储密码 +3. **JWT认证**:无状态的Token认证机制 +4. **表单验证**:前端实时验证和后端数据验证 + +##### 4.2.1.3 配件浏览和搜索系统 + +**配件列表页面实现:** + +```typescript +// app/components/page.tsx - 配件浏览核心功能 +export default function ComponentsPage() { + const [components, setComponents] = useState([]) + const [filters, setFilters] = useState({ + search: '', // 关键词搜索 + type: '', // 配件类型 + brand: '', // 品牌筛选 + minPrice: '', // 最低价格 + maxPrice: '' // 最高价格 + }) + + const fetchComponents = async () => { + const searchParams = new URLSearchParams() + if (filters.search) searchParams.set('search', filters.search) + if (filters.type) searchParams.set('type', filters.type) + if (filters.brand) searchParams.set('brand', filters.brand) + if (filters.minPrice) searchParams.set('minPrice', filters.minPrice) + if (filters.maxPrice) searchParams.set('maxPrice', filters.maxPrice) + searchParams.set('page', pagination.page.toString()) + searchParams.set('limit', pagination.limit.toString()) + + const response = await fetch(`/api/components?${searchParams}`) + if (response.ok) { + const data = await response.json() + setComponents(data.components) + setPagination(data.pagination) + } + } + + return ( +
+ {/* 搜索和筛选区域 */} +
+
+ {/* 关键词搜索 */} +
+ + setFilters({...filters, search: e.target.value})} + className="w-full pl-10 pr-4 py-2 border border-gray-300 rounded-md" + /> +
+ + {/* 配件类型筛选 */} + + + {/* 价格区间筛选 */} + setFilters({...filters, minPrice: e.target.value})} + className="w-full px-3 py-2 border border-gray-300 rounded-md" + /> + setFilters({...filters, maxPrice: e.target.value})} + className="w-full px-3 py-2 border border-gray-300 rounded-md" + /> +
+
+ + {/* 配件展示网格 */} +
+ {components.map((component) => ( + + ))} +
+ + {/* 分页控件 */} + +
+ ) +} +``` + +**配件卡片组件实现:** +```typescript +// components/ComponentCard.tsx - 配件展示卡片 +export function ComponentCard({ component }: { component: Component }) { + return ( +
+ +
+ {component.imageUrl ? ( + {component.name} + ) : ( +
+ +
+ )} +
+ +
+

+ {component.name} +

+

+ {component.brand} | {component.model} +

+
+ + ¥{component.price.toFixed(2)} + + 0 ? 'text-green-600' : 'text-red-600'}`}> + {component.stock > 0 ? `库存${component.stock}` : '缺货'} + +
+
+ + +
+ +
+
+ ) +} +``` + +**搜索功能特点:** +1. **多维度筛选**:支持类型、品牌、价格区间、关键词搜索 +2. **实时搜索**:用户输入时实时更新结果 +3. **分页展示**:大数据量的分页处理 +4. **响应式布局**:自适应网格布局系统 + +![image-20250624224518152](./%E5%9C%A8%E7%BA%BF%E7%94%B5%E8%84%91DIY%E7%B3%BB%E7%BB%9F.assets/image-20250624224518152.png) + +
配件商城 - 支持筛选与搜索
+ +![image-20250624225019124](./%E5%9C%A8%E7%BA%BF%E7%94%B5%E8%84%91DIY%E7%B3%BB%E7%BB%9F.assets/image-20250624225019124.png) + +
配件详情页
+ +##### 4.2.1.4 购物车和订单系统 + +**购物车功能实现:** + +```typescript +// app/cart/page.tsx - 购物车页面 +export default function CartPage() { + const [cartItems, setCartItems] = useState([]) + + const updateQuantity = async (itemId: string, newQuantity: number) => { + const token = localStorage.getItem('token') + + if (newQuantity === 0) { + // 删除商品 + await fetch(`/api/cart/${itemId}`, { + method: 'DELETE', + headers: { 'Authorization': `Bearer ${token}` } + }) + } else { + // 更新数量 + await fetch(`/api/cart/${itemId}`, { + method: 'PUT', + headers: { + 'Content-Type': 'application/json', + 'Authorization': `Bearer ${token}` + }, + body: JSON.stringify({ quantity: newQuantity }) + }) + } + + loadCart() // 重新加载购物车 + } + + const checkout = async () => { + if (cartItems.length === 0) { + alert('购物车为空') + return + } + + try { + const token = localStorage.getItem('token') + const response = await fetch('/api/orders', { + // ... + }) + + if (response.ok) { + const order = await response.json() + alert(`订单创建成功!订单号:${order.orderNumber}`) + // 清空购物车 + await fetch('/api/cart', { + method: 'DELETE', + headers: { 'Authorization': `Bearer ${token}` } + }) + router.push(`/orders/${order.id}`) + } + } catch (error) { + alert('结算失败,请稍后重试') + } + } + + return ( +
+

购物车

+ + {cartItems.length === 0 ? ( +
+ +

购物车是空的

+
+ ) : ( +
+ {/* 购物车商品列表 */} +
+ {cartItems.map(item => ( + + ))} +
+ + {/* 订单摘要 */} +
+

订单摘要

+
+
+ 商品总价: + ¥{getTotalPrice().toFixed(2)} +
+
+ 总计: + ¥{getTotalPrice().toFixed(2)} +
+
+ +
+
+ )} +
+ ) +} +``` + +![image-20250624225113890](./%E5%9C%A8%E7%BA%BF%E7%94%B5%E8%84%91DIY%E7%B3%BB%E7%BB%9F.assets/image-20250624225113890.png) + +
购物车页面
+ +**订单管理实现:** + +```typescript +// app/api/orders/route.ts - 订单创建API +export async function POST(request: NextRequest) { + try { + const { items } = await request.json() + const authHeader = request.headers.get('authorization') + const token = authHeader?.substring(7) + const decoded = verifyToken(token!) + + if (!decoded) { + return NextResponse.json({ message: '请先登录' }, { status: 401 }) + } + + // 生成订单号 + const orderNumber = `ORD${Date.now()}${Math.random().toString(36).substr(2, 6).toUpperCase()}` + + let totalAmount = 0 + const orderItems: any[] = [] + + // 验证配件和计算总价 + for (const item of items) { + const component = await prisma.component.findUnique({ + where: { id: item.componentId } + }) + + if (!component) { + return NextResponse.json( + { message: `配件不存在: ${item.componentId}` }, + { status: 400 } + ) + } + + if (component.stock < item.quantity) { + return NextResponse.json( + { message: `配件库存不足: ${component.name}` }, + { status: 400 } + ) + } + + const itemTotal = component.price * item.quantity + totalAmount += itemTotal + + orderItems.push({ + componentId: component.id, + quantity: item.quantity, + price: component.price + }) + } + + // 创建订单 + const order = await prisma.order.create({ + data: { + orderNumber, + totalAmount, + userId: decoded.userId, + orderItems: { create: orderItems } + }, + include: { + orderItems: { + include: { + component: { + include: { componentType: true } + } + } + } + } + }) + + // 更新库存 + for (const item of items) { + await prisma.component.update({ + where: { id: item.componentId }, + data: { stock: { decrement: item.quantity } } + }) + } + + return NextResponse.json(order, { status: 201 }) + } catch (error) { + return NextResponse.json({ message: '创建订单失败' }, { status: 500 }) + } +} +``` + +![image-20250624225136254](./%E5%9C%A8%E7%BA%BF%E7%94%B5%E8%84%91DIY%E7%B3%BB%E7%BB%9F.assets/image-20250624225136254.png) + +
订单管理页面
+ +**订单功能特点:** + +1. **购物车管理**:添加、删除、修改数量 +2. **库存验证**:实时检查配件库存 +3. **订单创建**:自动生成订单号,记录订单详情 +4. **库存更新**:订单创建后自动减少库存 + +##### 4.2.1.5 装机配置系统 + +**装机配置页面实现:** + +```typescript +// app/build/page.tsx - 装机配置核心功能 +export default function BuildPage() { + const [buildConfig, setBuildConfig] = useState({}) + const [availableComponents, setAvailableComponents] = useState<{ [key: string]: Component[] }>({}) + + // 一些辅助函数... + + return ( +
+
+
+

PC装机配置

+

选择每种配件,组装您的专属电脑

+ + {/* 配置进度 */} +
+
+ 配置进度 + {getCompletionRate()}% +
+
+
+
+
+
+ +
+ {/* 配件选择区域 */} +
+
+ {componentTypes.map((type) => { + const selectedComponent = buildConfig[type.name] + return ( + selectComponent(type.name, component)} + onRemove={() => removeComponent(type.name)} + /> + ) + })} +
+
+ + {/* 配置摘要 */} +
+

配置摘要

+
+ {componentTypes.map((type) => { + const component = buildConfig[type.name] + return ( +
+ {type.name}: + + {component ? `¥${component.price}` : '未选择'} + +
+ ) + })} + +
+
+ 总价: + ¥{getTotalPrice().toFixed(2)} +
+
+
+ +
+ +
+
+
+
+
+ ) +} +``` + +**装机配置特点:** +1. **分类选择**:每种配件类型只能选择一个 +2. **实时预览**:显示已选配件和总价 +3. **进度跟踪**:可视化配置完成度 +4. **批量操作**:一键添加所有配件到购物车 + +![image-20250624224542337](./%E5%9C%A8%E7%BA%BF%E7%94%B5%E8%84%91DIY%E7%B3%BB%E7%BB%9F.assets/image-20250624224542337.png) + +
整机装机页面
+![image-20250624225307836](./%E5%9C%A8%E7%BA%BF%E7%94%B5%E8%84%91DIY%E7%B3%BB%E7%BB%9F.assets/image-20250624225307836.png) + +
特定配件筛选
+ +##### 4.2.1.6 用户信息系统 + +![image-20250624230801501](./%E5%9C%A8%E7%BA%BF%E7%94%B5%E8%84%91DIY%E7%B3%BB%E7%BB%9F.assets/image-20250624230801501.png) + +
个人信息查看与修改
+ +#### 4.2.2 AI智能助手功能实现(核心创新) + +##### 4.2.2.1 AI对话界面实现 + +**对话界面核心组件:** + +```typescript +// app/ai-assistant/page.tsx - AI助手页面 +export default function AIAssistantPage() { + const [messages, setMessages] = useState([]) + const [conversations, setConversations] = useState([]) + const [currentConversationId, setCurrentConversationId] = useState(null) + + const sendMessage = async () => { + if (!input.trim() || isLoading) return + + // 处理 input... + + try { + // 发送请求... + + // 处理流式响应 + const reader = response.body?.getReader() + const decoder = new TextDecoder() + + setMessages(prev => [...prev, { + role: 'assistant', + content: '', + id: Date.now().toString() + }]) + + while (true) { + const { done, value } = await reader.read() + if (done) break + + const chunk = decoder.decode(value) + const lines = chunk.split('\n') + + for (const line of lines) { + if (line.startsWith('data: ')) { + const data = line.slice(6) + if (data === '[DONE]') { + loadConversations() + return + } + + // 处理流式数据... + } + } + } + } catch (error) { + console.error('发送消息失败:', error) + setMessages(prev => [...prev, { + role: 'assistant', + content: '抱歉,发生了错误,请稍后再试。' + }]) + } finally { + setIsLoading(false) + } + } + + return ( +
+
+ {/* 对话历史侧边栏 */} + + + {/* 主聊天区域 */} +
+ + + +
+
+
+ ) +} +``` + +![image-20250624225459858](./%E5%9C%A8%E7%BA%BF%E7%94%B5%E8%84%91DIY%E7%B3%BB%E7%BB%9F.assets/image-20250624225459858.png) + +
AI 聊天页面 - 分析用户需求并搜索对应的配件
+ +##### 4.2.2.2 AI工具调用实现 + +**配件查询工具实现:** + +```typescript +// lib/ai-assistant.ts - AI工具调用核心逻辑 + +// 具体代码在 5.1.2 展示 +``` + +![image-20250624224618803](./%E5%9C%A8%E7%BA%BF%E7%94%B5%E8%84%91DIY%E7%B3%BB%E7%BB%9F.assets/image-20250624224618803.png) + +
AI 研究完成后以卡片形式向用户展示配件
+ +**AI助手功能特点:** + +1. **智能对话**:基于Claude AI的自然语言理解 +2. **工具调用**:AI可以主动查询数据库获取实时信息 +3. **流式响应**:实时打字机效果提升用户体验 +4. **多轮对话**:保持上下文的连续对话 +5. **配件展示**:以卡片形式展示查询到的配件 +6. **对话管理**:完整的对话历史记录和管理 + +#### 4.2.3 管理员功能实现 + +##### 4.2.3.1 管理员认证和权限控制 + +**管理员认证组件:** + +```typescript +import { NextRequest } from 'next/server' +import { verifyToken } from '@/lib/auth' +import { prisma } from '@/lib/prisma' + +export async function requireAdmin(request: NextRequest) { + const authHeader = request.headers.get('Authorization') + const token = authHeader?.replace('Bearer ', '') + + if (!token) { + throw new Error('未提供认证令牌') + } + + const decoded = verifyToken(token) + if (!decoded) { + throw new Error('无效的认证令牌') + } + + const user = await prisma.user.findUnique({ + where: { id: decoded.userId }, + select: { id: true, isAdmin: true } + }) + + if (!user || !user.isAdmin) { + throw new Error('权限不足') + } + + return user +} +``` + +##### 4.2.3.2 配件管理功能 + +**配件管理页面实现:** + +```typescript +// app/admin/components/page.tsx - 管理员配件管理 +function AdminComponentsPage() { + const [components, setComponents] = useState([]) + const [showModal, setShowModal] = useState(false) + const [editingComponent, setEditingComponent] = useState(null) + + // 批量导入功能 + const handleBatchImport = async () => { + if (!batchFile) { + alert('请选择文件') + return + } + + setBatchUploading(true) + try { + const formData = new FormData() + formData.append('file', batchFile) + + const response = await fetch('/api/components/batch', { + method: 'POST', + headers: getAuthHeaders(), + body: JSON.stringify({ components: batchData }) + }) + + // ... + } catch (error) { + alert('批量导入失败') + } finally { + setBatchUploading(false) + } + } + + // 单个配件操作 + const handleSubmit = async (e: React.FormEvent) => { + // ... + } + + return ( +
+
+

配件管理

+
+ {/* 导入按钮 */} +
+
+ + {/* 配件列表 */} +
+ + + + + + + + + + + {components.map((component) => ( + + ))} + +
+ 配件信息 + + 价格/库存 + + 类型 + + 操作 +
+
+ + {/* 配件编辑模态框 */} + setShowModal(false)} + onSubmit={handleSubmit} + /> + + {/* 批量导入预览 */} + +
+ ) +} + +export default withAdminAuth(AdminComponentsPage) +``` + +![image-20250624225805038](./%E5%9C%A8%E7%BA%BF%E7%94%B5%E8%84%91DIY%E7%B3%BB%E7%BB%9F.assets/image-20250624225805038.png) + +
配件管理列表
+ +![image-20250624225832652](./%E5%9C%A8%E7%BA%BF%E7%94%B5%E8%84%91DIY%E7%B3%BB%E7%BB%9F.assets/image-20250624225832652.png) + +
批量导入配件(结合爬虫)
+ +##### 4.2.3.3 统计功能实现 + +**管理员统计页面:** + +```typescript +// app/api/admin/stats/route.ts - 统计数据API +export async function GET(request: NextRequest) { + try { + await requireAdmin(request) + + // 按消费金额排序的前十用户 + const topUsers = await prisma.user.groupBy({ + by: ['id'], + _sum: { + orders: { + totalAmount: true + } + }, + orderBy: { + _sum: { + orders: { + totalAmount: 'desc' + } + } + }, + take: 10 + }) + + // 按销售量排序的前十配件 + const topComponents = await prisma.orderItem.groupBy({ + by: ['componentId'], + _sum: { + quantity: true + }, + orderBy: { + _sum: { + quantity: 'desc' + } + }, + take: 10 + }) + + // 获取详细信息 + const usersWithSpending = await Promise.all( + topUsers.map(async (user) => { + const userInfo = await prisma.user.findUnique({ + where: { id: user.id }, + select: { username: true, name: true, email: true } + }) + return { + ...userInfo, + totalSpending: user._sum.orders?.totalAmount || 0 + } + }) + ) + + const componentsWithSales = await Promise.all( + topComponents.map(async (item) => { + const component = await prisma.component.findUnique({ + where: { id: item.componentId }, + include: { componentType: true } + }) + return { + ...component, + totalSales: item._sum.quantity || 0 + } + }) + ) + + // 总体统计 + const totalUsers = await prisma.user.count({ where: { isAdmin: false } }) + const totalOrders = await prisma.order.count() + const totalComponents = await prisma.component.count() + const totalRevenue = await prisma.order.aggregate({ + _sum: { totalAmount: true } + }) + + return NextResponse.json({ + overview: { + totalUsers, + totalOrders, + totalComponents, + totalRevenue: totalRevenue._sum.totalAmount || 0 + }, + topUsers: usersWithSpending, + topComponents: componentsWithSales, + recentOrders: await getRecentOrders() + }) + + } catch (error: any) { + return NextResponse.json( + { message: error.message || '获取统计数据失败' }, + { status: error.message === '权限不足' ? 403 : 500 } + ) + } +} +``` + +**数据可视化实现:** +```typescript +// 使用Chart.js和react-chartjs-2实现图表展示 +import { Bar, Doughnut } from 'react-chartjs-2' + +function AdminStatsPage() { + const [stats, setStats] = useState(null) + + // 用户消费排行榜配置 + const userChartData = { + labels: stats?.topUsers.map(u => u.username || u.name) || [], + datasets: [{ + label: '消费金额', + data: stats?.topUsers.map(u => u.totalSpending) || [], + backgroundColor: 'rgba(59, 130, 246, 0.5)', + borderColor: 'rgba(59, 130, 246, 1)', + borderWidth: 1 + }] + } + + // 配件销量排行榜配置 + const componentChartData = { + labels: stats?.topComponents.map(c => c.name) || [], + datasets: [{ + label: '销售数量', + data: stats?.topComponents.map(c => c.totalSales) || [], + backgroundColor: 'rgba(34, 197, 94, 0.5)', + borderColor: 'rgba(34, 197, 94, 1)', + borderWidth: 1 + }] + } + + return ( +
+

统计分析

+ +
+ {/* 总体数据卡片 */} +
+ + {/* 图表区域 */} +
+ {/* 用户消费排行榜 */} +
+

用户消费排行榜(前10名)

+ +
+ + {/* 配件销量排行榜 */} +
+

配件销量排行榜(前10名)

+ +
+
+
+ ) +} +``` + +![image-20250624230700395](./%E5%9C%A8%E7%BA%BF%E7%94%B5%E8%84%91DIY%E7%B3%BB%E7%BB%9F.assets/image-20250624230700395.png) + +
统计页面
+ +**管理员功能特点:** + +1. **权限控制**:严格的管理员身份验证 +2. **配件管理**:完整的CRUD操作 +3. **批量操作**:支持CSV/JSON批量导入 +4. **统计分析**:用户消费和配件销量统计 +5. **数据可视化**:图表展示统计结果 +6. **订单管理**:查看和管理所有订单 + +通过以上详细的功能实现展示,可以看出本系统完全满足了课程设计的所有要求,并在此基础上实现了诸多创新功能,特别是AI智能助手的集成,大大提升了用户体验和系统的实用性。系统采用现代化的技术栈,代码结构清晰,功能模块化,具有良好的可维护性和扩展性。 + +## 第五章 总结 + +### 5.1 项目开发过程中遇到的困难与解决方法 + +#### 5.1.1 技术选型和架构设计挑战 + +**遇到的困难:** +在项目初期,面临着技术栈选择的难题。传统的Java Web开发虽然成熟稳定,但在现代化用户界面和开发效率方面存在不足。同时,如何在满足课程设计基本要求的同时,实现更具创新性的功能,是一个重要的技术挑战。 + +**解决方案:** +经过深入调研和比较,最终选择了Next.js全栈框架作为核心技术栈: + +1. **框架优势分析**: + - Next.js 15.3.4提供了完整的全栈开发能力 + - 支持服务端渲染(SSR)和静态站点生成(SSG),提升性能和SEO + - App Router架构提供了更清晰的项目结构 + - 内置的API Routes功能简化了后端开发 + +2. **架构设计决策**: + - 采用三层架构:表现层、业务逻辑层、数据访问层 + - 服务层模式:将业务逻辑封装到独立的服务类中 + - 微服务理念:每个功能模块相对独立,便于维护和扩展 + + +**经验总结:** + +技术选型应该综合考虑项目需求、开发效率、团队技能和未来维护等多个因素。选择现代化的技术栈虽然有学习成本,但能够带来更好的开发体验和最终产品质量。 + +#### 5.1.2 AI助手功能集成的技术挑战 + +本项目中的AI助手旨在为用户提供智能化的PC配件查询和推荐服务。其核心是基于大型语言模型(Anthropic Claude系列),并通过工具调用(Tool Use)与网站后端的配件数据库进行交互。在集成过程中,我们遇到了多个技术挑战,尤其是在如何将模型的流式响应、工具调用、多轮对话和状态管理等特性无缝融合,以提供流畅且功能强大的用户体验。 + +##### 遇到的困难 + +AI助手功能的集成是本项目最具挑战性的部分,主要困难包括: + +1. **实时流式响应与工具调用的融合**: + 流式响应(Streaming)要求服务器持续向客户端推送数据,以实现打字机效果,提升用户体验。而工具调用本质上是一个“请求-等待-响应”的阻塞过程。如何在一个持续的流中,优雅地暂停文本输出、执行工具、再将工具结果返回给模型,并继续流式输出后续内容,是最大的技术难点。 + +2. **复杂的多轮工具调用与状态管理**: + 用户的单个问题可能需要AI进行多次工具调用才能完全解答。例如,“帮我找一款500元左右的AMD CPU,并展示出来”。这需要AI先调用 `query-components` 查找,然后根据结果再调用 `show-components` 展示。这要求后端能够维护一个复杂的、动态增长的对话上下文(`messages` 数组),确保每一次与AI的交互都包含完整的历史记录,包括之前的AI思考、工具调用和工具执行结果。 + +3. **前后端通信协议设计**: + 仅靠简单的文本流无法满足功能需求。前端需要明确知道当前流式数据是普通文本、AI正在思考使用哪个工具、还是一个需要渲染成特殊UI(如配件卡片)的指令。这需要设计一套清晰的、超越纯文本的通信协议。 + +4. **健壮的对话历史管理与错误恢复**: + 对话是持续的,用户随时可能返回之前的对话继续提问。系统必须能高效地加载、更新和持久化对话历史。同时,在复杂的AI与工具交互过程中,任何一步都可能出错(如API网络问题、工具执行失败)。系统需要具备容错能力,在出错时能给出清晰的反馈,并尽可能保存当前对话状态,避免用户丢失全部上下文。 + +##### 解决方案(结合具体代码分析) + +为了克服上述挑战,我们设计并实现了 `AIClient` 类,其核心逻辑集中在 `processQuery` 异步生成器函数中。 + +###### 1. 流式响应与工具调用事件的统一处理 + +**挑战**:融合流式输出和阻塞的工具调用。 + +**解决方案**:我们充分利用了 Anthropic API 的流式响应特性,它会将一次完整的AI响应拆分成多个事件(`chunk`)。我们在 `for await (const chunk of response)` 循环中对这些事件进行精细化处理,实现了在流式输出的同时,解析并准备工具调用。 + +**代码分析**: + +```typescript +// processQuery 方法内 +for await (const chunk of response) { + console.log(chunk); + + switch (chunk.type) { + // ... 其他 case ... + case "content_block_start": + const contentBlock = chunk.content_block; + if (contentBlock.type === "tool_use") { + // ... + yield `\n\n**使用工具**: ${contentBlock.name}\n\n\`\`\`\n`; // (1) + } + break; + + case "content_block_delta": + const contentBlockDelta = chunk.delta; + if (contentBlockDelta.type === "input_json_delta") { + // ... + yield contentBlockDelta.partial_json || ""; // (2) + } + break; + + // ... 其他 case ... + } +} +``` + +- **即时反馈**:当AI决定使用工具时,API会发送一个 `content_block_start` 且类型为 `tool_use` 的事件。我们捕捉到这个事件后,立刻 `yield` 一段表示“正在使用工具”的Markdown文本 **(1)**。这让用户能实时看到AI的“思考过程”,而不是面对长时间的无响应等待。 +- **流式展示工具参数**:紧接着,API会通过一系列 `content_body_delta` 且类型为 `input_json_delta` 的事件,流式地发来工具调用的参数JSON。我们将其直接 `yield` 给前端 **(2)**,前端可以实时展示AI正在构建的查询参数,进一步增强了透明度和用户体验。 +- **构建完整响应**:在处理流的同时,我们使用 `tempMsg` 对象,根据接收到的 `chunk` 逐步拼装出AI的完整响应(包括文本和工具调用请求)。这为后续的工具执行和状态更新做好了准备。 + +通过这种方式,我们将“思考-调用-执行”的非流式过程,巧妙地包装在了对用户的流式反馈之中。 + +###### 2. 迭代式多轮工具执行循环 + +**挑战**:处理需要多次工具调用的复杂查询,并管理好上下文。 + +**解决方案**:我们设计了一个 `while (currentIteration < maxIterations)` 循环,将用户的单次查询过程变成了一个“AI思考 -> 工具执行 -> AI再思考”的迭代循环。 + +**代码分析**: + +```typescript +// processQuery 方法内 +let maxIterations = 20; +let currentIteration = 0; + +while (currentIteration < maxIterations) { // (1) 核心循环 + currentIteration++; + + // ... 调用 aic.messages.create 并处理流式响应 ... + + // 将AI的完整响应(可能是文本或工具调用)加入到 messages 历史中 + messages.push({ role: tempMsg.role, content: ... }); + + // (2) 检查AI响应中是否包含工具调用 + if (!tempMsg.content.find(c => c.type === "tool_use")) { + break; // 如果没有工具调用,说明AI已完成回答,退出循环 + } + + // (3) 准备工具执行结果的消息体 + let tempUserMsg: MessageParam = { role: "user", content: [] }; + let needRerun = false; + + // (4) 遍历并执行所有工具调用 + for (const toolUse of tempMsg.content.filter(c => c.type === "tool_use")) { + // ... 执行 queryComponents 或 show-components ... + const result = await this.queryComponents(toolArgs); + + // (5) 将工具执行结果格式化为 tool_result 消息 + tempUserMsg.content.push({ + type: "tool_result", + tool_use_id: toolUse.id, + content: result + }); + needRerun = true; + } + + // (6) 将工具结果消息加入历史,准备下一次循环 + messages.push(tempUserMsg); + if (!needRerun) break; +} +``` + +1. **核心循环 (1)**:`while` 循环是实现多轮工具调用的引擎。只要AI还在请求使用工具,循环就会继续。 +2. **中断条件 (2)**:当AI的回复中不再包含 `tool_use` 类型的 `content_block` 时,意味着它认为任务已完成,可以生成最终答案了。此时 `break` 语句会终止循环。 +3. **工具执行 (4)**:循环内部会遍历AI请求的所有工具调用,并执行对应的本地方法(如 `this.queryComponents`)。 +4. **上下文注入 (5, 6)**:最关键的一步。工具的执行结果不会直接展示给用户,而是被包装成一个 `role: "user"` 且 `type: "tool_result"` 的消息,并添加到 `messages` 数组中。在下一次循环开始时,这个包含工具结果的 `messages` 数组会被再次发送给AI。这相当于告诉AI:“你上次想调用这个工具,这是它的执行结果,请基于这个结果继续你的思考和回答。” + +这个迭代循环完美地模拟了AI的思维链,使其能够处理复杂的、需要分步解决的问题。 + +###### 3. 自定义流式通信协议 + +**挑战**:前端需要结构化信息来渲染不同UI。 + +**解决方案**:我们通过 `yield` 语句,在文本流中嵌入了带特定前缀的“指令”,形成了一套简单有效的通信协议。 + +**代码分析**: + +```typescript +// 创建新对话时 +yield `conversation_id:${currentConversationId}`; + +// 调用 show-components 工具后 +yield `show_card: ${JSON.stringify(components)}`; + +// 在一个工具执行完毕,准备让AI生成最终回复前 +yield 'next_block'; +``` + +- `conversation_id:`:在对话创建之初,立即将新ID发送给前端,以便前端在后续请求中携带此ID。 +- `show_card:`:这是一个明确的UI渲染指令。当AI调用 `show-components` 工具后,后端获取到配件的详细信息,并将其序列化为JSON字符串,附在 `show_card:` 之后 `yield` 出去。前端接收到这个格式的字符串后,就知道应该解析其后的JSON数据,并渲染成配件卡片UI,而不是当成普通文本显示。 + + ![image-20250624232701990](./%E5%9C%A8%E7%BA%BF%E7%94%B5%E8%84%91DIY%E7%B3%BB%E7%BB%9F.assets/image-20250624232701990.png) +
show_card 指令展示
+- `next_block`:这是一个流程控制信号。它告诉前端,一个工具执行和结果返回的阶段已经完成,接下来AI将要生成总结性的文本。前端利用这个信号来创建新的消息气泡。 + ![image-20250624232606606](./%E5%9C%A8%E7%BA%BF%E7%94%B5%E8%84%91DIY%E7%B3%BB%E7%BB%9F.assets/image-20250624232606606.png) + +
next_block 指令展示
+ +这套协议将后端的业务逻辑(如展示卡片)与前端的UI实现解耦,使得通信清晰且可扩展。 + +###### 4. 原子化的对话状态管理与持久化 + +**挑战**:保证对话历史的完整性和面对错误时的健壮性。 + +**解决方案**:我们将对话管理抽象为 `ConversationService`,并在 `processQuery` 的开始和结束(包括异常情况)时进行调用,确保了对话状态的原子性更新。 + +**代码分析**: + +```typescript +// processQuery 方法开头 +if (conversationId) { + // 加载现有对话 + const conversation = await ConversationService.getConversation(conversationId, userId); + messages = [...conversation.messages]; + messages.push({ role: "user", content: query }); +} else { + // 创建新对话 + currentConversationId = await ConversationService.createConversation(userId, query); + // ... +} + +// processQuery 方法 try-catch-finally 结构 +try { + // ... 核心的 while 循环逻辑 ... + + // (1) 成功后保存 + if (currentConversationId) { + await ConversationService.updateConversationMessages(currentConversationId, userId, messages); + } +} catch (error) { + // ... 错误处理 ... + // (2) 失败时也尝试保存 + if (currentConversationId) { + try { + await ConversationService.updateConversationMessages(currentConversationId, userId, messages); + } catch (saveError) { + console.error('保存对话失败:', saveError); + } + } +} +``` + +- **加载与启动**:在处理查询前,代码首先会根据 `conversationId` 决定是加载旧对话还是创建新对话,为本次交互准备好完整的上下文 `messages`。 +- **事务性保存**:整个复杂的多轮交互(包含多次AI调用和工具执行)被视为一个事务。只有当 `while` 循环完全结束(即AI生成了最终答案)后,我们才调用 `updateConversationMessages` **(1)**,将包含用户提问、所有AI思考步骤、工具调用、工具结果和最终答案的完整 `messages` 数组一次性存入数据库。 +- **错误恢复**:通过 `try...catch` 结构,即使在处理过程中发生错误,我们依然会尝试保存截至出错前的所有 `messages` **(2)**。这极大地提升了系统的健壮性,用户不会因为一次偶然的失败而丢失整个对话历史,同时也为问题排查提供了宝贵的上下文记录。 + +### 5.2 结语 + +通过本次课程设计的完整实施,不仅成功构建了一个功能完善、技术先进的在线电脑DIY系统,更重要的是在这个过程中获得了全面的技术能力提升和深入的工程实践体验。 + +**项目成果的多重价值:** + +1. **技术价值:**展示了现代Web开发技术栈的综合应用,特别是AI技术与传统电商系统的深度融合,为同类项目提供了宝贵的技术参考。 + +2. **教育价值:**作为一个完整的学习项目,它涵盖了从需求分析到系统部署的全过程,为软件工程教育提供了优秀的实践案例。 + +3. **商业价值:**系统具备实际的商业应用潜力,AI助手功能的创新应用为传统电商模式带来了新的可能性。 + +4. **社会价值:**项目体现了技术创新对用户体验提升的促进作用,展示了人工智能技术普惠化应用的广阔前景。 + +**个人成长的深度反思:** + +在技术能力方面,通过项目实践掌握了全栈开发的完整技能体系,特别是在AI技术集成、现代前端框架应用、数据库设计优化等方面有了质的提升。更重要的是,培养了系统性思考问题的能力,学会了在复杂项目中平衡技术选型、开发效率和产品质量的关系。 + +在工程思维方面,深刻理解了软件工程不仅仅是编写代码,更是一个涉及需求分析、架构设计、质量控制、用户体验、安全性考虑等多个维度的综合性活动。良好的工程实践是确保项目成功的重要保障。 + +**对未来发展的展望:** + +技术发展日新月异,特别是AI技术的快速进步为软件开发带来了新的机遇和挑战。未来将继续关注技术发展趋势,不断学习新技术、新方法,将这个项目作为一个起点,在更大的技术舞台上发挥更大的价值。 diff --git a/docs/在线电脑DIY系统.pdf b/docs/在线电脑DIY系统.pdf new file mode 100644 index 0000000..95bbc4f Binary files /dev/null and b/docs/在线电脑DIY系统.pdf differ diff --git a/第一章-概述.md b/第一章-概述.md deleted file mode 100644 index 9039184..0000000 --- a/第一章-概述.md +++ /dev/null @@ -1,27 +0,0 @@ -# 第一章 概述 - -## 1.1 课程设计目的 - -通过本次课程设计的准备与总结,深入复习、领会、巩固和运用课堂上所学的软件开发方法和知识,为综合应用本专业所学习的多门课程知识创造实践机会。本课程设计旨在使学生深入了解软件工具与环境对于项目开发的重要性,并且重点深入掌握几种较新或较流行的软件工具或计算机应用技术。 - -在实际开发过程中,学生将体验完整的软件开发生命周期,从需求分析、系统设计到编码实现和测试部署,全面提升软件工程实践能力。通过构建真实的Web应用系统,学生能够将理论知识转化为实际操作技能,增强解决复杂工程问题的能力,提高今后参与开发稍大规模实际软件项目和探索未知领域的能力和自信心。 - -## 1.2 课程设计任务 - -本次课程设计的任务是开发一个在线电脑DIY系统,该系统面向现代消费者对个性化电脑配置的需求,提供一站式的电脑配件选购和装机方案定制服务。系统需要实现从配件展示、用户管理、购物车管理到订单处理的完整电商业务流程。 - -系统的核心功能包括企业信息展示和电脑配件详情展示,涵盖CPU、内存、硬盘、主板、显卡、机箱等六大类核心配件。每种配件支持多品牌、多型号的产品管理,满足不同用户的预算和性能需求。系统采用分角色管理模式,包括管理员和普通用户两种用户类型,通过权限控制确保系统安全性和数据完整性。 - -用户功能方面,系统支持用户注册、登录、个人信息管理、配件选购、装机方案定制、订单提交和订单查询等完整的购物流程。管理员功能涵盖配件类型管理、商品信息管理、用户管理、订单管理和数据统计分析等后台管理功能。特别是数据统计功能,能够提供按消费金额排序的用户分析和按销售量排序的产品分析,为商业决策提供数据支持。 - -## 1.3 使用技术及开发环境 - -本项目采用现代化的全栈Web开发技术栈,前端使用React 19.0框架配合Next.js 15.3.4进行开发,利用Next.js的服务端渲染(SSR)和静态生成(SSG)能力,提升应用性能和用户体验。前端UI框架选用TailwindCSS 4.0,通过原子化CSS类实现响应式设计和现代化的用户界面。 - -后端采用Next.js的API Routes功能构建RESTful API,实现前后端一体化开发。数据库选用PostgreSQL作为主数据库,通过Prisma 6.10.1作为ORM框架进行数据库操作,提供类型安全的数据库访问和强大的查询能力。身份认证采用JSON Web Token(JWT)机制,确保用户会话安全和API接口的访问控制。 - -开发工具方面,使用Visual Studio Code作为主要IDE,配合TypeScript 5.0提供强类型支持和更好的开发体验。包管理器采用Bun作为现代化的JavaScript运行时和包管理工具,提升开发效率和构建性能。版本控制使用Git,配合GitHub进行代码管理和协作开发。 - -图表展示功能使用Chart.js 4.5.0和React-Chartjs-2 5.3.0库,以及Recharts 2.15.4库,提供丰富的数据可视化选项。图标系统采用Lucide React 0.522.0,提供一致性的矢量图标库。项目采用模块化架构设计,通过组件化开发提高代码复用性和可维护性。 - -开发环境配置包括Node.js 20+、PostgreSQL 15+数据库服务器,以及相应的开发调试工具。项目支持热重载开发模式,提供实时预览和快速迭代能力。生产环境支持静态资源优化、代码分割和性能监控,确保应用的稳定性和高性能表现。 diff --git a/第三章-系统设计.md b/第三章-系统设计.md deleted file mode 100644 index dd9f01a..0000000 --- a/第三章-系统设计.md +++ /dev/null @@ -1,43 +0,0 @@ -# 第三章 系统设计 - -## 3.1 数据库设计 - -系统采用PostgreSQL作为主数据库,通过Prisma ORM进行数据建模和访问。数据库设计遵循第三范式,确保数据的一致性和完整性,同时考虑了系统的性能需求和扩展性要求。 - -用户表(users)是系统的核心表之一,存储所有用户的基本信息和权限信息。主键id采用cuid()函数生成的唯一标识符,确保全局唯一性。email字段定义为唯一约束的变长字符串,作为用户登录的主要标识。username字段同样设置唯一约束,提供用户的显示名称。password字段存储经过bcrypt加密的用户密码,确保密码安全性。name、phone、address字段为可选字段,存储用户的详细信息。isAdmin字段为布尔类型,默认值为false,用于区分普通用户和管理员。createdAt和updatedAt字段分别记录用户的创建时间和最后更新时间,支持自动时间戳更新。 - -配件类型表(component_types)定义了电脑配件的分类信息。主键id采用cuid()生成,name字段存储配件类型名称并设置唯一约束,确保类型名称的唯一性。description字段为可选字段,提供类型的详细描述信息。该表为配件分类提供基础数据支持。 - -配件表(components)是系统最重要的业务表之一,存储所有电脑配件的详细信息。主键id采用cuid()生成,name字段存储配件名称,brand字段存储配件品牌,model字段存储配件型号。price字段采用浮点数类型存储配件价格,支持精确的价格计算。description和imageUrl字段为可选字段,分别存储配件描述和图片URL。stock字段为整型,默认值为0,实时反映配件的库存数量。specifications字段采用字符串类型存储JSON格式的规格参数,提供灵活的参数定义能力。componentTypeId字段为外键,关联配件类型表,建立配件与类型的归属关系。createdAt和updatedAt字段记录配件的创建和更新时间。 - -订单表(orders)记录用户的购买订单信息。主键id采用cuid()生成,orderNumber字段存储唯一的订单号,便于订单查询和管理。totalAmount字段采用浮点数存储订单总金额。status字段采用枚举类型,支持PENDING(待确认)、CONFIRMED(已确认)、PROCESSING(处理中)、SHIPPED(已发货)、DELIVERED(已送达)、CANCELLED(已取消)等状态,默认为PENDING状态。userId字段为外键,关联用户表,建立订单与用户的归属关系。createdAt和updatedAt字段记录订单的创建和更新时间,支持订单时间追踪。 - -订单项表(order_items)是订单和配件之间的关联表,记录订单中每个配件的详细信息。主键id采用cuid()生成,quantity字段为整型,默认值为1,记录配件的购买数量。price字段记录配件的实际成交价格,避免因价格变动导致的历史订单金额不准确。orderId字段为外键,关联订单表,并设置级联删除约束,确保订单删除时相关订单项同时删除。componentId字段为外键,关联配件表,建立订单项与配件的关系。 - -购物车项表(cart_items)实现了基于数据库的购物车功能,支持用户在不同设备间的购物车同步。主键id采用cuid()生成,quantity字段记录配件的购买数量,默认值为1。userId字段为外键,关联用户表,并设置级联删除约束,确保用户删除时购物车数据同时清理。componentId字段为外键,关联配件表,并设置级联删除约束,确保配件删除时相关购物车项同时清理。createdAt和updatedAt字段记录购物车项的创建和更新时间。重要的是,userId和componentId字段组合设置唯一约束,确保一个用户对同一商品只能有一条购物车记录,避免数据冗余。 - -数据库设计还包含了完善的索引策略。用户表的email和username字段设置唯一索引,提升登录验证的查询性能。配件表的componentTypeId字段设置普通索引,优化按类型查询配件的性能。订单表的userId字段设置索引,提升用户订单查询的效率。外键约束确保了引用完整性,防止孤立数据的产生。 - -## 3.2 模块设计 - -系统采用模块化架构设计,将复杂的业务逻辑分解为相互独立且高内聚的功能模块。每个模块负责特定的业务领域,通过明确定义的接口进行交互,确保系统的可维护性和可扩展性。 - -用户认证模块是系统安全的核心模块,负责处理用户的注册、登录、权限验证和会话管理。该模块采用JWT令牌机制实现无状态认证,支持跨域访问和分布式部署。用户注册流程首先验证用户输入信息的合法性,包括邮箱格式验证、用户名唯一性检查和密码强度验证。密码采用bcrypt算法进行单向加密,盐值随机生成,确保即使数据库泄露也无法逆向获取原始密码。用户登录流程验证用户凭据的正确性,成功后生成包含用户信息的JWT令牌,设置合理的过期时间以平衡安全性和用户体验。 - -**[用户认证流程图占位符]** - -商品管理模块负责电脑配件的展示、检索和管理功能。该模块支持配件的分类浏览、关键词搜索、价格筛选和品牌过滤等多种检索方式。配件详情页面展示配件的完整信息,包括规格参数、库存状态、用户评价等。管理员可以通过该模块进行配件的增删改查操作,支持批量操作和数据导入导出功能。库存管理功能实时监控配件库存,支持库存预警和自动补货提醒。 - -购物车模块实现了基于数据库的购物车功能,相比传统的本地存储方案,提供了更好的数据持久性和跨设备同步能力。用户可以在任意页面将感兴趣的配件添加到购物车,系统自动检查库存可用性并更新购物车状态。购物车支持商品数量的实时调整,价格计算自动更新,提供直观的购物体验。结算流程集成了配件兼容性检查功能,确保用户选择的配件能够正常组装使用。 - -订单管理模块处理从订单创建到订单完成的全生命周期管理。订单创建流程首先验证购物车数据的有效性,检查库存充足性,计算订单总金额,生成唯一订单号,并将购物车商品转换为订单项。订单状态管理支持多种业务状态,管理员可以根据实际业务进度更新订单状态,用户可以实时查看订单处理进度。订单查询功能支持多维度检索,包括订单号查询、时间范围查询、状态筛选等。 - -**[订单处理流程图占位符]** - -装机方案模块是系统的特色功能模块,为用户提供智能化的电脑配置方案定制服务。用户可以从每种配件类型中选择一个产品,系统会实时计算总价格并检查配件间的兼容性。兼容性检查算法考虑了主板与CPU的接口匹配、内存类型与主板的兼容性、显卡尺寸与机箱空间的匹配等关键因素。用户确认配置方案后,可以一键将所有配件添加到购物车或直接提交订单,大大简化了DIY装机的复杂性。 - -数据统计模块为系统提供了强大的商业智能分析能力。该模块定期分析用户消费行为、商品销售数据、订单趋势等关键业务指标。用户消费排行统计按照消费金额对用户进行排序,识别高价值客户群体,为精准营销提供数据支持。商品销售排行统计按照销量对配件进行排序,为库存管理和采购决策提供参考依据。统计结果通过图表形式直观展示,支持多种图表类型包括柱状图、饼图、折线图等,满足不同的数据展示需求。 - -系统集成模块负责各功能模块间的协调和通信,提供统一的API接口和数据交换格式。该模块采用RESTful API设计规范,支持标准的HTTP方法和状态码,确保接口的规范性和易用性。数据传输采用JSON格式,支持请求参数验证和响应数据格式化。错误处理机制提供统一的错误码和错误信息,便于前端进行错误处理和用户提示。 - -安全防护模块贯穿系统的各个层面,提供全方位的安全保障。输入验证功能防止SQL注入、XSS攻击等常见安全威胁。API访问控制基于JWT令牌进行身份验证和权限授权,确保只有合法用户能够访问相应资源。数据加密功能对敏感信息进行加密存储和传输,保护用户隐私和商业机密。访问日志记录用户的关键操作,支持安全审计和异常行为分析。 diff --git a/第二章-需求分析.md b/第二章-需求分析.md deleted file mode 100644 index 0e99037..0000000 --- a/第二章-需求分析.md +++ /dev/null @@ -1,51 +0,0 @@ -# 第二章 需求分析 - -## 2.1 功能分析 - -在线电脑DIY系统是一个面向现代消费者的综合性电商平台,旨在为用户提供便捷的电脑配件选购和装机方案定制服务。系统的功能设计充分考虑了电脑DIY市场的特点和用户需求,构建了完整的业务流程和用户体验。 - -系统的核心功能围绕电脑配件的展示、选购和管理展开。首页作为系统的门户,无需用户登录即可访问,主要展示企业的品牌信息、发展历程和核心价值观,同时提供电脑配件的分类浏览功能。配件展示功能涵盖CPU、内存、硬盘、主板、显卡、机箱等六大类核心配件,每类配件支持多品牌、多型号的产品展示,用户可以通过品牌筛选、价格排序、性能对比等方式快速找到合适的产品。 - -用户管理功能实现了完整的用户生命周期管理。新用户可以通过注册功能创建账户,系统支持邮箱验证和用户名唯一性检查,确保账户安全性。登录功能采用JWT令牌机制,支持会话保持和自动登录功能。用户登录后可以访问个人中心,管理个人信息包括姓名、电话、地址等基本信息,同时可以查看账户统计信息如订单数量、消费金额、购物车商品数量等。 - -购物车功能是系统的重要组成部分,支持配件的添加、数量调整、删除和清空操作。购物车数据采用数据库存储,确保用户在不同设备间的数据同步。系统还提供了智能的库存检查功能,防止用户购买超出库存的商品,提升购物体验和业务准确性。 - -装机方案定制功能是系统的特色功能,用户可以从每种配件类型中选择一个产品,系统会自动检查配件间的兼容性,并计算总价格。用户确认方案后可以一键添加到购物车或直接提交订单,大大简化了DIY装机的复杂性。 - -订单管理功能涵盖了从订单创建到订单完成的全流程。用户可以提交订单并进行虚拟结算,无需真实付款。订单支持多种状态管理包括待确认、已确认、处理中、已发货、已送达和已取消,用户可以实时查看订单状态和物流信息。同时,系统提供订单历史查询功能,用户可以查看所有历史订单并支持重新下单操作。 - -管理员功能提供了强大的后台管理能力。配件类型管理允许管理员添加、修改和删除配件分类。商品信息管理支持商品的增删改查操作,包括商品名称、品牌、型号、价格、库存、规格参数等详细信息的管理。用户管理功能让管理员可以查看所有注册用户的信息和活动状态。订单管理功能提供订单的查看、状态修改和删除功能,帮助管理员高效处理业务。 - -数据统计功能是系统的高级功能,提供了丰富的业务分析能力。系统可以统计按消费金额倒序排列的前十名用户,帮助识别高价值客户。同时统计按销售量倒序排列的前十名配件,为库存管理和采购决策提供数据支持。统计结果通过柱状图、饼图等可视化图表展示,直观清晰地反映业务状况。 - -**[功能结构图占位符]** - -系统的功能结构采用层次化设计,分为用户界面层、业务逻辑层和数据访问层。用户界面层负责用户交互和页面展示,业务逻辑层处理核心业务规则和流程控制,数据访问层负责数据库操作和数据持久化。各层之间通过API接口进行通信,确保系统的模块化和可扩展性。 - -## 2.2 概念模型分析 - -系统的概念模型设计围绕电商业务的核心实体展开,主要包括用户、配件类型、配件、订单、购物车等核心实体,以及它们之间的复杂关系。通过合理的实体关系设计,系统能够准确反映真实业务场景,为后续的数据库设计奠定坚实基础。 - -用户实体是系统的核心实体之一,包含用户的基本信息和权限信息。用户实体的关键属性包括用户ID、邮箱、用户名、密码、姓名、电话、地址、管理员标识、创建时间和更新时间。邮箱和用户名作为唯一标识,确保用户账户的唯一性。管理员标识字段区分普通用户和管理员,实现权限控制。 - -配件类型实体定义了电脑配件的分类信息,包括类型ID、类型名称和类型描述。系统预设六种配件类型分别是CPU、内存、硬盘、主板、显卡和机箱,每种类型具有唯一的标识和描述信息。配件类型实体为配件分类和检索提供基础支持。 - -配件实体是系统的商品实体,包含了详细的商品信息。关键属性包括配件ID、配件名称、品牌、型号、价格、描述、图片URL、库存数量、规格参数、创建时间和更新时间。规格参数采用JSON格式存储,支持灵活的参数定义。库存数量字段支持实时库存管理,防止超卖现象。 - -订单实体记录用户的购买行为,包含订单ID、订单号、总金额、订单状态、创建时间和更新时间。订单号采用唯一标识,便于订单查询和管理。订单状态支持多种状态值,反映订单的处理进度。 - -订单项实体是订单和配件之间的关联实体,记录订单中每个配件的详细信息。关键属性包括订单项ID、数量、单价、订单ID和配件ID。通过订单项实体,系统可以准确记录每个订单的商品明细。 - -购物车实体记录用户的购物车信息,支持配件的临时存储和管理。关键属性包括购物车项ID、数量、创建时间、更新时间、用户ID和配件ID。购物车采用数据库存储,确保数据的持久性和跨设备同步。 - -**[ER图占位符]** - -实体间的关系设计体现了业务逻辑的复杂性。用户与订单之间存在一对多关系,一个用户可以创建多个订单,但每个订单只属于一个用户。用户与购物车项之间也存在一对多关系,一个用户可以有多个购物车项,支持多商品的购物车管理。 - -配件类型与配件之间存在一对多关系,一个配件类型可以包含多个具体配件,但每个配件只属于一个配件类型。这种关系支持配件的分类管理和检索。 - -订单与订单项之间存在一对多关系,一个订单可以包含多个订单项,每个订单项记录一个配件的购买信息。配件与订单项之间存在一对多关系,一个配件可以被多个订单项引用,但每个订单项只对应一个配件。 - -配件与购物车项之间存在一对多关系,一个配件可以被多个用户添加到购物车,但每个购物车项只对应一个配件。用户和配件通过购物车项建立多对多关系,实现灵活的购物车管理。 - -通过这种实体关系设计,系统能够准确建模电商业务的复杂关系,支持高效的数据操作和业务逻辑实现。实体间的外键约束确保数据一致性,级联删除和更新操作保证数据的完整性。 diff --git a/第五章-总结.md b/第五章-总结.md deleted file mode 100644 index 6cd0d6c..0000000 --- a/第五章-总结.md +++ /dev/null @@ -1,49 +0,0 @@ -# 第五章 总结 - -## 5.1 开发过程中遇到的困难 - -在本次课程设计的开发过程中,遇到了多个层面的技术挑战和业务难题,这些困难不仅考验了理论知识的掌握程度,更检验了解决实际问题的能力和持续学习的态度。 - -技术选型阶段面临的第一个挑战是如何在学校课程的技术栈与个人偏好之间做出平衡。学校课程主要教授Java Bean、Spring MVC和Spring Boot等传统Java技术栈,但个人对Java的笨重感和复杂的配置管理并不认同,更倾向于轻量级和高效的开发方式。基于之前掌握的Express + Vue.js技术栈,最终选择了Next.js全栈框架,这样既能保持JavaScript生态的一致性,又能体验现代化的全栈开发模式。然而,从分离式的前后端架构转向Next.js的一体化开发模式需要一个适应期,特别是Next.js 15版本引入的App Router架构与传统的Express路由和Vue.js组件化思维存在显著差异,需要重新理解服务端渲染、客户端组件和服务端组件的概念与使用场景。 - -数据库设计阶段遇到的主要困难是如何建立合理的实体关系模型。电商系统的业务逻辑相对复杂,用户、商品、订单、购物车之间存在多种关联关系。特别是购物车功能的设计,初期采用了localStorage方案,但后期发现无法满足跨设备同步的需求,需要重新设计为基于数据库的方案。这个改动涉及到数据模型的重新设计、API接口的重写和前端逻辑的大幅调整,几乎相当于重构了整个购物车模块。 - -身份认证和权限管理是另一个技术难点。JWT令牌的生成、验证和刷新机制需要在前后端之间建立一致的处理逻辑。在开发过程中,经常出现令牌过期后用户体验不佳的问题,需要实现自动刷新机制和无感知的重新认证。同时,权限控制需要在多个层面实现,包括API接口层面的权限验证和前端页面层面的访问控制,确保系统的安全性。 - -状态管理是前端开发中的一个持续挑战。虽然React提供了useState和useContext等状态管理工具,但在复杂的业务场景中,如何合理地组织状态、避免过度渲染和保持状态的一致性仍然需要仔细考虑。特别是购物车状态和用户登录状态的全局管理,需要在多个组件间保持同步,这要求对React的生命周期和渲染机制有深入的理解。 - -性能优化是开发后期面临的重要挑战。随着功能的增加和数据量的增长,页面加载速度和用户交互响应速度开始出现问题。需要学习和应用代码分割、懒加载、图片优化、缓存策略等多种优化技术。特别是数据库查询的优化,需要合理设计索引、避免N+1查询问题和实现有效的分页机制。 - -## 5.2 问题解决方法 - -面对开发过程中的各种困难,采用了系统性的问题解决方法,通过持续学习、实验验证和迭代改进,逐步克服了技术挑战并完成了系统开发。 - -针对技术栈转换和学习适应的问题,采用了对比学习和实践验证的策略。虽然学校课程侧重于Java Spring框架的学习,但个人更倾向于JavaScript生态的简洁性和开发效率。基于之前Express + Vue.js的开发经验,在学习Next.js时采用了类比的方式,将Express的中间件概念对应到Next.js的API中间件,将Vue.js的组件化思维迁移到React组件设计中。然而,Next.js的全栈特性带来了新的挑战,从传统的前后端分离架构转向一体化开发需要重新思考代码组织和数据流设计。通过反复实践和对比不同实现方式的优劣,逐步适应了Next.js的开发模式,并体会到了全栈开发的便利性和高效性。 - -数据库设计问题的解决采用了迭代设计的方法。首先建立基础的数据模型,然后在开发过程中根据实际需求不断完善和调整。Prisma ORM的使用大大简化了数据库操作的复杂性,通过schema文件可以清晰地定义数据模型和关系。当需要重构购物车功能时,通过数据库迁移功能平滑地完成了数据结构的变更,确保了数据的完整性和一致性。 - -身份认证问题的解决采用了成熟的JWT方案,并结合了最佳实践进行实现。通过研究相关的安全文档和实现案例,建立了完整的认证流程,包括令牌的生成、验证、刷新和注销机制。在前端实现了自动令牌刷新和错误处理逻辑,确保用户体验的流畅性。同时,在API层面实现了统一的权限验证中间件,确保了系统的安全性。 - -状态管理问题通过合理的架构设计得到了解决。采用了Context API结合自定义Hook的方式实现全局状态管理,避免了过度复杂的状态管理库。通过事件机制实现了组件间的松耦合通信,确保状态变更能够及时反映到所有相关组件。同时,采用了本地存储结合服务端状态的混合方案,平衡了性能和数据一致性的需求。 - -性能优化问题通过多种技术手段得到了改善。在前端层面,采用了Next.js的静态生成和服务端渲染功能,提升了首屏加载速度。通过代码分割和懒加载技术,减少了初始包的大小。在数据库层面,通过合理的索引设计和查询优化,提升了数据访问效率。图片资源采用了CDN分发和格式优化,减少了网络传输时间。 - -调试和测试过程中,建立了完善的错误处理机制。在开发阶段使用了详细的日志记录,便于问题定位和分析。通过浏览器开发者工具和React DevTools等调试工具,能够快速识别和解决前端问题。对于API接口,采用了Postman等工具进行测试验证,确保接口的正确性和稳定性。 - -## 5.3 个人收获与体会 - -通过本次课程设计的完整开发过程,在技术能力、工程思维和综合素质方面都获得了显著的提升,这些收获将对未来的学习和职业发展产生深远的影响。 - -技术能力方面,成功实现了从传统Java技术栈向现代JavaScript全栈开发的转型。虽然学校课程主要围绕Java Bean、Spring MVC和Spring Boot展开,但通过本次项目实践,深入掌握了基于JavaScript的现代Web开发完整技术栈。从之前熟悉的Express + Vue.js分离式架构,成功过渡到Next.js的一体化全栈开发模式,体验到了JavaScript生态的统一性和开发效率的显著提升。相比于Java的繁重配置和冗长代码,JavaScript技术栈的简洁性和灵活性让开发过程更加流畅和高效。特别是TypeScript的引入,在保持JavaScript灵活性的同时提供了类型安全,避免了Java的过度抽象和配置复杂性。通过Prisma ORM的使用,体验了现代化数据库操作方式相比传统MyBatis或Hibernate的优势。 - -工程思维的培养是本次课程设计的重要收获。学会了如何将复杂的业务需求分解为可管理的开发任务,如何设计可扩展和可维护的系统架构,如何在开发过程中保持代码质量和项目进度的平衡。版本控制和代码管理的实践让我理解了团队协作开发的重要性和规范性。 - -问题解决能力得到了显著提升。在面对技术难题时,学会了如何系统性地分析问题、查找资料、验证方案和实施解决方案。这个过程培养了独立思考和持续学习的能力,也增强了面对未知技术领域的信心。每一个问题的解决都是一次知识的积累和能力的提升。 - -项目管理和时间管理能力也得到了锻炼。在有限的时间内完成复杂的开发任务,需要合理规划开发计划、设定优先级和控制开发进度。通过这个过程,学会了如何在质量和效率之间找到平衡点,如何在面临技术挑战时调整开发策略。 - -用户体验和产品思维的培养是意外的收获。在开发过程中,不仅关注功能的实现,更加注重用户的使用体验和业务流程的合理性。这种从用户角度思考问题的方式,让开发出的系统更加贴近实际需求和使用场景。 - -通过本次课程设计,深刻体会到了技术选择的重要性和个人技术偏好的价值。虽然学校课程强调Java技术栈的企业级应用,但通过实际项目开发,验证了JavaScript全栈技术的可行性和优势。相比于Java的笨重配置和复杂抽象,JavaScript技术栈的简洁高效让开发过程更加愉悦和productive。从Express + Vue.js到Next.js的技术演进,不仅是工具的升级,更是开发理念的转变,体现了现代Web开发向一体化、高效化方向的发展趋势。这个过程不仅是技术技能的学习,更是工程能力和综合素质的全面提升,同时也坚定了选择现代化技术栈的信心。面对未来的学习和工作,有了更加清晰的技术方向和更加坚定的发展信心。 - -软件开发是一个需要持续学习和不断进步的领域,技术的快速发展要求开发者保持敏锐的学习能力和适应能力。本次课程设计的经验让我认识到,掌握学习方法和培养解决问题的思维方式,比单纯掌握某种技术更加重要。在未来的学习和工作中,将继续保持这种学习态度,不断探索新的技术领域,提升自身的专业能力和综合素质。 diff --git a/第四章-系统实现.md b/第四章-系统实现.md deleted file mode 100644 index 3dc8e3f..0000000 --- a/第四章-系统实现.md +++ /dev/null @@ -1,73 +0,0 @@ -# 第四章 系统实现 - -## 4.1 项目介绍 - -本项目采用现代化的Web开发架构,基于Next.js 15框架构建,实现了前后端一体化的开发模式。项目结构清晰明确,遵循了React和Next.js的最佳实践,确保代码的可维护性和可扩展性。 - -项目根目录包含了配置文件和依赖管理文件。package.json文件定义了项目的依赖关系和脚本命令,包括开发环境启动、生产构建、代码检查和数据库操作等核心命令。next.config.ts文件配置了Next.js的运行参数,包括Turbopack构建优化、静态资源处理和API路由配置。tsconfig.json文件定义了TypeScript的编译选项,确保代码的类型安全和编译一致性。tailwindcss配置文件定义了样式系统的全局配置,包括颜色主题、响应式断点和自定义样式类。 - -app目录是Next.js 13+版本的核心目录,采用了新的App Router架构。该目录包含了所有的页面组件、API路由和全局配置文件。layout.tsx文件定义了应用的全局布局,包括HTML结构、全局样式引入和公共组件如导航栏的渲染。page.tsx文件是应用的首页组件,展示企业信息和配件分类导航。globals.css文件包含了全局CSS样式,基于TailwindCSS框架构建了一致的设计系统。 - -api目录包含了所有的后端API接口,采用Next.js的API Routes功能实现。auth目录包含用户认证相关的API,包括登录、注册和令牌验证接口。components目录包含配件管理的API,支持配件的查询、创建、更新和删除操作。component-types目录管理配件类型的API接口。orders目录处理订单相关的业务逻辑,包括订单创建、查询、状态更新等功能。cart目录实现了基于数据库的购物车API,支持购物车项的增删改查操作。user目录包含用户信息管理和统计分析的API接口。admin目录提供了管理员专用的API接口,实现了后台管理功能。 - -页面目录结构清晰地反映了应用的功能模块。login和register目录分别包含用户登录和注册页面。components目录包含配件浏览和详情页面,支持动态路由参数。orders目录包含订单管理页面,支持订单列表和订单详情的展示。cart目录包含购物车页面,实现了购物车的可视化管理。build目录包含装机方案定制页面,提供交互式的配件选择和兼容性检查功能。profile目录包含用户个人中心页面,支持个人信息管理和账户统计展示。admin目录包含管理员后台页面,提供了完整的后台管理功能。 - -components目录包含了可复用的React组件。Navbar.tsx组件实现了响应式导航栏,支持用户状态显示、路由高亮和移动端适配。ComponentCard.tsx组件展示单个配件的卡片信息,包括图片、名称、价格和加入购物车功能。AddToCartButton.tsx组件提供了通用的添加购物车按钮,支持数量选择和库存检查。admin目录包含了管理员专用的组件,如数据表格、表单组件和图表组件等。 - -lib目录包含了公共的工具函数和配置文件。prisma.ts文件配置了Prisma客户端实例,提供了类型安全的数据库访问接口。auth.ts文件包含了JWT令牌的生成、验证和解析函数,确保了用户认证的安全性。该目录还可能包含其他工具函数如数据验证、格式化、API客户端等。 - -prisma目录包含了数据库相关的配置和文件。schema.prisma文件定义了完整的数据模型,包括所有表结构、字段类型、约束关系和索引配置。migrations目录包含了数据库迁移文件,记录了数据库结构的变更历史,支持版本控制和团队协作。 - -public目录存储了静态资源文件,包括图片、图标、字体等资源。这些文件可以直接通过URL访问,Next.js会自动处理静态资源的缓存和优化。 - -seed.ts文件是数据库初始化脚本,包含了初始数据的创建逻辑,用于在开发和测试环境中快速搭建基础数据。该脚本通常包含管理员账户、配件类型、示例配件等基础数据的创建。 - -**[项目结构截图占位符]** - -## 4.2 系统功能实现 - -系统首页作为用户进入应用的第一个页面,承担着品牌展示和功能导航的重要作用。页面采用现代化的响应式设计,顶部展示了企业的品牌标识和核心价值主张。主要内容区域通过精美的视觉设计展示了六大类电脑配件,每个配件类别都配有相应的图标和简要描述。用户可以通过点击不同的配件类别快速跳转到相应的配件浏览页面。页面底部包含了企业的联系信息和版权声明。整体设计简洁大方,符合现代Web应用的设计趋势。 - -**[首页截图占位符]** - -用户注册功能提供了完整的账户创建流程。注册表单包含邮箱、用户名、密码和确认密码字段,所有字段都配置了相应的验证规则。邮箱字段要求符合标准邮箱格式,用户名要求3-20位字符且不能与现有用户重复,密码要求至少6位字符包含字母和数字。表单提交后,系统会进行服务端验证,确保数据的合法性和唯一性。注册成功后,用户可以直接跳转到登录页面进行账户验证。页面设计友好,提供了清晰的错误提示和成功反馈。 - -**[注册页面截图占位符]** - -用户登录功能采用了安全的身份验证机制。登录表单支持邮箱或用户名两种登录方式,密码字段提供了显示/隐藏功能,提升用户体验。系统采用JWT令牌机制进行会话管理,登录成功后将令牌存储在本地存储中,实现自动登录功能。登录状态在整个应用中保持同步,导航栏会根据用户状态显示相应的菜单选项。安全性方面,系统限制了登录尝试次数,防止暴力破解攻击。 - -**[登录页面截图占位符]** - -配件浏览页面是系统的核心功能页面,提供了丰富的配件展示和检索功能。页面顶部包含了配件类型的筛选导航,用户可以快速切换不同的配件类别。主要内容区域采用网格布局展示配件卡片,每个卡片包含配件图片、名称、品牌、价格和库存信息。配件卡片支持鼠标悬停效果,点击可以跳转到配件详情页面。页面右侧提供了高级筛选选项,包括品牌筛选、价格范围和库存状态筛选。搜索功能支持关键词搜索,可以匹配配件名称、品牌和型号。 - -**[配件浏览页面截图占位符]** - -配件详情页面展示了单个配件的完整信息。页面左侧是配件的大图展示区域,支持图片放大查看功能。右侧是配件的详细信息,包括名称、品牌、型号、价格、库存状态和详细描述。规格参数表格清晰地列出了配件的技术参数,帮助用户做出购买决策。页面底部包含了添加购物车按钮,支持数量选择和库存检查。用户可以选择不同的购买数量,系统会实时验证库存可用性。 - -**[配件详情页面截图占位符]** - -购物车页面实现了完整的购物车管理功能。页面主要内容区域以表格形式展示购物车中的所有商品,包括商品图片、名称、单价、数量和小计金额。每个商品行都提供了数量调整按钮和删除按钮,用户可以方便地修改购物车内容。页面右侧是订单摘要区域,显示商品总数、总金额和结算按钮。购物车支持批量操作,用户可以一键清空购物车或选择性删除商品。结算功能会跳转到订单确认页面,完成购买流程。 - -**[购物车页面截图占位符]** - -装机方案定制页面是系统的特色功能,提供了交互式的电脑配置体验。页面分为六个配件类型区域,每个区域展示当前类型的推荐配件。用户可以从每种类型中选择一个配件,系统会实时更新配置清单和总价格。页面右侧是配置摘要区域,显示已选择的配件列表、兼容性检查结果和总价格。兼容性检查功能会自动验证配件间的匹配性,如CPU与主板的接口兼容性。用户确认配置后,可以一键将整套配置添加到购物车或直接提交订单。 - -**[装机方案页面截图占位符]** - -订单管理页面为用户提供了完整的订单查询和管理功能。页面以列表形式展示用户的所有历史订单,每个订单条目包含订单号、创建时间、订单状态、总金额和操作按钮。订单状态通过不同颜色的标签进行区分,便于用户快速了解订单进度。页面支持订单状态筛选,用户可以查看特定状态的订单。订单详情功能支持展开查看具体的商品明细和订单流程。重新下单功能允许用户快速重复购买历史订单的商品。 - -**[订单管理页面截图占位符]** - -个人中心页面提供了用户信息管理和账户统计功能。页面左侧是用户基本信息编辑区域,用户可以修改姓名、电话、地址等个人信息。右侧是账户统计区域,展示了订单数量、累计消费、待处理订单、已完成订单和购物车商品数量等关键指标。页面还包含密码修改功能,支持安全的密码更新操作。最近订单区域展示了用户的最新订单,方便快速查看订单状态。 - -**[个人中心页面截图占位符]** - -管理员后台页面提供了强大的系统管理功能。仪表板页面展示了系统的关键统计信息,包括用户数量、订单数量、销售额趋势等。配件管理页面支持配件的增删改查操作,提供了批量导入和导出功能。用户管理页面展示了所有注册用户的信息,支持用户状态管理和权限设置。订单管理页面允许管理员查看和处理所有订单,支持订单状态的批量更新。 - -**[管理员后台截图占位符]** - -数据统计页面是系统的高级功能,提供了丰富的商业分析图表。用户消费排行榜以柱状图形式展示了按消费金额排序的前十名用户,帮助识别高价值客户。商品销售排行榜展示了按销量排序的前十名配件,为库存管理提供数据支持。销售趋势图表展示了订单和销售额的时间变化趋势,帮助分析业务发展状况。图表采用了现代化的可视化库,支持交互式操作和数据导出功能。 - -**[数据统计页面截图占位符]** - -系统的响应式设计确保了在不同设备上的良好用户体验。移动端页面针对触摸操作进行了优化,导航菜单采用了折叠式设计,表格数据支持横向滚动查看。页面加载性能经过了优化,采用了懒加载、代码分割和静态资源压缩等技术手段。用户交互体验流畅,表单验证实时反馈,操作响应及时,错误处理友好,为用户提供了专业级的购物体验。