本文目录导读:

我来为您详细介绍如何编写订单状态更新脚本,包含多种实现方案。
MySQL 存储过程方案
DELIMITER $$
CREATE PROCEDURE update_order_status(
IN p_order_id VARCHAR(50),
IN p_new_status VARCHAR(20),
IN p_user_id VARCHAR(50),
OUT p_result VARCHAR(200)
)
BEGIN
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
ROLLBACK;
SET p_result = '更新失败:数据库异常';
END;
START TRANSACTION;
-- 验证订单是否存在
IF NOT EXISTS (SELECT 1 FROM orders WHERE order_id = p_order_id) THEN
SET p_result = '更新失败:订单不存在';
ROLLBACK;
ELSE
-- 记录状态变更历史
INSERT INTO order_status_history (
order_id,
old_status,
new_status,
operator,
created_at
)
SELECT
p_order_id,
status,
p_new_status,
p_user_id,
NOW()
FROM orders
WHERE order_id = p_order_id;
-- 更新订单状态
UPDATE orders
SET status = p_new_status,
update_time = NOW(),
update_user = p_user_id
WHERE order_id = p_order_id;
-- 特殊状态处理
CASE p_new_status
WHEN 'shipped' THEN
UPDATE orders SET shipping_time = NOW()
WHERE order_id = p_order_id;
WHEN 'completed' THEN
UPDATE orders SET completed_time = NOW()
WHERE order_id = p_order_id;
WHEN 'cancelled' THEN
UPDATE orders SET cancel_time = NOW()
WHERE order_id = p_order_id;
END CASE;
COMMIT;
SET p_result = '更新成功';
END IF;
END$$
DELIMITER ;
Python 脚本方案
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import pymysql
import logging
from datetime import datetime
from typing import Optional
class OrderStatusUpdater:
"""订单状态更新器"""
# 定义状态流转规则
STATUS_FLOW = {
'pending': ['confirmed', 'cancelled'],
'confirmed': ['processing', 'cancelled'],
'processing': ['shipped', 'cancelled'],
'shipped': ['delivered', 'cancelled'],
'delivered': ['completed', 'returning'],
'returning': ['refunded'],
'refunded': [], # 最终状态
'completed': [], # 最终状态
'cancelled': [] # 最终状态
}
def __init__(self, db_config: dict):
self.db_config = db_config
self.setup_logging()
def setup_logging(self):
"""配置日志"""
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
handlers=[
logging.FileHandler('order_update.log'),
logging.StreamHandler()
]
)
self.logger = logging.getLogger(__name__)
def get_db_connection(self):
"""获取数据库连接"""
return pymysql.connect(**self.db_config)
def validate_status_transition(self, old_status: str, new_status: str) -> bool:
"""验证状态流转是否合法"""
if old_status not in self.STATUS_FLOW:
return False
return new_status in self.STATUS_FLOW[old_status]
def update_order_status(
self,
order_id: str,
new_status: str,
operator: str = 'system',
remark: Optional[str] = None
) -> dict:
"""
更新订单状态
Args:
order_id: 订单ID
new_status: 新状态
operator: 操作人
remark: 备注
Returns:
dict: 操作结果
"""
conn = None
try:
conn = self.get_db_connection()
cursor = conn.cursor()
# 查询当前订单信息
cursor.execute(
"SELECT id, status, order_number FROM orders WHERE order_id = %s",
(order_id,)
)
order = cursor.fetchone()
if not order:
return {'success': False, 'message': '订单不存在'}
_, old_status, order_number = order
# 验证状态流转
if not self.validate_status_transition(old_status, new_status):
return {
'success': False,
'message': f'不允许的状态流转: {old_status} -> {new_status}'
}
# 开始事务
conn.begin()
# 更新订单状态
update_time = datetime.now()
cursor.execute(
"""UPDATE orders
SET status = %s,
update_time = %s,
update_user = %s
WHERE order_id = %s""",
(new_status, update_time, operator, order_id)
)
# 记录状态变更历史
cursor.execute(
"""INSERT INTO order_status_history
(order_id, old_status, new_status, operator, remark, created_at)
VALUES (%s, %s, %s, %s, %s, %s)""",
(order_id, old_status, new_status, operator, remark, update_time)
)
# 特殊状态处理
if new_status == 'shipped':
cursor.execute(
"UPDATE orders SET shipping_time = %s WHERE order_id = %s",
(update_time, order_id)
)
elif new_status == 'completed':
cursor.execute(
"UPDATE orders SET completed_time = %s WHERE order_id = %s",
(update_time, order_id)
)
conn.commit()
self.logger.info(
f"订单 {order_number} 状态更新成功: {old_status} -> {new_status}"
)
return {
'success': True,
'message': '更新成功',
'data': {
'order_id': order_id,
'order_number': order_number,
'old_status': old_status,
'new_status': new_status,
'update_time': update_time.isoformat()
}
}
except Exception as e:
if conn:
conn.rollback()
self.logger.error(f"更新订单状态失败: {str(e)}")
return {'success': False, 'message': f'更新失败: {str(e)}'}
finally:
if conn:
conn.close()
def batch_update_status(
self,
order_ids: list,
new_status: str,
operator: str = 'system'
) -> dict:
"""
批量更新订单状态
Args:
order_ids: 订单ID列表
new_status: 新状态
operator: 操作人
Returns:
dict: 批量操作结果
"""
results = {
'success_count': 0,
'fail_count': 0,
'details': []
}
for order_id in order_ids:
result = self.update_order_status(order_id, new_status, operator)
if result['success']:
results['success_count'] += 1
else:
results['fail_count'] += 1
results['details'].append(result)
return results
# 使用示例
if __name__ == '__main__':
# 数据库配置
db_config = {
'host': 'localhost',
'user': 'root',
'password': 'password',
'database': 'order_db',
'charset': 'utf8mb4'
}
# 创建更新器
updater = OrderStatusUpdater(db_config)
# 单个订单更新
result = updater.update_order_status(
order_id='ORD2024001',
new_status='shipped',
operator='admin',
remark='快递已发出'
)
print(result)
# 批量更新
order_ids = ['ORD2024002', 'ORD2024003', 'ORD2024004']
batch_result = updater.batch_update_status(
order_ids=order_ids,
new_status='completed',
operator='system'
)
print(batch_result)
Node.js 脚本方案
// orderStatusUpdater.js
const mysql = require('mysql2/promise');
const { v4: uuidv4 } = require('uuid');
class OrderStatusUpdater {
constructor(dbConfig) {
this.dbConfig = {
host: dbConfig.host || 'localhost',
user: dbConfig.user,
password: dbConfig.password,
database: dbConfig.database,
waitForConnections: true,
connectionLimit: 10,
queueLimit: 0
};
// 状态流转规则
this.statusFlow = {
'pending': ['confirmed', 'cancelled'],
'confirmed': ['processing', 'cancelled'],
'processing': ['shipped', 'cancelled'],
'shipped': ['delivered', 'returning'],
'delivered': ['completed', 'returning'],
'returning': ['refunded'],
'refunded': [],
'completed': [],
'cancelled': []
};
this.pool = mysql.createPool(this.dbConfig);
}
validateStatusTransition(oldStatus, newStatus) {
return this.statusFlow[oldStatus]?.includes(newStatus) || false;
}
async updateOrderStatus(orderId, newStatus, operator = 'system', remark = '') {
const connection = await this.pool.getConnection();
try {
await connection.beginTransaction();
// 查询订单信息
const [orders] = await connection.execute(
'SELECT id, status, order_number FROM orders WHERE order_id = ?',
[orderId]
);
if (orders.length === 0) {
throw new Error('订单不存在');
}
const { status: oldStatus, order_number: orderNumber } = orders[0];
// 验证状态流转
if (!this.validateStatusTransition(oldStatus, newStatus)) {
throw new Error(`不允许的状态流转: ${oldStatus} -> ${newStatus}`);
}
// 更新订单状态
const updateTime = new Date();
await connection.execute(
'UPDATE orders SET status = ?, update_time = ?, update_user = ? WHERE order_id = ?',
[newStatus, updateTime, operator, orderId]
);
// 记录状态变更历史
if (typeof remark !== 'string') {
remark = '';
}
const historyId = uuidv4();
await connection.execute(
'INSERT INTO order_status_history (id, order_id, old_status, new_status, operator, remark, created_at) VALUES (?, ?, ?, ?, ?, ?, ?)',
[historyId, orderId, oldStatus, newStatus, operator, remark, updateTime]
);
// 特殊状态处理
if (newStatus === 'shipped') {
await connection.execute(
'UPDATE orders SET shipping_time = ? WHERE order_id = ?',
[updateTime, orderId]
);
} else if (newStatus === 'completed') {
await connection.execute(
'UPDATE orders SET completed_time = ? WHERE order_id = ?',
[updateTime, orderId]
);
}
await connection.commit();
console.log(`订单 ${orderNumber} 状态更新成功: ${oldStatus} -> ${newStatus}`);
return {
success: true,
message: '更新成功',
data: {
orderId,
orderNumber,
oldStatus,
newStatus,
updateTime: updateTime.toISOString()
}
};
} catch (error) {
await connection.rollback();
console.error('更新订单状态失败:', error.message);
return {
success: false,
message: error.message
};
} finally {
connection.release();
}
}
async batchUpdateStatus(orderIds, newStatus, operator = 'system') {
const results = {
successCount: 0,
failCount: 0,
details: []
};
for (const orderId of orderIds) {
const result = await this.updateOrderStatus(orderId, newStatus, operator);
if (result.success) {
results.successCount++;
} else {
results.failCount++;
}
results.details.push(result);
}
return results;
}
async close() {
await this.pool.end();
}
}
// 使用示例
async function main() {
const updater = new OrderStatusUpdater({
host: 'localhost',
user: 'root',
password: 'password',
database: 'order_db'
});
try {
// 单个订单更新
const result = await updater.updateOrderStatus(
'ORD2024001',
'shipped',
'admin',
'快递已发出'
);
console.log('更新结果:', result);
// 批量更新
const orderIds = ['ORD2024002', 'ORD2024003', 'ORD2024004'];
const batchResult = await updater.batchUpdateStatus(
orderIds,
'completed',
'system'
);
console.log('批量更新结果:', batchResult);
} finally {
await updater.close();
}
}
main().catch(console.error);
监控统计脚本
# order_status_monitor.py
import pymysql
import pandas as pd
from datetime import datetime, timedelta
import matplotlib.pyplot as plt
class OrderStatusMonitor:
"""订单状态监控"""
def __init__(self, db_config):
self.conn = pymysql.connect(**db_config)
def get_status_statistics(self, days=30):
"""获取状态统计数据"""
start_date = datetime.now() - timedelta(days=days)
query = """
SELECT
DATE(created_at) as date,
status,
COUNT(*) as count,
SUM(total_amount) as total_amount
FROM orders
WHERE created_at >= %s
GROUP BY DATE(created_at), status
ORDER BY date, status
"""
df = pd.read_sql(query, self.conn, params=(start_date,))
return df
def get_status_change_analysis(self, days=30):
"""获取状态变更分析"""
start_date = datetime.now() - timedelta(days=days)
query = """
SELECT
osh.old_status,
osh.new_status,
COUNT(*) as count,
AVG(TIMESTAMPDIFF(HOUR, o.created_at, osh.created_at)) as avg_hours
FROM order_status_history osh
JOIN orders o ON osh.order_id = o.order_id
WHERE osh.created_at >= %s
GROUP BY osh.old_status, osh.new_status
ORDER BY count DESC
"""
df = pd.read_sql(query, self.conn, params=(start_date,))
return df
def plot_status_distribution(self, days=30):
"""绘制状态分布图"""
df = self.get_status_statistics(days)
# 透视表
pivot_df = df.pivot_table(
index='date',
columns='status',
values='count',
fill_value=0
)
# 绘图
plt.figure(figsize=(12, 6))
pivot_df.plot(kind='bar', stacked=True)
plt.title(f'订单状态分布(近{days}天)')
plt.xlabel('日期')
plt.ylabel('订单数量')
plt.legend(title='状态')
plt.tight_layout()
plt.savefig('order_status_distribution.png')
plt.close()
def close(self):
self.conn.close()
# 使用示例
if __name__ == '__main__':
db_config = {
'host': 'localhost',
'user': 'root',
'password': 'password',
'database': 'order_db',
'charset': 'utf8mb4'
}
monitor = OrderStatusMonitor(db_config)
# 获取状态统计
stats = monitor.get_status_statistics(30)
print("状态统计:")
print(stats)
# 获取状态变更分析
analysis = monitor.get_status_change_analysis(30)
print("\n状态变更分析:")
print(analysis)
# 生成图表
monitor.plot_status_distribution(30)
monitor.close()
数据库表结构
-- 订单表
CREATE TABLE `orders` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`order_id` varchar(50) NOT NULL COMMENT '订单唯一标识',
`order_number` varchar(50) NOT NULL COMMENT '订单编号',
`user_id` varchar(50) NOT NULL COMMENT '用户ID',
`total_amount` decimal(10,2) NOT NULL DEFAULT '0.00' COMMENT '订单总金额',
`status` varchar(20) NOT NULL DEFAULT 'pending' COMMENT '订单状态',
`shipping_time` datetime DEFAULT NULL COMMENT '发货时间',
`completed_time` datetime DEFAULT NULL COMMENT '完成时间',
`cancel_time` datetime DEFAULT NULL COMMENT '取消时间',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`update_user` varchar(50) DEFAULT NULL COMMENT '更新人',
`created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_order_id` (`order_id`),
UNIQUE KEY `uk_order_number` (`order_number`),
KEY `idx_user_id` (`user_id`),
KEY `idx_status` (`status`),
KEY `idx_created_at` (`created_at`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='订单表';
-- 订单状态变更历史表
CREATE TABLE `order_status_history` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`order_id` varchar(50) NOT NULL COMMENT '订单ID',
`old_status` varchar(20) NOT NULL COMMENT '原状态',
`new_status` varchar(20) NOT NULL COMMENT '新状态',
`operator` varchar(50) NOT NULL COMMENT '操作人',
`remark` varchar(500) DEFAULT NULL COMMENT '备注',
`created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
PRIMARY KEY (`id`),
KEY `idx_order_id` (`order_id`),
KEY `idx_created_at` (`created_at`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='订单状态变更历史表';
使用建议
- 事务处理:务必使用事务,确保数据一致性
- 状态验证:验证状态流转的合法性
- 审计日志:记录每次状态变更的详细信息
- 异常处理:完善错误处理和回滚机制
- 监控告警:设置关键状态的监控和告警
根据实际需求选择合适的方案,建议在生产环境中使用存储过程或Python脚本方案,并配合完善的监控机制。