Admin.php 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362
  1. <?php
  2. namespace common\models\backend;
  3. use backend\models\AdminRole;
  4. use common\enums\StatusEnum;
  5. use common\helpers\Auth;
  6. use common\models\base\BaseActiveRecord;
  7. use common\models\base\User;
  8. use common\models\mall\Mall;
  9. use common\models\rbac\AuthAssignment;
  10. use Exception;
  11. use Yii;
  12. use yii\web\IdentityInterface;
  13. use yii\base\Model;
  14. /**
  15. * This is the model class for table "{{%admin}}".
  16. *
  17. * @property int $id ID
  18. * @property string $account 用户名
  19. * @property string $username 用户名
  20. * @property string $password 密码
  21. * @property string $auth_key
  22. * @property int $mall_id
  23. * @property int $mch_id
  24. * @property int $store_id
  25. * @property string $access_token
  26. * @property int $admin_type 管理员类型1超级管理员2管理员3操作员
  27. * @property int $mall_num
  28. * @property int $remark
  29. * @property int $is_default 是否删除
  30. * @property int $expired_at 过期时间
  31. * @property int $created_at 创建时间
  32. * @property int $updated_at 更新时间
  33. * @property int $status 状态
  34. * @property int $source 来源类型:0:默认;1:注册
  35. * @property int $view_times 商城浏览时长
  36. * @property int $addons_view_times 应用浏览时长
  37. * @property int $reference_id 推荐人id
  38. *
  39. */
  40. class Admin extends User
  41. {
  42. const ADMIN_TYPE_SUPER = 1; // 超级管理员
  43. const ADMIN_TYPE_AGENT = 2; // 管理员(代理商新增商城等操作)
  44. const ADMIN_TYPE_OPERATE = 3; // 操作员(登录至商城)
  45. /**
  46. * {@inheritdoc}
  47. */
  48. public static function tableName()
  49. {
  50. return '{{%admin}}';
  51. }
  52. /**
  53. * {@inheritdoc}
  54. */
  55. public function rules()
  56. {
  57. return [
  58. [['username', 'account','password', 'admin_type'], 'required'],
  59. [['admin_type','mall_id','mch_id', 'is_default', 'mall_num', 'expired_at', 'created_at','status', 'updated_at','store_id','source','view_times','addons_view_times','reference_id','mobile'], 'integer'],
  60. [['password', 'auth_key','access_token','account','remark'], 'string'],
  61. [['username'], 'string', 'max' => 50],
  62. ];
  63. }
  64. /**
  65. * {@inheritdoc}
  66. */
  67. public function attributeLabels()
  68. {
  69. return [
  70. 'id' => 'ID',
  71. 'username' => '用户名',
  72. 'password' => '密码',
  73. 'mall_id' => '商城id',
  74. 'mch_id' => '商户id',
  75. 'store_id' => '门店id',
  76. 'auth_key' => '',
  77. 'access_token' => '',
  78. 'admin_type' => '管理员类型',
  79. 'mall_num' => '商城数量',
  80. 'is_default' => '是否默认',
  81. 'expired_at' => '过期时间',
  82. 'created_at' => '创建时间',
  83. 'updated_at' => '更新时间',
  84. 'status' => '更新时间',
  85. 'source' => '来源类型:0:默认;1:注册',
  86. 'view_times' => '商城浏览时长',
  87. 'addons_view_times' => '应用浏览时长',
  88. 'reference_id' => '推荐人id',
  89. 'mobile' => '手机号',
  90. ];
  91. }
  92. /**YII登录机制实现接口 */
  93. public static function findIdentity($id)
  94. {
  95. return static::findOne($id);
  96. }
  97. public static function findIdentityByAccessToken($token, $type = null)
  98. {
  99. return static::findOne(['access_token' => $token]);
  100. }
  101. public function getId()
  102. {
  103. return $this->id;
  104. }
  105. public function getAuthKey()
  106. {
  107. return $this->auth_key;
  108. }
  109. public function validateAuthKey($authKey)
  110. {
  111. return $this->getAuthKey() === $authKey;
  112. }
  113. public function validatePassword($password)
  114. {
  115. return Yii::$app->security->validatePassword($password, $this->password);
  116. }
  117. /**YII登录机制实现接口 */
  118. /**
  119. * 关联授权角色
  120. *
  121. * @return \yii\db\ActiveQuery
  122. */
  123. public function getAssignment()
  124. {
  125. return $this->hasOne(AuthAssignment::class, ['user_id' => 'id'])
  126. ->where(['app_id' => Yii::$app->id]);
  127. }
  128. public function getMall()
  129. {
  130. return $this->hasMany(Mall::class, ['admin_id' => 'id']);
  131. }
  132. /**
  133. * 管理员登录
  134. * @Author bing
  135. * @DateTime 2021-08-12 19:12:55
  136. * @return void
  137. * @copyright: Copyright (c) 2020 广东七件事集团
  138. */
  139. public static function login($params)
  140. {
  141. try {
  142. $username = $params['username'] ?? '';
  143. $password = $params['password'] ?? '';
  144. $where = ['status' => StatusEnum::ENABLED, 'username' => $username];
  145. if (!empty($params['new_mall_id'])) {
  146. $where['mall_id'] = $params['new_mall_id'];
  147. }
  148. $admin = Admin::findOne($where);
  149. if($admin['expired_at']>0&&$admin['expired_at']<=time()) throw new Exception('您的账号已过期');
  150. if(empty($admin)) throw new Exception('登录账号不存在');
  151. $admin_type = $admin->admin_type;
  152. $mall_id = $admin['mall_id'] ?? 0;
  153. if(
  154. in_array($admin_type,[self::ADMIN_TYPE_SUPER,self::ADMIN_TYPE_AGENT]) && $params['login_type']!=Yii::$app->params['login_type'] ||
  155. in_array($admin_type,[self::ADMIN_TYPE_OPERATE]) && $params['login_type']==Yii::$app->params['login_type']
  156. ) {
  157. throw new Exception('登录网址错误');
  158. }
  159. // 密码校验
  160. if (!$admin || !$admin->validatePassword($password)) throw new Exception('登录账号或密码错误');
  161. // 管理员类型处理
  162. switch ($admin_type) {
  163. case self::ADMIN_TYPE_SUPER:
  164. $redirect_url = 'admin/mall/wraparound';
  165. break;
  166. case self::ADMIN_TYPE_AGENT:
  167. $redirect_url = 'admin/mall/wraparound';
  168. if ($admin->expired_at !== 0 && time() > $admin->expired_at) throw new \Exception('账户已过期!请联系管理员');
  169. break;
  170. case self::ADMIN_TYPE_OPERATE:
  171. $redirect_url = 'mall/overview/index';
  172. //$mall = Mall::findOne($mall_id);
  173. $mall = Mall::getOne([['id' => $mall_id]],true);
  174. Yii::$app->session->set('mall', $mall);
  175. if (empty($mall)) throw new \Exception('未找到商城');
  176. if ($mall['expired_at'] != 0 && $mall['expired_at'] < time()) {
  177. $phone = Yii::$app->services->setting->platform->get('system.contact_tel');
  178. $msg = sprintf('商城已过期,请联系客服进行续费(或联系客服电话:%s)', $phone);
  179. throw new \Exception($msg);
  180. }
  181. break;
  182. default:
  183. throw new \Exception('未知账号类型');
  184. }
  185. // 执行登录
  186. $config_params = Yii::$app->params;
  187. $mall_login_remember_time = $config_params['mall_login_remember_time'] ?? 86400 * 30;
  188. $mall_login_no_remember_time = $config_params['mall_login_no_remember_time'] ?? 3600 * 8;
  189. if (Yii::$app->user->login($admin, $params['is_remember'] == 'true' ? $mall_login_remember_time : $mall_login_no_remember_time)) {
  190. if($admin_type == self::ADMIN_TYPE_OPERATE){
  191. $auths = Auth::getAuth();
  192. if($auths && !in_array($redirect_url,$auths)){
  193. $auths = array_values(array_filter($auths));
  194. $cond = [['pid' => 0], ['<>','status',StatusEnum::DELETE]];
  195. $cond[] = ['is_addon' => 0, 'cate_id' => 2];
  196. $menus = Menu::getMenus($cond, [], true,'id, url');
  197. $menusMap = array_column($menus,'id', 'url');
  198. $menus = array_column($menus,'url');
  199. $intersect = array_intersect($auths,$menus);
  200. $intersect = array_values($intersect);
  201. $redirect_url = $intersect ? $intersect[0] : $redirect_url;
  202. // 兼容例如 mall/diy的url
  203. if ($intersect && isset($menusMap[$intersect[0]]) && count(explode('/', $redirect_url)) < 3) {
  204. $childMenus = Menu::getMenus([
  205. ['pid' => $menusMap[$intersect[0]]],
  206. ['<>','status',StatusEnum::DELETE],
  207. ['is_addon' => 0, 'cate_id' => 2]
  208. ], [], true,'url');
  209. $childMenus = array_column($childMenus,'url');
  210. $intersect = array_values(array_intersect($auths, $childMenus));
  211. $intersect && $redirect_url = $intersect[0];
  212. }
  213. }
  214. }
  215. return compact('redirect_url');
  216. } else {
  217. throw new \Exception('登录失败');
  218. }
  219. } catch (Exception $e) {
  220. self::setStaticError($e->getMessage());
  221. return false;
  222. }
  223. }
  224. /**
  225. * 添加管理员
  226. * @param array $params
  227. * @return bool|Admin
  228. */
  229. public static function setData(array $params)
  230. {
  231. $tr = \Yii::$app->db->beginTransaction();
  232. try {
  233. if (!empty($params['id'])) {
  234. $where = ['id' => $params['id'], ['status' => StatusEnum::ENABLED]];
  235. if (isset($params['mall_id'])) $where[] = ['mall_id' => $params['mall_id']];
  236. $model = self::findOne($where);
  237. if (empty($model)) throw new Exception('服务不存在或已删除');
  238. } else {
  239. $model = new self();
  240. $model->loadDefaultValues();
  241. $model->auth_key = Yii::$app->security->generateRandomString();
  242. }
  243. if(!empty($params['password'])){
  244. $params['password'] = Yii::$app->security->generatePasswordHash($params['password']);
  245. $params['auth_key'] = Yii::$app->security->generateRandomString();
  246. }else{
  247. unset($params['password']);
  248. }
  249. if(!empty($params['expired_at'])) $params['expired_at'] = strtotime($params['expired_at']);
  250. if (!$model->load($params, '') || !$model->save()) throw new \PHPUnit\Util\Exception($model->getErrorMessage());
  251. if(!empty($params['role_id'])){
  252. $res = AdminRole::setData(['id' => $params['admin_role_id'], 'role_id' => $params['role_id'], 'admin_id' => $model->id]);
  253. if ($res === false) throw new Exception(AdminRole::getStaticError());
  254. }
  255. if(!empty($params['admin_type'])&&$params['admin_type']==1){
  256. $res = AdminRole::findOne(['admin_id' => $model->id]);
  257. if(!empty($res))$res->delete();
  258. }
  259. $tr->commit();
  260. return $model;
  261. } catch (Exception $e) {
  262. $tr->rollBack();
  263. self::$static_error = $e->getMessage();
  264. return false;
  265. }
  266. }
  267. /**
  268. * 检测参数数据
  269. * @Author: 广东七件事 zal
  270. * @Date: 2020-04-08
  271. * @Time: 19:49
  272. * @param $arr
  273. * @param $data
  274. * @throws \Exception
  275. */
  276. private static function checkData($arr, $data)
  277. {
  278. foreach ($arr as $key => $item) {
  279. if (!isset($data[$key])) {
  280. throw new \Exception('请传参数' . $key . '->' . $item);
  281. }
  282. }
  283. }
  284. public static function isSuperAdmin($id)
  285. {
  286. $res = self::findOne($id);
  287. if (empty($res)) return false;
  288. if ($res->admin_type == self::ADMIN_TYPE_SUPER) return true;
  289. return false;
  290. }
  291. public static function del($params){
  292. $tr = \Yii::$app->db->beginTransaction();
  293. try {
  294. $model = self::findOne($params);
  295. $model->status = StatusEnum::DELETE;
  296. if($model->admin_type=='1'&& $model->username=='admin') throw new Exception('超级管理员不允许删除');
  297. $res = $model->save();
  298. if ($res === false) throw new Exception(self::getStaticError());
  299. $res = AdminRole::deleteAll(['admin_id'=>$params['id']]);
  300. if ($res === false) throw new Exception(AdminRole::getStaticError());
  301. $tr->commit();
  302. return $model;
  303. }catch (Exception $e){
  304. $tr->rollBack();
  305. self::$static_error = $e->getMessage();
  306. return false;
  307. }
  308. }
  309. /**
  310. * mall_id获取默认商城管理员
  311. *
  312. * @param integer $mall_id
  313. * @return self|null
  314. */
  315. public static function getDefaultByMallId(int $mall_id)
  316. {
  317. return static::find()
  318. ->where(['mall_id' => $mall_id, 'is_default' => 1])
  319. ->one();
  320. }
  321. /**
  322. * 设置新密码
  323. *
  324. * @param string $password
  325. * @return boolean
  326. */
  327. public function setNewPassword(string $password)
  328. {
  329. $this->password = Yii::$app->security->generatePasswordHash($password);
  330. return $this->save();
  331. }
  332. }