| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384 |
- <?php
- namespace App\Services;
- use Illuminate\Support\Facades\DB;
- use Illuminate\Support\Facades\Validator;
- use Illuminate\Validation\ValidationException;
- /** 联系我们:后台维护多个邮箱与多个域名,前台原样展示 */
- class ContactConfigurationService
- {
- public const MAX_ITEMS = 50;
- public function get(): array
- {
- return $this->format(DB::table('contact_settings')->where('id', 1)->first());
- }
- public function save(array $input): array
- {
- $data = Validator::make($input, [
- 'emails' => ['present', 'array', 'max:' . self::MAX_ITEMS],
- 'emails.*' => ['nullable', 'string', 'max:254'],
- 'domains' => ['present', 'array', 'max:' . self::MAX_ITEMS],
- 'domains.*' => ['nullable', 'string', 'max:2048'],
- ], [
- 'emails.present' => '请提交邮箱数组', 'emails.array' => '邮箱必须为数组', 'emails.max' => '邮箱最多' . self::MAX_ITEMS . '个',
- 'emails.*.string' => '每个邮箱必须为字符串', 'emails.*.max' => '每个邮箱最多254个字符',
- 'domains.present' => '请提交域名数组', 'domains.array' => '域名必须为数组', 'domains.max' => '域名最多' . self::MAX_ITEMS . '个',
- 'domains.*.string' => '每个域名必须为字符串', 'domains.*.max' => '每个域名最多2048个字符',
- ])->validate();
- foreach (['emails' => '邮箱', 'domains' => '域名'] as $field => $label) {
- if (array_values($data[$field]) !== $data[$field]) {
- throw ValidationException::withMessages([$field => $label . '必须为顺序数组']);
- }
- }
- $emails = [];
- foreach ($data['emails'] as $index => $email) {
- $email = trim((string) $email);
- if ($email === '') continue;
- if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
- throw ValidationException::withMessages(['emails.' . $index => '邮箱格式不正确:' . $email]);
- }
- if (!in_array(strtolower($email), array_map('strtolower', $emails), true)) $emails[] = $email;
- }
- $domains = [];
- foreach ($data['domains'] as $index => $domain) {
- if (trim((string) $domain) === '') continue;
- $url = SiteConfigurationService::normalizeDomain((string) $domain, 'domains.' . $index);
- if (!in_array($url, $domains, true)) $domains[] = $url;
- }
- $payload = ['emails' => $emails, 'domains' => $domains];
- return DB::transaction(function () use ($payload) {
- DB::table('contact_settings')->insertOrIgnore(['id' => 1, 'emails' => '[]', 'domains' => '[]', 'created_at' => now(), 'updated_at' => now()]);
- $before = $this->format(DB::table('contact_settings')->where('id', 1)->lockForUpdate()->first());
- if ($before !== $payload) {
- DB::table('contact_settings')->where('id', 1)->update([
- 'emails' => json_encode($payload['emails'], JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR),
- 'domains' => json_encode($payload['domains'], JSON_UNESCAPED_SLASHES | JSON_THROW_ON_ERROR),
- 'updated_at' => now(),
- ]);
- OperationAuditService::record('contact_configuration', 1, 'update', $before, $payload);
- }
- return $payload;
- }, 3);
- }
- private function format(?object $row): array
- {
- return ['emails' => $this->list($row->emails ?? null), 'domains' => $this->list($row->domains ?? null)];
- }
- private function list(?string $value): array
- {
- if ($value === null || trim($value) === '') return [];
- $items = json_decode($value, true, 512, JSON_THROW_ON_ERROR);
- if (!is_array($items) || array_values($items) !== $items || count(array_filter($items, 'is_string')) !== count($items)) {
- throw new \RuntimeException('联系我们配置格式异常');
- }
- return $items;
- }
- }
|