first commit
This commit is contained in:
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace app\model;
|
||||
|
||||
use app\model\QfShop;
|
||||
|
||||
class Access extends QfShop
|
||||
{
|
||||
/**
|
||||
* 创建一个新的授权
|
||||
*
|
||||
* @param [int] AdminID
|
||||
* @param [plat] 授权平台
|
||||
* @return 授权信息|false
|
||||
*/
|
||||
public function createAccess($access_admin, $access_plat)
|
||||
{
|
||||
//将该平台下所有授权记录标记为失效
|
||||
// $this->where([
|
||||
// "access_admin" => $access_admin,
|
||||
// "access_plat" => $access_plat
|
||||
// ])->update(['access_status' => 1]);
|
||||
//生成一个新的Access_token
|
||||
$access_token = sha1(time()) . rand(100000, 99999) . sha1(time());
|
||||
$access_id = $this->insertGetId([
|
||||
"access_admin" => $access_admin,
|
||||
"access_plat" => $access_plat,
|
||||
"access_token" => $access_token,
|
||||
"access_ip" => request()->ip(),
|
||||
"access_createtime" => time(),
|
||||
"access_updatetime" => time()
|
||||
]);
|
||||
$access = $this->where("access_id", $access_id)->find();
|
||||
return $access ?? false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
<?php
|
||||
|
||||
namespace app\model;
|
||||
|
||||
use app\model\QfShop;
|
||||
|
||||
class Admin extends QfShop
|
||||
{
|
||||
/**
|
||||
* 用户登录
|
||||
*
|
||||
* @param string 帐号
|
||||
* @param string 密码
|
||||
* @return void
|
||||
*/
|
||||
public function login($admin_account, $admin_password)
|
||||
{
|
||||
$admin = $this->where([
|
||||
"admin_account" => $admin_account,
|
||||
])->find();
|
||||
if ($admin) {
|
||||
//判断密码是否正确
|
||||
$salt = $admin['admin_salt'];
|
||||
$password = $admin['admin_password'];
|
||||
if ($password != encodePassword($admin_password, $salt)) {
|
||||
return false;
|
||||
}
|
||||
return $admin->toArray() ?? false;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public function getListByPage($maps, $order = null, $field = "*")
|
||||
{
|
||||
$resource = $this->view('admin', $field)->view('group', '*', 'group.group_id = admin.admin_group', 'left');
|
||||
foreach ($maps as $map) {
|
||||
switch (count($map)) {
|
||||
case 1:
|
||||
$resource = $resource->where($map[0]);
|
||||
break;
|
||||
case 2:
|
||||
$resource = $resource->where($map[0], $map[1]);
|
||||
break;
|
||||
case 3:
|
||||
$resource = $resource->where($map[0], $map[1], $map[2]);
|
||||
break;
|
||||
default:
|
||||
}
|
||||
}
|
||||
if ($order) {
|
||||
$resource = $resource->order($order);
|
||||
}
|
||||
return $resource->paginate($this->per_page);
|
||||
}
|
||||
|
||||
/**
|
||||
* 重置密码
|
||||
*
|
||||
* @param string UID
|
||||
* @param string 密码
|
||||
* @return void
|
||||
*/
|
||||
public function motifyPassword($admin_id, $password)
|
||||
{
|
||||
$access = new Access();
|
||||
//将所有授权记录标记为失效
|
||||
$access->where('access_admin', $admin_id)->update(['access_status' => 1]);
|
||||
$salt = getRandString(4);
|
||||
$password = encodePassword($password, $salt);
|
||||
return $this->where([
|
||||
"admin_id" => $admin_id
|
||||
])->update([
|
||||
"admin_password" => $password,
|
||||
"admin_salt" => $salt,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过帐号获取用户信息
|
||||
*
|
||||
* @param string 帐号/手机号
|
||||
* @return void
|
||||
*/
|
||||
public function getAdminByAccount($admin_account)
|
||||
{
|
||||
$admin = $this->where([
|
||||
"admin_account" => $admin_account
|
||||
])->find();
|
||||
if ($admin) {
|
||||
return $admin->toArray() ?? false;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* AccessToken获取用户信息
|
||||
*
|
||||
* @param string access_token
|
||||
* @return void
|
||||
*/
|
||||
public function getAdminByAccessToken($access_token)
|
||||
{
|
||||
$Access = new Access();
|
||||
$access = $Access->where([
|
||||
"access_token" => $access_token,
|
||||
"access_status" => 0,
|
||||
])->find();
|
||||
if ($access) {
|
||||
if (time() > $access['access_updatetime'] + 7200) {
|
||||
return false;
|
||||
}
|
||||
if ($access['access_updatetime'] - $access['access_createtime'] > 86400) {
|
||||
return false;
|
||||
}
|
||||
$Access->where([
|
||||
"access_id" => $access['access_id'],
|
||||
])->update([
|
||||
'access_updatetime' => time()
|
||||
]);
|
||||
$this->where("admin_id", $access['access_admin'])->update([
|
||||
'admin_updatetime' => time()
|
||||
]);
|
||||
$admin = $this->where("admin_id", $access['access_admin'])->find();
|
||||
return $admin->toArray() ?? false;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
namespace app\model;
|
||||
|
||||
use app\model\QfShop;
|
||||
|
||||
class App extends QfShop
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
namespace app\model;
|
||||
|
||||
use app\model\QfShop;
|
||||
|
||||
class Attach extends QfShop
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,191 @@
|
||||
<?php
|
||||
|
||||
namespace app\model;
|
||||
|
||||
use think\facade\Db;
|
||||
|
||||
use app\model\QfShop;
|
||||
|
||||
class Auth extends QfShop
|
||||
{
|
||||
/**
|
||||
* 判断用户组是否获得某节点的授权
|
||||
*
|
||||
* @param int 用户组ID
|
||||
* @param int 节点ID
|
||||
* @return void
|
||||
*/
|
||||
public function auth($auth_group, $auth_node)
|
||||
{
|
||||
$auth = $this->where([
|
||||
"auth_group" => $auth_group,
|
||||
"auth_node" => $auth_node
|
||||
])->find();
|
||||
return $auth ? true : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据用户组 获取管理后台菜单
|
||||
*
|
||||
* @param int 用户组ID
|
||||
* @return void
|
||||
*/
|
||||
public function getAdminMenuListByAdminId($group_id)
|
||||
{
|
||||
if ($group_id == 1) {
|
||||
//超级管理员组
|
||||
$list = Node::where([
|
||||
"node_pid" => 0,
|
||||
"node_show" => 1,
|
||||
])
|
||||
->order("node_order desc,node_id asc")
|
||||
->select();
|
||||
for ($i = 0; $i < count($list); $i++) {
|
||||
$list[$i]['subList'] = $this->getSubAdminListByPid($list[$i]['node_id'], $group_id);
|
||||
for ($j = 0; $j < count($list[$i]['subList']); $j++) {
|
||||
$list[$i]['subList'][$j]['subList'] = $this->getSubAdminListByPid($list[$i]['subList'][$j]['node_id'], $group_id);
|
||||
}
|
||||
}
|
||||
return $list;
|
||||
} else {
|
||||
//其他组
|
||||
$list = Node::where([
|
||||
"node_pid" => 0,
|
||||
"node_show" => 1,
|
||||
])
|
||||
->order("node_order desc,node_id asc")
|
||||
->select();
|
||||
for ($i = 0; $i < count($list); $i++) {
|
||||
$list[$i]['subList'] = $this->getSubAdminListByPid($list[$i]['node_id'], 1);
|
||||
for ($j = 0; $j < count($list[$i]['subList']); $j++) {
|
||||
$list[$i]['subList'][$j]['subList'] = $this->getSubAdminListByPid($list[$i]['subList'][$j]['node_id'], 1);
|
||||
}
|
||||
}
|
||||
if($list){
|
||||
$list = $list->toArray();
|
||||
}
|
||||
$list2 = Node::alias("node")
|
||||
->view('node', '*')
|
||||
->view('auth', '*', 'node.node_id=auth.auth_node', 'left')
|
||||
->where([
|
||||
"node_module" => "qfadmin",
|
||||
"node_show" => 1,
|
||||
"auth_group" => $group_id
|
||||
])
|
||||
->order("node_order desc,node_id asc")
|
||||
->select()->toArray();
|
||||
|
||||
foreach ($list2 as $k => $v) {
|
||||
//一级
|
||||
foreach ($list as $key => $value) {
|
||||
if($v['node_id'] == $value['node_id']){
|
||||
$list[$key]['select'] = 1;
|
||||
}
|
||||
//2级
|
||||
foreach ($value['subList'] as $key2 => $value2) {
|
||||
if($v['node_id'] == $value2['node_id']){
|
||||
$list[$key]['subList'][$key2]['select'] = 1;
|
||||
}
|
||||
//3级
|
||||
foreach ($value2['subList'] as $key3 => $value3) {
|
||||
if($v['node_id'] == $value3['node_id']){
|
||||
$list[$key]['subList'][$key2]['subList'][$key3]['select'] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach ($list as $key => $value) {
|
||||
//一级
|
||||
if(empty($value['select'])){
|
||||
if(!empty($value['subList'])){
|
||||
foreach ($value['subList'] as $key2 => $value2) {
|
||||
//2级
|
||||
if(empty($value2['select'])){
|
||||
if(!empty($value2['subList'])){
|
||||
foreach ($value2['subList'] as $key3 => $value3) {
|
||||
//3级
|
||||
if(empty($value3['select'])){
|
||||
if(empty($value3['subList'])){
|
||||
unset($list[$key]['subList'][$key2]['subList'][$key3]);
|
||||
if(empty($list[$key]['subList'][$key2]['subList'])){
|
||||
unset($list[$key]['subList'][$key2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}else{
|
||||
unset($list[$key]['subList'][$key2]);
|
||||
if(empty($list[$key]['subList'])){
|
||||
unset($list[$key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}else{
|
||||
unset($list[$key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
$list = array_values($list);
|
||||
foreach ($list as $key => $value) {
|
||||
if(!empty($value['subList'])){
|
||||
$list[$key]['subList'] = array_values($list[$key]['subList']);
|
||||
foreach ($value['subList'] as $key2 => $value2) {
|
||||
if(!empty($value2['subList'])){
|
||||
try {
|
||||
$list[$key]['subList'][$key2]['subList'] = array_values($list[$key]['subList'][$key2]['subList']);
|
||||
} catch (\Throwable $th) {
|
||||
//throw $th;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $list;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据节点ID 获取用户组的子菜单
|
||||
*
|
||||
* @param int 节点ID
|
||||
* @param int 用户组ID
|
||||
* @return void
|
||||
*/
|
||||
public function getSubAdminListByPid($node_id, $group_id = 1)
|
||||
{
|
||||
if ($group_id == 1) {
|
||||
//超级管理员组
|
||||
return Node::where([
|
||||
"node_pid" => $node_id,
|
||||
"node_show" => 1
|
||||
])
|
||||
->order("node_order desc,node_id asc")
|
||||
->select();
|
||||
} else {
|
||||
//其他组
|
||||
return Node::alias("node")
|
||||
->view('node', '*')
|
||||
->view('auth', '*', 'node.node_id=auth.auth_node', 'left')
|
||||
->where([
|
||||
"node_pid" => $node_id,
|
||||
"node_show" => 1,
|
||||
"auth_group" => $group_id
|
||||
])
|
||||
->order("node_order desc,node_id asc")
|
||||
->select();
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 删除授权记录
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function cleanAuth()
|
||||
{
|
||||
//清空auth表
|
||||
Db::execute("truncate table " . config('database.connections.mysql.prefix') . "auth");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace app\model;
|
||||
|
||||
use app\model\QfShop;
|
||||
|
||||
class Conf extends QfShop
|
||||
{
|
||||
/**
|
||||
* 更新配置
|
||||
*
|
||||
* @param string 配置key
|
||||
* @param string 配置值
|
||||
* @param int 整形配置
|
||||
* @param string 配置描述
|
||||
* @return void
|
||||
*/
|
||||
public function updateConf($key, $value, $int = 0, $desc = null)
|
||||
{
|
||||
$data = [];
|
||||
if ($desc) {
|
||||
$data['conf_desc'] = $desc;
|
||||
}
|
||||
$data['conf_value'] = $value;
|
||||
$this->where([
|
||||
"conf_key" => $key,
|
||||
"conf_readonly" => 0,
|
||||
])->update($data);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace app\model;
|
||||
|
||||
use app\model\QfShop;
|
||||
|
||||
class Feedback extends QfShop
|
||||
{
|
||||
/**
|
||||
* 主键
|
||||
* @var string
|
||||
*/
|
||||
protected $pk = 'id';
|
||||
|
||||
/**
|
||||
* 是否需要自动写入时间戳
|
||||
* @var bool
|
||||
*/
|
||||
protected $autoWriteTimestamp = true;
|
||||
|
||||
/**
|
||||
* 只读属性
|
||||
* @var array
|
||||
*/
|
||||
protected $readonly = [
|
||||
'id',
|
||||
];
|
||||
|
||||
/**
|
||||
* 字段类型或者格式转换
|
||||
* @var array
|
||||
*/
|
||||
protected $type = [
|
||||
'id' => 'integer',
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
namespace app\model;
|
||||
|
||||
use app\model\QfShop;
|
||||
|
||||
class Group extends QfShop
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
namespace app\model;
|
||||
|
||||
use app\model\QfShop;
|
||||
|
||||
class Node extends QfShop
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,226 @@
|
||||
<?php
|
||||
|
||||
namespace app\model;
|
||||
|
||||
use think\Model;
|
||||
use think\helper\Str;
|
||||
use app\model\Token as TokenModel;
|
||||
|
||||
/**
|
||||
* QfShop 数据模型基类
|
||||
*/
|
||||
class QfShop extends Model
|
||||
{
|
||||
/**
|
||||
* 默认分页获取条数
|
||||
*
|
||||
* @var int 默认分页获取条数
|
||||
*/
|
||||
public $page_size = 40;
|
||||
public $per_page = 10;
|
||||
|
||||
/**
|
||||
* 翻页搜索器
|
||||
* @access public
|
||||
* @param object $query
|
||||
* @param mixed $value
|
||||
* @param mixed $data
|
||||
*/
|
||||
public function searchPageAttr($query, $value, $data)
|
||||
{
|
||||
$pageNo = isset($data['page_no']) ? $data['page_no'] : 1;
|
||||
$pageSize = isset($data['page_size']) ? $data['page_size'] : $this->page_size;
|
||||
$query->page($pageNo, $pageSize);
|
||||
}
|
||||
|
||||
/**
|
||||
* 排序搜索器
|
||||
* @access public
|
||||
* @param object $query
|
||||
* @param mixed $value
|
||||
* @param mixed $data
|
||||
*/
|
||||
public function searchOrderAttr($query, $value, $data)
|
||||
{
|
||||
$order = [];
|
||||
if (!empty($data['order_field']) || !empty($data['order_type'])) {
|
||||
$order[$data['order_field']] = $data['order_type'];
|
||||
} else {
|
||||
$order = $this->defaultOrder;
|
||||
}
|
||||
if (!empty($this->fixedOrder)) {
|
||||
// 固定排序必须在前,否则将导致自定义排序无法覆盖
|
||||
$order = array_merge($this->fixedOrder, $order);
|
||||
if (!empty($data['order_field']) && $this->isReverse) {
|
||||
$order = array_reverse($order);
|
||||
}
|
||||
}
|
||||
if (!empty($order)) {
|
||||
$query->order($order);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置默认排序
|
||||
* @access public
|
||||
* @param array $order 默认排序
|
||||
* @param array $fixed 固定排序
|
||||
* @param bool $reverse 是否调整顺序
|
||||
* @return $this
|
||||
*/
|
||||
public function setDefaultOrder(array $order, $fixed = [], $reverse = false)
|
||||
{
|
||||
$this->defaultOrder = $order;
|
||||
$this->fixedOrder = $fixed;
|
||||
$this->isReverse = $reverse;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 模型验证器
|
||||
* @access public
|
||||
* @param array|object $data 验证数据
|
||||
* @param string|null $scene 场景名
|
||||
* @param bool $clean 是否清理规则键值不存在的$data
|
||||
* @param string $validate 验证器规则或类
|
||||
* @return bool
|
||||
*/
|
||||
public function validateData(array &$data, $scene = null, $clean = false, $validate = '')
|
||||
{
|
||||
try {
|
||||
// 确定规则来源
|
||||
if (empty($validate)) {
|
||||
$class = '\\app\\validate\\' . $this->getName();
|
||||
if ($scene) {
|
||||
$v = new $class();
|
||||
$v->extractScene($data, $scene, $clean, $this->getPk());
|
||||
} else {
|
||||
$v = validate($class);
|
||||
}
|
||||
} else {
|
||||
$v = validate($validate);
|
||||
if ($scene) {
|
||||
$v->extractScene($data, $scene, $clean, $this->getPk());
|
||||
}
|
||||
}
|
||||
|
||||
if ($clean) {
|
||||
$keys = $v->getRuleKey();
|
||||
foreach ($data as $key => $value) {
|
||||
if (!in_array($key, $keys, true)) {
|
||||
unset($data[$key]);
|
||||
}
|
||||
}
|
||||
|
||||
unset($key, $value);
|
||||
}
|
||||
|
||||
$v->failException(true)->check($data);
|
||||
} catch (ValidateException $e) {
|
||||
return $this->setError($e->getMessage());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检测是否存在相同值
|
||||
* @access public
|
||||
* @param array $map 查询条件
|
||||
* @return bool false:不存在
|
||||
*/
|
||||
public static function checkUnique(array $map)
|
||||
{
|
||||
if (empty($map)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$count = self::where($map)->count();
|
||||
if (is_numeric($count) && $count <= 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 后台使用分页获取数据
|
||||
*
|
||||
* @param array 筛选数组
|
||||
* @param string 排序方式
|
||||
* @param string 搜索字段
|
||||
* @return void
|
||||
*/
|
||||
public function getListByPage($maps, $order = null, $field = "*")
|
||||
{
|
||||
$resource = $this->field($field);
|
||||
foreach ($maps as $map) {
|
||||
switch (count($map)) {
|
||||
case 1:
|
||||
$resource = $resource->where($map[0]);
|
||||
break;
|
||||
case 2:
|
||||
$resource = $resource->where($map[0], $map[1]);
|
||||
break;
|
||||
case 3:
|
||||
$resource = $resource->where($map[0], $map[1], $map[2]);
|
||||
break;
|
||||
default:
|
||||
}
|
||||
}
|
||||
if ($order) {
|
||||
$resource = $resource->order($order);
|
||||
}
|
||||
return $resource->paginate($this->per_page);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 替换数组中的驼峰键名为下划线
|
||||
* @access public
|
||||
* @param array $name 需要修改的键名
|
||||
* @param array &$data 源数据
|
||||
*/
|
||||
public static function keyToSnake(array $name, array &$data)
|
||||
{
|
||||
if (!is_array($name)) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($name as $value) {
|
||||
foreach ($data as &$item) {
|
||||
if (!array_key_exists($value, $item)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$temp = $item[$value];
|
||||
unset($item[$value]);
|
||||
|
||||
$item[Str::snake($value)] = $temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将数组键名驼峰转下划线
|
||||
* @access public
|
||||
* @param array $data 数据
|
||||
* @return array
|
||||
*/
|
||||
public static function snake(array $data)
|
||||
{
|
||||
if (empty($data)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
foreach ($data as $itemKey => $item) {
|
||||
foreach ($item as $valueKey => $value) {
|
||||
$data[$itemKey][Str::snake($valueKey)] = $value;
|
||||
unset($data[$itemKey][$valueKey]);
|
||||
}
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
<?php
|
||||
|
||||
namespace app\model;
|
||||
|
||||
class Sms
|
||||
{
|
||||
/**
|
||||
* 发送通知短信
|
||||
*
|
||||
* @param string 手机号码
|
||||
* @param string 内容
|
||||
* @param string 签到二维码链接
|
||||
* @return void
|
||||
*/
|
||||
public function sendSmsNotice($smsData)
|
||||
{
|
||||
//短连接生成
|
||||
$baidu_token = config('qfshop.baidu_token');
|
||||
if (!$baidu_token) {
|
||||
jerr('请先在后台系统设置短链接相关参数!');
|
||||
}
|
||||
$urlData = [
|
||||
[
|
||||
'LongUrl' => $smsData['qrcodeUrl'],
|
||||
'TermOfValidity' => "1-year",
|
||||
]
|
||||
];
|
||||
$urlHeader = array(
|
||||
'Content-Type: application/json; charset=UTF-8',
|
||||
'Dwz-Token: '.$baidu_token,
|
||||
);
|
||||
$res = curlHelper("https://dwz.cn/api/v3/short-urls", "POST", json_encode($urlData,256), $urlHeader)['body'];
|
||||
$res = json_decode($res, true);
|
||||
if($res['Code'] != 0){
|
||||
return false;
|
||||
}
|
||||
|
||||
$smsData['qrcodeurl'] = $res['ShortUrls'][0]['ShortUrl'];
|
||||
|
||||
$result = $this->sendSms($smsData);
|
||||
if($result){
|
||||
return true;
|
||||
}else{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 发送短信(百度)
|
||||
*
|
||||
* @param string 手机号码
|
||||
* @param string 内容
|
||||
* @return void
|
||||
*/
|
||||
private function sendSms($smsData)
|
||||
{
|
||||
//初始化短信相关配置
|
||||
$sms_sign = config('qfshop.sms_sign');
|
||||
$sms_tmpl = config('qfshop.sms_tmpl_1');
|
||||
$error = null;
|
||||
if (!($sms_sign && $sms_tmpl)) {
|
||||
$error = jerr('请先在后台系统设置短信相关参数!');
|
||||
}
|
||||
|
||||
require_once __DIR__ . "/../../extend/baidu/baidusmsv3.php";
|
||||
$config = array(
|
||||
'endPoint' => 'smsv3.bj.baidubce.com',
|
||||
'accessKey' => 'b71eab07ebcc4f09b3f770e43a9d126d',
|
||||
'secretAccessKey' => '3c6c8b3d85274baab4c38481996919ec',
|
||||
);
|
||||
$smsClient = new \Baidusmsv3($config);
|
||||
$message = array(
|
||||
'template' => $sms_tmpl, //短信模板ID
|
||||
'signatureId' => $sms_sign, //短信签名ID
|
||||
'mobile' => $smsData['mobile'],
|
||||
"contentVar" => array(
|
||||
'param1' => '“'.$smsData['title'].'“',
|
||||
'param2' => $smsData['time'],
|
||||
'param3' => $smsData['address'],
|
||||
'param4' => '青峰网络',
|
||||
'param5' => $smsData['qrcodeurl'],
|
||||
),
|
||||
);
|
||||
$result = $smsClient->sendMessage($message);
|
||||
if($result['code'] == 1000){
|
||||
return true;
|
||||
}else{
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 发送短信验证码
|
||||
*
|
||||
* @param string 手机号码
|
||||
* @return void
|
||||
*/
|
||||
public function sendSmsCode($mobile,$code)
|
||||
{
|
||||
//初始化短信相关配置
|
||||
$sms_sign = config('qfshop.sms_sign');
|
||||
$sms_tmpl = config('qfshop.sms_tmpl_2');
|
||||
$error = null;
|
||||
if (!($sms_sign && $sms_tmpl)) {
|
||||
$error = jerr('请先在后台系统设置短信相关参数!');
|
||||
}
|
||||
|
||||
require_once __DIR__ . "/../../extend/baidu/baidusmsv3.php";
|
||||
$config = array(
|
||||
'endPoint' => 'smsv3.bj.baidubce.com',
|
||||
'accessKey' => 'b71eab07ebcc4f09b3f770e43a9d126d',
|
||||
'secretAccessKey' => '3c6c8b3d85274baab4c38481996919ec',
|
||||
);
|
||||
$smsClient = new \Baidusmsv3($config);
|
||||
$message = array(
|
||||
'template' => $sms_tmpl, //短信模板ID
|
||||
'signatureId' => $sms_sign, //短信签名ID
|
||||
'mobile' => $mobile,
|
||||
"contentVar" => array(
|
||||
'code' => ''.$code,
|
||||
'time' => '5',
|
||||
),
|
||||
);
|
||||
$result = $smsClient->sendMessage($message);
|
||||
if($result['code'] == 1000){
|
||||
return true;
|
||||
}else{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,178 @@
|
||||
<?php
|
||||
|
||||
namespace app\model;
|
||||
|
||||
use app\model\QfShop;
|
||||
|
||||
class Source extends QfShop
|
||||
{
|
||||
/**
|
||||
* 主键
|
||||
* @var string
|
||||
*/
|
||||
protected $pk = 'source_id';
|
||||
|
||||
/**
|
||||
* 是否需要自动写入时间戳
|
||||
* @var bool
|
||||
*/
|
||||
protected $autoWriteTimestamp = true;
|
||||
|
||||
/**
|
||||
* 只读属性
|
||||
* @var array
|
||||
*/
|
||||
protected $readonly = [
|
||||
'source_id',
|
||||
];
|
||||
|
||||
/**
|
||||
* 字段类型或者格式转换
|
||||
* @var array
|
||||
*/
|
||||
protected $type = [
|
||||
'source_id' => 'integer',
|
||||
'is_delete' => 'integer',
|
||||
'status' => 'integer',
|
||||
'time' => 'timestamp',
|
||||
];
|
||||
|
||||
|
||||
/**
|
||||
* @description: 获取一个信息
|
||||
* @param {*} $code
|
||||
* @return {*}
|
||||
*/
|
||||
public function getDetail(array $data)
|
||||
{
|
||||
$map[] = ['status', '=', 1];
|
||||
$map[] = ['is_delete', '=', 0];
|
||||
$map[] = ['source_id', '=', $data['id']];
|
||||
$field = 'source_id as id,title,url,update_time as time';
|
||||
$result = $this->where($map)->field($field)->find();
|
||||
if(!is_null($result)){
|
||||
$result->inc('page_views')->update();
|
||||
}
|
||||
$result['times'] = substr($result['time'], 0, 10);
|
||||
unset($result['time']);
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取列表
|
||||
* @access public
|
||||
* @param array $data 外部数据
|
||||
* @return array|false
|
||||
* @throws
|
||||
*/
|
||||
public function getList(array $data)
|
||||
{
|
||||
|
||||
// 搜索条件
|
||||
$map = [];
|
||||
empty($data['title']) ?: $map[] = ['title', 'like', '%' . $data['title'] . '%'];
|
||||
|
||||
$map[] = ['status', '=', 1];
|
||||
|
||||
if(!empty($data['day']) && $data['day']==2){
|
||||
// 获取今天的时间戳范围
|
||||
$todayStart = strtotime(date('Y-m-d'));
|
||||
$todayEnd = $todayStart + 86400; // 86400 秒 = 24 小时
|
||||
// 获取昨天的时间戳范围
|
||||
$yesterdayStart = $todayStart - 86400;
|
||||
$yesterdayEnd = $todayStart;
|
||||
// 添加日期范围条件
|
||||
$map[] = ['create_time', 'between', [$yesterdayStart, $todayEnd]];
|
||||
}
|
||||
|
||||
$result['total_result'] = $this->where($map)->count();
|
||||
if ($result['total_result'] <= 0) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
$order = ['source_id' => 'desc'];
|
||||
if(!empty($data['type']) && $data['type']==2){
|
||||
$order = ['source_id' => 'asc'];
|
||||
}
|
||||
|
||||
$result['items'] = $this->setDefaultOrder($order)
|
||||
->field('source_id as id,title,url,update_time as time')
|
||||
->where($map)
|
||||
->withSearch(['page', 'order'], $data)
|
||||
->select()->each(function($item,$key){
|
||||
$item['times'] = substr($item['time'], 0, 10);
|
||||
unset($item['time']);
|
||||
return $item;
|
||||
})
|
||||
->toArray();
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取最新
|
||||
* @access public
|
||||
* @param array $data 外部数据
|
||||
* @return array|false
|
||||
* @throws
|
||||
*/
|
||||
public function getNew(array $data)
|
||||
{
|
||||
|
||||
// 搜索条件
|
||||
$map = [];
|
||||
|
||||
$map[] = ['status', '=', 1];
|
||||
|
||||
$result['total_result'] = $this->where($map)->count();
|
||||
if ($result['total_result'] <= 0) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
$result['items'] = $this->setDefaultOrder(['update_time' => 'desc'])
|
||||
->field('title,update_time as time')
|
||||
->where($map)
|
||||
->withSearch(['page', 'order'], $data)
|
||||
->select()->each(function($item,$key){
|
||||
$item['times'] = substr($item['time'], 5, 5);
|
||||
unset($item['time']);
|
||||
return $item;
|
||||
})
|
||||
->toArray();
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取最热
|
||||
* @access public
|
||||
* @param array $data 外部数据
|
||||
* @return array|false
|
||||
* @throws
|
||||
*/
|
||||
public function getHot(array $data)
|
||||
{
|
||||
// 搜索条件
|
||||
$map = [];
|
||||
|
||||
$map[] = ['status', '=', 1];
|
||||
|
||||
$result['total_result'] = $this->where($map)->count();
|
||||
if ($result['total_result'] <= 0) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
$result['items'] = $this->setDefaultOrder(['page_views' => 'desc'])
|
||||
->field('title,update_time as time')
|
||||
->where($map)
|
||||
->withSearch(['page', 'order'], $data)
|
||||
->select()->each(function($item,$key){
|
||||
$item['times'] = substr($item['time'], 5, 5);
|
||||
unset($item['time']);
|
||||
return $item;
|
||||
})
|
||||
->toArray();
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
|
||||
namespace app\model;
|
||||
|
||||
use app\model\QfShop;
|
||||
|
||||
class SourceLog extends QfShop
|
||||
{
|
||||
/**
|
||||
* 主键
|
||||
* @var string
|
||||
*/
|
||||
protected $pk = 'source_log_id';
|
||||
|
||||
/**
|
||||
* 是否需要自动写入时间戳
|
||||
* @var bool
|
||||
*/
|
||||
protected $autoWriteTimestamp = true;
|
||||
|
||||
/**
|
||||
* 只读属性
|
||||
* @var array
|
||||
*/
|
||||
protected $readonly = [
|
||||
'source_log_id',
|
||||
];
|
||||
|
||||
/**
|
||||
* 字段类型或者格式转换
|
||||
* @var array
|
||||
*/
|
||||
protected $type = [
|
||||
'source_log_id' => 'integer',
|
||||
'end_time' => 'timestamp',
|
||||
];
|
||||
|
||||
public function addLog($name="任务名称",$total_num=0)
|
||||
{
|
||||
try {
|
||||
$Log = [
|
||||
'name' => $name,
|
||||
'total_num' => $total_num,
|
||||
'create_time' => time(),
|
||||
'update_time' => time(),
|
||||
];
|
||||
$logId = $this->insertGetId($Log);
|
||||
return $logId;
|
||||
} catch (\Throwable $th) {
|
||||
//throw $th;
|
||||
}
|
||||
}
|
||||
|
||||
public function editLog($source_log_id,$total_num,$edit_name,$fail_dec='',$type=0)
|
||||
{
|
||||
try {
|
||||
$data = [];
|
||||
$data['total_num'] = $total_num;
|
||||
if(!empty($fail_dec)){
|
||||
$data['fail_dec'] = $fail_dec;
|
||||
}
|
||||
$data['update_time'] = time();
|
||||
if($type==3){
|
||||
$this->where('source_log_id', $source_log_id)
|
||||
->update(['end_time' => time()]);
|
||||
}else{
|
||||
if($type==1){
|
||||
$data['end_time'] = time();
|
||||
}
|
||||
$this->where('source_log_id', $source_log_id)
|
||||
->inc($edit_name)
|
||||
->update($data);
|
||||
}
|
||||
} catch (\Throwable $th) {
|
||||
//throw $th;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
<?php
|
||||
|
||||
namespace app\model;
|
||||
|
||||
use app\model\QfShop;
|
||||
|
||||
class Token extends QfShop
|
||||
{
|
||||
/**
|
||||
* 创建更新一个新的授权
|
||||
*
|
||||
* @param [int] 用户ID
|
||||
* @param [plat] 授权平台
|
||||
* @return 授权信息|false
|
||||
*/
|
||||
public function createAccess($user_id, $platform)
|
||||
{
|
||||
$token = $this->where([
|
||||
"user_id" => $user_id,
|
||||
"platform" => $platform
|
||||
])->find();
|
||||
//生成一个新的Access_token
|
||||
$access_token = sha1(time()) . rand(100000, 99999) . sha1(time());
|
||||
$expires = time() + (30 * 24 * 60 * 60); // 30天
|
||||
if($token){
|
||||
//如果已有token 执行更新
|
||||
$token_id = $token['token_id'];
|
||||
$this->where('token_id',$token_id)->update([
|
||||
"token" => $access_token,
|
||||
"ip" => request()->ip(),
|
||||
"token_expires" => $expires,
|
||||
"create_time" => time(),
|
||||
]);
|
||||
}else{
|
||||
//如果没有token 执行新增
|
||||
$token_id = $this->insertGetId([
|
||||
"user_id" => $user_id,
|
||||
"platform" => $platform,
|
||||
"token" => $access_token,
|
||||
"ip" => request()->ip(),
|
||||
"token_expires" => $expires,
|
||||
"create_time" => time(),
|
||||
]);
|
||||
}
|
||||
$access = $this->where("token_id", $token_id)->find();
|
||||
return $access ?? false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 授权校验
|
||||
*
|
||||
* @param string token
|
||||
* @return void
|
||||
* 校验成功 更新授权码过期时间
|
||||
*/
|
||||
public function getToken($access_token)
|
||||
{
|
||||
$token = $this->where([
|
||||
"token" => $access_token
|
||||
])->find();
|
||||
if ($token) {
|
||||
if (time() > $token['token_expires']) {
|
||||
return false;
|
||||
}
|
||||
$expires = time() + (30 * 24 * 60 * 60); // 30天
|
||||
$this->where([
|
||||
"token_id" => $token['token_id'],
|
||||
])->update([
|
||||
'token_expires' => $expires
|
||||
]);
|
||||
$user = User::field("user_id,status,mobile")->where(["user_id" => $token['user_id'],"is_delete" => 0])->find();
|
||||
if(!$user){
|
||||
return jerr("账号不存在");
|
||||
}
|
||||
if ($user['status'] == 0) {
|
||||
return jerr("你的账户被禁用");
|
||||
}
|
||||
return $user;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
namespace app\model;
|
||||
|
||||
use app\model\QfShop;
|
||||
|
||||
class User extends QfShop
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
<?php
|
||||
|
||||
namespace app\model;
|
||||
//验证码类
|
||||
class Validate
|
||||
{
|
||||
private $charset = 'abcdefghkmnprstuvwxyzABCDEFGHKMNPRSTUVWXYZ23456789'; //随机因子
|
||||
private $code; //验证码
|
||||
private $codelen = 4; //验证码长度
|
||||
private $width = 130; //宽度
|
||||
private $height = 50; //高度
|
||||
private $img; //图形资源句柄
|
||||
private $font; //指定的字体
|
||||
private $fontsize = 20; //指定字体大小
|
||||
private $fontcolor; //指定字体颜色
|
||||
|
||||
//构造方法初始化
|
||||
public function __construct()
|
||||
{
|
||||
$this->font = $_SERVER['DOCUMENT_ROOT'] . '/static/admin/css/fonts/code.ttc';
|
||||
}
|
||||
|
||||
//生成随机码
|
||||
private function createCode()
|
||||
{
|
||||
$_len = strlen($this->charset) - 1;
|
||||
for ($i = 0; $i < $this->codelen; $i++) {
|
||||
$this->code .= $this->charset[mt_rand(0, $_len)];
|
||||
}
|
||||
}
|
||||
|
||||
//生成背景
|
||||
private function createBg()
|
||||
{
|
||||
$this->img = imagecreatetruecolor($this->width, $this->height);
|
||||
$color = imagecolorallocate($this->img, mt_rand(157, 255), mt_rand(157, 255), mt_rand(157, 255));
|
||||
imagefilledrectangle($this->img, 0, $this->height, $this->width, 0, $color);
|
||||
}
|
||||
|
||||
//生成文字
|
||||
private function createFont()
|
||||
{
|
||||
$_x = $this->width / $this->codelen;
|
||||
for ($i = 0; $i < $this->codelen; $i++) {
|
||||
$this->fontcolor = imagecolorallocate($this->img, mt_rand(0, 156), mt_rand(0, 156), mt_rand(0, 156));
|
||||
imagettftext($this->img, $this->fontsize, mt_rand(-30, 30), $_x * $i + mt_rand(1, 5), $this->height / 1.4, $this->fontcolor, $this->font, $this->code[$i]);
|
||||
}
|
||||
}
|
||||
|
||||
//生成线条、雪花
|
||||
private function createLine()
|
||||
{
|
||||
for ($i = 0; $i < 6; $i++) {
|
||||
$color = imagecolorallocate($this->img, mt_rand(0, 156), mt_rand(0, 156), mt_rand(0, 156));
|
||||
imageline($this->img, mt_rand(0, $this->width), mt_rand(0, $this->height), mt_rand(0, $this->width), mt_rand(0, $this->height), $color);
|
||||
}
|
||||
for ($i = 0; $i < 100; $i++) {
|
||||
$color = imagecolorallocate($this->img, mt_rand(200, 255), mt_rand(200, 255), mt_rand(200, 255));
|
||||
imagestring($this->img, mt_rand(1, 5), mt_rand(0, $this->width), mt_rand(0, $this->height), '*', $color);
|
||||
}
|
||||
}
|
||||
|
||||
//对外生成
|
||||
public function getImg()
|
||||
{
|
||||
$this->createBg();
|
||||
$this->createCode();
|
||||
$this->createLine();
|
||||
$this->createFont();
|
||||
imagepng($this->img);
|
||||
$image_data = ob_get_contents();
|
||||
ob_end_clean();
|
||||
imagedestroy($this->img);
|
||||
return "data:image/png;base64," . base64_encode($image_data);
|
||||
}
|
||||
|
||||
//获取验证码
|
||||
public function getCode()
|
||||
{
|
||||
return strtolower($this->code);
|
||||
}
|
||||
/**
|
||||
* 验证图形验证码
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function validateImgCode($token, $code)
|
||||
{
|
||||
if (!$token) {
|
||||
return jerr("TOKEN参数丢失");
|
||||
}
|
||||
if (!$code) {
|
||||
return jerr("请输入验证码");
|
||||
}
|
||||
$code = strtoupper($code);
|
||||
$token = $token;
|
||||
$_code = cache($token);
|
||||
if (!$_code) {
|
||||
return jerr("验证码已过期");
|
||||
}
|
||||
if ($code != $_code) {
|
||||
return jerr('验证码错误');
|
||||
}
|
||||
// 删除设置的缓存
|
||||
cache($token, null);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user