本文目录导读:

我来给你一个完整的PHP进销存系统实现方案,包含核心功能和代码示例。
数据库设计
-- 商品表
CREATE TABLE products (
id INT PRIMARY KEY AUTO_INCREMENT,
sku VARCHAR(50) UNIQUE NOT NULL,
name VARCHAR(100) NOT NULL,
category_id INT,
unit VARCHAR(20),
purchase_price DECIMAL(10,2),
sale_price DECIMAL(10,2),
stock_quantity INT DEFAULT 0,
min_stock INT DEFAULT 0,
status TINYINT DEFAULT 1,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 供应商表
CREATE TABLE suppliers (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(100) NOT NULL,
contact VARCHAR(50),
phone VARCHAR(20),
email VARCHAR(100),
address VARCHAR(200)
);
-- 采购单表
CREATE TABLE purchase_orders (
id INT PRIMARY KEY AUTO_INCREMENT,
order_no VARCHAR(30) UNIQUE NOT NULL,
supplier_id INT,
user_id INT,
total_amount DECIMAL(10,2),
status TINYINT DEFAULT 1, -- 1:待入库 2:已入库 3:已取消
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (supplier_id) REFERENCES suppliers(id)
);
-- 采购单明细表
CREATE TABLE purchase_order_items (
id INT PRIMARY KEY AUTO_INCREMENT,
order_id INT,
product_id INT,
quantity INT,
price DECIMAL(10,2),
subtotal DECIMAL(10,2),
FOREIGN KEY (order_id) REFERENCES purchase_orders(id),
FOREIGN KEY (product_id) REFERENCES products(id)
);
-- 销售单表
CREATE TABLE sales_orders (
id INT PRIMARY KEY AUTO_INCREMENT,
order_no VARCHAR(30) UNIQUE NOT NULL,
customer_name VARCHAR(50),
user_id INT,
total_amount DECIMAL(10,2),
status TINYINT DEFAULT 1, -- 1:待发货 2:已完成 3:已取消
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 销售单明细表
CREATE TABLE sales_order_items (
id INT PRIMARY KEY AUTO_INCREMENT,
order_id INT,
product_id INT,
quantity INT,
price DECIMAL(10,2),
subtotal DECIMAL(10,2),
FOREIGN KEY (order_id) REFERENCES sales_orders(id),
FOREIGN KEY (product_id) REFERENCES products(id)
);
核心PHP类实现
数据库连接类 (Database.php)
<?php
class Database {
private $host = "localhost";
private $db_name = "inventory_db";
private $username = "root";
private $password = "";
private $conn;
public function getConnection() {
$this->conn = null;
try {
$this->conn = new PDO(
"mysql:host=" . $this->host . ";dbname=" . $this->db_name,
$this->username,
$this->password
);
$this->conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch(PDOException $e) {
echo "连接失败: " . $e->getMessage();
}
return $this->conn;
}
}
?>
商品管理类 (Product.php)
<?php
class Product {
private $conn;
private $table_name = "products";
public function __construct($db) {
$this->conn = $db;
}
// 添加商品
public function create($data) {
$query = "INSERT INTO " . $this->table_name .
" (sku, name, category_id, unit, purchase_price, sale_price, min_stock)
VALUES (:sku, :name, :category_id, :unit, :purchase_price, :sale_price, :min_stock)";
$stmt = $this->conn->prepare($query);
$stmt->bindParam(":sku", $data['sku']);
$stmt->bindParam(":name", $data['name']);
$stmt->bindParam(":category_id", $data['category_id']);
$stmt->bindParam(":unit", $data['unit']);
$stmt->bindParam(":purchase_price", $data['purchase_price']);
$stmt->bindParam(":sale_price", $data['sale_price']);
$stmt->bindParam(":min_stock", $data['min_stock']);
return $stmt->execute();
}
// 获取商品列表
public function getProducts($page = 1, $limit = 10) {
$offset = ($page - 1) * $limit;
$query = "SELECT * FROM " . $this->table_name . "
LIMIT :limit OFFSET :offset";
$stmt = $this->conn->prepare($query);
$stmt->bindParam(":limit", $limit, PDO::PARAM_INT);
$stmt->bindParam(":offset", $offset, PDO::PARAM_INT);
$stmt->execute();
return $stmt->fetchAll(PDO::FETCH_ASSOC);
}
// 更新库存
public function updateStock($id, $quantity, $type = 'increment') {
if($type == 'decrement') {
$quantity = -$quantity;
}
$query = "UPDATE " . $this->table_name .
" SET stock_quantity = stock_quantity + :quantity WHERE id = :id";
$stmt = $this->conn->prepare($query);
$stmt->bindParam(":quantity", $quantity);
$stmt->bindParam(":id", $id);
return $stmt->execute();
}
// 检查库存是否充足
public function checkStock($id, $quantity) {
$query = "SELECT stock_quantity FROM " . $this->table_name .
" WHERE id = :id AND stock_quantity >= :quantity";
$stmt = $this->conn->prepare($query);
$stmt->bindParam(":id", $id);
$stmt->bindParam(":quantity", $quantity);
$stmt->execute();
return $stmt->rowCount() > 0;
}
}
?>
采购管理类 (Purchase.php)
<?php
class Purchase {
private $conn;
private $product;
public function __construct($db) {
$this->conn = $db;
$this->product = new Product($db);
}
// 创建采购单
public function createOrder($supplier_id, $user_id, $items) {
$this->conn->beginTransaction();
try {
// 生成订单号
$order_no = 'PO' . date('YmdHis') . rand(1000, 9999);
$total_amount = 0;
// 计算总金额
foreach($items as $item) {
$total_amount += $item['price'] * $item['quantity'];
}
// 插入采购单
$query = "INSERT INTO purchase_orders
(order_no, supplier_id, user_id, total_amount)
VALUES (:order_no, :supplier_id, :user_id, :total_amount)";
$stmt = $this->conn->prepare($query);
$stmt->bindParam(":order_no", $order_no);
$stmt->bindParam(":supplier_id", $supplier_id);
$stmt->bindParam(":user_id", $user_id);
$stmt->bindParam(":total_amount", $total_amount);
$stmt->execute();
$order_id = $this->conn->lastInsertId();
// 插入采购明细
foreach($items as $item) {
$query = "INSERT INTO purchase_order_items
(order_id, product_id, quantity, price, subtotal)
VALUES (:order_id, :product_id, :quantity, :price, :subtotal)";
$stmt = $this->conn->prepare($query);
$stmt->bindParam(":order_id", $order_id);
$stmt->bindParam(":product_id", $item['product_id']);
$stmt->bindParam(":quantity", $item['quantity']);
$stmt->bindParam(":price", $item['price']);
$subtotal = $item['price'] * $item['quantity'];
$stmt->bindParam(":subtotal", $subtotal);
$stmt->execute();
}
$this->conn->commit();
return ["success" => true, "order_id" => $order_id];
} catch(Exception $e) {
$this->conn->rollBack();
return ["success" => false, "error" => $e->getMessage()];
}
}
// 确认入库
public function confirmWarehouse($order_id) {
$this->conn->beginTransaction();
try {
// 获取采购单明细
$query = "SELECT * FROM purchase_order_items WHERE order_id = :order_id";
$stmt = $this->conn->prepare($query);
$stmt->bindParam(":order_id", $order_id);
$stmt->execute();
$items = $stmt->fetchAll(PDO::FETCH_ASSOC);
// 更新商品库存
foreach($items as $item) {
$this->product->updateStock($item['product_id'], $item['quantity']);
}
// 更新采购单状态为已入库
$query = "UPDATE purchase_orders SET status = 2 WHERE id = :id";
$stmt = $this->conn->prepare($query);
$stmt->bindParam(":id", $order_id);
$stmt->execute();
$this->conn->commit();
return ["success" => true];
} catch(Exception $e) {
$this->conn->rollBack();
return ["success" => false, "error" => $e->getMessage()];
}
}
}
?>
销售管理类 (Sales.php)
<?php
class Sales {
private $conn;
private $product;
public function __construct($db) {
$this->conn = $db;
$this->product = new Product($db);
}
// 创建销售单
public function createOrder($customer_name, $user_id, $items) {
$this->conn->beginTransaction();
try {
// 检查所有商品库存
foreach($items as $item) {
if(!$this->product->checkStock($item['product_id'], $item['quantity'])) {
throw new Exception("商品ID: " . $item['product_id'] . " 库存不足");
}
}
// 生成订单号
$order_no = 'SO' . date('YmdHis') . rand(1000, 9999);
$total_amount = 0;
// 计算总金额
foreach($items as $item) {
$total_amount += $item['price'] * $item['quantity'];
}
// 插入销售单
$query = "INSERT INTO sales_orders
(order_no, customer_name, user_id, total_amount)
VALUES (:order_no, :customer_name, :user_id, :total_amount)";
$stmt = $this->conn->prepare($query);
$stmt->bindParam(":order_no", $order_no);
$stmt->bindParam(":customer_name", $customer_name);
$stmt->bindParam(":user_id", $user_id);
$stmt->bindParam(":total_amount", $total_amount);
$stmt->execute();
$order_id = $this->conn->lastInsertId();
// 插入销售明细并更新库存
foreach($items as $item) {
$query = "INSERT INTO sales_order_items
(order_id, product_id, quantity, price, subtotal)
VALUES (:order_id, :product_id, :quantity, :price, :subtotal)";
$stmt = $this->conn->prepare($query);
$stmt->bindParam(":order_id", $order_id);
$stmt->bindParam(":product_id", $item['product_id']);
$stmt->bindParam(":quantity", $item['quantity']);
$stmt->bindParam(":price", $item['price']);
$subtotal = $item['price'] * $item['quantity'];
$stmt->bindParam(":subtotal", $subtotal);
$stmt->execute();
// 扣减库存
$this->product->updateStock($item['product_id'], $item['quantity'], 'decrement');
}
$this->conn->commit();
return ["success" => true, "order_id" => $order_id];
} catch(Exception $e) {
$this->conn->rollBack();
return ["success" => false, "error" => $e->getMessage()];
}
}
}
?>
前端页面示例 (add_sale.php)
<!DOCTYPE html>
<html>
<head>销售管理</title>
<style>
.container { max-width: 800px; margin: 20px auto; }
.form-group { margin-bottom: 15px; }
.form-group label { display: block; margin-bottom: 5px; }
.form-group input, .form-group select { width: 100%; padding: 8px; }
.btn { padding: 10px 20px; background: #007bff; color: white; border: none; cursor: pointer; }
.btn-danger { background: #dc3545; }
.items-table { width: 100%; border-collapse: collapse; }
.items-table th, .items-table td { padding: 10px; border: 1px solid #ddd; text-align: left; }
</style>
</head>
<body>
<div class="container">
<h2>新建销售单</h2>
<form id="saleForm">
<div class="form-group">
<label>客户名称</label>
<input type="text" name="customer_name" required>
</div>
<div class="form-group">
<label>销售员ID</label>
<input type="number" name="user_id" value="1" required>
</div>
<h3>商品明细</h3>
<table class="items-table">
<thead>
<tr>
<th>商品</th>
<th>数量</th>
<th>单价</th>
<th>操作</th>
</tr>
</thead>
<tbody id="itemsBody">
<tr>
<td>
<select name="items[0][product_id]" required>
<?php
// 这里需要从数据库获取商品列表
// 需要你根据实际情况填充
?>
<option value="1">商品1</option>
<option value="2">商品2</option>
</select>
</td>
<td><input type="number" name="items[0][quantity]" min="1" required></td>
<td><input type="number" name="items[0][price]" step="0.01" required></td>
<td><button type="button" class="btn-danger" onclick="removeRow(this)">删除</button></td>
</tr>
</tbody>
</table>
<br>
<button type="button" onclick="addRow()">添加商品</button>
<br><br>
<button type="submit" class="btn">提交销售单</button>
</form>
</div>
<script>
// 添加商品行
function addRow() {
const tbody = document.getElementById('itemsBody');
const rowCount = tbody.children.length;
const tr = document.createElement('tr');
tr.innerHTML = `
<td>
<select name="items[${rowCount}][product_id]" required>
<option value="1">商品1</option>
<option value="2">商品2</option>
</select>
</td>
<td><input type="number" name="items[${rowCount}][quantity]" min="1" required></td>
<td><input type="number" name="items[${rowCount}][price]" step="0.01" required></td>
<td><button type="button" class="btn-danger" onclick="removeRow(this)">删除</button></td>
`;
tbody.appendChild(tr);
}
// 删除商品行
function removeRow(btn) {
const tbody = document.getElementById('itemsBody');
if(tbody.children.length > 1) {
btn.parentElement.parentElement.remove();
} else {
alert('至少保留一行');
}
}
// 提交表单
document.getElementById('saleForm').addEventListener('submit', function(e) {
e.preventDefault();
const formData = new FormData(this);
const data = Object.fromEntries(formData);
// 格式化items数组
const items = [];
for(let key in data) {
if(key.startsWith('items[')) {
const match = key.match(/items\[(\d+)\]\[(\w+)\]/);
if(match) {
const index = match[1];
const field = match[2];
if(!items[index]) items[index] = {};
items[index][field] = parseFloat(data[key]);
}
}
}
const payload = {
customer_name: data.customer_name,
user_id: data.user_id,
items: items.filter(item => item && Object.keys(item).length === 3)
};
// AJAX请求
fetch('api/create_sale.php', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播