# 第5章 管理员模块的开发
## 1、后台管理员登录
```
-- 管理员数据表
DROP TABLE IF EXISTS `shop_admin`;
CREATE TABLE IF NOT EXISTS `shop_admin`(
`adminid` INT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`adminuser` VARCHAR(32) NOT NULL DEFAULT '' COMMENT '管理员账号',
`adminpass` CHAR(32) NOT NULL DEFAULT '' COMMENT '管理员密码',
`adminemail` VARCHAR(50) NOT NULL DEFAULT '' COMMENT '管理员电子邮箱',
`logintime` INT UNSIGNED NOT NULL DEFAULT '0' COMMENT '登录时间',
`loginip` BIGINT NOT NULL DEFAULT '0' COMMENT '登录IP',
`createtime` INT UNSIGNED NOT NULL DEFAULT '0' COMMENT '创建时间',
PRIMARY KEY(`adminid`),
UNIQUE shop_admin_adminuser_adminpass(`adminuser`, `adminpass`),
UNIQUE shop_admin_adminuser_adminemail(`adminuser`, `adminemail`)
)ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `shop_admin`(adminuser,adminpass,adminemail,createtime) VALUES('admin', md5('123'), 'shop@imooc.com', UNIX_TIMESTAMP());
```
## 2、创建Form组件
> 提示:如果你正在你的应用程序中使用 Twitter Bootstrap CSS 你可以使用yii\bootstrap\ActiveForm 来代替 yii\widgets\ActiveForm。 前者继承自后者并在生成表单字段时使用 Bootstrap 特有的样式。
```
<?php
use yii\bootstrap\ActiveForm;
use yii\helpers\Html;
?>
...
<?php $form = ActiveForm::begin([
'fieldConfig' => [
'template' => '{error}{input}',
],
]); ?>
<div class="span4 box">
<div class="content-wrap">
<h6>慕课商城 - 后台管理</h6>
<?php echo $form->field($model, 'adminuser')->textInput(["class" => "span12", "placeholder" => "管理员账号"]); ?>
<?php echo $form->field($model, 'adminpass')->passwordInput(["class" => "span12", "placeholder" => "管理员密码"]); ?>
<a href="<?php echo yii\helpers\Url::to(['public/seekpassword']); ?>" class="forgot">忘记密码?</a>
<?php echo $form->field($model, 'rememberMe')->checkbox([
'id' => 'remember-me',
'template' => '<div class="remember">{input}<label for="remember-me">记住我</label></div>',
]); ?>
<?php echo Html::submitButton('登录', ["class" => "btn-glow primary login"]); ?>
</div>
</div>
<?php ActiveForm::end(); ?>
```
## 3、管理员登录和退出(账号密码校验、记住登录状态)
\modules\controllers\PublicController.php
```
public function actionLogin()
{
if (Yii::$app->session['admin']['isLogin'] == 1) {
return $this->redirect(['/admin/default/index']);
}
$this->layout = false;
$model = new Admin;
if (Yii::$app->request->isPost) { // Yii::$app->request
$post = Yii::$app->request->post();
if ($model->login($post)) {
$this->redirect(['default/index']);
Yii::$app->end();
}
}
return $this->render("login", ['model' => $model]);
}
public function actionLogout()
{
Yii::$app->session->removeAll();
if (!isset(Yii::$app->session['admin']['isLogin'])) {
$this->redirect(['public/login']);
Yii::$app->end();
}
$this->goback();
}
```
\modules\models\Admin.php
```
public function login($data)
{
$this->scenario = "login";
if ($this->load($data) && $this->validate()) {
//做点有意义的事
$lifetime = $this->rememberMe ? 24*3600 : 0;
$session = Yii::$app->session;
session_set_cookie_params($lifetime);
$session['admin'] = [
'adminuser' => $this->adminuser,
'isLogin' => 1,
];
$this->updateAll(['logintime' => time(), 'loginip' => ip2long(Yii::$app->request->userIP)], 'adminuser = :user', [':user' => $this->adminuser]);
return (bool)$session['admin']['isLogin'];
}
return false;
}
```
## 4、找回密码,发送邮件
\modules\controllers\PublicController.php
```
public function actionSeekpassword()
{
$this->layout = false;
$model = new Admin;
if (Yii::$app->request->isPost) {
$post = Yii::$app->request->post();
if ($model->seekPass($post)) {
Yii::$app->session->setFlash('info', '电子邮件已经发送成功,请查收');
}
}
return $this->render("seekpassword", ['model' => $model]);
```
\modules\models\Admin.php
```
public function seekPass($data)
{
$this->scenario = "seekpass";
if ($this->load($data) && $this->validate()) {
//做点有意义的事
$time = time();
$token = $this->createToken($data['Admin']['adminuser'], $time);
$mailer = Yii::$app->mailer->compose('seekpass', ['adminuser' => $data['Admin']['adminuser'], 'time' => $time, 'token' => $token]);
$mailer->setFrom("wbo86@126.com");
$mailer->setTo($data['Admin']['adminemail']);
$mailer->setSubject("慕课商城-找回密码");
if ($mailer->send()) {
return true;
}
}
return false;
}
public function createToken($adminuser, $time)
{
return md5(md5($adminuser).base64_encode(Yii::$app->request->userIP).md5($time));
}
```
\mail\seekpass.php
```
<p>尊敬的<?php echo $adminuser; ?>,您好:</p>
<p>您的找回密码链接如下:</p>
<?php
$url = Yii::$app->urlManager->createAbsoluteUrl(['admin/manage/mailchangepass', 'timestamp' => $time, 'adminuser' => $adminuser, 'token' => $token]);
?>
<p><a href="<?php echo $url; ?>"><?php echo $url; ?></a></p>
<p>该链接5分钟内有效,请勿传递给别人!</p>
<p>该邮件为系统自动发送,请勿回复!</p>
```
发送邮件配置项:
```
'mailer' => [
'class' => 'yii\swiftmailer\Mailer',
// send all mails to a file by default. You have to set
// 'useFileTransport' to false and configure a transport
// for the mailer to send real emails.
'useFileTransport' => false,
'transport' => [
'class' => 'Swift_SmtpTransport',
'host' => 'smtp.126.com',
'username' => '...@126.com',
'password' => '...',
'port' => '465',
'encryption' => 'ssl',
],
],
```
https://www.yiichina.com/doc/guide/2.0/tutorial-mailing
## 5、修改密码
\modules\controllers\ManageController.php
```
public function actionMailchangepass()
{
$this->layout = false;
$time = Yii::$app->request->get("timestamp");
$adminuser = Yii::$app->request->get("adminuser");
$token = Yii::$app->request->get("token");
$model = new Admin;
$myToken = $model->createToken($adminuser, $time);
if ($token != $myToken) {
$this->redirect(['public/login']);
Yii::$app->end();
}
if (time() - $time > 300) {
$this->redirect(['public/login']);
Yii::$app->end();
}
if (Yii::$app->request->isPost) {
$post = Yii::$app->request->post();
if ($model->changePass($post)) {
Yii::$app->session->setFlash('info', '密码修改成功');
}
}
$model->adminuser = $adminuser;
return $this->render("mailchangepass", ['model' => $model]);
}
```
\modules\models\Admin.php
```
public function changePass($data)
{
$this->scenario = "changepass";
if ($this->load($data) && $this->validate()) {
return (bool)$this->updateAll(['adminpass' => md5($this->adminpass)], 'adminuser = :user', [':user' => $this->adminuser]);
}
return false;
}
```
## 6、后台管理员列表
\modules\controllers\ManageController.php
```
use yii\data\Pagination;
...
public function actionManagers()
{
$this->layout = "layout1";
$model = Admin::find();
$count = $model->count();
$pageSize = Yii::$app->params['pageSize']['manage'];
$pager = new Pagination(['totalCount' => $count, 'pageSize' => $pageSize]);
$managers = $model->offset($pager->offset)->limit($pager->limit)->all();
return $this->render("managers", ['managers' => $managers, 'pager' => $pager]);
}
```
分页
```
<?php foreach($managers as $manager): ?>
<!-- row -->
<tr>
<td>
<?php echo $manager->adminid; ?>
</td>
<td>
<?php echo $manager->adminuser; ?>
</td>
<td>
<?php echo $manager->adminemail; ?>
</td>
<td>
<?php echo date('Y-m-d H:i:s', $manager->logintime); ?>
</td>
<td>
<?php echo long2ip($manager->loginip); ?>
</td>
<td>
<?php echo date("Y-m-d H:i:s", $manager->createtime); ?>
</td>
<td class="align-right">
<a href="<?php echo yii\helpers\Url::to(['manage/del', 'adminid' => $manager->adminid]) ?>">删除</a>
</td>
</tr>
<?php endforeach; ?>
<div class="pagination pull-right">
<?php echo yii\widgets\LinkPager::widget(['pagination' => $pager, 'prevPageLabel' => '‹', 'nextPageLabel' => '›']); ?>
</div>
```
## 7、添加管理员
```
public function actionReg()
{
$this->layout = 'layout1';
$model = new Admin;
if (Yii::$app->request->isPost) {
$post = Yii::$app->request->post();
if ($model->reg($post)) {
Yii::$app->session->setFlash('info', '添加成功');
} else {
Yii::$app->session->setFlash('info', '添加失败');
}
}
$model->adminpass = '';
$model->repass = '';
return $this->render('reg', ['model' => $model]);
}
```
\modules\controllers\ManageController.php
```
public function reg($data)
{
$this->scenario = 'adminadd';
if ($this->load($data) && $this->validate()) {
$this->adminpass = md5($this->adminpass);
if ($this->save(false)) {
return true;
}
return false;
}
return false;
}
```
\modules\views\manage\reg.php
```
<?php
if (Yii::$app->session->hasFlash('info')) {
echo Yii::$app->session->getFlash('info');
}
$form = ActiveForm::begin([
'options' => ['class' => 'new_user_form inline-input'],
'fieldConfig' => [
'template' => '<div class="span12 field-box">{label}{input}</div>{error}'
],
]);
?>
<?php echo $form->field($model, 'adminuser')->textInput(['class' => 'span9']); ?>
<?php echo $form->field($model, 'adminemail')->textInput(['class' => 'span9']); ?>
<?php echo $form->field($model, 'adminpass')->passwordInput(['class' => 'span9']); ?>
<?php echo $form->field($model, 'repass')->passwordInput(['class' => 'span9']); ?>
<div class="span11 field-box actions">
<?php echo Html::submitButton('创建', ['class' => 'btn-glow primary']); ?>
<span>或者</span>
<?php echo Html::resetButton('取消', ['class' => 'reset']); ?>
</div>
<?php ActiveForm::end(); ?>
```
\modules\models\Admin.php
```
public function reg($data)
{
$this->scenario = 'adminadd';
if ($this->load($data) && $this->validate()) {
$this->adminpass = md5($this->adminpass);
if ($this->save(false)) {
return true;
}
return false;
}
return false;
}
```
## 8、删除操作
```
public function actionDel()
{
$adminid = (int)Yii::$app->request->get("adminid");
if (empty($adminid)) {
$this->redirect(['manage/managers']);
}
$model = new Admin;
if ($model->deleteAll('adminid = :id', [':id' => $adminid])) {
Yii::$app->session->setFlash('info', '删除成功');
$this->redirect(['manage/managers']);
}
}
```