本文目录导读:

在 PHP 项目(特别是进销存、ERP、资产盘点等系统)中,标记“账面与实际不符”的数据,核心是将盘点数据与账面数据进行比对,找出差异并设置状态字段。
下面给出一个完整的实现思路和代码示例,包含数据库设计、后端逻辑和前端标记。
数据库表设计(关键字段)
假设有两张核心表:
inventory_book(账面库存/资产表)inventory_check_record(盘点记录表)
-- 账面表(当前系统账面数据) CREATE TABLE `inventory_book` ( `id` int(11) NOT NULL AUTO_INCREMENT, `item_code` varchar(50) NOT NULL COMMENT '物品编码', `quantity` decimal(10,2) NOT NULL DEFAULT 0.00 COMMENT '账面数量', `update_time` datetime DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `uk_item_code` (`item_code`) ); -- 盘点记录表(每次盘点结果) CREATE TABLE `inventory_check_record` ( `id` int(11) NOT NULL AUTO_INCREMENT, `check_batch` varchar(50) NOT NULL COMMENT '盘点批次号', `item_code` varchar(50) NOT NULL COMMENT '物品编码', `book_quantity` decimal(10,2) NOT NULL COMMENT '账面数量(盘点时快照)', `actual_quantity` decimal(10,2) NOT NULL COMMENT '实盘数量', `diff_quantity` decimal(10,2) NOT NULL COMMENT '差异数量 (=actual-book)', `status` tinyint(4) NOT NULL DEFAULT 0 COMMENT '0-未处理 1-已处理 2-待审核 3-差异确认', `is_discrepancy` tinyint(4) NOT NULL DEFAULT 0 COMMENT '0-相符 1-不符', `remark` varchar(255) DEFAULT NULL COMMENT '差异说明', `check_time` datetime DEFAULT NULL, PRIMARY KEY (`id`), KEY `idx_check_batch` (`check_batch`), KEY `idx_status` (`status`), KEY `idx_is_discrepancy` (`is_discrepancy`) );
关键字段说明:
diff_quantity:差异数量(正数=盘盈,负数=盘亏)is_discrepancy:标记是否不符,当actual_quantity != book_quantity时设为 1。status:后续流程状态(可扩展)。
PHP 后端:比对并生成差异标记
<?php
/**
* 执行盘点,比对账面与实际,标记不符数据
* @param string $checkBatch 盘点批次号
* @param array $checkData 从客户端提交的盘点数据 [ ['item_code'=>'A001', 'actual_quantity'=>10], ... ]
* @return array 盘点结果统计
*/
function executeInventoryCheck($checkBatch, $checkData) {
$db = getDBConnection(); // 你的数据库连接
$matchedCount = 0;
$discrepancyCount = 0;
$resultList = [];
// 开始事务
$db->beginTransaction();
try {
foreach ($checkData as $item) {
$itemCode = $item['item_code'];
$actualQty = $item['actual_quantity'];
// 1. 查询账面数量(快照当前账面值)
$bookRow = $db->query("SELECT id, quantity FROM inventory_book WHERE item_code = ?", [$itemCode])->fetch();
if (!$bookRow) {
// 账面无此物品 -> 视为全部盘盈,差异 = actual_quantity
$bookQty = 0;
$diffQty = $actualQty;
$isDiscrepancy = 1;
} else {
$bookQty = $bookRow['quantity'];
$diffQty = $actualQty - $bookQty;
$isDiscrepancy = ($diffQty != 0) ? 1 : 0; // 标记不符
}
// 2. 插入盘点记录
$insertSql = "INSERT INTO inventory_check_record
(check_batch, item_code, book_quantity, actual_quantity, diff_quantity, is_discrepancy, check_time)
VALUES (?, ?, ?, ?, ?, ?, NOW())";
$db->execute($insertSql, [
$checkBatch,
$itemCode,
$bookQty,
$actualQty,
$diffQty,
$isDiscrepancy
]);
// 3. 统计
if ($isDiscrepancy) {
$discrepancyCount++;
} else {
$matchedCount++;
}
$resultList[] = [
'item_code' => $itemCode,
'book_qty' => $bookQty,
'actual_qty' => $actualQty,
'diff' => $diffQty,
'is_discrepancy' => $isDiscrepancy
];
}
$db->commit();
return [
'success' => true,
'total_items' => count($checkData),
'matched' => $matchedCount,
'discrepancy' => $discrepancyCount,
'details' => $resultList
];
} catch (\Exception $e) {
$db->rollback();
return ['success' => false, 'message' => $e->getMessage()];
}
}
// 调用示例
$result = executeInventoryCheck('20250328001', [
['item_code' => 'A001', 'actual_quantity' => 10],
['item_code' => 'A002', 'actual_quantity' => 5],
['item_code' => 'A003', 'actual_quantity' => 12]
]);
前端展示:高亮/标记差异行
前端可以是 HTML + JS,也可以是基于 Vue/React 的界面,关键是通过 is_discrepancy 或 diff != 0 来做样式标记。
示例 HTML + JavaScript (纯展示)
<table id="inventoryTable" border="1">
<thead>
<tr>
<th>物品编码</th>
<th>账面数量</th>
<th>实盘数量</th>
<th>差异</th>
<th>状态</th>
</tr>
</thead>
<tbody id="tableBody">
<!-- 动态填充 -->
</tbody>
</table>
<script>
// 假设从后端API获取数据
const inventoryData = [
{ item_code: 'A001', book_qty: 10, actual_qty: 10, diff: 0, is_discrepancy: 0 },
{ item_code: 'A002', book_qty: 8, actual_qty: 5, diff: -3, is_discrepancy: 1 },
{ item_code: 'A003', book_qty: 12, actual_qty: 15, diff: 3, is_discrepancy: 1 },
{ item_code: 'A004', book_qty: 6, actual_qty: 6, diff: 0, is_discrepancy: 0 }
];
function renderTable(data) {
const tbody = document.getElementById('tableBody');
tbody.innerHTML = '';
data.forEach(item => {
const tr = document.createElement('tr');
// 关键:根据是否相符添加不同CSS类
if (item.is_discrepancy) {
tr.classList.add('discrepancy-row'); // 自定义样式:红色背景或特殊图标
} else {
tr.classList.add('match-row'); // 绿色背景或正常样式
}
tr.innerHTML = `
<td>${item.item_code}</td>
<td>${item.book_qty}</td>
<td>${item.actual_qty}</td>
<td class="diff-${item.diff > 0 ? 'positive' : (item.diff < 0 ? 'negative' : 'zero')}">${item.diff}</td>
<td>${item.is_discrepancy ? '⚠️ 不符' : '✅ 相符'}</td>
`;
// 差异列可再细分颜色:正数(盘盈蓝),负数(盘亏红)
tbody.appendChild(tr);
});
}
renderTable(inventoryData);
</script>
<style>
.discrepancy-row {
background-color: #ffe6e6; /* 浅红色背景 */
font-weight: bold;
}
.match-row {
background-color: #e6ffe6; /* 浅绿色背景 */
}
.diff-positive { color: blue; }
.diff-negative { color: red; }
.diff-zero { color: gray; }
</style>
高级标记策略(可选)
a. 标记“部分不符”或“严重不符”
在数据库加一个字段 discrepancy_level,根据差异绝对值分级:
if ($diffQty == 0) {
$level = 0; // 相符
} elseif (abs($diffQty) <= 5) {
$level = 1; // 轻微不符
} else {
$level = 2; // 严重不符
}
b. 标记“账面存在但未盘点”(遗漏)
如果在盘点提交时没有传入某个账面物品,可以在比对后额外生成一条记录:
// 查询所有账面物品,与提交的盘点物品取差集
$bookItems = $db->query("SELECT item_code, quantity FROM inventory_book")->fetchAll();
$checkedCodes = array_column($checkData, 'item_code');
$missedItems = array_filter($bookItems, function($item) use ($checkedCodes) {
return !in_array($item['item_code'], $checkedCodes);
});
// 对这些未盘点到的物品也标记为不符(实际数量视为0或缺失)
foreach ($missedItems as $missed) {
// 插入盘点记录,actual_quantity = NULL 或 0,diff = -book_quantity
}
c. 利用 is_discrepancy 做后续审核流
- 后端查询时添加过滤:
SELECT * FROM inventory_check_record WHERE is_discrepancy = 1 AND status = 0
- 前端只展示不符数据,方便快速处理。
核心原则
| 步骤 | 关键操作 |
|---|---|
| 比对 | actual_quantity - book_quantity 计算差异 |
| 标记 | 将差异 !=0 的记录 is_discrepancy 设为 1 |
| 存储 | 同时记录账面快照,防止后续修改影响历史 |
| 展示 | 前端根据 is_discrepancy 应用高亮样式 |
| 扩展 | 可增加差异级别、未盘点标记、审核状态 |
这样,从数据库到前端都能清晰、准确地标记出“账面与实际不符”的数据,方便后续盘点差异分析和调账。
版权声明: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直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播