基于 Laravel 开发一个二手书交易系统

从 0 到 1 实战:基于 Laravel 开发一个二手书交易系统

本文分享一个基于 Laravel 开发的二手书交易系统实战案例,详细介绍了项目背景、需求分析、数据库设计、模型关系、路由规划、图书发布、购物车、订单事务处理、模拟支付、权限控制以及后台管理等内容。项目围绕真实的二手书交易场景展开,重点解决了库存唯一、订单一致性和角色权限等实际开发问题,非常适合作为 Laravel 学习和面试展示项目。


基于 Laravel 开发一个二手书交易系统:项目设计、功能拆解与落地实践

一、项目背景

随着高校和读书社区的发展,二手书交易一直是一个很有现实价值的场景。很多学生和读者手中都有大量闲置书籍,这些书往往只看过一次,保存完好,但长期放置又会造成资源浪费。

市面上虽然存在一些综合类二手交易平台,但对于“书籍”这个垂直品类来说,它有一些比较鲜明的特点:

  • 用户更关注书籍版本、出版社、成色、笔记情况
  • 交易金额通常不高,但交易频次较高
  • 搜索和分类的重要性很强
  • 买家经常会关注同一本书的不同卖家报价
  • 卖家对发布流程的便捷性要求较高

因此,我决定使用 Laravel 开发一个专门面向“二手书交易”的 Web 系统,用来实现一个完整的交易闭环,包括:

  • 用户注册登录
  • 图书发布
  • 图书浏览与搜索
  • 购物车
  • 下单支付(模拟)
  • 订单管理
  • 卖家管理书籍状态
  • 收藏与评价
  • 后台管理

这个项目既能锻炼 Laravel 的基础能力,也能覆盖实际开发中常见的模块设计,是一个非常适合练手和写进简历的中型项目。


二、项目目标

本项目希望实现一个基本可用的二手书交易平台,满足以下核心目标:

1. 面向用户端

普通用户可以:

  • 注册账号、登录系统
  • 浏览二手书列表
  • 查看书籍详情
  • 按分类、关键词、价格筛选图书
  • 发布自己想出售的书籍
  • 收藏感兴趣的书籍
  • 将书籍加入购物车
  • 提交订单并完成模拟支付
  • 查看历史订单
  • 对已完成交易进行评价

2. 面向卖家端

卖家可以:

  • 发布二手书信息
  • 编辑书籍资料
  • 上传书籍图片
  • 管理库存状态
  • 查看自己收到的订单
  • 标记发货
  • 处理下架、售罄等状态

3. 面向管理员

管理员可以:

  • 管理用户
  • 管理图书分类
  • 审核图书信息
  • 处理违规发布内容
  • 查看订单统计
  • 管理评价和举报信息

三、技术选型

这套系统的技术栈如下:

1
2
3
4
5
6
7
8
9
后端框架:Laravel 10
前端模板:Blade
数据库:MySQL 8.x
缓存/队列:Redis(可选)
认证方案:Laravel Breeze / Laravel Sanctum
文件存储:本地存储或 OSS
UI 框架:Bootstrap 5
开发环境:PHP 8.2 + Composer + Node.js + Vite
部署环境:Nginx + PHP-FPM + MySQL

为什么选择 Laravel?

Laravel 非常适合构建这种中小型业务系统,主要有几个原因:

  1. MVC 结构清晰
    模型、控制器、视图分离明确,便于维护。

  2. Eloquent ORM 开发效率高
    数据表之间的关系建模非常自然,特别适合电商/交易类系统。

  3. 路由和中间件机制成熟
    用户权限、认证拦截、后台管理都比较方便。

  4. 生态完善
    包括认证、文件上传、邮件通知、队列任务、API 开发等都有成熟方案。

  5. 适合作为完整案例展示
    从数据库设计到前后台交互都能覆盖,容易形成可讲述的项目经验。


四、需求分析

在正式开始编码之前,我先对系统做了一个需求拆分。


五、核心功能模块

1. 用户模块

用户模块主要负责账号体系与个人中心功能,包含:

  • 注册
  • 登录
  • 退出登录
  • 修改个人资料
  • 修改头像
  • 修改密码
  • 查看我的发布
  • 查看我的订单
  • 查看我的收藏

2. 图书模块

图书模块是系统的核心,主要包括:

  • 发布图书
  • 编辑图书
  • 删除图书
  • 图书详情展示
  • 图书列表分页
  • 分类筛选
  • 关键词搜索
  • 书籍状态管理(在售、已售、下架)

图书发布时,需要录入以下字段:

  • 书名
  • 作者
  • 出版社
  • ISBN(可选)
  • 原价
  • 售价
  • 成色
  • 分类
  • 描述
  • 图片
  • 是否有笔记/划线
  • 卖家信息

3. 购物车模块

买家可以将感兴趣的二手书加入购物车,并进行统一结算。

由于二手书一般每本只有一件库存,所以这里的购物车逻辑和普通电商有些区别:

  • 书籍通常只能买一件
  • 同一本书一旦被购买,其他用户应无法继续下单
  • 加入购物车并不代表锁定库存
  • 真正扣减库存应发生在订单创建/支付环节

4. 订单模块

订单模块包括:

  • 创建订单
  • 查看订单详情
  • 模拟支付
  • 取消订单
  • 卖家发货
  • 买家确认收货
  • 订单评价

订单状态设计为:

1
2
3
4
5
6
pending     待支付
paid 已支付
shipped 已发货
completed 已完成
cancelled 已取消
refunded 已退款(预留)

5. 收藏与评价模块

为了增强平台互动,可以加入:

  • 收藏书籍
  • 取消收藏
  • 订单完成后进行评分
  • 发表评论内容
  • 展示卖家信誉

6. 后台管理模块

后台可以实现以下功能:

  • 用户管理
  • 分类管理
  • 书籍审核
  • 订单查看
  • 举报处理
  • 数据统计

六、系统角色设计

本系统主要有三类角色:

角色 描述
普通用户 可以浏览、购买、收藏图书
卖家 实际上也是普通用户,但可以发布图书
管理员 负责后台管理与审核

从实现角度来说,可以在 users 表中增加一个 role 字段:

1
role: user / admin

卖家不需要单独的角色字段,因为“能发布图书的普通用户”天然就是卖家。


七、数据库设计

数据库设计是整个项目的关键部分。下面是我对主要数据表的设计思路。


八、数据表设计

1. users 用户表

1
2
3
4
5
6
7
8
9
10
id
name
email
password
avatar
phone
address
role
created_at
updated_at

说明:

  • role 用于区分普通用户和管理员
  • avatar 存储头像路径
  • address 可以作为默认收货地址

2. categories 图书分类表

1
2
3
4
5
id
name
sort
created_at
updated_at

示例分类:

  • 文学
  • 计算机
  • 考研
  • 外语
  • 历史
  • 经管
  • 小说
  • 教材

3. books 图书表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
id
user_id
category_id
title
author
publisher
isbn
origin_price
price
condition_level
description
image
status
has_note
stock
view_count
created_at
updated_at
deleted_at

字段说明:

  • user_id:卖家 ID
  • category_id:分类 ID
  • condition_level:成色,例如“95新”“8成新”
  • status:在售、已售、下架、待审核
  • has_note:是否有笔记
  • stock:库存,虽然二手书通常是 1,但可以预留多个册数场景
  • view_count:浏览量
  • deleted_at:软删除

推荐状态值:

1
2
3
4
5
pending   待审核
active 在售
sold 已售
off 已下架
rejected 审核拒绝

4. cart_items 购物车表

1
2
3
4
5
id
user_id
book_id
created_at
updated_at

说明:

  • 一个用户可以收藏多个购物车商品
  • 同一本书对于同一用户只能存在一条记录

5. orders 订单表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
id
order_no
buyer_id
seller_id
total_amount
status
payment_time
shipping_time
completion_time
receiver_name
receiver_phone
receiver_address
remark
created_at
updated_at

说明:

  • order_no 为订单编号
  • 一个订单可以只买一本,也可以支持多本
  • buyer_id 是买家
  • seller_id 可在单卖家场景中存在;多卖家场景建议拆分子订单

6. order_items 订单明细表

1
2
3
4
5
6
7
8
id
order_id
book_id
book_title
book_price
quantity
created_at
updated_at

说明:

  • 下单时把书名和价格冗余存进去,避免后续图书信息修改影响订单历史
  • 二手书场景下一般 quantity = 1

7. favorites 收藏表

1
2
3
4
5
id
user_id
book_id
created_at
updated_at

8. reviews 评价表

1
2
3
4
5
6
7
8
9
id
order_id
book_id
buyer_id
seller_id
rating
content
created_at
updated_at

评分建议使用 1~5 分。


9. reports 举报表(可选)

1
2
3
4
5
6
7
id
user_id
book_id
reason
status
created_at
updated_at

九、Eloquent 模型关系设计

Laravel 的优势之一就是模型关系表达非常清晰。

User 模型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class User extends Authenticatable
{
public function books()
{
return $this->hasMany(Book::class);
}

public function orders()
{
return $this->hasMany(Order::class, 'buyer_id');
}

public function favorites()
{
return $this->hasMany(Favorite::class);
}
}

Book 模型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
class Book extends Model
{
use SoftDeletes;

protected $fillable = [
'user_id',
'category_id',
'title',
'author',
'publisher',
'isbn',
'origin_price',
'price',
'condition_level',
'description',
'image',
'status',
'has_note',
'stock',
];

public function seller()
{
return $this->belongsTo(User::class, 'user_id');
}

public function category()
{
return $this->belongsTo(Category::class);
}
}

Order 模型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class Order extends Model
{
protected $fillable = [
'order_no',
'buyer_id',
'seller_id',
'total_amount',
'status',
'receiver_name',
'receiver_phone',
'receiver_address',
'remark',
];

public function buyer()
{
return $this->belongsTo(User::class, 'buyer_id');
}

public function items()
{
return $this->hasMany(OrderItem::class);
}
}

十、项目目录结构设计

在 Laravel 中,这个项目我会尽量按职责拆分目录:

1
2
3
4
5
6
7
8
9
10
11
12
app/
├── Http/
│ ├── Controllers/
│ │ ├── Front/
│ │ ├── Seller/
│ │ └── Admin/
│ ├── Requests/
│ └── Middleware/
├── Models/
├── Services/
├── Repositories/
└── Helpers/

推荐拆分方式

  • Front:前台用户功能
  • Seller:卖家中心
  • Admin:后台管理
  • Requests:表单校验
  • Services:业务逻辑,比如创建订单、支付处理
  • Repositories:可选,用于封装数据访问

对于中型项目,Controller 不宜写太重,可以把复杂逻辑放到 Service 层。


十一、路由设计

前台路由示例

1
2
3
4
5
6
7
8
9
10
Route::get('/', [HomeController::class, 'index'])->name('home');
Route::get('/books', [BookController::class, 'index'])->name('books.index');
Route::get('/books/{book}', [BookController::class, 'show'])->name('books.show');

Route::middleware('auth')->group(function () {
Route::get('/cart', [CartController::class, 'index'])->name('cart.index');
Route::post('/cart/add/{book}', [CartController::class, 'add'])->name('cart.add');
Route::post('/orders/checkout', [OrderController::class, 'checkout'])->name('orders.checkout');
Route::get('/orders', [OrderController::class, 'index'])->name('orders.index');
});

卖家路由示例

1
2
3
4
5
6
Route::middleware('auth')->prefix('seller')->name('seller.')->group(function () {
Route::get('/books', [SellerBookController::class, 'index'])->name('books.index');
Route::get('/books/create', [SellerBookController::class, 'create'])->name('books.create');
Route::post('/books', [SellerBookController::class, 'store'])->name('books.store');
Route::get('/orders', [SellerOrderController::class, 'index'])->name('orders.index');
});

后台路由示例

1
2
3
4
5
6
Route::middleware(['auth', 'admin'])->prefix('admin')->name('admin.')->group(function () {
Route::resource('users', AdminUserController::class);
Route::resource('categories', AdminCategoryController::class);
Route::resource('books', AdminBookController::class);
Route::resource('orders', AdminOrderController::class);
});

十二、关键业务流程设计


十三、图书发布流程

卖家发布一本二手书,大致流程如下:

1
2
3
4
5
6
7
8
进入发布页面
-> 填写图书信息
-> 上传图片
-> 提交表单
-> 后端校验
-> 保存数据库
-> 状态设为 pending 或 active
-> 返回发布成功页面

表单校验示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class StoreBookRequest extends FormRequest
{
public function rules(): array
{
return [
'title' => 'required|string|max:255',
'author' => 'required|string|max:100',
'category_id' => 'required|exists:categories,id',
'price' => 'required|numeric|min:0.01',
'origin_price' => 'nullable|numeric|min:0',
'condition_level' => 'required|string|max:50',
'description' => 'required|string|min:10',
'image' => 'required|image|max:2048',
];
}
}

控制器示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public function store(StoreBookRequest $request)
{
$data = $request->validated();

if ($request->hasFile('image')) {
$data['image'] = $request->file('image')->store('books', 'public');
}

$data['user_id'] = auth()->id();
$data['status'] = 'pending';
$data['stock'] = 1;

Book::create($data);

return redirect()->route('seller.books.index')
->with('success', '图书发布成功,等待审核');
}

十四、图书搜索与筛选设计

图书搜索是用户体验的重点之一。

支持筛选条件

  • 关键词(书名、作者、出版社)
  • 分类
  • 价格区间
  • 成色
  • 排序方式(最新、价格升序、价格降序、热度)

查询示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public function index(Request $request)
{
$query = Book::query()
->where('status', 'active');

if ($keyword = $request->keyword) {
$query->where(function ($q) use ($keyword) {
$q->where('title', 'like', "%{$keyword}%")
->orWhere('author', 'like', "%{$keyword}%")
->orWhere('publisher', 'like', "%{$keyword}%");
});
}

if ($categoryId = $request->category_id) {
$query->where('category_id', $categoryId);
}

if ($min = $request->min_price) {
$query->where('price', '>=', $min);
}

if ($max = $request->max_price) {
$query->where('price', '<=', $max);
}

$books = $query->latest()->paginate(12);

return view('books.index', compact('books'));
}

这个逻辑虽然简单,但已经能满足大部分场景。后续还可以进一步加入:

  • Elasticsearch 全文搜索
  • 热门搜索关键词统计
  • 搜索联想
  • 历史搜索记录

十五、购物车设计思路

购物车逻辑看似简单,实际上很容易出现并发问题。

添加购物车时要注意

  1. 图书必须是“在售”
  2. 不能添加自己发布的书
  3. 购物车中不能重复添加
  4. 库存必须大于 0

示例代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public function add(Book $book)
{
if ($book->user_id == auth()->id()) {
return back()->with('error', '不能购买自己发布的图书');
}

if ($book->status !== 'active' || $book->stock < 1) {
return back()->with('error', '该图书已不可购买');
}

CartItem::firstOrCreate([
'user_id' => auth()->id(),
'book_id' => $book->id,
]);

return back()->with('success', '已加入购物车');
}

十六、订单创建与事务处理

订单创建是整个系统中最核心、最敏感的模块,必须确保数据一致性。

关键问题

  • 下单时图书是否已被别人买走?
  • 同一本二手书是否会被重复售卖?
  • 扣减库存和创建订单是否要放进事务?
  • 订单失败时是否要回滚?

答案是:必须使用数据库事务

下单核心流程

1
2
3
4
5
6
7
8
9
10
用户点击结算
-> 获取购物车商品
-> 检查每本书是否仍在售
-> 开启事务
-> 创建订单
-> 创建订单明细
-> 扣减库存
-> 修改图书状态为 sold
-> 删除购物车记录
-> 提交事务

示例代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
DB::transaction(function () use ($cartItems, $request) {
$totalAmount = $cartItems->sum(fn($item) => $item->book->price);

$firstBook = $cartItems->first()->book;

$order = Order::create([
'order_no' => 'ORD' . now()->format('YmdHis') . rand(1000, 9999),
'buyer_id' => auth()->id(),
'seller_id' => $firstBook->user_id,
'total_amount' => $totalAmount,
'status' => 'pending',
'receiver_name' => $request->receiver_name,
'receiver_phone' => $request->receiver_phone,
'receiver_address' => $request->receiver_address,
]);

foreach ($cartItems as $item) {
$book = Book::lockForUpdate()->find($item->book_id);

if (!$book || $book->status !== 'active' || $book->stock < 1) {
throw new \Exception("图书 {$book->title} 已不可购买");
}

OrderItem::create([
'order_id' => $order->id,
'book_id' => $book->id,
'book_title' => $book->title,
'book_price' => $book->price,
'quantity' => 1,
]);

$book->update([
'stock' => 0,
'status' => 'sold',
]);
}

CartItem::where('user_id', auth()->id())->delete();
});

为什么要使用 lockForUpdate()

因为二手书库存非常敏感,同一本书可能被两个人同时抢购。

lockForUpdate() 能在事务中锁住这条记录,避免多个请求同时修改库存,防止“超卖”。


十七、模拟支付设计

由于这是一个练手项目,不接入真实支付,可以设计一个模拟支付流程。

流程

1
2
3
4
5
订单创建成功
-> 进入支付页面
-> 点击“确认支付”
-> 修改订单状态为 paid
-> 记录支付时间

示例代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public function pay(Order $order)
{
if ($order->buyer_id !== auth()->id()) {
abort(403);
}

if ($order->status !== 'pending') {
return back()->with('error', '订单状态异常');
}

$order->update([
'status' => 'paid',
'payment_time' => now(),
]);

return redirect()->route('orders.show', $order)
->with('success', '支付成功');
}

后续若要扩展,也可以对接:

  • 支付宝沙箱
  • 微信支付
  • Stripe

十八、卖家发货与买家确认收货

发货逻辑

卖家在订单状态为 paid 时,才可以点击发货。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public function ship(Order $order)
{
if ($order->seller_id !== auth()->id()) {
abort(403);
}

if ($order->status !== 'paid') {
return back()->with('error', '订单尚未支付');
}

$order->update([
'status' => 'shipped',
'shipping_time' => now(),
]);

return back()->with('success', '已发货');
}

确认收货逻辑

买家在订单状态为 shipped 时可以确认收货:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public function confirm(Order $order)
{
if ($order->buyer_id !== auth()->id()) {
abort(403);
}

if ($order->status !== 'shipped') {
return back()->with('error', '订单状态不允许确认收货');
}

$order->update([
'status' => 'completed',
'completion_time' => now(),
]);

return back()->with('success', '交易完成');
}

十九、权限控制设计

Laravel 的中间件特别适合做权限控制。

登录权限

未登录用户不能:

  • 发布图书
  • 加入购物车
  • 下单
  • 收藏
  • 评价

管理员权限

管理员才可以访问后台路由。

admin 中间件示例

1
2
3
4
5
6
7
8
public function handle(Request $request, Closure $next)
{
if (auth()->check() && auth()->user()->role === 'admin') {
return $next($request);
}

abort(403, '无权限访问');
}

二十、前端页面设计思路

尽管这是后端项目,但前端交互体验也很重要。

页面结构建议

1. 首页

展示:

  • 热门图书
  • 最新发布
  • 分类入口
  • 搜索框

2. 图书列表页

展示:

  • 缩略图
  • 书名
  • 作者
  • 成色
  • 价格
  • 卖家
  • 收藏按钮

3. 图书详情页

展示:

  • 大图
  • 书籍基础信息
  • 卖家信息
  • 图书描述
  • 是否有笔记
  • 加购物车按钮
  • 立即购买按钮

4. 卖家中心

展示:

  • 我的发布
  • 待售图书
  • 已售图书
  • 发布新图书
  • 收到的订单

5. 个人中心

展示:

  • 我的订单
  • 我的收藏
  • 我的地址
  • 账户设置

6. 管理后台

展示:

  • 用户列表
  • 图书审核
  • 分类管理
  • 订单管理
  • 数据面板

二十一、Blade 模板拆分建议

可以将 Blade 模板按以下方式组织:

1
2
3
4
5
6
7
8
9
10
resources/views/
├── layouts/
│ └── app.blade.php
├── home/
├── books/
├── cart/
├── orders/
├── seller/
├── admin/
└── components/

公共布局模板

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>@yield('title', '二手书交易系统')</title>
@vite(['resources/css/app.css', 'resources/js/app.js'])
</head>
<body>
@include('components.navbar')

<main class="container mt-4">
@include('components.flash')
@yield('content')
</main>
</body>
</html>

这样后续维护会轻松很多。


二十二、项目中的难点与解决方案

这个项目虽然体量不算特别大,但在开发过程中还是会遇到一些比较典型的难点。

难点 1:防止二手书重复售卖

问题

二手书通常只有一件库存,如果两个买家同时购买,就容易发生超卖。

解决方案

  • 下单时使用事务
  • 查询库存时使用 lockForUpdate()
  • 支付前后确保状态校验
  • 图书状态从 active 变为 sold

难点 2:订单与图书状态的一致性

问题

订单创建成功但图书状态未更新,或者图书售出但订单失败,会造成脏数据。

解决方案

将以下操作放进同一个事务中:

  • 创建订单
  • 创建订单明细
  • 更新图书库存
  • 修改图书状态
  • 清空购物车

只要其中一步失败,就整体回滚。


难点 3:书籍信息快照

问题

如果订单中的书名、价格直接关联 books 表,后续卖家修改图书信息会影响历史订单显示。

解决方案

order_items 表中冗余保存:

  • 书名
  • 成交价格
  • 数量

这样历史订单永远不会因为主表变化而失真。


难点 4:权限边界

问题

买家、卖家、管理员的操作权限不同,很容易出现越权访问。

解决方案

多层控制:

  • 路由中间件限制
  • 控制器内再次校验资源归属
  • 使用 Policy 统一处理授权逻辑

例如:

1
2
3
4
public function update(User $user, Book $book)
{
return $user->id === $book->user_id;
}

难点 5:图片上传与存储

问题

图书图片是系统的重要组成部分,需要考虑:

  • 文件大小限制
  • 图片格式校验
  • 存储路径管理
  • 默认图处理

解决方案

  • 使用 Laravel Storage
  • 统一存入 public/books
  • 保存相对路径到数据库
  • 在前端通过 Storage::url() 渲染图片

二十三、性能优化思路

项目初期数据量不大,但仍然可以从一开始养成性能优化意识。

1. 避免 N+1 查询

图书列表页通常会展示:

  • 图书信息
  • 分类名
  • 卖家信息

如果不做预加载,很容易出现 N+1 问题。

1
$books = Book::with(['category', 'seller'])->latest()->paginate(12);

2. 使用索引

建议为以下字段加索引:

  • books.category_id
  • books.status
  • books.user_id
  • orders.buyer_id
  • orders.seller_id
  • favorites.user_id
  • cart_items.user_id

3. 热门数据缓存

首页热门图书、分类列表可以做缓存:

1
2
3
$categories = Cache::remember('book_categories', 3600, function () {
return Category::orderBy('sort')->get();
});

4. 图片压缩

如果图书图片过大,会明显影响页面加载速度。可以在上传后使用图片处理库进行压缩,比如 Intervention Image。


二十四、可扩展功能

这个项目如果继续深入,还可以扩展很多高级功能。

1. 即时聊天

买家可以和卖家直接沟通,比如:

  • 书内有无笔记
  • 是否包邮
  • 能否议价

可以使用:

  • Laravel WebSockets
  • Pusher
  • Echo

2. 举报与审核机制

针对违规内容、盗版书、虚假信息进行举报与审核。

3. 支付接入

接入真实支付系统,实现完整交易闭环。

4. 物流信息

卖家发货后填写快递单号,买家查看物流状态。

5. 消息通知

包括:

  • 下单通知
  • 支付通知
  • 发货通知
  • 收货通知
  • 审核结果通知

可以使用:

  • 邮件
  • 短信
  • 站内信
  • WebSocket 实时通知

6. API 化

前后端分离版本可使用:

  • Laravel Sanctum
  • Laravel Passport
  • Vue / React / UniApp

7. 评分信誉体系

为卖家建立信誉分:

  • 成交量
  • 好评率
  • 回复速度
  • 发货及时率

8. 推荐系统

根据用户收藏、浏览、购买行为推荐类似图书。


二十五、项目开发流程回顾

整个项目可以按以下顺序推进:

第一步:初始化项目

1
laravel new used-book-market

或:

1
composer create-project laravel/laravel used-book-market

第二步:配置数据库

修改 .env

1
2
3
4
5
6
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=used_book_market
DB_USERNAME=root
DB_PASSWORD=123456

第三步:安装认证脚手架

1
2
3
4
composer require laravel/breeze --dev
php artisan breeze:install blade
npm install && npm run build
php artisan migrate

第四步:创建模型和迁移

1
2
3
4
5
6
7
php artisan make:model Book -mcr
php artisan make:model Category -mcr
php artisan make:model Order -mcr
php artisan make:model OrderItem -mcr
php artisan make:model CartItem -mcr
php artisan make:model Favorite -mcr
php artisan make:model Review -mcr

第五步:补充迁移文件并执行

1
php artisan migrate

第六步:实现前台列表、详情、发布功能

优先完成最关键的业务链路:

  • 图书列表
  • 图书详情
  • 发布图书
  • 我的图书

第七步:实现购物车与订单

完成交易闭环:

  • 加入购物车
  • 结算
  • 创建订单
  • 模拟支付
  • 发货
  • 收货

第八步:加入后台管理

补充:

  • 分类管理
  • 图书审核
  • 用户管理
  • 订单查看

第九步:优化样式和交互

  • 表单校验提示
  • 空状态页面
  • Toast 提示
  • 图片预览
  • 分页美化

文章目录

  1. 从 0 到 1 实战:基于 Laravel 开发一个二手书交易系统
  2. 基于 Laravel 开发一个二手书交易系统:项目设计、功能拆解与落地实践
    1. 一、项目背景
    2. 二、项目目标
      1. 1. 面向用户端
      2. 2. 面向卖家端
      3. 3. 面向管理员
    3. 三、技术选型
      1. 为什么选择 Laravel?
    4. 四、需求分析
    5. 五、核心功能模块
      1. 1. 用户模块
      2. 2. 图书模块
      3. 3. 购物车模块
      4. 4. 订单模块
      5. 5. 收藏与评价模块
      6. 6. 后台管理模块
    6. 六、系统角色设计
    7. 七、数据库设计
    8. 八、数据表设计
      1. 1. users 用户表
      2. 2. categories 图书分类表
      3. 3. books 图书表
      4. 4. cart_items 购物车表
      5. 5. orders 订单表
      6. 6. order_items 订单明细表
      7. 7. favorites 收藏表
      8. 8. reviews 评价表
      9. 9. reports 举报表(可选)
    9. 九、Eloquent 模型关系设计
      1. User 模型
      2. Book 模型
      3. Order 模型
    10. 十、项目目录结构设计
      1. 推荐拆分方式
    11. 十一、路由设计
      1. 前台路由示例
      2. 卖家路由示例
      3. 后台路由示例
    12. 十二、关键业务流程设计
    13. 十三、图书发布流程
      1. 表单校验示例
      2. 控制器示例
    14. 十四、图书搜索与筛选设计
      1. 支持筛选条件
      2. 查询示例
    15. 十五、购物车设计思路
      1. 添加购物车时要注意
      2. 示例代码
    16. 十六、订单创建与事务处理
      1. 关键问题
      2. 下单核心流程
      3. 示例代码
      4. 为什么要使用 lockForUpdate()?
    17. 十七、模拟支付设计
      1. 流程
      2. 示例代码
    18. 十八、卖家发货与买家确认收货
      1. 发货逻辑
      2. 确认收货逻辑
    19. 十九、权限控制设计
      1. 登录权限
      2. 管理员权限
      3. admin 中间件示例
    20. 二十、前端页面设计思路
      1. 页面结构建议
        1. 1. 首页
        2. 2. 图书列表页
        3. 3. 图书详情页
        4. 4. 卖家中心
        5. 5. 个人中心
        6. 6. 管理后台
    21. 二十一、Blade 模板拆分建议
      1. 公共布局模板
    22. 二十二、项目中的难点与解决方案
      1. 难点 1:防止二手书重复售卖
        1. 问题
        2. 解决方案
      2. 难点 2:订单与图书状态的一致性
        1. 问题
        2. 解决方案
      3. 难点 3:书籍信息快照
        1. 问题
        2. 解决方案
      4. 难点 4:权限边界
        1. 问题
        2. 解决方案
      5. 难点 5:图片上传与存储
        1. 问题
        2. 解决方案
    23. 二十三、性能优化思路
      1. 1. 避免 N+1 查询
      2. 2. 使用索引
      3. 3. 热门数据缓存
      4. 4. 图片压缩
    24. 二十四、可扩展功能
      1. 1. 即时聊天
      2. 2. 举报与审核机制
      3. 3. 支付接入
      4. 4. 物流信息
      5. 5. 消息通知
      6. 6. API 化
      7. 7. 评分信誉体系
      8. 8. 推荐系统
    25. 二十五、项目开发流程回顾
      1. 第一步:初始化项目
      2. 第二步:配置数据库
      3. 第三步:安装认证脚手架
      4. 第四步:创建模型和迁移
      5. 第五步:补充迁移文件并执行
      6. 第六步:实现前台列表、详情、发布功能
      7. 第七步:实现购物车与订单
      8. 第八步:加入后台管理
      9. 第九步:优化样式和交互