|
@@ -21,11 +21,19 @@ class InspectionAuth
|
|
|
protected $_user = null;
|
|
|
protected $_token = '';
|
|
|
protected $keeptime = 2592000;
|
|
|
- protected $allowFields = ['id', 'user_id', 'name', 'phone', 'supplier_id', 'audit_status', 'status'];
|
|
|
+ protected $requestUri = '';
|
|
|
+ protected $rules = [];
|
|
|
+ //默认配置
|
|
|
+ protected $config = [];
|
|
|
+ protected $options = [];
|
|
|
+ protected $allowFields = ['id', 'user_id', 'name', 'phone', 'supplier_id', 'audit_status', 'status', 'region_full', 'address'];
|
|
|
|
|
|
public function __construct($options = [])
|
|
|
{
|
|
|
- // 可扩展配置
|
|
|
+ if ($config = Config::get('inspection')) {
|
|
|
+ $this->config = array_merge($this->config, $config);
|
|
|
+ }
|
|
|
+ $this->options = array_merge($this->config, $options);
|
|
|
}
|
|
|
|
|
|
public static function instance($options = [])
|
|
@@ -37,7 +45,26 @@ class InspectionAuth
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * 初始化验货员身份(通过token)
|
|
|
+ * 兼容调用application模型的属性
|
|
|
+ *
|
|
|
+ * @param string $name
|
|
|
+ * @return mixed
|
|
|
+ */
|
|
|
+ public function __get($name)
|
|
|
+ {
|
|
|
+ return $this->_application ? $this->_application->$name : null;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 兼容调用application模型的属性
|
|
|
+ */
|
|
|
+ public function __isset($name)
|
|
|
+ {
|
|
|
+ return isset($this->_application) ? isset($this->_application->$name) : false;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 根据Token初始化验货员身份
|
|
|
* @param string $token
|
|
|
* @return bool
|
|
|
*/
|
|
@@ -49,49 +76,232 @@ class InspectionAuth
|
|
|
if ($this->_error) {
|
|
|
return false;
|
|
|
}
|
|
|
- $application = InspectionApplication::where('token', $token)
|
|
|
- ->where('audit_status', 2)
|
|
|
- ->where('status', 1)
|
|
|
- ->find();
|
|
|
+
|
|
|
+ if (!$token) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ $application = InspectionApplication::where([
|
|
|
+ 'token' => $token,
|
|
|
+ 'audit_status' => 2,
|
|
|
+ 'status' => 1
|
|
|
+ ])->where('token_expire_time', '>', time())->find();
|
|
|
+
|
|
|
if (!$application) {
|
|
|
- $this->setError('验货员未登录或未通过审核');
|
|
|
+ $this->setError('验货员未登录或登录已过期');
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ $user = User::get($application->user_id);
|
|
|
+ if (!$user) {
|
|
|
+ $this->setError('用户不存在');
|
|
|
return false;
|
|
|
}
|
|
|
+
|
|
|
+ if ($user->status != 1) {
|
|
|
+ $this->setError('用户已被禁用');
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
$this->_application = $application;
|
|
|
- $this->_user = User::get($application->user_id);
|
|
|
+ $this->_user = $user;
|
|
|
$this->_logined = true;
|
|
|
$this->_token = $token;
|
|
|
+
|
|
|
+ //初始化成功的事件
|
|
|
+ Hook::listen("inspection_init_successed", $this->_application);
|
|
|
+
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
+ * 验货员登录
|
|
|
+ * @param string $phone 手机号
|
|
|
+ * @param string $password 密码(实际项目中可能需要验证码等)
|
|
|
+ * @return bool
|
|
|
+ */
|
|
|
+ public function login($phone, $password = '')
|
|
|
+ {
|
|
|
+ $application = InspectionApplication::where([
|
|
|
+ 'phone' => $phone,
|
|
|
+ 'audit_status' => 2,
|
|
|
+ 'status' => 1
|
|
|
+ ])->find();
|
|
|
+
|
|
|
+ if (!$application) {
|
|
|
+ $this->setError('验货员不存在或未通过审核');
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ $user = User::get($application->user_id);
|
|
|
+ if (!$user) {
|
|
|
+ $this->setError('关联用户不存在');
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ if ($user->status != 1) {
|
|
|
+ $this->setError('用户已被禁用');
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 检查登录失败次数
|
|
|
+ if ($application->login_failure >= 10 && time() - $application->login_failure_time < 86400) {
|
|
|
+ $this->setError('登录失败次数过多,请24小时后重试');
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 验证密码
|
|
|
+ if ($password && $application->password != $this->getEncryptPassword($password, $application->salt)) {
|
|
|
+ $application->save(['login_failure' => $application->login_failure + 1, 'login_failure_time' => time()]);
|
|
|
+ $this->setError('密码错误');
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ //直接登录验货员
|
|
|
+ return $this->direct($application->user_id);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
* 直接登录验货员
|
|
|
* @param int $user_id
|
|
|
* @return bool
|
|
|
*/
|
|
|
public function direct($user_id)
|
|
|
{
|
|
|
- $application = InspectionApplication::where('user_id', $user_id)
|
|
|
- ->where('audit_status', 2)
|
|
|
- ->where('status', 1)
|
|
|
- ->find();
|
|
|
+ $application = InspectionApplication::where([
|
|
|
+ 'user_id' => $user_id,
|
|
|
+ 'audit_status' => 2,
|
|
|
+ 'status' => 1
|
|
|
+ ])->find();
|
|
|
+
|
|
|
if (!$application) {
|
|
|
$this->setError('验货员未通过审核');
|
|
|
return false;
|
|
|
}
|
|
|
- $token = Random::uuid();
|
|
|
- $expire = time() + $this->keeptime;
|
|
|
- $application->token = $token;
|
|
|
- $application->token_expiretime = $expire;
|
|
|
- $application->save();
|
|
|
- $this->_application = $application;
|
|
|
- $this->_user = User::get($application->user_id);
|
|
|
- $this->_logined = true;
|
|
|
- $this->_token = $token;
|
|
|
+
|
|
|
+ $user = User::get($application->user_id);
|
|
|
+ if (!$user) {
|
|
|
+ $this->setError('关联用户不存在');
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ Db::startTrans();
|
|
|
+ try {
|
|
|
+ $ip = request()->ip();
|
|
|
+ $time = time();
|
|
|
+ $token = Random::uuid();
|
|
|
+ $expire = $time + $this->keeptime;
|
|
|
+
|
|
|
+ //判断连续登录和最大连续登录
|
|
|
+ if ($application->login_time < \fast\Date::unixtime('day')) {
|
|
|
+ $application->successions = $application->login_time < \fast\Date::unixtime('day', -1) ? 1 : $application->successions + 1;
|
|
|
+ $application->max_successions = max($application->successions, $application->max_successions);
|
|
|
+ }
|
|
|
+
|
|
|
+ $application->prev_time = $application->login_time;
|
|
|
+ //记录本次登录的IP和时间
|
|
|
+ $application->login_ip = $ip;
|
|
|
+ $application->login_time = $time;
|
|
|
+ //重置登录失败次数
|
|
|
+ $application->login_failure = 0;
|
|
|
+ //设置token
|
|
|
+ $application->token = $token;
|
|
|
+ $application->token_expire_time = $expire;
|
|
|
+
|
|
|
+ $application->save();
|
|
|
+
|
|
|
+ $this->_application = $application;
|
|
|
+ $this->_user = $user;
|
|
|
+ $this->_logined = true;
|
|
|
+ $this->_token = $token;
|
|
|
+
|
|
|
+ //登录成功的事件
|
|
|
+ Hook::listen("inspection_login_successed", $this->_application);
|
|
|
+ Db::commit();
|
|
|
+ } catch (Exception $e) {
|
|
|
+ Db::rollback();
|
|
|
+ $this->setError($e->getMessage());
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 退出登录
|
|
|
+ * @return bool
|
|
|
+ */
|
|
|
+ public function logout()
|
|
|
+ {
|
|
|
+ if (!$this->_logined) {
|
|
|
+ $this->setError('未登录');
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ Db::startTrans();
|
|
|
+ try {
|
|
|
+ $this->_application->token = null;
|
|
|
+ $this->_application->token_expire_time = null;
|
|
|
+ $this->_application->save();
|
|
|
+
|
|
|
+ $this->_logined = false;
|
|
|
+ $this->_token = '';
|
|
|
+
|
|
|
+ //退出成功的事件
|
|
|
+ Hook::listen("inspection_logout_successed", $this->_application);
|
|
|
+ Db::commit();
|
|
|
+ } catch (Exception $e) {
|
|
|
+ Db::rollback();
|
|
|
+ $this->setError($e->getMessage());
|
|
|
+ return false;
|
|
|
+ }
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
+ * 修改密码
|
|
|
+ * @param string $newpassword 新密码
|
|
|
+ * @param string $oldpassword 旧密码
|
|
|
+ * @param bool $ignoreoldpassword 忽略旧密码
|
|
|
+ * @return boolean
|
|
|
+ */
|
|
|
+ public function changepwd($newpassword, $oldpassword = '', $ignoreoldpassword = false)
|
|
|
+ {
|
|
|
+ if (!$this->_logined) {
|
|
|
+ $this->setError('您尚未登录');
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ //判断旧密码是否正确
|
|
|
+ if ($this->_application->password == $this->getEncryptPassword($oldpassword, $this->_application->salt) || $ignoreoldpassword) {
|
|
|
+ Db::startTrans();
|
|
|
+ try {
|
|
|
+ $salt = Random::alnum();
|
|
|
+ $newpassword = $this->getEncryptPassword($newpassword, $salt);
|
|
|
+
|
|
|
+ // 更新验货员申请表的密码和salt
|
|
|
+ $this->_application->password = $newpassword;
|
|
|
+ $this->_application->salt = $salt;
|
|
|
+ $this->_application->login_failure = 0;
|
|
|
+ // 清除当前token,强制重新登录
|
|
|
+ $this->_application->token = null;
|
|
|
+ $this->_application->token_expire_time = null;
|
|
|
+ $this->_application->save();
|
|
|
+
|
|
|
+ //修改密码成功的事件
|
|
|
+ Hook::listen("inspection_changepwd_successed", $this->_application);
|
|
|
+ Db::commit();
|
|
|
+ } catch (Exception $e) {
|
|
|
+ Db::rollback();
|
|
|
+ $this->setError($e->getMessage());
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+ } else {
|
|
|
+ $this->setError('旧密码错误');
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
* 判断是否已登录
|
|
|
* @return bool
|
|
|
*/
|
|
@@ -128,50 +338,50 @@ class InspectionAuth
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * 获取供应商ID
|
|
|
- * @return int
|
|
|
+ * 获取验货员基本信息
|
|
|
*/
|
|
|
- public function getSupplierId()
|
|
|
+ public function getInspectorInfo()
|
|
|
{
|
|
|
- return $this->_application ? $this->_application->supplier_id : 0;
|
|
|
+ if (!$this->_application) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ $data = $this->_application->toArray();
|
|
|
+ $allowFields = $this->getAllowFields();
|
|
|
+ $inspectorInfo = array_intersect_key($data, array_flip($allowFields));
|
|
|
+
|
|
|
+ // 添加token信息
|
|
|
+ $inspectorInfo['token'] = $this->_token;
|
|
|
+ $inspectorInfo['token_expire_time'] = $this->_application->token_expire_time;
|
|
|
+
|
|
|
+ return $inspectorInfo;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * 退出登录
|
|
|
- * @return bool
|
|
|
+ * 获取供应商ID
|
|
|
+ * @return int
|
|
|
*/
|
|
|
- public function logout()
|
|
|
+ public function getSupplierId()
|
|
|
{
|
|
|
- if (!$this->_logined) {
|
|
|
- $this->setError('未登录');
|
|
|
- return false;
|
|
|
- }
|
|
|
- $this->_application->token = null;
|
|
|
- $this->_application->token_expiretime = null;
|
|
|
- $this->_application->save();
|
|
|
- $this->_logined = false;
|
|
|
- $this->_token = '';
|
|
|
- return true;
|
|
|
+ return $this->_application ? $this->_application->supplier_id : 0;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * 设置错误信息
|
|
|
- * @param string $error
|
|
|
- * @return $this
|
|
|
+ * 获取当前请求的URI
|
|
|
+ * @return string
|
|
|
*/
|
|
|
- public function setError($error)
|
|
|
+ public function getRequestUri()
|
|
|
{
|
|
|
- $this->_error = $error;
|
|
|
- return $this;
|
|
|
+ return $this->requestUri;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * 获取错误信息
|
|
|
- * @return string
|
|
|
+ * 设置当前请求的URI
|
|
|
+ * @param string $uri
|
|
|
*/
|
|
|
- public function getError()
|
|
|
+ public function setRequestUri($uri)
|
|
|
{
|
|
|
- return $this->_error;
|
|
|
+ $this->requestUri = $uri;
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -191,4 +401,94 @@ class InspectionAuth
|
|
|
{
|
|
|
$this->allowFields = $fields;
|
|
|
}
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 检测当前控制器和方法是否匹配传递的数组
|
|
|
+ *
|
|
|
+ * @param array $arr 需要验证权限的数组
|
|
|
+ * @return boolean
|
|
|
+ */
|
|
|
+ public function match($arr = [])
|
|
|
+ {
|
|
|
+ $request = Request::instance();
|
|
|
+ $arr = is_array($arr) ? $arr : explode(',', $arr);
|
|
|
+ if (!$arr) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ $arr = array_map('strtolower', $arr);
|
|
|
+ // 是否存在
|
|
|
+ if (in_array(strtolower($request->action()), $arr) || in_array('*', $arr)) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 没找到匹配
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 设置会话有效时间
|
|
|
+ * @param int $keeptime 默认为永久
|
|
|
+ */
|
|
|
+ public function keeptime($keeptime = 0)
|
|
|
+ {
|
|
|
+ $this->keeptime = $keeptime;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 设置初始密码
|
|
|
+ * @param string $password 密码
|
|
|
+ * @return boolean
|
|
|
+ */
|
|
|
+ public function setPassword($password)
|
|
|
+ {
|
|
|
+ if (!$this->_application) {
|
|
|
+ $this->setError('验货员信息不存在');
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ try {
|
|
|
+ $salt = Random::alnum();
|
|
|
+ $encryptPassword = $this->getEncryptPassword($password, $salt);
|
|
|
+
|
|
|
+ $this->_application->password = $encryptPassword;
|
|
|
+ $this->_application->salt = $salt;
|
|
|
+ $this->_application->save();
|
|
|
+
|
|
|
+ return true;
|
|
|
+ } catch (Exception $e) {
|
|
|
+ $this->setError($e->getMessage());
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取密码加密后的字符串
|
|
|
+ * @param string $password 密码
|
|
|
+ * @param string $salt 密码盐
|
|
|
+ * @return string
|
|
|
+ */
|
|
|
+ public function getEncryptPassword($password, $salt = '')
|
|
|
+ {
|
|
|
+ return md5(md5($password) . $salt);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 设置错误信息
|
|
|
+ * @param string $error
|
|
|
+ * @return $this
|
|
|
+ */
|
|
|
+ public function setError($error)
|
|
|
+ {
|
|
|
+ $this->_error = $error;
|
|
|
+ return $this;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取错误信息
|
|
|
+ * @return string
|
|
|
+ */
|
|
|
+ public function getError()
|
|
|
+ {
|
|
|
+ return $this->_error ? __($this->_error) : '';
|
|
|
+ }
|
|
|
}
|