AdminController.php 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339
  1. <?php
  2. namespace frontend\controllers;
  3. use Yii;
  4. use frontend\models\Admin;
  5. use frontend\models\Role;
  6. use frontend\models\AdminRole;
  7. class AdminController extends BaseController
  8. {
  9. /**
  10. * 在N秒内登录失败锁定
  11. */
  12. public $loginFailureWithinTime = 1800;
  13. /**
  14. * 登录N次后锁定
  15. * @var int
  16. */
  17. public $loginFailureLockCount = 5;
  18. /**
  19. * 登录若干次后锁定N秒
  20. * @var int
  21. */
  22. public $loginFailureLockTime = 1800;
  23. /**
  24. * 管理员列表
  25. */
  26. public function actionList()
  27. {
  28. $post = Yii::$app->request->post();
  29. $searchBy = isset($post['searchBy']) ? trim($post['searchBy']) : '';
  30. $keyword = isset($post['keyword']) ? trim($post['keyword']) : '';
  31. $pageSize = isset($post['pageSize']) && intval($post['pageSize']) > 0 ? intval($post['pageSize']) : 20;
  32. $pageNumber = isset($post['pageNumber']) ? $post['pageNumber'] : 1;
  33. $orderBy = isset($post['orderBy']) ? $post['orderBy'] : '';
  34. $order = isset($post['order']) ? $post['order'] : '';
  35. $where = ['and'];
  36. if ($keyword) {
  37. if ($searchBy == 'username') {
  38. $where[] = ['like', 'username', $keyword];
  39. } elseif ($searchBy == 'email') {
  40. $where[] = ['like', 'email', $keyword];
  41. }
  42. }
  43. $query = Admin::find()->where($where);
  44. $offset = $pageSize * ($pageNumber - 1);
  45. $query->offset($offset)->limit($pageSize);
  46. $totalCount = $query->count();
  47. $pageCount = ceil($totalCount / $pageSize);
  48. $data = [
  49. 'totalCount' => $totalCount,
  50. 'pageCount' => $pageCount,
  51. 'dataList' => [],
  52. ];
  53. if ($totalCount) {
  54. // 排序
  55. $allowOrderColumn = ['username', 'email', 'login_date', 'login_ip'];
  56. if (in_array($order, $allowOrderColumn) && in_array($orderBy, ['asc', 'desc'])) {
  57. if ($orderBy == 'asc') {
  58. $orderCondition = [$order => SORT_ASC];
  59. } else {
  60. $orderCondition = [$order => SORT_DESC];
  61. }
  62. } else {
  63. $orderCondition = ['id' => SORT_DESC];
  64. }
  65. $dataList = $query->orderBy($orderCondition)->asArray()->all();
  66. foreach ($dataList as $k => $v) {
  67. $status = '';
  68. if ($v['is_account_enabled'] && !$v['is_account_locked'] && !$v['is_account_expired'] && !$v['is_credentials_expired']) {
  69. $status = '正常';
  70. } elseif (!$v['is_account_enabled']) {
  71. $status = '未启用';
  72. } elseif ($v['is_account_locked']) {
  73. $status = '已锁定';
  74. } elseif ($v['is_account_expired']) {
  75. $status = '已过期';
  76. } elseif ($v['is_credentials_expired']) {
  77. $status = '凭证过期';
  78. }
  79. $dataList[$k]['status'] = $status;
  80. }
  81. $data['dataList'] = $dataList;
  82. return $this->outJson(1, $data);
  83. } else {
  84. return $this->outJson(1, $data, '没有数据');
  85. }
  86. }
  87. /**
  88. * 添加管理员
  89. */
  90. public function actionAdd()
  91. {
  92. $post = Yii::$app->request->post();
  93. $attributes['Admin']['username'] = isset($post['username']) ? $post['username'] : '';
  94. $attributes['Admin']['password'] = isset($post['password']) ? $post['password'] : '';
  95. $attributes['Admin']['email'] = isset($post['email']) ? $post['email'] : '';
  96. $attributes['Admin']['is_account_enabled'] = !empty($post['is_account_enabled']) ? true : false;
  97. $attributes['Admin']['department'] = isset($post['department']) ? $post['department'] : '';
  98. $attributes['Admin']['name'] = isset($post['name']) ? $post['name'] : '';
  99. $attributes['Admin']['description'] = isset($post['description']) ? $post['description'] : '';
  100. $code = 0;
  101. // 校验数据
  102. $admin = Admin::find()->where(['username' => $attributes['Admin']['username']])->limit(1)->asArray()->one();
  103. if ($admin) {
  104. return $this->outJson($code);
  105. }
  106. if (empty($post['role_id']) || !is_numeric($post['role_id'])) {
  107. return $this->outJson($code);
  108. }
  109. $role = Role::find()->where(['id' => $post['role_id']])->limit(1)->asArray()->one();
  110. if (!$role) {
  111. return $this->outJson($code);
  112. }
  113. $model = new Admin();
  114. $model->load($attributes);
  115. if ($model->validate()) {
  116. $datetime = date('Y-m-d H:i:s');
  117. $model->create_date = $datetime;
  118. $model->modify_date = $datetime;
  119. $model->password = Admin::hash($model->password);
  120. $result = $model->save();
  121. if ($result) {
  122. $adminRoleModel = new AdminRole();
  123. $adminRoleModel->admin_set_id = $model->id;
  124. $adminRoleModel->role_set_id = $role['id'];
  125. $adminRoleModel->save();
  126. $code = 1;
  127. }
  128. }
  129. return $this->outJson($code);
  130. }
  131. /**
  132. * 检查用户名
  133. */
  134. public function actionCheckUsername()
  135. {
  136. $username = trim(Yii::$app->request->post('username'));
  137. $count = Admin::find()->where(['username' => $username])->count();
  138. $code = $count ? 1 : 0;
  139. return $this->outJson($code);
  140. }
  141. /**
  142. * 某个管理员
  143. */
  144. public function actionGetAdminById()
  145. {
  146. $id = (int) Yii::$app->request->post('id');
  147. if (!$id) {
  148. return $this->outJson(0, [], '参数错误');
  149. }
  150. $admin = Admin::find()->where(['id' => $id])->limit(1)->asArray()->one();
  151. if (!$admin) {
  152. return $this->outJson(0, [], '没有该管理员');
  153. }
  154. $adminRole = AdminRole::find()->where(['admin_set_id' => $id])->limit(1)->asArray()->one();
  155. $admin['role_id'] = $adminRole ? $adminRole['role_set_id'] : 0;
  156. return $this->outJson(1, $admin);
  157. }
  158. /**
  159. * 编辑管理员
  160. */
  161. public function actionEdit()
  162. {
  163. $post = Yii::$app->request->post();
  164. $attributes['Admin']['id'] = isset($post['id']) ? $post['id'] : '';
  165. $attributes['Admin']['username'] = isset($post['username']) ? $post['username'] : '';
  166. $attributes['Admin']['password'] = isset($post['password']) ? $post['password'] : '';
  167. $attributes['Admin']['email'] = isset($post['email']) ? $post['email'] : '';
  168. $attributes['Admin']['is_account_enabled'] = !empty($post['is_account_enabled']) ? true : false;
  169. $attributes['Admin']['department'] = isset($post['department']) ? $post['department'] : '';
  170. $attributes['Admin']['name'] = isset($post['name']) ? $post['name'] : '';
  171. $attributes['Admin']['description'] = isset($post['description']) ? $post['description'] : '';
  172. $code = 0;
  173. // 校验管理员
  174. $model = Admin::find()->where(['id' => $attributes['Admin']['id']])->limit(1)->one();
  175. if (!$model) {
  176. return $this->outJson($code);
  177. }
  178. // 检查角色
  179. if (empty($post['role_id']) || !is_numeric($post['role_id'])) {
  180. return $this->outJson($code);
  181. }
  182. $role = Role::find()->where(['id' => $post['role_id']])->limit(1)->asArray()->one();
  183. if (!$role) {
  184. return $this->outJson($code);
  185. }
  186. if (!empty($attributes['Admin']['password'])) {
  187. $attributes['Admin']['password'] = Admin::hash($attributes['Admin']['password']);
  188. } else {
  189. $attributes['Admin']['password'] = $model->password;
  190. }
  191. $model->load($attributes);
  192. if ($model->validate()) {
  193. $datetime = date('Y-m-d H:i:s');
  194. $model->modify_date = $datetime;
  195. $result = $model->save();
  196. if ($result) {
  197. $adminRoleModel = AdminRole::find()->where(['admin_set_id' => $model->id])->limit(1)->one();
  198. if (!$adminRoleModel) {
  199. $adminRoleModel = new AdminRole();
  200. }
  201. $adminRoleModel->admin_set_id = $model->id;
  202. $adminRoleModel->role_set_id = $role['id'];
  203. $adminRoleModel->save();
  204. $code = 1;
  205. }
  206. }
  207. return $this->outJson($code);
  208. }
  209. /**
  210. * 登录
  211. */
  212. public function actionLogin()
  213. {
  214. $username = trim(Yii::$app->request->post('username'));
  215. $password = trim(Yii::$app->request->post('password'));
  216. $login_ip = trim(Yii::$app->request->post('login_ip'));
  217. $query = Admin::find()->where(['username' => $username])->limit(1);
  218. $model = $query->one();
  219. if (!$model) {
  220. return $this->outJson(0, [], '您的用户名或密码错误');
  221. }
  222. // 同一个ip在半个小时内密码错误5次以上则锁定半个小时,所以要判断login_ip login_date login_failure_count三个字段的值
  223. $login_time = strtotime($model->login_date); // $model->login_date可能会为null,所以要先判断一下
  224. if (Yii::$app->params['admin_login_lock'] && $login_ip == $model->login_ip && $login_time && time() - $login_time < $this->loginFailureWithinTime && $model->login_failure_count >= $this->loginFailureLockCount) {
  225. $model->is_account_locked = true;
  226. $model->save();
  227. } elseif ($model->is_account_locked) {
  228. // 解锁并清零
  229. $model->is_account_locked = false;
  230. $model->login_failure_count = 0;
  231. $model->save();
  232. }
  233. if (!$model->is_account_enabled) {
  234. return $this->outJson(0, [], '您的账号已被禁用,无法登录!');
  235. } elseif ($model->is_account_expired) {
  236. return $this->outJson(0, [], '您的账号已过期,无法登录!');
  237. } elseif ($model->is_account_locked) {
  238. return $this->outJson(0, [], '您的账号已被锁定,无法登录!');
  239. } elseif ($model->is_credentials_expired) {
  240. return $this->outJson(0, [], '您的账号凭证已过期,无法登录!');
  241. }
  242. if (Admin::hash($password) != $model->password) {
  243. $model->login_failure_count = intval($model->login_failure_count) + 1;
  244. $model->login_date = date('Y-m-d H:i:s');
  245. $model->login_ip = $login_ip;
  246. $model->save();
  247. return $this->outJson(0, [], '您的用户名或密码错误!');
  248. }
  249. $model->login_failure_count = 0;
  250. $model->login_date = date('Y-m-d H:i:s');
  251. $model->login_ip = $login_ip;
  252. $model->save();
  253. return $this->outJson(1, $model->toArray());
  254. }
  255. /**
  256. * 修改密码
  257. */
  258. public function actionUpdatePassword()
  259. {
  260. $id = (int) Yii::$app->request->post('id');
  261. $currentPassword = trim(Yii::$app->request->post('currentPassword')); // 当前密码
  262. $newPassword = trim(Yii::$app->request->post('newPassword')); // 新密码
  263. if (strlen($newPassword) < 6 || strlen($newPassword) > 20) {
  264. return $this->outJson(0, [], '新密码必须大于6位并小于20位');
  265. }
  266. $query = Admin::find()->where(['id' => $id])->limit(1);
  267. $model = $query->one();
  268. if (!$model) {
  269. return $this->outJson(0, [], '没有该用户');
  270. }
  271. // 校验用户输入的原密码是否正确
  272. if (Admin::hash($currentPassword) != $model->password) {
  273. return $this->outJson(0, [], '原密码错误');
  274. }
  275. // 加密后保存
  276. $model->password = Admin::hash($newPassword);
  277. $model->modify_date = date('Y-m-d H:i:s');
  278. $model->save();
  279. return $this->outJson(1, $model->toArray());
  280. }
  281. /**
  282. * 获取通用信息
  283. * @return array
  284. */
  285. public function actionGetCommonInfo()
  286. {
  287. $db_version = Yii::$app->db->getDriverName() . ' ' . Yii::$app->db->createCommand('SELECT VERSION()')->queryScalar();
  288. $data = [
  289. 'db_version' => $db_version,
  290. ];
  291. return $this->outJson(1, $data);
  292. }
  293. }