系统概述
1. 项目目标
开发一个基于 Web 的离线订单管理系统,主要服务于外贸公司,该系统旨在帮助业务员录入、管理、跟踪和导出来自邮件、展会、客户拜访等线下渠道获取的订单信息,实现订单处理的数字化和流程化,提高工作效率。

(图片来源网络,侵删)
2. 技术栈
- 后端: PHP (推荐 PHP 7.4+)
- 前端: HTML5, CSS3, JavaScript (原生或使用 Bootstrap/Tailwind CSS 快速构建响应式界面)
- 数据库: MySQL 5.7+
- Web 服务器: Apache 或 Nginx
3. 核心功能模块
- 用户管理: 用户登录、注册、权限控制(管理员、业务员、财务等)。
- 客户管理: 添加、编辑、查看客户信息(公司名、联系人、邮箱、电话、地址等)。
- 产品管理: 添加、编辑、查看产品信息(SKU、名称、描述、成本价、销售价等)。
- 订单管理:
- 创建订单: 手动录入订单信息,包括客户、产品、数量、价格、币种、付款方式、交货期等。
- 订单列表: 分页、搜索、排序(按订单号、客户、日期、状态)。
- 订单详情: 查看和编辑订单的完整信息。
- 订单状态管理: 标记订单状态(如:草稿、已确认、生产中、已发货、已完成、已取消)。
- 报表与统计:
- 销售额统计(按时间段、客户、产品)。
- 订单数量统计。
- 可导出为 Excel 或 PDF。
数据库设计
这是系统的核心,良好的数据库设计至关重要,以下是几个核心表的设计。
1. 用户表 (users)
CREATE TABLE `users` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(50) NOT NULL COMMENT '用户名',
`password` varchar(255) NOT NULL COMMENT '密码 (存储哈希值)',
`full_name` varchar(100) NOT NULL COMMENT '真实姓名',
`email` varchar(100) DEFAULT NULL COMMENT '邮箱',
`role` enum('admin', 'sales', 'finance') NOT NULL DEFAULT 'sales' COMMENT '角色',
`created_at` timestamp NOT NULL DEFAULT current_timestamp(),
`updated_at` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
PRIMARY KEY (`id`),
UNIQUE KEY `username` (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
2. 客户表 (customers)
CREATE TABLE `customers` ( `id` int(11) NOT NULL AUTO_INCREMENT, `customer_code` varchar(20) NOT NULL COMMENT '客户编码', `company_name` varchar(255) NOT NULL COMMENT '公司名', `contact_person` varchar(100) DEFAULT NULL COMMENT '联系人', `email` varchar(100) DEFAULT NULL COMMENT '邮箱', `phone` varchar(20) DEFAULT NULL COMMENT '电话', `address` text COMMENT '地址', `country` varchar(50) DEFAULT NULL COMMENT '国家', `created_by` int(11) NOT NULL COMMENT '创建人ID (关联users.id)', `created_at` timestamp NOT NULL DEFAULT current_timestamp(), `updated_at` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(), PRIMARY KEY (`id`), UNIQUE KEY `customer_code` (`customer_code`), KEY `created_by` (`created_by`), CONSTRAINT `customers_ibfk_1` FOREIGN KEY (`created_by`) REFERENCES `users` (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
3. 产品表 (products)
CREATE TABLE `products` ( `id` int(11) NOT NULL AUTO_INCREMENT, `sku` varchar(50) NOT NULL COMMENT 'SKU/产品编码', `product_name` varchar(255) NOT NULL COMMENT '产品名称', `description` text COMMENT '产品描述', `cost_price` decimal(10, 2) DEFAULT NULL COMMENT '成本价', `sale_price` decimal(10, 2) NOT NULL COMMENT '销售价', `currency` char(3) NOT NULL DEFAULT 'USD' COMMENT '币种', `created_by` int(11) NOT NULL COMMENT '创建人ID', `created_at` timestamp NOT NULL DEFAULT current_timestamp(), `updated_at` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(), PRIMARY KEY (`id`), UNIQUE KEY `sku` (`sku`), KEY `created_by` (`created_by`), CONSTRAINT `products_ibfk_1` FOREIGN KEY (`created_by`) REFERENCES `users` (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
4. 订单主表 (orders)
CREATE TABLE `orders` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`order_number` varchar(50) NOT NULL COMMENT '订单号',
`customer_id` int(11) NOT NULL COMMENT '客户ID (关联customers.id)',
`order_date` date NOT NULL COMMENT '下单日期',
`delivery_date` date DEFAULT NULL COMMENT '要求交货日期',
`total_amount` decimal(15, 2) NOT NULL COMMENT '订单总金额',
`currency` char(3) NOT NULL DEFAULT 'USD' COMMENT '币种',
`payment_terms` varchar(100) DEFAULT NULL COMMENT '付款方式 (如: T/T, L/C)',
`shipping_address` text COMMENT '收货地址',
`status` enum('draft', 'confirmed', 'in_production', 'shipped', 'completed', 'cancelled') NOT NULL DEFAULT 'draft' COMMENT '订单状态',
`notes` text COMMENT '备注',
`created_by` int(11) NOT NULL COMMENT '创建人ID',
`created_at` timestamp NOT NULL DEFAULT current_timestamp(),
`updated_at` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
PRIMARY KEY (`id`),
UNIQUE KEY `order_number` (`order_number`),
KEY `customer_id` (`customer_id`),
KEY `created_by` (`created_by`),
CONSTRAINT `orders_ibfk_1` FOREIGN KEY (`customer_id`) REFERENCES `customers` (`id`),
CONSTRAINT `orders_ibfk_2` FOREIGN KEY (`created_by`) REFERENCES `users` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
5. 订单明细表 (order_items)
CREATE TABLE `order_items` ( `id` int(11) NOT NULL AUTO_INCREMENT, `order_id` int(11) NOT NULL COMMENT '订单ID (关联orders.id)', `product_id` int(11) NOT NULL COMMENT '产品ID (关联products.id)', `quantity` int(11) NOT NULL COMMENT '数量', `unit_price` decimal(10, 2) NOT NULL COMMENT '单价', `total_price` decimal(10, 2) NOT NULL COMMENT '小计', PRIMARY KEY (`id`), KEY `order_id` (`order_id`), KEY `product_id` (`product_id`), CONSTRAINT `order_items_ibfk_1` FOREIGN KEY (`order_id`) REFERENCES `orders` (`id`), CONSTRAINT `order_items_ibfk_2` FOREIGN KEY (`product_id`) REFERENCES `products` (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
核心功能实现
我们将以 订单创建 和 订单列表 为例,展示核心的 PHP 代码。
1. 项目结构
/your-project-root
|-- /assets
| |-- /css
| |-- /js
|-- /includes
| |-- db.php # 数据库连接
| |-- header.php # 公共头部
| |-- footer.php # 公共底部
| |-- auth_check.php # 权限检查
|-- index.php # 首页/仪表盘
|-- login.php # 登录页面
|-- orders.php # 订单列表页面
|-- create_order.php # 创建订单页面
|-- order_details.php # 订单详情页面
|-- ...
2. 数据库连接 (includes/db.php)
<?php
// includes/db.php
$host = 'localhost';
$dbname = 'your_database_name';
$username = 'your_db_username';
$password = 'your_db_password';
try {
$pdo = new PDO("mysql:host=$host;dbname=$dbname;charset=utf8mb4", $username, $password);
// 设置 PDO 错误模式为异常
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch(PDOException $e) {
die("数据库连接失败: " . $e->getMessage());
}
?>
3. 订单列表页面 (orders.php)
这个页面将展示所有订单,并提供搜索和分页功能。
<?php
session_start();
if (!isset($_SESSION['user_id'])) {
header('Location: login.php');
exit;
}
require_once 'includes/db.php';
require_once 'includes/header.php';
// --- 分页逻辑 ---
$records_per_page = 10;
$page = isset($_GET['page']) && is_numeric($_GET['page']) ? (int)$_GET['page'] : 1;
$offset = ($page - 1) * $records_per_page;
// --- 搜索逻辑 ---
$search_query = "WHERE 1=1";
if (!empty($_GET['search'])) {
$search_term = '%' . $_GET['search'] . '%';
$search_query .= " AND (o.order_number LIKE :search OR c.company_name LIKE :search)";
}
// --- 获取订单总数 (用于分页) ---
$total_stmt = $pdo->prepare("SELECT COUNT(*) FROM orders o JOIN customers c ON o.customer_id = c.id $search_query");
if (!empty($_GET['search'])) {
$total_stmt->bindParam(':search', $search_term);
}
$total_stmt->execute();
$total_records = $total_stmt->fetchColumn();
$total_pages = ceil($total_records / $records_per_page);
// --- 获取当前页的订单数据 ---
$stmt = $pdo->prepare("
SELECT o.*, c.company_name
FROM orders o
JOIN customers c ON o.customer_id = c.id
$search_query
ORDER BY o.created_at DESC
LIMIT :offset, :limit
");
if (!empty($_GET['search'])) {
$stmt->bindParam(':search', $search_term);
}
$stmt->bindValue(':offset', $offset, PDO::PARAM_INT);
$stmt->bindValue(':limit', $records_per_page, PDO::PARAM_INT);
$stmt->execute();
$orders = $stmt->fetchAll(PDO::FETCH_ASSOC);
?>
<h1 class="mb-4">订单列表</h1>
<!-- 搜索表单 -->
<form action="orders.php" method="get" class="mb-4">
<div class="input-group">
<input type="text" name="search" class="form-control" placeholder="搜索订单号或客户名..." value="<?= htmlspecialchars($_GET['search'] ?? '') ?>">
<button class="btn btn-primary" type="submit">搜索</button>
<a href="orders.php" class="btn btn-secondary">重置</a>
</div>
</form>
<!-- 订单列表表格 -->
<div class="table-responsive">
<table class="table table-striped table-hover">
<thead>
<tr>
<th>订单号</th>
<th>客户</th>
<th>下单日期</th>
<th>总金额</th>
<th>状态</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<?php if ($orders): ?>
<?php foreach ($orders as $order): ?>
<tr>
<td><?= htmlspecialchars($order['order_number']) ?></td>
<td><?= htmlspecialchars($order['company_name']) ?></td>
<td><?= $order['order_date'] ?></td>
<td><?= htmlspecialchars($order['currency']) ?> <?= number_format($order['total_amount'], 2) ?></td>
<td><span class="badge bg-info"><?= htmlspecialchars($order['status']) ?></span></td>
<td>
<a href="order_details.php?id=<?= $order['id'] ?>" class="btn btn-sm btn-info">查看</a>
<a href="create_order.php?id=<?= $order['id'] ?>" class="btn btn-sm btn-warning">编辑</a>
</td>
</tr>
<?php endforeach; ?>
<?php else: ?>
<tr>
<td colspan="6" class="text-center">没有找到订单。</td>
</tr>
<?php endif; ?>
</tbody>
</table>
</div>
<!-- 分页链接 -->
<nav aria-label="Page navigation">
<ul class="pagination justify-content-center">
<?php for ($i = 1; $i <= $total_pages; $i++): ?>
<li class="page-item <?= $i == $page ? 'active' : '' ?>">
<a class="page-link" href="orders.php?page=<?= $i ?>&search=<?= htmlspecialchars($_GET['search'] ?? '') ?>"><?= $i ?></a>
</li>
<?php endfor; ?>
</ul>
</nav>
<?php require_once 'includes/footer.php'; ?>
4. 创建/编辑订单页面 (create_order.php)
这个页面比较复杂,需要一个表单来输入订单信息,并且需要动态地添加产品行。

(图片来源网络,侵删)
<?php
session_start();
if (!isset($_SESSION['user_id'])) {
header('Location: login.php');
exit;
}
require_once 'includes/db.php';
require_once 'includes/header.php';
// 获取所有客户和产品用于下拉列表
$stmt_customers = $pdo->query("SELECT id, company_name FROM customers ORDER BY company_name");
$customers = $stmt_customers->fetchAll(PDO::FETCH_ASSOC);
$stmt_products = $pdo->query("SELECT id, sku, product_name, sale_price, currency FROM products ORDER BY product_name");
$products = $stmt_products->fetchAll(PDO::FETCH_ASSOC);
$is_edit = isset($_GET['id']);
$order_data = null;
$order_items = [];
if ($is_edit) {
$order_id = $_GET['id'];
// 获取订单主信息
$stmt = $pdo->prepare("SELECT * FROM orders WHERE id = ?");
$stmt->execute([$order_id]);
$order_data = $stmt->fetch(PDO::FETCH_ASSOC);
// 获取订单明细
$stmt_items = $pdo->prepare("
SELECT oi.*, p.sku, p.product_name
FROM order_items oi
JOIN products p ON oi.product_id = p.id
WHERE oi.order_id = ?
");
$stmt_items->execute([$order_id]);
$order_items = $stmt_items->fetchAll(PDO::FETCH_ASSOC);
}
?>
<h1 class="mb-4"><?= $is_edit ? '编辑订单' : '创建新订单' ?></h1>
<form action="process_order.php" method="post">
<input type="hidden" name="order_id" value="<?= $is_edit ? $order_data['id'] : '' ?>">
<div class="row mb-3">
<div class="col-md-6">
<label for="order_number" class="form-label">订单号</label>
<input type="text" class="form-control" id="order_number" name="order_number" value="<?= $is_edit ? htmlspecialchars($order_data['order_number']) : '' ?>" required>
</div>
<div class="col-md-6">
<label for="customer_id" class="form-label">客户</label>
<select class="form-select" id="customer_id" name="customer_id" required>
<option value="">请选择客户</option>
<?php foreach ($customers as $customer): ?>
<option value="<?= $customer['id'] ?>" <?= ($is_edit && $order_data['customer_id'] == $customer['id']) ? 'selected' : '' ?>><?= htmlspecialchars($customer['company_name']) ?></option>
<?php endforeach; ?>
</select>
</div>
</div>
<div class="row mb-3">
<div class="col-md-6">
<label for="order_date" class="form-label">下单日期</label>
<input type="date" class="form-control" id="order_date" name="order_date" value="<?= $is_edit ? $order_data['order_date'] : date('Y-m-d') ?>" required>
</div>
<div class="col-md-6">
<label for="currency" class="form-label">币种</label>
<select class="form-select" id="currency" name="currency">
<option value="USD" <?= ($is_edit && $order_data['currency'] == 'USD') ? 'selected' : '' ?>>USD</option>
<option value="EUR" <?= ($is_edit && $order_data['currency'] == 'EUR') ? 'selected' : '' ?>>EUR</option>
<option value="CNY" <?= ($is_edit && $order_data['currency'] == 'CNY') ? 'selected' : '' ?>>CNY</option>
</select>
</div>
</div>
<!-- 订单明细表格 -->
<h3 class="mt-4 mb-3">订单明细</h3>
<div class="table-responsive">
<table class="table table-bordered" id="itemsTable">
<thead>
<tr>
<th>产品</th>
<th>SKU</th>
<th>单价</th>
<th>数量</th>
<th>小计</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<?php if ($is_edit && $order_items): ?>
<?php foreach ($order_items as $item): ?>
<tr>
<input type="hidden" name="product_id[]" value="<?= $item['product_id'] ?>">
<td><?= htmlspecialchars($item['product_name']) ?></td>
<td><?= htmlspecialchars($item['sku']) ?></td>
<td><input type="number" class="form-control form-control-sm item-price" value="<?= $item['unit_price'] ?>" data-price="<?= $item['unit_price'] ?>" readonly></td>
<td><input type="number" class="form-control form-control-sm item-quantity" name="quantity[]" value="<?= $item['quantity'] min="1" onchange="calculateRow(this)"></td>
<td><input type="text" class="form-control form-control-sm item-total" value="<?= $item['total_price'] ?>" readonly></td>
<td><button type="button" class="btn btn-sm btn-danger remove-row">删除</button></td>
</tr>
<?php endforeach; ?>
<?php else: ?>
<!-- 默认空行 -->
<tr>
<td colspan="6" class="text-center">请添加产品</td>
</tr>
<?php endif; ?>
</tbody>
<tfoot>
<tr>
<td colspan="4"><strong>订单总金额:</strong></td>
<td><strong id="grandTotal">0.00</strong></td>
<td></td>
</tr>
</tfoot>
</table>
</div>
<button type="button" class="btn btn-secondary mb-3" onclick="addRow()">+ 添加产品</button>
<div class="mb-3">
<label for="notes" class="form-label">备注</label>
<textarea class="form-control" id="notes" name="notes" rows="3"><?= $is_edit ? htmlspecialchars($order_data['notes']) : '' ?></textarea>
</div>
<button type="submit" class="btn btn-primary">保存订单</button>
<a href="orders.php" class="btn btn-secondary">取消</a>
</form>
<?php require_once 'includes/footer.php'; ?>
<!-- JavaScript 用于动态添加行和计算金额 -->
<script>
function addRow() {
const tbody = document.querySelector('#itemsTable tbody');
const rowCount = tbody.rows.length;
const newRow = tbody.insertRow();
newRow.innerHTML = `
<td>
<select name="product_id[]" class="form-select product-select" onchange="updateProductInfo(this)">
<option value="">请选择产品</option>
<?php foreach ($products as $product): ?>
<option value="<?= $product['id'] ?>" data-price="<?= $product['sale_price'] ?>" data-currency="<?= $product['currency'] ?>"><?= htmlspecialchars($product['product_name']) ?> (<?= htmlspecialchars($product['sku']) ?>)</option>
<?php endforeach; ?>
</select>
</td>
<td><input type="text" class="form-control sku-input" readonly></td>
<td><input type="number" class="form-control form-control-sm item-price" readonly></td>
<td><input type="number" class="form-control form-control-sm item-quantity" min="1" value="1" onchange="calculateRow(this)"></td>
<td><input type="text" class="form-control form-control-sm item-total" readonly></td>
<td><button type="button" class="btn btn-sm btn-danger remove-row">删除</button></td>
`;
attachRemoveListener(newRow.querySelector('.remove-row'));
}
function updateProductInfo(selectElement) {
const option = selectElement.options[selectElement.selectedIndex];
const price = option.getAttribute('data-price');
const sku = option.text.split('(')[1].replace(')', '');
const row = selectElement.closest('tr');
row.querySelector('.sku-input').value = sku;
row.querySelector('.item-price').value = price;
calculateRow(row.querySelector('.item-quantity'));
}
function calculateRow(quantityInput) {
const row = quantityInput.closest('tr');
const price = parseFloat(row.querySelector('.item-price').value) || 0;
const quantity = parseInt(quantityInput.value) || 0;
const total = price * quantity;
row.querySelector('.item-total').value = total.toFixed(2);
updateGrandTotal();
}
function updateGrandTotal() {
let total = 0;
document.querySelectorAll('.item-total').forEach(input => {
total += parseFloat(input.value) || 0;
});
document.getElementById('grandTotal').textContent = total.toFixed(2);
}
function attachRemoveListener(button) {
button.addEventListener('click', function() {
this.closest('tr').remove();
updateGrandTotal();
});
}
// 为初始的删除按钮添加监听器
document.querySelectorAll('.remove-row').forEach(button => {
attachRemoveListener(button);
});
</script>
5. 处理订单数据 (process_order.php)
这个脚本接收来自 create_order.php 表单的数据,并将其保存到数据库中,这里需要使用事务来确保数据的一致性。
<?php
session_start();
require_once 'includes/db.php';
// 验证用户登录
if (!isset($_SESSION['user_id'])) {
die('未授权访问');
}
// 验证并获取POST数据
$order_number = $_POST['order_number'] ?? '';
$customer_id = $_POST['customer_id'] ?? 0;
$order_date = $_POST['order_date'] ?? '';
$currency = $_POST['currency'] ?? 'USD';
$notes = $_POST['notes'] ?? '';
$order_id = $_POST['order_id'] ?? 0;
$product_ids = $_POST['product_id'] ?? [];
$quantities = $_POST['quantity'] ?? [];
// 基本数据验证
if (empty($order_number) || !$customer_id || empty($order_date) || empty($product_ids)) {
die('请填写所有必填项。');
}
try {
$pdo->beginTransaction();
// 1. 计算订单总金额
$grand_total = 0;
$item_details = [];
for ($i = 0; $i < count($product_ids); $i++) {
if (empty($product_ids[$i]) || $quantities[$i] <= 0) continue;
$stmt = $pdo->prepare("SELECT sale_price FROM products WHERE id = ?");
$stmt->execute([$product_ids[$i]]);
$product = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$product) {
throw new Exception("产品ID {$product_ids[$i]} 不存在。");
}
$unit_price = $product['sale_price'];
$total_price = $unit_price * $quantities[$i];
$grand_total += $total_price;
$item_details[] = [
'product_id' => $product_ids[$i],
'quantity' => $quantities[$i],
'unit_price' => $unit_price,
'total_price' => $total_price
];
}
if ($grand_total <= 0) {
throw new Exception('订单总金额必须大于零。');
}
// 2. 更新或插入订单主表
if ($order_id) {
// 编辑模式
$stmt = $pdo->prepare("
UPDATE orders
SET customer_id = ?, order_date = ?, currency = ?, total_amount = ?, notes = ?
WHERE id = ? AND created_by = ?
");
$stmt->execute([$customer_id, $order_date, $currency, $grand_total, $notes, $order_id, $_SESSION['user_id']]);
} else {
// 创建模式
$stmt = $pdo->prepare("
INSERT INTO orders (order_number, customer_id, order_date, currency, total_amount, notes, created_by)
VALUES (?, ?, ?, ?, ?, ?, ?)
");
$stmt->execute([$order_number, $customer_id, $order_date, $currency, $grand_total, $notes, $_SESSION['user_id']]);
$order_id = $pdo->lastInsertId();
}
// 3. 删除旧的订单明细 (如果是编辑模式)
if ($order_id) {
$stmt = $pdo->prepare("DELETE FROM order_items WHERE order_id = ?");
$stmt->execute([$order_id]);
}
// 4. 插入新的订单明细
$stmt = $pdo->prepare("INSERT INTO order_items (order_id, product_id, quantity, unit_price, total_price) VALUES (?, ?, ?, ?, ?)");
foreach ($item_details as $item) {
$stmt->execute([$order_id, $item['product_id'], $item['quantity'], $item['unit_price'], $item['total_price']]);
}
$pdo->commit();
header('Location: order_details.php?id=' . $order_id);
} catch (Exception $e) {
$pdo->rollBack();
die("保存订单时发生错误: " . $e->getMessage());
}
?>
后续开发建议
-
用户认证与授权:
- 实现一个完整的登录/注册系统。
- 使用
$_SESSION来管理用户登录状态。 - 创建一个权限检查函数(如
is_admin(),is_sales()),在每个需要权限的页面顶部调用它。
-
安全加固:
- 密码哈希: 在存储用户密码时,永远不要存明文,使用
password_hash()和password_verify()。 - 防止SQL注入: 代码中已使用 PDO 的预处理语句,这是最好的实践。
- 防止XSS攻击: 在输出用户到HTML页面的数据前,使用
htmlspecialchars()函数进行转义。 - 输入验证: 对所有用户输入(无论是GET还是POST)进行严格的验证和过滤。
- 密码哈希: 在存储用户密码时,永远不要存明文,使用
-
报表功能:
(图片来源网络,侵删)- 使用 PHPExcel 或 PhpSpreadsheet 库来生成 Excel 报表。
- 使用 TCPDF 或 DomPDF 库来生成 PDF 报表。
- 编写 SQL 查询,按时间、客户等维度聚合销售数据。
-
用户体验优化:
- 使用 AJAX 来实现无刷新加载、搜索等功能,提升交互体验。
- 引入 Bootstrap 或 Tailwind CSS 等现代前端框架,让界面更美观、响应式。
- 添加加载动画、操作成功/失败的提示信息。
-
部署与维护:
- 使用 Composer 来管理 PHP 依赖。
- 将配置信息(如数据库凭证)放在单独的
.env文件中,而不是代码里。 - 定期备份数据库。
这份指南为您提供了一个坚实的基础,您可以根据这个框架继续扩展和完善功能,例如添加邮件通知、文件上传(如合同附件)等高级功能。
