WordPress文创IP柔性周边开发项目管理插件教程
一、项目概述与需求分析
文创IP柔性周边开发是一个复杂的过程,涉及设计、生产、库存、销售等多个环节。在WordPress中实现项目管理功能,可以帮助团队高效协作,跟踪项目进度,管理产品生命周期。
核心需求包括:
- 项目创建与基本信息管理
- 任务分配与进度跟踪
- 设计稿版本管理
- 生产流程监控
- 库存与销售数据关联
二、插件基础结构搭建
首先,我们需要创建插件的基本文件结构:
<?php
/**
* Plugin Name: 文创IP项目管理
* Plugin URI: https://yourwebsite.com/
* Description: 文创IP柔性周边开发项目管理插件
* Version: 1.0.0
* Author: 你的名字
* License: GPL v2 or later
*/
// 防止直接访问
if (!defined('ABSPATH')) {
exit;
}
// 定义插件常量
define('CULTURAL_PROJECT_VERSION', '1.0.0');
define('CULTURAL_PROJECT_PLUGIN_DIR', plugin_dir_path(__FILE__));
define('CULTURAL_PROJECT_PLUGIN_URL', plugin_dir_url(__FILE__));
// 初始化插件
add_action('init', 'cultural_project_init');
function cultural_project_init() {
// 加载文本域
load_plugin_textdomain('cultural-project', false, dirname(plugin_basename(__FILE__)) . '/languages');
// 注册自定义文章类型
register_project_post_type();
// 注册自定义分类法
register_project_taxonomies();
}
// 激活插件时创建数据库表
register_activation_hook(__FILE__, 'cultural_project_activate');
function cultural_project_activate() {
// 创建必要的数据库表
create_project_tables();
// 设置默认选项
update_option('cultural_project_version', CULTURAL_PROJECT_VERSION);
}
?>
三、自定义文章类型与分类法
创建项目管理所需的文章类型和分类系统:
<?php
// 注册项目自定义文章类型
function register_project_post_type() {
$labels = array(
'name' => __('文创项目', 'cultural-project'),
'singular_name' => __('文创项目', 'cultural-project'),
'menu_name' => __('文创项目管理', 'cultural-project'),
'add_new' => __('添加新项目', 'cultural-project'),
'add_new_item' => __('添加新文创项目', 'cultural-project'),
'edit_item' => __('编辑项目', 'cultural-project'),
'new_item' => __('新项目', 'cultural-project'),
'view_item' => __('查看项目', 'cultural-project'),
'search_items' => __('搜索项目', 'cultural-project'),
'not_found' => __('未找到项目', 'cultural-project'),
'not_found_in_trash' => __('回收站中无项目', 'cultural-project')
);
$args = array(
'labels' => $labels,
'public' => true,
'publicly_queryable' => true,
'show_ui' => true,
'show_in_menu' => true,
'query_var' => true,
'rewrite' => array('slug' => 'cultural-project'),
'capability_type' => 'post',
'has_archive' => true,
'hierarchical' => false,
'menu_position' => 25,
'menu_icon' => 'dashicons-portfolio',
'supports' => array('title', 'editor', 'thumbnail', 'custom-fields'),
'show_in_rest' => true // 启用Gutenberg编辑器支持
);
register_post_type('cultural_project', $args);
}
// 注册项目分类法
function register_project_taxonomies() {
// 项目状态分类
$status_labels = array(
'name' => __('项目状态', 'cultural-project'),
'singular_name' => __('项目状态', 'cultural-project'),
'search_items' => __('搜索状态', 'cultural-project'),
'all_items' => __('所有状态', 'cultural-project'),
'edit_item' => __('编辑状态', 'cultural-project'),
'update_item' => __('更新状态', 'cultural-project'),
'add_new_item' => __('添加新状态', 'cultural-project'),
'new_item_name' => __('新状态名称', 'cultural-project'),
'menu_name' => __('项目状态', 'cultural-project')
);
$status_args = array(
'hierarchical' => true,
'labels' => $status_labels,
'show_ui' => true,
'show_admin_column' => true,
'query_var' => true,
'rewrite' => array('slug' => 'project-status'),
'show_in_rest' => true
);
register_taxonomy('project_status', array('cultural_project'), $status_args);
// IP分类
$ip_labels = array(
'name' => __('IP分类', 'cultural-project'),
'singular_name' => __('IP分类', 'cultural-project'),
'search_items' => __('搜索IP', 'cultural-project'),
'all_items' => __('所有IP', 'cultural-project'),
'edit_item' => __('编辑IP', 'cultural-project'),
'update_item' => __('更新IP', 'cultural-project'),
'add_new_item' => __('添加新IP', 'cultural-project'),
'new_item_name' => __('新IP名称', 'cultural-project'),
'menu_name' => __('IP分类', 'cultural-project')
);
$ip_args = array(
'hierarchical' => true,
'labels' => $ip_labels,
'show_ui' => true,
'show_admin_column' => true,
'query_var' => true,
'rewrite' => array('slug' => 'ip-category'),
'show_in_rest' => true
);
register_taxonomy('ip_category', array('cultural_project'), $ip_args);
}
?>
四、项目元数据管理
为项目添加自定义字段,存储项目详细信息:
<?php
// 添加项目元数据框
add_action('add_meta_boxes', 'cultural_project_add_meta_boxes');
function cultural_project_add_meta_boxes() {
add_meta_box(
'cultural_project_details',
__('项目详情', 'cultural-project'),
'cultural_project_details_callback',
'cultural_project',
'normal',
'high'
);
add_meta_box(
'cultural_project_tasks',
__('项目任务', 'cultural-project'),
'cultural_project_tasks_callback',
'cultural_project',
'normal',
'high'
);
}
// 项目详情元数据框回调函数
function cultural_project_details_callback($post) {
// 添加安全验证
wp_nonce_field('cultural_project_save_data', 'cultural_project_meta_nonce');
// 获取现有值
$budget = get_post_meta($post->ID, '_project_budget', true);
$start_date = get_post_meta($post->ID, '_project_start_date', true);
$end_date = get_post_meta($post->ID, '_project_end_date', true);
$product_manager = get_post_meta($post->ID, '_product_manager', true);
$designer = get_post_meta($post->ID, '_designer', true);
// 输出表单字段
?>
<table class="form-table">
<tr>
<th><label for="project_budget"><?php _e('项目预算 (元)', 'cultural-project'); ?></label></th>
<td>
<input type="number" id="project_budget" name="project_budget"
value="<?php echo esc_attr($budget); ?>" class="regular-text" step="0.01" min="0">
</td>
</tr>
<tr>
<th><label for="project_start_date"><?php _e('开始日期', 'cultural-project'); ?></label></th>
<td>
<input type="date" id="project_start_date" name="project_start_date"
value="<?php echo esc_attr($start_date); ?>" class="regular-text">
</td>
</tr>
<tr>
<th><label for="project_end_date"><?php _e('预计完成日期', 'cultural-project'); ?></label></th>
<td>
<input type="date" id="project_end_date" name="project_end_date"
value="<?php echo esc_attr($end_date); ?>" class="regular-text">
</td>
</tr>
<tr>
<th><label for="product_manager"><?php _e('产品经理', 'cultural-project'); ?></label></th>
<td>
<input type="text" id="product_manager" name="product_manager"
value="<?php echo esc_attr($product_manager); ?>" class="regular-text">
</td>
</tr>
<tr>
<th><label for="designer"><?php _e('设计师', 'cultural-project'); ?></label></th>
<td>
<input type="text" id="designer" name="designer"
value="<?php echo esc_attr($designer); ?>" class="regular-text">
</td>
</tr>
</table>
<?php
}
// 保存元数据
add_action('save_post', 'cultural_project_save_meta_data');
function cultural_project_save_meta_data($post_id) {
// 检查非ce
if (!isset($_POST['cultural_project_meta_nonce'])) {
return;
}
// 验证nonce
if (!wp_verify_nonce($_POST['cultural_project_meta_nonce'], 'cultural_project_save_data')) {
return;
}
// 检查自动保存
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
return;
}
// 检查用户权限
if (!current_user_can('edit_post', $post_id)) {
return;
}
// 保存字段数据
$fields = array(
'project_budget',
'project_start_date',
'project_end_date',
'product_manager',
'designer'
);
foreach ($fields as $field) {
if (isset($_POST[$field])) {
update_post_meta($post_id, '_' . $field, sanitize_text_field($_POST[$field]));
}
}
}
?>
五、任务管理系统
实现项目任务管理功能:
<?php
// 任务管理回调函数
function cultural_project_tasks_callback($post) {
// 获取现有任务
$tasks = get_post_meta($post->ID, '_project_tasks', true);
$tasks = $tasks ? json_decode($tasks, true) : array();
?>
<div id="project-tasks-container">
<table class="widefat fixed" id="tasks-table">
<thead>
<tr>
<th width="5%"><?php _e('ID', 'cultural-project'); ?></th>
<th width="30%"><?php _e('任务名称', 'cultural-project'); ?></th>
<th width="15%"><?php _e('负责人', 'cultural-project'); ?></th>
<th width="15%"><?php _e('截止日期', 'cultural-project'); ?></th>
<th width="10%"><?php _e('状态', 'cultural-project'); ?></th>
<th width="10%"><?php _e('优先级', 'cultural-project'); ?></th>
<th width="15%"><?php _e('操作', 'cultural-project'); ?></th>
</tr>
</thead>
<tbody id="tasks-list">
<?php if (!empty($tasks)): ?>
<?php foreach ($tasks as $index => $task): ?>
<tr data-index="<?php echo $index; ?>">
<td><?php echo $index + 1; ?></td>
<td><input type="text" name="tasks[<?php echo $index; ?>][name]"
value="<?php echo esc_attr($task['name']); ?>" class="regular-text"></td>
<td><input type="text" name="tasks[<?php echo $index; ?>][assignee]"
value="<?php echo esc_attr($task['assignee']); ?>" class="regular-text"></td>
<td><input type="date" name="tasks[<?php echo $index; ?>][due_date]"
value="<?php echo esc_attr($task['due_date']); ?>" class="regular-text"></td>
<td>
<select name="tasks[<?php echo $index; ?>][status]" class="regular-text">
<option value="pending" <?php selected($task['status'], 'pending'); ?>><?php _e('待开始', 'cultural-project'); ?></option>
<option value="in_progress" <?php selected($task['status'], 'in_progress'); ?>><?php _e('进行中', 'cultural-project'); ?></option>
<option value="completed" <?php selected($task['status'], 'completed'); ?>><?php _e('已完成', 'cultural-project'); ?></option>
<option value="blocked" <?php selected($task['status'], 'blocked'); ?>><?php _e('受阻', 'cultural-project'); ?></option>
</select>
</td>
<td>
<select name="tasks[<?php echo $index; ?>][priority]" class="regular-text">
<option value="low" <?php selected($task['priority'], 'low'); ?>><?php _e('低', 'cultural-project'); ?></option>
<option value="medium" <?php selected($task['priority'], 'medium'); ?>><?php _e('中', 'cultural-project'); ?></option>
<option value="high" <?php selected($task['priority'], 'high'); ?>><?php _e('高', 'cultural-project'); ?></option>
<option value="urgent" <?php selected($task['priority'], 'urgent'); ?>><?php _e('紧急', 'cultural-project'); ?></option>
</select>
</td>
<td>
<button type="button" class="button remove-task"><?php _e('删除', 'cultural-project'); ?></button>
</td>
</tr>
<?php endforeach; ?>
<?php endif; ?>
</tbody>
</table>
<p>
<button type="button" id="add-task" class="button button-primary">
<?php _e('添加新任务', 'cultural-project'); ?>
</button>
</p>
</div>
<script type="text/javascript">
jQuery(document).ready(function($) {
var taskIndex = <?php echo !empty($tasks) ? count($tasks) : 0; ?>;
// 添加新任务
$('#add-task').click(function() {
var newRow = '<tr data-index="' + taskIndex + '">' +
'<td>' + (taskIndex + 1) + '</td>' +
'<td><input type="text" name="tasks[' + taskIndex + '][name]" class="regular-text"></td>' +
'<td><input type="text" name="tasks[' + taskIndex + '][assignee]" class="regular-text"></td>' +
'<td><input type="date" name="tasks[' + taskIndex + '][due_date]" class="regular-text"></td>' +
'<td>' +
'<select name="tasks[' + taskIndex + '][status]" class="regular-text">' +
'<option value="pending"><?php _e('待开始', 'cultural-project'); ?></option>' +
'<option value="in_progress"><?php _e('进行中', 'cultural-project'); ?></option>' +
'<option value="completed"><?php _e('已完成', 'cultural-project'); ?></option>' +
'<option value="blocked"><?php _e('受阻', 'cultural-project'); ?></option>' +
'</select>' +
'</td>' +
'<td>' +
'<select name="tasks[' + taskIndex + '][priority]" class="regular-text">' +
'<option value="low"><?php _e('低', 'cultural-project'); ?></option>' +
'<option value="medium"><?php _e('中', 'cultural-project'); ?></option>' +
'<option value="high"><?php _e('高', 'cultural-project'); ?></option>' +
'<option value="urgent"><?php _e('紧急', 'cultural-project'); ?></option>' +
'</select>' +
'</td>' +
'<td><button type="button" class="button remove-task"><?php _e('删除', 'cultural-project'); ?></button></td>' +
'</tr>';
$('#tasks-list').append(newRow);
taskIndex++;
});
// 删除任务
$(document).on('click', '.remove-task', function() {
$(this).closest('tr').remove();
// 重新编号
$('#tasks-list tr').each(function(index) {
$(this).find('td:first').text(index + 1);
});
});
});
</script>
<?php
}
// 保存任务数据
add_action('save_post', 'cultural_project_save_tasks');
function cultural_project_save_tasks($post_id) {
if (!isset($_POST['cultural_project_meta_nonce']) ||
!wp_verify_nonce($_POST['cultural_project_meta_nonce'], 'cultural_project_save_data')) {
return;
}
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
return;
}
if (!current_user_can('edit_post', $post_id)) {
return;
}
if (isset($_POST['tasks'])) {
$tasks = array();
foreach ($_POST['tasks'] as $task) {
if (!empty($task['name'])) {
$tasks[] = array(
name' => sanitize_text_field($task['name']),
'assignee' => sanitize_text_field($task['assignee']),
'due_date' => sanitize_text_field($task['due_date']),
'status' => sanitize_text_field($task['status']),
'priority' => sanitize_text_field($task['priority'])
);
}
}
update_post_meta($post_id, '_project_tasks', json_encode($tasks));
} else {
delete_post_meta($post_id, '_project_tasks');
}
}
?>
## 六、设计稿版本管理系统
文创IP开发中设计稿版本管理至关重要,以下是实现代码:
<?php
// 添加设计稿管理元数据框
add_action('add_meta_boxes', 'cultural_project_design_meta_box');
function cultural_project_design_meta_box() {
add_meta_box(
'cultural_project_designs',
__('设计稿管理', 'cultural-project'),
'cultural_project_designs_callback',
'cultural_project',
'side',
'default'
);
}
// 设计稿管理回调函数
function cultural_project_designs_callback($post) {
// 获取现有设计稿
$designs = get_post_meta($post->ID, '_project_designs', true);
$designs = $designs ? json_decode($designs, true) : array();
wp_nonce_field('cultural_project_save_designs', 'cultural_project_design_nonce');
?>
<div id="design-version-manager">
<div id="design-list">
<?php if (!empty($designs)): ?>
<?php foreach ($designs as $index => $design): ?>
<div class="design-item" data-index="<?php echo $index; ?>">
<h4><?php echo esc_html($design['version']); ?> - <?php echo esc_html($design['title']); ?></h4>
<p><strong><?php _e('设计师:', 'cultural-project'); ?></strong> <?php echo esc_html($design['designer']); ?></p>
<p><strong><?php _e('日期:', 'cultural-project'); ?></strong> <?php echo esc_html($design['date']); ?></p>
<?php if (!empty($design['file_url'])): ?>
<p><a href="<?php echo esc_url($design['file_url']); ?>" target="_blank"><?php _e('查看文件', 'cultural-project'); ?></a></p>
<?php endif; ?>
<input type="hidden" name="designs[<?php echo $index; ?>][version]" value="<?php echo esc_attr($design['version']); ?>">
<input type="hidden" name="designs[<?php echo $index; ?>][title]" value="<?php echo esc_attr($design['title']); ?>">
<input type="hidden" name="designs[<?php echo $index; ?>][designer]" value="<?php echo esc_attr($design['designer']); ?>">
<input type="hidden" name="designs[<?php echo $index; ?>][date]" value="<?php echo esc_attr($design['date']); ?>">
<input type="hidden" name="designs[<?php echo $index; ?>][file_url]" value="<?php echo esc_attr($design['file_url']); ?>">
<input type="hidden" name="designs[<?php echo $index; ?>][notes]" value="<?php echo esc_attr($design['notes']); ?>">
</div>
<?php endforeach; ?>
<?php endif; ?>
</div>
<hr>
<h4><?php _e('添加新设计稿版本', 'cultural-project'); ?></h4>
<p>
<label for="design_version"><?php _e('版本号:', 'cultural-project'); ?></label>
<input type="text" id="design_version" name="new_design_version" class="widefat" placeholder="v1.0">
</p>
<p>
<label for="design_title"><?php _e('标题:', 'cultural-project'); ?></label>
<input type="text" id="design_title" name="new_design_title" class="widefat">
</p>
<p>
<label for="design_designer"><?php _e('设计师:', 'cultural-project'); ?></label>
<input type="text" id="design_designer" name="new_design_designer" class="widefat">
</p>
<p>
<label for="design_date"><?php _e('日期:', 'cultural-project'); ?></label>
<input type="date" id="design_date" name="new_design_date" class="widefat">
</p>
<p>
<label for="design_file"><?php _e('设计稿文件:', 'cultural-project'); ?></label>
<input type="text" id="design_file" name="new_design_file" class="widefat design-file-url" readonly>
<button type="button" class="button upload-design-file"><?php _e('上传文件', 'cultural-project'); ?></button>
</p>
<p>
<label for="design_notes"><?php _e('备注:', 'cultural-project'); ?></label>
<textarea id="design_notes" name="new_design_notes" class="widefat" rows="3"></textarea>
</p>
<button type="button" id="add-design-version" class="button button-primary">
<?php _e('添加设计稿版本', 'cultural-project'); ?>
</button>
</div>
<script type="text/javascript">
jQuery(document).ready(function($) {
var designIndex = <?php echo !empty($designs) ? count($designs) : 0; ?>;
// 文件上传
$('.upload-design-file').click(function(e) {
e.preventDefault();
var fileFrame = wp.media({
title: '<?php _e('选择设计稿文件', 'cultural-project'); ?>',
button: {
text: '<?php _e('使用此文件', 'cultural-project'); ?>'
},
multiple: false
});
fileFrame.on('select', function() {
var attachment = fileFrame.state().get('selection').first().toJSON();
$(this).closest('p').find('.design-file-url').val(attachment.url);
}.bind(this));
fileFrame.open();
});
// 添加设计稿版本
$('#add-design-version').click(function() {
var version = $('#design_version').val();
var title = $('#design_title').val();
var designer = $('#design_designer').val();
var date = $('#design_date').val();
var fileUrl = $('#design_file').val();
var notes = $('#design_notes').val();
if (!version || !title) {
alert('<?php _e('请填写版本号和标题', 'cultural-project'); ?>');
return;
}
var newDesign = '<div class="design-item" data-index="' + designIndex + '">' +
'<h4>' + version + ' - ' + title + '</h4>' +
'<p><strong><?php _e('设计师:', 'cultural-project'); ?></strong> ' + designer + '</p>' +
'<p><strong><?php _e('日期:', 'cultural-project'); ?></strong> ' + date + '</p>' +
(fileUrl ? '<p><a href="' + fileUrl + '" target="_blank"><?php _e('查看文件', 'cultural-project'); ?></a></p>' : '') +
'<input type="hidden" name="designs[' + designIndex + '][version]" value="' + version + '">' +
'<input type="hidden" name="designs[' + designIndex + '][title]" value="' + title + '">' +
'<input type="hidden" name="designs[' + designIndex + '][designer]" value="' + designer + '">' +
'<input type="hidden" name="designs[' + designIndex + '][date]" value="' + date + '">' +
'<input type="hidden" name="designs[' + designIndex + '][file_url]" value="' + fileUrl + '">' +
'<input type="hidden" name="designs[' + designIndex + '][notes]" value="' + notes + '">' +
'</div>';
$('#design-list').append(newDesign);
designIndex++;
// 清空表单
$('#design_version, #design_title, #design_designer, #design_date, #design_file, #design_notes').val('');
});
});
</script>
<style>
.design-item {
border: 1px solid #ddd;
padding: 10px;
margin-bottom: 10px;
border-radius: 4px;
background: #f9f9f9;
}
.design-item h4 {
margin-top: 0;
color: #333;
}
</style>
<?php
}
// 保存设计稿数据
add_action('save_post', 'cultural_project_save_designs');
function cultural_project_save_designs($post_id) {
if (!isset($_POST['cultural_project_design_nonce']) ||
!wp_verify_nonce($_POST['cultural_project_design_nonce'], 'cultural_project_save_designs')) {
return;
}
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
return;
}
if (!current_user_can('edit_post', $post_id)) {
return;
}
if (isset($_POST['designs'])) {
$designs = array();
foreach ($_POST['designs'] as $design) {
if (!empty($design['version']) && !empty($design['title'])) {
$designs[] = array(
'version' => sanitize_text_field($design['version']),
'title' => sanitize_text_field($design['title']),
'designer' => sanitize_text_field($design['designer']),
'date' => sanitize_text_field($design['date']),
'file_url' => esc_url_raw($design['file_url']),
'notes' => sanitize_textarea_field($design['notes'])
);
}
}
update_post_meta($post_id, '_project_designs', json_encode($designs));
}
}
?>
## 七、生产流程与库存管理
<?php
// 生产流程管理类
class ProductionManager {
// 初始化生产流程
public static function init() {
add_action('add_meta_boxes', array(__CLASS__, 'add_production_meta_boxes'));
add_action('save_post', array(__CLASS__, 'save_production_data'));
add_action('admin_menu', array(__CLASS__, 'add_inventory_page'));
}
// 添加工序管理元数据框
public static function add_production_meta_boxes() {
add_meta_box(
'cultural_project_production',
__('生产流程管理', 'cultural-project'),
array(__CLASS__, 'production_callback'),
'cultural_project',
'normal',
'high'
);
}
// 生产流程回调函数
public static function production_callback($post) {
$production_steps = get_post_meta($post->ID, '_production_steps', true);
$production_steps = $production_steps ? json_decode($production_steps, true) : self::get_default_steps();
$inventory = get_post_meta($post->ID, '_project_inventory', true);
$inventory = $inventory ? json_decode($inventory, true) : array(
'planned' => 0,
'produced' => 0,
'in_stock' => 0,
'sold' => 0
);
wp_nonce_field('cultural_project_save_production', 'cultural_project_production_nonce');
?>
<h3><?php _e('生产工序', 'cultural-project'); ?></h3>
<table class="widefat fixed" id="production-steps-table">
<thead>
<tr>
<th width="5%"><?php _e('序号', 'cultural-project'); ?></th>
<th width="25%"><?php _e('工序名称', 'cultural-project'); ?></th>
<th width="15%"><?php _e('负责供应商', 'cultural-project'); ?></th>
<th width="15%"><?php _e('计划开始', 'cultural-project'); ?></th>
<th width="15%"><?php _e('计划完成', 'cultural-project'); ?></th>
<th width="15%"><?php _e('实际完成', 'cultural-project'); ?></th>
<th width="10%"><?php _e('状态', 'cultural-project'); ?></th>
</tr>
</thead>
<tbody>
<?php foreach ($production_steps as $index => $step): ?>
<tr>
<td><?php echo $index + 1; ?></td>
<td>
<input type="text" name="production_steps[<?php echo $index; ?>][name]"
value="<?php echo esc_attr($step['name']); ?>" class="regular-text">
</td>
<td>
<input type="text" name="production_steps[<?php echo $index; ?>][supplier]"
value="<?php echo esc_attr($step['supplier']); ?>" class="regular-text">
</td>
<td>
<input type="date" name="production_steps[<?php echo $index; ?>][plan_start]"
value="<?php echo esc_attr($step['plan_start']); ?>" class="regular-text">
</td>
<td>
<input type="date" name="production_steps[<?php echo $index; ?>][plan_end]"
value="<?php echo esc_attr($step['plan_end']); ?>" class="regular-text">
</td>
<td>
<input type="date" name="production_steps[<?php echo $index; ?>][actual_end]"
value="<?php echo esc_attr($step['actual_end']); ?>" class="regular-text">
</td>
<td>
<select name="production_steps[<?php echo $index; ?>][status]" class="regular-text">
<option value="pending" <?php selected($step['status'], 'pending'); ?>><?php _e('未开始', 'cultural-project'); ?></option>
<option value="in_progress" <?php selected($step['status'], 'in_progress'); ?>><?php _e('进行中', 'cultural-project'); ?></option>
<option value="completed" <?php selected($step['status'], 'completed'); ?>><?php _e('已完成', 'cultural-project'); ?></option>
<option value="delayed" <?php selected($step['status'], 'delayed'); ?>><?php _e('延迟', 'cultural-project'); ?></option>
</select>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<h3><?php _e('库存管理', 'cultural-project'); ?></h3>
<table class="form-table">
<tr>
<th><label for="planned_quantity"><?php _e('计划生产数量', 'cultural-project'); ?></label></th>
<td>
<input type="number" id="planned_quantity" name="inventory[planned]"
value="<?php echo esc_attr($inventory['planned']); ?>" min="0" class="small-text">
</td>
</tr>
<tr>
<th><label for="produced_quantity"><?php _e('已生产数量', 'cultural-project'); ?></label></th>
<td>
<input type="number" id="produced_quantity" name="inventory[produced]"
value="<?php echo esc_attr($inventory['produced']); ?>" min="0" class="small-text">
</td>
</tr>
<tr>
<th><label for="in_stock_quantity"><?php _e('当前库存', 'cultural-project'); ?></label></th>
<td>
<input type="number" id="in_stock_quantity" name="inventory[in_stock]"
value="<?php echo esc_attr($inventory['in_stock']); ?>" min="0" class="small-text">
</td>
</tr>
<tr>
<th><label for="sold_quantity"><?php _e('已销售数量', 'cultural-project'); ?></label></th>
<td>
<input type="number" id="sold_quantity" name="inventory[sold]"
value="<?php echo esc_attr($inventory['sold']); ?>" min="0" class="small-text">
</td>
</tr>
</table>
<?php
// 显示库存统计
self::display_inventory_stats($inventory);
}
// 获取默认生产工序
private static function get_default_steps() {
return array(
array(
'name' => '设计确认',
'supplier' => '',
'plan_start' => '',
'plan_end' => '',
'actual_end' => '',
'status' => 'pending'
),
array(
'name' => '材料采购',
'supplier' => '',
'plan_start' => '',
'plan_end' => '',
'actual_end' => '',
'status' => 'pending'
),
array(
'name' => '样品制作',
'supplier' => '',
'plan_start' => '',
'plan_end' => '',
'actual_end' => '',
'status' => 'pending'
),
array(
'name' => '批量生产',
'supplier' => '',
'plan_start' => '',
'plan_end' => '',
'actual_end' => '',
'status' => 'pending'
