本文目录导读:

我来为您详细规划PHP项目中文档在线借阅功能的开发流程。
核心功能模块设计
数据库表结构
-- 文档表
CREATE TABLE documents (
id INT PRIMARY KEY AUTO_INCREMENT,VARCHAR(200) NOT NULL,
author VARCHAR(100),
file_path VARCHAR(500),
file_size INT,
file_type VARCHAR(50),
status TINYINT DEFAULT 1, -- 1:可借阅 0:已下架
borrow_count INT DEFAULT 0,
max_borrow_days INT DEFAULT 30,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
-- 借阅记录表
CREATE TABLE borrow_records (
id INT PRIMARY KEY AUTO_INCREMENT,
document_id INT NOT NULL,
user_id INT NOT NULL,
borrow_date DATETIME NOT NULL,
due_date DATETIME NOT NULL,
return_date DATETIME,
status TINYINT DEFAULT 0, -- 0:借阅中 1:已归还 2:逾期
renew_count INT DEFAULT 0,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (document_id) REFERENCES documents(id),
FOREIGN KEY (user_id) REFERENCES users(id)
);
后端API开发(PHP)
文档借阅控制器
<?php
// BorrowController.php
class BorrowController {
private $db;
public function __construct($db) {
$this->db = $db;
}
// 借阅文档
public function borrowDocument($userId, $documentId) {
try {
$this->db->beginTransaction();
// 检查文档是否可借阅
$doc = $this->getDocument($documentId);
if (!$doc || $doc['status'] != 1) {
throw new Exception("文档不可借阅");
}
// 检查该用户是否已借阅
if ($this->hasBorrowed($userId, $documentId)) {
throw new Exception("您已借阅过此文档");
}
// 创建借阅记录
$borrowDate = date('Y-m-d H:i:s');
$dueDate = date('Y-m-d H:i:s', strtotime("+{$doc['max_borrow_days']} days"));
$sql = "INSERT INTO borrow_records (document_id, user_id, borrow_date, due_date)
VALUES (?, ?, ?, ?)";
$stmt = $this->db->prepare($sql);
$stmt->execute([$documentId, $userId, $borrowDate, $dueDate]);
// 更新文档借阅次数
$this->updateBorrowCount($documentId);
$this->db->commit();
return ['success' => true, 'message' => '借阅成功', 'due_date' => $dueDate];
} catch (Exception $e) {
$this->db->rollBack();
return ['success' => false, 'message' => $e->getMessage()];
}
}
// 归还文档
public function returnDocument($userId, $borrowRecordId) {
$returnDate = date('Y-m-d H:i:s');
$sql = "UPDATE borrow_records SET
return_date = ?,
status = CASE
WHEN return_date > due_date THEN 2
ELSE 1
END
WHERE id = ? AND user_id = ? AND status = 0";
$stmt = $this->db->prepare($sql);
return $stmt->execute([$returnDate, $borrowRecordId, $userId]);
}
// 续借文档
public function renewDocument($userId, $borrowRecordId) {
try {
$this->db->beginTransaction();
// 检查续借条件
$record = $this->getBorrowRecord($borrowRecordId);
if (!$record || $record['user_id'] != $userId) {
throw new Exception("借阅记录不存在");
}
if ($record['renew_count'] >= 1) {
throw new Exception("已达最大续借次数");
}
// 延长借阅期限
$newDueDate = date('Y-m-d H:i:s', strtotime($record['due_date'] . ' + 14 days'));
$sql = "UPDATE borrow_records SET
due_date = ?,
renew_count = renew_count + 1
WHERE id = ? AND status = 0";
$stmt = $this->db->prepare($sql);
$stmt->execute([$newDueDate, $borrowRecordId]);
$this->db->commit();
return ['success' => true, 'new_due_date' => $newDueDate];
} catch (Exception $e) {
$this->db->rollBack();
return ['success' => false, 'message' => $e->getMessage()];
}
}
private function hasBorrowed($userId, $documentId) {
$sql = "SELECT id FROM borrow_records
WHERE user_id = ? AND document_id = ? AND status = 0";
$stmt = $this->db->prepare($sql);
$stmt->execute([$userId, $documentId]);
return $stmt->fetch() ? true : false;
}
}
前端实现(HTML + JavaScript + AJAX)
借阅功能前端界面
<!DOCTYPE html>
<html>
<head>文档借阅系统</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="container">
<h2>文档借阅管理</h2>
<!-- 文档列表 -->
<div id="documentList"></div>
<!-- 借阅弹窗 -->
<div id="borrowModal" class="modal">
<div class="modal-content">
<span class="close">×</span>
<h3>确认借阅文档</h3>
<p id="documentInfo"></p>
<div class="form-group">
<label>借阅时长: <span id="maxDays"></span> 天</label>
</div>
<button onclick="confirmBorrow()" class="btn-primary">确认借阅</button>
</div>
</div>
<!-- 我的借阅记录 -->
<div id="myBorrows">
<h3>我的借阅记录</h3>
<div id="borrowRecords"></div>
</div>
</div>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script>
// 加载文档列表
function loadDocuments() {
$.ajax({
url: '/api/documents.php',
method: 'GET',
success: function(data) {
renderDocumentList(data);
}
});
}
// 借阅文档
function borrowDocument(docId) {
$.ajax({
url: '/api/borrow.php',
method: 'POST',
data: {
action: 'borrow',
document_id: docId
},
success: function(response) {
if(response.success) {
alert('借阅成功,请在 ' + response.due_date + ' 前归还');
loadMyBorrows();
} else {
alert(response.message);
}
}
});
}
// 归还文档
function returnDocument(recordId) {
if(confirm('确认归还此文档?')) {
$.ajax({
url: '/api/borrow.php',
method: 'POST',
data: {
action: 'return',
record_id: recordId
},
success: function(response) {
if(response.success) {
alert('归还成功');
loadMyBorrows();
}
}
});
}
}
// 续借文档
function renewDocument(recordId) {
$.ajax({
url: '/api/borrow.php',
method: 'POST',
data: {
action: 'renew',
record_id: recordId
},
success: function(response) {
if(response.success) {
alert('续借成功,新到期时间:' + response.new_due_date);
loadMyBorrows();
} else {
alert(response.message);
}
}
});
}
</script>
</body>
</html>
权限控制与安全策略
权限验证中间件
<?php
// AuthMiddleware.php
class AuthMiddleware {
public function checkPermission($userId, $documentId, $action) {
switch($action) {
case 'borrow':
// 检查用户等级和文档权限
return $this->canBorrow($userId, $documentId);
case 'return':
// 只有借阅者可以归还
return $this->isOwner($userId, $documentId);
default:
return false;
}
}
private function canBorrow($userId, $documentId) {
// 实现权限检查逻辑
// VIP用户可以借阅更多文档
$userLevel = $this->getUserLevel($userId);
$docLevel = $this->getDocumentLevel($documentId);
return $userLevel >= $docLevel;
}
}
进阶功能实现
定时任务 - 逾期提醒
<?php
// cron/overdue_reminder.php
// 每天运行一次,检查逾期文档
$sql = "SELECT br.*, d.title, u.email
FROM borrow_records br
JOIN documents d ON br.document_id = d.id
JOIN users u ON br.user_id = u.id
WHERE br.status = 0 AND br.due_date < NOW()";
$stmt = $db->prepare($sql);
$stmt->execute();
$overdueRecords = $stmt->fetchAll();
foreach ($overdueRecords as $record) {
// 发送逾期提醒邮件
sendOverdueEmail($record['email'], $record['title'], $record['due_date']);
}
文档预览功能
<?php
// DocumentPreviewController.php
class DocumentPreviewController {
public function previewDocument($documentId, $userId) {
// 验证权限
$sql = "SELECT * FROM borrow_records
WHERE document_id = ? AND user_id = ? AND status = 0";
$stmt = $this->db->prepare($sql);
$stmt->execute([$documentId, $userId]);
if ($stmt->fetch()) {
// 允许预览(前几页)
return $this->generatePreview($documentId);
} else {
// 只显示文档信息
return $this->getDocumentInfo($documentId);
}
}
}
配置建议
系统配置
<?php
// config/borrow.php
return [
// 借阅规则配置
'rules' => [
'max_borrow_days' => 30, // 最大借阅天数
'max_renew_times' => 1, // 最大续借次数
'renew_days' => 14, // 续借延长天数
'max_borrow_count' => 5, // 同时最大借阅数量
'overdue_fine_per_day' => 0.5 // 逾期费用(每天)
],
// 文件上传配置
'upload' => [
'max_file_size' => 50 * 1024 * 1024, // 50MB
'allowed_types' => ['pdf', 'doc', 'docx', 'txt'],
'upload_path' => '/uploads/documents/'
]
];
这个完整的借阅系统包含了基本的借阅流程、权限控制、安全策略和扩展功能,您可以根据实际需求进行调整和优化。