后台调整

机构后台api登录,注册,图片上传
This commit is contained in:
15090180611 2025-01-17 13:59:57 +08:00
parent 3ed8ce6bbb
commit 74c5f0aebf
17 changed files with 779 additions and 839 deletions

View File

@ -353,6 +353,7 @@
<option value="" selected>请选择模块</option> <option value="" selected>请选择模块</option>
<option value="api">API</option> <option value="api">API</option>
<option value="backend">后台</option> <option value="backend">后台</option>
<option value="manystoreapi">机构后台API</option>
<option value="frontend">前台</option> <option value="frontend">前台</option>
</select> </select>
</div> </div>

View File

@ -4,7 +4,7 @@
<!-- 加载样式及META信息 --> <!-- 加载样式及META信息 -->
{include file="common/meta" /} {include file="common/meta" /}
</head> </head>
<body class="hold-transition {$Think.config.fastadmin.adminskin|default='skin-black-blue'} sidebar-mini {:$Think.cookie.sidebar_collapse?'sidebar-collapse':''} fixed {:$Think.config.fastadmin.multipletab?'multipletab':''} {:$Think.config.fastadmin.multiplenav?'multiplenav':''}" id="tabs"> <body class="hold-transition {$Think.config.fastadmin.adminskin|default='skin-blue-light'} sidebar-mini {:$Think.cookie.sidebar_collapse?'sidebar-collapse':''} fixed {:$Think.config.fastadmin.multipletab?'multipletab':''} {:$Think.config.fastadmin.multiplenav?'multiplenav':''}" id="tabs">
<div class="wrapper"> <div class="wrapper">

View File

@ -249,7 +249,7 @@ class ManystoreApiBase extends Controller
/** /**
* 引入后台控制器的traits * 引入后台控制器的traits
*/ */
use \app\manystore\library\traits\Backend; // use \app\manystore\library\traits\Backend;
public function _initialize() public function _initialize()
{ {
@ -279,7 +279,7 @@ class ManystoreApiBase extends Controller
$this->auth = Auth::instance(); $this->auth = Auth::instance();
$token = $this->request->server('HTTP_TOKEN', $this->request->request('token', \think\Cookie::get('token'))); $token = $this->request->server('HTTP_TOKEN', $this->request->request('token', \think\Cookie::get('token')));
if(!$token)$token = $this->request->server('HTTP_SHOP_TOKEN',"");
// 设置当前请求的URI // 设置当前请求的URI
$this->auth->setRequestUri($path); $this->auth->setRequestUri($path);
// 检测是否需要验证登录 // 检测是否需要验证登录
@ -297,7 +297,7 @@ class ManystoreApiBase extends Controller
// } // }
// $this->error(__('Please login first'), url('index/login', ['url' => $url])); // $this->error(__('Please login first'), url('index/login', ['url' => $url]));
$this->error(__('Please login first'), ['errcode'=>30002], 401); $this->apierror(__('Please login first'), ['errcode'=>30002], 401);
} }
@ -308,7 +308,7 @@ class ManystoreApiBase extends Controller
// 判断控制器和方法判断是否有对应权限 // 判断控制器和方法判断是否有对应权限
if (!$this->auth->check($path)) { if (!$this->auth->check($path)) {
Hook::listen('manystore_nopermission', $this); Hook::listen('manystore_nopermission', $this);
$this->error(__('You have no permission'), null, 403); $this->apierror(__('You have no permission'), null, 403);
} }
} }

View File

@ -48,6 +48,7 @@ class Token
if (true === $name) { if (true === $name) {
return new $class($options); return new $class($options);
} }
$options = array_merge(Config::get('token'), $options);
self::$instance[$name] = new $class($options); self::$instance[$name] = new $class($options);
} }

View File

@ -297,6 +297,8 @@ return [
'show_submenu' => false, 'show_submenu' => false,
//后台皮肤,为空时表示使用skin-black-blue //后台皮肤,为空时表示使用skin-black-blue
'adminskin' => '', 'adminskin' => '',
//后台皮肤,为空时表示使用skin-black-blue
'manystoreskin' => '',
//后台是否启用面包屑 //后台是否启用面包屑
'breadcrumb' => false, 'breadcrumb' => false,
//是否允许未知来源的插件压缩包 //是否允许未知来源的插件压缩包

View File

@ -4,7 +4,7 @@
<!-- 加载样式及META信息 --> <!-- 加载样式及META信息 -->
{include file="common/meta" /} {include file="common/meta" /}
</head> </head>
<body class="hold-transition {$Think.config.fastadmin.adminskin|default='skin-black-blue'} sidebar-mini {:$Think.cookie.sidebar_collapse?'sidebar-collapse':''} fixed {:$Think.config.fastadmin.multipletab?'multipletab':''} {:$Think.config.fastadmin.multiplenav?'multiplenav':''}" id="tabs"> <body class="hold-transition {$Think.config.fastadmin.manystoreskin|default='skin-black-light'} sidebar-mini {:$Think.cookie.sidebar_collapse?'sidebar-collapse':''} fixed {:$Think.config.fastadmin.multipletab?'multipletab':''} {:$Think.config.fastadmin.multiplenav?'multiplenav':''}" id="tabs">
<div class="wrapper"> <div class="wrapper">

View File

@ -1,288 +0,0 @@
<?php
namespace app\manystoreapi\controller;
use app\common\controller\ManystoreBase;
use fast\Random;
use think\addons\Service;
use think\Cache;
use think\Config;
use think\Db;
use think\Lang;
/**
* Ajax异步请求接口
* @internal
*/
class Ajax extends ManystoreBase
{
protected $noNeedLogin = ['lang'];
protected $noNeedRight = ['*'];
protected $layout = '';
public function _initialize()
{
parent::_initialize();
//设置过滤方法
$this->request->filter(['strip_tags', 'htmlspecialchars']);
}
/**
* 加载语言包
*/
public function lang()
{
header('Content-Type: application/javascript');
$controllername = input("controllername");
//默认只加载了控制器对应的语言名,你还根据控制器名来加载额外的语言包
$this->loadlang($controllername);
return jsonp(Lang::get(), 200, [], ['json_encode_param' => JSON_FORCE_OBJECT | JSON_UNESCAPED_UNICODE]);
}
/**
* 上传文件
*/
public function upload()
{
Config::set('default_return_type', 'json');
$file = $this->request->file('file');
if (empty($file)) {
$this->error(__('No file upload or server upload limit exceeded'));
}
//判断是否已经存在附件
$sha1 = $file->hash();
$extparam = $this->request->post();
$upload = Config::get('upload');
preg_match('/(\d+)(\w+)/', $upload['maxsize'], $matches);
$type = strtolower($matches[2]);
$typeDict = ['b' => 0, 'k' => 1, 'kb' => 1, 'm' => 2, 'mb' => 2, 'gb' => 3, 'g' => 3];
$size = (int)$upload['maxsize'] * pow(1024, isset($typeDict[$type]) ? $typeDict[$type] : 0);
$fileInfo = $file->getInfo();
$suffix = strtolower(pathinfo($fileInfo['name'], PATHINFO_EXTENSION));
$suffix = $suffix && preg_match("/^[a-zA-Z0-9]+$/", $suffix) ? $suffix : 'file';
$fileInfo['suffix'] = $suffix;
$mimetypeArr = explode(',', strtolower($upload['mimetype']));
$typeArr = explode('/', $fileInfo['type']);
//禁止上传PHP和HTML文件
if (in_array($fileInfo['type'], ['text/x-php', 'text/html']) || in_array($suffix, ['php', 'html', 'htm', 'phar', 'phtml']) || preg_match("/^php(.*)/i", $fileInfo['suffix'])) {
$this->error(__('Uploaded file format is limited'));
}
//Mimetype值不正确
if (stripos($fileInfo['type'], '/') === false) {
$this->error(__('Uploaded file format is limited'));
}
//验证文件后缀
if ($upload['mimetype'] !== '*' &&
(
!in_array($suffix, $mimetypeArr)
|| (stripos($typeArr[0] . '/', $upload['mimetype']) !== false && (!in_array($fileInfo['type'], $mimetypeArr) && !in_array($typeArr[0] . '/*', $mimetypeArr)))
)
) {
$this->error(__('Uploaded file format is limited'));
}
//验证是否为图片文件
$imagewidth = $imageheight = 0;
if (in_array($fileInfo['type'], ['image/gif', 'image/jpg', 'image/jpeg', 'image/bmp', 'image/png', 'image/webp']) || in_array($suffix, ['gif', 'jpg', 'jpeg', 'bmp', 'png', 'webp'])) {
$imgInfo = getimagesize($fileInfo['tmp_name']);
if (!$imgInfo || !isset($imgInfo[0]) || !isset($imgInfo[1])) {
$this->error(__('Uploaded file is not a valid image'));
}
$imagewidth = isset($imgInfo[0]) ? $imgInfo[0] : $imagewidth;
$imageheight = isset($imgInfo[1]) ? $imgInfo[1] : $imageheight;
}
$replaceArr = [
'{year}' => date("Y"),
'{mon}' => date("m"),
'{day}' => date("d"),
'{hour}' => date("H"),
'{min}' => date("i"),
'{sec}' => date("s"),
'{random}' => Random::alnum(16),
'{random32}' => Random::alnum(32),
'{filename}' => $suffix ? substr($fileInfo['name'], 0, strripos($fileInfo['name'], '.')) : $fileInfo['name'],
'{suffix}' => $suffix,
'{.suffix}' => $suffix ? '.' . $suffix : '',
'{filemd5}' => md5_file($fileInfo['tmp_name']),
];
$savekey = $upload['savekey'];
$savekey = str_replace(array_keys($replaceArr), array_values($replaceArr), $savekey);
$uploadDir = substr($savekey, 0, strripos($savekey, '/') + 1);
$fileName = substr($savekey, strripos($savekey, '/') + 1);
//
$splInfo = $file->validate(['size' => $size])->move(ROOT_PATH . '/public' . $uploadDir, $fileName);
$category = request()->post('category');
$category = array_key_exists($category, config('site.attachmentcategory') ?? []) ? $category : '';
if ($splInfo) {
$params = array(
'category' => $category,
'shop_id' => (int)SHOP_ID,
'user_id' => 0,
'filesize' => $fileInfo['size'],
'imagewidth' => $imagewidth,
'imageheight' => $imageheight,
'imagetype' => $suffix,
'imageframes' => 0,
'mimetype' => $fileInfo['type'],
'url' => $uploadDir . $splInfo->getSaveName(),
'uploadtime' => time(),
'storage' => 'local',
'sha1' => $sha1,
'extparam' => json_encode($extparam),
);
$attachment = model("ManystoreAttachment");
$attachment->data(array_filter($params));
$attachment->save();
\think\Hook::listen("upload_after", $attachment);
$this->success(__('Upload successful'), null, [
'url' => $uploadDir . $splInfo->getSaveName()
]);
} else {
// 上传失败获取错误信息
$this->error($file->getError());
}
}
/**
* 通用排序
*/
public function weigh()
{
//排序的数组
$ids = $this->request->post("ids");
//拖动的记录ID
$changeid = $this->request->post("changeid");
//操作字段
$field = $this->request->post("field");
//操作的数据表
$table = $this->request->post("table");
//主键
$pk = $this->request->post("pk");
//排序的方式
$orderway = $this->request->post("orderway", "", 'strtolower');
$orderway = $orderway == 'asc' ? 'ASC' : 'DESC';
$sour = $weighdata = [];
$ids = explode(',', $ids);
$prikey = $pk ? $pk : (Db::name($table)->getPk() ?: 'id');
$pid = $this->request->post("pid");
//限制更新的字段
$field = in_array($field, ['weigh']) ? $field : 'weigh';
// 如果设定了pid的值,此时只匹配满足条件的ID,其它忽略
if ($pid !== '') {
$hasids = [];
$list = Db::name($table)->where($prikey, 'in', $ids)->where('pid', 'in', $pid)->field("{$prikey},pid")->select();
foreach ($list as $k => $v) {
$hasids[] = $v[$prikey];
}
$ids = array_values(array_intersect($ids, $hasids));
}
$list = Db::name($table)->field("$prikey,$field")->where($prikey, 'in', $ids)->order($field, $orderway)->select();
foreach ($list as $k => $v) {
$sour[] = $v[$prikey];
$weighdata[$v[$prikey]] = $v[$field];
}
$position = array_search($changeid, $ids);
$desc_id = $sour[$position]; //移动到目标的ID值,取出所处改变前位置的值
$sour_id = $changeid;
$weighids = array();
$temp = array_values(array_diff_assoc($ids, $sour));
foreach ($temp as $m => $n) {
if ($n == $sour_id) {
$offset = $desc_id;
} else {
if ($sour_id == $temp[0]) {
$offset = isset($temp[$m + 1]) ? $temp[$m + 1] : $sour_id;
} else {
$offset = isset($temp[$m - 1]) ? $temp[$m - 1] : $sour_id;
}
}
$weighids[$n] = $weighdata[$offset];
Db::name($table)->where($prikey, $n)->update([$field => $weighdata[$offset]]);
}
$this->success();
}
/**
* 清空系统缓存
*/
public function wipecache()
{
$type = $this->request->request("type");
switch ($type) {
case 'all':
case 'content':
Cache::clear('ShopCacheTag'.SHOP_ID);
if ($type == 'content')
break;
}
\think\Hook::listen("wipecache_after");
$this->success();
}
/**
* 读取分类数据,联动列表
*/
public function category()
{
$type = $this->request->get('type');
$pid = $this->request->get('pid');
$where = ['status' => 'normal'];
$categorylist = null;
if ($pid !== '') {
if ($type) {
$where['type'] = $type;
}
if ($pid) {
$where['pid'] = $pid;
}
$categorylist = Db::name('category')->where($where)->field('id as value,name')->order('weigh desc,id desc')->select();
}
$this->success('', null, $categorylist);
}
/**
* 读取省市区数据,联动列表
*/
public function area()
{
$params = $this->request->get("row/a");
if (!empty($params)) {
$province = isset($params['province']) ? $params['province'] : '';
$city = isset($params['city']) ? $params['city'] : null;
} else {
$province = $this->request->get('province');
$city = $this->request->get('city');
}
$where = ['pid' => 0, 'level' => 1];
$provincelist = null;
if ($province !== '') {
if ($province) {
$where['pid'] = $province;
$where['level'] = 2;
}
if ($city !== '') {
if ($city) {
$where['pid'] = $city;
$where['level'] = 3;
}
$provincelist = Db::name('area')->where($where)->field('id as value,name')->select();
}
}
$this->success('', null, $provincelist);
}
}

View File

@ -0,0 +1,160 @@
<?php
namespace app\manystoreapi\controller;
use app\common\controller\ManystoreApiBase;
use app\common\model\ManystoreAttachment;
/**
* 机构API后台附件管理接口
*/
class Attachment extends ManystoreApiBase
{
protected $noNeedLogin = [];
protected $noNeedRight = '*';
/**
* @var \app\common\model\ManystoreAttachment
*/
protected $model = null;
public function _initialize()
{
$this->model = new \app\common\model\ManystoreAttachment;
parent::_initialize();
}
/**
* 附件列表查看
* @ApiMethod (GET)
* @ApiParams (name="category", type="string", required=true, description="附件分类分类标识category1=非机密类1,category2=非机密类2,cert=证件机密类,code=二维码类,user=用户普通上传")
* @ApiParams (name="mimetype", type="string", required=true, description="消息类型image/*=图片,audio/*=音频,video/*=视频,text/*=文档,application/*=应用程序,zip,rar,7z,tar=压缩文件")
*/
public function index()
{
//设置过滤方法
$this->request->filter(['strip_tags', 'trim']);
$mimetypeQuery = [];
$filter = $this->request->request('filter');
$filterArr = $this->request->param();
if (isset($filterArr['category']) && $filterArr['category'] == 'unclassed') {
$filterArr['category'] = ',unclassed';
$this->request->get(['filter' => json_encode(array_diff_key($filterArr, ['category' => '']))]);
}
if (isset($filterArr['mimetype']) && preg_match("/[]\,|\*]/", $filterArr['mimetype'])) {
$this->request->get(['filter' => json_encode(array_diff_key($filterArr, ['mimetype' => '']))]);
$mimetypeQuery = function ($query) use ($filterArr) {
$mimetypeArr = explode(',', $filterArr['mimetype']);
foreach ($mimetypeArr as $index => $item) {
if (stripos($item, "/*") !== false) {
$query->whereOr('mimetype', 'like', str_replace("/*", "/", $item) . '%');
} else {
$query->whereOr('mimetype', 'like', '%' . $item . '%');
}
}
};
}
list($where, $sort, $order, $offset, $limit) = $this->buildparams();
$list = $this->model->with(["user"])
->where($mimetypeQuery)
->whereRaw("`filename` NOT REGEXP '^[0-9A-Fa-f]{32}'")
->where($where)
->order($sort, $order)
->paginate($limit);
foreach ($list as $row) {
$row->getRelation('user')->visible(['nickname', 'realname', 'mobile', 'avatar']);
}
$rows = $list->items();
$cdnurl = preg_replace("/\/(\w+)\.php$/i", '', $this->request->root());
foreach ($rows as $k => &$v) {
$v['fullurl'] = ($v['storage'] == 'local' ? $cdnurl : $this->view->config['upload']['cdnurl']) . $v['url'];
}
unset($v);
$result = array("total" => $list->total(), "rows" => $rows);
$this->apisuccess(__('发送成功'),$result);
//return json($result);
}
/**
* 删除附件
* @ApiMethod (POST)
* @ApiParams (name="ids", type="string", required=true, description="附件id")
* @param array $ids
*/
public function del($ids = "")
{
if (!$this->request->isPost()) {
$this->apierror(__("Invalid parameters"));
}
$ids = $ids ? $ids : $this->request->post("ids");
if ($ids) {
\think\Hook::add('upload_delete', function ($params) {
if ($params['storage'] == 'local') {
$attachmentFile = ROOT_PATH . '/public' . $params['url'];
if (is_file($attachmentFile)) {
@unlink($attachmentFile);
}
}
});
$attachmentlist = $this->model->where('id', 'in', $ids)->select();
foreach ($attachmentlist as $attachment) {
\think\Hook::listen("upload_delete", $attachment);
$attachment->delete();
}
$this->apisuccess();
}
$this->apierror(__('Parameter %s can not be empty', 'ids'));
}
/**
* 归类
* @ApiMethod (POST)
* @ApiParams (name="category", type="string", required=true, description="附件分类分类标识category1=非机密类1,category2=非机密类2,cert=证件机密类,code=二维码类,user=用户普通上传")
* @ApiParams (name="ids", type="string", required=true, description="附件id")
*/
public function classify()
{
// if (!$this->auth->check('general/attachment/edit')) {
// \think\Hook::listen('admin_nopermission', $this);
// $this->apierror(__('You have no permission'), '');
// }
if (!$this->request->isPost()) {
$this->apierror(__("Invalid parameters"));
}
$category = $this->request->post('category', '');
$ids = $this->request->post('ids');
if (!$ids) {
$this->apierror(__('Parameter %s can not be empty', 'ids'));
}
$categoryList = \app\common\model\Attachment::getCategoryList();
if ($category && !isset($categoryList[$category])) {
$this->apierror(__('Category not found'));
}
// if(!defined('SHOP_ID')){
// define('SHOP_ID', $this->auth->shop_id);
// }
$category = $category == 'unclassed' ? '' : $category;
ManystoreAttachment::where('id', 'in', $ids)->update(['category' => $category]);
$this->apisuccess();
}
}

View File

@ -0,0 +1,362 @@
<?php
namespace app\manystoreapi\controller;
use app\admin\model\school\classes\VirtualHead;
use app\common\controller\ManystoreApiBase;
use app\common\exception\UploadException;
use app\common\library\Upload;
use app\common\library\Virtual;
use app\common\model\Area;
use app\common\model\ManystoreAttachment;
use app\common\model\Version;
use fast\Random;
use think\captcha\Captcha;
use think\Config;
use think\Hook;
/**
* 机构API后台公共接口
*/
class Common extends ManystoreApiBase
{
protected $noNeedLogin = ['init', 'captcha','virtualgenerate','get_week_by_time'];
protected $noNeedRight = '*';
public function _initialize()
{
if (isset($_SERVER['HTTP_ORIGIN'])) {
header('Access-Control-Expose-Headers: __token__');//跨域让客户端获取到
}
//跨域检测
check_cors_request();
if (!isset($_COOKIE['PHPSESSID'])) {
Config::set('session.id', $this->request->server("HTTP_SID"));
}
parent::_initialize();
}
/**
* 加载初始化
*
* @ApiParams (name="version", type="string", required=true, description="版本号")
* @ApiParams (name="lng", type="string", required=true, description="经度")
* @ApiParams (name="lat", type="string", required=true, description="纬度")
*/
public function init()
{
if ($version = $this->request->request('version')) {
$lng = $this->request->request('lng');
$lat = $this->request->request('lat');
//配置信息
$upload = Config::get('upload');
//如果非服务端中转模式需要修改为中转
if ($upload['storage'] != 'local' && isset($upload['uploadmode']) && $upload['uploadmode'] != 'server') {
//临时修改上传模式为服务端中转
set_addon_config($upload['storage'], ["uploadmode" => "server"], false);
$upload = \app\common\model\Config::upload();
// 上传信息配置后
Hook::listen("upload_config_init", $upload);
$upload = Config::set('upload', array_merge(Config::get('upload'), $upload));
}
$upload['cdnurl'] = $upload['cdnurl'] ? $upload['cdnurl'] : cdnurl('', true);
$upload['uploadurl'] = preg_match("/^((?:[a-z]+:)?\/\/)(.*)/i", $upload['uploadurl']) ? $upload['uploadurl'] : url($upload['storage'] == 'local' ? '/api/common/upload' : $upload['uploadurl'], '', false, true);
$content = [
'citydata' => Area::getCityFromLngLat($lng, $lat),
'versiondata' => Version::check($version),
'uploaddata' => $upload,
'coverdata' => Config::get("cover"),
];
$this->apisuccess('', $content);
} else {
$this->apierror(__('Invalid parameters'));
}
}
/**
* 用户上传文件(上传到总后台)
* @ApiMethod (POST)
* @ApiParams (name="file", type="File", required=true, description="文件流")
* @ApiParams (name="category", type="string", required=true, description="分类标识category1=非机密类1,category2=非机密类2,cert=证件机密类,code=二维码类,user=用户普通上传")
*
*/
public function upload()
{
Config::set('default_return_type', 'json');
//必须设定cdnurl为空,否则cdnurl函数计算错误
Config::set('upload.cdnurl', '');
$category = $this->request->post("category",'user');
// var_dump($category);die;
$chunkid = $this->request->post("chunkid");
if ($chunkid) {
if (!Config::get('upload.chunking')) {
$this->apierror(__('Chunk file disabled'));
}
$action = $this->request->post("action");
$chunkindex = $this->request->post("chunkindex/d");
$chunkcount = $this->request->post("chunkcount/d");
$filename = $this->request->post("filename");
$method = $this->request->method(true);
if ($action == 'merge') {
$attachment = null;
//合并分片文件
try {
$upload = new Upload();
$attachment = $upload->merge($chunkid, $chunkcount, $filename);
} catch (UploadException $e) {
$this->apierror($e->getMessage());
}
$this->apisuccess(__('Uploaded successful'), ['url' => $attachment->url, 'fullurl' => cdnurl($attachment->url, true)]);
} elseif ($method == 'clean') {
//删除冗余的分片文件
try {
$upload = new Upload();
$upload->clean($chunkid);
} catch (UploadException $e) {
$this->apierror($e->getMessage());
}
$this->apisuccess();
} else {
//上传分片文件
//默认普通上传文件
$file = $this->request->file('file');
try {
$upload = new Upload($file);
$upload->chunk($chunkid, $chunkindex, $chunkcount);
} catch (UploadException $e) {
$this->apierror($e->getMessage());
}
$this->apisuccess();
}
} else {
$attachment = null;
//默认普通上传文件
$file = $this->request->file('file');
try {
$upload = new Upload($file,$category);
$attachment = $upload->upload();
// $attachment = $upload->upload();
} catch (UploadException $e) {
$this->apierror($e->getMessage().$e->getFile().$e->getLine());
} catch (\Exception $e) {
$this->apierror($e->getMessage().$e->getFile().$e->getLine());
}
$this->apisuccess(__('Uploaded successful'), ['url' => $attachment->url, 'fullurl' => cdnurl($attachment->url, true)]);
}
}
/**
* 机构端上传文件(上传到机构后台)
* @ApiMethod (POST)
* @ApiParams (name="file", type="File", required=true, description="文件流")
* @ApiParams (name="category", type="string", required=true, description="分类标识category1=非机密类1,category2=非机密类2,cert=证件机密类,code=二维码类,user=用户普通上传")
*
*/
public function manystoreupload()
{
Config::set('default_return_type', 'json');
$file = $this->request->file('file');
$category = $this->request->post("category",'user');
if (empty($file)) {
$this->apierror(__('No file upload or server upload limit exceeded'));
}
//判断是否已经存在附件
$sha1 = $file->hash();
$extparam = $this->request->post();
$upload = Config::get('upload');
preg_match('/(\d+)(\w+)/', $upload['maxsize'], $matches);
$type = strtolower($matches[2]);
$typeDict = ['b' => 0, 'k' => 1, 'kb' => 1, 'm' => 2, 'mb' => 2, 'gb' => 3, 'g' => 3];
$size = (int)$upload['maxsize'] * pow(1024, isset($typeDict[$type]) ? $typeDict[$type] : 0);
$fileInfo = $file->getInfo();
$suffix = strtolower(pathinfo($fileInfo['name'], PATHINFO_EXTENSION));
$suffix = $suffix && preg_match("/^[a-zA-Z0-9]+$/", $suffix) ? $suffix : 'file';
$fileInfo['suffix'] = $suffix;
$mimetypeArr = explode(',', strtolower($upload['mimetype']));
$typeArr = explode('/', $fileInfo['type']);
//禁止上传PHP和HTML文件
if (in_array($fileInfo['type'], ['text/x-php', 'text/html']) || in_array($suffix, ['php', 'html', 'htm', 'phar', 'phtml']) || preg_match("/^php(.*)/i", $fileInfo['suffix'])) {
$this->apierror(__('Uploaded file format is limited'));
}
//Mimetype值不正确
if (stripos($fileInfo['type'], '/') === false) {
$this->apierror(__('Uploaded file format is limited'));
}
//验证文件后缀
if ($upload['mimetype'] !== '*' &&
(
!in_array($suffix, $mimetypeArr)
|| (stripos($typeArr[0] . '/', $upload['mimetype']) !== false && (!in_array($fileInfo['type'], $mimetypeArr) && !in_array($typeArr[0] . '/*', $mimetypeArr)))
)
) {
$this->apierror(__('Uploaded file format is limited'));
}
//验证是否为图片文件
$imagewidth = $imageheight = 0;
if (in_array($fileInfo['type'], ['image/gif', 'image/jpg', 'image/jpeg', 'image/bmp', 'image/png', 'image/webp']) || in_array($suffix, ['gif', 'jpg', 'jpeg', 'bmp', 'png', 'webp'])) {
$imgInfo = getimagesize($fileInfo['tmp_name']);
if (!$imgInfo || !isset($imgInfo[0]) || !isset($imgInfo[1])) {
$this->apierror(__('Uploaded file is not a valid image'));
}
$imagewidth = isset($imgInfo[0]) ? $imgInfo[0] : $imagewidth;
$imageheight = isset($imgInfo[1]) ? $imgInfo[1] : $imageheight;
}
$replaceArr = [
'{year}' => date("Y"),
'{mon}' => date("m"),
'{day}' => date("d"),
'{hour}' => date("H"),
'{min}' => date("i"),
'{sec}' => date("s"),
'{random}' => Random::alnum(16),
'{random32}' => Random::alnum(32),
'{filename}' => $suffix ? substr($fileInfo['name'], 0, strripos($fileInfo['name'], '.')) : $fileInfo['name'],
'{suffix}' => $suffix,
'{.suffix}' => $suffix ? '.' . $suffix : '',
'{filemd5}' => md5_file($fileInfo['tmp_name']),
];
$savekey = $upload['savekey'];
$savekey = str_replace(array_keys($replaceArr), array_values($replaceArr), $savekey);
$uploadDir = substr($savekey, 0, strripos($savekey, '/') + 1);
$fileName = substr($savekey, strripos($savekey, '/') + 1);
//
$splInfo = $file->validate(['size' => $size])->move(ROOT_PATH . '/public' . $uploadDir, $fileName);
$category = array_key_exists($category, config('site.attachmentcategory') ?? []) ? $category : 'user';
if ($splInfo) {
$user_id = 0;
$user = $this->auth->getUser();//登录用户
if($user)$user_id = $user['user_id'];
$params = array(
'category' => $category,
'shop_id' => (int)$this->auth->shop_id ?:0,
'user_id' => $user_id,
'filesize' => $fileInfo['size'],
'imagewidth' => $imagewidth,
'imageheight' => $imageheight,
'imagetype' => $suffix,
'imageframes' => 0,
'mimetype' => $fileInfo['type'],
'url' => $uploadDir . $splInfo->getSaveName(),
'uploadtime' => time(),
'storage' => 'local',
'sha1' => $sha1,
'extparam' => json_encode($extparam),
);
$attachment = new ManystoreAttachment;
$attachment->data(array_filter($params));
$attachment->save();
\think\Hook::listen("upload_after", $attachment);
// $this->success(__('Upload successful'), null, [
// 'url' => $uploadDir . $splInfo->getSaveName()
// ]);
$this->apisuccess(__('Uploaded successful'), ['url' => $attachment->url, 'fullurl' => cdnurl($attachment->url, true)]);
} else {
// 上传失败获取错误信息
$this->apierror($file->getError());
}
}
/**
* 验证码
* @ApiParams (name="id", type="string", required=true, description="要生成验证码的标识")
* @return \think\Response
*/
public function captcha($id = "")
{
\think\Config::set([
'captcha' => array_merge(config('captcha'), [
'fontSize' => 44,
'imageH' => 150,
'imageW' => 350,
])
]);
$captcha = new Captcha((array)Config::get('captcha'));
return $captcha->entry($id);
}
/**
* @ApiTitle(生成随机昵称和头像)
* @ApiSummary(生成随机昵称和头像)
* @ApiMethod(GET)
* @ApiParams(name = "number", type = "int",required=true,description = "生成数量")
* @ApiReturn({ unpaid_user_data 参与中 paid_user_data 已报名 })
*/
public function virtualgenerate(){
$number = $this->request->get('number/d','');
if(empty($number)){
$this->apierror(__('缺少必要参数'));
}
try {
$res = (new Virtual)->getVirtualUser($number);
} catch (\Exception $e){
// Log::log($e->getMessage());
$this->apierror($e->getMessage(),['errcode'=>$e->getCode()]);
}
$this->apisuccess('生成成功', $res);
}
/**
* @ApiTitle(通过时间点得到当前的星期数据)
* @ApiSummary(通过时间点得到当前的星期数据)
* @ApiMethod(GET)
* @ApiParams(name="time",type="string",required=true,description="选择的时间点")
* @ApiReturn({ unpaid_user_data 参与中 paid_user_data 已报名 })
*/
public function get_week_by_time(){
$time = $this->request->get('time/s','');
// if(empty($time)){
// $this->error(__('缺少必要参数'));
// }
try {
$res = (new Virtual)->getWeekByTime($time);
} catch (\Exception $e){
// Log::log($e->getMessage());
$this->apierror($e->getMessage(),['errcode'=>$e->getCode()]);
}
$this->apisuccess('生成成功', $res);
}
}

View File

@ -1,59 +0,0 @@
<?php
namespace app\manystoreapi\controller;
use app\common\controller\ManystoreBase;
use think\Config;
/**
* 控制台
*
* @icon fa fa-dashboard
* @remark 用于展示当前系统中的统计数据、统计报表及重要实时数据
*/
class Dashboard extends ManystoreBase
{
/**
* 查看
*/
public function index()
{
$seventtime = \fast\Date::unixtime('day', -7);
$paylist = $createlist = [];
for ($i = 0; $i < 7; $i++)
{
$day = date("Y-m-d", $seventtime + ($i * 86400));
$createlist[$day] = mt_rand(20, 200);
$paylist[$day] = mt_rand(1, mt_rand(1, $createlist[$day]));
}
$hooks = config('addons.hooks');
$uploadmode = isset($hooks['upload_config_init']) && $hooks['upload_config_init'] ? implode(',', $hooks['upload_config_init']) : 'local';
$addonComposerCfg = ROOT_PATH . '/vendor/karsonzhang/fastadmin-addons/composer.json';
Config::parse($addonComposerCfg, "json", "composer");
$config = Config::get("composer");
$addonVersion = isset($config['version']) ? $config['version'] : __('Unknown');
$this->view->assign([
'totaluser' => 35200,
'totalviews' => 219390,
'totalorder' => 32143,
'totalorderamount' => 174800,
'todayuserlogin' => 321,
'todayusersignup' => 430,
'todayorder' => 2324,
'unsettleorder' => 132,
'sevendnu' => '80%',
'sevendau' => '32%',
'paylist' => $paylist,
'createlist' => $createlist,
'addonversion' => $addonVersion,
'uploadmode' => $uploadmode
]);
$this->view->assign('check_full',(new \app\common\model\dyqc\ManystoreShop)->checkFull(SHOP_ID));
$this->view->assign('check_full_msg',(new \app\common\model\dyqc\ManystoreShop)->checkFullMsg(SHOP_ID));
return $this->view->fetch();
}
}

View File

@ -1,133 +0,0 @@
<?php
namespace app\manystoreapi\controller;
use app\manystore\model\ManystoreLog;
use app\common\controller\ManystoreBase;
use think\Config;
use think\Hook;
use think\Validate;
/**
* 后台首页
* @internal
*/
class Index extends ManystoreBase
{
protected $noNeedLogin = ['login'];
protected $noNeedRight = ['index', 'logout'];
protected $layout = '';
public function _initialize()
{
parent::_initialize();
//移除HTML标签
$this->request->filter('trim,strip_tags,htmlspecialchars');
}
/**
* 后台首页
*/
public function index()
{
//左侧菜单
$cookieArr = ['adminskin' => "/^skin\-([a-z\-]+)\$/i", 'multiplenav' => "/^(0|1)\$/", 'multipletab' => "/^(0|1)\$/", 'show_submenu' => "/^(0|1)\$/"];
foreach ($cookieArr as $key => $regex) {
$cookieValue = $this->request->cookie($key);
if (!is_null($cookieValue) && preg_match($regex, $cookieValue)) {
config('fastadmin.' . $key, $cookieValue);
}
}
list($menulist, $navlist, $fixedmenu, $referermenu) = $this->auth->getSidebar([
'dashboard' => 'hot',
'addon' => ['new', 'red', 'badge'],
'auth/rule' => __('Menu'),
'general' => ['new', 'purple'],
], $this->view->site['fixedpage']);
$action = $this->request->request('action');
if ($this->request->isPost()) {
if ($action == 'refreshmenu') {
$this->success('', null, ['menulist' => $menulist, 'navlist' => $navlist]);
}
}
$this->assignconfig('cookie', ['prefix' => config('cookie.prefix')]);
$this->view->assign('menulist', $menulist);
$this->view->assign('navlist', $navlist);
$this->view->assign('fixedmenu', $fixedmenu);
$this->view->assign('referermenu', $referermenu);
$this->view->assign('title', __('Home'));
return $this->view->fetch();
}
/**
* 管理员登录
*/
public function login()
{
$url = $this->request->get('url', 'index/index');
if ($this->auth->isLogin()) {
$this->success(__("You've logged in, do not login again"), $url);
}
if ($this->request->isPost()) {
$username = $this->request->post('username');
$password = $this->request->post('password');
$keeplogin = $this->request->post('keeplogin');
$token = $this->request->post('__token__');
$rule = [
'username' => 'require|length:3,30',
'password' => 'require|length:3,30',
'__token__' => 'require|token',
];
$data = [
'username' => $username,
'password' => $password,
'__token__' => $token,
];
// if (Config::get('fastadmin.login_captcha')) {
// $rule['captcha'] = 'require|captcha';
// $data['captcha'] = $this->request->post('captcha');
// }
// $validate = new Validate($rule, [], ['username' => __('Username'), 'password' => __('Password'), 'captcha' => __('Captcha')]);
$validate = new Validate($rule, [], ['username' => __('Username'), 'password' => __('Password')]);
$result = $validate->check($data);
if (!$result) {
$this->error($validate->getError(), $url, ['token' => $this->request->token()]);
}
ManystoreLog::setTitle(__('Login'));
$result = $this->auth->login($username, $password, $keeplogin ? 86400 : 0);
if ($result === true) {
Hook::listen("admin_login_after", $this->request);
$this->success(__('Login successful'), $url, ['url' => $url, 'id' => $this->auth->id, 'username' => $username, 'avatar' => $this->auth->avatar]);
} else {
$msg = $this->auth->getError();
$msg = $msg ? $msg : __('Username or password is incorrect');
$this->error($msg, $url, ['token' => $this->request->token()]);
}
}
// 根据客户端的cookie,判断是否可以自动登录
if ($this->auth->autologin()) {
$this->redirect($url);
}
$background = Config::get('fastadmin.login_background');
$background = stripos($background, 'http') === 0 ? $background : config('site.cdnurl') . $background;
$this->view->assign('background', $background);
$this->view->assign('title', __('Login'));
Hook::listen("admin_login_init", $this->request);
return $this->view->fetch();
}
/**
* 注销登录
*/
public function logout()
{
$this->auth->logout();
Hook::listen("manystore_logout_after", $this->request);
$this->success(__('Logout successful'), 'index/login');
}
}

View File

@ -0,0 +1,105 @@
<?php
namespace app\manystoreapi\controller;
use app\common\controller\ManystoreApiBase;
use app\common\library\Sms as Smslib;
use app\common\model\User;
use app\manystore\model\Manystore;
use think\Hook;
/**
* 机构API后台手机短信接口
*/
class Sms extends ManystoreApiBase
{
protected $noNeedLogin = '*';
protected $noNeedRight = '*';
/**
* 发送验证码
*
* @ApiMethod (POST)
* @ApiParams (name="mobile", type="string", required=true, description="手机号")
* @ApiParams (name="event", type="string", required=true, description="事件名称")
*/
public function send()
{
$mobile = $this->request->post("mobile");
$event = $this->request->post("event");
$event = $event ? $event : 'register';
if (!$mobile || !\think\Validate::regex($mobile, "^1\d{10}$")) {
$this->apierror(__('手机号不正确'));
}
$last = Smslib::get($mobile, $event);
if ($last && time() - $last['createtime'] < 60) {
$this->apierror(__('发送频繁'));
}
$ipSendTotal = \app\common\model\Sms::where(['ip' => $this->request->ip()])->whereTime('createtime', '-1 hours')->count();
if ($ipSendTotal >= 5) {
$this->apierror(__('发送频繁'));
}
if ($event) {
$userinfo = Manystore::getByMobile($mobile);
if ($event == 'register' && $userinfo) {
//已被注册
$this->apierror(__('已被注册'));
} elseif (in_array($event, ['changemobile']) && $userinfo) {
//被占用
$this->apierror(__('已被占用'));
} elseif (in_array($event, ['changepwd', 'resetpwd']) && !$userinfo) {
//未注册
$this->apierror(__('未注册'));
}
}
if (!Hook::get('sms_send')) {
$this->apierror(__('请在后台插件管理安装短信验证插件'));
}
$ret = Smslib::send($mobile, null, $event);
if ($ret) {
$this->apisuccess(__('发送成功'));
} else {
$this->apierror(__('发送失败,请检查短信配置是否正确'));
}
}
/**
* 检测验证码
*
* @ApiMethod (POST)
* @ApiParams (name="mobile", type="string", required=true, description="手机号")
* @ApiParams (name="event", type="string", required=true, description="事件名称")
* @ApiParams (name="captcha", type="string", required=true, description="验证码")
*/
public function check()
{
$mobile = $this->request->post("mobile");
$event = $this->request->post("event");
$event = $event ? $event : 'register';
$captcha = $this->request->post("captcha");
if (!$mobile || !\think\Validate::regex($mobile, "^1\d{10}$")) {
$this->apierror(__('手机号不正确'));
}
if ($event) {
$userinfo = Manystore::getByMobile($mobile);
if ($event == 'register' && $userinfo) {
//已被注册
$this->apierror(__('已被注册'));
} elseif (in_array($event, ['changemobile']) && $userinfo) {
//被占用
$this->apierror(__('已被占用'));
} elseif (in_array($event, ['changepwd', 'resetpwd']) && !$userinfo) {
//未注册
$this->apierror(__('未注册'));
}
}
$ret = Smslib::check($mobile, $captcha, $event);
if ($ret) {
$this->apisuccess(__('成功'));
} else {
$this->apierror(__('验证码不正确'));
}
}
}

View File

@ -2,13 +2,13 @@
namespace app\manystoreapi\controller; namespace app\manystoreapi\controller;
use app\common\controller\Api; use app\common\controller\ManystoreApiBase;
use fast\Random; use fast\Random;
/** /**
* Token接口 * 机构API后台Token接口
*/ */
class Token extends Api class Token extends ManystoreApiBase
{ {
protected $noNeedLogin = []; protected $noNeedLogin = [];
protected $noNeedRight = '*'; protected $noNeedRight = '*';
@ -20,8 +20,9 @@ class Token extends Api
public function check() public function check()
{ {
$token = $this->auth->getToken(); $token = $this->auth->getToken();
$tokenInfo = \app\common\library\Token::get($token); // $tokenInfo = \app\common\library\Token::get($token);
$this->success('', ['token' => $tokenInfo['token'], 'expires_in' => $tokenInfo['expires_in']]); $tokenInfo = \app\common\library\Token::init($this->auth->init_data)->get($token);
$this->apisuccess('', ['token' => $tokenInfo['token'], 'expires_in' => $tokenInfo['expires_in']]);
} }
/** /**
@ -32,11 +33,11 @@ class Token extends Api
{ {
//删除源Token //删除源Token
$token = $this->auth->getToken(); $token = $this->auth->getToken();
\app\common\library\Token::delete($token); \app\common\library\Token::init($this->auth->init_data)->delete($token);
//创建新Token //创建新Token
$token = Random::uuid(); $token = Random::uuid();
\app\common\library\Token::set($token, $this->auth->id, 2592000); \app\common\library\Token::init($this->auth->init_data)->set($token, $this->auth->id, 2592000);
$tokenInfo = \app\common\library\Token::get($token); $tokenInfo = \app\common\library\Token::init($this->auth->init_data)->get($token);
$this->success('', ['token' => $tokenInfo['token'], 'expires_in' => $tokenInfo['expires_in']]); $this->apisuccess('', ['token' => $tokenInfo['token'], 'expires_in' => $tokenInfo['expires_in']]);
} }
} }

View File

@ -1,13 +1,14 @@
<?php <?php
namespace app\api\controller; namespace app\manystoreapi\controller;
use addons\xilufitness\services\login\LoginService; use addons\xilufitness\services\login\LoginService;
use app\common\controller\Api; use app\common\controller\ManystoreApiBase;
use app\common\library\Ems; use app\common\library\Ems;
use app\common\library\Sms; use app\common\library\Sms;
use app\common\model\dyqc\ManystoreShop; use app\common\model\dyqc\ManystoreShop;
use app\common\model\manystore\UserAuth; use app\common\model\manystore\UserAuth;
use app\manystore\model\Manystore;
use fast\Random; use fast\Random;
use think\Cache; use think\Cache;
use think\Config; use think\Config;
@ -17,9 +18,9 @@ use think\Validate;
use app\admin\library\Wechat; use app\admin\library\Wechat;
/** /**
* 会员接口 * 机构API后台机构账户接口
*/ */
class User extends Api class User extends ManystoreApiBase
{ {
protected $noNeedLogin = ["registerLogin",'getOpenid','decodeData','login', 'mobilelogin', 'register', 'resetpwd', 'changeemail', 'changemobile', 'third']; protected $noNeedLogin = ["registerLogin",'getOpenid','decodeData','login', 'mobilelogin', 'register', 'resetpwd', 'changeemail', 'changemobile', 'third'];
protected $noNeedRight = '*'; protected $noNeedRight = '*';
@ -38,142 +39,6 @@ class User extends Api
/**
* @ApiTitle(获取小程序openid信息)
* @ApiSummary(根据前端code换取openid信息)
* @ApiRoute(/api/user/getOpenid)
* @ApiMethod(GET)
* @ApiParams(name="code",type="string",required=true,description="前端code值")
* @ApiHeaders(name = "brand-key", type = "string",require = true, description = "应用key")
* @ApiHeaders(name = "token", type = "string", require = true, description = "Token")
* @ApiReturnParams(name="code", type="integer",required=true, sample="0")
* @ApiReturnParams(name="msg", type="string",required=true, sample="获取成功")
* @ApiReturnParams(name="data", type="bject",required=true, description= "扩展数据")
* @ApiReturn({
"code" => 1,
"msg" => "获取成功",
"data" => {}
*})
*/
public function getOpenid(){
$code = $this->request->param('code/s');
try {
$result = LoginService::getInstance(['mini_config' => $this->miniConfig])->getOpenid($code);
} catch (\WeChat\Exceptions\LocalCacheException $e){
$this->error($e->getMessage());
} catch (\Exception $e){
$this->error($e->getMessage());
}
if(empty($result['openid'])){
$this->error(__('获取openid失败'),$result);
}
Cache::set('wechat_miniapp_code'.$code.$result['openid'],"1",60);
$this->success('',$result);
}
/**
* @ApiTitle(加密信息解密)
* @ApiSummary(解密微信信息)
* @ApiRoute(/api/user/decodeData)
* @ApiMethod(POST)
* @ApiParams(name = "iv", type = "string",required=true)
* @ApiParams(name = "encryptedData", type = "string",required=true)
* @ApiParams(name = "sessionKey", type = "string",required=true)
* @ApiHeaders(name = "brand-key", type = "string",require = true, description = "应用key")
* @ApiHeaders(name = "token", type = "string", require = true, description = "Token")
* @ApiReturn({
"code" => 1,
"msg" => "获取成功",
"data" => {}
*})
*/
public function decodeData() {
$iv = $this->request->param('iv/s');
$encryptedData = $this->request->param('encryptedData/s');
$sessionKey = $this->request->param('sessionKey/s');
if(empty($iv) || empty($encryptedData) || empty($sessionKey)){
$this->error(__('Params error'));
}
$result = LoginService::getInstance(['mini_config' => $this->miniConfig])->decodeData($iv,$sessionKey,$encryptedData);
$info = empty($result["phoneNumber"]) ? ($result["purePhoneNumber"] ?? '' ) : $result["phoneNumber"];
Cache::set('wechat_miniapp_core'.$info,"1",60);
$this->success('',$result);
}
/**
* @ApiTitle(微信小程序授权登录注册通用[支持静默登录])
* @ApiSummary(登录注册通用-支持静默登录)
* @ApiRoute(/api/user/registerLogin)
* @ApiMethod(POST)
* @ApiParams(name = "mobile", type = "string",required=false,description = "mobile 静默非必传,手机授权必传")
* @ApiParams(name = "unionid", type = "string",required=false, description = "unionid 非必传")
* @ApiParams(name = "apptype", type = "string",required=false, description = "应用类型默认miniapp")
* @ApiParams(name = "platform", type = "string",require=false, description = "平台标识默认wechat")
* @ApiParams(name = "openid", type = "string", require=true, description = "授权的openid")
* @ApiParams(name = "keeptime", type = "string", require=false, description = "token保持时间默认0永久")
* @ApiParams(name = "code", type = "string", require=true, description = "授权的code")
* @ApiReturn({
"code" => 1,
"msg" => "获取成功",
"data" => {tokenxxxxx,'errcode':0(如果为30001则是需要重新授权)}
*})
*/
public function registerLogin(){
$extend= $params = [];
$extend['mobile'] = $this->request->param('mobile/s','');
$params['unionid'] = $this->request->param('unionid/s','');
$params['apptype'] = $this->request->param('apptype/s','miniapp');
$params['openid'] = $this->request->param('openid/s','');
$platform = $this->request->param('platform/s','wechat');
$code = $this->request->param('code/s','');
if(empty($code)){
$this->error(__('缺少code'));
}
//手机号变必填
// if(empty($extend['mobile'])){
// $this->error(__('未传手机号'));
// }
$wechat_mini_code = Cache::get("{$platform}_{$params['apptype']}_code".$code.$params['openid']);
if(!$wechat_mini_code)$this->error("授权code已过期或已使用请重新发起授权",['errcode'=>30002]);
if($extend['mobile']){
$wechat_mini_mobile = Cache::get("{$platform}_{$params['apptype']}_core".$extend['mobile']);
if(!$wechat_mini_mobile)$this->error("授权手机号已过期或已使用,请重新发起授权!",['errcode'=>30002]);
}
//推荐人:逻辑未实现
$rec_user_id = $this->request->param('rec_user_id',0,'xilufitness_get_id_value');
$keeptime = $this->request->param('keeptime/d',0);
//access_token
try {
\addons\third\library\Service::loginAndRegisterByMobile($platform, $params, $extend, $keeptime);
} catch (\Exception $e){
Log::log($e->getMessage());
$this->error($e->getMessage(),['errcode'=>$e->getCode()]);
}
Cache::rm("{$platform}_{$params['apptype']}_code".$code.$params['openid']);
if($extend['mobile']){
Cache::rm("{$platform}_{$params['apptype']}_core".$extend['mobile']);
}
$this->success('获取成功', ['token' => $this->auth->getToken()]);
}
/** /**
@ -186,14 +51,9 @@ class User extends Api
'welcome' => $this->auth->nickname, 'welcome' => $this->auth->nickname,
'user_info'=>$this->auth->getUserinfo() 'user_info'=>$this->auth->getUserinfo()
]; ];
//是否有核销按钮展示权
$data['have_auth'] = \app\common\model\User::verificationAuth($this->auth->id);
$data['have_teacher'] = \app\common\model\User::teacherAuth($this->auth->id);
//机构认证信息
$data['shop_auth_info'] = ManystoreShop::getAuthInfo($this->auth->id);
$data['user_info']["avatar"] = $data['user_info']["avatar"]? cdnurl($data['user_info']["avatar"],true):$data['user_info']["avatar"]; $data['user_info']["avatar"] = $data['user_info']["avatar"]? cdnurl($data['user_info']["avatar"],true):$data['user_info']["avatar"];
$this->success('调用成功',$data); $this->apisuccess('调用成功',$data);
} }
/** /**
@ -208,14 +68,14 @@ class User extends Api
$account = $this->request->post('account'); $account = $this->request->post('account');
$password = $this->request->post('password'); $password = $this->request->post('password');
if (!$account || !$password) { if (!$account || !$password) {
$this->error(__('Invalid parameters')); $this->apierror(__('Invalid parameters'));
} }
$ret = $this->auth->login($account, $password); $ret = $this->auth->login($account, $password);
if ($ret) { if ($ret) {
$data = ['userinfo' => $this->auth->getUserinfo()]; $data = ['userinfo' => $this->auth->getUserinfo()];
$this->success(__('Logged in successful'), $data); $this->apisuccess(__('Logged in successful'), $data);
} else { } else {
$this->error($this->auth->getError()); $this->apierror($this->auth->getError());
} }
} }
@ -239,7 +99,7 @@ class User extends Api
if (!Sms::check($mobile, $captcha, 'mobilelogin')) { if (!Sms::check($mobile, $captcha, 'mobilelogin')) {
$this->error(__('Captcha is incorrect')); $this->error(__('Captcha is incorrect'));
} }
$user = \app\common\model\User::getByMobile($mobile); $user = Manystore::getByMobile($mobile);
if ($user) { if ($user) {
if ($user->status != 'normal') { if ($user->status != 'normal') {
$this->error(__('Account is locked')); $this->error(__('Account is locked'));
@ -247,55 +107,19 @@ class User extends Api
//如果已经有账号则直接登录 //如果已经有账号则直接登录
$ret = $this->auth->direct($user->id); $ret = $this->auth->direct($user->id);
} else { } else {
$ret = $this->auth->register($mobile, Random::alnum(), '', $mobile, []); $ret = null;
// $ret = $this->auth->register($mobile, Random::alnum(), '', $mobile, []);
} }
if ($ret) { if ($ret) {
Sms::flush($mobile, 'mobilelogin'); Sms::flush($mobile, 'mobilelogin');
$data = ['userinfo' => $this->auth->getUserinfo()]; $data = ['userinfo' => $this->auth->getUserinfo()];
$this->success(__('Logged in successful'), $data); $this->apisuccess(__('Logged in successful'), $data);
} else { } else {
$this->error($this->auth->getError()); $this->apierror($this->auth->getError());
} }
} }
/**
* 注册会员
*
* @ApiMethod (POST)
* @ApiParams (name="username", type="string", required=true, description="用户名")
* @ApiParams (name="password", type="string", required=true, description="密码")
* @ApiParams (name="email", type="string", required=true, description="邮箱")
* @ApiParams (name="mobile", type="string", required=true, description="手机号")
* @ApiParams (name="code", type="string", required=true, description="验证码")
*/
public function register()
{
$username = $this->request->post('username');
$password = $this->request->post('password');
$email = $this->request->post('email');
$mobile = $this->request->post('mobile');
$code = $this->request->post('code');
if (!$username || !$password) {
$this->error(__('Invalid parameters'));
}
if ($email && !Validate::is($email, "email")) {
$this->error(__('Email is incorrect'));
}
if ($mobile && !Validate::regex($mobile, "^1\d{10}$")) {
$this->error(__('Mobile is incorrect'));
}
$ret = Sms::check($mobile, $code, 'register');
if (!$ret) {
$this->error(__('Captcha is incorrect'));
}
$ret = $this->auth->register($username, $password, $email, $mobile, []);
if ($ret) {
$data = ['userinfo' => $this->auth->getUserinfo()];
$this->success(__('Sign up successful'), $data);
} else {
$this->error($this->auth->getError());
}
}
/** /**
* 退出登录 * 退出登录
@ -304,10 +128,10 @@ class User extends Api
public function logout() public function logout()
{ {
if (!$this->request->isPost()) { if (!$this->request->isPost()) {
$this->error(__('Invalid parameters')); $this->apierror(__('Invalid parameters'));
} }
$this->auth->logout(); $this->auth->logout();
$this->success(__('Logout successful')); $this->apisuccess(__('Logout successful'));
} }
/** /**
@ -318,11 +142,6 @@ class User extends Api
* @ApiParams (name="avatar", type="string", required=true, description="头像地址") * @ApiParams (name="avatar", type="string", required=true, description="头像地址")
* @ApiParams (name="username", type="string", required=true, description="用户名") * @ApiParams (name="username", type="string", required=true, description="用户名")
* @ApiParams (name="nickname", type="string", required=true, description="昵称") * @ApiParams (name="nickname", type="string", required=true, description="昵称")
* @ApiParams (name="realname", type="string", required=true, description="姓名")
* @ApiParams (name="gender", type="int", required=true, description="性别0女 1男")
* @ApiParams (name="birthday", type="string", required=true, description="出生日期:日期字符串 比如”1995-9-20")
* @ApiParams (name="work", type="string", required=true, description="职业")
* @ApiParams (name="bio", type="string", required=true, description="个人简介")
*/ */
public function profile() public function profile()
{ {
@ -333,45 +152,45 @@ class User extends Api
if(!$update_fields)$this->error(__('请指定要更新的字段!')); if(!$update_fields)$this->error(__('请指定要更新的字段!'));
$username = $this->request->post('username/s'); $username = $this->request->post('username/s');
$nickname = $this->request->post('nickname/s'); $nickname = $this->request->post('nickname/s');
$realname = $this->request->post('realname/s'); // $realname = $this->request->post('realname/s');
$gender = $this->request->post('gender/d'); // $gender = $this->request->post('gender/d');
$birthday = $this->request->post('birthday/s'); // $birthday = $this->request->post('birthday/s');
$work = $this->request->post('work/s'); // $work = $this->request->post('work/s');
$bio = $this->request->post('bio/s',null); // $bio = $this->request->post('bio/s',null);
$avatar = $this->request->post('avatar', null, 'trim,strip_tags,htmlspecialchars'); $avatar = $this->request->post('avatar', null, 'trim,strip_tags,htmlspecialchars');
if ($username && in_array('username', $update_fields)) { if ($username && in_array('username', $update_fields)) {
$exists = \app\common\model\User::where('username', $username)->where('id', '<>', $this->auth->id)->find(); $exists = Manystore::where('username', $username)->where('id', '<>', $this->auth->id)->find();
if ($exists) { if ($exists) {
$this->error(__('Username already exists')); $this->apierror(__('Username already exists'));
} }
$user->username = $username; $user->username = $username;
} }
if ($nickname && in_array('nickname', $update_fields)) { if ($nickname && in_array('nickname', $update_fields)) {
$exists = \app\common\model\User::where('nickname', $nickname)->where('id', '<>', $this->auth->id)->find(); $exists = Manystore::where('nickname', $nickname)->where('id', '<>', $this->auth->id)->find();
if ($exists) { if ($exists) {
$this->error(__('Nickname already exists')); $this->apierror(__('Nickname already exists'));
} }
$user->nickname = $nickname; $user->nickname = $nickname;
} }
if(in_array('bio', $update_fields))$user->bio = $bio; // if(in_array('bio', $update_fields))$user->bio = $bio;
if($avatar!==null && in_array('avatar', $update_fields))$user->avatar = $avatar; if($avatar!==null && in_array('avatar', $update_fields))$user->avatar = $avatar;
if(in_array('realname', $update_fields))$user->realname = $realname; // if(in_array('realname', $update_fields))$user->realname = $realname;
if(in_array('gender', $update_fields)){ // if(in_array('gender', $update_fields)){
if(!in_array($gender, [1,0]))$this->error(__('请输入正确的性别!')); // if(!in_array($gender, [1,0]))$this->error(__('请输入正确的性别!'));
$user->gender = $gender; // $user->gender = $gender;
} // }
if(in_array('birthday', $update_fields))$user->birthday = $birthday; // if(in_array('birthday', $update_fields))$user->birthday = $birthday;
if(in_array('work', $update_fields))$user->work = $work; // if(in_array('work', $update_fields))$user->work = $work;
$user->save(); $user->save();
//调用事件 //调用事件
$datas = ['user' => $user]; $datas = ['user' => $user];
\think\Hook::listen('user_update_after', $datas); \think\Hook::listen('manystore_update_after', $datas);
$this->success(); $this->apisuccess();
} }
/** /**
@ -387,26 +206,26 @@ class User extends Api
$email = $this->request->post('email'); $email = $this->request->post('email');
$captcha = $this->request->post('captcha'); $captcha = $this->request->post('captcha');
if (!$email || !$captcha) { if (!$email || !$captcha) {
$this->error(__('Invalid parameters')); $this->apierror(__('Invalid parameters'));
} }
if (!Validate::is($email, "email")) { if (!Validate::is($email, "email")) {
$this->error(__('Email is incorrect')); $this->apierror(__('Email is incorrect'));
} }
if (\app\common\model\User::where('email', $email)->where('id', '<>', $user->id)->find()) { if (Manystore::where('email', $email)->where('id', '<>', $user->id)->find()) {
$this->error(__('Email already exists')); $this->apierror(__('Email already exists'));
} }
$result = Ems::check($email, $captcha, 'changeemail'); $result = Ems::check($email, $captcha, 'changeemail');
if (!$result) { if (!$result) {
$this->error(__('Captcha is incorrect')); $this->apierror(__('Captcha is incorrect'));
} }
$verification = $user->verification; // $verification = $user->verification;
$verification->email = 1; // $verification->email = 1;
$user->verification = $verification; // $user->verification = $verification;
$user->email = $email; $user->email = $email;
$user->save(); $user->save();
Ems::flush($email, 'changeemail'); Ems::flush($email, 'changeemail');
$this->success(); $this->apisuccess();
} }
/** /**
@ -422,118 +241,87 @@ class User extends Api
$mobile = $this->request->post('mobile'); $mobile = $this->request->post('mobile');
$captcha = $this->request->post('captcha'); $captcha = $this->request->post('captcha');
if (!$mobile || !$captcha) { if (!$mobile || !$captcha) {
$this->error(__('Invalid parameters')); $this->apierror(__('Invalid parameters'));
} }
if (!Validate::regex($mobile, "^1\d{10}$")) { if (!Validate::regex($mobile, "^1\d{10}$")) {
$this->error(__('Mobile is incorrect')); $this->apierror(__('Mobile is incorrect'));
} }
if (\app\common\model\User::where('mobile', $mobile)->where('id', '<>', $user->id)->find()) { if (Manystore::where('mobile', $mobile)->where('id', '<>', $user->id)->find()) {
$this->error(__('Mobile already exists')); $this->apierror(__('Mobile already exists'));
} }
$result = Sms::check($mobile, $captcha, 'changemobile'); $result = Sms::check($mobile, $captcha, 'changemobile');
if (!$result) { if (!$result) {
$this->error(__('Captcha is incorrect')); $this->apierror(__('Captcha is incorrect'));
} }
$verification = $user->verification; // $verification = $user->verification;
$verification->mobile = 1; // $verification->mobile = 1;
$user->verification = $verification; // $user->verification = $verification;
$user->mobile = $mobile; $user->mobile = $mobile;
$user->save(); $user->save();
Sms::flush($mobile, 'changemobile'); Sms::flush($mobile, 'changemobile');
$this->success(); $this->apisuccess();
} }
/**
* 第三方登录
*
* @ApiMethod (POST)
* @ApiParams (name="platform", type="string", required=true, description="平台名称")
* @ApiParams (name="code", type="string", required=true, description="Code码")
*/
public function third()
{
$url = url('user/index');
$platform = $this->request->post("platform");
$code = $this->request->post("code");
$config = get_addon_config('third');
if (!$config || !isset($config[$platform])) {
$this->error(__('Invalid parameters'));
}
$app = new \addons\third\library\Application($config);
//通过code换access_token和绑定会员
$result = $app->{$platform}->getUserInfo(['code' => $code]);
if ($result) {
$loginret = \addons\third\library\Service::connect($platform, $result);
if ($loginret) {
$data = [
'userinfo' => $this->auth->getUserinfo(),
'thirdinfo' => $result
];
$this->success(__('Logged in successful'), $data);
}
}
$this->error(__('Operation failed'), $url);
}
/** // /**
* 重置密码 // * 重置密码
* // *
* @ApiMethod (POST) // * @ApiMethod (POST)
* @ApiParams (name="mobile", type="string", required=true, description="手机号") // * @ApiParams (name="mobile", type="string", required=true, description="手机号")
* @ApiParams (name="newpassword", type="string", required=true, description="新密码") // * @ApiParams (name="newpassword", type="string", required=true, description="新密码")
* @ApiParams (name="captcha", type="string", required=true, description="验证码") // * @ApiParams (name="captcha", type="string", required=true, description="验证码")
*/ // */
public function resetpwd() // public function resetpwd()
{ // {
$type = $this->request->post("type", "mobile"); // $type = $this->request->post("type", "mobile");
$mobile = $this->request->post("mobile"); // $mobile = $this->request->post("mobile");
$email = $this->request->post("email"); // $email = $this->request->post("email");
$newpassword = $this->request->post("newpassword"); // $newpassword = $this->request->post("newpassword");
$captcha = $this->request->post("captcha"); // $captcha = $this->request->post("captcha");
if (!$newpassword || !$captcha) { // if (!$newpassword || !$captcha) {
$this->error(__('Invalid parameters')); // $this->error(__('Invalid parameters'));
} // }
//验证Token // //验证Token
if (!Validate::make()->check(['newpassword' => $newpassword], ['newpassword' => 'require|regex:\S{6,30}'])) { // if (!Validate::make()->check(['newpassword' => $newpassword], ['newpassword' => 'require|regex:\S{6,30}'])) {
$this->error(__('Password must be 6 to 30 characters')); // $this->error(__('Password must be 6 to 30 characters'));
} // }
if ($type == 'mobile') { // if ($type == 'mobile') {
if (!Validate::regex($mobile, "^1\d{10}$")) { // if (!Validate::regex($mobile, "^1\d{10}$")) {
$this->error(__('Mobile is incorrect')); // $this->error(__('Mobile is incorrect'));
} // }
$user = \app\common\model\User::getByMobile($mobile); // $user = \app\common\model\User::getByMobile($mobile);
if (!$user) { // if (!$user) {
$this->error(__('User not found')); // $this->error(__('User not found'));
} // }
$ret = Sms::check($mobile, $captcha, 'resetpwd'); // $ret = Sms::check($mobile, $captcha, 'resetpwd');
if (!$ret) { // if (!$ret) {
$this->error(__('Captcha is incorrect')); // $this->error(__('Captcha is incorrect'));
} // }
Sms::flush($mobile, 'resetpwd'); // Sms::flush($mobile, 'resetpwd');
} else { // } else {
if (!Validate::is($email, "email")) { // if (!Validate::is($email, "email")) {
$this->error(__('Email is incorrect')); // $this->error(__('Email is incorrect'));
} // }
$user = \app\common\model\User::getByEmail($email); // $user = \app\common\model\User::getByEmail($email);
if (!$user) { // if (!$user) {
$this->error(__('User not found')); // $this->error(__('User not found'));
} // }
$ret = Ems::check($email, $captcha, 'resetpwd'); // $ret = Ems::check($email, $captcha, 'resetpwd');
if (!$ret) { // if (!$ret) {
$this->error(__('Captcha is incorrect')); // $this->error(__('Captcha is incorrect'));
} // }
Ems::flush($email, 'resetpwd'); // Ems::flush($email, 'resetpwd');
} // }
//模拟一次登录 // //模拟一次登录
$this->auth->direct($user->id); // $this->auth->direct($user->id);
$ret = $this->auth->changepwd($newpassword, '', true); // $ret = $this->auth->changepwd($newpassword, '', true);
if ($ret) { // if ($ret) {
$this->success(__('Reset password successful')); // $this->success(__('Reset password successful'));
} else { // } else {
$this->error($this->auth->getError()); // $this->error($this->auth->getError());
} // }
} // }

View File

@ -244,22 +244,22 @@ class ManystoreAuth
return $ids; return $ids;
} }
/** // /**
* 获得用户资料 // * 获得用户资料
* @param int $uid 用户id // * @param int $uid 用户id
* @return mixed // * @return mixed
*/ // */
protected function getUserInfo($uid) // protected function getUserInfo($uid)
{ // {
static $user_info = []; // static $user_info = [];
//
$user = Db::name($this->config['auth_user']); // $user = Db::name($this->config['auth_user']);
// 获取用户表主键 // // 获取用户表主键
$_pk = is_string($user->getPk()) ? $user->getPk() : 'uid'; // $_pk = is_string($user->getPk()) ? $user->getPk() : 'uid';
if (!isset($user_info[$uid])) { // if (!isset($user_info[$uid])) {
$user_info[$uid] = $user->where($_pk, $uid)->find(); // $user_info[$uid] = $user->where($_pk, $uid)->find();
} // }
//
return $user_info[$uid]; // return $user_info[$uid];
} // }
} }

View File

@ -1,6 +1,6 @@
@import url("../css/bootstrap.css"); @import url("../css/bootstrap.css");
@import url("../css/fastadmin.css"); @import url("../css/fastadmin.css");
@import url("../css/skins/skin-black-blue.css"); @import url("../css/skins/skin-blue-light.css");
@import url("../css/iconfont.css"); @import url("../css/iconfont.css");
@import url("../libs/font-awesome/css/font-awesome.min.css"); @import url("../libs/font-awesome/css/font-awesome.min.css");
@import url("../libs/toastr/toastr.min.css"); @import url("../libs/toastr/toastr.min.css");

View File

@ -1,6 +1,6 @@
@import url("../css/bootstrap.css"); @import url("../css/bootstrap.css");
@import url("../css/fastadmin.css"); @import url("../css/fastadmin.css");
@import url("../css/skins/skin-black-blue.css"); @import url("../css/skins/skin-black-light.css");
@import url("../css/iconfont.css"); @import url("../css/iconfont.css");
@import url("../libs/font-awesome/css/font-awesome.min.css"); @import url("../libs/font-awesome/css/font-awesome.min.css");
@import url("../libs/toastr/toastr.min.css"); @import url("../libs/toastr/toastr.min.css");