# 第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']);
}
}
```