feat(vip): Batch 1 per-level packages and admin schema

This commit is contained in:
kate522 committed 2026-07-21 16:32:06 +08:00
1 parent 69836154fd
commit a4562627d8
6 files changed
+300 -47

No files matched your search

+85 -12
View File
@@ -12,11 +12,14 @@ trait VipServicePackages {
/**
* Parse packages_raw lines: price|days|title
* Parse per-level product lines (zibll vip_product).
*
* @return array<int, array{price:float,days:int,title:string}>
* Preferred: price|show_price|time|unit|tag|title
* Legacy: price|days|title
*
* @return array<int, array{price:float,show_price:float,time:int,unit:string,tag:string,tag_class:string,title:string,days:int}>
*/
public function parse_packages(string $raw): array {
public function parse_level_products(string $raw): array {
$lines = preg_split('/\r\n|\r|\n/', $raw) ?: [];
$out = [];
foreach ($lines as $line) {
@@ -26,20 +29,90 @@ trait VipServicePackages {
}
$parts = array_map('trim', explode('|', $line));
$price = isset($parts[0]) ? (float) $parts[0] : 0.0;
$days = isset($parts[1]) ? (int) $parts[1] : 0;
$title = isset($parts[2]) ? sanitize_text_field($parts[2]) : '';
if ($price <= 0) {
continue;
}
if ($title === '') {
$title = $days > 0
? sprintf(__('%d天会员', 'aksrt'), $days)
: __('永久会员', 'aksrt');
$n = count($parts);
// New format: price|show_price|time|unit|tag|title (6+)
// Or: price|show_price|time|unit|title (5)
if ($n >= 4 && (in_array(strtolower((string) ($parts[3] ?? '')), ['day', 'month', 'd', 'm'], true)
|| (isset($parts[3]) && $parts[3] !== '' && !is_numeric($parts[3])))) {
$show_price = isset($parts[1]) ? (float) $parts[1] : 0.0;
$time = isset($parts[2]) ? (int) $parts[2] : 0;
$unit_raw = strtolower((string) ($parts[3] ?? 'month'));
$unit = ($unit_raw === 'day' || $unit_raw === 'd') ? 'day' : 'month';
$tag = '';
$title = '';
if ($n >= 6) {
$tag = sanitize_text_field((string) ($parts[4] ?? ''));
$title = sanitize_text_field((string) ($parts[5] ?? ''));
} elseif ($n === 5) {
// price|show|time|unit|title
$title = sanitize_text_field((string) ($parts[4] ?? ''));
}
} else {
// Legacy: price|days|title
$show_price = 0.0;
$days_legacy = isset($parts[1]) ? (int) $parts[1] : 0;
$time = $days_legacy;
$unit = 'day';
$tag = '';
$title = isset($parts[2]) ? sanitize_text_field($parts[2]) : '';
}
$time = max(0, $time);
$days = $this->duration_to_days($time, $unit);
if ($title === '') {
if ($time <= 0) {
$title = __('永久会员', 'aksrt');
} elseif ($unit === 'day') {
$title = sprintf(__('%d天会员', 'aksrt'), $time);
} else {
$title = sprintf(__('%d个月会员', 'aksrt'), $time);
}
}
$out[] = [
'price' => round($price, 2),
'days' => max(0, $days),
'title' => $title,
'price' => round($price, 2),
'show_price' => max(0.0, round($show_price, 2)),
'time' => $time,
'unit' => $unit,
'tag' => $tag,
'tag_class' => '',
'title' => $title,
'days' => $days,
];
}
return $out;
}
/**
* Approximate days for catalog labels / order meta; activate prefers time+unit calendar math.
*/
public function duration_to_days(int $time, string $unit = 'day'): int {
if ($time <= 0) {
return 0;
}
if ($unit === 'month') {
return $time * 30;
}
return $time;
}
/**
* @deprecated Use parse_level_products — kept as thin adapter for upgrade fixed lines.
*
* @return array<int, array{price:float,days:int,title:string}>
*/
public function parse_packages(string $raw): array {
$parsed = $this->parse_level_products($raw);
$out = [];
foreach ($parsed as $p) {
$out[] = [
'price' => (float) $p['price'],
'days' => (int) $p['days'],
'title' => (string) $p['title'],
];
}
return $out;