diff --git a/app/Http/Controllers/Api/SystemController.php b/app/Http/Controllers/Api/SystemController.php index dee3c7fd8..99c9ea348 100755 --- a/app/Http/Controllers/Api/SystemController.php +++ b/app/Http/Controllers/Api/SystemController.php @@ -28,7 +28,7 @@ class SystemController extends AbstractController * @apiParam {String} type * - get: 获取(默认) * - all: 获取所有(需要管理员权限) - * - save: 保存设置(参数:['reg', 'reg_invite', 'login_code', 'password_policy', 'project_invite', 'chat_nickname', 'auto_archived', 'archived_day', 'start_home', 'home_footer']) + * - save: 保存设置(参数:['reg', 'reg_invite', 'login_code', 'password_policy', 'project_invite', 'chat_nickname', 'auto_archived', 'archived_day', 'all_group_mute', 'start_home', 'home_footer']) * @apiSuccess {Number} ret 返回状态码(1正确、0错误) * @apiSuccess {String} msg 返回信息(错误描述) @@ -53,6 +53,7 @@ class SystemController extends AbstractController 'chat_nickname', 'auto_archived', 'archived_day', + 'all_group_mute', 'start_home', 'home_footer' ])) { @@ -86,6 +87,7 @@ class SystemController extends AbstractController $setting['chat_nickname'] = $setting['chat_nickname'] ?: 'optional'; $setting['auto_archived'] = $setting['auto_archived'] ?: 'close'; $setting['archived_day'] = floatval($setting['archived_day']) ?: 7; + $setting['all_group_mute'] = $setting['all_group_mute'] ?: 'open'; $setting['start_home'] = $setting['start_home'] ?: 'close'; // return Base::retSuccess('success', $setting ?: json_decode('{}')); diff --git a/app/Http/Controllers/Api/UsersController.php b/app/Http/Controllers/Api/UsersController.php index fc9782bf0..3f2fa84c0 100755 --- a/app/Http/Controllers/Api/UsersController.php +++ b/app/Http/Controllers/Api/UsersController.php @@ -666,7 +666,7 @@ class UsersController extends AbstractController } } if ($upArray) { - AbstractModel::transaction(function() use ($type, $upArray, $userInfo, $transferUser) { + AbstractModel::transaction(function() use ($user, $type, $upArray, $userInfo, $transferUser) { $userInfo->updateInstance($upArray); $userInfo->save(); if ($type === 'setdisable') { @@ -676,6 +676,13 @@ class UsersController extends AbstractController ]); $userTransfer->save(); $userTransfer->start(); + // 离职移出全员群组 + $dialog = WebSocketDialog::whereGroupType('all')->orderByDesc('id')->first(); + $dialog?->exitGroup($userInfo->userid, 'remove'); + } elseif ($type === 'cleardisable') { + // 取消离职重新加入全员群组 + $dialog = WebSocketDialog::whereGroupType('all')->orderByDesc('id')->first(); + $dialog?->joinGroup($userInfo->userid, $user->userid); } }); } diff --git a/app/Models/User.php b/app/Models/User.php index cc80e0edd..f550fabff 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -230,7 +230,11 @@ class User extends AbstractModel $user = User::createInstance($inArray); $user->az = Base::getFirstCharter($user->nickname); $user->pinyin = Base::cn2pinyin($user->nickname); - $user->save(); + if ($user->save()) { + // 加入全员群组 + $dialog = WebSocketDialog::whereGroupType('all')->orderByDesc('id')->first(); + $dialog?->joinGroup($user->userid, 0); + } return $user->find($user->userid); } diff --git a/app/Models/WebSocketDialog.php b/app/Models/WebSocketDialog.php index f8f596bbe..2accb67af 100644 --- a/app/Models/WebSocketDialog.php +++ b/app/Models/WebSocketDialog.php @@ -3,6 +3,7 @@ namespace App\Models; use App\Exceptions\ApiException; +use App\Module\Base; use App\Tasks\PushTask; use Carbon\Carbon; use Hhxsv5\LaravelS\Swoole\Task\Task; @@ -116,6 +117,9 @@ class WebSocketDialog extends AbstractModel $this->name = '[Delete]'; $this->dialog_delete = 1; } + } elseif ($this->group_type === 'all') { + $this->name = Base::Lang('全体成员'); + $this->all_group_mute = Base::settingFind('system', 'all_group_mute'); } break; } @@ -249,6 +253,26 @@ class WebSocketDialog extends AbstractModel } } + /** + * 检查禁言 + * @param $userid + * @return void + */ + public function checkMute($userid) + { + if ($this->group_type === 'all') { + $allGroupMute = Base::settingFind('system', 'all_group_mute'); + switch ($allGroupMute) { + case 'all': + throw new ApiException('当前会话全员禁言'); + case 'user': + if (!User::find($userid)?->isAdmin()) { + throw new ApiException('当前会话禁言'); + } + } + } + } + /** * 获取群组名称 * @return mixed|string|null @@ -350,7 +374,7 @@ class WebSocketDialog extends AbstractModel 'name' => $name ?: '', 'group_type' => $group_type, 'owner_id' => $owner_id, - 'last_at' => $group_type === 'user' ? Carbon::now() : null, + 'last_at' => in_array($group_type, ['user', 'all']) ? Carbon::now() : null, ]); $dialog->save(); foreach (is_array($userid) ? $userid : [$userid] as $value) { @@ -358,7 +382,7 @@ class WebSocketDialog extends AbstractModel WebSocketDialogUser::createInstance([ 'dialog_id' => $dialog->id, 'userid' => $value, - 'important' => $group_type != 'user' + 'important' => !in_array($group_type, ['user', 'all']) ])->save(); } } diff --git a/app/Models/WebSocketDialogMsg.php b/app/Models/WebSocketDialogMsg.php index d6ac02d2e..4d73b9ba3 100644 --- a/app/Models/WebSocketDialogMsg.php +++ b/app/Models/WebSocketDialogMsg.php @@ -553,6 +553,7 @@ class WebSocketDialogMsg extends AbstractModel if (empty($dialog)) { throw new ApiException('获取会话失败'); } + $dialog->checkMute($sender); // if ($update_id) { // 修改 diff --git a/database/migrations/2022_07_04_144546_generate_web_socket_dialogs_all_group.php b/database/migrations/2022_07_04_144546_generate_web_socket_dialogs_all_group.php new file mode 100644 index 000000000..9393ff8d0 --- /dev/null +++ b/database/migrations/2022_07_04_144546_generate_web_socket_dialogs_all_group.php @@ -0,0 +1,31 @@ +exists()) { + $userids = User::whereNull('disable_at')->pluck('userid')->toArray(); + WebSocketDialog::createGroup(null, $userids, 'all'); + } + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + + } +} diff --git a/resources/assets/js/pages/manage/components/DialogGroupInfo.vue b/resources/assets/js/pages/manage/components/DialogGroupInfo.vue index effae34b6..40c48bcd2 100644 --- a/resources/assets/js/pages/manage/components/DialogGroupInfo.vue +++ b/resources/assets/js/pages/manage/components/DialogGroupInfo.vue @@ -30,7 +30,7 @@ -
+
@@ -94,6 +94,7 @@ export default { if (group_type === 'project') return '项目群组' if (group_type === 'task') return '任务群组' if (group_type === 'user') return '个人群组' + if (group_type === 'all') return '全员群组' return '未知' }, diff --git a/resources/assets/js/pages/manage/components/DialogWrapper.vue b/resources/assets/js/pages/manage/components/DialogWrapper.vue index ce8ae98bf..d259f2143 100644 --- a/resources/assets/js/pages/manage/components/DialogWrapper.vue +++ b/resources/assets/js/pages/manage/components/DialogWrapper.vue @@ -121,7 +121,11 @@ @on-progress="chatFile('progress', $event)" @on-success="chatFile('success', $event)" @on-error="chatFile('error', $event)"/> +
+ {{$L('禁言发言')}} +
0 ? this.msgId : this.replyActiveId) }, @@ -914,7 +932,7 @@ export default { inputFocus() { this.$nextTick(_ => { - this.$refs.input.focus() + this.$refs.input && this.$refs.input.focus() }) }, diff --git a/resources/assets/js/pages/manage/setting/components/SystemSetting.vue b/resources/assets/js/pages/manage/setting/components/SystemSetting.vue index b8af14e6d..e2aafe3f9 100644 --- a/resources/assets/js/pages/manage/setting/components/SystemSetting.vue +++ b/resources/assets/js/pages/manage/setting/components/SystemSetting.vue @@ -61,6 +61,16 @@
{{$L('任务完成 % 天后自动归档。', formDatum.archived_day)}}
+ + + {{$L('开放')}} + {{$L('成员禁言')}} + {{$L('全部禁言')}} + +
{{$L('开放:所有人都可以发言。')}}
+
{{$L('成员禁言:仅管理员可以发言。')}}
+
{{$L('全部禁言:所有人都禁止发言。')}}
+
{{$L('开启')}} diff --git a/resources/assets/sass/pages/components/dialog-wrapper.scss b/resources/assets/sass/pages/components/dialog-wrapper.scss index 3eaf9a28c..8eb1e66b4 100644 --- a/resources/assets/sass/pages/components/dialog-wrapper.scss +++ b/resources/assets/sass/pages/components/dialog-wrapper.scss @@ -982,6 +982,14 @@ overflow: hidden; } + .chat-mute { + color: $primary-desc-color; + background-color: #F4F5F7; + padding: 8px 12px; + border-radius: 10px; + text-align: center; + } + .chat-input-box { .chat-input-wrapper { background-color: #F4F5F7; @@ -1362,6 +1370,9 @@ background-color: #f8f8f8; padding: 8px 10px; margin-bottom: 0; + .chat-mute { + background-color: #ffffff; + } .chat-input-box { .chat-input-wrapper { background-color: #ffffff;