文章目录[隐藏]
WordPress文创IP柔性联名产品开发协同插件开发教程
一、插件概述与开发环境搭建
1.1 插件功能简介
本插件旨在为文创IP持有方和产品开发方提供一个高效的协同工作平台,实现IP授权管理、产品设计协作、进度跟踪和版权保护等功能。通过该插件,双方可以实时共享设计稿、管理授权协议、跟踪产品开发进度,并确保IP使用的合规性。
1.2 开发环境准备
在开始开发前,请确保您的环境满足以下要求:
- WordPress 5.0+
- PHP 7.4+
- MySQL 5.6+
- 基本的HTML/CSS/JavaScript知识
- 本地开发环境(如XAMPP、MAMP或Local by Flywheel)
二、插件基础结构创建
2.1 创建插件主文件
首先,在WordPress的wp-content/plugins/目录下创建插件文件夹cultural-ip-collaboration,然后创建主文件cultural-ip-collaboration.php:
<?php
/**
* Plugin Name: 文创IP柔性联名产品开发协同插件
* Plugin URI: https://yourwebsite.com/
* Description: 为文创IP持有方和产品开发方提供协同工作平台
* Version: 1.0.0
* Author: 您的名称
* License: GPL v2 or later
* Text Domain: cultural-ip-collaboration
*/
// 防止直接访问
if (!defined('ABSPATH')) {
exit;
}
// 定义插件常量
define('CIC_VERSION', '1.0.0');
define('CIC_PLUGIN_DIR', plugin_dir_path(__FILE__));
define('CIC_PLUGIN_URL', plugin_dir_url(__FILE__));
// 初始化插件
require_once CIC_PLUGIN_DIR . 'includes/class-initializer.php';
register_activation_hook(__FILE__, array('CIC_Initializer', 'activate'));
register_deactivation_hook(__FILE__, array('CIC_Initializer', 'deactivate'));
// 启动插件
function run_cultural_ip_collaboration() {
$plugin = new CIC_Initializer();
$plugin->run();
}
run_cultural_ip_collaboration();
?>
2.2 创建初始化类
在includes文件夹中创建class-initializer.php:
<?php
/**
* 插件初始化类
* 负责插件的激活、停用和核心功能加载
*/
class CIC_Initializer {
/**
* 激活插件时执行
*/
public static function activate() {
// 创建必要的数据库表
self::create_database_tables();
// 设置默认选项
self::set_default_options();
// 刷新重写规则
flush_rewrite_rules();
}
/**
* 停用插件时执行
*/
public static function deactivate() {
// 清理临时数据
delete_option('cic_flush_rewrite_rules');
// 刷新重写规则
flush_rewrite_rules();
}
/**
* 创建数据库表
*/
private static function create_database_tables() {
global $wpdb;
$charset_collate = $wpdb->get_charset_collate();
// IP项目表
$table_projects = $wpdb->prefix . 'cic_projects';
$sql_projects = "CREATE TABLE IF NOT EXISTS $table_projects (
id INT(11) NOT NULL AUTO_INCREMENT,
project_name VARCHAR(255) NOT NULL,
ip_owner_id INT(11) NOT NULL,
developer_id INT(11) NOT NULL,
status ENUM('pending', 'active', 'completed', 'cancelled') DEFAULT 'pending',
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (id)
) $charset_collate;";
// 设计稿版本表
$table_designs = $wpdb->prefix . 'cic_designs';
$sql_designs = "CREATE TABLE IF NOT EXISTS $table_designs (
id INT(11) NOT NULL AUTO_INCREMENT,
project_id INT(11) NOT NULL,
version VARCHAR(50) NOT NULL,
file_url VARCHAR(500) NOT NULL,
uploaded_by INT(11) NOT NULL,
feedback TEXT,
approval_status ENUM('pending', 'approved', 'rejected') DEFAULT 'pending',
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id),
FOREIGN KEY (project_id) REFERENCES $table_projects(id) ON DELETE CASCADE
) $charset_collate;";
require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
dbDelta($sql_projects);
dbDelta($sql_designs);
}
/**
* 设置默认选项
*/
private static function set_default_options() {
if (!get_option('cic_settings')) {
$default_settings = array(
'max_file_size' => 10, // MB
'allowed_file_types' => array('jpg', 'png', 'pdf', 'psd', 'ai'),
'notification_email' => get_option('admin_email'),
'auto_versioning' => true
);
update_option('cic_settings', $default_settings);
}
}
/**
* 运行插件
*/
public function run() {
// 加载依赖文件
$this->load_dependencies();
// 初始化模块
$this->init_modules();
// 注册短代码
$this->register_shortcodes();
// 注册管理页面
$this->register_admin_pages();
}
/**
* 加载依赖文件
*/
private function load_dependencies() {
// 核心功能类
require_once CIC_PLUGIN_DIR . 'includes/class-project-manager.php';
require_once CIC_PLUGIN_DIR . 'includes/class-design-manager.php';
require_once CIC_PLUGIN_DIR . 'includes/class-ip-license-manager.php';
// 工具类
require_once CIC_PLUGIN_DIR . 'includes/class-utilities.php';
// API类
require_once CIC_PLUGIN_DIR . 'includes/class-api-handler.php';
}
/**
* 初始化模块
*/
private function init_modules() {
$project_manager = new CIC_Project_Manager();
$design_manager = new CIC_Design_Manager();
$license_manager = new CIC_IP_License_Manager();
// 初始化各模块
$project_manager->init();
$design_manager->init();
$license_manager->init();
}
/**
* 注册短代码
*/
private function register_shortcodes() {
add_shortcode('cic_project_dashboard', array($this, 'render_project_dashboard'));
add_shortcode('cic_design_upload', array($this, 'render_design_upload_form'));
}
/**
* 注册管理页面
*/
private function register_admin_pages() {
add_action('admin_menu', array($this, 'add_admin_menu'));
}
/**
* 添加管理菜单
*/
public function add_admin_menu() {
add_menu_page(
'文创IP协同管理',
'IP协同',
'manage_options',
'cic-dashboard',
array($this, 'render_admin_dashboard'),
'dashicons-portfolio',
30
);
add_submenu_page(
'cic-dashboard',
'项目管理',
'项目',
'manage_options',
'cic-projects',
array($this, 'render_projects_page')
);
add_submenu_page(
'cic-dashboard',
'授权管理',
'授权',
'manage_options',
'cic-licenses',
array($this, 'render_licenses_page')
);
}
/**
* 渲染管理仪表板
*/
public function render_admin_dashboard() {
include CIC_PLUGIN_DIR . 'admin/views/dashboard.php';
}
/**
* 渲染项目管理页面
*/
public function render_projects_page() {
include CIC_PLUGIN_DIR . 'admin/views/projects.php';
}
/**
* 渲染授权管理页面
*/
public function render_licenses_page() {
include CIC_PLUGIN_DIR . 'admin/views/licenses.php';
}
/**
* 渲染项目仪表板短代码
*/
public function render_project_dashboard($atts) {
ob_start();
include CIC_PLUGIN_DIR . 'public/views/project-dashboard.php';
return ob_get_clean();
}
/**
* 渲染设计上传表单短代码
*/
public function render_design_upload_form($atts) {
ob_start();
include CIC_PLUGIN_DIR . 'public/views/design-upload.php';
return ob_get_clean();
}
}
?>
三、核心功能模块开发
3.1 项目管理模块
创建includes/class-project-manager.php:
<?php
/**
* 项目管理类
* 处理文创IP项目的创建、更新和查询
*/
class CIC_Project_Manager {
private $db;
private $table_projects;
public function __construct() {
global $wpdb;
$this->db = $wpdb;
$this->table_projects = $wpdb->prefix . 'cic_projects';
}
/**
* 初始化项目管理模块
*/
public function init() {
add_action('wp_ajax_create_project', array($this, 'handle_create_project'));
add_action('wp_ajax_update_project_status', array($this, 'handle_update_project_status'));
}
/**
* 创建新项目
* @param array $project_data 项目数据
* @return int|false 项目ID或false
*/
public function create_project($project_data) {
$default_data = array(
'project_name' => '',
'ip_owner_id' => 0,
'developer_id' => 0,
'description' => '',
'deadline' => null,
'budget' => 0,
'status' => 'pending'
);
$data = wp_parse_args($project_data, $default_data);
// 验证必要字段
if (empty($data['project_name']) || $data['ip_owner_id'] <= 0 || $data['developer_id'] <= 0) {
return false;
}
// 插入项目数据
$result = $this->db->insert(
$this->table_projects,
array(
'project_name' => sanitize_text_field($data['project_name']),
'ip_owner_id' => intval($data['ip_owner_id']),
'developer_id' => intval($data['developer_id']),
'description' => sanitize_textarea_field($data['description']),
'deadline' => $data['deadline'],
'budget' => floatval($data['budget']),
'status' => sanitize_text_field($data['status'])
),
array('%s', '%d', '%d', '%s', '%s', '%f', '%s')
);
if ($result === false) {
return false;
}
$project_id = $this->db->insert_id;
// 发送通知邮件
$this->send_project_creation_notification($project_id, $data);
return $project_id;
}
/**
* 获取用户参与的项目
* @param int $user_id 用户ID
* @param string $role 用户角色 (ip_owner 或 developer)
* @return array 项目列表
*/
public function get_user_projects($user_id, $role = '') {
$where_clause = '';
$params = array($user_id);
if ($role === 'ip_owner') {
$where_clause = 'WHERE ip_owner_id = %d';
} elseif ($role === 'developer') {
$where_clause = 'WHERE developer_id = %d';
} else {
$where_clause = 'WHERE ip_owner_id = %d OR developer_id = %d';
$params[] = $user_id;
}
$query = $this->db->prepare(
"SELECT * FROM {$this->table_projects}
{$where_clause}
ORDER BY created_at DESC",
$params
);
return $this->db->get_results($query, ARRAY_A);
}
/**
* 更新项目状态
* @param int $project_id 项目ID
* @param string $status 新状态
* @return bool 是否成功
*/
public function update_project_status($project_id, $status) {
$allowed_statuses = array('pending', 'active', 'completed', 'cancelled');
if (!in_array($status, $allowed_statuses)) {
return false;
}
$result = $this->db->update(
$this->table_projects,
array('status' => $status),
array('id' => $project_id),
array('%s'),
array('%d')
);
return $result !== false;
}
/**
* 发送项目创建通知
*/
private function send_project_creation_notification($project_id, $project_data) {
$ip_owner = get_userdata($project_data['ip_owner_id']);
$developer = get_userdata($project_data['developer_id']);
if (!$ip_owner || !$developer) {
return;
}
$subject = sprintf('新的文创IP合作项目已创建: %s', $project_data['project_name']);
$message = sprintf(
"您好!nn一个新的文创IP合作项目已经创建。nn项目名称: %snIP持有方: %sn开发方: %sn描述: %snn请登录系统查看详情。nn%s",
$project_data['project_name'],
$ip_owner->display_name,
$developer->display_name,
$project_data['description'],
home_url('/project-dashboard/')
);
// 发送给IP持有方
wp_mail($ip_owner->user_email, $subject, $message);
// 发送给开发方
wp_mail($developer->user_email, $subject, $message);
}
/**
* 处理创建项目的AJAX请求
*/
public function handle_create_project() {
// 验证nonce
if (!wp_verify_nonce($_POST['nonce'], 'create_project_nonce')) {
wp_die('安全验证失败');
}
// 验证用户权限
if (!current_user_can('edit_posts')) {
wp_die('权限不足');
}
$project_data = array(
'project_name' => sanitize_text_field($_POST['project_name']),
'ip_owner_id' => intval($_POST['ip_owner_id']),
'developer_id' => intval($_POST['developer_id']),
'description' => sanitize_textarea_field($_POST['description']),
'deadline' => sanitize_text_field($_POST['deadline']),
'budget' => floatval($_POST['budget'])
);
$project_id = $this->create_project($project_data);
if ($project_id) {
wp_send_json_success(array(
'message' => '项目创建成功',
'project_id' => $project_id
));
} else {
wp_send_json_error('项目创建失败');
}
}
}
?>
3.2 设计稿管理模块
创建includes/class-design-manager.php:
<?php
/**
* 设计稿管理类
* 处理设计稿的上传、版本控制和审批流程
*/
class CIC_Design_Manager {
private $db;
private $table_designs;
private $upload_dir;
public function __construct() {
global $wpdb;
$this->db = $wpdb;
$this->table_designs = $wpdb->prefix . 'cic_designs';
$this->upload_dir = wp_upload_dir();
}
/**
* 初始化设计稿管理模块
*/
public function init() {
add_action('wp_ajax_upload_design', array($this, 'handle_design_upload'));
add_action('wp_ajax_update_design_feedback', array($this, 'handle_update_feedback'));
add_action('wp_enqueue_scripts', array($this, 'enqueue_frontend_scripts'));
}
/**
* 上传设计稿
* @param int $project_id 项目ID
* @param array $file_data 文件数据
* @param int $user_id 上传用户ID
* @return array 上传结果
*/
public function upload_design($project_id, $file_data, $user_id) {
// 验证项目是否存在
$project = $this->get_project($project_id);
if (!$project) {
return array('success' => false, 'message' => '项目不存在');
}
// 验证用户权限
if (!$this->can_upload_to_project($user_id, $project_id)) {
return array('success' => false, 'message' => '没有上传权限');
}
// 验证文件
$validation_result = $this->validate_design_file($file_data);
if (!$validation_result['success']) {
return $validation_result;
}
// 创建上传目录
$upload_path = $this->create_upload_directory($project_id);
// 生成唯一文件名
$file_extension = pathinfo($file_data['name'], PATHINFO_EXTENSION);
$unique_filename = $this->generate_unique_filename($project_id, $file_extension);
unique_filename;
// 移动上传的文件
if (!move_uploaded_file($file_data['tmp_name'], $target_path)) {
return array('success' => false, 'message' => '文件移动失败');
}
// 获取下一个版本号
$next_version = $this->get_next_version_number($project_id);
// 保存到数据库
$result = $this->db->insert(
$this->table_designs,
array(
'project_id' => $project_id,
'version' => $next_version,
'file_url' => $this->get_relative_url($target_path),
'uploaded_by' => $user_id,
'approval_status' => 'pending',
'notes' => sanitize_text_field($file_data['notes'] ?? '')
),
array('%d', '%s', '%s', '%d', '%s', '%s')
);
if ($result === false) {
// 如果数据库保存失败,删除已上传的文件
unlink($target_path);
return array('success' => false, 'message' => '数据库保存失败');
}
$design_id = $this->db->insert_id;
// 发送通知
$this->send_design_upload_notification($design_id, $project_id, $user_id);
return array(
'success' => true,
'message' => '设计稿上传成功',
'design_id' => $design_id,
'version' => $next_version,
'file_url' => $this->get_relative_url($target_path)
);
}
/**
* 获取项目信息
*/
private function get_project($project_id) {
global $wpdb;
$table = $wpdb->prefix . 'cic_projects';
return $wpdb->get_row($wpdb->prepare(
"SELECT * FROM {$table} WHERE id = %d",
$project_id
));
}
/**
* 验证用户上传权限
*/
private function can_upload_to_project($user_id, $project_id) {
global $wpdb;
$table = $wpdb->prefix . 'cic_projects';
$project = $wpdb->get_row($wpdb->prepare(
"SELECT ip_owner_id, developer_id FROM {$table} WHERE id = %d",
$project_id
));
if (!$project) {
return false;
}
// 只有项目相关的IP持有方或开发方可以上传
return $user_id == $project->ip_owner_id || $user_id == $project->developer_id;
}
/**
* 验证设计文件
*/
private function validate_design_file($file_data) {
$settings = get_option('cic_settings', array());
$max_size = ($settings['max_file_size'] ?? 10) * 1024 * 1024; // 转换为字节
$allowed_types = $settings['allowed_file_types'] ?? array('jpg', 'png', 'pdf', 'psd', 'ai');
// 检查文件大小
if ($file_data['size'] > $max_size) {
return array(
'success' => false,
'message' => sprintf('文件大小不能超过%dMB', $settings['max_file_size'] ?? 10)
);
}
// 检查文件类型
$file_extension = strtolower(pathinfo($file_data['name'], PATHINFO_EXTENSION));
if (!in_array($file_extension, $allowed_types)) {
return array(
'success' => false,
'message' => sprintf('不支持的文件类型。允许的类型: %s', implode(', ', $allowed_types))
);
}
// 检查上传错误
if ($file_data['error'] !== UPLOAD_ERR_OK) {
$error_messages = array(
UPLOAD_ERR_INI_SIZE => '文件大小超过服务器限制',
UPLOAD_ERR_FORM_SIZE => '文件大小超过表单限制',
UPLOAD_ERR_PARTIAL => '文件只有部分被上传',
UPLOAD_ERR_NO_FILE => '没有文件被上传',
UPLOAD_ERR_NO_TMP_DIR => '找不到临时文件夹',
UPLOAD_ERR_CANT_WRITE => '文件写入失败',
UPLOAD_ERR_EXTENSION => 'PHP扩展阻止了文件上传'
);
return array(
'success' => false,
'message' => $error_messages[$file_data['error']] ?? '未知上传错误'
);
}
return array('success' => true);
}
/**
* 创建上传目录
*/
private function create_upload_directory($project_id) {
$base_dir = $this->upload_dir['basedir'] . '/cic-designs';
$project_dir = $base_dir . '/project-' . $project_id;
// 创建目录(如果不存在)
if (!file_exists($base_dir)) {
wp_mkdir_p($base_dir);
}
if (!file_exists($project_dir)) {
wp_mkdir_p($project_dir);
}
// 添加安全文件
$this->add_security_files($project_dir);
return $project_dir;
}
/**
* 添加安全文件
*/
private function add_security_files($directory) {
// 添加禁止访问的.htaccess文件(如果使用Apache)
$htaccess_content = "Options -IndexesnDeny from all";
$htaccess_file = $directory . '/.htaccess';
if (!file_exists($htaccess_file)) {
file_put_contents($htaccess_file, $htaccess_content);
}
// 添加空的index.php文件
$index_file = $directory . '/index.php';
if (!file_exists($index_file)) {
file_put_contents($index_file, '<?php // Silence is golden');
}
}
/**
* 生成唯一文件名
*/
private function generate_unique_filename($project_id, $extension) {
$timestamp = current_time('Ymd-His');
$random_string = wp_generate_password(8, false);
return sprintf('project-%d-%s-%s.%s',
$project_id,
$timestamp,
$random_string,
$extension
);
}
/**
* 获取下一个版本号
*/
private function get_next_version_number($project_id) {
$latest_version = $this->db->get_var($this->db->prepare(
"SELECT version FROM {$this->table_designs}
WHERE project_id = %d
ORDER BY created_at DESC LIMIT 1",
$project_id
));
if (!$latest_version) {
return 'v1.0';
}
// 解析版本号,增加小版本号
if (preg_match('/v(d+).(d+)/', $latest_version, $matches)) {
$major = $matches[1];
$minor = $matches[2] + 1;
return sprintf('v%d.%d', $major, $minor);
}
// 如果版本号格式不符合预期,返回默认值
return 'v1.0';
}
/**
* 获取相对URL
*/
private function get_relative_url($absolute_path) {
$upload_dir = wp_upload_dir();
return str_replace($upload_dir['basedir'], '', $absolute_path);
}
/**
* 发送设计稿上传通知
*/
private function send_design_upload_notification($design_id, $project_id, $uploader_id) {
$project = $this->get_project($project_id);
$uploader = get_userdata($uploader_id);
if (!$project || !$uploader) {
return;
}
// 确定接收者(如果是IP持有方上传,则通知开发方,反之亦然)
$recipient_id = ($uploader_id == $project->ip_owner_id)
? $project->developer_id
: $project->ip_owner_id;
$recipient = get_userdata($recipient_id);
if (!$recipient) {
return;
}
$subject = sprintf('新设计稿已上传 - 项目: %s', $project->project_name);
$message = sprintf(
"您好!nn%s 在项目 '%s' 中上传了新的设计稿。nn版本号: %sn上传时间: %snn请登录系统查看并审核。nn%s",
$uploader->display_name,
$project->project_name,
$this->get_design_version($design_id),
current_time('Y-m-d H:i:s'),
home_url('/project/' . $project_id . '/designs/')
);
wp_mail($recipient->user_email, $subject, $message);
}
/**
* 获取设计稿版本
*/
private function get_design_version($design_id) {
return $this->db->get_var($this->db->prepare(
"SELECT version FROM {$this->table_designs} WHERE id = %d",
$design_id
));
}
/**
* 处理设计稿上传的AJAX请求
*/
public function handle_design_upload() {
// 验证nonce
if (!wp_verify_nonce($_POST['nonce'], 'upload_design_nonce')) {
wp_send_json_error('安全验证失败');
}
// 验证用户权限
if (!is_user_logged_in()) {
wp_send_json_error('请先登录');
}
// 验证文件上传
if (!isset($_FILES['design_file']) || $_FILES['design_file']['error'] !== UPLOAD_ERR_OK) {
wp_send_json_error('文件上传失败');
}
$project_id = intval($_POST['project_id']);
$user_id = get_current_user_id();
$result = $this->upload_design($project_id, $_FILES['design_file'], $user_id);
if ($result['success']) {
wp_send_json_success($result);
} else {
wp_send_json_error($result['message']);
}
}
/**
* 加载前端脚本
*/
public function enqueue_frontend_scripts() {
if (is_page('project-dashboard') || has_shortcode(get_post()->post_content, 'cic_design_upload')) {
wp_enqueue_script(
'cic-design-upload',
CIC_PLUGIN_URL . 'public/js/design-upload.js',
array('jquery'),
CIC_VERSION,
true
);
wp_localize_script('cic-design-upload', 'cic_ajax', array(
'ajax_url' => admin_url('admin-ajax.php'),
'nonce' => wp_create_nonce('upload_design_nonce'),
'max_file_size' => get_option('cic_settings')['max_file_size'] ?? 10,
'allowed_types' => get_option('cic_settings')['allowed_file_types'] ?? []
));
wp_enqueue_style(
'cic-design-styles',
CIC_PLUGIN_URL . 'public/css/design-styles.css',
array(),
CIC_VERSION
);
}
}
}
?>
## 四、前端界面开发
### 4.1 设计稿上传界面
创建`public/views/design-upload.php`:
<?php
/**
- 设计稿上传表单
- 供前端用户上传设计稿
*/
if (!defined('ABSPATH')) {
exit;
}
// 检查用户是否登录
if (!is_user_logged_in()) {
echo '<div class="cic-alert cic-alert-warning">请先登录系统</div>';
return;
}
$user_id = get_current_user_id();
$project_id = isset($_GET['project_id']) ? intval($_GET['project_id']) : 0;
// 获取用户参与的项目
global $wpdb;
$table_projects = $wpdb->prefix . 'cic_projects';
$projects = $wpdb->get_results($wpdb->prepare(
"SELECT * FROM {$table_projects}
WHERE (ip_owner_id = %d OR developer_id = %d)
AND status = 'active'
ORDER BY project_name ASC",
$user_id,
$user_id
));
// 如果指定了项目ID,验证用户是否有权限
if ($project_id > 0) {
$has_access = false;
foreach ($projects as $project) {
if ($project->id == $project_id) {
$has_access = true;
break;
}
}
if (!$has_access) {
echo '<div class="cic-alert cic-alert-danger">您没有访问此项目的权限</div>';
$project_id = 0;
}
}
?>
<div class="cic-design-upload-container">
<h2>设计稿上传</h2>
<?php if (empty($projects)): ?>
<div class="cic-alert cic-alert-info">
您当前没有活跃的项目。请先创建或加入一个项目。
</div>
<?php else: ?>
<!-- 项目选择 -->
<div class="cic-form-group">
<label for="cic-project-select">选择项目:</label>
<select id="cic-project-select" class="cic-form-control">
<option value="">请选择项目</option>
<?php foreach ($projects as $project): ?>
<option value="<?php echo esc_attr($project->id); ?>"
<?php selected($project_id, $project->id); ?>>
<?php echo esc_html($project->project_name); ?>
</option>
<?php endforeach; ?>
</select>
</div>
<!-- 上传表单 -->
<div id="cic-upload-form" style="<?php echo $project_id ? '' : 'display: none;'; ?>">
<form id="cic-design-upload-form" enctype="multipart/form-data">
<input type="hidden" name="action" value="upload_design">
<input type="hidden" name="project_id" id="cic-project-id" value="<?php echo esc_attr($project_id); ?>">
<div class="cic-form-group">
<label for="cic-design-file">选择设计文件:</label>
<input type="file" id="cic-design-file" name="design_file"
class="cic-form-control" accept=".jpg,.jpeg,.png,.pdf,.psd,.ai" required>
<small class="cic-form-text">
支持的文件格式:JPG, PNG, PDF, PSD, AI。最大文件大小:<?php
echo esc_html(get_option('cic_settings')['max_file_size'] ?? 10); ?>MB
</small>
</div>
<div class="cic-form-group">
<label for="cic-design-notes">备注说明:</label>
<textarea id="cic-design-notes" name="notes"
class="cic-form-control" rows="3"
placeholder="请简要说明本次上传的设计稿内容或修改点..."></textarea>
</div>
<div class="cic-form-group">
<button type="submit" class="cic-btn cic-btn-primary">
<span class="cic-btn-text">上传设计稿</span>
<span class="cic-spinner" style="display: none;">上传中...</span>
</button>
</div>
</form>
<!-- 上传进度 -->
<div id="cic-upload-progress" style="display: none;">
<div class="cic-progress">
<div class="cic-progress-bar" role="progressbar" style="width: 0%;"></div>
</div>
<div class="cic-progress-text">准备上传...</div>
</div>
<!-- 上传结果 -->
<div id="cic-upload-result"></div>
</div>
<!-- 项目详情 -->
<?php if ($project_id): ?>
<div class="cic-project-info">
<h3>项目信息</h3>
<?php
$project = $wpdb->get_row($wpdb->prepare(
"SELECT p.*,
u1.display_name as ip_owner_name,
u2.display_name as developer_name
FROM {$table_projects} p
LEFT JOIN {$wpdb->users} u1 ON p.ip_owner_id = u1.ID
LEFT JOIN {$wpdb->users} u2 ON p.developer_id = u2.ID
WHERE p.id = %d",
$project_id
));
if ($project):
?>
<table class="cic-info-table">
<tr>
<th>项目名称:</th>
<td><?php echo esc_html($project->project_name); ?></td>
</tr>
<tr>
<th>IP持有方:</th>
<td><?php echo esc_html($project->ip_owner_name); ?></td>
</tr>
<tr>
<th>开发方:</th>
<td><?php echo esc_html($project->developer_name); ?></td>
</tr>
<tr>
<th>项目状态:</th>
<td>
<span class="cic-status-badge cic-status-<?php echo esc_attr($project->status); ?>">
<?php
$status_labels = array(
'pending' => '待开始',
'active' => '进行中',
'completed' => '已完成',
'cancelled' => '已取消'
);
echo esc_html($status_labels[$project->status] ?? $project->status);
?>
</span>
</td>
</tr>
<tr>
<th>创建时间:</th>
<td><?php echo esc_html(date('Y-m-d H:i', strtotime($project->created_at))); ?></td>
</tr>
</table>
<?php endif; ?>
</div>
<?php endif; ?>
<?php endif; ?>
</div>
<script>
jQuery(document).ready(function($) {
// 项目选择变化
$('#cic-project-select').on('change',


