feat(admin): native plate moderators, product variants, discount term fields

Add WP-native ops UI without SPA: plate moderator list/application review
meta box, product SKU variants editor meta box, and shop_discount taxonomy
add/edit form fields. No admin build artifacts included.
This commit is contained in:
kate522 committed 2026-07-15 02:19:06 +08:00
1 parent f4b72c8f70
commit 83f0467084
5 files changed
+497

No files matched your search

+157
View File
@@ -33,6 +33,12 @@ class AKSRT_Shop_Term_Meta {
public function init(): void {
add_action('init', [$this, 'register_discount_taxonomy'], 5);
add_action('init', [$this, 'register_term_meta_fields'], 10);
// Native term UI for shop_discount (zibll-style admin ops).
add_action('shop_discount_add_form_fields', [$this, 'render_discount_add_fields']);
add_action('shop_discount_edit_form_fields', [$this, 'render_discount_edit_fields'], 10, 1);
add_action('created_shop_discount', [$this, 'save_discount_term_fields']);
add_action('edited_shop_discount', [$this, 'save_discount_term_fields']);
}
// ─── Taxonomy Registration ───────────────────────────────────
@@ -408,4 +414,155 @@ class AKSRT_Shop_Term_Meta {
$defaults = $shop['product_defaults'] ?? [];
return $defaults[$param_key] ?? $product_value;
}
/**
* Add form fields for shop_discount taxonomy.
*/
public function render_discount_add_fields(): void {
$fields = $this->get_discount_field_definitions();
foreach ($fields as $key => $def) {
$label = (string) ($def['description'] ?? $key);
$default = $def['default'] ?? '';
echo '<div class="form-field">';
echo '<label for="' . esc_attr($key) . '">' . esc_html($label) . '</label>';
$this->render_discount_field_control($key, $default, false);
echo '</div>';
}
}
/**
* Edit form fields for shop_discount taxonomy.
*/
public function render_discount_edit_fields($term): void {
if (!($term instanceof WP_Term)) {
return;
}
$fields = $this->get_discount_field_definitions();
foreach ($fields as $key => $def) {
$label = (string) ($def['description'] ?? $key);
$value = get_term_meta($term->term_id, $key, true);
if ($value === '' || $value === false) {
$value = $def['default'] ?? '';
}
echo '<tr class="form-field">';
echo '<th scope="row"><label for="' . esc_attr($key) . '">' . esc_html($label) . '</label></th>';
echo '<td>';
$this->render_discount_field_control($key, $value, true);
echo '</td></tr>';
}
}
/**
* @param string|int|float $value
*/
private function render_discount_field_control(string $key, $value, bool $edit): void {
$id = esc_attr($key);
$name = esc_attr($key);
$val = (string) $value;
if ($key === 'shop_discount_type') {
$opts = [
'reduction' => __('立减', 'aksrt'),
'discount' => __('折扣', 'aksrt'),
'gift' => __('赠品', 'aksrt'),
];
echo '<select name="' . $name . '" id="' . $id . '">';
foreach ($opts as $k => $label) {
printf('<option value="%s"%s>%s</option>', esc_attr($k), selected($val, $k, false), esc_html($label));
}
echo '</select>';
return;
}
if ($key === 'shop_discount_scope') {
$opts = [
'item' => __('单品', 'aksrt'),
'product' => __('商品', 'aksrt'),
'author' => __('商家', 'aksrt'),
'order' => __('整单', 'aksrt'),
];
echo '<select name="' . $name . '" id="' . $id . '">';
foreach ($opts as $k => $label) {
printf('<option value="%s"%s>%s</option>', esc_attr($k), selected($val, $k, false), esc_html($label));
}
echo '</select>';
return;
}
if ($key === 'shop_discount_user_limit') {
$opts = [
'' => __('不限', 'aksrt'),
'vip' => __('VIP1', 'aksrt'),
'vip_2' => __('VIP2', 'aksrt'),
'auth' => __('已认证', 'aksrt'),
];
echo '<select name="' . $name . '" id="' . $id . '">';
foreach ($opts as $k => $label) {
printf('<option value="%s"%s>%s</option>', esc_attr($k), selected($val, $k, false), esc_html($label));
}
echo '</select>';
return;
}
if (in_array($key, ['shop_discount_is_important', 'shop_discount_countdown'], true)) {
echo '<label><input type="checkbox" name="' . $name . '" id="' . $id . '" value="1" ' . checked($val, '1', false) . '> ' . esc_html__('启用', 'aksrt') . '</label>';
return;
}
if ($key === 'shop_discount_gift_config') {
echo '<textarea name="' . $name . '" id="' . $id . '" rows="3" class="large-text">' . esc_textarea($val) . '</textarea>';
return;
}
$type = in_array($key, ['shop_discount_priority'], true) ? 'number' : 'text';
if (in_array($key, ['shop_discount_start', 'shop_discount_end'], true)) {
$type = 'datetime-local';
// Convert mysql-ish values to datetime-local if needed.
if ($val !== '' && str_contains($val, ' ')) {
$val = str_replace(' ', 'T', substr($val, 0, 16));
}
}
printf(
'<input type="%s" name="%s" id="%s" value="%s" class="%s" />',
esc_attr($type),
$name,
$id,
esc_attr($val),
$edit ? 'regular-text' : ''
);
}
public function save_discount_term_fields(int $term_id): void {
if (!current_user_can('manage_categories')) {
return;
}
$fields = $this->get_discount_field_definitions();
foreach ($fields as $key => $def) {
if (in_array($key, ['shop_discount_is_important', 'shop_discount_countdown'], true)) {
$raw = isset($_POST[$key]) ? '1' : '';
} else {
if (!isset($_POST[$key])) {
continue;
}
$raw = wp_unslash($_POST[$key]);
}
if (isset($def['sanitize']) && is_callable($def['sanitize'])) {
$value = call_user_func($def['sanitize'], $raw);
} else {
$value = sanitize_text_field((string) $raw);
}
if (in_array($key, ['shop_discount_start', 'shop_discount_end'], true) && is_string($value) && str_contains($value, 'T')) {
$value = str_replace('T', ' ', $value);
if (strlen($value) === 16) {
$value .= ':00';
}
}
update_term_meta($term_id, $key, $value);
}
}
}