| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283 |
- <?php
- namespace App\Services\Payment;
- use App\Constants\Util;
- use App\Models\RechargeChannel;
- use App\Services\OperationAuditService;
- use Illuminate\Support\Facades\DB;
- use Illuminate\Support\Facades\Schema;
- use Illuminate\Support\Facades\Validator;
- use Illuminate\Validation\ValidationException;
- final class RechargeChannelLogoService
- {
- public static function normalize($logo): ?string
- {
- Validator::make(['logo' => $logo], ['logo' => ['nullable', 'string', 'max:2048']])->validate();
- $logo = trim((string)($logo ?? '')); $parts = parse_url($logo);
- $relative = str_starts_with($logo, '/') && !str_starts_with($logo, '//');
- $absolute = filter_var($logo, FILTER_VALIDATE_URL) && $parts && in_array(strtolower($parts['scheme'] ?? ''), ['http', 'https'], true)
- && !isset($parts['user']) && !isset($parts['pass']);
- if ($logo !== '' && (preg_match('/[\x00-\x20\x7f\\\\]/', $logo) || (!$relative && !$absolute))) {
- throw ValidationException::withMessages(['logo' => '请使用上传后的图片路径或HTTP/HTTPS图片地址']);
- }
- return $logo === '' ? null : $logo;
- }
- public static function configured(array $types): array
- {
- if (!Schema::hasTable('recharge_method_logos')) return [];
- return DB::table('recharge_method_logos')->whereIn('channel_type', $types)->pluck('logo', 'channel_type')->all();
- }
- public function options(): array
- {
- $rows = [];
- foreach (PaymentProviderCatalog::channelFormOptions(1)['types'] as $type) {
- $rows[$type['value']] = ['channel_type' => $type['value'],
- 'channel_name' => ($type['payment_company_label'] === '' ? '' : $type['payment_company_label'] . ' / ') . $type['label'], 'logo' => ''];
- }
- $fallback = [];
- foreach (RechargeChannel::where('data_type', 1)->orderBy('sort')->orderBy('id')->get() as $channel) {
- if (!isset($rows[$channel->type])) $rows[$channel->type] = ['channel_type' => $channel->type, 'channel_name' => $channel->name, 'logo' => ''];
- if (!isset($fallback[$channel->type]) && $channel->logo !== '') $fallback[$channel->type] = $channel->logo;
- }
- $configured = self::configured(array_keys($rows));
- foreach ($rows as $type => &$row) {
- $logo = array_key_exists($type, $configured) ? $configured[$type] : ($fallback[$type] ?? '');
- $row['logo'] = $logo ? (string)Util::ensureUrl($logo) : '';
- }
- unset($row);
- return ['total' => count($rows), 'data' => array_values($rows)];
- }
- public static function store(string $type, ?string $logo): void
- {
- if (Schema::hasTable('recharge_method_logos')) {
- $before = DB::table('recharge_method_logos')->where('channel_type', $type)->first();
- DB::table('recharge_method_logos')->updateOrInsert(['channel_type' => $type],
- ['logo' => $logo, 'created_at' => $before->created_at ?? now(), 'updated_at' => now()]);
- }
- RechargeChannel::where('data_type', 1)->where('type', $type)->update(['logo' => $logo]);
- }
- public function save(array $input): array
- {
- Validator::make($input, ['channel_type' => ['required', 'string', 'max:100'], 'logo' => ['present', 'nullable', 'string', 'max:2048']])->validate();
- $types = array_column(PaymentProviderCatalog::channelFormOptions(1)['types'], 'value');
- $type = $input['channel_type'];
- if (!in_array($type, $types, true) && !RechargeChannel::where('data_type', 1)->where('type', $type)->exists()) {
- throw ValidationException::withMessages(['channel_type' => '充值方式不存在']);
- }
- if (!Schema::hasTable('recharge_method_logos')) throw ValidationException::withMessages(['config' => '充值Logo配置未初始化,请先完成系统更新']);
- $logo = self::normalize($input['logo']);
- return DB::transaction(function () use ($type, $logo) {
- $before = DB::table('recharge_method_logos')->where('channel_type', $type)->lockForUpdate()->first();
- self::store($type, $logo);
- $result = ['channel_type' => $type, 'logo' => $logo ? (string)Util::ensureUrl($logo) : ''];
- OperationAuditService::record('recharge_channel_logo', null, 'save', (array)$before, $result);
- return $result;
- }, 3);
- }
- }
|