AdminRepository.php 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334
  1. <?php
  2. namespace app\common\repositories\system\admin;
  3. //附件
  4. use app\common\dao\system\admin\AdminDao;
  5. use app\common\model\system\admin\Admin;
  6. use app\common\repositories\BaseRepository;
  7. use app\common\repositories\system\auth\RoleRepository;
  8. use ln\exceptions\AuthException;
  9. use ln\services\JwtTokenService;
  10. use FormBuilder\Exception\FormBuilderException;
  11. use FormBuilder\Factory\Elm;
  12. use FormBuilder\Form;
  13. use think\db\exception\DataNotFoundException;
  14. use think\db\exception\DbException;
  15. use think\db\exception\ModelNotFoundException;
  16. use think\exception\ValidateException;
  17. use think\facade\Cache;
  18. use think\facade\Config;
  19. use think\facade\Route;
  20. use think\Model;
  21. /**
  22. * Class BaseRepository
  23. * @package common\repositories
  24. * @mixin AdminDao
  25. */
  26. class AdminRepository extends BaseRepository
  27. {
  28. public function __construct(AdminDao $dao)
  29. {
  30. /**
  31. * @var AdminDao
  32. */
  33. $this->dao = $dao;
  34. }
  35. /**
  36. * @param array $where
  37. * @param $page
  38. * @param $limit
  39. * @return array
  40. * @throws DataNotFoundException
  41. * @throws DbException
  42. * @throws ModelNotFoundException
  43. * @author zfy
  44. * @day 2020-04-09
  45. */
  46. public function getList(array $where, $page, $limit)
  47. {
  48. $query = $this->dao->search($where);
  49. $count = $query->count();
  50. $list = $query->page($page, $limit)->hidden(['pwd', 'is_del', 'update_time'])->select();
  51. foreach ($list as $k => $role) {
  52. $list[$k]['rule_name'] = $role->roleNames();
  53. }
  54. return compact('list', 'count');
  55. }
  56. public function passwordEncode($password)
  57. {
  58. return password_hash($password, PASSWORD_BCRYPT);
  59. }
  60. /**
  61. * 更新
  62. * @param int $id id
  63. * @param array $data 数组
  64. * @return int
  65. * @throws DbException
  66. * @author 张先生
  67. * @date 2020-03-26
  68. */
  69. public function update(int $id, array $data)
  70. {
  71. if (isset($data['roles']))
  72. $data['roles'] = implode(',', $data['roles']);
  73. return $this->dao->update($id, $data);
  74. }
  75. /**
  76. * @param int $id
  77. * @param $isSelf
  78. * @return Form
  79. * @throws FormBuilderException
  80. * @author zfy
  81. * @day 2020-04-20
  82. */
  83. public function passwordForm(int $id, $isSelf = false)
  84. {
  85. $form = Elm::createForm(Route::buildUrl($isSelf ? 'systemAdminEditPassword' : 'systemAdminPassword', $isSelf ? [] : compact('id'))->build(), [
  86. $rules[] = Elm::password('pwd', '密码')->required(),
  87. $rules[] = Elm::password('againPassword', '确认密码')->required(),
  88. ]);
  89. return $form->setTitle('修改密码');
  90. }
  91. /**
  92. * @param array $formData
  93. * @return Form
  94. * @throws FormBuilderException
  95. * @author zfy
  96. * @day 2020-04-20
  97. */
  98. public function editForm(array $formData)
  99. {
  100. $form = Elm::createForm(Route::buildUrl('systemAdminEdit')->build());
  101. $form->setRule([
  102. Elm::input('real_name', '管理员姓名')->required(),
  103. Elm::input('phone', '联系电话')
  104. ]);
  105. return $form->setTitle('修改信息')->formData($formData);
  106. }
  107. /**
  108. * @param int|null $id
  109. * @param array $formData
  110. * @return Form
  111. * @throws FormBuilderException
  112. * @author zfy
  113. * @day 2020-04-08
  114. */
  115. public function form(?int $id = null, array $formData = []): Form
  116. {
  117. $form = Elm::createForm(is_null($id) ? Route::buildUrl('systemAdminCreate')->build() : Route::buildUrl('systemAdminUpdate', ['id' => $id])->build());
  118. $rules = [
  119. Elm::select('roles', '身份', [])->options(function () {
  120. $data = app()->make(RoleRepository::class)->getAllOptions(0);
  121. $options = [];
  122. foreach ($data as $value => $label) {
  123. $options[] = compact('value', 'label');
  124. }
  125. return $options;
  126. })->multiple(true),
  127. Elm::input('real_name', '管理员姓名'),
  128. Elm::input('account', '账号')->required(),
  129. Elm::input('phone', ' 联系电话'),
  130. ];
  131. if (!$id) {
  132. $rules[] = Elm::password('pwd', '密码')->required();
  133. $rules[] = Elm::password('againPassword', '确认密码')->required();
  134. }
  135. $rules[] = Elm::switches('status', '是否开启', 1)->inactiveValue(0)->activeValue(1)->inactiveText('关闭')->activeText('开启');
  136. $form->setRule($rules);
  137. return $form->setTitle(is_null($id) ? '添加管理员' : '编辑管理员')->formData($formData);
  138. }
  139. /**
  140. * @param int $id
  141. * @return Form
  142. * @throws DataNotFoundException
  143. * @throws DbException
  144. * @throws FormBuilderException
  145. * @throws ModelNotFoundException
  146. * @author zfy
  147. * @day 2020-04-09
  148. */
  149. public function updateForm(int $id)
  150. {
  151. return $this->form($id, $this->dao->get($id)->toArray());
  152. }
  153. /**
  154. * @param string $account
  155. * @param string $password
  156. * @return array|Model|null
  157. * @throws DataNotFoundException
  158. * @throws DbException
  159. * @throws ModelNotFoundException
  160. * @author zfy
  161. * @day 2020-04-10
  162. */
  163. public function login(string $account, string $password)
  164. {
  165. $adminInfo = $this->dao->accountByAdmin($account);
  166. if (!$adminInfo)
  167. throw new ValidateException('账号不存在');
  168. if ($adminInfo['status'] != 1)
  169. throw new ValidateException('账号已关闭');
  170. if (!password_verify($password, $adminInfo->pwd))
  171. $this->loginFailure($account);
  172. $adminInfo->last_time = date('Y-m-d H:i:s');
  173. $adminInfo->last_ip = app('request')->ip();
  174. $adminInfo->login_count++;
  175. $adminInfo->save();
  176. return $adminInfo;
  177. }
  178. /**
  179. * TODO 登录尝试次数限制
  180. * @param $account
  181. * @param int $number
  182. * @param int $n
  183. * @author Qinii
  184. * @day 7/6/21
  185. */
  186. public function loginFailure($account,$number = 5,$n = 3)
  187. {
  188. $key = 'sys_login_failuree_'.$account;
  189. $numb = Cache::get($key) ?? 0;
  190. $numb++;
  191. if($numb >= $number){
  192. $fail_key = 'sys_login_freeze_'.$account;
  193. Cache::set($fail_key,1,15*60);
  194. throw new ValidateException('账号或密码错误次数太多,请稍后在尝试');
  195. }else{
  196. Cache::set($key,$numb,5*60);
  197. $msg = '账号或密码错误';
  198. $_n = $number - $numb;
  199. if($_n <= $n){
  200. $msg .= ',还可尝试'.$_n.'次';
  201. }
  202. throw new ValidateException($msg);
  203. }
  204. }
  205. /**
  206. * @param string $token
  207. * @param int $exp
  208. * @author zfy
  209. * @day 2020-04-10
  210. */
  211. public function cacheToken(string $token, int $exp)
  212. {
  213. Cache::set('admin_' . $token, time() + $exp, $exp);
  214. }
  215. public function checkToken(string $token)
  216. {
  217. $has = Cache::has('admin_' . $token);
  218. if (!$has)
  219. throw new AuthException('无效的token');
  220. $lastTime = Cache::get('admin_' . $token);
  221. if (($lastTime + (intval(Config::get('admin.token_valid_exp', 15))) * 60) < time())
  222. throw new AuthException('token 已过期');
  223. }
  224. public function updateToken(string $token)
  225. {
  226. Cache::set('admin_' . $token, time(), intval(Config::get('admin.token_valid_exp', 15)) * 60);
  227. }
  228. public function clearToken(string $token)
  229. {
  230. Cache::delete('admin_' . $token);
  231. }
  232. /**
  233. * @param Admin $admin
  234. * @return array
  235. * @author zfy
  236. * @day 2020-04-09
  237. */
  238. public function createToken(Admin $admin)
  239. {
  240. $service = new JwtTokenService();
  241. $exp = intval(Config::get('admin.token_exp', 3));
  242. $token = $service->createToken($admin->admin_id, 'admin', strtotime("+ {$exp}hour"));
  243. $this->cacheToken($token['token'], $token['out']);
  244. return $token;
  245. }
  246. /**
  247. * 检测验证码
  248. * @param string $key key
  249. * @param string $code 验证码
  250. * @author 张先生
  251. * @date 2020-03-26
  252. */
  253. public function checkCode(string $key, string $code)
  254. {
  255. $_code = Cache::get('am_captcha' . $key);
  256. if (!$_code) {
  257. throw new ValidateException('验证码过期');
  258. }
  259. if (strtolower($_code) != strtolower($code)) {
  260. throw new ValidateException('验证码错误');
  261. }
  262. //删除code
  263. Cache::delete('am_captcha' . $key);
  264. }
  265. /**
  266. * @param string $code
  267. * @return string
  268. * @author zfy
  269. * @day 2020-04-09
  270. */
  271. public function createLoginKey(string $code)
  272. {
  273. $key = uniqid(microtime(true), true);
  274. Cache::set('am_captcha' . $key, $code, Config::get('admin.captcha_exp', 5) * 60);
  275. return $key;
  276. }
  277. /**
  278. * TODO 命令行重置密码
  279. * @param $name
  280. * @param $pwd
  281. * @author Qinii
  282. * @day 6/19/21
  283. */
  284. public function resetPwd($name,$pwd)
  285. {
  286. $account = $this->dao->accountByAdmin($name);
  287. if(!$account) {
  288. echo '管理员账号不存在';
  289. }else{
  290. $pwd_ = $this->passwordEncode($pwd);
  291. $account->pwd = $pwd_;
  292. $account->save();
  293. echo '账号:'.$name.';密码已重置:'.$pwd;
  294. }
  295. }
  296. }