文章目录[隐藏]
WordPress柔性供应商管理模块开发实战教程
一、项目概述与需求分析
在当今电商和内容管理系统中,供应商管理是企业运营的重要环节。WordPress作为全球最流行的内容管理系统,虽然拥有丰富的插件生态,但针对柔性供应商管理的专业解决方案仍然有限。本教程将带领您从零开始开发一个完整的WordPress柔性供应商管理模块。
核心需求分析:
- 供应商信息管理(基础资料、联系方式、资质文件)
- 产品与供应商关联管理
- 供应商绩效评估系统
- 灵活的权限控制机制
- 数据可视化报表
二、环境搭建与基础配置
首先,我们需要创建一个WordPress插件的基本结构:
<?php
/**
* Plugin Name: 柔性供应商管理模块
* Plugin URI: https://yourwebsite.com/
* Description: 强大的WordPress供应商管理系统
* Version: 1.0.0
* Author: 您的名称
* License: GPL v2 or later
*/
// 防止直接访问
if (!defined('ABSPATH')) {
exit;
}
// 定义插件常量
define('VSM_PLUGIN_DIR', plugin_dir_path(__FILE__));
define('VSM_PLUGIN_URL', plugin_dir_url(__FILE__));
define('VSM_VERSION', '1.0.0');
// 初始化插件
function vsm_init() {
// 检查必要依赖
if (!class_exists('WooCommerce') && !class_exists('Easy_Digital_Downloads')) {
add_action('admin_notices', function() {
echo '<div class="notice notice-warning"><p>供应商管理模块建议与WooCommerce或EDD配合使用</p></div>';
});
}
// 加载核心类
require_once VSM_PLUGIN_DIR . 'includes/class-vendor-manager.php';
require_once VSM_PLUGIN_DIR . 'includes/class-vendor-post-type.php';
require_once VSM_PLUGIN_DIR . 'includes/class-vendor-meta-boxes.php';
}
add_action('plugins_loaded', 'vsm_init');
三、供应商自定义文章类型开发
创建供应商专用的自定义文章类型,这是整个模块的基础:
<?php
// 文件路径: includes/class-vendor-post-type.php
class VSM_Vendor_Post_Type {
public function __construct() {
add_action('init', array($this, 'register_vendor_post_type'));
add_action('init', array($this, 'register_vendor_taxonomies'));
}
/**
* 注册供应商自定义文章类型
*/
public function register_vendor_post_type() {
$labels = array(
'name' => '供应商',
'singular_name' => '供应商',
'menu_name' => '供应商管理',
'add_new' => '添加供应商',
'add_new_item' => '添加新供应商',
'edit_item' => '编辑供应商',
'new_item' => '新供应商',
'view_item' => '查看供应商',
'search_items' => '搜索供应商',
'not_found' => '未找到供应商',
'not_found_in_trash' => '回收站中无供应商'
);
$args = array(
'labels' => $labels,
'public' => true,
'publicly_queryable' => true,
'show_ui' => true,
'show_in_menu' => true,
'query_var' => true,
'rewrite' => array('slug' => 'vendor'),
'capability_type' => 'post',
'has_archive' => true,
'hierarchical' => false,
'menu_position' => 30,
'menu_icon' => 'dashicons-businessperson',
'supports' => array('title', 'editor', 'thumbnail', 'excerpt'),
'show_in_rest' => true, // 支持Gutenberg编辑器
);
register_post_type('vsm_vendor', $args);
}
/**
* 注册供应商分类法
*/
public function register_vendor_taxonomies() {
// 供应商分类
register_taxonomy(
'vsm_vendor_category',
'vsm_vendor',
array(
'labels' => array(
'name' => '供应商分类',
'singular_name' => '供应商分类',
),
'hierarchical' => true,
'show_ui' => true,
'show_admin_column' => true,
'query_var' => true,
'rewrite' => array('slug' => 'vendor-category'),
'show_in_rest' => true,
)
);
// 供应商标签
register_taxonomy(
'vsm_vendor_tag',
'vsm_vendor',
array(
'labels' => array(
'name' => '供应商标签',
'singular_name' => '供应商标签',
),
'hierarchical' => false,
'show_ui' => true,
'show_admin_column' => true,
'query_var' => true,
'rewrite' => array('slug' => 'vendor-tag'),
'show_in_rest' => true,
)
);
}
}
// 初始化类
new VSM_Vendor_Post_Type();
四、供应商元数据管理
为供应商添加详细的元数据字段,存储供应商的详细信息:
<?php
// 文件路径: includes/class-vendor-meta-boxes.php
class VSM_Vendor_Meta_Boxes {
public function __construct() {
add_action('add_meta_boxes', array($this, 'add_vendor_meta_boxes'));
add_action('save_post_vsm_vendor', array($this, 'save_vendor_meta_data'));
add_action('admin_enqueue_scripts', array($this, 'enqueue_admin_scripts'));
}
/**
* 添加供应商元数据框
*/
public function add_vendor_meta_boxes() {
add_meta_box(
'vsm_vendor_details',
'供应商详细信息',
array($this, 'render_vendor_details_meta_box'),
'vsm_vendor',
'normal',
'high'
);
add_meta_box(
'vsm_vendor_performance',
'供应商绩效评估',
array($this, 'render_vendor_performance_meta_box'),
'vsm_vendor',
'side',
'default'
);
}
/**
* 渲染供应商详细信息元数据框
*/
public function render_vendor_details_meta_box($post) {
// 添加安全验证
wp_nonce_field('vsm_vendor_meta_box', 'vsm_vendor_meta_box_nonce');
// 获取现有值
$contact_person = get_post_meta($post->ID, '_vsm_contact_person', true);
$email = get_post_meta($post->ID, '_vsm_email', true);
$phone = get_post_meta($post->ID, '_vsm_phone', true);
$address = get_post_meta($post->ID, '_vsm_address', true);
$website = get_post_meta($post->ID, '_vsm_website', true);
$tax_number = get_post_meta($post->ID, '_vsm_tax_number', true);
$contract_date = get_post_meta($post->ID, '_vsm_contract_date', true);
$contract_expiry = get_post_meta($post->ID, '_vsm_contract_expiry', true);
// 输出HTML表单
?>
<div class="vsm-meta-box">
<table class="form-table">
<tr>
<th><label for="vsm_contact_person">联系人</label></th>
<td>
<input type="text" id="vsm_contact_person" name="vsm_contact_person"
value="<?php echo esc_attr($contact_person); ?>" class="regular-text">
</td>
</tr>
<tr>
<th><label for="vsm_email">邮箱地址</label></th>
<td>
<input type="email" id="vsm_email" name="vsm_email"
value="<?php echo esc_attr($email); ?>" class="regular-text">
</td>
</tr>
<tr>
<th><label for="vsm_phone">联系电话</label></th>
<td>
<input type="tel" id="vsm_phone" name="vsm_phone"
value="<?php echo esc_attr($phone); ?>" class="regular-text">
</td>
</tr>
<tr>
<th><label for="vsm_address">地址</label></th>
<td>
<textarea id="vsm_address" name="vsm_address" rows="3"
class="large-text"><?php echo esc_textarea($address); ?></textarea>
</td>
</tr>
<tr>
<th><label for="vsm_contract_date">合同开始日期</label></th>
<td>
<input type="date" id="vsm_contract_date" name="vsm_contract_date"
value="<?php echo esc_attr($contract_date); ?>">
</td>
</tr>
<tr>
<th><label for="vsm_contract_expiry">合同到期日</label></th>
<td>
<input type="date" id="vsm_contract_expiry" name="vsm_contract_expiry"
value="<?php echo esc_attr($contract_expiry); ?>">
<p class="description">到期前30天将发送提醒邮件</p>
</td>
</tr>
</table>
</div>
<?php
}
/**
* 保存供应商元数据
*/
public function save_vendor_meta_data($post_id) {
// 安全检查
if (!isset($_POST['vsm_vendor_meta_box_nonce']) ||
!wp_verify_nonce($_POST['vsm_vendor_meta_box_nonce'], 'vsm_vendor_meta_box')) {
return;
}
// 检查自动保存
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
return;
}
// 检查用户权限
if (!current_user_can('edit_post', $post_id)) {
return;
}
// 保存字段数据
$fields = array(
'vsm_contact_person',
'vsm_email',
'vsm_phone',
'vsm_address',
'vsm_website',
'vsm_tax_number',
'vsm_contract_date',
'vsm_contract_expiry'
);
foreach ($fields as $field) {
if (isset($_POST[$field])) {
$value = sanitize_text_field($_POST[$field]);
update_post_meta($post_id, '_' . $field, $value);
}
}
// 自动计算并保存绩效评分
$this->calculate_vendor_performance($post_id);
}
/**
* 计算供应商绩效评分
*/
private function calculate_vendor_performance($vendor_id) {
// 这里可以添加复杂的绩效计算逻辑
// 示例:基于订单完成率、产品质量、交货时间等计算
$base_score = 80; // 基础分
$adjustments = 0; // 调整分
// 模拟计算逻辑
$on_time_delivery = get_post_meta($vendor_id, '_vsm_on_time_delivery', true);
if ($on_time_delivery > 95) {
$adjustments += 10;
} elseif ($on_time_delivery < 80) {
$adjustments -= 15;
}
$quality_rating = get_post_meta($vendor_id, '_vsm_quality_rating', true);
if ($quality_rating > 4.5) {
$adjustments += 10;
} elseif ($quality_rating < 3.0) {
$adjustments -= 20;
}
$final_score = max(0, min(100, $base_score + $adjustments));
update_post_meta($vendor_id, '_vsm_performance_score', $final_score);
// 根据评分设置供应商状态
$status = '良好';
if ($final_score < 60) {
$status = '需改进';
} elseif ($final_score < 80) {
$status = '一般';
} elseif ($final_score >= 90) {
$status = '优秀';
}
update_post_meta($vendor_id, '_vsm_status', $status);
}
/**
* 加载管理端脚本和样式
*/
public function enqueue_admin_scripts($hook) {
global $post_type;
if (($hook == 'post.php' || $hook == 'post-new.php') && $post_type == 'vsm_vendor') {
wp_enqueue_style('vsm-admin-style', VSM_PLUGIN_URL . 'assets/css/admin.css', array(), VSM_VERSION);
wp_enqueue_script('vsm-admin-script', VSM_PLUGIN_URL . 'assets/js/admin.js', array('jquery', 'jquery-ui-datepicker'), VSM_VERSION, true);
// 本地化脚本
wp_localize_script('vsm-admin-script', 'vsm_admin', array(
'ajax_url' => admin_url('admin-ajax.php'),
'nonce' => wp_create_nonce('vsm_admin_nonce')
));
}
}
}
new VSM_Vendor_Meta_Boxes();
五、供应商与产品关联系统
创建供应商与WooCommerce产品的关联功能:
<?php
// 文件路径: includes/class-vendor-product-relationship.php
class VSM_Vendor_Product_Relationship {
public function __construct() {
// 为产品添加供应商选择框
add_action('woocommerce_product_options_general_product_data', array($this, 'add_vendor_to_product'));
add_action('woocommerce_process_product_meta', array($this, 'save_product_vendor'));
// 在供应商页面显示关联产品
add_action('add_meta_boxes', array($this, 'add_vendor_products_meta_box'));
// 添加供应商筛选到产品列表
add_action('restrict_manage_posts', array($this, 'add_vendor_filter_to_products'));
add_filter('parse_query', array($this, 'filter_products_by_vendor'));
}
/**
* 在产品编辑页面添加供应商选择
*/
public function add_vendor_to_product() {
global $post;
$args = array(
'post_type' => 'vsm_vendor',
'posts_per_page' => -1,
'post_status' => 'publish',
'orderby' => 'title',
'order' => 'ASC'
);
$vendors = get_posts($args);
if (empty($vendors)) {
return;
}
echo '<div class="options_group">';
woocommerce_wp_select(array(
'id' => '_vsm_product_vendor',
'label' => '供应商',
'options' => $this->get_vendors_array($vendors),
'desc_tip' => true,
'description' => '选择该产品的供应商'
));
echo '</div>';
}
/**
* 将供应商转换为选项数组
*/
private function get_vendors_array($vendors) {
$vendors_array = array('' => '选择供应商');
foreach ($vendors as $vendor) {
$vendors_array[$vendor->ID] = $vendor->post_title;
}
return $vendors_array;
}
/**
* 保存产品供应商关联
*/
public function save_product_vendor($product_id) {
if (isset($_POST['_vsm_product_vendor'])) {
$vendor_id = intval($_POST['_vsm_product_vendor']);
update_post_meta($product_id, '_vsm_product_vendor', $vendor_id);
// 同时更新供应商的产品列表
$this->update_vendor_products($vendor_id, $product_id, 'add');
}
}
/**
* 更新供应商的产品列表
*/
private function update_vendor_products($vendor_id, $product_id, $action = 'add') {
$vendor_products = get_post_meta($vendor_id, '_vsm_products', true);
if (!is_array($vendor_products)) {
$vendor_products = array();
}
if ($action === 'add') {
if (!in_array($product_id, $vendor_products)) {
$vendor_products[] = $product_id;
}
} elseif ($action === 'remove') {
$vendor_products = array_diff($vendor_products, array($product_id));
}
update_post_meta($vendor_id, '_vsm_products', $vendor_products);
}
/**
* 在产品列表添加供应商筛选
*/
public function add_vendor_filter_to_products() {
global $post_type;
if ($post_type !== 'product') {
return;
}
$args = array(
'post_type' => 'vsm_vendor',
'posts_per_page' => -1,
'post_status' => 'publish'
);
$vendors = get_posts($args);
if (empty($vendors)) {
return;
}
$current_vendor = isset($_GET['vsm_vendor_filter']) ? $_GET['vsm_vendor_filter'] : '';
echo '<select name="vsm_vendor_filter" id="vsm_vendor_filter">';
echo '<option value="">所有供应商</option>';
foreach ($vendors as $vendor) {
printf(
六、供应商绩效评估与报表系统
<?php
// 文件路径: includes/class-vendor-performance.php
class VSM_Vendor_Performance {
private $metrics_weights = array(
'delivery_time' => 0.3,
'quality' => 0.4,
'communication' => 0.2,
'pricing' => 0.1
);
public function __construct() {
add_action('admin_menu', array($this, 'add_performance_page'));
add_action('wp_ajax_vsm_log_performance', array($this, 'log_performance_ajax'));
add_action('vsm_daily_performance_cron', array($this, 'calculate_daily_performance'));
// 注册定时任务
if (!wp_next_scheduled('vsm_daily_performance_cron')) {
wp_schedule_event(time(), 'daily', 'vsm_daily_performance_cron');
}
}
/**
* 添加绩效管理页面
*/
public function add_performance_page() {
add_submenu_page(
'edit.php?post_type=vsm_vendor',
'供应商绩效报表',
'绩效报表',
'manage_options',
'vsm-performance',
array($this, 'render_performance_page')
);
}
/**
* 渲染绩效报表页面
*/
public function render_performance_page() {
?>
<div class="wrap">
<h1 class="wp-heading-inline">供应商绩效报表</h1>
<hr class="wp-header-end">
<div class="vsm-performance-filters">
<form method="get" action="">
<input type="hidden" name="post_type" value="vsm_vendor">
<input type="hidden" name="page" value="vsm-performance">
<label for="time_range">时间范围:</label>
<select name="time_range" id="time_range">
<option value="7days">最近7天</option>
<option value="30days">最近30天</option>
<option value="90days">最近90天</option>
<option value="custom">自定义</option>
</select>
<div id="custom_date_range" style="display:none; margin-top:10px;">
<label>从:</label>
<input type="date" name="date_from" value="<?php echo date('Y-m-d', strtotime('-30 days')); ?>">
<label>到:</label>
<input type="date" name="date_to" value="<?php echo date('Y-m-d'); ?>">
</div>
<button type="submit" class="button button-primary">筛选</button>
</form>
</div>
<div class="vsm-performance-stats">
<?php $this->display_performance_stats(); ?>
</div>
<div class="vsm-performance-table">
<?php $this->display_performance_table(); ?>
</div>
<div class="vsm-performance-charts">
<?php $this->display_performance_charts(); ?>
</div>
</div>
<script>
jQuery(document).ready(function($) {
$('#time_range').change(function() {
if ($(this).val() === 'custom') {
$('#custom_date_range').show();
} else {
$('#custom_date_range').hide();
}
});
});
</script>
<?php
}
/**
* 显示绩效统计
*/
private function display_performance_stats() {
global $wpdb;
$stats = array(
'total_vendors' => 0,
'avg_score' => 0,
'top_performer' => '',
'needs_improvement' => 0
);
// 获取所有供应商
$vendors = get_posts(array(
'post_type' => 'vsm_vendor',
'posts_per_page' => -1,
'post_status' => 'publish'
));
$stats['total_vendors'] = count($vendors);
if ($stats['total_vendors'] > 0) {
$total_score = 0;
$top_score = 0;
foreach ($vendors as $vendor) {
$score = get_post_meta($vendor->ID, '_vsm_performance_score', true);
$score = $score ? floatval($score) : 0;
$total_score += $score;
if ($score > $top_score) {
$top_score = $score;
$stats['top_performer'] = $vendor->post_title;
}
if ($score < 60) {
$stats['needs_improvement']++;
}
}
$stats['avg_score'] = round($total_score / $stats['total_vendors'], 1);
}
?>
<div class="vsm-stats-grid">
<div class="vsm-stat-card">
<h3>供应商总数</h3>
<div class="vsm-stat-number"><?php echo $stats['total_vendors']; ?></div>
</div>
<div class="vsm-stat-card">
<h3>平均绩效分</h3>
<div class="vsm-stat-number"><?php echo $stats['avg_score']; ?></div>
</div>
<div class="vsm-stat-card">
<h3>最佳供应商</h3>
<div class="vsm-stat-number"><?php echo $stats['top_performer']; ?></div>
</div>
<div class="vsm-stat-card">
<h3>需改进供应商</h3>
<div class="vsm-stat-number"><?php echo $stats['needs_improvement']; ?></div>
</div>
</div>
<?php
}
/**
* 显示绩效表格
*/
private function display_performance_table() {
$vendors = get_posts(array(
'post_type' => 'vsm_vendor',
'posts_per_page' => -1,
'post_status' => 'publish',
'orderby' => 'meta_value_num',
'meta_key' => '_vsm_performance_score',
'order' => 'DESC'
));
?>
<table class="wp-list-table widefat fixed striped">
<thead>
<tr>
<th>供应商名称</th>
<th>绩效评分</th>
<th>状态</th>
<th>准时交货率</th>
<th>质量评分</th>
<th>沟通评分</th>
<th>最后评估时间</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<?php if (empty($vendors)): ?>
<tr>
<td colspan="8" style="text-align:center;">暂无供应商数据</td>
</tr>
<?php else: ?>
<?php foreach ($vendors as $vendor):
$score = get_post_meta($vendor->ID, '_vsm_performance_score', true);
$status = get_post_meta($vendor->ID, '_vsm_status', true);
$delivery_rate = get_post_meta($vendor->ID, '_vsm_on_time_delivery', true);
$quality = get_post_meta($vendor->ID, '_vsm_quality_rating', true);
$communication = get_post_meta($vendor->ID, '_vsm_communication_score', true);
$last_evaluated = get_post_meta($vendor->ID, '_vsm_last_evaluated', true);
// 确定状态颜色
$status_class = '';
if ($score >= 90) $status_class = 'vsm-status-excellent';
elseif ($score >= 80) $status_class = 'vsm-status-good';
elseif ($score >= 60) $status_class = 'vsm-status-fair';
else $status_class = 'vsm-status-poor';
?>
<tr>
<td>
<strong>
<a href="<?php echo get_edit_post_link($vendor->ID); ?>">
<?php echo esc_html($vendor->post_title); ?>
</a>
</strong>
</td>
<td>
<div class="vsm-score-bar">
<div class="vsm-score-fill" style="width: <?php echo esc_attr($score); ?>%;"></div>
<span class="vsm-score-text"><?php echo esc_html($score); ?></span>
</div>
</td>
<td>
<span class="vsm-status-badge <?php echo $status_class; ?>">
<?php echo esc_html($status); ?>
</span>
</td>
<td><?php echo $delivery_rate ? esc_html($delivery_rate) . '%' : 'N/A'; ?></td>
<td><?php echo $quality ? esc_html($quality) . '/5' : 'N/A'; ?></td>
<td><?php echo $communication ? esc_html($communication) . '/10' : 'N/A'; ?></td>
<td><?php echo $last_evaluated ? date('Y-m-d', strtotime($last_evaluated)) : 'N/A'; ?></td>
<td>
<button class="button button-small vsm-evaluate-btn"
data-vendor-id="<?php echo $vendor->ID; ?>">
重新评估
</button>
</td>
</tr>
<?php endforeach; ?>
<?php endif; ?>
</tbody>
</table>
<?php
}
/**
* 记录绩效数据(AJAX接口)
*/
public function log_performance_ajax() {
// 验证nonce
if (!check_ajax_referer('vsm_admin_nonce', 'nonce', false)) {
wp_die('安全验证失败');
}
$vendor_id = intval($_POST['vendor_id']);
$metric = sanitize_text_field($_POST['metric']);
$value = floatval($_POST['value']);
$notes = sanitize_textarea_field($_POST['notes']);
if (!$vendor_id || !$metric) {
wp_send_json_error('参数错误');
}
// 记录绩效数据
$performance_log = get_post_meta($vendor_id, '_vsm_performance_log', true);
if (!is_array($performance_log)) {
$performance_log = array();
}
$log_entry = array(
'timestamp' => current_time('mysql'),
'metric' => $metric,
'value' => $value,
'notes' => $notes,
'recorded_by' => get_current_user_id()
);
$performance_log[] = $log_entry;
update_post_meta($vendor_id, '_vsm_performance_log', $performance_log);
// 更新特定指标
update_post_meta($vendor_id, '_vsm_' . $metric, $value);
// 重新计算总分
$this->calculate_vendor_score($vendor_id);
wp_send_json_success('绩效数据已记录');
}
/**
* 计算供应商总分
*/
private function calculate_vendor_score($vendor_id) {
$total_score = 0;
$total_weight = 0;
foreach ($this->metrics_weights as $metric => $weight) {
$value = get_post_meta($vendor_id, '_vsm_' . $metric, true);
if ($value !== '') {
// 标准化分数(假设各指标满分100)
$normalized_score = min(100, max(0, floatval($value)));
$total_score += $normalized_score * $weight;
$total_weight += $weight;
}
}
if ($total_weight > 0) {
$final_score = round($total_score / $total_weight, 1);
update_post_meta($vendor_id, '_vsm_performance_score', $final_score);
update_post_meta($vendor_id, '_vsm_last_evaluated', current_time('mysql'));
}
return $final_score;
}
/**
* 每日绩效计算任务
*/
public function calculate_daily_performance() {
$vendors = get_posts(array(
'post_type' => 'vsm_vendor',
'posts_per_page' => -1,
'post_status' => 'publish'
));
foreach ($vendors as $vendor) {
$this->calculate_vendor_score($vendor->ID);
}
}
}
七、供应商前端展示与短代码
<?php
// 文件路径: includes/class-vendor-frontend.php
class VSM_Vendor_Frontend {
public function __construct() {
// 注册短代码
add_shortcode('vsm_vendor_list', array($this, 'vendor_list_shortcode'));
add_shortcode('vsm_vendor_detail', array($this, 'vendor_detail_shortcode'));
// 添加供应商模板
add_filter('template_include', array($this, 'vendor_template'));
// 注册前端样式和脚本
add_action('wp_enqueue_scripts', array($this, 'enqueue_frontend_assets'));
}
/**
* 供应商列表短代码
*/
public function vendor_list_shortcode($atts) {
$atts = shortcode_atts(array(
'category' => '',
'limit' => 12,
'columns' => 3,
'show_rating' => 'yes'
), $atts, 'vsm_vendor_list');
$args = array(
'post_type' => 'vsm_vendor',
'posts_per_page' => intval($atts['limit']),
'post_status' => 'publish'
);
if (!empty($atts['category'])) {
$args['tax_query'] = array(
array(
'taxonomy' => 'vsm_vendor_category',
'field' => 'slug',
'terms' => $atts['category']
)
);
}
$vendors = new WP_Query($args);
if (!$vendors->have_posts()) {
return '<p>暂无供应商信息</p>';
}
ob_start();
?>
<div class="vsm-vendor-grid vsm-columns-<?php echo esc_attr($atts['columns']); ?>">
<?php while ($vendors->have_posts()): $vendors->the_post();
$vendor_id = get_the_ID();
$score = get_post_meta($vendor_id, '_vsm_performance_score', true);
$contact_person = get_post_meta($vendor_id, '_vsm_contact_person', true);
$phone = get_post_meta($vendor_id, '_vsm_phone', true);
?>
<div class="vsm-vendor-card">
<div class="vsm-vendor-thumbnail">
<?php if (has_post_thumbnail()): ?>
<a href="<?php the_permalink(); ?>">
<?php the_post_thumbnail('medium'); ?>
</a>
<?php endif; ?>
</div>
<div class="vsm-vendor-content">
<h3 class="vsm-vendor-title">
<a href="<?php the_permalink(); ?>"><?php the_title(); ?></a>
</h3>
<?php if ($atts['show_rating'] === 'yes' && $score): ?>
<div class="vsm-vendor-rating">
<div class="vsm-rating-stars" data-score="<?php echo esc_attr($score); ?>"></div>
<span class="vsm-rating-score"><?php echo esc_html($score); ?>分</span>
</div>
<?php endif; ?>
<div class="vsm-vendor-excerpt">
<?php the_excerpt(); ?>
</div>
<div class="vsm-vendor-meta">
<?php if ($contact_person): ?>
<div class="vsm-meta-item">
<span class="dashicons dashicons-businessperson"></span>
<?php echo esc_html($contact_person); ?>
</div>
<?php endif; ?>
<?php if ($phone): ?>
<div class="vsm-meta-item">
<span class="dashicons dashicons-phone"></span>
<?php echo esc_html($phone); ?>
</div>
<?php endif; ?>
</div>
<a href="<?php the_permalink(); ?>" class="vsm-view-details">
查看详情
</a>
</div>
</div>
<?php endwhile; wp_reset_postdata(); ?>
</div>
<?php if ($vendors->max_num_pages > 1): ?>
<div class="vsm-pagination">
<?php
echo paginate_links(array(
'total' => $vendors->max_num_pages,
'current' => max(1, get_query_var('paged')),
'prev_text' => '«',
'next_text' => '»'
));
?>
</div>
<?php endif;
return ob_get_clean();
}
/**
* 供应商详情短代码
*/
public function vendor_detail_shortcode($atts) {
$atts = shortcode_atts(array(
'id' => 0,
'show_products' => 'yes'
), $atts, 'vsm_vendor_detail');
$vendor_id = intval($atts['id']);
if (!$vendor_id || get_post_type($vendor_id) !== 'vsm_vendor') {
return '<p>供应商不存在</p>';
}
ob_start();
// 设置全局post变量
global $post;
$post = get_post($vendor_id);
setup_postdata($post);
?>
<div class="vsm-vendor-detail">
<div class="vsm-vendor-header">
<div class="vsm-vendor-header-left">
