diff --git a/app/admin/controller/Dashboard.php b/app/admin/controller/Dashboard.php index 927704f..6412bd3 100644 --- a/app/admin/controller/Dashboard.php +++ b/app/admin/controller/Dashboard.php @@ -21,16 +21,16 @@ class Dashboard extends Backend return $response; } - $scope = $this->channelScopeOrNull(); + $ownerAdminId = $this->ownerAdminIdOrNull(); $todayStart = strtotime(date('Y-m-d')); $todayEnd = $todayStart + 86400 - 1; $yesterdayStart = $todayStart - 86400; $yesterdayEnd = $todayStart - 1; - $userTotal = $this->countUsers($scope); - $newToday = $this->countUsersInRange($scope, $todayStart, $todayEnd); - $newYesterday = $this->countUsersInRange($scope, $yesterdayStart, $yesterdayEnd); + $userTotal = $this->countUsers($ownerAdminId); + $newToday = $this->countUsersInRange($ownerAdminId, $todayStart, $todayEnd); + $newYesterday = $this->countUsersInRange($ownerAdminId, $yesterdayStart, $yesterdayEnd); $growthPct = null; if ($newYesterday > 0) { $growthPct = round(($newToday - $newYesterday) / $newYesterday * 100, 1); @@ -38,14 +38,14 @@ class Dashboard extends Backend $growthPct = 100.0; } - $depositAgg = $this->aggregateDepositToday($scope, $todayStart, $todayEnd); - $withdrawPending = $this->countWithdrawPending($scope); - $betAgg = $this->aggregateBetToday($scope, $todayStart, $todayEnd); + $depositAgg = $this->aggregateDepositToday($ownerAdminId, $todayStart, $todayEnd); + $withdrawPending = $this->countWithdrawPending($ownerAdminId); + $betAgg = $this->aggregateBetToday($ownerAdminId, $todayStart, $todayEnd); - $trend = $this->buildSevenDayTrend($scope); - $channelShare = $this->buildChannelShare($scope); - $depositAmountChannelShare = $this->buildDepositAmountChannelShare($scope); - $recentUsers = $this->fetchRecentUsers($scope, 10); + $trend = $this->buildSevenDayTrend($ownerAdminId); + $channelShare = $this->buildChannelShare($ownerAdminId); + $depositAmountChannelShare = $this->buildDepositAmountChannelShare($ownerAdminId); + $recentUsers = $this->fetchRecentUsers($ownerAdminId, 10); return $this->success('', [ 'remark' => get_route_remark(), @@ -68,27 +68,27 @@ class Dashboard extends Backend } /** - * @param int[]|null $scope null=超管不限制;非 null 时 whereIn channel_id + * @param int|null $ownerAdminId null=超管不限制;非 null 时 where admin_id */ - private function countUsers(?array $scope): int + private function countUsers(?int $ownerAdminId): int { $q = Db::name('user'); - if ($scope !== null) { - $q->whereIn('channel_id', $scope); + if ($ownerAdminId !== null) { + $q->where('admin_id', '=', $ownerAdminId); } return intval($q->count()); } /** - * @param int[]|null $scope + * @param int|null $ownerAdminId */ - private function countUsersInRange(?array $scope, int $start, int $end): int + private function countUsersInRange(?int $ownerAdminId, int $start, int $end): int { $q = Db::name('user') ->where('create_time', '>=', $start) ->where('create_time', '<=', $end); - if ($scope !== null) { - $q->whereIn('channel_id', $scope); + if ($ownerAdminId !== null) { + $q->where('admin_id', '=', $ownerAdminId); } return intval($q->count()); } @@ -96,17 +96,17 @@ class Dashboard extends Backend /** * 今日成功充值:status=1,按创建日落在今日(与 mock 即时成功一致)。 * - * @param int[]|null $scope + * @param int|null $ownerAdminId * @return array{count:int, amount:string} */ - private function aggregateDepositToday(?array $scope, int $todayStart, int $todayEnd): array + private function aggregateDepositToday(?int $ownerAdminId, int $todayStart, int $todayEnd): array { $q = Db::name('deposit_order') ->where('status', 1) ->where('create_time', '>=', $todayStart) ->where('create_time', '<=', $todayEnd); - if ($scope !== null) { - $q->whereIn('channel_id', $scope); + if ($ownerAdminId !== null) { + $q->whereIn('user_id', $this->scopedUserIds($ownerAdminId)); } $rows = $q->fieldRaw('COUNT(*) AS c, COALESCE(SUM(CAST(amount AS DECIMAL(18,2))),0) AS s')->find(); if (!is_array($rows)) { @@ -120,13 +120,13 @@ class Dashboard extends Backend } /** - * @param int[]|null $scope + * @param int|null $ownerAdminId */ - private function countWithdrawPending(?array $scope): int + private function countWithdrawPending(?int $ownerAdminId): int { $q = Db::name('withdraw_order')->where('status', 0); - if ($scope !== null) { - $q->whereIn('channel_id', $scope); + if ($ownerAdminId !== null) { + $q->whereIn('user_id', $this->scopedUserIds($ownerAdminId)); } return intval($q->count()); } @@ -134,17 +134,17 @@ class Dashboard extends Backend /** * 今日投注:创建时间在今日且订单未作废(status 1 或 2)。 * - * @param int[]|null $scope + * @param int|null $ownerAdminId * @return array{count:int, amount:string} */ - private function aggregateBetToday(?array $scope, int $todayStart, int $todayEnd): array + private function aggregateBetToday(?int $ownerAdminId, int $todayStart, int $todayEnd): array { $q = Db::name('bet_order') ->whereIn('status', [1, 2]) ->where('create_time', '>=', $todayStart) ->where('create_time', '<=', $todayEnd); - if ($scope !== null) { - $q->whereIn('channel_id', $scope); + if ($ownerAdminId !== null) { + $q->whereIn('user_id', $this->scopedUserIds($ownerAdminId)); } $rows = $q->fieldRaw('COUNT(*) AS c, COALESCE(SUM(CAST(total_amount AS DECIMAL(18,2))),0) AS s')->find(); if (!is_array($rows)) { @@ -157,10 +157,10 @@ class Dashboard extends Backend } /** - * @param int[]|null $scope + * @param int|null $ownerAdminId * @return array{days:string[], new_users:int[], deposit_amount:string[], bet_amount:string[]} */ - private function buildSevenDayTrend(?array $scope): array + private function buildSevenDayTrend(?int $ownerAdminId): array { $days = []; $newUsers = []; @@ -172,14 +172,14 @@ class Dashboard extends Backend $dayEnd = $dayStart + 86400 - 1; $days[] = date('m-d', $dayStart); - $newUsers[] = $this->countUsersInRange($scope, $dayStart, $dayEnd); + $newUsers[] = $this->countUsersInRange($ownerAdminId, $dayStart, $dayEnd); $dq = Db::name('deposit_order') ->where('status', 1) ->where('create_time', '>=', $dayStart) ->where('create_time', '<=', $dayEnd); - if ($scope !== null) { - $dq->whereIn('channel_id', $scope); + if ($ownerAdminId !== null) { + $dq->whereIn('user_id', $this->scopedUserIds($ownerAdminId)); } $drow = $dq->fieldRaw('COALESCE(SUM(CAST(amount AS DECIMAL(18,2))),0) AS s')->find(); $dsum = is_array($drow) && isset($drow['s']) ? strval($drow['s']) : '0'; @@ -189,8 +189,8 @@ class Dashboard extends Backend ->whereIn('status', [1, 2]) ->where('create_time', '>=', $dayStart) ->where('create_time', '<=', $dayEnd); - if ($scope !== null) { - $bq->whereIn('channel_id', $scope); + if ($ownerAdminId !== null) { + $bq->whereIn('user_id', $this->scopedUserIds($ownerAdminId)); } $brow = $bq->fieldRaw('COALESCE(SUM(CAST(total_amount AS DECIMAL(18,2))),0) AS s')->find(); $bsum = is_array($brow) && isset($brow['s']) ? strval($brow['s']) : '0'; @@ -208,14 +208,14 @@ class Dashboard extends Backend /** * 用户按渠道分布(取前 8 名,其余合并为「其他」)。 * - * @param int[]|null $scope + * @param int|null $ownerAdminId * @return list */ - private function buildChannelShare(?array $scope): array + private function buildChannelShare(?int $ownerAdminId): array { $q = Db::name('user')->fieldRaw('channel_id, COUNT(*) AS c')->group('channel_id'); - if ($scope !== null) { - $q->whereIn('channel_id', $scope); + if ($ownerAdminId !== null) { + $q->where('admin_id', '=', $ownerAdminId); } $rows = $q->orderRaw('c DESC')->select()->toArray(); if ($rows === []) { @@ -257,17 +257,17 @@ class Dashboard extends Backend /** * 成功充值金额按订单归属渠道汇总(status=1,受渠道范围限制)。 * - * @param int[]|null $scope + * @param int|null $ownerAdminId * @return list value 为两位小数字符串,供前端饼图展示 */ - private function buildDepositAmountChannelShare(?array $scope): array + private function buildDepositAmountChannelShare(?int $ownerAdminId): array { $q = Db::name('deposit_order') ->where('status', 1) ->fieldRaw('channel_id, COALESCE(SUM(CAST(amount AS DECIMAL(18,2))),0) AS s') ->group('channel_id'); - if ($scope !== null) { - $q->whereIn('channel_id', $scope); + if ($ownerAdminId !== null) { + $q->whereIn('user_id', $this->scopedUserIds($ownerAdminId)); } $rows = $q->select()->toArray(); if ($rows === []) { @@ -322,17 +322,17 @@ class Dashboard extends Backend } /** - * @param int[]|null $scope + * @param int|null $ownerAdminId * @return list */ - private function fetchRecentUsers(?array $scope, int $limit): array + private function fetchRecentUsers(?int $ownerAdminId, int $limit): array { $q = Db::name('user') ->field(['id', 'username', 'create_time', 'channel_id', 'head_image']) ->order('id', 'desc') ->limit($limit); - if ($scope !== null) { - $q->whereIn('channel_id', $scope); + if ($ownerAdminId !== null) { + $q->where('admin_id', '=', $ownerAdminId); } $rows = $q->select()->toArray(); if ($rows === []) { @@ -372,22 +372,31 @@ class Dashboard extends Backend } /** - * 非超管:按管理员所属渠道过滤;未绑定渠道时按 channel_id IN (0) 与列表页一致。 - * 超管:返回 null,表示 SQL 不加渠道条件。 + * 非超管:按当前管理员名下用户过滤。 + * 超管:返回 null,表示 SQL 不加管理员条件。 * - * @return int[]|null + * @return int|null */ - private function channelScopeOrNull(): ?array + private function ownerAdminIdOrNull(): ?int { if (!$this->auth || $this->auth->isSuperAdmin()) { return null; } - $admin = Db::name('admin')->field(['id', 'channel_id'])->where('id', $this->auth->id)->find(); - $ids = []; - if ($admin && !empty($admin['channel_id'])) { - $ids[] = $admin['channel_id']; + $idRaw = $this->auth->id; + if ($idRaw === null || $idRaw === '' || !is_numeric(strval($idRaw))) { + return 0; } + $id = intval(strval($idRaw)); + return $id > 0 ? $id : 0; + } - return $ids !== [] ? array_values(array_unique($ids)) : [0]; + /** + * @return int[] + */ + private function scopedUserIds(int $ownerAdminId): array + { + $ids = Db::name('user')->where('admin_id', '=', $ownerAdminId)->column('id'); + $ids = array_map('intval', $ids); + return $ids === [] ? [0] : array_values(array_unique($ids)); } } diff --git a/app/admin/controller/operation/UserNoticeRead.php b/app/admin/controller/operation/UserNoticeRead.php index ef0e6a3..ce2541f 100644 --- a/app/admin/controller/operation/UserNoticeRead.php +++ b/app/admin/controller/operation/UserNoticeRead.php @@ -32,4 +32,32 @@ class UserNoticeRead extends Backend $this->model = new \app\common\model\UserNoticeRead(); return null; } + + protected function _index(): Response + { + if ($this->request && $this->request->get('select')) { + return $this->select($this->request); + } + + list($where, $alias, $limit, $order) = $this->queryBuilder(); + $table = strtolower($this->model->getTable()); + $mainShort = $alias[$table] ?? ''; + if ($mainShort !== '' && $this->auth && !$this->auth->isSuperAdmin()) { + $where[] = ['user.admin_id', '=', intval(strval($this->auth->id))]; + } + + $res = $this->model + ->withJoin($this->withJoinTable, $this->withJoinType) + ->with($this->withJoinTable) + ->alias($alias) + ->where($where) + ->order($order) + ->paginate($limit); + + return $this->success('', [ + 'list' => $res->items(), + 'total' => $res->total(), + 'remark' => get_route_remark(), + ]); + } } diff --git a/app/admin/controller/order/BetOrder.php b/app/admin/controller/order/BetOrder.php index e6196a7..025bb7a 100644 --- a/app/admin/controller/order/BetOrder.php +++ b/app/admin/controller/order/BetOrder.php @@ -3,7 +3,6 @@ namespace app\admin\controller\order; use app\common\controller\Backend; -use support\think\Db; use support\Response; use Webman\Http\Request as WebmanRequest; @@ -79,8 +78,7 @@ class BetOrder extends Backend $table = strtolower($this->model->getTable()); $mainShort = $alias[$table] ?? ''; if ($mainShort !== '' && $this->auth && !$this->auth->isSuperAdmin()) { - $channelIds = $this->getScopedChannelIdsForFilter(); - $where[] = [$mainShort . '.channel_id', 'in', $channelIds !== [] ? $channelIds : [0]]; + $where[] = ['user.admin_id', '=', intval(strval($this->auth->id))]; } $res = $this->model @@ -103,25 +101,4 @@ class BetOrder extends Backend ]); } - /** - * @return int[] - */ - private function getScopedChannelIdsForFilter(): array - { - if (!$this->auth) { - return [0]; - } - if ($this->auth->isSuperAdmin()) { - return []; - } - $admin = Db::name('admin') - ->field(['id', 'channel_id']) - ->where('id', $this->auth->id) - ->find(); - $ids = []; - if ($admin && !empty($admin['channel_id'])) { - $ids[] = $admin['channel_id']; - } - return array_values(array_unique($ids)); - } } diff --git a/app/admin/controller/order/DepositOrder.php b/app/admin/controller/order/DepositOrder.php index b7058cf..317cff6 100644 --- a/app/admin/controller/order/DepositOrder.php +++ b/app/admin/controller/order/DepositOrder.php @@ -3,7 +3,6 @@ namespace app\admin\controller\order; use app\common\controller\Backend; -use support\think\Db; use support\Response; use Webman\Http\Request as WebmanRequest; @@ -49,8 +48,7 @@ class DepositOrder extends Backend $table = strtolower($this->model->getTable()); $mainShort = $alias[$table] ?? ''; if ($mainShort !== '' && $this->auth && !$this->auth->isSuperAdmin()) { - $channelIds = $this->getScopedChannelIdsForFilter(); - $where[] = [$mainShort . '.channel_id', 'in', $channelIds !== [] ? $channelIds : [0]]; + $where[] = ['user.admin_id', '=', intval(strval($this->auth->id))]; } $this->appendDepositOrderIndexWhere($where, $mainShort); @@ -115,7 +113,7 @@ class DepositOrder extends Backend ->withJoin($this->withJoinTable, $this->withJoinType) ->with($this->withJoinTable) ->visible([ - 'user' => ['username', 'phone'], + 'user' => ['username', 'phone', 'admin_id'], 'channel' => ['name'], ]) ->where($this->model->getTable() . '.id', $id) @@ -131,36 +129,18 @@ class DepositOrder extends Backend if (!$this->auth || $this->auth->isSuperAdmin()) { return true; } - $channelIds = $this->getScopedChannelIdsForFilter(); - if ($channelIds === []) { + $userRow = $row['user'] ?? null; + if (!is_array($userRow)) { return false; } - $raw = $row['channel_id'] ?? null; - if ($raw === null || $raw === '') { + $adminIdRaw = $userRow['admin_id'] ?? null; + if ($adminIdRaw === null || $adminIdRaw === '') { return false; } - if (!is_numeric(strval($raw))) { + if (!is_numeric(strval($adminIdRaw))) { return false; } - return in_array(intval(strval($raw)), $channelIds, true); + return intval(strval($adminIdRaw)) === intval(strval($this->auth->id)); } - /** - * @return int[] - */ - private function getScopedChannelIdsForFilter(): array - { - if (!$this->auth) { - return [0]; - } - if ($this->auth->isSuperAdmin()) { - return []; - } - $admin = Db::name('admin')->field(['id', 'channel_id'])->where('id', $this->auth->id)->find(); - $ids = []; - if ($admin && !empty($admin['channel_id'])) { - $ids[] = $admin['channel_id']; - } - return array_values(array_unique($ids)); - } } diff --git a/app/admin/controller/order/WithdrawOrder.php b/app/admin/controller/order/WithdrawOrder.php index eac55fb..aa5c792 100644 --- a/app/admin/controller/order/WithdrawOrder.php +++ b/app/admin/controller/order/WithdrawOrder.php @@ -48,8 +48,7 @@ class WithdrawOrder extends Backend $table = strtolower($this->model->getTable()); $mainShort = $alias[$table] ?? ''; if ($mainShort !== '' && $this->auth && !$this->auth->isSuperAdmin()) { - $channelIds = $this->getScopedChannelIdsForFilter(); - $where[] = [$mainShort . '.channel_id', 'in', $channelIds !== [] ? $channelIds : [0]]; + $where[] = ['user.admin_id', '=', intval(strval($this->auth->id))]; } $res = $this->model @@ -386,17 +385,17 @@ class WithdrawOrder extends Backend if (!$this->auth || $this->auth->isSuperAdmin()) { return true; } - $channelIds = $this->getScopedChannelIdsForFilter(); - if ($channelIds === []) { + $uidRaw = is_array($row) ? ($row['user_id'] ?? null) : ($row->user_id ?? null); + $uid = $this->intParam($uidRaw); + if ($uid <= 0) { return false; } - $raw = is_array($row) ? ($row['channel_id'] ?? null) : ($row->channel_id ?? null); - if ($raw === null || $raw === '') { - // 无归属渠道的数据只有超管可见 + $user = Db::name('user')->field(['id', 'admin_id'])->where('id', $uid)->find(); + if (!is_array($user)) { return false; } - $cid = $this->intParam($raw); - return in_array($cid, $channelIds, true); + $ownerAdminId = $this->intParam($user['admin_id'] ?? 0); + return $ownerAdminId > 0 && $ownerAdminId === $this->intParam($this->auth->id ?? 0); } private function intParam($raw): int @@ -453,22 +452,4 @@ class WithdrawOrder extends Backend return $negative ? ('-' . $v) : $v; } - /** - * @return int[] - */ - private function getScopedChannelIdsForFilter(): array - { - if (!$this->auth) { - return [0]; - } - if ($this->auth->isSuperAdmin()) { - return []; - } - $admin = Db::name('admin')->field(['id', 'channel_id'])->where('id', $this->auth->id)->find(); - $ids = []; - if ($admin && !empty($admin['channel_id'])) { - $ids[] = $admin['channel_id']; - } - return array_values(array_unique($ids)); - } } diff --git a/app/admin/controller/user/User.php b/app/admin/controller/user/User.php index f4d5ab3..4ef282a 100644 --- a/app/admin/controller/user/User.php +++ b/app/admin/controller/user/User.php @@ -15,6 +15,11 @@ use Webman\Http\Request as WebmanRequest; */ class User extends Backend { + /** + * 这些接口只要求登录,不单独校验权限节点 + */ + protected array $noNeedPermission = ['adminScopeTree']; + /** * User模型对象 * @var object|null @@ -22,6 +27,11 @@ class User extends Backend */ protected ?object $model = null; + /** + * 渠道管理员仅可管理自己名下(admin_id=当前管理员)的用户 + */ + protected bool|string|int $dataLimit = true; + protected array|string $preExcludeFields = ['id', 'uuid', 'create_time', 'update_time', 'invite_code', 'coin', 'total_deposit_coin', 'total_withdraw_coin', 'bet_flow_coin']; protected array $withJoinTable = ['channel', 'admin']; @@ -390,9 +400,17 @@ class User extends Backend return $response; } + $currentAdminLeaf = $this->getCurrentAdminLeaf(); + if ($currentAdminLeaf === null) { + return $this->error(__('Record not found')); + } + $groupIds = $this->getManageableAdminGroupIds(); if ($groupIds === []) { - return $this->success('', ['list' => []]); + return $this->success('', [ + 'list' => [$currentAdminLeaf], + 'current_admin_id' => $currentAdminLeaf['value'], + ]); } $groups = Db::name('admin_group') @@ -488,12 +506,45 @@ class User extends Backend foreach ($roots as $rid) { $tree[] = $buildNode($rid); } + if (!isset($adminPrimary[intval(strval($currentAdminLeaf['value']))])) { + $tree[] = $currentAdminLeaf; + } return $this->success('', [ 'list' => $tree, + 'current_admin_id' => $currentAdminLeaf['value'], ]); } + private function getCurrentAdminLeaf(): ?array + { + $adminIdRaw = $this->auth->id ?? null; + if ($adminIdRaw === null || $adminIdRaw === '' || !is_numeric(strval($adminIdRaw))) { + return null; + } + $adminId = intval(strval($adminIdRaw)); + if ($adminId <= 0) { + return null; + } + $row = Db::name('admin') + ->field(['id', 'username', 'channel_id', 'invite_code']) + ->where('id', $adminId) + ->find(); + if (!$row) { + return null; + } + $invite = $row['invite_code'] ?? ''; + $invite = is_string($invite) ? $invite : ''; + $channelId = $row['channel_id'] ?? null; + return [ + 'value' => strval($adminId), + 'label' => strval($row['username'] ?? ('#' . strval($adminId))), + 'is_leaf' => true, + 'channel_id' => $channelId === null || $channelId === '' ? null : intval(strval($channelId)), + 'invite_code' => $invite, + ]; + } + /** * @return int[] */ diff --git a/app/admin/controller/user/UserWalletRecord.php b/app/admin/controller/user/UserWalletRecord.php index de67024..53d15b7 100644 --- a/app/admin/controller/user/UserWalletRecord.php +++ b/app/admin/controller/user/UserWalletRecord.php @@ -3,7 +3,6 @@ namespace app\admin\controller\user; use app\common\controller\Backend; -use support\think\Db; use support\Response; use Webman\Http\Request as WebmanRequest; @@ -79,8 +78,7 @@ class UserWalletRecord extends Backend $table = strtolower($this->model->getTable()); $mainShort = $alias[$table] ?? ''; if ($mainShort !== '' && $this->auth && !$this->auth->isSuperAdmin()) { - $channelIds = $this->getScopedChannelIdsForFilter(); - $where[] = [$mainShort . '.channel_id', 'in', $channelIds !== [] ? $channelIds : [0]]; + $where[] = ['user.admin_id', '=', intval(strval($this->auth->id))]; } $res = $this->model @@ -103,27 +101,4 @@ class UserWalletRecord extends Backend ]); } - /** - * 非超管:与渠道管理一致,仅本账号相关渠道 - * - * @return int[] - */ - private function getScopedChannelIdsForFilter(): array - { - if (!$this->auth) { - return [0]; - } - if ($this->auth->isSuperAdmin()) { - return []; - } - $admin = Db::name('admin') - ->field(['id', 'channel_id']) - ->where('id', $this->auth->id) - ->find(); - $ids = []; - if ($admin && !empty($admin['channel_id'])) { - $ids[] = $admin['channel_id']; - } - return array_values(array_unique($ids)); - } } diff --git a/web/src/views/backend/channel/index.vue b/web/src/views/backend/channel/index.vue index 44f9dfa..733db85 100644 --- a/web/src/views/backend/channel/index.vue +++ b/web/src/views/backend/channel/index.vue @@ -6,17 +6,55 @@ :buttons="['refresh', 'add', 'edit', 'delete', 'comSearch', 'quickSearch', 'columnDisplay']" :quick-search-placeholder="t('Quick search placeholder', { fields: t('channel.quick Search Fields') })" > +
+
+ +
{{ t('channel.settle_stats_channel_total') }}
+
{{ settleStats.channel_total }}
+
+ +
{{ t('channel.settle_stats_enabled') }}
+
{{ settleStats.enabled_count }}
+
+ +
{{ t('channel.settle_stats_pending_dividend') }}
+
{{ settleStats.carryover_positive_count }}
+
+ +
{{ t('channel.settle_stats_pending_amount') }}
+
{{ settleStats.carryover_positive_total }}
+
+
+
+ + {{ t('channel.settle_filter_all') }} + {{ t('channel.settle_filter_with_balance') }} + {{ t('channel.settle_filter_no_balance') }} + {{ t('channel.settle_filter_enabled') }} + {{ t('channel.settle_filter_disabled') }} + + + {{ t('channel.batch_settle_pending') }} + +
+
- +
- + @@ -44,8 +82,8 @@ - - + + @@ -53,16 +91,18 @@ - +
@@ -115,7 +155,7 @@ @@ -597,4 +697,71 @@ onMounted(() => { .share-group-empty { color: var(--el-text-color-placeholder); } + +.channel-top-actions { + margin: 8px 0 12px; +} + +.channel-stats-cards { + display: grid; + grid-template-columns: repeat(4, minmax(0, 1fr)); + gap: 10px; + margin-bottom: 10px; +} + +.channel-stat-card .label { + font-size: 12px; + color: var(--el-text-color-secondary); +} + +.channel-stat-card .value { + margin-top: 6px; + font-size: 20px; + font-weight: 600; + color: var(--el-text-color-primary); +} + +.channel-action-row { + display: flex; + justify-content: space-between; + gap: 10px; + align-items: center; + flex-wrap: wrap; +} + +.manual-settle-dialog-body { + max-height: min(70vh, 680px); + overflow: auto; + padding-right: 2px; +} + +.manual-settle-form { + display: grid; + grid-template-columns: repeat(2, minmax(0, 1fr)); + column-gap: 16px; +} + +.manual-settle-form :deep(.el-form-item) { + margin-bottom: 12px; +} + +.manual-settle-form-item-full { + grid-column: 1 / -1; +} + +.manual-settle-footer { + display: flex; + justify-content: flex-end; + gap: 8px; +} + +@media (max-width: 900px) { + .channel-stats-cards { + grid-template-columns: repeat(2, minmax(0, 1fr)); + } + + .manual-settle-form { + grid-template-columns: 1fr; + } +} diff --git a/web/src/views/backend/user/user/popupForm.vue b/web/src/views/backend/user/user/popupForm.vue index 1eea496..a7a5173 100644 --- a/web/src/views/backend/user/user/popupForm.vue +++ b/web/src/views/backend/user/user/popupForm.vue @@ -210,6 +210,7 @@ type TreeNode = { const adminScopeTree = ref([]) const adminIdToChannelId = ref>({}) const adminIdToInviteCode = ref>({}) +const currentAdminId = ref('') const treeProps = { value: 'value', @@ -309,6 +310,8 @@ const loadAdminScopeTree = async () => { method: 'get', }) const list = (res.data?.list ?? []) as TreeNode[] + const currentIdRaw = res.data?.current_admin_id + currentAdminId.value = currentIdRaw === undefined || currentIdRaw === null ? '' : String(currentIdRaw) adminScopeTree.value = list const { mapCh, mapInv } = buildAdminMapsFromTree(list) @@ -316,6 +319,14 @@ const loadAdminScopeTree = async () => { adminIdToInviteCode.value = mapInv await nextTick() + if ( + baTable.form.operate === 'Add' && + baTable.form.items && + (baTable.form.items.admin_id === undefined || baTable.form.items.admin_id === null || baTable.form.items.admin_id === '') && + currentAdminId.value !== '' + ) { + baTable.form.items.admin_id = currentAdminId.value + } const aid = baTable.form.items?.admin_id if (aid !== undefined && aid !== null && aid !== '') { onAdminTreeChange(aid as string | number) @@ -398,6 +409,14 @@ watch( (op) => { if (op === 'Add') { syncRiskFromFlags(0) + if ( + baTable.form.items && + (baTable.form.items.admin_id === undefined || baTable.form.items.admin_id === null || baTable.form.items.admin_id === '') && + currentAdminId.value !== '' + ) { + baTable.form.items.admin_id = currentAdminId.value + onAdminTreeChange(currentAdminId.value) + } } } )