Files
ALL-teach_sys/frontend_智能开发/网页未导入数据/智能开发产业/学生完成的项目/购物网站前端展示页面开发项目.md

1354 lines
41 KiB
Markdown
Raw Normal View History

# 无标题
# 一、项目背景
在电子商务快速发展的环境下,购物网站已成为消费者获取商品与完成交易的主要平台。相比于后台功能的稳定性,前端展示页面直接决定了用户的第一印象与购物体验,是影响转化率与复购率的关键环节。
- 当前电商竞争激烈,用户浏览习惯趋向于 **快速、直观、便捷**,因此前端页面需同时满足 **美观性、交互性与响应速度**
- 消费者群体覆盖 **PC、平板、手机等多终端设备**,页面需要良好的适配性与响应式布局;
- 在购物场景中,商品展示不仅是图片与文字的堆砌,还需要借助 **分类导航、筛选搜索、商品详情、购物车交互** 等功能,提升浏览效率与用户留存度。
本项目的开发对象是一家虚拟购物平台的前端展示页面,目标是构建一个 **界面友好、功能完善、跨平台适配** 的购物网站原型,作为前端开发与电商运营课程的综合实践案例。
# 二、项目核心目标
1. **首页展示**
- 提供导航栏(分类、购物车、用户中心、登录注册入口);
- 首页 banner 轮播,突出推荐商品或促销活动;
- 商品卡片式展示,包含图片、名称、价格、加入购物车按钮。
2. **商品分类与搜索**
- 分类导航:支持多级分类(如服饰 > 女装 > 外套);
- 搜索框:支持关键词查询,并返回相关商品列表;
- 筛选功能:支持价格区间、品牌、销量等条件。
3. **商品详情页**
- 展示高清图片、价格、库存、规格参数、用户评价;
- 具备数量选择与“加入购物车”按钮;
- 支持图片放大查看与规格切换。
4. **购物车与结算**
- 用户可在购物车查看所选商品、修改数量、删除条目;
- 提供合计金额显示与“去结算”按钮;
- 页面需动态更新购物车商品数量。
5. **用户交互与体验**
- 页面需支持响应式布局兼容手机、平板、PC
- 保持加载速度快,页面跳转流畅;
- 提供基础交互提示(如 hover 效果、按钮点击反馈)。
6. **技术要求**
- 前端框架HTML5 + CSS3 + JavaScript可扩展 React/Vue 等框架);
- 样式:支持组件化与可复用样式,页面结构清晰;
- 动态效果:支持简单动画(如轮播图、按钮 hover 过渡)。
# 三、项目需求与功能模块分解
为确保购物网站前端展示页面设计逻辑完整、交互合理,需要将核心业务流程拆解,输入的提示词如下:
```markdown
我需要做一个购物网站,现在需要你输出这个项目的需求,并且把功能板块拆解开来;
```
得到的结果(功能模块)如下:
## 1. 用户输入行为
| **用户操作** | **说明** |
| --- | --- |
| 点击首页导航栏 | 用户在首页选择分类、购物车、个人中心等入口 |
| 搜索框输入关键词 | 用户输入商品名称/品牌并提交查询 |
| 筛选/排序操作 | 用户根据价格区间、销量、人气等进行筛选或排序 |
| 点击商品卡片 | 用户点击商品卡片进入详情页 |
| 在详情页选择规格/数量 | 用户选择商品型号、颜色、数量等 |
| 点击“加入购物车”按钮 | 将所选商品加入购物车 |
| 在购物车修改商品数量 | 增加/减少数量或删除商品 |
| 点击“去结算”按钮 | 进入结算/支付页面 |
| 用户登录/注册 | 输入账号、密码或注册新用户 |
| 查看订单历史 | 在个人中心查看已下单的订单列表 |
---
## 2. 系统输出反馈
| **页面反馈** | **说明** |
| --- | --- |
| 渲染首页商品列表 | 展示推荐商品、促销 banner 与分类入口 |
| 返回搜索结果 | 根据关键词渲染商品列表 |
| 更新筛选/排序结果 | 按条件刷新商品展示内容 |
| 展示商品详情 | 显示高清图片、价格、库存、评价、规格 |
| 更新购物车图标 | 动态显示购物车商品数量 |
| 渲染购物车列表 | 展示已选商品、数量、金额合计 |
| 生成结算页面 | 显示收货信息、支付金额、支付方式 |
| 验证用户登录状态 | 成功则进入个人中心,失败则提示错误 |
| 展示订单历史 | 渲染用户过往订单及物流状态 |
---
## 3. 功能模块划分
- **首页模块**:商品展示、促销轮播、分类导航。
- **搜索与分类模块**:关键词搜索、多条件筛选与排序。
- **商品详情模块**:商品图片、规格、评价与加入购物车功能。
- **购物车模块**:商品数量调整、合计金额计算、删除功能。
- **结算与支付模块**:收货地址、支付金额确认、支付方式选择。
- **用户登录/注册模块**:账号登录、注册与状态验证。
- **个人中心模块**:订单历史、收货地址管理、账号设置。
# 四、项目开发逻辑说明
项目开发逻辑说明的核心作用在于为参与者奠定一条清晰、共享的思考主线,把零散任务串成可验证、可复现、可迭代的决策路径,确保进度、成本和质量始终围绕最初商业目标递进,最终实现价值交付与知识沉淀的双赢。
输入给ChatGpt的提示词及输出结果如下
```markdown
输出这个项目的开发逻辑说明
```
1. **整体导航与页面切换逻辑**
- 用户通过首页顶部导航栏进入各模块页面(首页、分类、购物车、个人中心)。
- 所有页面切换保持统一的路由规则(如 `home → detail → cart → checkout`),并通过前端路由实现无刷新跳转。
- 页面在切换时需保留用户状态(如登录状态、购物车数量),避免信息丢失。
2. **首页与商品展示逻辑**
- 首页加载时,通过接口获取推荐商品与轮播图信息,渲染到商品卡片区。
- 用户点击分类入口或搜索框时,跳转到商品分类/搜索结果页面。
- “加入购物车”按钮点击后,实时调用购物车更新逻辑,并在页面顶部动态刷新购物车图标数量。
3. **搜索与筛选逻辑**
- 用户在搜索框输入关键词并提交,系统调用商品数据接口,返回符合条件的商品列表。
- 筛选条件(如价格区间、销量、评分)变化时,页面自动刷新商品结果并保持搜索关键词不变。
- 排序选项(价格升序、销量优先)通过前端逻辑控制数据展示顺序,保证结果直观可读。
4. **商品详情逻辑**
- 用户点击商品卡片进入详情页,页面需渲染商品高清图、价格、库存、评价等详细信息。
- 规格选择逻辑:点击不同的规格选项,价格和库存信息实时更新。
- “加入购物车”按钮触发购物车数据更新,若用户未登录,则提示登录。
5. **购物车逻辑**
- 加入购物车后,购物车页面渲染所有选中商品的名称、价格、数量、合计金额。
- 用户可在购物车修改数量或删除商品,页面需实时更新总金额。
- 点击“去结算”按钮后,校验用户是否登录;若未登录,跳转到登录页面;若已登录,则进入结算页面。
6. **结算与支付逻辑**
- 结算页面需展示用户收货信息、支付金额明细、选择支付方式入口。
- 用户点击“确认支付”后,模拟生成订单,并跳转到订单成功页。
- 若支付失败或取消,系统提示并返回购物车。
7. **用户登录/注册逻辑**
- 用户登录:输入账号密码,验证通过后存储登录状态(本地存储或 session
- 用户注册:填写必要信息(用户名、邮箱/手机号、密码),完成后自动跳转到登录页面。
- 登录状态需在所有页面全局生效,并影响购物车、个人中心等功能的可用性。
8. **个人中心逻辑**
- 登录用户可在个人中心查看历史订单、账户信息、收货地址。
- 点击历史订单可进入订单详情页,查看支付状态与物流信息。
- 支持用户修改基本资料与退出登录操作。
# 五、重要注意事项与关键点补充
让AI代替开发者的思考学习过程询问项目开发的重要部分内容可以弥补开发者经验不足的问题并且可以保障项目质量。
输入给ChatGpt的提示词及输出结果如下
```markdown
这个项目有什么需要我注意的地方?
```
1. **页面一致性与可用性**
- 所有页面(首页、分类、详情、购物车、结算、个人中心)必须采用统一的导航栏与页脚设计,保证用户无论在哪个页面都能快速返回首页或进入购物车。
- 保证移动端与PC端的样式一致性响应式布局必须覆盖主流分辨率≥320px 的手机屏幕到 ≥1920px 的桌面屏幕)。
2. **数据交互与状态管理**
- 购物车、登录状态、订单信息等关键数据需统一管理,避免因刷新或页面切换导致数据丢失。
- 推荐使用本地存储localStorage/sessionStorage或前端状态管理工具如 Redux/Vuex来保证状态同步。
3. **用户体验优化**
- 搜索和筛选需设置防抖/节流,避免频繁请求导致性能下降。
- 商品图片需支持懒加载,提升页面加载速度。
- 在购物流程中,每个关键动作(加入购物车、提交订单、支付确认)必须有明确的视觉反馈。
4. **安全性与合规性**
- 登录/注册输入框需有前端校验如密码长度≥6位、邮箱格式正确
- 支付流程可先模拟,但必须预留安全接口,后续接入第三方支付时保证合规。
- 避免在前端暴露敏感信息(如用户密码、支付密钥),所有敏感校验必须在后端完成。
5. **性能与兼容性**
- CSS、JS 文件需压缩打包,减少首屏加载时间。
- 图片需使用合适格式(如 WebP、JPEG 压缩)保证清晰度与加载速度的平衡。
- 必须兼容主流浏览器Chrome、Firefox、Safari、Edge及常用手机浏览器微信内置浏览器、UC、QQ 浏览器)。
6. **常见易错点提醒**
- **购物车数量更新异常**:常见问题是修改数量后金额未实时更新,需要双向绑定逻辑。
- **登录状态丢失**:若只保存在内存中,刷新页面会丢失,应写入本地存储。
- **结算金额不一致**:前端显示金额必须与后端订单生成金额一致,避免用户体验差或纠纷。
- **响应式缺陷**仅在PC端测试可能导致移动端显示错乱需逐屏测试。
# 六、页面结构与交互流程图
页面结构与交互流程图将抽象需求转译为“可视化蓝图”,以节点连线清晰呈现信息层级、页面关系、操作路径与状态反馈,使产品、设计、开发、测试四方在同一幅图里快速对齐认知、发现断点与冗余。
输入给ChatGpt的提示词及输出结果如下
```markdown
给我这个项目的结构框架和用户交互流程(文字版)
```
## 1. 页面结构图
```
首页Home
├── 商品分类页Category
│ ├── 分类列表
│ ├── 筛选条件
│ └── 排序选项
├── 搜索结果页Search Result
│ ├── 搜索框
│ ├── 商品列表
│ └── 筛选/排序功能
├── 商品详情页Product Detail
│ ├── 商品图片展示
│ ├── 规格参数选择
│ ├── 用户评价
│ └── 加入购物车按钮
├── 购物车页Cart
│ ├── 已选商品列表
│ ├── 数量修改与删除
│ └── 去结算按钮
├── 结算/支付页Checkout/Payment
│ ├── 收货信息
│ ├── 支付方式选择
│ └── 订单确认
├── 订单成功页Order Success
│ └── 返回首页 / 查看订单按钮
├── 用户登录/注册页Login/Register
│ ├── 登录表单
│ └── 注册表单
└── 个人中心页User Center
├── 历史订单
├── 收货地址管理
└── 账号信息设置
```
---
## 2. 用户交互流程图
```
用户进入首页
浏览推荐商品 / 选择分类 / 搜索商品
商品列表展示(分类页 / 搜索结果页)
点击商品 → 进入商品详情页
选择规格、数量 → 点击“加入购物车”
进入购物车页
调整数量 / 删除商品 → 点击“去结算”
结算页(需登录验证)
[未登录] → 跳转登录/注册页 → 登录成功返回结算
[已登录] → 填写收货信息 → 选择支付方式 → 确认订单
支付成功 → 跳转订单成功页
用户可选择:
- 返回首页继续购物
- 前往个人中心查看订单历史
```
# 七、常见错误与优化建议
1. **页面跳转状态丢失**
- **错误表现**:用户从首页进入商品详情或购物车时,登录状态或购物车数据丢失,导致需要重复登录或重新选择商品。
- **原因分析**:缺乏统一的状态管理,仅在页面级别存储用户信息。
- **优化建议**使用本地存储LocalStorage/SessionStorage或前端状态管理Redux/Vuex保证数据在多页面间持久化。
2. **购物车更新不同步**
- **错误表现**:用户在详情页加入购物车后,购物车图标数量未更新,或购物车页面数据与实际不一致。
- **原因分析**:购物车数据修改后未触发全局刷新,或接口调用与渲染逻辑未绑定。
- **优化建议**:建立购物车数据的统一更新方法,并在更新后触发全局状态变化,保证所有组件同步响应。
3. **响应式布局缺陷**
- **错误表现**:网站在手机端或平板端出现内容溢出、按钮错位、文字遮挡等问题。
- **原因分析**:页面仅针对 PC 端设计,未充分考虑不同分辨率适配。
- **优化建议**采用响应式框架Bootstrap、Tailwind CSS或媒体查询逐屏测试常见设备分辨率。
4. **商品搜索与筛选性能低下**
- **错误表现**:用户在搜索框输入或筛选条件切换时,页面卡顿或频繁刷新。
- **原因分析**:没有设置防抖/节流,导致过多请求同时发出。
- **优化建议**:对搜索/筛选操作设置防抖300ms 左右),减少请求次数,同时对返回结果做缓存以提升性能。
5. **结算金额与订单金额不一致**
- **错误表现**:结算页面显示的总金额与订单提交后生成的金额不同,容易引发纠纷。
- **原因分析**:仅在前端计算金额,缺乏与后端的校验逻辑。
- **优化建议**:金额计算应以前端展示为主,但最终以后台返回金额为准,前端需同步展示后端的确认金额。
6. **安全校验缺失**
- **错误表现**:登录表单可输入无效账号,或结算时可提交空收货地址。
- **原因分析**:缺少前端输入验证逻辑。
- **优化建议**:在前端增加正则验证(如密码长度、邮箱格式、地址非空),并结合后端二次校验,避免恶意输入。
7. **图片加载过慢**
- **错误表现**:商品图片清晰度高,但页面加载时间过长,用户等待体验差。
- **原因分析**:未进行图片压缩与懒加载。
- **优化建议**:采用 WebP 等高效格式,结合懒加载(仅当图片进入视口时才加载)。
# 八、项目开发阶段
项目具体开发阶段可以在项目架构清晰的前提下向AI输出具体的描述需求及要求文字用AI辅助生成代码供开发者参考与使用。
输入给ChatGpt的提示词及输出结果如下
```markdown
基于以上内容的聊天记录和网页开发的一般流程,分板块输出符合我要求的具体代码,并且要完整、细致、可供我直接黏贴复制。
```
## 1. 公共脚本
```jsx
/**
* 公共方法库 - common.js
* 提供购物车管理、订单管理、工具函数等功能
* 所有页面均可调用
*/
//////////////////// 工具函数 ////////////////////
/**
* 格式化价格(保留两位小数,前缀¥)
* @param {number} price
* @returns {string}
*/
function formatPrice(price) {
return "¥" + price.toFixed(2);
}
//////////////////// 购物车相关 ////////////////////
/**
* 获取购物车
* @returns {Array}
*/
function getCart() {
return JSON.parse(localStorage.getItem("cart")) || [];
}
/**
* 保存购物车
* @param {Array} cart
*/
function saveCart(cart) {
localStorage.setItem("cart", JSON.stringify(cart));
}
/**
* 清空购物车
*/
function clearCart() {
localStorage.removeItem("cart");
}
/**
* 添加商品到购物车
* @param {Object} product - 商品对象
* @param {number} quantity - 数量
*/
function addToCart(product, quantity = 1) {
let cart = getCart();
const index = cart.findIndex(item => item.id === product.id && item.spec === product.spec);
if (index > -1) {
cart[index].quantity += quantity;
} else {
cart.push({ ...product, quantity });
}
saveCart(cart);
alert("已加入购物车!");
}
/**
* 从购物车中删除商品
* @param {number} index - 商品在购物车中的索引
*/
function removeFromCart(index) {
let cart = getCart();
if (index > -1) {
cart.splice(index, 1);
saveCart(cart);
}
}
//////////////////// 订单相关 ////////////////////
/**
* 获取订单列表
* @returns {Array}
*/
function getOrders() {
return JSON.parse(localStorage.getItem("orders")) || [];
}
/**
* 保存订单
* @param {Array} orders
*/
function saveOrders(orders) {
localStorage.setItem("orders", JSON.stringify(orders));
}
/**
* 添加新订单
* @param {Object} order
*/
function addOrder(order) {
let orders = getOrders();
orders.push(order);
saveOrders(orders);
}
//////////////////// 导航高亮(可选) ////////////////////
/**
* 页面导航高亮处理
* 在每个页面的 <nav> 中给当前页面加高亮样式
*/
function highlightNav() {
const path = window.location.pathname.split("/").pop();
const links = document.querySelectorAll("nav a");
links.forEach(link => {
if (link.getAttribute("href") === path) {
link.style.fontWeight = "bold";
link.style.color = "#e91e63";
}
});
}
// 页面加载完成后自动执行高亮
document.addEventListener("DOMContentLoaded", highlightNav);
```
## 2. 购物网站首页的基础框架代码
```html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>购物网站首页</title>
<style>
/* 基础样式 */
body {
font-family: Arial, sans-serif;
margin: 0;
padding: 0;
background-color: #f5f5f5;
}
header {
background-color: #333;
color: #fff;
padding: 15px;
display: flex;
justify-content: space-between;
align-items: center;
}
header h1 {
margin: 0;
font-size: 20px;
}
nav a {
color: #fff;
margin-left: 20px;
text-decoration: none;
}
nav a:hover {
text-decoration: underline;
}
.banner {
width: 100%;
height: 250px;
background: url('https://picsum.photos/1200/250?random=1') no-repeat center;
background-size: cover;
}
.product-list {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 20px;
padding: 20px;
}
.product-card {
background: #fff;
border-radius: 5px;
padding: 10px;
box-shadow: 0 2px 6px rgba(0,0,0,0.1);
text-align: center;
transition: transform 0.2s;
}
.product-card:hover {
transform: translateY(-5px);
}
.product-card img {
width: 100%;
border-radius: 5px;
}
.product-card h3 {
font-size: 16px;
margin: 10px 0 5px;
}
.product-card p {
color: #e91e63;
font-weight: bold;
}
.product-card button {
background: #e91e63;
border: none;
padding: 8px 12px;
color: #fff;
border-radius: 3px;
cursor: pointer;
}
.product-card button:hover {
background: #c2185b;
}
</style>
</head>
<body>
<!-- 顶部导航 -->
<header>
<h1>我的购物网站</h1>
<nav>
<a href="#">首页</a>
<a href="#">分类</a>
<a href="#">购物车</a>
<a href="#">个人中心</a>
</nav>
</header>
<!-- banner 区域 -->
<div class="banner"></div>
<!-- 商品展示区 -->
<section class="product-list" id="productList">
<!-- 商品卡片通过JS动态加载 -->
</section>
<script>
// 模拟商品数据
const products = [
{ id: 1, name: "高清电子书阅读器", price: 59.9, img: "https://picsum.photos/200/200?random=11" },
{ id: 2, name: "运动健身手环", price: 199.0, img: "https://picsum.photos/200/200?random=12" },
{ id: 3, name: "智能家居摄像头", price: 299.0, img: "https://picsum.photos/200/200?random=13" },
{ id: 4, name: "便携式咖啡机", price: 499.0, img: "https://picsum.photos/200/200?random=14" },
{ id: 5, name: "便携式登山背包", price: 129.0, img: "https://picsum.photos/200/200?random=15" },
{ id: 6, name: "速干运动裤", price: 89.0, img: "https://picsum.photos/200/200?random=16" }
];
const productList = document.getElementById("productList");
// 渲染商品卡片
products.forEach(product => {
const card = document.createElement("div");
card.className = "product-card";
card.innerHTML = `
<img src="${product.img}" alt="${product.name}">
<h3>${product.name}</h3>
<p>¥${product.price.toFixed(2)}</p>
<button onclick="addToCart(${product.id})">加入购物车</button>
`;
productList.appendChild(card);
});
// 模拟加入购物车
function addToCart(id) {
const product = products.find(p => p.id === id);
alert(`已将【${product.name}】加入购物车!`);
}
</script>
</body>
</html>
```
## 3. 商品详情页逻辑
- detail.html
```html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>商品详情</title>
<link rel="stylesheet" href="css/style.css">
<style>
.detail-container {
max-width: 1000px;
margin: 30px auto;
display: flex;
gap: 30px;
background: #fff;
padding: 20px;
border-radius: 6px;
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
}
.detail-container img {
width: 400px;
border-radius: 4px;
}
.detail-info {
flex: 1;
}
.detail-info h2 {
margin: 0 0 15px;
font-size: 22px;
}
.detail-info p {
margin: 8px 0;
}
.detail-price {
color: #e91e63;
font-size: 20px;
margin: 10px 0;
}
.detail-actions {
margin-top: 20px;
}
.detail-actions input {
width: 60px;
padding: 6px;
margin-right: 10px;
}
.detail-actions button {
padding: 10px 20px;
margin-right: 10px;
background: #333;
color: #fff;
border: none;
border-radius: 4px;
cursor: pointer;
}
.detail-actions button:hover {
background: #e91e63;
}
</style>
</head>
<body>
<!-- 顶部导航 -->
<header>
<h1>我的购物网站</h1>
<nav>
<a href="index.html">首页</a>
<a href="cart.html">购物车</a>
<a href="user-center.html">个人中心</a>
</nav>
</header>
<!-- 商品详情 -->
<div class="detail-container">
<img id="productImg" src="" alt="商品图片">
<div class="detail-info">
<h2 id="productName">商品名称</h2>
<p id="productDesc">这里是商品描述。</p>
<p class="detail-price" id="productPrice"></p>
<p>
规格:
<select id="productSpec">
<option value="默认">默认</option>
<option value="大号">大号</option>
<option value="中号">中号</option>
<option value="小号">小号</option>
</select>
</p>
<div class="detail-actions">
<input type="number" id="productQuantity" value="1" min="1">
<button id="addToCartBtn">加入购物车</button>
<button id="buyNowBtn">立即购买</button>
</div>
</div>
</div>
<script src="js/common.js"></script>
<script src="js/detail.js"></script>
</body>
</html>
```
- js/detail.js
```jsx
/**
* 商品详情逻辑 - detail.js
* 负责渲染商品信息 & 加入购物车 & 立即购买
*/
// 模拟商品数据(实际可从 products.json 或 URL 参数获取)
const products = [
{ id: 1, name: "高清电子书阅读器", desc: "屏幕清晰,眼睛不疲惫。", price: 59.9, img: "https://picsum.photos/400/400?random=21" },
{ id: 2, name: "运动健身手环", desc: "轻便舒适,适合日常和运动。", price: 199.0, img: "https://picsum.photos/400/400?random=22" },
{ id: 3, name: "智能家居摄像头", desc: "高清画质,自带续航。", price: 299.0, img: "https://picsum.photos/400/400?random=23" },
{ id: 4, name: "便携式咖啡机", desc: "经典时尚,操作方便。", price: 499.0, img: "https://picsum.photos/400/400?random=24" },
{ id: 5, name: "便携式登山背包", desc: "大容量设计,适合旅行和上学。", price: 129.0, img: "https://picsum.photos/400/400?random=25" },
{ id: 6, name: "速干运动裤", desc: "舒适弹性,适合运动休闲。", price: 89.0, img: "https://picsum.photos/400/400?random=26" }
];
// 获取 URL 参数 (例如 detail.html?id=2)
const urlParams = new URLSearchParams(window.location.search);
const productId = parseInt(urlParams.get("id")) || 1; // 默认展示第1个
// 找到对应商品
const product = products.find(p => p.id === productId);
// DOM 元素
const productImg = document.getElementById("productImg");
const productName = document.getElementById("productName");
const productDesc = document.getElementById("productDesc");
const productPrice = document.getElementById("productPrice");
const productSpec = document.getElementById("productSpec");
const productQuantity = document.getElementById("productQuantity");
const addToCartBtn = document.getElementById("addToCartBtn");
const buyNowBtn = document.getElementById("buyNowBtn");
// 渲染商品
function renderProduct() {
if (!product) {
document.querySelector(".detail-container").innerHTML = "<p>商品不存在</p>";
return;
}
productImg.src = product.img;
productName.innerText = product.name;
productDesc.innerText = product.desc;
productPrice.innerText = formatPrice(product.price);
}
// 加入购物车
addToCartBtn.addEventListener("click", () => {
const quantity = parseInt(productQuantity.value);
const spec = productSpec.value;
addToCart({ ...product, spec }, quantity);
});
// 立即购买
buyNowBtn.addEventListener("click", () => {
const quantity = parseInt(productQuantity.value);
const spec = productSpec.value;
// 先加入购物车,再跳转到结算
addToCart({ ...product, spec }, quantity);
window.location.href = "checkout.html";
});
// 初始化
renderProduct();
```
## 4. 购物车逻辑
```html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>购物车</title>
<style>
body {
font-family: Arial, sans-serif;
margin: 0;
padding: 0;
background-color: #f5f5f5;
}
header {
background-color: #333;
color: #fff;
padding: 15px;
display: flex;
justify-content: space-between;
align-items: center;
}
header h1 {
margin: 0;
font-size: 20px;
}
nav a {
color: #fff;
margin-left: 20px;
text-decoration: none;
}
nav a:hover {
text-decoration: underline;
}
.cart-container {
max-width: 1000px;
margin: 20px auto;
padding: 20px;
background: #fff;
border-radius: 5px;
box-shadow: 0 2px 6px rgba(0,0,0,0.1);
}
.cart-item {
display: flex;
align-items: center;
justify-content: space-between;
padding: 10px 0;
border-bottom: 1px solid #ddd;
}
.cart-item img {
width: 80px;
height: 80px;
object-fit: cover;
border-radius: 5px;
}
.cart-item-info {
flex: 2;
margin-left: 15px;
}
.cart-item-info h3 {
margin: 0 0 5px;
}
.cart-item-price {
flex: 1;
text-align: center;
color: #e91e63;
font-weight: bold;
}
.cart-item-quantity {
flex: 1;
text-align: center;
}
.cart-item-quantity input {
width: 50px;
text-align: center;
padding: 5px;
}
.cart-item-remove {
flex: 0.5;
text-align: center;
}
.cart-item-remove button {
background: #f44336;
color: #fff;
border: none;
padding: 6px 10px;
cursor: pointer;
border-radius: 3px;
}
.cart-summary {
text-align: right;
margin-top: 20px;
}
.cart-summary p {
font-size: 18px;
margin: 5px 0;
}
.checkout-btn {
background: #e91e63;
border: none;
padding: 10px 20px;
color: #fff;
border-radius: 3px;
cursor: pointer;
font-size: 16px;
}
.checkout-btn:hover {
background: #c2185b;
}
</style>
</head>
<body>
<!-- 顶部导航 -->
<header>
<h1>我的购物网站</h1>
<nav>
<a href="index.html">首页</a>
<a href="#">分类</a>
<a href="cart.html">购物车</a>
<a href="#">个人中心</a>
</nav>
</header>
<!-- 购物车主体 -->
<div class="cart-container" id="cartContainer">
<!-- 购物车商品通过JS渲染 -->
</div>
<div class="cart-summary" id="cartSummary">
<p>总金额:¥<span id="totalPrice">0.00</span></p>
<button class="checkout-btn" onclick="checkout()">去结算</button>
</div>
<script>
// 模拟购物车数据(后续可与详情页 addToCart 对接)
let cart = [
{ id: 1, name: "夏季T恤", price: 59.9, quantity: 2, img: "https://picsum.photos/200/200?random=11" },
{ id: 2, name: "运动鞋", price: 199.0, quantity: 1, img: "https://picsum.photos/200/200?random=12" }
];
const cartContainer = document.getElementById("cartContainer");
const totalPriceEl = document.getElementById("totalPrice");
// 渲染购物车
function renderCart() {
cartContainer.innerHTML = "";
let total = 0;
cart.forEach((item, index) => {
total += item.price * item.quantity;
const cartItem = document.createElement("div");
cartItem.className = "cart-item";
cartItem.innerHTML = `
<img src="${item.img}" alt="${item.name}">
<div class="cart-item-info">
<h3>${item.name}</h3>
</div>
<div class="cart-item-price">¥${item.price.toFixed(2)}</div>
<div class="cart-item-quantity">
<input type="number" min="1" value="${item.quantity}" onchange="updateQuantity(${index}, this.value)">
</div>
<div class="cart-item-remove">
<button onclick="removeItem(${index})">删除</button>
</div>
`;
cartContainer.appendChild(cartItem);
});
totalPriceEl.innerText = total.toFixed(2);
}
// 修改数量
function updateQuantity(index, value) {
cart[index].quantity = parseInt(value);
renderCart();
}
// 删除商品
function removeItem(index) {
cart.splice(index, 1);
renderCart();
}
// 去结算
function checkout() {
if (cart.length === 0) {
alert("购物车为空,无法结算!");
return;
}
alert("跳转到结算页面(模拟)");
}
// 初始渲染
renderCart();
</script>
</body>
</html>
```
## 5. 结算逻辑
```html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>结算与支付</title>
<style>
body {
font-family: Arial, sans-serif;
margin: 0;
padding: 0;
background-color: #f5f5f5;
}
header {
background-color: #333;
color: #fff;
padding: 15px;
display: flex;
justify-content: space-between;
align-items: center;
}
header h1 {
margin: 0;
font-size: 20px;
}
nav a {
color: #fff;
margin-left: 20px;
text-decoration: none;
}
nav a:hover {
text-decoration: underline;
}
.checkout-container {
max-width: 1000px;
margin: 20px auto;
padding: 20px;
background: #fff;
border-radius: 5px;
box-shadow: 0 2px 6px rgba(0,0,0,0.1);
}
h2 {
border-left: 4px solid #e91e63;
padding-left: 10px;
margin-top: 20px;
}
.form-group {
margin: 15px 0;
}
.form-group label {
display: block;
margin-bottom: 5px;
}
.form-group input {
width: 100%;
padding: 8px;
border: 1px solid #ccc;
border-radius: 3px;
}
.order-summary {
margin-top: 20px;
padding: 15px;
border: 1px solid #ddd;
border-radius: 5px;
background: #fafafa;
}
.order-summary p {
margin: 8px 0;
font-size: 16px;
}
.payment-options {
margin-top: 15px;
}
.payment-options label {
margin-right: 15px;
}
.checkout-btn {
margin-top: 20px;
background: #e91e63;
border: none;
padding: 12px 20px;
color: #fff;
border-radius: 3px;
cursor: pointer;
font-size: 16px;
}
.checkout-btn:hover {
background: #c2185b;
}
</style>
</head>
<body>
<!-- 顶部导航 -->
<header>
<h1>我的购物网站</h1>
<nav>
<a href="index.html">首页</a>
<a href="#">分类</a>
<a href="cart.html">购物车</a>
<a href="#">个人中心</a>
</nav>
</header>
<!-- 结算主体 -->
<div class="checkout-container">
<h2>收货信息</h2>
<div class="form-group">
<label for="name">收货人姓名</label>
<input type="text" id="name" placeholder="请输入姓名">
</div>
<div class="form-group">
<label for="phone">联系电话</label>
<input type="text" id="phone" placeholder="请输入手机号">
</div>
<div class="form-group">
<label for="address">收货地址</label>
<input type="text" id="address" placeholder="请输入详细地址">
</div>
<h2>订单信息</h2>
<div class="order-summary" id="orderSummary">
<!-- 模拟订单商品信息 -->
<p>夏季T恤 x2 — ¥119.80</p>
<p>运动鞋 x1 — ¥199.00</p>
<p><strong>总金额¥318.80</strong></p>
</div>
<h2>支付方式</h2>
<div class="payment-options">
<label><input type="radio" name="payment" value="支付宝"> 支付宝</label>
<label><input type="radio" name="payment" value="微信支付"> 微信支付</label>
<label><input type="radio" name="payment" value="银行卡"> 银行卡</label>
</div>
<button class="checkout-btn" onclick="confirmOrder()">确认支付</button>
</div>
<script>
function confirmOrder() {
const name = document.getElementById("name").value.trim();
const phone = document.getElementById("phone").value.trim();
const address = document.getElementById("address").value.trim();
const payment = document.querySelector("input[name='payment']:checked");
if (!name || !phone || !address) {
alert("请填写完整的收货信息!");
return;
}
if (!payment) {
alert("请选择支付方式!");
return;
}
alert(`订单已提交!收货人:${name}, 支付方式:${payment.value}`);
// 这里可跳转到订单成功页
window.location.href = "order-success.html";
}
</script>
</body>
</html>
```
## 6. 订单成功页逻辑
```html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>订单成功</title>
<style>
body {
font-family: Arial, sans-serif;
margin: 0;
padding: 0;
background-color: #f5f5f5;
text-align: center;
}
header {
background-color: #333;
color: #fff;
padding: 15px;
}
header h1 {
margin: 0;
font-size: 20px;
}
.success-container {
max-width: 600px;
margin: 50px auto;
padding: 30px;
background: #fff;
border-radius: 5px;
box-shadow: 0 2px 6px rgba(0,0,0,0.1);
}
.success-icon {
font-size: 60px;
color: #4caf50;
margin-bottom: 20px;
}
.success-container h2 {
margin-top: 0;
color: #333;
}
.success-container p {
color: #666;
font-size: 16px;
margin: 10px 0 20px;
}
.success-actions a {
display: inline-block;
margin: 10px;
padding: 12px 20px;
border-radius: 3px;
text-decoration: none;
color: #fff;
font-size: 16px;
}
.btn-home {
background: #2196f3;
}
.btn-home:hover {
background: #1976d2;
}
.btn-orders {
background: #e91e63;
}
.btn-orders:hover {
background: #c2185b;
}
</style>
</head>
<body>
<!-- 顶部导航 -->
<header>
<h1>我的购物网站</h1>
</header>
<!-- 成功提示内容 -->
<div class="success-container">
<div class="success-icon"></div>
<h2>订单提交成功!</h2>
<p>感谢您的购买,我们会尽快为您发货。</p>
<div class="success-actions">
<a href="index.html" class="btn-home">返回首页</a>
<a href="user-center.html" class="btn-orders">查看我的订单</a>
</div>
</div>
</body>
</html>
```
## 7. 个人中心逻辑代码
- user-center.html
```html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>个人中心</title>
<link rel="stylesheet" href="css/style.css">
<style>
body {
font-family: Arial, sans-serif;
margin: 0;
padding: 0;
background-color: #f5f5f5;
}
header {
background-color: #333;
color: #fff;
padding: 15px;
display: flex;
justify-content: space-between;
align-items: center;
}
header h1 {
margin: 0;
font-size: 20px;
}
nav a {
color: #fff;
margin-left: 20px;
text-decoration: none;
}
nav a:hover {
text-decoration: underline;
}
.user-container {
max-width: 1000px;
margin: 20px auto;
padding: 20px;
background: #fff;
border-radius: 5px;
box-shadow: 0 2px 6px rgba(0,0,0,0.1);
}
h2 {
border-left: 4px solid #e91e63;
padding-left: 10px;
margin-top: 20px;
}
.order {
border-bottom: 1px solid #ddd;
padding: 15px 0;
}
.order:last-child {
border-bottom: none;
}
.order h3 {
margin: 0 0 10px;
}
.order p {
margin: 4px 0;
color: #555;
}
.order-items {
margin-top: 10px;
padding-left: 15px;
}
.no-orders {
text-align: center;
color: #999;
margin: 30px 0;
}
</style>
</head>
<body>
<!-- 顶部导航 -->
<header>
<h1>我的购物网站</h1>
<nav>
<a href="index.html">首页</a>
<a href="cart.html">购物车</a>
<a href="user-center.html">个人中心</a>
</nav>
</header>
<!-- 用户中心主体 -->
<div class="user-container">
<h2>我的订单</h2>
<div id="orderList"></div>
</div>
<script src="js/common.js"></script>
<script src="js/user-center.js"></script>
</body>
</html>
```
- js/user-center.js
```jsx
/**
* 个人中心逻辑 - user-center.js
* 负责渲染用户的历史订单
*/
const orderListEl = document.getElementById("orderList");
function renderOrders() {
const orders = getOrders(); // 调用 common.js 获取订单数据
if (orders.length === 0) {
orderListEl.innerHTML = `<p class="no-orders">暂无订单记录</p>`;
return;
}
orders.forEach(order => {
const orderDiv = document.createElement("div");
orderDiv.className = "order";
orderDiv.innerHTML = `
<h3>订单号:${order.id}</h3>
<p>收货人:${order.user} | 电话:${order.phone}</p>
<p>收货地址:${order.address}</p>
<p>支付方式:${order.payment}</p>
<p>下单时间:${order.createdAt}</p>
<p><strong>总金额:${formatPrice(order.total)}</strong></p>
<div class="order-items">
${order.items.map(item => `
<p>${item.name}${item.spec ? " - " + item.spec : ""} x${item.quantity} — ${formatPrice(item.price * item.quantity)}</p>
`).join("")}
</div>
`;
orderListEl.appendChild(orderDiv);
});
}
// 初始化
renderOrders();
```