From fa1c917b97ebc17e3b454bfa2f8d3e911cb73d83 Mon Sep 17 00:00:00 2001 From: kuaifan Date: Sat, 16 Jul 2022 16:22:05 +0800 Subject: [PATCH] =?UTF-8?q?perf:=20=E4=BC=98=E5=8C=96=E5=88=A0=E9=99=A4?= =?UTF-8?q?=E6=88=90=E5=91=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/Http/Controllers/Api/UsersController.php | 23 +++++---- app/Models/User.php | 37 ++++++++++---- app/Models/UserDelete.php | 48 ++++++++++++++++++- ...07_16_161354_add_user_deletes_operator.php | 34 +++++++++++++ ...22_07_16_161857_add_user_deletes_cache.php | 34 +++++++++++++ resources/assets/js/components/UserAvatar.vue | 22 +++++---- .../manage/components/TeamManagement.vue | 15 ++++-- .../assets/sass/components/user-avatar.scss | 39 +++++++++------ 8 files changed, 205 insertions(+), 47 deletions(-) create mode 100644 database/migrations/2022_07_16_161354_add_user_deletes_operator.php create mode 100644 database/migrations/2022_07_16_161857_add_user_deletes_cache.php diff --git a/app/Http/Controllers/Api/UsersController.php b/app/Http/Controllers/Api/UsersController.php index 3910c14a2..915ee7740 100755 --- a/app/Http/Controllers/Api/UsersController.php +++ b/app/Http/Controllers/Api/UsersController.php @@ -382,7 +382,7 @@ class UsersController extends AbstractController */ public function search() { - $builder = User::select(['userid', 'email', 'nickname', 'profession', 'userimg', 'az', 'pinyin', 'line_at', 'disable_at']); + $builder = User::select(User::$basicField); // $keys = Request::input('keys'); $sorts = Request::input('sorts'); @@ -455,6 +455,8 @@ class UsersController extends AbstractController */ public function basic() { + User::auth(); + // $userid = Request::input('userid'); $array = Base::json2array($userid); if (empty($array)) { @@ -466,6 +468,9 @@ class UsersController extends AbstractController $retArray = []; foreach ($array AS $id) { $basic = User::userid2basic($id); + if (empty($basic)) { + $basic = UserDelete::userid2basic($id); + } if ($basic) { $retArray[] = $basic; } @@ -576,7 +581,7 @@ class UsersController extends AbstractController * - clearadmin 取消管理员 * - setdisable 设为离职(需要参数 disable_time、transfer_userid) * - cleardisable 取消离职 - * - delete 删除会员 + * - delete 删除会员(需要参数 delete_reason) * @apiParam {String} [email] 邮箱地址 * @apiParam {String} [tel] 联系电话 * @apiParam {String} [password] 新的密码 @@ -584,6 +589,7 @@ class UsersController extends AbstractController * @apiParam {String} [profession] 职位 * @apiParam {String} [disable_time] 离职时间 * @apiParam {String} [transfer_userid] 离职交接人 + * @apiParam {String} [delete_reason] 删除原因 * * @apiSuccess {Number} ret 返回状态码(1正确、0错误) * @apiSuccess {String} msg 返回信息(错误描述) @@ -644,7 +650,10 @@ class UsersController extends AbstractController if ($userInfo->userid === $user->userid) { return Base::retError('不能删除自己'); } - $userInfo->deleteUser(); + if (empty($data['delete_reason'])) { + return Base::retError('请填写删除原因'); + } + $userInfo->deleteUser($data['delete_reason']); break; } if (isset($upArray['identity'])) { @@ -1119,13 +1128,7 @@ class UsersController extends AbstractController } } if ($type == 'confirm') { - $deleteArr = [ - 'userid' => $user->userid, - 'email' => $user->email, - 'reason' => $reason - ]; - $userDelete = UserDelete::createInstance($deleteArr); - if ($userDelete->save() && $user->deleteUser()) { + if ($user->deleteUser($reason)) { return Base::retSuccess('删除成功', $user); } else { return Base::retError('删除失败'); diff --git a/app/Models/User.php b/app/Models/User.php index be11673d3..de2096088 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -71,7 +71,11 @@ class User extends AbstractModel 'updated_at', ]; - protected $defaultAvatarMode = 'auto'; // auto自动生成,system系统默认 + // 默认头像类型:auto自动生成,system系统默认 + public static $defaultAvatarMode = 'auto'; + + // 基本信息的字段 + public static $basicField = ['userid', 'email', 'nickname', 'profession', 'userimg', 'az', 'pinyin', 'line_at', 'disable_at']; /** * 更新数据校验 @@ -104,9 +108,9 @@ class User extends AbstractModel public function getUserimgAttribute($value) { if ($value && !str_contains($value, 'avatar/')) { + // 自定义头像 return Base::fillUrl($value); - } - if ($this->defaultAvatarMode === 'auto') { + } else if (self::$defaultAvatarMode === 'auto') { // 自动生成头像 return url("avatar/" . urlencode($this->nickname) . ".png"); } else { @@ -182,12 +186,30 @@ class User extends AbstractModel /** * 删除会员 + * @param $reason * @return bool|null */ - public function deleteUser() + public function deleteUser($reason) { - UserEmailVerification::whereEmail($this->email)->delete(); - return $this->delete(); + return AbstractModel::transaction(function () use ($reason) { + // 删除原因 + $userDelete = UserDelete::createInstance([ + 'operator' => User::userid(), + 'userid' => $this->userid, + 'email' => $this->email, + 'reason' => $reason, + 'cache' => $this->getRawOriginal() + ]); + $userDelete->save(); + // 删除未读 + WebSocketDialogMsgRead::whereUserid($this->userid)->delete(); + // 删除待办 + WebSocketDialogMsgTodo::whereUserid($this->userid)->delete(); + // 删除邮箱验证记录 + UserEmailVerification::whereEmail($this->email)->delete(); + // + return $this->delete(); + }); } /** ***************************************************************************************** */ @@ -436,8 +458,7 @@ class User extends AbstractModel if (isset($_A["__static_userid2basic_" . $userid])) { return $_A["__static_userid2basic_" . $userid]; } - $fields = ['userid', 'email', 'nickname', 'profession', 'userimg', 'az', 'pinyin', 'line_at', 'disable_at']; - $userInfo = self::whereUserid($userid)->select($fields)->first(); + $userInfo = self::whereUserid($userid)->select(User::$basicField)->first(); if ($userInfo) { $userInfo->online = $userInfo->getOnlineStatus(); } diff --git a/app/Models/UserDelete.php b/app/Models/UserDelete.php index 8a2edad94..96958f766 100644 --- a/app/Models/UserDelete.php +++ b/app/Models/UserDelete.php @@ -3,22 +3,27 @@ namespace App\Models; +use App\Module\Base; /** * App\Models\UserDelete * * @property int $id + * @property int|null $operator 操作人员 * @property int|null $userid 用户id - * @property string|null $email 邮箱帐号 + * @property string|null $email 邮箱账号 * @property string|null $reason 注销原因 + * @property string|null $cache 会员资料缓存 * @property \Illuminate\Support\Carbon|null $created_at * @property \Illuminate\Support\Carbon|null $updated_at * @method static \Illuminate\Database\Eloquent\Builder|UserDelete newModelQuery() * @method static \Illuminate\Database\Eloquent\Builder|UserDelete newQuery() * @method static \Illuminate\Database\Eloquent\Builder|UserDelete query() + * @method static \Illuminate\Database\Eloquent\Builder|UserDelete whereCache($value) * @method static \Illuminate\Database\Eloquent\Builder|UserDelete whereCreatedAt($value) * @method static \Illuminate\Database\Eloquent\Builder|UserDelete whereEmail($value) * @method static \Illuminate\Database\Eloquent\Builder|UserDelete whereId($value) + * @method static \Illuminate\Database\Eloquent\Builder|UserDelete whereOperator($value) * @method static \Illuminate\Database\Eloquent\Builder|UserDelete whereReason($value) * @method static \Illuminate\Database\Eloquent\Builder|UserDelete whereUpdatedAt($value) * @method static \Illuminate\Database\Eloquent\Builder|UserDelete whereUserid($value) @@ -26,5 +31,46 @@ namespace App\Models; */ class UserDelete extends AbstractModel { + /** + * 昵称 + * @param $value + * @return string + */ + public function getCacheAttribute($value) + { + if (!is_array($value)) { + $value = Base::json2array($value); + // 昵称 + if (!$value['nickname']) { + $value['nickname'] = Base::cardFormat($value['email']); + } + // 头像 + if ($value['userimg'] && !str_contains($value['userimg'], 'avatar/')) { + $value['userimg'] = Base::fillUrl($value['userimg']); + } else if (User::$defaultAvatarMode === 'auto') { + $value['userimg'] = url("avatar/" . urlencode($value['nickname']) . ".png"); + } else { + $name = ($value['userid'] - 1) % 21 + 1; + $value['userimg'] = url("images/avatar/default_{$name}.png"); + } + } + return $value; + } + /** + * userid 获取 基础信息 + * @param int $userid 会员ID + * @return array|null + */ + public static function userid2basic($userid) + { + $row = self::whereUserid($userid)->first(); + if (empty($row) || empty($row->cache)) { + return null; + } + $cache = $row->cache; + $cache = array_intersect_key($cache, array_flip(User::$basicField)); + $cache['delete_at'] = $row->created_at->format($row->dateFormat ?: 'Y-m-d H:i:s'); + return $cache; + } } diff --git a/database/migrations/2022_07_16_161354_add_user_deletes_operator.php b/database/migrations/2022_07_16_161354_add_user_deletes_operator.php new file mode 100644 index 000000000..f13fc7344 --- /dev/null +++ b/database/migrations/2022_07_16_161354_add_user_deletes_operator.php @@ -0,0 +1,34 @@ +bigInteger('operator')->nullable()->default(0)->after('id')->comment('操作人员'); + } + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('user_deletes', function (Blueprint $table) { + $table->dropColumn("operator"); + }); + } +} diff --git a/database/migrations/2022_07_16_161857_add_user_deletes_cache.php b/database/migrations/2022_07_16_161857_add_user_deletes_cache.php new file mode 100644 index 000000000..c08f1543e --- /dev/null +++ b/database/migrations/2022_07_16_161857_add_user_deletes_cache.php @@ -0,0 +1,34 @@ +text('cache')->after('reason')->nullable()->default('')->comment('会员资料缓存'); + } + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('user_deletes', function (Blueprint $table) { + $table->dropColumn("cache"); + }); + } +} diff --git a/resources/assets/js/components/UserAvatar.vue b/resources/assets/js/components/UserAvatar.vue index 79601f105..a93dbce43 100755 --- a/resources/assets/js/components/UserAvatar.vue +++ b/resources/assets/js/components/UserAvatar.vue @@ -7,9 +7,10 @@ :placement="tooltipPlacement">
-

{{$L('昵称')}}: {{user.nickname}}

+

{{$L('昵称')}}: {{user.nickname}}{{$L('已删除')}}{{$L('已离职')}}

{{$L('职位/职称')}}: {{user.profession || '-'}}

-

{{$L('离职时间')}}: {{user.disable_at}}

+

{{$L('删除时间')}}: {{user.delete_at}}

+

{{$L('离职时间')}}: {{user.disable_at}}

@@ -27,7 +28,6 @@
@@ -118,7 +118,8 @@ return { 'avatar-box': true, 'online': this.userId === this.userid || this.user.online, - 'disable': this.user.disable_at + 'disabled': this.user.disable_at, + 'deleted': this.user.delete_at } }, @@ -145,13 +146,16 @@ nameStyle() { const {showIcon} = this; + const {delete_at, disable_at} = this.user + const styles = {} if (!showIcon) { - return { - paddingLeft: 0 - } - } else { - return {} + styles.paddingLeft = 0 } + if (delete_at || disable_at) { + styles.opacity = 0.8 + styles.textDecoration = "line-through" + } + return styles }, avatarSize() { diff --git a/resources/assets/js/pages/manage/components/TeamManagement.vue b/resources/assets/js/pages/manage/components/TeamManagement.vue index 98f3ddc3b..f63e3db8f 100644 --- a/resources/assets/js/pages/manage/components/TeamManagement.vue +++ b/resources/assets/js/pages/manage/components/TeamManagement.vue @@ -484,16 +484,21 @@ export default { break; case 'delete': - $A.modalConfirm({ - content: `你确定要删除帐号【ID:${row.userid},${row.nickname}】吗?`, - loading: true, - onOk: () => { + $A.modalInput({ + title: `删除帐号【ID:${row.userid},${row.nickname}】`, + placeholder: "请输入删除原因", + okText: "确定删除", + onOk: (value) => { + if (!value) { + return '删除原因不能为空' + } return this.operationUser({ userid: row.userid, type: name, + delete_reason: value }); } - }); + }) break; default: diff --git a/resources/assets/sass/components/user-avatar.scss b/resources/assets/sass/components/user-avatar.scss index 6cdc751ee..68ac51c7c 100755 --- a/resources/assets/sass/components/user-avatar.scss +++ b/resources/assets/sass/components/user-avatar.scss @@ -43,7 +43,8 @@ background-color: $primary-color; } } - &.disable { + &.disabled, + &.deleted { &:after { content: ""; position: absolute; @@ -56,6 +57,11 @@ border-radius: 50%; } } + &.deleted { + &:after { + transform: rotate(-45deg); + } + } } .avatar-name { padding-left: 6px; @@ -63,19 +69,6 @@ text-overflow: ellipsis; white-space: nowrap; } - .avatar-disable { - margin-left: 2px; - white-space: nowrap; - font-size: 12px; - height: 20px; - line-height: 20px; - padding: 0 6px; - border-radius: 3px; - transform: scale(0.9); - transform-origin: right center; - color: #ffffff; - background-color: #ED4014; - } } } .common-avatar-transfer { @@ -83,6 +76,24 @@ line-height: 1.5; > p { padding: 1px 2px; + > em { + font-style: normal; + &.disabled, + &.deleted { + display: inline-block; + margin-left: 2px; + white-space: nowrap; + font-size: 12px; + height: 20px; + line-height: 20px; + padding: 0 6px; + border-radius: 3px; + transform: scale(0.9); + transform-origin: right center; + color: #ffffff; + background-color: #ED4014; + } + } } .avatar-icons { margin-top: 12px;