perf: 优化删除成员

This commit is contained in:
kuaifan 2022-07-16 16:22:05 +08:00
parent 29ba6713f0
commit fa1c917b97
8 changed files with 205 additions and 47 deletions

View File

@ -382,7 +382,7 @@ class UsersController extends AbstractController
*/ */
public function search() 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'); $keys = Request::input('keys');
$sorts = Request::input('sorts'); $sorts = Request::input('sorts');
@ -455,6 +455,8 @@ class UsersController extends AbstractController
*/ */
public function basic() public function basic()
{ {
User::auth();
//
$userid = Request::input('userid'); $userid = Request::input('userid');
$array = Base::json2array($userid); $array = Base::json2array($userid);
if (empty($array)) { if (empty($array)) {
@ -466,6 +468,9 @@ class UsersController extends AbstractController
$retArray = []; $retArray = [];
foreach ($array AS $id) { foreach ($array AS $id) {
$basic = User::userid2basic($id); $basic = User::userid2basic($id);
if (empty($basic)) {
$basic = UserDelete::userid2basic($id);
}
if ($basic) { if ($basic) {
$retArray[] = $basic; $retArray[] = $basic;
} }
@ -576,7 +581,7 @@ class UsersController extends AbstractController
* - clearadmin 取消管理员 * - clearadmin 取消管理员
* - setdisable 设为离职(需要参数 disable_time、transfer_userid * - setdisable 设为离职(需要参数 disable_time、transfer_userid
* - cleardisable 取消离职 * - cleardisable 取消离职
* - delete 删除会员 * - delete 删除会员(需要参数 delete_reason
* @apiParam {String} [email] 邮箱地址 * @apiParam {String} [email] 邮箱地址
* @apiParam {String} [tel] 联系电话 * @apiParam {String} [tel] 联系电话
* @apiParam {String} [password] 新的密码 * @apiParam {String} [password] 新的密码
@ -584,6 +589,7 @@ class UsersController extends AbstractController
* @apiParam {String} [profession] 职位 * @apiParam {String} [profession] 职位
* @apiParam {String} [disable_time] 离职时间 * @apiParam {String} [disable_time] 离职时间
* @apiParam {String} [transfer_userid] 离职交接人 * @apiParam {String} [transfer_userid] 离职交接人
* @apiParam {String} [delete_reason] 删除原因
* *
* @apiSuccess {Number} ret 返回状态码1正确、0错误 * @apiSuccess {Number} ret 返回状态码1正确、0错误
* @apiSuccess {String} msg 返回信息(错误描述) * @apiSuccess {String} msg 返回信息(错误描述)
@ -644,7 +650,10 @@ class UsersController extends AbstractController
if ($userInfo->userid === $user->userid) { if ($userInfo->userid === $user->userid) {
return Base::retError('不能删除自己'); return Base::retError('不能删除自己');
} }
$userInfo->deleteUser(); if (empty($data['delete_reason'])) {
return Base::retError('请填写删除原因');
}
$userInfo->deleteUser($data['delete_reason']);
break; break;
} }
if (isset($upArray['identity'])) { if (isset($upArray['identity'])) {
@ -1119,13 +1128,7 @@ class UsersController extends AbstractController
} }
} }
if ($type == 'confirm') { if ($type == 'confirm') {
$deleteArr = [ if ($user->deleteUser($reason)) {
'userid' => $user->userid,
'email' => $user->email,
'reason' => $reason
];
$userDelete = UserDelete::createInstance($deleteArr);
if ($userDelete->save() && $user->deleteUser()) {
return Base::retSuccess('删除成功', $user); return Base::retSuccess('删除成功', $user);
} else { } else {
return Base::retError('删除失败'); return Base::retError('删除失败');

View File

@ -71,7 +71,11 @@ class User extends AbstractModel
'updated_at', '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) public function getUserimgAttribute($value)
{ {
if ($value && !str_contains($value, 'avatar/')) { if ($value && !str_contains($value, 'avatar/')) {
// 自定义头像
return Base::fillUrl($value); return Base::fillUrl($value);
} } else if (self::$defaultAvatarMode === 'auto') {
if ($this->defaultAvatarMode === 'auto') {
// 自动生成头像 // 自动生成头像
return url("avatar/" . urlencode($this->nickname) . ".png"); return url("avatar/" . urlencode($this->nickname) . ".png");
} else { } else {
@ -182,12 +186,30 @@ class User extends AbstractModel
/** /**
* 删除会员 * 删除会员
* @param $reason
* @return bool|null * @return bool|null
*/ */
public function deleteUser() public function deleteUser($reason)
{ {
UserEmailVerification::whereEmail($this->email)->delete(); return AbstractModel::transaction(function () use ($reason) {
return $this->delete(); // 删除原因
$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])) { if (isset($_A["__static_userid2basic_" . $userid])) {
return $_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(User::$basicField)->first();
$userInfo = self::whereUserid($userid)->select($fields)->first();
if ($userInfo) { if ($userInfo) {
$userInfo->online = $userInfo->getOnlineStatus(); $userInfo->online = $userInfo->getOnlineStatus();
} }

View File

@ -3,22 +3,27 @@
namespace App\Models; namespace App\Models;
use App\Module\Base;
/** /**
* App\Models\UserDelete * App\Models\UserDelete
* *
* @property int $id * @property int $id
* @property int|null $operator 操作人员
* @property int|null $userid 用户id * @property int|null $userid 用户id
* @property string|null $email 邮箱 * @property string|null $email 邮箱
* @property string|null $reason 注销原因 * @property string|null $reason 注销原因
* @property string|null $cache 会员资料缓存
* @property \Illuminate\Support\Carbon|null $created_at * @property \Illuminate\Support\Carbon|null $created_at
* @property \Illuminate\Support\Carbon|null $updated_at * @property \Illuminate\Support\Carbon|null $updated_at
* @method static \Illuminate\Database\Eloquent\Builder|UserDelete newModelQuery() * @method static \Illuminate\Database\Eloquent\Builder|UserDelete newModelQuery()
* @method static \Illuminate\Database\Eloquent\Builder|UserDelete newQuery() * @method static \Illuminate\Database\Eloquent\Builder|UserDelete newQuery()
* @method static \Illuminate\Database\Eloquent\Builder|UserDelete query() * @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 whereCreatedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder|UserDelete whereEmail($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 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 whereReason($value)
* @method static \Illuminate\Database\Eloquent\Builder|UserDelete whereUpdatedAt($value) * @method static \Illuminate\Database\Eloquent\Builder|UserDelete whereUpdatedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder|UserDelete whereUserid($value) * @method static \Illuminate\Database\Eloquent\Builder|UserDelete whereUserid($value)
@ -26,5 +31,46 @@ namespace App\Models;
*/ */
class UserDelete extends AbstractModel 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;
}
} }

View File

@ -0,0 +1,34 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class AddUserDeletesOperator extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('user_deletes', function (Blueprint $table) {
if (!Schema::hasColumn('user_deletes', 'operator')) {
$table->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");
});
}
}

View File

@ -0,0 +1,34 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class AddUserDeletesCache extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('user_deletes', function (Blueprint $table) {
if (!Schema::hasColumn('user_deletes', 'cache')) {
$table->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");
});
}
}

View File

@ -7,9 +7,10 @@
:placement="tooltipPlacement"> :placement="tooltipPlacement">
<div slot="content" class="common-avatar-transfer"> <div slot="content" class="common-avatar-transfer">
<slot/> <slot/>
<p>{{$L('昵称')}}: {{user.nickname}}</p> <p>{{$L('昵称')}}: {{user.nickname}}<em v-if="user.delete_at" class="deleted no-dark-content">{{$L('已删除')}}</em><em v-else-if="user.disable_at" class="disabled no-dark-content">{{$L('已离职')}}</em></p>
<p>{{$L('职位/职称')}}: {{user.profession || '-'}}</p> <p>{{$L('职位/职称')}}: {{user.profession || '-'}}</p>
<p v-if="user.disable_at"><strong>{{$L('离职时间')}}: {{user.disable_at}}</strong></p> <p v-if="user.delete_at"><strong>{{$L('删除时间')}}: {{user.delete_at}}</strong></p>
<p v-else-if="user.disable_at"><strong>{{$L('离职时间')}}: {{user.disable_at}}</strong></p>
<slot name="end"/> <slot name="end"/>
<div v-if="userId != userid && showIconMenu" class="avatar-icons"> <div v-if="userId != userid && showIconMenu" class="avatar-icons">
<Icon type="ios-chatbubbles" @click="openDialog"/> <Icon type="ios-chatbubbles" @click="openDialog"/>
@ -27,7 +28,6 @@
</div> </div>
<template v-if="showName"> <template v-if="showName">
<div class="avatar-name" :style="nameStyle">{{user.nickname}}</div> <div class="avatar-name" :style="nameStyle">{{user.nickname}}</div>
<div v-if="user.disable_at" class="avatar-disable">{{$L('离职')}}</div>
</template> </template>
</div> </div>
</ETooltip> </ETooltip>
@ -118,7 +118,8 @@
return { return {
'avatar-box': true, 'avatar-box': true,
'online': this.userId === this.userid || this.user.online, '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() { nameStyle() {
const {showIcon} = this; const {showIcon} = this;
const {delete_at, disable_at} = this.user
const styles = {}
if (!showIcon) { if (!showIcon) {
return { styles.paddingLeft = 0
paddingLeft: 0
}
} else {
return {}
} }
if (delete_at || disable_at) {
styles.opacity = 0.8
styles.textDecoration = "line-through"
}
return styles
}, },
avatarSize() { avatarSize() {

View File

@ -484,16 +484,21 @@ export default {
break; break;
case 'delete': case 'delete':
$A.modalConfirm({ $A.modalInput({
content: `你确定要删除帐号【ID:${row.userid}${row.nickname}】吗?`, title: `删除帐号【ID:${row.userid}${row.nickname}`,
loading: true, placeholder: "请输入删除原因",
onOk: () => { okText: "确定删除",
onOk: (value) => {
if (!value) {
return '删除原因不能为空'
}
return this.operationUser({ return this.operationUser({
userid: row.userid, userid: row.userid,
type: name, type: name,
delete_reason: value
}); });
} }
}); })
break; break;
default: default:

View File

@ -43,7 +43,8 @@
background-color: $primary-color; background-color: $primary-color;
} }
} }
&.disable { &.disabled,
&.deleted {
&:after { &:after {
content: ""; content: "";
position: absolute; position: absolute;
@ -56,6 +57,11 @@
border-radius: 50%; border-radius: 50%;
} }
} }
&.deleted {
&:after {
transform: rotate(-45deg);
}
}
} }
.avatar-name { .avatar-name {
padding-left: 6px; padding-left: 6px;
@ -63,19 +69,6 @@
text-overflow: ellipsis; text-overflow: ellipsis;
white-space: nowrap; 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 { .common-avatar-transfer {
@ -83,6 +76,24 @@
line-height: 1.5; line-height: 1.5;
> p { > p {
padding: 1px 2px; 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 { .avatar-icons {
margin-top: 12px; margin-top: 12px;