|
|
@@ -13,16 +13,37 @@ use Illuminate\Validation\ValidationException;
|
|
|
|
|
|
class Egame extends Controller
|
|
|
{
|
|
|
+ private const FALLBACK_GAME_TYPE_NAMES = [
|
|
|
+ 1 => '视讯',
|
|
|
+ 2 => '电子',
|
|
|
+ 3 => '彩票',
|
|
|
+ 4 => '体育',
|
|
|
+ 5 => '电竞',
|
|
|
+ 6 => '捕鱼',
|
|
|
+ 7 => '棋牌',
|
|
|
+ ];
|
|
|
+
|
|
|
public function items(): JsonResponse
|
|
|
{
|
|
|
try {
|
|
|
request()->validate([
|
|
|
- 'item_type' => ['nullable', Rule::in(['platform', 'game'])],
|
|
|
+ 'item_type' => ['nullable', Rule::in([
|
|
|
+ EgameItem::TYPE_CATEGORY,
|
|
|
+ EgameItem::TYPE_PLATFORM,
|
|
|
+ EgameItem::TYPE_GAME,
|
|
|
+ ])],
|
|
|
+ 'platform_scope' => ['nullable', Rule::in([
|
|
|
+ EgameItem::PLATFORM_SCOPE_GLOBAL,
|
|
|
+ EgameItem::PLATFORM_SCOPE_CATEGORY,
|
|
|
+ ])],
|
|
|
'plat_type' => ['nullable', 'string', 'max:32'],
|
|
|
'game_type' => ['nullable', 'integer', 'min:0', 'max:255'],
|
|
|
'game_code' => ['nullable', 'string', 'max:128'],
|
|
|
'keyword' => ['nullable', 'string', 'max:128'],
|
|
|
- 'status' => ['nullable', 'integer', Rule::in([0, 1])],
|
|
|
+ 'status' => ['nullable', 'integer', Rule::in([
|
|
|
+ EgameItem::STATUS_DISABLED,
|
|
|
+ EgameItem::STATUS_ENABLED,
|
|
|
+ ])],
|
|
|
'page' => ['nullable', 'integer', 'min:1'],
|
|
|
'limit' => ['nullable', 'integer', 'min:1', 'max:200'],
|
|
|
]);
|
|
|
@@ -35,7 +56,21 @@ class Egame extends Controller
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- $keyword = trim((string)request()->input('keyword', ''));
|
|
|
+ $platformScope = (string) request()->input('platform_scope', '');
|
|
|
+ if ($platformScope !== '') {
|
|
|
+ $itemType = (string) request()->input('item_type', '');
|
|
|
+ if ($itemType !== '' && $itemType !== EgameItem::TYPE_PLATFORM) {
|
|
|
+ throw new Exception('platform_scope 只适用于平台配置', HttpStatus::CUSTOM_ERROR);
|
|
|
+ }
|
|
|
+ $query->where('item_type', EgameItem::TYPE_PLATFORM);
|
|
|
+ if ($platformScope === EgameItem::PLATFORM_SCOPE_GLOBAL) {
|
|
|
+ $query->where('game_type', 0);
|
|
|
+ } else {
|
|
|
+ $query->where('game_type', '>', 0);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ $keyword = trim((string) request()->input('keyword', ''));
|
|
|
if ($keyword !== '') {
|
|
|
$query->where(function ($query) use ($keyword) {
|
|
|
$query->where('name', 'like', "%{$keyword}%")
|
|
|
@@ -44,13 +79,16 @@ class Egame extends Controller
|
|
|
});
|
|
|
}
|
|
|
|
|
|
- $limit = (int)request()->input('limit', 15);
|
|
|
- $page = (int)request()->input('page', 1);
|
|
|
+ $limit = (int) request()->input('limit', 15);
|
|
|
+ $page = (int) request()->input('page', 1);
|
|
|
$total = (clone $query)->count();
|
|
|
+ $states = $this->catalogStates();
|
|
|
$list = $query->orderByDesc('sort')
|
|
|
->orderByDesc('id')
|
|
|
->forPage($page, $limit)
|
|
|
- ->get();
|
|
|
+ ->get()
|
|
|
+ ->map(fn (EgameItem $item) => $this->decorateItem($item, $states))
|
|
|
+ ->values();
|
|
|
} catch (ValidationException $e) {
|
|
|
return $this->error(HttpStatus::VALIDATION_FAILED, $e->validator->errors()->first());
|
|
|
} catch (Exception $e) {
|
|
|
@@ -60,84 +98,144 @@ class Egame extends Controller
|
|
|
return $this->success(['total' => $total, 'data' => $list]);
|
|
|
}
|
|
|
|
|
|
+ public function options(): JsonResponse
|
|
|
+ {
|
|
|
+ try {
|
|
|
+ $states = $this->catalogStates();
|
|
|
+ $categoryPlatformCounts = $this->groupedCounts(
|
|
|
+ EgameItem::query()
|
|
|
+ ->where('item_type', EgameItem::TYPE_PLATFORM)
|
|
|
+ ->where('game_type', '>', 0),
|
|
|
+ 'game_type',
|
|
|
+ 'plat_type'
|
|
|
+ );
|
|
|
+ $categoryGameCounts = $this->groupedCounts(
|
|
|
+ EgameItem::query()->where('item_type', EgameItem::TYPE_GAME),
|
|
|
+ 'game_type',
|
|
|
+ 'id'
|
|
|
+ );
|
|
|
+ $platformCategoryCounts = $this->groupedCounts(
|
|
|
+ EgameItem::query()
|
|
|
+ ->where('item_type', EgameItem::TYPE_PLATFORM)
|
|
|
+ ->where('game_type', '>', 0),
|
|
|
+ 'plat_type',
|
|
|
+ 'game_type'
|
|
|
+ );
|
|
|
+ $platformGameCounts = $this->groupedCounts(
|
|
|
+ EgameItem::query()->where('item_type', EgameItem::TYPE_GAME),
|
|
|
+ 'plat_type',
|
|
|
+ 'id'
|
|
|
+ );
|
|
|
+
|
|
|
+ $categories = EgameItem::query()
|
|
|
+ ->where('item_type', EgameItem::TYPE_CATEGORY)
|
|
|
+ ->orderByDesc('sort')
|
|
|
+ ->orderBy('game_type')
|
|
|
+ ->get()
|
|
|
+ ->map(function (EgameItem $item) use ($states, $categoryPlatformCounts, $categoryGameCounts) {
|
|
|
+ $this->decorateItem($item, $states);
|
|
|
+ $key = (string) $item->game_type;
|
|
|
+ $item->setAttribute('platform_count', $categoryPlatformCounts[$key] ?? 0);
|
|
|
+ $item->setAttribute('game_count', $categoryGameCounts[$key] ?? 0);
|
|
|
+ return $item;
|
|
|
+ })
|
|
|
+ ->values();
|
|
|
+
|
|
|
+ $platforms = EgameItem::query()
|
|
|
+ ->where('item_type', EgameItem::TYPE_PLATFORM)
|
|
|
+ ->where('game_type', 0)
|
|
|
+ ->orderByDesc('sort')
|
|
|
+ ->orderBy('name')
|
|
|
+ ->orderBy('plat_type')
|
|
|
+ ->get()
|
|
|
+ ->map(function (EgameItem $item) use ($states, $platformCategoryCounts, $platformGameCounts) {
|
|
|
+ $this->decorateItem($item, $states);
|
|
|
+ $key = strtolower((string) $item->plat_type);
|
|
|
+ $item->setAttribute('category_count', $platformCategoryCounts[$key] ?? 0);
|
|
|
+ $item->setAttribute('game_count', $platformGameCounts[$key] ?? 0);
|
|
|
+ return $item;
|
|
|
+ })
|
|
|
+ ->values();
|
|
|
+ } catch (Exception $e) {
|
|
|
+ return $this->error(HttpStatus::CUSTOM_ERROR, $e->getMessage());
|
|
|
+ }
|
|
|
+
|
|
|
+ return $this->success([
|
|
|
+ 'categories' => $categories,
|
|
|
+ 'platforms' => $platforms,
|
|
|
+ 'statuses' => [
|
|
|
+ ['value' => EgameItem::STATUS_ENABLED, 'label' => '开启'],
|
|
|
+ ['value' => EgameItem::STATUS_DISABLED, 'label' => '关闭'],
|
|
|
+ ],
|
|
|
+ 'ingress' => [
|
|
|
+ ['value' => '1', 'label' => '仅电脑'],
|
|
|
+ ['value' => '2', 'label' => '仅手机'],
|
|
|
+ ['value' => '3', 'label' => '通用'],
|
|
|
+ ],
|
|
|
+ ]);
|
|
|
+ }
|
|
|
+
|
|
|
public function update(): JsonResponse
|
|
|
{
|
|
|
- DB::beginTransaction();
|
|
|
try {
|
|
|
request()->validate([
|
|
|
'id' => ['nullable', 'integer', 'min:0'],
|
|
|
- 'item_type' => ['required', Rule::in(['platform', 'game'])],
|
|
|
- 'plat_type' => ['required', 'string', 'max:32'],
|
|
|
- 'game_type' => ['required', 'integer', 'min:0', 'max:255'],
|
|
|
+ 'item_type' => ['nullable', Rule::in([
|
|
|
+ EgameItem::TYPE_CATEGORY,
|
|
|
+ EgameItem::TYPE_PLATFORM,
|
|
|
+ EgameItem::TYPE_GAME,
|
|
|
+ ])],
|
|
|
+ 'platform_scope' => ['nullable', Rule::in([
|
|
|
+ EgameItem::PLATFORM_SCOPE_GLOBAL,
|
|
|
+ EgameItem::PLATFORM_SCOPE_CATEGORY,
|
|
|
+ ])],
|
|
|
+ 'plat_type' => ['nullable', 'string', 'max:32'],
|
|
|
+ 'game_type' => ['nullable', 'integer', 'min:0', 'max:255'],
|
|
|
'game_code' => ['nullable', 'string', 'max:128'],
|
|
|
'name' => ['nullable', 'string', 'max:128'],
|
|
|
- 'ingress' => ['nullable', 'string', 'max:16'],
|
|
|
+ 'ingress' => ['nullable', Rule::in(['1', '2', '3'])],
|
|
|
+ 'lobby_enabled' => ['nullable', 'boolean'],
|
|
|
'logo' => ['nullable', 'string', 'max:500'],
|
|
|
'logo_langs' => ['nullable', 'array'],
|
|
|
- 'status' => ['nullable', 'integer', Rule::in([0, 1])],
|
|
|
+ 'status' => ['nullable', 'integer', Rule::in([
|
|
|
+ EgameItem::STATUS_DISABLED,
|
|
|
+ EgameItem::STATUS_ENABLED,
|
|
|
+ ])],
|
|
|
'sort' => ['nullable', 'integer', 'min:-999999', 'max:999999'],
|
|
|
]);
|
|
|
|
|
|
- $data = [
|
|
|
- 'item_type' => request()->input('item_type'),
|
|
|
- 'plat_type' => strtolower(trim((string)request()->input('plat_type'))),
|
|
|
- 'game_type' => (int)request()->input('game_type'),
|
|
|
- 'game_code' => trim((string)request()->input('game_code', '')),
|
|
|
- 'name' => trim((string)request()->input('name', '')),
|
|
|
- 'ingress' => trim((string)request()->input('ingress', '3')),
|
|
|
- 'logo' => trim((string)request()->input('logo', '')),
|
|
|
- 'logo_langs' => request()->input('logo_langs', null),
|
|
|
- 'status' => (int)request()->input('status', 1),
|
|
|
- 'sort' => (int)request()->input('sort', 0),
|
|
|
- ];
|
|
|
-
|
|
|
- if ($data['item_type'] === 'platform') {
|
|
|
- $data['game_code'] = '';
|
|
|
- $data['ingress'] = '3';
|
|
|
- }
|
|
|
- if ($data['item_type'] === 'game' && $data['game_code'] === '') {
|
|
|
- throw new Exception('游戏配置必须填写 game_code', HttpStatus::CUSTOM_ERROR);
|
|
|
- }
|
|
|
-
|
|
|
- $id = (int)request()->input('id', 0);
|
|
|
- if ($id > 0) {
|
|
|
- $item = EgameItem::query()->find($id);
|
|
|
- if (!$item) {
|
|
|
- throw new Exception('配置不存在', HttpStatus::CUSTOM_ERROR);
|
|
|
+ $id = (int) request()->input('id', 0);
|
|
|
+ $item = DB::transaction(function () use ($id) {
|
|
|
+ if ($id > 0) {
|
|
|
+ $item = EgameItem::query()->find($id);
|
|
|
+ if (!$item) {
|
|
|
+ throw new Exception('配置不存在', HttpStatus::CUSTOM_ERROR);
|
|
|
+ }
|
|
|
+ $this->assertIdentityUnchanged($item);
|
|
|
+ } else {
|
|
|
+ $identity = $this->normalizedIdentityForCreate();
|
|
|
+ $item = EgameItem::query()->firstOrNew($identity);
|
|
|
}
|
|
|
- $duplicate = EgameItem::query()
|
|
|
- ->where('item_type', $data['item_type'])
|
|
|
- ->where('plat_type', $data['plat_type'])
|
|
|
- ->where('game_type', $data['game_type'])
|
|
|
- ->where('game_code', $data['game_code'])
|
|
|
- ->where('id', '<>', $id)
|
|
|
- ->exists();
|
|
|
- if ($duplicate) {
|
|
|
- throw new Exception('相同平台/类型/游戏代码配置已存在', HttpStatus::CUSTOM_ERROR);
|
|
|
+
|
|
|
+ $data = $this->mutableItemData($item, !$item->exists);
|
|
|
+ $name = array_key_exists('name', $data) ? $data['name'] : (string) $item->name;
|
|
|
+ if ($item->isCategory() && trim($name) === '') {
|
|
|
+ throw new Exception('分类名称不能为空', HttpStatus::CUSTOM_ERROR);
|
|
|
}
|
|
|
- $item->fill($data)->save();
|
|
|
- } else {
|
|
|
- EgameItem::query()->updateOrCreate(
|
|
|
- [
|
|
|
- 'item_type' => $data['item_type'],
|
|
|
- 'plat_type' => $data['plat_type'],
|
|
|
- 'game_type' => $data['game_type'],
|
|
|
- 'game_code' => $data['game_code'],
|
|
|
- ],
|
|
|
- $data
|
|
|
- );
|
|
|
- }
|
|
|
-
|
|
|
- DB::commit();
|
|
|
+
|
|
|
+ if (!empty($data) || !$item->exists) {
|
|
|
+ $item->fill($data)->save();
|
|
|
+ }
|
|
|
+
|
|
|
+ return $item->fresh();
|
|
|
+ });
|
|
|
} catch (ValidationException $e) {
|
|
|
- DB::rollBack();
|
|
|
return $this->error(HttpStatus::VALIDATION_FAILED, $e->validator->errors()->first());
|
|
|
} catch (Exception $e) {
|
|
|
- DB::rollBack();
|
|
|
- return $this->error((int)$e->getCode(), $e->getMessage());
|
|
|
+ return $this->error((int) $e->getCode(), $e->getMessage());
|
|
|
}
|
|
|
|
|
|
- return $this->success();
|
|
|
+ return $this->success($this->decorateItem($item, $this->catalogStates()));
|
|
|
}
|
|
|
|
|
|
public function setStatus(): JsonResponse
|
|
|
@@ -145,22 +243,26 @@ class Egame extends Controller
|
|
|
try {
|
|
|
request()->validate([
|
|
|
'id' => ['required', 'integer', 'min:1'],
|
|
|
- 'status' => ['required', 'integer', Rule::in([0, 1])],
|
|
|
+ 'status' => ['required', 'integer', Rule::in([
|
|
|
+ EgameItem::STATUS_DISABLED,
|
|
|
+ EgameItem::STATUS_ENABLED,
|
|
|
+ ])],
|
|
|
]);
|
|
|
|
|
|
- $item = EgameItem::query()->find((int)request()->input('id'));
|
|
|
+ $item = EgameItem::query()->find((int) request()->input('id'));
|
|
|
if (!$item) {
|
|
|
throw new Exception('配置不存在', HttpStatus::CUSTOM_ERROR);
|
|
|
}
|
|
|
- $item->status = (int)request()->input('status');
|
|
|
+ $item->status = (int) request()->input('status');
|
|
|
$item->save();
|
|
|
+ $item = $item->fresh();
|
|
|
} catch (ValidationException $e) {
|
|
|
return $this->error(HttpStatus::VALIDATION_FAILED, $e->validator->errors()->first());
|
|
|
} catch (Exception $e) {
|
|
|
- return $this->error((int)$e->getCode(), $e->getMessage());
|
|
|
+ return $this->error((int) $e->getCode(), $e->getMessage());
|
|
|
}
|
|
|
|
|
|
- return $this->success();
|
|
|
+ return $this->success($this->decorateItem($item, $this->catalogStates()));
|
|
|
}
|
|
|
|
|
|
public function delete(): JsonResponse
|
|
|
@@ -170,17 +272,315 @@ class Egame extends Controller
|
|
|
'id' => ['required', 'integer', 'min:1'],
|
|
|
]);
|
|
|
|
|
|
- $item = EgameItem::query()->find((int)request()->input('id'));
|
|
|
- if (!$item) {
|
|
|
+ if (!EgameItem::query()->whereKey((int) request()->input('id'))->exists()) {
|
|
|
throw new Exception('配置不存在', HttpStatus::CUSTOM_ERROR);
|
|
|
}
|
|
|
- $item->delete();
|
|
|
} catch (ValidationException $e) {
|
|
|
return $this->error(HttpStatus::VALIDATION_FAILED, $e->validator->errors()->first());
|
|
|
} catch (Exception $e) {
|
|
|
- return $this->error((int)$e->getCode(), $e->getMessage());
|
|
|
+ return $this->error((int) $e->getCode(), $e->getMessage());
|
|
|
+ }
|
|
|
+
|
|
|
+ return $this->error(
|
|
|
+ HttpStatus::CUSTOM_ERROR,
|
|
|
+ '第三方游戏目录由同步任务维护,不能删除,请将状态设为关闭'
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ private function normalizedIdentityForCreate(): array
|
|
|
+ {
|
|
|
+ $input = request()->all();
|
|
|
+ if (!array_key_exists('item_type', $input) || !array_key_exists('game_type', $input)) {
|
|
|
+ throw new Exception('新增配置必须填写 item_type 和 game_type', HttpStatus::CUSTOM_ERROR);
|
|
|
+ }
|
|
|
+
|
|
|
+ $itemType = (string) request()->input('item_type', '');
|
|
|
+ $platformScope = (string) request()->input('platform_scope', '');
|
|
|
+ if (!in_array($itemType, [
|
|
|
+ EgameItem::TYPE_CATEGORY,
|
|
|
+ EgameItem::TYPE_PLATFORM,
|
|
|
+ EgameItem::TYPE_GAME,
|
|
|
+ ], true)) {
|
|
|
+ throw new Exception('item_type 参数错误', HttpStatus::CUSTOM_ERROR);
|
|
|
}
|
|
|
+ if ($platformScope !== '' && $itemType !== EgameItem::TYPE_PLATFORM) {
|
|
|
+ throw new Exception('platform_scope 只适用于平台配置', HttpStatus::CUSTOM_ERROR);
|
|
|
+ }
|
|
|
+
|
|
|
+ $identity = [
|
|
|
+ 'item_type' => $itemType,
|
|
|
+ 'plat_type' => strtolower(trim((string) request()->input('plat_type', ''))),
|
|
|
+ 'game_type' => (int) request()->input('game_type'),
|
|
|
+ 'game_code' => trim((string) request()->input('game_code', '')),
|
|
|
+ ];
|
|
|
+
|
|
|
+ if ($itemType === EgameItem::TYPE_CATEGORY) {
|
|
|
+ if ($identity['game_type'] <= 0) {
|
|
|
+ throw new Exception('分类 game_type 必须大于 0', HttpStatus::CUSTOM_ERROR);
|
|
|
+ }
|
|
|
+ $identity['plat_type'] = '';
|
|
|
+ $identity['game_code'] = '';
|
|
|
+ return $identity;
|
|
|
+ }
|
|
|
+
|
|
|
+ if ($identity['plat_type'] === '') {
|
|
|
+ throw new Exception('平台代码不能为空', HttpStatus::CUSTOM_ERROR);
|
|
|
+ }
|
|
|
+
|
|
|
+ if ($itemType === EgameItem::TYPE_PLATFORM) {
|
|
|
+ if ($platformScope === EgameItem::PLATFORM_SCOPE_GLOBAL) {
|
|
|
+ $identity['game_type'] = 0;
|
|
|
+ }
|
|
|
+ if ($platformScope === EgameItem::PLATFORM_SCOPE_CATEGORY && $identity['game_type'] <= 0) {
|
|
|
+ throw new Exception('平台分类关联的 game_type 必须大于 0', HttpStatus::CUSTOM_ERROR);
|
|
|
+ }
|
|
|
+ $identity['game_code'] = '';
|
|
|
+ return $identity;
|
|
|
+ }
|
|
|
+
|
|
|
+ if ($identity['game_type'] <= 0) {
|
|
|
+ throw new Exception('游戏 game_type 必须大于 0', HttpStatus::CUSTOM_ERROR);
|
|
|
+ }
|
|
|
+ if ($identity['game_code'] === '') {
|
|
|
+ throw new Exception('游戏配置必须填写 game_code', HttpStatus::CUSTOM_ERROR);
|
|
|
+ }
|
|
|
+
|
|
|
+ return $identity;
|
|
|
+ }
|
|
|
+
|
|
|
+ private function assertIdentityUnchanged(EgameItem $item): void
|
|
|
+ {
|
|
|
+ $input = request()->all();
|
|
|
+ $checks = [
|
|
|
+ 'item_type' => (string) $item->item_type,
|
|
|
+ 'plat_type' => strtolower((string) $item->plat_type),
|
|
|
+ 'game_type' => (int) $item->game_type,
|
|
|
+ 'game_code' => (string) $item->game_code,
|
|
|
+ ];
|
|
|
+
|
|
|
+ foreach ($checks as $field => $expected) {
|
|
|
+ if (!array_key_exists($field, $input) || $input[$field] === null) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ $actual = $input[$field];
|
|
|
+ if ($field === 'plat_type') {
|
|
|
+ $actual = strtolower(trim((string) $actual));
|
|
|
+ } elseif ($field === 'game_type') {
|
|
|
+ $actual = (int) $actual;
|
|
|
+ } else {
|
|
|
+ $actual = trim((string) $actual);
|
|
|
+ }
|
|
|
+ if ($actual !== $expected) {
|
|
|
+ throw new Exception('目录标识不允许修改:' . $field, HttpStatus::CUSTOM_ERROR);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (
|
|
|
+ array_key_exists('platform_scope', $input)
|
|
|
+ && $input['platform_scope'] !== null
|
|
|
+ && $input['platform_scope'] !== ''
|
|
|
+ ) {
|
|
|
+ $expectedScope = '';
|
|
|
+ if ($item->isGlobalPlatform()) {
|
|
|
+ $expectedScope = EgameItem::PLATFORM_SCOPE_GLOBAL;
|
|
|
+ } elseif ($item->isPlatformRelation()) {
|
|
|
+ $expectedScope = EgameItem::PLATFORM_SCOPE_CATEGORY;
|
|
|
+ }
|
|
|
+ if ((string) $input['platform_scope'] !== $expectedScope) {
|
|
|
+ throw new Exception('目录标识不允许修改:platform_scope', HttpStatus::CUSTOM_ERROR);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- return $this->success([], '删除成功');
|
|
|
+ private function mutableItemData(EgameItem $item, bool $isNew): array
|
|
|
+ {
|
|
|
+ $input = request()->all();
|
|
|
+ $data = $isNew ? [
|
|
|
+ 'name' => '',
|
|
|
+ 'ingress' => '3',
|
|
|
+ 'lobby_enabled' => 0,
|
|
|
+ 'logo' => '',
|
|
|
+ 'logo_langs' => null,
|
|
|
+ 'status' => EgameItem::STATUS_ENABLED,
|
|
|
+ 'sort' => 0,
|
|
|
+ ] : [];
|
|
|
+
|
|
|
+ foreach (['name', 'ingress', 'logo'] as $field) {
|
|
|
+ if (array_key_exists($field, $input)) {
|
|
|
+ $data[$field] = trim((string) $input[$field]);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (array_key_exists('logo_langs', $input)) {
|
|
|
+ $data['logo_langs'] = $item->item_type === EgameItem::TYPE_GAME
|
|
|
+ ? $input['logo_langs']
|
|
|
+ : null;
|
|
|
+ }
|
|
|
+ if (array_key_exists('status', $input)) {
|
|
|
+ $data['status'] = (int) $input['status'];
|
|
|
+ }
|
|
|
+ if (array_key_exists('sort', $input)) {
|
|
|
+ $data['sort'] = (int) $input['sort'];
|
|
|
+ }
|
|
|
+ if (array_key_exists('lobby_enabled', $input)) {
|
|
|
+ $data['lobby_enabled'] = $item->isPlatformRelation()
|
|
|
+ ? (int) request()->boolean('lobby_enabled')
|
|
|
+ : 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ if ($item->item_type !== EgameItem::TYPE_GAME && array_key_exists('ingress', $data)) {
|
|
|
+ $data['ingress'] = '3';
|
|
|
+ }
|
|
|
+ if ($item->item_type !== EgameItem::TYPE_GAME && array_key_exists('logo_langs', $data)) {
|
|
|
+ $data['logo_langs'] = null;
|
|
|
+ }
|
|
|
+ if (!$item->isPlatformRelation() && array_key_exists('lobby_enabled', $data)) {
|
|
|
+ $data['lobby_enabled'] = 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ return $data;
|
|
|
+ }
|
|
|
+
|
|
|
+ private function catalogStates(): array
|
|
|
+ {
|
|
|
+ $states = [
|
|
|
+ 'categories' => [],
|
|
|
+ 'global_platforms' => [],
|
|
|
+ 'platform_relations' => [],
|
|
|
+ ];
|
|
|
+
|
|
|
+ $rows = EgameItem::query()
|
|
|
+ ->whereIn('item_type', [EgameItem::TYPE_CATEGORY, EgameItem::TYPE_PLATFORM])
|
|
|
+ ->get();
|
|
|
+
|
|
|
+ foreach ($rows as $row) {
|
|
|
+ if ($row->isCategory()) {
|
|
|
+ $states['categories'][(string) $row->game_type] = $row;
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ $platType = strtolower((string) $row->plat_type);
|
|
|
+ if ($row->isGlobalPlatform()) {
|
|
|
+ $states['global_platforms'][$platType] = $row;
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ if ($row->isPlatformRelation()) {
|
|
|
+ $states['platform_relations'][$platType][(string) $row->game_type] = $row;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return $states;
|
|
|
+ }
|
|
|
+
|
|
|
+ private function decorateItem(EgameItem $item, array $states): EgameItem
|
|
|
+ {
|
|
|
+ $platType = strtolower((string) $item->plat_type);
|
|
|
+ $gameType = (string) $item->game_type;
|
|
|
+ $disabledBy = null;
|
|
|
+
|
|
|
+ $category = $states['categories'][$gameType] ?? null;
|
|
|
+ $globalPlatform = $states['global_platforms'][$platType] ?? null;
|
|
|
+ $platformRelation = $states['platform_relations'][$platType][$gameType] ?? null;
|
|
|
+
|
|
|
+ if ($item->isCategory()) {
|
|
|
+ if (!$this->enabled($item)) {
|
|
|
+ $disabledBy = 'category';
|
|
|
+ }
|
|
|
+ } elseif ($item->isGlobalPlatform()) {
|
|
|
+ if (!$this->enabled($item)) {
|
|
|
+ $disabledBy = 'platform';
|
|
|
+ }
|
|
|
+ } elseif ($item->isPlatformRelation()) {
|
|
|
+ if (!$this->enabled($category)) {
|
|
|
+ $disabledBy = 'category';
|
|
|
+ } elseif (!$this->enabled($globalPlatform)) {
|
|
|
+ $disabledBy = 'platform';
|
|
|
+ } elseif (!$this->enabled($item)) {
|
|
|
+ $disabledBy = 'platform_category';
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ if (!$this->enabled($category)) {
|
|
|
+ $disabledBy = 'category';
|
|
|
+ } elseif (!$this->enabled($globalPlatform)) {
|
|
|
+ $disabledBy = 'platform';
|
|
|
+ } elseif (!$this->enabled($platformRelation)) {
|
|
|
+ $disabledBy = 'platform_category';
|
|
|
+ } elseif (!$this->enabled($item)) {
|
|
|
+ $disabledBy = 'game';
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ $item->setAttribute('game_type_name', $this->gameTypeName((int) $item->game_type, $states));
|
|
|
+ $item->setAttribute(
|
|
|
+ 'platform_name',
|
|
|
+ $this->platformName($item, $globalPlatform, $platformRelation)
|
|
|
+ );
|
|
|
+ if ($item->item_type === EgameItem::TYPE_PLATFORM) {
|
|
|
+ $item->setAttribute(
|
|
|
+ 'platform_scope',
|
|
|
+ $item->isGlobalPlatform()
|
|
|
+ ? EgameItem::PLATFORM_SCOPE_GLOBAL
|
|
|
+ : EgameItem::PLATFORM_SCOPE_CATEGORY
|
|
|
+ );
|
|
|
+ } else {
|
|
|
+ $item->setAttribute('platform_scope', null);
|
|
|
+ }
|
|
|
+ $item->setAttribute('effective_status', $disabledBy === null ? 1 : 0);
|
|
|
+ $item->setAttribute('disabled_by', $disabledBy);
|
|
|
+
|
|
|
+ return $item;
|
|
|
+ }
|
|
|
+
|
|
|
+ private function enabled(?EgameItem $item): bool
|
|
|
+ {
|
|
|
+ return $item !== null && $item->status === EgameItem::STATUS_ENABLED;
|
|
|
+ }
|
|
|
+
|
|
|
+ private function platformName(
|
|
|
+ EgameItem $item,
|
|
|
+ ?EgameItem $globalPlatform,
|
|
|
+ ?EgameItem $platformRelation
|
|
|
+ ): string {
|
|
|
+ if ($item->isCategory()) {
|
|
|
+ return '';
|
|
|
+ }
|
|
|
+ if ($item->isGlobalPlatform() && trim((string) $item->name) !== '') {
|
|
|
+ return (string) $item->name;
|
|
|
+ }
|
|
|
+ if ($globalPlatform && trim((string) $globalPlatform->name) !== '') {
|
|
|
+ return (string) $globalPlatform->name;
|
|
|
+ }
|
|
|
+ if ($platformRelation && trim((string) $platformRelation->name) !== '') {
|
|
|
+ return (string) $platformRelation->name;
|
|
|
+ }
|
|
|
+ if ($item->item_type === EgameItem::TYPE_PLATFORM && trim((string) $item->name) !== '') {
|
|
|
+ return (string) $item->name;
|
|
|
+ }
|
|
|
+
|
|
|
+ return (string) $item->plat_type;
|
|
|
+ }
|
|
|
+
|
|
|
+ private function gameTypeName(int $gameType, array $states): string
|
|
|
+ {
|
|
|
+ if ($gameType <= 0) {
|
|
|
+ return '';
|
|
|
+ }
|
|
|
+
|
|
|
+ $category = $states['categories'][(string) $gameType] ?? null;
|
|
|
+ if ($category && trim((string) $category->name) !== '') {
|
|
|
+ return (string) $category->name;
|
|
|
+ }
|
|
|
+
|
|
|
+ return self::FALLBACK_GAME_TYPE_NAMES[$gameType] ?? ('分类' . $gameType);
|
|
|
+ }
|
|
|
+
|
|
|
+ private function groupedCounts($query, string $groupColumn, string $countColumn): array
|
|
|
+ {
|
|
|
+ return $query
|
|
|
+ ->select($groupColumn)
|
|
|
+ ->selectRaw("COUNT(DISTINCT {$countColumn}) AS aggregate")
|
|
|
+ ->groupBy($groupColumn)
|
|
|
+ ->pluck('aggregate', $groupColumn)
|
|
|
+ ->map(fn ($count) => (int) $count)
|
|
|
+ ->all();
|
|
|
}
|
|
|
}
|