feat(payment): 支付&付费菜单按参考主题重构并新增提现策略页
- 子菜单重组为知识付费/余额充值/VIP会员/创作分成/推广返佣/收款接口/提现策略 - 收款接口页 1:1 复刻 Zibll 双下拉结构,仅保留支付宝/微信/PayPal/Stripe/易支付 - 订单前缀/流水号前缀/提现单号前缀配置保留并移入收款接口页 - 知识付费/推广返佣按参考主题全字段复刻,余额充值并入充值卡配置 - 新增 tabbed/between_number/page_select 表单控件及后端 pages 搜索源 - 清理旧 SPA 组件、无消费者 REST 端点与废弃配置键(不写双路兼容) - 更新存量契约测试至新 schema 文件
This commit is contained in:
@@ -192,7 +192,7 @@ class SchemaProvider {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (in_array($type, ['fieldset', 'accordion', 'sortable', 'link'], true) && !is_array($value)) {
|
||||
if (in_array($type, ['fieldset', 'accordion', 'sortable', 'link', 'between_number'], true) && !is_array($value)) {
|
||||
$errors[] = sprintf('%s must be an object', $field['label'] ?? $key);
|
||||
continue;
|
||||
}
|
||||
@@ -732,23 +732,46 @@ class SchemaProvider {
|
||||
continue;
|
||||
}
|
||||
foreach ($group['fields'] ?? [] as $field) {
|
||||
if (!is_array($field) || empty($field['key'])) {
|
||||
continue;
|
||||
}
|
||||
// UI-only controls never become persisted settings keys.
|
||||
if (!empty($field['ui_only'])) {
|
||||
continue;
|
||||
}
|
||||
// Notice/help-only rows are UI chrome, not stored settings keys.
|
||||
if (($field['type'] ?? '') === 'notice') {
|
||||
continue;
|
||||
}
|
||||
$fields[] = $field;
|
||||
$fields = array_merge($fields, $this->collect_persisted_fields(is_array($field) ? $field : []));
|
||||
}
|
||||
}
|
||||
return $fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Flatten one field definition into persisted keys. Tabbed is a UI-only
|
||||
* container: its sub-fields are flat top-level option keys, so they are
|
||||
* expanded into the persisted field list (notice / ui_only rows skipped).
|
||||
*
|
||||
* @return array<int,array<string,mixed>>
|
||||
*/
|
||||
private function collect_persisted_fields(array $field): array {
|
||||
if (($field['type'] ?? '') === 'tabbed') {
|
||||
$fields = [];
|
||||
foreach ((array) ($field['tabs'] ?? []) as $tab) {
|
||||
if (!is_array($tab)) {
|
||||
continue;
|
||||
}
|
||||
foreach ((array) ($tab['fields'] ?? []) as $sub) {
|
||||
$fields = array_merge($fields, $this->collect_persisted_fields(is_array($sub) ? $sub : []));
|
||||
}
|
||||
}
|
||||
return $fields;
|
||||
}
|
||||
if (empty($field['key'])) {
|
||||
return [];
|
||||
}
|
||||
// UI-only controls never become persisted settings keys.
|
||||
if (!empty($field['ui_only'])) {
|
||||
return [];
|
||||
}
|
||||
// Notice/help-only rows are UI chrome, not stored settings keys.
|
||||
if (($field['type'] ?? '') === 'notice') {
|
||||
return [];
|
||||
}
|
||||
return [$field];
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize legacy numeric money settings without accepting lossy precision.
|
||||
*
|
||||
@@ -848,6 +871,17 @@ class SchemaProvider {
|
||||
return $this->sanitize_object_fields($value, (array) ($field['fields'] ?? []));
|
||||
}
|
||||
|
||||
if ($type === 'between_number') {
|
||||
$defaults = is_array($field['default'] ?? null) ? $field['default'] : ['min' => 0, 'max' => 0];
|
||||
if (!is_array($value)) {
|
||||
return ['min' => (int) ($defaults['min'] ?? 0), 'max' => (int) ($defaults['max'] ?? 0)];
|
||||
}
|
||||
return [
|
||||
'min' => is_numeric($value['min'] ?? null) ? (int) $value['min'] : (int) ($defaults['min'] ?? 0),
|
||||
'max' => is_numeric($value['max'] ?? null) ? (int) $value['max'] : (int) ($defaults['max'] ?? 0),
|
||||
];
|
||||
}
|
||||
|
||||
if (in_array($type, ['group', 'repeater'], true)) {
|
||||
if (!is_array($value)) {
|
||||
return [];
|
||||
@@ -1006,6 +1040,8 @@ class SchemaProvider {
|
||||
'accordion'=> 'array',
|
||||
'sortable' => 'array',
|
||||
'link' => 'array',
|
||||
'between_number' => 'array',
|
||||
'page_select' => 'int',
|
||||
'async_select' => 'array',
|
||||
'json' => 'array',
|
||||
// 自定义面板(验证码服务商等)按对象存储
|
||||
|
||||
Reference in New Issue
Block a user