Skip to content

[ページ管理] ページ権限一覧, ページ権限設定で数万ユーザでもページ開けるように対応 #2180

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Apr 21, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 30 additions & 9 deletions app/Plugins/Manage/PageManage/PageManage.php
Original file line number Diff line number Diff line change
Expand Up @@ -750,13 +750,23 @@ public function role($request, $page_id, $group_id)
->orderBy('group_id', 'asc')
->get();

// 数万ユーザでメモリ不足になるため、GROUP_CONCAT()を使用して、グループ参加者のユーザ名を取得
// GROUP_CONCAT()はmysql設定でgroup_concat_max_len(default=1024)の制限があり、それ以上の長さの文字列は消える。
$group_users = User::
select(
'group_users.group_id',
DB::raw("GROUP_CONCAT(users.name SEPARATOR ',') as group_user_names"),
DB::raw('count(group_users.group_id) as user_count')
)
->join('group_users', 'group_users.user_id', '=', 'users.id')
->where('group_users.deleted_at', null)
->groupBy('group_users.group_id')
->get();

foreach ($groups as $group) {
$group->page_roles = $page_roles->where('group_id', $group->id);

// 数万ユーザでメモリ不足になるため、DB呼び出し
$group->group_user_names = User::whereIn('id', GroupUser::where('group_id', $group->id)->pluck('user_id'))
->pluck('name')
->implode(', ');
$group->group_user_names = optional($group_users->firstWhere('group_id', $group->id))->group_user_names;
$group->group_user_count = optional($group_users->firstWhere('group_id', $group->id))->user_count ?? 0;
}

// 自分のページから親を遡って取得
Expand Down Expand Up @@ -1054,11 +1064,22 @@ public function roleList($request, $id)
// ※ with('group_user')は、数万ユーザの場合、1Gでもメモリ不足になる。
$groups = Group::orderBy('display_sequence', 'asc')->get();

// 数万ユーザでメモリ不足になるため、GROUP_CONCAT()を使用して、グループ参加者のユーザ名を取得
// GROUP_CONCAT()はmysql設定でgroup_concat_max_len(default=1024)の制限があり、それ以上の長さの文字列は消える。
$group_users = User::
select(
'group_users.group_id',
DB::raw("GROUP_CONCAT(users.name SEPARATOR '<br>') as group_user_names"),
DB::raw('count(group_users.group_id) as user_count')
)
->join('group_users', 'group_users.user_id', '=', 'users.id')
->where('group_users.deleted_at', null)
->groupBy('group_users.group_id')
->get();

foreach ($groups as $group) {
// 数万ユーザでメモリ不足になるため、DB呼び出し
$group->group_user_names = User::whereIn('id', GroupUser::where('group_id', $group->id)->pluck('user_id'))
->pluck('name')
->implode('<br />');
$group->group_user_names = optional($group_users->firstWhere('group_id', $group->id))->group_user_names;
$group->group_user_count = optional($group_users->firstWhere('group_id', $group->id))->user_count ?? 0;
}

// 管理画面プラグインの戻り値の返し方
Expand Down
14 changes: 13 additions & 1 deletion resources/views/plugins/manage/page/role.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@

<div class="mt-1 mb-1">
<small>
<b><a href="{{url('/manage/group/edit')}}/{{$group->id}}" target="_blank">参加ユーザ <i class="fas fa-external-link-alt"></i></a></b>:{{$group->group_user_names}}
<b><a href="{{url('/manage/group/edit')}}/{{$group->id}}" target="_blank">参加ユーザ <span class="badge badge-pill badge-primary">{{$group->group_user_count}}人</span> <i class="fas fa-external-link-alt"></i></a></b>:<span class="txt-limit">{{$group->group_user_names}}</span>
</small>
</div>

Expand Down Expand Up @@ -149,4 +149,16 @@
</div>
</div>
</div>

<script>
// 表示する文字数制限
const limits = document.getElementsByClassName("txt-limit");
for (const limit of limits) {
const str = limit.innerHTML;
const len = 400; // 全角400字(約1000バイト)
if (str.length > len) {
limit.innerHTML = str.substring(0, len) + "<br><div class='text-danger'>(ユーザ多数のため以下省略)</div>";
}
}
</script>
@endsection
17 changes: 15 additions & 2 deletions resources/views/plugins/manage/page/role_list.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -166,13 +166,13 @@
<tr>
<th colspan="4">グループ名</th>
@foreach($groups as $group)
<th class="py-1">{{$group->name}} <a href="{{url('/manage/group/edit')}}/{{$group->id}}" target="_blank"> <i class="fas fa-external-link-alt"></i></a></th>
<th class="py-1">{{$group->name}} <span class="badge badge-pill badge-primary">{{$group->group_user_count}}人</span> <a href="{{url('/manage/group/edit')}}/{{$group->id}}" target="_blank"> <i class="fas fa-external-link-alt"></i></a></th>
@endforeach
</tr>
<tr>
<th colspan="4">参加ユーザ</th>
@foreach($groups as $group)
<td nowrap class="table-text py-1"><small>{!!$group->group_user_names!!}</small></td>
<td nowrap class="table-text py-1"><small class="txt-limit">{!!$group->group_user_names!!}</small></td>
@endforeach
</tr>

Expand All @@ -181,4 +181,17 @@
<small class="text-muted">※ 横スクロールできます。</small>
</div>
@endif
</div>

<script>
// 表示する文字数制限
const limits = document.getElementsByClassName("txt-limit");
for (const limit of limits) {
const str = limit.innerHTML;
const len = 400; // 全角400字(約1000バイト)
if (str.length > len) {
limit.innerHTML = str.substring(0, len) + "<br><div class='text-danger'>(ユーザ多数のため以下省略)</div>";
}
}
</script>
@endsection