| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384 |
- <?php
- namespace App\Services;
- use App\Models\RechargeChannel;
- use Illuminate\Support\Facades\DB;
- use Illuminate\Support\Facades\Validator;
- use Illuminate\Validation\ValidationException;
- final class RechargeBonusAdminService
- {
- private function ready(): void
- {
- if (!RechargeBonusService::available()) throw ValidationException::withMessages(['config' => '充值赠送配置未初始化,请先完成系统更新']);
- }
- private function channel($type): string
- {
- Validator::make(['channel_type' => $type], ['channel_type' => ['required', 'string', 'max:100']])->validate();
- if (!RechargeChannel::where('data_type', 1)->where('type', $type)->exists()) throw ValidationException::withMessages(['channel_type' => '充值方式不存在']);
- return $type;
- }
- private function texts(array $texts): array
- {
- $rules = []; $messages = [];
- foreach (['zh' => '中文', 'en' => '英文', 'vi' => '越南文'] as $lang => $label) {
- $rules[$lang] = ['required', 'array:text']; $rules[$lang . '.text'] = ['required', 'string', 'max:100'];
- $messages[$lang . '.required'] = $label . '角标文字不能为空'; $messages[$lang . '.text.required'] = $label . '角标文字不能为空';
- }
- $result = Validator::make($texts, $rules, $messages)->validate();
- foreach ($result as $lang => &$text) {
- if (preg_replace('/[\s\p{Z}\x{200B}\x{FEFF}]+/u', '', $text['text']) === '') throw ValidationException::withMessages(['translations.' . $lang . '.text' => '角标文字不能为空']);
- $text['text'] = trim($text['text']);
- }
- unset($text);
- return $result;
- }
- public function listing(): array
- {
- $this->ready(); $rules = DB::table('recharge_bonuses')->get()->keyBy('channel_type'); $rows = [];
- foreach (RechargeChannel::where('data_type', 1)->orderBy('sort')->orderBy('id')->get() as $channel) {
- if (isset($rows[$channel->type])) continue;
- $rule = $rules[$channel->type] ?? null;
- $rows[$channel->type] = ['channel_type' => $channel->type, 'channel_name' => $channel->name,
- 'bonus_percent' => RechargeBonusService::percent($rule->bonus_percent ?? '0'), 'enabled' => (int)($rule->enabled ?? 0),
- 'translations' => $rule ? json_decode($rule->translations, true) : ['zh' => ['text' => ''], 'en' => ['text' => ''], 'vi' => ['text' => '']]];
- }
- return ['total' => count($rows), 'data' => array_values($rows)];
- }
- public function save(array $input): array
- {
- $this->ready();
- $data = Validator::make($input, ['channel_type' => ['required', 'string'], 'bonus_percent' => ['required', 'numeric', 'between:0,100', 'regex:/^\d+(\.\d{1,2})?$/'],
- 'enabled' => ['required', 'integer', 'in:0,1'], 'translations' => ['required', 'array:zh,en,vi']])->validate();
- $this->channel($data['channel_type']); $data['translations'] = $this->texts($data['translations']);
- return DB::transaction(function () use ($data) {
- $before = DB::table('recharge_bonuses')->where('channel_type', $data['channel_type'])->lockForUpdate()->first();
- $now = RechargeBonusService::now();
- DB::table('recharge_bonuses')->updateOrInsert(['channel_type' => $data['channel_type']], [
- 'bonus_percent' => bcadd((string)$data['bonus_percent'], '0', 2), 'enabled' => $data['enabled'],
- 'translations' => json_encode($data['translations'], JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR),
- 'created_at' => $before->created_at ?? $now, 'updated_at' => $now]);
- OperationAuditService::record('recharge_bonus', null, 'save', (array)$before, $data);
- return $data;
- });
- }
- public function status(array $input): array
- {
- $this->ready(); $data = Validator::make($input, ['channel_type' => ['required', 'string'], 'enabled' => ['required', 'integer', 'in:0,1']])->validate();
- $this->channel($data['channel_type']);
- return DB::transaction(function () use ($data) {
- $row = DB::table('recharge_bonuses')->where('channel_type', $data['channel_type'])->lockForUpdate()->first();
- if (!$row) throw ValidationException::withMessages(['channel_type' => '请先保存该充值方式的赠送配置']);
- if ($data['enabled']) $this->texts(json_decode($row->translations, true));
- DB::table('recharge_bonuses')->where('channel_type', $data['channel_type'])->update(['enabled' => $data['enabled'], 'updated_at' => RechargeBonusService::now()]);
- OperationAuditService::record('recharge_bonus', null, 'status', (array)$row, $data);
- return $data;
- });
- }
- }
|