文章目录[隐藏]
WordPress小批量定制插件实现质量追溯的详细教程
概述:为什么需要质量追溯系统?
在当今数字化生产环境中,质量追溯已成为企业确保产品质量、提升客户信任度的关键环节。对于使用WordPress管理业务的中小企业来说,一个轻量级但功能完善的质量追溯系统能够帮助追踪产品从原材料到成品的全过程,快速定位质量问题,并满足行业合规要求。
本教程将指导您开发一个WordPress定制插件,实现小批量生产环境下的质量追溯功能。该系统将记录每个产品的生产批次、检验结果、操作人员等关键信息,并建立完整的产品生命周期档案。
环境准备与插件基础结构
首先,我们需要创建插件的基本结构。在WordPress的wp-content/plugins/目录下创建一个新文件夹quality-traceability-system。
<?php
/**
* Plugin Name: 质量追溯系统
* Plugin URI: https://yourwebsite.com/
* Description: 小批量生产环境下的质量追溯解决方案
* Version: 1.0.0
* Author: 您的名称
* License: GPL v2 or later
* Text Domain: quality-trace
*/
// 防止直接访问
if (!defined('ABSPATH')) {
exit;
}
// 定义插件常量
define('QTS_VERSION', '1.0.0');
define('QTS_PLUGIN_DIR', plugin_dir_path(__FILE__));
define('QTS_PLUGIN_URL', plugin_dir_url(__FILE__));
// 初始化插件
class Quality_Traceability_System {
private static $instance = null;
public static function get_instance() {
if (null === self::$instance) {
self::$instance = new self();
}
return self::$instance;
}
private function __construct() {
$this->init_hooks();
}
private function init_hooks() {
// 激活/停用插件时的操作
register_activation_hook(__FILE__, array($this, 'activate'));
register_deactivation_hook(__FILE__, array($this, 'deactivate'));
// 初始化
add_action('init', array($this, 'init'));
// 管理菜单
add_action('admin_menu', array($this, 'add_admin_menu'));
// 加载文本域
add_action('plugins_loaded', array($this, 'load_textdomain'));
}
public function activate() {
// 创建数据库表
$this->create_database_tables();
// 设置默认选项
update_option('qts_version', QTS_VERSION);
}
public function deactivate() {
// 清理临时数据
// 注意:这里不删除数据表,以便保留追溯记录
}
public function load_textdomain() {
load_plugin_textdomain('quality-trace', false, dirname(plugin_basename(__FILE__)) . '/languages/');
}
public function init() {
// 初始化代码
}
public function add_admin_menu() {
// 添加管理菜单
add_menu_page(
__('质量追溯', 'quality-trace'),
__('质量追溯', 'quality-trace'),
'manage_options',
'quality-trace',
array($this, 'display_main_page'),
'dashicons-clipboard',
30
);
}
public function display_main_page() {
// 主页面显示
echo '<div class="wrap">';
echo '<h1>' . __('质量追溯系统', 'quality-trace') . '</h1>';
echo '<p>' . __('欢迎使用质量追溯系统。请使用左侧菜单管理产品批次和追溯记录。', 'quality-trace') . '</p>';
echo '</div>';
}
private function create_database_tables() {
global $wpdb;
$charset_collate = $wpdb->get_charset_collate();
$table_prefix = $wpdb->prefix . 'qts_';
// 批次表
$batch_table = $table_prefix . 'batches';
$batch_sql = "CREATE TABLE IF NOT EXISTS $batch_table (
id mediumint(9) NOT NULL AUTO_INCREMENT,
batch_number varchar(50) NOT NULL,
product_name varchar(200) NOT NULL,
production_date date NOT NULL,
quantity int NOT NULL,
raw_material_info text,
production_notes text,
status varchar(20) DEFAULT 'in_production',
created_at datetime DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id),
UNIQUE KEY batch_number (batch_number)
) $charset_collate;";
// 检验记录表
$inspection_table = $table_prefix . 'inspections';
$inspection_sql = "CREATE TABLE IF NOT EXISTS $inspection_table (
id mediumint(9) NOT NULL AUTO_INCREMENT,
batch_id mediumint(9) NOT NULL,
inspection_type varchar(100) NOT NULL,
inspector_name varchar(100) NOT NULL,
inspection_date datetime NOT NULL,
parameters_tested text,
results text,
pass_fail enum('pass','fail') NOT NULL,
notes text,
created_at datetime DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id),
FOREIGN KEY (batch_id) REFERENCES $batch_table(id) ON DELETE CASCADE
) $charset_collate;";
// 追溯记录表
$trace_table = $table_prefix . 'traceability';
$trace_sql = "CREATE TABLE IF NOT EXISTS $trace_table (
id mediumint(9) NOT NULL AUTO_INCREMENT,
batch_id mediumint(9) NOT NULL,
event_type varchar(100) NOT NULL,
event_description text NOT NULL,
operator varchar(100),
location varchar(200),
event_date datetime NOT NULL,
metadata text,
created_at datetime DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id),
FOREIGN KEY (batch_id) REFERENCES $batch_table(id) ON DELETE CASCADE
) $charset_collate;";
require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
dbDelta($batch_sql);
dbDelta($inspection_sql);
dbDelta($trace_sql);
}
}
// 启动插件
Quality_Traceability_System::get_instance();
?>
数据库设计与数据模型
我们的追溯系统需要三个核心数据表:
- 批次表:存储产品批次的基本信息
- 检验记录表:存储每个批次的检验结果
- 追溯记录表:存储产品生命周期的所有关键事件
这种设计确保了数据的完整性和关联性,每个检验记录和追溯事件都与特定批次关联,形成完整的追溯链。
批次管理功能实现
接下来,我们添加批次管理功能。在插件类中添加以下方法:
// 在Quality_Traceability_System类中添加以下方法
/**
* 添加批次管理子菜单
*/
public function add_admin_menu() {
add_menu_page(
__('质量追溯', 'quality-trace'),
__('质量追溯', 'quality-trace'),
'manage_options',
'quality-trace',
array($this, 'display_main_page'),
'dashicons-clipboard',
30
);
// 批次管理
add_submenu_page(
'quality-trace',
__('批次管理', 'quality-trace'),
__('批次管理', 'quality-trace'),
'manage_options',
'qts-batches',
array($this, 'display_batches_page')
);
// 添加新批次
add_submenu_page(
'quality-trace',
__('添加批次', 'quality-trace'),
__('添加批次', 'quality-trace'),
'manage_options',
'qts-add-batch',
array($this, 'display_add_batch_page')
);
}
/**
* 显示批次管理页面
*/
public function display_batches_page() {
global $wpdb;
$table_name = $wpdb->prefix . 'qts_batches';
// 处理批量操作
if (isset($_POST['action']) && $_POST['action'] == 'delete' && isset($_POST['batch_ids'])) {
$this->delete_batches($_POST['batch_ids']);
}
// 获取批次数据
$batches = $wpdb->get_results("SELECT * FROM $table_name ORDER BY production_date DESC");
echo '<div class="wrap">';
echo '<h1 class="wp-heading-inline">' . __('批次管理', 'quality-trace') . '</h1>';
echo '<a href="' . admin_url('admin.php?page=qts-add-batch') . '" class="page-title-action">' . __('添加新批次', 'quality-trace') . '</a>';
echo '<hr class="wp-header-end">';
if (empty($batches)) {
echo '<div class="notice notice-info"><p>' . __('暂无批次记录。', 'quality-trace') . '</p></div>';
} else {
echo '<form method="post">';
echo '<input type="hidden" name="action" value="delete">';
echo '<table class="wp-list-table widefat fixed striped">';
echo '<thead><tr>';
echo '<th class="manage-column column-cb check-column"><input type="checkbox" id="cb-select-all"></th>';
echo '<th>' . __('批次号', 'quality-trace') . '</th>';
echo '<th>' . __('产品名称', 'quality-trace') . '</th>';
echo '<th>' . __('生产日期', 'quality-trace') . '</th>';
echo '<th>' . __('数量', 'quality-trace') . '</th>';
echo '<th>' . __('状态', 'quality-trace') . '</th>';
echo '<th>' . __('操作', 'quality-trace') . '</th>';
echo '</tr></thead>';
echo '<tbody>';
foreach ($batches as $batch) {
$status_labels = array(
'in_production' => __('生产中', 'quality-trace'),
'inspecting' => __('检验中', 'quality-trace'),
'completed' => __('完成', 'quality-trace'),
'hold' => __('暂停', 'quality-trace')
);
echo '<tr>';
echo '<th scope="row" class="check-column"><input type="checkbox" name="batch_ids[]" value="' . $batch->id . '"></th>';
echo '<td>' . esc_html($batch->batch_number) . '</td>';
echo '<td>' . esc_html($batch->product_name) . '</td>';
echo '<td>' . esc_html($batch->production_date) . '</td>';
echo '<td>' . esc_html($batch->quantity) . '</td>';
echo '<td>' . esc_html($status_labels[$batch->status] ?? $batch->status) . '</td>';
echo '<td>';
echo '<a href="' . admin_url('admin.php?page=qts-trace&batch_id=' . $batch->id) . '">' . __('追溯', 'quality-trace') . '</a> | ';
echo '<a href="' . admin_url('admin.php?page=qts-inspection&batch_id=' . $batch->id) . '">' . __('检验', 'quality-trace') . '</a>';
echo '</td>';
echo '</tr>';
}
echo '</tbody></table>';
echo '<div class="tablenav bottom">';
echo '<input type="submit" class="button button-primary" value="' . __('删除选中', 'quality-trace') . '" onclick="return confirm('' . __('确定要删除选中的批次吗?', 'quality-trace') . '')">';
echo '</div>';
echo '</form>';
}
echo '</div>';
}
/**
* 显示添加批次页面
*/
public function display_add_batch_page() {
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['add_batch'])) {
$this->save_batch($_POST);
}
echo '<div class="wrap">';
echo '<h1>' . __('添加新批次', 'quality-trace') . '</h1>';
echo '<form method="post">';
wp_nonce_field('qts_add_batch', 'qts_nonce');
echo '<table class="form-table">';
echo '<tr>';
echo '<th scope="row"><label for="batch_number">' . __('批次号 *', 'quality-trace') . '</label></th>';
echo '<td><input type="text" id="batch_number" name="batch_number" class="regular-text" required></td>';
echo '</tr>';
echo '<tr>';
echo '<th scope="row"><label for="product_name">' . __('产品名称 *', 'quality-trace') . '</label></th>';
echo '<td><input type="text" id="product_name" name="product_name" class="regular-text" required></td>';
echo '</tr>';
echo '<tr>';
echo '<th scope="row"><label for="production_date">' . __('生产日期 *', 'quality-trace') . '</label></th>';
echo '<td><input type="date" id="production_date" name="production_date" required></td>';
echo '</tr>';
echo '<tr>';
echo '<th scope="row"><label for="quantity">' . __('数量 *', 'quality-trace') . '</label></th>';
echo '<td><input type="number" id="quantity" name="quantity" min="1" required></td>';
echo '</tr>';
echo '<tr>';
echo '<th scope="row"><label for="raw_material_info">' . __('原材料信息', 'quality-trace') . '</label></th>';
echo '<td><textarea id="raw_material_info" name="raw_material_info" rows="4" class="large-text"></textarea></td>';
echo '</tr>';
echo '<tr>';
echo '<th scope="row"><label for="production_notes">' . __('生产备注', 'quality-trace') . '</label></th>';
echo '<td><textarea id="production_notes" name="production_notes" rows="4" class="large-text"></textarea></td>';
echo '</tr>';
echo '<tr>';
echo '<th scope="row"><label for="status">' . __('状态', 'quality-trace') . '</label></th>';
echo '<td>';
echo '<select id="status" name="status">';
echo '<option value="in_production">' . __('生产中', 'quality-trace') . '</option>';
echo '<option value="inspecting">' . __('检验中', 'quality-trace') . '</option>';
echo '<option value="completed">' . __('完成', 'quality-trace') . '</option>';
echo '<option value="hold">' . __('暂停', 'quality-trace') . '</option>';
echo '</select>';
echo '</td>';
echo '</tr>';
echo '</table>';
echo '<p class="submit">';
echo '<input type="submit" name="add_batch" class="button button-primary" value="' . __('保存批次', 'quality-trace') . '">';
echo '</p>';
echo '</form>';
echo '</div>';
}
/**
* 保存批次信息
*/
private function save_batch($data) {
global $wpdb;
if (!wp_verify_nonce($data['qts_nonce'], 'qts_add_batch')) {
wp_die(__('安全验证失败', 'quality-trace'));
}
$table_name = $wpdb->prefix . 'qts_batches';
$result = $wpdb->insert(
$table_name,
array(
'batch_number' => sanitize_text_field($data['batch_number']),
'product_name' => sanitize_text_field($data['product_name']),
'production_date' => sanitize_text_field($data['production_date']),
'quantity' => intval($data['quantity']),
'raw_material_info' => sanitize_textarea_field($data['raw_material_info']),
'production_notes' => sanitize_textarea_field($data['production_notes']),
'status' => sanitize_text_field($data['status'])
),
array('%s', '%s', '%s', '%d', '%s', '%s', '%s')
);
if ($result) {
echo '<div class="notice notice-success"><p>' . __('批次添加成功!', 'quality-trace') . '</p></div>';
} else {
echo '<div class="notice notice-error"><p>' . __('添加批次时出错:', 'quality-trace') . $wpdb->last_error . '</p></div>';
}
}
/**
* 删除批次
*/
private function delete_batches($batch_ids) {
global $wpdb;
if (!is_array($batch_ids)) {
return;
}
$table_name = $wpdb->prefix . 'qts_batches';
$ids = array_map('intval', $batch_ids);
$ids_string = implode(',', $ids);
$result = $wpdb->query("DELETE FROM $table_name WHERE id IN ($ids_string)");
if ($result) {
echo '<div class="notice notice-success"><p>' . __('选中批次已删除。', 'quality-trace') . '</p></div>';
}
}
质量检验记录功能
质量检验是追溯系统的核心。以下是检验记录功能的实现:
// 在add_admin_menu方法中添加检验管理子菜单
add_submenu_page(
'quality-trace',
__('检验记录', 'quality-trace'),
__('检验记录', 'quality-trace'),
'manage_options',
'qts-inspections',
array($this, 'display_inspections_page')
);
/**
* 显示检验记录页面
*/
public function display_inspections_page() {
global $wpdb;
$batch_id = isset($_GET['batch_id']) ? intval($_GET['batch_id']) : 0;
$inspection_table = $wpdb->prefix . 'qts_inspections';
$batch_table = $wpdb->prefix . 'qts_batches';
// 添加检验记录
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['add_inspection'])) {
$this->save_inspection($_POST, $batch_id);
}
echo '<div class="wrap">';
// 获取批次信息
$batch_info = null;
if ($batch_id > 0) {
$batch_info = $wpdb->get_row($wpdb->prepare(
"SELECT * FROM $batch_table WHERE id = %d", $batch_id
));
}
if ($batch_info) {
echo '<h1>' . sprintf(__('批次 %s 的检验记录', 'quality-trace'), esc_html($batch_info->batch_number)) . '</h1>';
echo '<p><strong>' . __('产品名称', 'quality-trace') . ':</strong> ' . esc_html($batch_info->product_name) . '</p>';
// 显示添加检验表单
echo '<h2>' . __('添加检验记录', 'quality-trace') . '</h2>';
echo '<form method="post" class="qts-form">';
wp_nonce_field('qts_add_inspection', 'qts_inspection_nonce');
echo '<table class="form-table">';
echo '<tr>';
echo '<th scope="row"><label for="inspection_type">' . __('检验类型 *', 'quality-trace') . '</label></th>';
echo '<td>';
echo '<select id="inspection_type" name="inspection_type" required>';
echo '<option value="">' . __('请选择', 'quality-trace') . '</option>';
echo '<option value="incoming">' . __('来料检验', 'quality-trace') . '</option>';
echo '<option value="process">' . __('过程检验', 'quality-trace') . '</option>';
echo '<option value="final">' . __('最终检验', 'quality-trace') . '</option>';
echo '<option value="sampling">' . __('抽样检验', 'quality-trace') . '</option>';
echo '</select>';
echo '</td>';
echo '</tr>';
echo '<tr>';
echo '<th scope="row"><label for="inspector_name">' . __('检验员 *', 'quality-trace') . '</label></th>';
echo '<td><input type="text" id="inspector_name" name="inspector_name" class="regular-text" required></td>';
echo '</tr>';
echo '<tr>';
echo '<th scope="row"><label for="inspection_date">' . __('检验日期 *', 'quality-trace') . '</label></th>';
echo '<td><input type="datetime-local" id="inspection_date" name="inspection_date" required></td>';
echo '</tr>';
echo '<tr>';
echo '<th scope="row"><label for="parameters_tested">' . __('检验参数', 'quality-trace') . '</label></th>';
echo '<td><textarea id="parameters_tested" name="parameters_tested" rows="3" class="large-text" placeholder="' . __('例如:尺寸、外观、性能等', 'quality-trace') . '"></textarea></td>';
echo '</tr>';
echo '<tr>';
echo '<th scope="row"><label for="results">' . __('检验结果 *', 'quality-trace') . '</label></th>';
echo '<td><textarea id="results" name="results" rows="4" class="large-text" required placeholder="' . __('详细记录检验数据和观察结果', 'quality-trace') . '"></textarea></td>';
echo '</tr>';
echo '<tr>';
echo '<th scope="row"><label for="pass_fail">' . __('合格判定 *', 'quality-trace') . '</label></th>';
echo '<td>';
echo '<label><input type="radio" name="pass_fail" value="pass" required> ' . __('合格', 'quality-trace') . '</label> ';
echo '<label><input type="radio" name="pass_fail" value="fail"> ' . __('不合格', 'quality-trace') . '</label>';
echo '</td>';
echo '</tr>';
echo '<tr>';
echo '<th scope="row"><label for="notes">' . __('备注', 'quality-trace') . '</label></th>';
echo '<td><textarea id="notes" name="notes" rows="3" class="large-text"></textarea></td>';
echo '</tr>';
echo '</table>';
echo '<p class="submit">';
echo '<input type="submit" name="add_inspection" class="button button-primary" value="' . __('保存检验记录', 'quality-trace') . '">';
echo '</p>';
echo '</form>';
// 显示历史检验记录
echo '<h2>' . __('历史检验记录', 'quality-trace') . '</h2>';
$inspections = $wpdb->get_results($wpdb->prepare(
"SELECT * FROM $inspection_table WHERE batch_id = %d ORDER BY inspection_date DESC", $batch_id
));
if (empty($inspections)) {
echo '<div class="notice notice-info"><p>' . __('暂无检验记录。', 'quality-trace') . '</p></div>';
} else {
echo '<table class="wp-list-table widefat fixed striped">';
echo '<thead><tr>';
echo '<th>' . __('检验类型', 'quality-trace') . '</th>';
echo '<th>' . __('检验员', 'quality-trace') . '</th>';
echo '<th>' . __('检验日期', 'quality-trace') . '</th>';
echo '<th>' . __('检验参数', 'quality-trace') . '</th>';
echo '<th>' . __('判定结果', 'quality-trace') . '</th>';
echo '<th>' . __('操作', 'quality-trace') . '</th>';
echo '</tr></thead>';
echo '<tbody>';
foreach ($inspections as $inspection) {
$pass_fail_label = $inspection->pass_fail == 'pass' ?
'<span class="dashicons dashicons-yes-alt" style="color:#46b450;"></span> ' . __('合格', 'quality-trace') :
'<span class="dashicons dashicons-dismiss" style="color:#dc3232;"></span> ' . __('不合格', 'quality-trace');
echo '<tr>';
echo '<td>' . esc_html($inspection->inspection_type) . '</td>';
echo '<td>' . esc_html($inspection->inspector_name) . '</td>';
echo '<td>' . esc_html($inspection->inspection_date) . '</td>';
echo '<td>' . esc_html(substr($inspection->parameters_tested, 0, 50)) . '...</td>';
echo '<td>' . $pass_fail_label . '</td>';
echo '<td>';
echo '<a href="#" class="view-inspection-details" data-id="' . $inspection->id . '">' . __('查看详情', 'quality-trace') . '</a>';
echo '</td>';
echo '</tr>';
// 详情行(初始隐藏)
echo '<tr id="inspection-details-' . $inspection->id . '" class="inspection-details-row" style="display:none;">';
echo '<td colspan="6">';
echo '<div class="inspection-details">';
echo '<h4>' . __('检验详情', 'quality-trace') . '</h4>';
echo '<p><strong>' . __('检验结果', 'quality-trace') . ':</strong><br>' . nl2br(esc_html($inspection->results)) . '</p>';
if (!empty($inspection->notes)) {
echo '<p><strong>' . __('备注', 'quality-trace') . ':</strong><br>' . nl2br(esc_html($inspection->notes)) . '</p>';
}
echo '<p><strong>' . __('记录时间', 'quality-trace') . ':</strong> ' . esc_html($inspection->created_at) . '</p>';
echo '</div>';
echo '</td>';
echo '</tr>';
}
echo '</tbody></table>';
// 添加查看详情的JavaScript
echo '<script>
jQuery(document).ready(function($) {
$(".view-inspection-details").click(function(e) {
e.preventDefault();
var inspectionId = $(this).data("id");
$("#inspection-details-" + inspectionId).toggle();
});
});
</script>';
}
} else {
echo '<h1>' . __('检验记录', 'quality-trace') . '</h1>';
echo '<div class="notice notice-warning"><p>' . __('请先选择批次以查看检验记录。', 'quality-trace') . '</p></div>';
// 显示批次列表供选择
$batches = $wpdb->get_results("SELECT id, batch_number, product_name FROM $batch_table ORDER BY production_date DESC LIMIT 20");
if (!empty($batches)) {
echo '<h3>' . __('选择批次', 'quality-trace') . '</h3>';
echo '<ul>';
foreach ($batches as $batch) {
echo '<li><a href="' . admin_url('admin.php?page=qts-inspections&batch_id=' . $batch->id) . '">' .
esc_html($batch->batch_number) . ' - ' . esc_html($batch->product_name) . '</a></li>';
}
echo '</ul>';
}
}
echo '</div>';
}
/**
* 保存检验记录
*/
private function save_inspection($data, $batch_id) {
global $wpdb;
if (!wp_verify_nonce($data['qts_inspection_nonce'], 'qts_add_inspection')) {
wp_die(__('安全验证失败', 'quality-trace'));
}
$table_name = $wpdb->prefix . 'qts_inspections';
$result = $wpdb->insert(
$table_name,
array(
'batch_id' => $batch_id,
'inspection_type' => sanitize_text_field($data['inspection_type']),
'inspector_name' => sanitize_text_field($data['inspector_name']),
'inspection_date' => sanitize_text_field($data['inspection_date']),
'parameters_tested' => sanitize_textarea_field($data['parameters_tested']),
'results' => sanitize_textarea_field($data['results']),
'pass_fail' => sanitize_text_field($data['pass_fail']),
'notes' => sanitize_textarea_field($data['notes'])
),
array('%d', '%s', '%s', '%s', '%s', '%s', '%s', '%s')
);
if ($result) {
echo '<div class="notice notice-success"><p>' . __('检验记录保存成功!', 'quality-trace') . '</p></div>';
// 如果检验不合格,自动更新批次状态为暂停
if ($data['pass_fail'] == 'fail') {
$wpdb->update(
$wpdb->prefix . 'qts_batches',
array('status' => 'hold'),
array('id' => $batch_id),
array('%s'),
array('%d')
);
}
} else {
echo '<div class="notice notice-error"><p>' . __('保存检验记录时出错:', 'quality-trace') . $wpdb->last_error . '</p></div>';
}
}
完整追溯链功能实现
追溯链功能记录产品从生产到交付的全过程事件:
// 在add_admin_menu方法中添加追溯管理子菜单
add_submenu_page(
'quality-trace',
__('追溯记录', 'quality-trace'),
__('追溯记录', 'quality-trace'),
'manage_options',
'qts-trace',
array($this, 'display_trace_page')
);
/**
* 显示追溯记录页面
*/
public function display_trace_page() {
global $wpdb;
$batch_id = isset($_GET['batch_id']) ? intval($_GET['batch_id']) : 0;
$trace_table = $wpdb->prefix . 'qts_traceability';
$batch_table = $wpdb->prefix . 'qts_batches';
$inspection_table = $wpdb->prefix . 'qts_inspections';
// 添加追溯事件
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['add_trace_event'])) {
$this->save_trace_event($_POST, $batch_id);
}
echo '<div class="wrap">';
// 获取批次信息
$batch_info = null;
if ($batch_id > 0) {
$batch_info = $wpdb->get_row($wpdb->prepare(
"SELECT * FROM $batch_table WHERE id = %d", $batch_id
));
}
if ($batch_info) {
echo '<h1>' . sprintf(__('批次 %s 的完整追溯链', 'quality-trace'), esc_html($batch_info->batch_number)) . '</h1>';
// 批次基本信息
echo '<div class="qts-batch-info">';
echo '<h3>' . __('批次基本信息', 'quality-trace') . '</h3>';
echo '<table class="widefat">';
echo '<tr><td width="150"><strong>' . __('批次号', 'quality-trace') . '</strong></td><td>' . esc_html($batch_info->batch_number) . '</td></tr>';
echo '<tr><td><strong>' . __('产品名称', 'quality-trace') . '</strong></td><td>' . esc_html($batch_info->product_name) . '</td></tr>';
echo '<tr><td><strong>' . __('生产日期', 'quality-trace') . '</strong></td><td>' . esc_html($batch_info->production_date) . '</td></tr>';
echo '<tr><td><strong>' . __('生产数量', 'quality-trace') . '</strong></td><td>' . esc_html($batch_info->quantity) . '</td></tr>';
echo '<tr><td><strong>' . __('当前状态', 'quality-trace') . '</strong></td><td>' . esc_html($batch_info->status) . '</td></tr>';
echo '</table>';
echo '</div>';
// 添加追溯事件表单
echo '<div class="qts-add-trace-event">';
echo '<h3>' . __('添加追溯事件', 'quality-trace') . '</h3>';
echo '<form method="post" class="qts-form">';
wp_nonce_field('qts_add_trace_event', 'qts_trace_nonce');
echo '<table class="form-table">';
echo '<tr>';
echo '<th scope="row"><label for="event_type">' . __('事件类型 *', 'quality-trace') . '</label></th>';
echo '<td>';
echo '<select id="event_type" name="event_type" required>';
echo '<option value="">' . __('请选择', 'quality-trace') . '</option>';
echo '<option value="material_receiving">' . __('原材料接收', 'quality-trace') . '</option>';
echo '<option value="production_start">' . __('生产开始', 'quality-trace') . '</option>';
echo '<option value="process_check">' . __('过程检查', 'quality-trace') . '</option>';
echo '<option value="equipment_change">' . __('设备更换', 'quality-trace') . '</option>';
echo '<option value="operator_change">' . __('操作员变更', 'quality-trace') . '</option>';
echo '<option value="warehousing">' . __('入库', 'quality-trace') . '</option>';
echo '<option value="shipping">' . __('发货', 'quality-trace') . '</option>';
echo '<option value="customer_receiving">' . __('客户接收', 'quality-trace') . '</option>';
echo '<option value="other">' . __('其他', 'quality-trace') . '</option>';
echo '</select>';
echo '</td>';
echo '</tr>';
echo '<tr>';
echo '<th scope="row"><label for="event_description">' . __('事件描述 *', 'quality-trace') . '</label></th>';
echo '<td><textarea id="event_description" name="event_description" rows="3" class="large-text" required></textarea></td>';
echo '</tr>';
echo '<tr>';
echo '<th scope="row"><label for="operator">' . __('操作人员', 'quality-trace') . '</label></th>';
echo '<td><input type="text" id="operator" name="operator" class="regular-text"></td>';
echo '</tr>';
echo '<tr>';
echo '<th scope="row"><label for="location">' . __('地点', 'quality-trace') . '</label></th>';
echo '<td><input type="text" id="location" name="location" class="regular-text" placeholder="' . __('例如:生产线A、仓库区等', 'quality-trace') . '"></td>';
echo '</tr>';
echo '<tr>';
echo '<th scope="row"><label for="event_date">' . __('事件时间 *', 'quality-trace') . '</label></th>';
echo '<td><input type="datetime-local" id="event_date" name="event_date" required></td>';
echo '</tr>';
echo '<tr>';
echo '<th scope="row"><label for="metadata">' . __('附加数据', 'quality-trace') . '</label></th>';
echo '<td><textarea id="metadata" name="metadata" rows="3" class="large-text" placeholder="' . __('JSON格式的附加信息', 'quality-trace') . '"></textarea></td>';
echo '</tr>';
echo '</table>';
echo '<p class="submit">';
echo '<input type="submit" name="add_trace_event" class="button button-primary" value="' . __('保存事件', 'quality-trace') . '">';
echo '</p>';
echo '</form>';
echo '</div>';
// 显示完整追溯链
echo '<div class="qts-trace-chain">';
echo '<h3>' . __('完整追溯链', 'quality-trace') . '</h3>';
// 获取所有相关记录
