ThinkAdmin/app/data/service/UserService.php
2020-11-24 18:24:54 +08:00

139 lines
5.0 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace app\data\service;
use think\admin\Service;
/**
* 用户数据接口服务
* Class UserService
* @package app\store\service
*/
class UserService extends Service
{
/**
* 认证有效时间
* @var integer
*/
private $expire = 3600;
/**
* 获取用户数据
* @param string $type 接口类型
* @param integer $uuid 用户UID
* @return array
* @throws \think\Exception
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function get(string $type, int $uuid)
{
$user = $this->app->db->name('DataUser')->where(['id' => $uuid, 'deleted' => 0])->findOrEmpty();
$data = $this->app->db->name('DataUserToken')->where(['uid' => $uuid, 'type' => $type])->findOrEmpty();
[$state, $message] = $this->checkUserToken($type, $data['token'] ?? '', $data);
if (empty($state)) throw new \think\Exception($message);
unset($user['deleted'], $user['password']);
$user['token'] = ['token' => $data['token'], 'expire' => $data['time']];
return $user;
}
/**
* 更新用户用户参数
* @param array $map 查询条件
* @param array $data 更新数据
* @param string $type 接口类型
* @param boolean $force 强刷令牌
* @return array
* @throws \think\Exception
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function save(array $map, array $data, string $type, bool $force = false): array
{
unset($data['id'], $data['deleted'], $data['create_at']);
if ($uuid = $this->app->db->name('DataUser')->where($map)->where(['deleted' => 0])->value('id')) {
if (!empty($data)) {
$map = ['id' => $uuid, 'deleted' => 0];
$this->app->db->name('DataUser')->strict(false)->where($map)->update($data);
}
} else {
$uuid = $this->app->db->name('DataUser')->strict(false)->insertGetId($data);
}
if ($force) $this->buildUserToken(intval($uuid), $type);
return $this->get($type, $uuid);
}
/**
* 获取用户数据统计
* @param int $uid 用户UID
* @return array
*/
public function total(int $uid): array
{
$query = $this->app->db->name('DataUser');
return ['my_invite' => $query->where(['from' => $uid])->count()];
}
/**
* 生成新的用户令牌
* @param int $uid 授权用户
* @param string $type 接口类型
* @return array [创建状态, 状态描述, 令牌数据]
* @throws \think\db\exception\DbException
*/
public function buildUserToken(int $uid, string $type): array
{
// 清理历史认证及已过期的认证
$map1 = [['time', '<', $time = time()]];
$map2 = [['uid', '=', $uid], ['type', '=', $type]];
$this->app->db->name('DataUserToken')->whereOr([$map1, $map2])->delete();
// 创建用户新的用户认证数据
do $map = ['type' => $type, 'token' => md5(uniqid('', true) . rand(100, 999))];
while ($this->app->db->name('DataUserToken')->where($map)->count() > 0);
$data = array_merge($map, ['uid' => $uid, 'time' => $time + $this->expire, 'tokenv' => $this->_buildTokenVerify()]);
if ($this->app->db->name('DataUserToken')->insert($data) !== false) {
return [1, '刷新用户认证成功', $data];
} else {
return [0, '刷新用户认证失败', []];
}
}
/**
* 检查接口授权 TOKEN 是否有效
* @param string $type 接口类型
* @param string $token 认证令牌
* @param array $data 认证数据
* @return array [ 检查状态状态描述用户UID, 有效时间 ]
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function checkUserToken(string $type, string $token, array $data = []): array
{
if (empty($data)) {
$map = ['type' => $type, 'token' => $token];
$data = $this->app->db->name('DataUserToken')->where($map)->find();
}
if (empty($data) || empty($data['uid'])) {
return [0, '接口认证令牌无效', 0, 0];
} elseif ($data['time'] < time()) {
return [0, '接口认证令牌已失效', 0, 0];
} elseif ($data['tokenv'] !== $this->_buildTokenVerify()) {
return [0, '接口请求客户端已更换', 0, 0];
} else {
return [1, '接口认证令牌验证成功', $data['uid'], $data['time']];
}
}
/**
* 获取令牌的认证值
* @return string
*/
private function _buildTokenVerify(): string
{
return md5($this->app->request->server('HTTP_USER_AGENT', '-'));
}
}