mirror of
https://github.com/kuaifan/dootask.git
synced 2026-02-28 21:20:31 +00:00
perf: 优化删除成员
This commit is contained in:
parent
29ba6713f0
commit
fa1c917b97
@ -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('删除失败');
|
||||
|
||||
@ -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();
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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");
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -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");
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -7,9 +7,10 @@
|
||||
:placement="tooltipPlacement">
|
||||
<div slot="content" class="common-avatar-transfer">
|
||||
<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 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"/>
|
||||
<div v-if="userId != userid && showIconMenu" class="avatar-icons">
|
||||
<Icon type="ios-chatbubbles" @click="openDialog"/>
|
||||
@ -27,7 +28,6 @@
|
||||
</div>
|
||||
<template v-if="showName">
|
||||
<div class="avatar-name" :style="nameStyle">{{user.nickname}}</div>
|
||||
<div v-if="user.disable_at" class="avatar-disable">{{$L('离职')}}</div>
|
||||
</template>
|
||||
</div>
|
||||
</ETooltip>
|
||||
@ -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() {
|
||||
|
||||
@ -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:
|
||||
|
||||
@ -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;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user