实现用户管理功能
*做的应该差不多了 *应该没有功能遗漏
This commit is contained in:
parent
93a978fb76
commit
468b1a9374
@ -30,7 +30,7 @@ class AdminController extends Controller
|
|||||||
'rules' => [
|
'rules' => [
|
||||||
[
|
[
|
||||||
'allow' => true,
|
'allow' => true,
|
||||||
'actions' => ['index', 'system', 'user', 'info', 'user-view', 'user-create', 'user-update', 'user-delete'],
|
'actions' => ['index', 'system', 'user', 'info', 'user-view', 'user-create', 'user-update', 'user-delete', 'user-totpoff', 'user-pwdreset'],
|
||||||
'roles' => ['admin'], // only admin can do these
|
'roles' => ['admin'], // only admin can do these
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
@ -41,11 +41,13 @@ class AdminController extends Controller
|
|||||||
'index' => ['GET'],
|
'index' => ['GET'],
|
||||||
'system' => ['GET'],
|
'system' => ['GET'],
|
||||||
'user' => ['GET'],
|
'user' => ['GET'],
|
||||||
'user-view' => ['GET','POST'],
|
'user-view' => ['GET', 'POST'],
|
||||||
'user-create' => ['GET', 'POST'],
|
'user-create' => ['GET', 'POST'],
|
||||||
'user-update' => ['GET', 'POST'],
|
'user-update' => ['GET', 'POST'],
|
||||||
'user-delete' => ['POST'],
|
'user-delete' => ['POST'],
|
||||||
'info' => ['GET'],
|
'info' => ['GET'],
|
||||||
|
'user-totpoff' => ['POST'],
|
||||||
|
'user-pwdreset' => ['POST'],
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
]
|
]
|
||||||
@ -93,30 +95,47 @@ class AdminController extends Controller
|
|||||||
/**
|
/**
|
||||||
* Displays a single User model.
|
* Displays a single User model.
|
||||||
* @param int $id ID
|
* @param int $id ID
|
||||||
* @throws NotFoundHttpException if the model cannot be found
|
* @throws NotFoundHttpException|Throwable if the model cannot be found
|
||||||
*/
|
*/
|
||||||
public function actionUserView(int $id): array|string
|
public function actionUserView(int $id): array|string
|
||||||
{
|
{
|
||||||
$model = $this->findModel($id);
|
$model = $this->findModel($id);
|
||||||
|
|
||||||
if (isset($_POST['hasEditable'])) {
|
if (isset($_POST['hasEditable'])) {
|
||||||
Yii::$app->response->format = Response::FORMAT_JSON;
|
Yii::$app->response->format = Response::FORMAT_JSON;
|
||||||
|
if (isset($_POST['name'])) { //修改昵称
|
||||||
$oldValue = $model->name;
|
$oldValue = $model->name;
|
||||||
// TODO: Implement the logic to update the value of the model
|
$model->name = $_POST['name'];
|
||||||
if ($model->load($_POST)) {
|
if ($model->save(true, ['name'])) {
|
||||||
// read or convert your posted information
|
return ['output' => $model->name, 'message' => ''];
|
||||||
$value = $model->name;
|
|
||||||
|
|
||||||
// validate if any errors
|
|
||||||
if ($model->save(true,['name'])) {
|
|
||||||
// return JSON encoded output in the below format on success with an empty `message`
|
|
||||||
return ['output' => $value, 'message' => ''];
|
|
||||||
} else {
|
} else {
|
||||||
// alternatively you can return a validation error (by entering an error message in `message` key)
|
|
||||||
return ['output' => $oldValue, 'message' => 'Incorrect Value! Please reenter.'];
|
return ['output' => $oldValue, 'message' => 'Incorrect Value! Please reenter.'];
|
||||||
}
|
}
|
||||||
} // else if nothing to do always return an empty JSON encoded output
|
} elseif (isset($_POST['status'])) { //修改用户状态
|
||||||
else {
|
if ($id == Yii::$app->user->id) {
|
||||||
|
return ['output' => 'ERROR', 'message' => 'You cannot change your own status'];
|
||||||
|
}
|
||||||
|
$oldValue = $model->status;
|
||||||
|
$model->status = $_POST['status'];
|
||||||
|
$status = $this->actionUserDelete($id, $model->status);
|
||||||
|
if ($status == 1) {
|
||||||
|
return ['output' => $model->status == 0 ? '禁用' : '启用', 'message' => ''];
|
||||||
|
} elseif ($status == 0) {
|
||||||
|
return ['output' => $oldValue == 0 ? '禁用' : '启用', 'message' => '删除失败'];
|
||||||
|
} elseif ($status == 2) {
|
||||||
|
return ['output' => $oldValue == 0 ? '禁用' : '启用', 'message' => '无需操作'];
|
||||||
|
} elseif ($status == 3) {
|
||||||
|
return ['output' => $oldValue == 0 ? '禁用' : '启用', 'message' => '操作不允许'];
|
||||||
|
}
|
||||||
|
} elseif (isset($_POST['bio'])) { //修改用户简介
|
||||||
|
$oldValue = $model->bio;
|
||||||
|
$model->bio = $_POST['bio'];
|
||||||
|
if ($model->save(true, ['bio'])) {
|
||||||
|
return ['output' => $model->bio, 'message' => ''];
|
||||||
|
} else {
|
||||||
|
return ['output' => $oldValue, 'message' => 'Incorrect Value! Please reenter.'];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
return ['output' => '', 'message' => ''];
|
return ['output' => '', 'message' => ''];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -191,25 +210,77 @@ class AdminController extends Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* 0: delete failed
|
||||||
|
* 1: delete success
|
||||||
|
* 2: nothing to do
|
||||||
|
* 3: operation not allowed
|
||||||
* @param int $id ID
|
* @param int $id ID
|
||||||
* @return Response
|
|
||||||
* @throws NotFoundHttpException if the model cannot be found
|
* @throws NotFoundHttpException if the model cannot be found
|
||||||
* @throws Throwable
|
* @throws Throwable
|
||||||
* @throws StaleObjectException
|
|
||||||
*/
|
*/
|
||||||
public function actionUserDelete(int $id): Response
|
protected function actionUserDelete(int $id, int $operation): int
|
||||||
{
|
{
|
||||||
$user = $this->findModel($id);
|
$user = $this->findModel($id);
|
||||||
$alreadyDisabled = $user->status == 0;
|
if ($user->status == $operation) {
|
||||||
$str = $alreadyDisabled ? '启用' : '禁用';
|
// nothing to do
|
||||||
if ($user->deleteAccount($alreadyDisabled)) {
|
return 2;
|
||||||
$logout_result = '';
|
|
||||||
if (!$alreadyDisabled) {
|
|
||||||
$logout_result = AdminSword::forceUserLogout($id);
|
|
||||||
}
|
}
|
||||||
Yii::$app->session->setFlash('success', '账户' . $str . '成功,' . $logout_result);
|
if ($operation != 1 && $operation != 0) {
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
if ($user->deleteAccount($operation == 1)) {
|
||||||
|
$logout_result = '';
|
||||||
|
if ($operation == 0) {
|
||||||
|
AdminSword::forceUserLogout($id);
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
} else {
|
} else {
|
||||||
Yii::$app->session->setFlash('error', '账户' . $str . '失败');
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $id
|
||||||
|
* @return Response
|
||||||
|
*/
|
||||||
|
public function actionUserTotpoff(int $id)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$user = $this->findModel($id);
|
||||||
|
} catch (NotFoundHttpException $e) {
|
||||||
|
Yii::$app->session->setFlash('error', '用户不存在');
|
||||||
|
return $this->redirect(['user']);
|
||||||
|
}
|
||||||
|
if ($user->is_otp_enabled) {
|
||||||
|
$user->otp_secret = null;
|
||||||
|
$user->is_otp_enabled = 0;
|
||||||
|
$user->recovery_codes = null;
|
||||||
|
$user->save(false);
|
||||||
|
Yii::$app->session->setFlash('success', '二步验证已关闭');
|
||||||
|
return $this->redirect(['user-view', 'id' => $id]);
|
||||||
|
} else {
|
||||||
|
Yii::$app->session->setFlash('error', '二步验证未启用,无需关闭');
|
||||||
|
return $this->redirect(['user-view', 'id' => $id]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Response
|
||||||
|
* @throws Exception
|
||||||
|
* @throws NotFoundHttpException
|
||||||
|
*/
|
||||||
|
public function actionUserPwdreset(): Response
|
||||||
|
{
|
||||||
|
$id = Yii::$app->request->post('User')['id'];
|
||||||
|
$model = $this->findModel($id);
|
||||||
|
|
||||||
|
if ($model->load(Yii::$app->request->post()) && $model->validate()) {
|
||||||
|
$model->password = Yii::$app->security->generatePasswordHash($model->password);
|
||||||
|
if ($model->save(false)) {
|
||||||
|
Yii::$app->session->setFlash('success', '密码重置成功');
|
||||||
|
} else {
|
||||||
|
Yii::$app->session->setFlash('error', '密码重置失败');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return $this->redirect(['user-view', 'id' => $id]);
|
return $this->redirect(['user-view', 'id' => $id]);
|
||||||
}
|
}
|
||||||
|
@ -554,7 +554,7 @@ class UserController extends Controller
|
|||||||
$user->otp_secret = null;
|
$user->otp_secret = null;
|
||||||
$user->is_otp_enabled = 0;
|
$user->is_otp_enabled = 0;
|
||||||
$user->recovery_codes = null;
|
$user->recovery_codes = null;
|
||||||
$user->save();
|
$user->save(false);
|
||||||
Yii::$app->session->setFlash('success', '二步验证已关闭');
|
Yii::$app->session->setFlash('success', '二步验证已关闭');
|
||||||
} else {
|
} else {
|
||||||
Yii::$app->session->setFlash('error', '二步验证未启用,无需关闭');
|
Yii::$app->session->setFlash('error', '二步验证未启用,无需关闭');
|
||||||
|
@ -2,9 +2,12 @@
|
|||||||
|
|
||||||
use app\assets\FontAwesomeAsset;
|
use app\assets\FontAwesomeAsset;
|
||||||
use app\models\PublicKeyCredentialSourceRepository;
|
use app\models\PublicKeyCredentialSourceRepository;
|
||||||
|
use app\models\User;
|
||||||
use app\utils\FileSizeHelper;
|
use app\utils\FileSizeHelper;
|
||||||
use app\utils\IPLocation;
|
use app\utils\IPLocation;
|
||||||
use kartik\editable\Editable;
|
use kartik\editable\Editable;
|
||||||
|
use yii\bootstrap5\ActiveForm;
|
||||||
|
use yii\bootstrap5\Modal;
|
||||||
use yii\helpers\Html;
|
use yii\helpers\Html;
|
||||||
use yii\web\YiiAsset;
|
use yii\web\YiiAsset;
|
||||||
use yii\widgets\DetailView;
|
use yii\widgets\DetailView;
|
||||||
@ -24,25 +27,21 @@ FontAwesomeAsset::register($this);
|
|||||||
|
|
||||||
<h1>用户详情</h1>
|
<h1>用户详情</h1>
|
||||||
|
|
||||||
<!-- <p>-->
|
|
||||||
<!-- --><?php //= Html::a($str . '用户', ['user-delete', 'id' => $model->id], [
|
|
||||||
// 'class' => 'btn btn-danger ' . $isCurrentUser,
|
|
||||||
// 'data' => [
|
|
||||||
// 'confirm' => '你确定要' . $str . '这个用户吗?',
|
|
||||||
// 'method' => 'post',
|
|
||||||
// ],
|
|
||||||
// 'title' => '点击' . $str . '用户',
|
|
||||||
// ]) ?>
|
|
||||||
<!-- </p>-->
|
|
||||||
<p>
|
<p>
|
||||||
<?= Html::a('禁用二步验证', ['user-totpoff', 'id' => $model->id], [
|
<?= Html::a('禁用二步验证', ['user-totpoff', 'id' => $model->id], [
|
||||||
'class' => 'btn btn-danger'.($model->is_otp_enabled == 0 ? ' disabled' : ''),
|
'class' => 'btn btn-danger' . ($model->is_otp_enabled == 0 ? ' disabled' : ''),
|
||||||
'data' => [
|
'data' => [
|
||||||
'confirm' => '你确定要取消这个用户的多因素登录吗?',
|
'confirm' => '你确定要取消这个用户的多因素登录吗?',
|
||||||
'method' => 'post',
|
'method' => 'post',
|
||||||
],
|
],
|
||||||
'title' => '点击取消用户的多因素登录',
|
'title' => '点击取消用户的多因素登录',
|
||||||
]) ?>
|
]) ?>
|
||||||
|
<?= Html::button('重置密码', [
|
||||||
|
'class' => 'btn btn-danger',
|
||||||
|
'data-bs-toggle' => 'modal',
|
||||||
|
'data-bs-target' => '#resetPasswordModal',
|
||||||
|
'title' => '点击重置用户密码',
|
||||||
|
]) ?>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
|
||||||
@ -66,7 +65,7 @@ FontAwesomeAsset::register($this);
|
|||||||
return $model->getGravatar(email: $model->email, s: 100, img: true);
|
return $model->getGravatar(email: $model->email, s: 100, img: true);
|
||||||
}],
|
}],
|
||||||
['attribute' => 'status', 'label' => '账户状态', 'format' => 'raw', 'value' => function ($model) {
|
['attribute' => 'status', 'label' => '账户状态', 'format' => 'raw', 'value' => function ($model) {
|
||||||
if(Yii::$app->user->id == $model->id){
|
if (Yii::$app->user->id == $model->id) {
|
||||||
return $model->status == 0 ? '禁用' : '启用';
|
return $model->status == 0 ? '禁用' : '启用';
|
||||||
}
|
}
|
||||||
return Editable::widget([
|
return Editable::widget([
|
||||||
@ -96,17 +95,17 @@ FontAwesomeAsset::register($this);
|
|||||||
return $model->last_login_ip;
|
return $model->last_login_ip;
|
||||||
}
|
}
|
||||||
}],
|
}],
|
||||||
['attribute' => 'bio', 'label' => '用户简介','format'=>'raw','value'=>function ($model) {
|
['attribute' => 'bio', 'label' => '用户简介', 'format' => 'raw', 'value' => function ($model) {
|
||||||
return Editable::widget([
|
return Editable::widget([
|
||||||
'name'=>'bio',
|
'name' => 'bio',
|
||||||
'asPopover' => true,
|
'asPopover' => true,
|
||||||
'displayValue' => '查看',
|
'displayValue' => '查看',
|
||||||
'inputType' => Editable::INPUT_TEXTAREA,
|
'inputType' => Editable::INPUT_TEXTAREA,
|
||||||
'value' => $model->bio,
|
'value' => $model->bio,
|
||||||
'header' => '用户简介',
|
'header' => '用户简介',
|
||||||
'submitOnEnter' => false,
|
'submitOnEnter' => false,
|
||||||
'size'=>'lg',
|
'size' => 'lg',
|
||||||
'options' => ['class'=>'form-control', 'rows'=>5]
|
'options' => ['class' => 'form-control', 'rows' => 5]
|
||||||
]);
|
]);
|
||||||
}],
|
}],
|
||||||
['attribute' => 'role', 'label' => '用户身份', 'value' => function ($model) {
|
['attribute' => 'role', 'label' => '用户身份', 'value' => function ($model) {
|
||||||
@ -155,6 +154,24 @@ FontAwesomeAsset::register($this);
|
|||||||
return FileSizeHelper::getUsedPercent($model->id) . '<br>' . FileSizeHelper::getFormatUserAllDirSize($model->id) . ' / ' . FileSizeHelper::formatMegaBytes($model->storage_limit);
|
return FileSizeHelper::getUsedPercent($model->id) . '<br>' . FileSizeHelper::getFormatUserAllDirSize($model->id) . ' / ' . FileSizeHelper::formatMegaBytes($model->storage_limit);
|
||||||
}],
|
}],
|
||||||
],
|
],
|
||||||
]) ?>
|
])
|
||||||
|
?>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
Modal::begin([
|
||||||
|
'title' => '<h4>重置密码</h4>',
|
||||||
|
'id' => 'resetPasswordModal',
|
||||||
|
'size' => 'modal-lg',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$form = ActiveForm::begin(['id' => 'reset-password-form', 'action' => ['admin/user-pwdreset'], 'method' => 'post']);
|
||||||
|
|
||||||
|
echo $form->field($model, 'id')->hiddenInput()->label(false);
|
||||||
|
echo $form->field($model, 'password')->passwordInput(['maxlength' => true, 'value' => ''])->label('新密码');
|
||||||
|
|
||||||
|
echo Html::submitButton('提交', ['class' => 'btn btn-primary']);
|
||||||
|
|
||||||
|
ActiveForm::end();
|
||||||
|
Modal::end();
|
||||||
|
?>
|
||||||
|
Loading…
Reference in New Issue
Block a user