This commit is contained in:
wuyanwen 2019-12-02 22:58:11 +08:00
parent 0b67395085
commit 38bcb43e70
277 changed files with 0 additions and 40995 deletions

View File

@ -1,15 +0,0 @@
app_debug=true
app_trace=true
db_connection=mysql
db_host=localhost
db_database=thinking
db_username=user
db_port=3306
db_password=password
redis_host=
redis_port=
redis_password=

7
.gitignore vendored
View File

@ -1,7 +0,0 @@
/.idea
/.vscode
/vendor
*.log
thinkphp
.env
.DS_Store

View File

@ -1,42 +0,0 @@
sudo: false
language: php
branches:
only:
- stable
cache:
directories:
- $HOME/.composer/cache
before_install:
- composer self-update
install:
- composer install --no-dev --no-interaction --ignore-platform-reqs
- zip -r --exclude='*.git*' --exclude='*.zip' --exclude='*.travis.yml' ThinkPHP_Core.zip .
- composer require --update-no-dev --no-interaction "topthink/think-image:^1.0"
- composer require --update-no-dev --no-interaction "topthink/think-migration:^1.0"
- composer require --update-no-dev --no-interaction "topthink/think-captcha:^1.0"
- composer require --update-no-dev --no-interaction "topthink/think-mongo:^1.0"
- composer require --update-no-dev --no-interaction "topthink/think-worker:^1.0"
- composer require --update-no-dev --no-interaction "topthink/think-helper:^1.0"
- composer require --update-no-dev --no-interaction "topthink/think-queue:^1.0"
- composer require --update-no-dev --no-interaction "topthink/think-angular:^1.0"
- composer require --dev --update-no-dev --no-interaction "topthink/think-testing:^1.0"
- zip -r --exclude='*.git*' --exclude='*.zip' --exclude='*.travis.yml' ThinkPHP_Full.zip .
script:
- php think unit
deploy:
provider: releases
api_key:
secure: TSF6bnl2JYN72UQOORAJYL+CqIryP2gHVKt6grfveQ7d9rleAEoxlq6PWxbvTI4jZ5nrPpUcBUpWIJHNgVcs+bzLFtyh5THaLqm39uCgBbrW7M8rI26L8sBh/6nsdtGgdeQrO/cLu31QoTzbwuz1WfAVoCdCkOSZeXyT/CclH99qV6RYyQYqaD2wpRjrhA5O4fSsEkiPVuk0GaOogFlrQHx+C+lHnf6pa1KxEoN1A0UxxVfGX6K4y5g4WQDO5zT4bLeubkWOXK0G51XSvACDOZVIyLdjApaOFTwamPcD3S1tfvuxRWWvsCD5ljFvb2kSmx5BIBNwN80MzuBmrGIC27XLGOxyMerwKxB6DskNUO9PflKHDPI61DRq0FTy1fv70SFMSiAtUv9aJRT41NQh9iJJ0vC8dl+xcxrWIjU1GG6+l/ZcRqVx9V1VuGQsLKndGhja7SQ+X1slHl76fRq223sMOql7MFCd0vvvxVQ2V39CcFKao/LB1aPH3VhODDEyxwx6aXoTznvC/QPepgWsHOWQzKj9ftsgDbsNiyFlXL4cu8DWUty6rQy8zT2b4O8b1xjcwSUCsy+auEjBamzQkMJFNlZAIUrukL/NbUhQU37TAbwsFyz7X0E/u/VMle/nBCNAzgkMwAUjiHM6FqrKKBRWFbPrSIixjfjkCnrMEPw=
file:
- ThinkPHP_Core.zip
- ThinkPHP_Full.zip
skip_cleanup: true
on:
tags: true

20
LICENSE
View File

@ -1,20 +0,0 @@
The MIT License (MIT)
Copyright (c) 2018 JaguarJack
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@ -1,81 +0,0 @@
# think-admin
# ENV
- php >= 7.1.3
- mysql >= 5.5
# install
- curl -sS http://install.phpcomposer.com/installer | php
- composer config -g repo.packagist composer https://packagist.laravel-china.org
- composer update
- 修改根目录下 .env.emp .env
- .env 配置数据库信息
- php think migrate:run
- php think seed:run
# Use
- 配置虚拟域名 OR 在根目录下执行 php think run
- yourUrl/login
- 默认用户名 admin 密码 admin
# nginx 配置
```
server {
listen 端口;
server_name 域名;
access_log logs/wenwen.access.log;
root 项目目录/public;
index index.php index.html index.htm;
location / {
index index.php index.html index.htm;
if (!-e $request_filename) {
rewrite ^(.*)$ /index.php?s=$1 last;
break;
}
}
#error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
location ~ \.php$ {
root 项目目录/public;
fastcgi_pass phpfastcgi;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
location ^~ /data {
deny all;
}
}
```
# Problem
> SQLSTATE[42000]: Syntax error or access violation: 1067 Invalid default value for 'updated_at'
设置 sql_mode;
```
show variables like 'sql_mode' ;
```
> remove 'NO_ZERO_IN_DATE,NO_ZERO_DATE'
```
SET GLOBAL sql_mode='STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION'
```
# Test Address
<a href="http://tp5.whwww.net" target="__BLANK">测试地址</a>
- 账号admin
- 密码: 123456
# Talking
- 可以提 ISSUE请按照 issue 模板提问
- 欢迎进入 Q 群,可以及时反馈一些问题。
- ![输入图片说明](https://images.gitee.com/uploads/images/2018/1219/110300_0257b6c0_810218.jpeg "微信图片_20181219105915.jpg")
仅供学习

View File

@ -1 +0,0 @@
deny from all

View File

@ -1,48 +0,0 @@
<?php
namespace app\admin\controller;
use think\Controller;
use app\traits\ControllerTrait;
abstract class Base extends Controller
{
use ControllerTrait;
protected $limit = 10;
protected $page = 1;
protected $middleware = ['checkLogin', 'auth', 'logRecord'];
/**
* 过滤参数
*
* @time at 2018年11月15日
* @param $params
* @return void
*/
protected function checkParams(&$params)
{
$this->limit = $params['limit'] ?? $this->limit;
$this->page = $params['page'] ?? $this->page;
foreach ($params as $key => $param) {
if (!$param || $key == 'limit' || $key == 'page') {
unset($params[$key]);
}
}
$this->start = $this->start();
}
/**
* Table ID Start
*
* @time at 2018年11月16日
* @return float|int
*/
protected function start()
{
return (int)$this->limit * ((int)$this->page - 1) + 1;
}
}

View File

@ -1,63 +0,0 @@
<?php
/**
* Created by PhpStorm.
* User: Administrator
* Date: 2019/1/18
* Time: 10:36
*/
namespace app\admin\controller;
use think\Db;
class Database extends Base
{
/**
* 数据字典列表
*
* @time at 2019年01月18日
* @return mixed
*/
public function index()
{
$this->tables = Db::query('SHOW TABLE STATUS');
return $this->fetch();
}
/**
* 优化表
*
* @time at 2019年01月18日
* @return void
*/
public function optimize()
{
$table = $this->request->post('table');
if (!$table) {
$this->error('参数错误, 未指定表');
}
Db::query(sprintf('optimize table %s', $table)) ? $this->success('优化成功') : $this->error('优化失败');
}
/**
*
*
* @time at 2019年01月18日
* @return void
*/
public function view()
{
$table = $this->request->param('table');
if (!$table) {
$this->error('参数错误', '未指定表');
}
$this->table = Db::query('show full columns from ' . $table);
return $this->fetch();
}
}

View File

@ -1,43 +0,0 @@
<?php
namespace app\admin\controller;
use think\permissions\facade\Permissions;
use think\permissions\facade\Roles;
use app\service\MenuService;
class Index extends Base
{
protected $middleware = [ 'checkLogin' ];
/**
* 首页
*
* @time at 2018年11月15日
* @return mixed|string
*/
public function index(MenuService $menuService)
{
$loginUser = $this->getLoginUser();
$userHasRoles = $loginUser->getRoles();
$permissionIds = [];
$userHasRoles->each(function ($role, $key) use (&$permissionIds) {
$permissionIds = array_merge($permissionIds, Roles::getRoleBy($role->id)->getPermissions(false));
});
$permissions = Permissions::whereIn('id', $permissionIds)->where('is_show', 1)->select();
$this->permissions = $menuService->tree($permissions);
$this->loginUser = $loginUser;
return $this->fetch();
}
/**
* main
*
* @time at 2018年11月16日
* @return mixed|string
*/
public function main()
{
return $this->fetch();
}
}

View File

@ -1,30 +0,0 @@
<?php
/**
* Created by PhpStorm.
* User: Administrator
* Date: 2019/1/18
* Time: 9:01
*/
namespace app\admin\controller;
use app\model\LogRecordModel;
class Log extends Base
{
/**
* 日志列表
*
* @time at 2019年01月18日
* @param LogRecordModel $logRecordModel
* @return mixed
*/
public function index(LogRecordModel $logRecordModel)
{
$params = $this->request->param();
$this->checkParams($params);
$this->list = $logRecordModel->getAll($params, $this->limit);
return $this->fetch();
}
}

View File

@ -1,55 +0,0 @@
<?php
namespace app\admin\controller;
use app\traits\Auth;
use think\Controller;
class Login extends Controller
{
use Auth;
protected $redirect = '/index';
/**
* Login Page
*
* @return mixed
*/
public function login()
{
// 登录逻辑
if ($this->request->isPost()) {
$this->authLogin($this->request);
}
return $this->fetch('/index/login');
}
/**
* 登出
*
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector|\think\response\Redirect
*/
public function logout()
{
$this->authLogout();
return redirect(url('login'));
}
/**
* 验证规则
*
* @time at 2018年11月13日
* @return array
*/
protected function rule()
{
return [
$this->name() => 'require',
'password|密码' => 'require',
'captcha|验证码' => 'require|captcha'
];
}
}

View File

@ -1,78 +0,0 @@
<?php
namespace app\admin\controller;
use think\Collection;
use think\permissions\facade\Permissions;
use app\admin\request\PermissionRequest;
use app\service\MenuService;
class Permission extends Base
{
public function index(MenuService $menuService)
{
$this->permissions = new Collection($menuService->sort(Permissions::select()));
return $this->fetch();
}
/**
* Create Data
*
* @time at 2018年11月13日
* @return mixed|string
*/
public function create(PermissionRequest $request, MenuService $menuService)
{
if ($request->isPost()) {
$data = $request->post();
Permissions::store($data) ? $this->success('添加成功', url('permission/index')) : $this->error('添加失败');
}
$this->permissions = $menuService->sort(Permissions::select());
$this->permissionId = $this->request->param('id') ?? 0;
return $this->fetch();
}
/**
* Edit Data
*
* @time at 2018年11月13日
* @return mixed|string
*/
public function edit(PermissionRequest $request, MenuService $menuService)
{
if ($request->isPost()) {
$data = $request->post();
Permissions::updateBy($data['id'], $data) !== false ? $this->success('编辑成功', url('permission/index')) : $this->error('');
}
$permissionId = $this->request->param('id');
if (!$permissionId) {
$this->error('不存在的数据');
}
$this->permissions = $menuService->sort(Permissions::select());
$this->permission = Permissions::getPermissionBy($permissionId);
return $this->fetch();
}
/**
* Delete Data
*
* @time at 2018年11月13日
* @return void
*/
public function delete()
{
$permissionId = $this->request->post('id');
if (!$permissionId) {
$this->error('不存在数据');
}
if (Permissions::where('pid', $permissionId)->find()) {
$this->error('请先删除子菜单');
}
// 删除权限关联的角色信息
Permissions::detachRole($permissionId);
if (Permissions::deleteBy($permissionId)) {
$this->success('删除成功', url('permission/index'));
}
$this->error('删除失败');
}
}

View File

@ -1,115 +0,0 @@
<?php
namespace app\admin\controller;
use think\permissions\facade\Roles;
use app\admin\request\RoleRequest;
use think\permissions\facade\Permissions;
use app\service\MenuService;
class Role extends Base
{
public function index()
{
$this->roles = Roles::paginate(10);
return $this->fetch();
}
/**
* create Data
*
* @time at 2018年11月13日
* @return mixed|string
*/
public function create(RoleRequest $request)
{
if ($request->isPost()) {
Roles::store($request->post()) ? $this->success('创建成功', url('role/index')) : $this->error('创建失败');
}
return $this->fetch();
}
/**
* Edit Data
*
* @time at 2018年11月13日
* @return mixed|string
*/
public function edit(RoleRequest $request)
{
if ($this->request->isPost()) {
Roles::updateBy($request->post('id'), $request->post()) !== false ? $this->success('编辑成功', url('role/index')) : $this->error('编辑失败');
}
$this->role = Roles::getRoleBy($this->request->param('id'));
return $this->fetch();
}
/**
* Delete Data
*
* @time at 2018年11月13日
* @return void
*/
public function delete()
{
$roleId = $this->request->post('id');
if (!$roleId) {
$this->error('角色信息不存在');
}
// 删除角色相关的用户
Roles::detachUsers($roleId);
// 删除角色相关的权限
Roles::detachPermissions($roleId);
if (Roles::deleteBy($roleId)) {
$this->success('删除成功', url('role/index'));
}
$this->error('删除失败');
}
/**
* 获取角色权限
*
* @time at 2018年09月21日
* @return void
*/
public function getPermissionsOfRole(MenuService $menuService)
{
$field = ['name', 'id', 'pid'];
$roleId = $this->request->post('role_id');
$permissions = Permissions::field($field)->all();
$roleHasPermissions = Roles::getRoleBy($roleId)->getPermissions(false);
$permissions = $permissions->each(function ($item, $key) use ($roleHasPermissions){
if (!$item->pid) {
$item->open = true;
}
$item->checked = in_array($item->id, $roleHasPermissions) ? true : false;
return $item;
});
header('content-Type: application/json');
exit(json_encode($menuService->sort($permissions)));
}
/**
* 分配权限
*
* @time at 2018年11月15日
* @return mixed|string
*/
public function givePermissions()
{
if ($this->request->isPost()) {
$postData = $this->request->post();
$roleId = $postData['role_id'];
if (!isset($postData['permissions'])) {
Roles::detachPermissions($roleId);
$this->success('分配成功', url('role/index'));
}
$permissions = $postData['permissions'];
Roles::detachPermissions($roleId);
Roles::attachPermissions($roleId, $permissions) ? $this->success('分配成功', url('role/index')) : $this->error('分配失败');
}
$this->role_id = $this->request->param('id');
return $this->fetch('role/givePermissions');
}
}

View File

@ -1,126 +0,0 @@
<?php
namespace app\admin\controller;
use app\model\UserModel;
use app\admin\request\UserRequest;
use think\permissions\facade\Roles;
class User extends Base
{
/**
* User List
*
* @time at 2018年11月12日
* @return mixed|string
*/
public function index(UserModel $userModel)
{
$params = $this->request->param();
$this->checkParams($params);
$this->users = $userModel->getList($params, $this->limit);
return $this->fetch();
}
/**
* create Data
*
* @time at 2018年11月12日
* @return mixed|string
*/
public function create(UserModel $userModel, UserRequest $request)
{
if ($request->isPost()) {
$data = $request->post();
$data['password'] = generatePassword($data['password']);
if ($userId = $userModel->store($data)) {
// 分配角色
$this->giveRoles($userModel, $userId, $data);
$this->success('添加成功', url('user/index'));
}
$this->error('添加失败');
}
$this->roles = Roles::all();
return $this->fetch();
}
/**
* Edit Data
*
* @time at 2018年11月12日
* @return mixed|string
*/
public function edit(UserModel $userModel, UserRequest $request)
{
if ($request->isPost()) {
$data = $request->post();
$this->giveRoles($userModel, $data['id'], $data);
$data['password'] = generatePassword($data['password']);
$userModel->updateBy($data['id'], $data) ? $this->success('修改成功', url('user/index')) : $this->error('修改失败');
}
$id = $this->request->param('id');
if (!$id) {
$this->error('数据不存在');
}
$user = $userModel->findBy($id);
$userHasRoles = $user->getRoles(false);
$roles = Roles::all()->each(function($item, $key) use ($userHasRoles){
$item->checked = in_array($item->id, $userHasRoles) ? true : false;
return $item;
});
$this->user = $user;
$this->roles = $roles;
return $this->fetch();
}
/**
* Delete Data
*
* @time at 2018年11月12日
* @return void
*/
public function delete(UserModel $userModel)
{
$id = $this->request->post('id');
if (!$id) {
$this->error('不存在的数据');
}
// 删除用户相关的角色
$userModel->detachRoles($id);
if ($userModel->deleteBy($id)) {
$this->success('删除成功', url('user/index'));
}
$this->error('删除失败');
}
/**
* 分配角色
*
* @time at 2018年11月15日
* @param \app\model\UserModel $userModel
* @param int $userId
* @param $data
* @return bool
*/
protected function giveRoles(UserModel $userModel, int $userId, &$data)
{
if (isset($data['roles'])) {
$rolesIds = $data['roles'];
if (!is_array($rolesIds)) {
$rolesIds = [$rolesIds];
}
$userModel->detachRoles($userId);
$userModel->attachRoles($userId, $rolesIds);
unset($data['roles']);
return true;
}
$userModel->detachRoles($userId);
return true;
}
}

View File

@ -1,30 +0,0 @@
<?php
/**
* UserRequest.php
* Created by wuyanwen <wuyanwen1992@gmail.com>
* Date: 2018/11/29 0029 21:56
*/
namespace app\admin\request;
use think\exception\HttpResponseException;
use think\Request;
abstract class FormRequest extends Request
{
/**
* FormRequest constructor.
*/
public function __construct()
{
parent::__construct();
if ($this->withServer($_SERVER)->isAjax(true) && $err = $this->validate()) {
throw new HttpResponseException(json([
'code' => 0,
'msg' => $err,
'wait' => 3,
]));
}
}
}

View File

@ -1,17 +0,0 @@
<?php
/**
* UserRequest.php
* Created by wuyanwen <wuyanwen1992@gmail.com>
* Date: 2018/11/29 0029 21:56
*/
namespace app\admin\request;
use app\admin\validates\PermissionValidate;
class PermissionRequest extends FormRequest
{
public function validate()
{
return (new PermissionValidate())->getErrors($this->post());
}
}

View File

@ -1,17 +0,0 @@
<?php
/**
* UserRequest.php
* Created by wuyanwen <wuyanwen1992@gmail.com>
* Date: 2018/11/29 0029 21:56
*/
namespace app\admin\request;
use app\admin\validates\RoleValidate;
class RoleRequest extends FormRequest
{
public function validate()
{
return (new RoleValidate())->getErrors($this->post());
}
}

View File

@ -1,17 +0,0 @@
<?php
/**
* UserRequest.php
* Created by wuyanwen <wuyanwen1992@gmail.com>
* Date: 2018/11/29 0029 21:56
*/
namespace app\admin\request;
use app\admin\validates\UserValidate;
class UserRequest extends FormRequest
{
public function validate()
{
return (new UserValidate())->getErrors($this->post());
}
}

View File

@ -1,35 +0,0 @@
<?php
/**
* Created by PhpStorm.
* User: Administrator
* Date: 2018/11/12 0012
* Time: 下午 16:31
*/
namespace app\admin\validates;;
use think\Validate;
abstract class AbstractValidate extends Validate
{
/**
* Get Validate Errors
*
* @time at 2018年11月12日
* @param $data
* @return array
*/
public function getErrors($data)
{
$this->check($data);
return $this->getError();
}
public function __set($name, $value)
{
// TODO: Implement __set() method.
$this->rule[$name] = $value;
}
}

View File

@ -1,19 +0,0 @@
<?php
/**
* Created by PhpStorm.
* User: Administrator
* Date: 2018/11/14 0014
* Time: 下午 18:21
*/
namespace app\admin\validates;
class PermissionValidate extends AbstractValidate
{
protected $rule = [
'name|菜单名称' => 'require|min:2|max:10|chs|unique:permissions',
'module|模块名称' => 'require|min:2|max:10|alpha',
'controller|控制器名称' => 'require|min:2|max:50|alpha',
'action|方法名称' => 'require|min:2|max:50|alpha',
];
}

View File

@ -1,15 +0,0 @@
<?php
/**
* Created by PhpStorm.
* User: Administrator
* Date: 2018/11/14 0014
* Time: 下午 17:42
*/
namespace app\admin\validates;
class RoleValidate extends AbstractValidate
{
protected $rule = [
'name|角色名' => 'require|min:3|max:15|chs|unique:roles',
];
}

View File

@ -1,18 +0,0 @@
<?php
/**
* Created by PhpStorm.
* User: Administrator
* Date: 2018/11/12 0012
* Time: 下午 16:38
*/
namespace app\admin\validates;
class UserValidate extends AbstractValidate
{
protected $rule = [
'name|用户名' => 'require|min:3|max:15|alphaNum|unique:users',
'email|邮箱' => 'email|unique:users',
'password|密码' => 'confirm|min:6|max:20|alphaDash',
];
}

View File

@ -1,20 +0,0 @@
<?php
/**
* Created by PhpStorm.
* User: Administrator
* Date: 2018/11/13 0013
* Time: 上午 9:33
*/
namespace app\behavior;
class LoginRecord
{
public function run($params)
{
$user = $params['user'];
## 登录记录
$user->login_at = date('Y-m-d h:i:s', time());
$user->login_ip = request()->ip();
$user->save();
}
}

View File

@ -1,15 +0,0 @@
<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: yunwuxin <448901948@qq.com>
// +----------------------------------------------------------------------
return [
'make:curd' => app\command\MakeCurd::class,
'rbac:publish' => think\permissions\command\PermissionPublish::class,
];

View File

@ -1,154 +0,0 @@
<?php
namespace app\command;
use think\console\Command;
use think\console\Input;
use think\console\input\Argument;
use think\console\input\Option;
use think\console\Output;
use think\DB;
class MakeCurd extends Command
{
protected $appPath;
protected $stubPath;
// view 默认的三个模板
protected $views = ['index', 'create', 'edit'];
public function __construct()
{
parent::__construct();
$this->appPath = env('app_path');
$this->stubPath = $this->appPath . 'command' . DIRECTORY_SEPARATOR . 'stub' .DIRECTORY_SEPARATOR;
}
protected function configure()
{
$this->setName('make:curd')
->addArgument('controller', Argument::OPTIONAL, "controller name")
->addArgument('model', Argument::OPTIONAL, "model name")
->addOption('module', null, Option::VALUE_REQUIRED, 'module name')
->setDescription('Create curd option controller model --module?');
}
protected function execute(Input $input, Output $output)
{
// 首先获取默认模块
$moduleName = config('app.default_module');
$controllerName = trim($input->getArgument('controller'));
if (!$controllerName) {
$output->writeln('Controller Name Must Set');exit;
}
$modelName = trim($input->getArgument('model'));
if (!$modelName) {
$output->writeln('Model Name Must Set');exit;
}
if ($input->hasOption('module')) {
$moduleName = $input->getOption('module');
}
$this->makeController($controllerName, $moduleName);
$output->writeln($controllerName . ' controller create success');
$this->makeModel($modelName, $moduleName);
$output->writeln($modelName . ' model create success');
$this->makeView($controllerName, $moduleName);
$output->writeln($controllerName . ' view create success');
}
// 创建控制器文件
protected function makeController($controllerName, $moduleName)
{
$controllerStub = $this->stubPath . 'Controller.stub';
$controllerStub = str_replace(['$controller', '$module'], [ucfirst($controllerName), strtolower($moduleName)], file_get_contents($controllerStub));
$controllerPath = $this->appPath . $moduleName . DIRECTORY_SEPARATOR . 'controller' . DIRECTORY_SEPARATOR;
if (!is_dir($controllerPath)) {
mkdir($controllerPath, 0777, true);
}
return file_put_contents( $controllerPath . $controllerName . '.php', $controllerStub);
}
// 创建模型文件
public function makeModel($modelName, $moduleName)
{
$modelPath = $this->appPath . DIRECTORY_SEPARATOR . 'model';
if (!is_dir($modelPath)) {
mkdir($modelPath, 0777, true);
}
$modelContents = "<?php \r\n \r\n";
$modelContents .= "namespace app\model;\r\n \r\n";
$modelContents .= 'class $modelModel extends BaseModel';
$modelContents .= "\r\n { \r\n \t";
$modelContents .= 'protected $table = \'' . config('database.prefix') . '$_table\';';
$modelContents = $this->writeField($modelContents, $modelName);
$modelContents = str_replace('$model', ucfirst($modelName), $modelContents);
$modelContents = str_replace('$_table', $this->unCamelize($modelName), $modelContents);
$modelContents .= "\r\n }";
return file_put_contents($modelPath . DIRECTORY_SEPARATOR . $modelName . 'Model.php', $modelContents);
}
private function writeField($modelContents, $modelName)
{
$info = Db::query('show full columns from ' . config('database.prefix') . $this->unCamelize($modelName));
foreach ($info as $value) {
$modelContents .= sprintf("\r\n %s \t protected $%s = '%s'; \r\n", $this->fieldComment($value['Comment']), $this->combine($value['Field']), $value['Field']);
}
return $modelContents;
}
// 创建模板
public function makeView($controllerName, $moduleName)
{
$viewStub = $this->stubPath . 'View.stub';
$viewPath = (config('template.view_base') ? config('template.view_base') . $moduleName . DIRECTORY_SEPARATOR : env('app_path') . $moduleName . DIRECTORY_SEPARATOR . 'views' . DIRECTORY_SEPARATOR) . strtolower($controllerName);
if (!is_dir($viewPath)) {
mkdir($viewPath, 0777, true);
}
$stub = explode('||', file_get_contents($viewStub));
foreach ($this->views as $view) {
if ($view == 'index') {
file_put_contents($viewPath . DIRECTORY_SEPARATOR . $view .'.html', trim($stub[0]));
} else {
file_put_contents($viewPath . DIRECTORY_SEPARATOR . $view .'.html', trim($stub[1]));
}
}
}
/**
* 字符注释
*
* @time at 2019年01月08日
* @param $comment
* @return string
*/
private function fieldComment($comment)
{
return sprintf("\t /** \r\n \t * @var string \r\n \t * @desc %s \r\n \t */ \r\n", $comment);
}
/**
* 驼峰分割
*
* @time at 2019年01月02日
* @param string $camelCaps
* @param string $separator
* @return string
*/
private function unCamelize(string $string, string $separator = '_')
{
return strtolower(preg_replace('/(?<=[a-z])([A-Z])/', $separator . '$1', $string));
}
private function combine(string $string)
{
$s = explode('_', $string);
array_walk($s, function (&$value, $key) {
if ($key) {
$value = ucfirst($value);
}
});
return implode($s, '');
}
}

View File

@ -1,20 +0,0 @@
<?php
namespace app\$module\controller;
class $controller extends Base
{
public function index()
{
return $this->fetch();
}
public function create()
{
return $this->fetch();
}
public function edit()
{
return $this->fetch();
}
public function delete()
{}
}

View File

@ -1,12 +0,0 @@
{extend name="public:base" /}
{block name="menu"}{/block}
{block name="search"}{/block}
{block name="button-create"}{/block}
{block name="table-head"}{/block}
{block name="table-body"}{/block}
{block name="paginate"}{/block}
||
{extend name="public:form" /}
{block name="menu"}{/block}
{block name='action'}{/block}
{block name="form"}{/block}

View File

@ -1,67 +0,0 @@
<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: 流年 <liu21st@gmail.com>
// +----------------------------------------------------------------------
// 应用公共文件
/**
* 钩子行为
*/
if (!function_exists('hook')) {
function hook($behavior, $params) {
\think\facade\Hook::exec($behavior, $params);
}
}
/**
* 编辑按钮
*/
if (!function_exists('editButton')) {
function editButton(string $url, string $name = '编辑') {
return sprintf('<a href="%s"><button class="btn btn-info btn-xs edit" type="button"><i class="fa fa-paste"></i> %s</button></a>', $url, $name);
}
}
/**
* 增加按钮
*/
if (!function_exists('createButton')) {
function createButton(string $url, string $name, $isBig = true) {
return $isBig ? sprintf('<a href="%s"> <button type="button" class="btn btn-w-m btn-primary"><i class="fa fa-check-square-o"></i> %s</button></a>', $url, $name) :
sprintf('<a href="%s"> <button type="button" class="btn btn-xs btn-primary"><i class="fa fa-check-square-o"></i> %s</button></a>', $url, $name);
}
}
/**
* 删除按钮
*/
if (!function_exists('deleteButton')) {
function deleteButton(string $url, int $id, string $name="删除") {
return sprintf('<button class="btn btn-danger btn-xs delete" data-url="%s" data=%d type="button"><i class="fa fa-trash"></i> %s</button>', $url, $id, $name);
}
}
/**
* 搜索按钮
*/
if (!function_exists('searchButton')) {
function searchButton(string $name="搜索") {
return sprintf('<button class="btn btn-white" type="submit"><i class="fa fa-search"></i> %s</button>', $name);
}
}
/**
* 生成密码
*/
if (!function_exists('generatePassword')) {
function generatePassword(string $password, int $algo = PASSWORD_DEFAULT) {
return password_hash($password, $algo);
}
}

View File

@ -1,60 +0,0 @@
<?php
/**
* Created by PhpStorm.
* User: Administrator
* Date: 2018/11/16 0016
* Time: 下午 14:51
*/
namespace app\component\upload;
use think\exception\ThrowableError;
use think\facade\Request;
use app\exceptions\UploadException;
class LocalUpload implements UploadInterface
{
protected $name = null;
/**
* Upload File
*
* @time at 2018年11月16日
* @return string
*/
public function file(){}
/**
* Upload Image
*
* @time at 2018年11月16日
* @return string
*/
public function image()
{
try {
$file = Request::file($this->name);
if (!$this->name) {
throw new UploadException('请选择上传的图片');
}
$info = $file->validate(config('admin.image'))->move(config('admin.local_upload_path'));
if (!$info) {
throw new UploadException($file->getError());
}
return $info->getSaveName();
} catch (UploadException $exception) {
return $exception->getMessage();
}
}
/**
* Set Image Name
*
* @time at 2018年11月16日
* @param $name
* @return $this
*/
public function name($name)
{
$this->name = $name;
return $this;
}
}

View File

@ -1,15 +0,0 @@
<?php
/**
* Created by PhpStorm.
* User: Administrator
* Date: 2018/11/16 0016
* Time: 下午 14:50
*/
namespace app\component\upload;
interface UploadInterface
{
public function file();
public function image();
}

View File

@ -1,13 +0,0 @@
<?php
/**
* Created by PhpStorm.
* User: Administrator
* Date: 2018/11/13 0013
* Time: 上午 10:49
*/
namespace app\exceptions;
class AppException extends \Exception
{
}

View File

@ -1,14 +0,0 @@
<?php
/**
* Created by PhpStorm.
* User: Administrator
* Date: 2018/11/16 0016
* Time: 下午 15:03
*/
namespace app\exceptions;
class UploadException extends \Exception
{
}

View File

@ -1,15 +0,0 @@
<?php
namespace app\http\middleware;
class CheckLogin
{
public function handle($request, \Closure $next)
{
if (!$request->session('user')) {
return redirect(url('login'));
}
return $next($request);
}
}

View File

@ -1,16 +0,0 @@
<?php
namespace app\http\middleware;
use app\service\LogService;
class LogRecord
{
public function handle($request, \Closure $next)
{
(new LogService())->record($request);
return $next($request);
}
}

View File

@ -1,64 +0,0 @@
<?php
/**
* Created by PhpStorm.
* User: Administrator
* Date: 2018/11/12 0012
* Time: 上午 11:05
*/
namespace app\model;
use think\Model;
class BaseModel extends Model
{
const LIMIT = 10;
/**
* Store Data
*
* @time at 2018年11月12日
* @param array $data
* @return bool
*/
public function store(array $data)
{
return $this->save($data) ? $this->id : false;
}
/**
* Find By ID
*
* @time at 2018年11月12日
* @param int $id
* @return array|false|\PDOStatement|string|\think\Model
*/
public function findBy(int $id)
{
return $this->where('id', $id)->find();
}
/**
* Update By ID && Data
*
* @time at 2018年11月12日
* @param int $id
* @param array $data
* @return bool
*/
public function updateBy(int $id, array $data)
{
return $this->save($data, ['id' => $id]);
}
/**
* Delete By ID
*
* @time at 2018年11月12日
* @param int $id
* @return bool|null
*/
public function deleteBy(int $id)
{
return $this->where('id', $id)->delete();
}
}

View File

@ -1,36 +0,0 @@
<?php
/**
* Created by PhpStorm.
* User: Administrator
* Date: 2019/1/17
* Time: 18:09
*/
namespace app\model;
use http\Env\Request;
class LogRecordModel extends BaseModel
{
protected $name = 'option_log';
/**
* 日志列表
*
* @time at 2019年01月18日
* @param array $params
* @param int $limit
* @return mixed
*/
public function getAll(array $params, $limit = self::LIMIT)
{
if (!count($params)) {
return $this->order('created_at', 'desc')->paginate($limit, false, ['query' => request()->param()]);
}
if (isset($params['name'])) {
$list = $this->whereLike('user_name', '%'.$params['name'].'%');
}
return $list->order('created_at', 'desc')->paginate($limit, false, ['query' => request()->param()]);
}
}

View File

@ -1,37 +0,0 @@
<?php
namespace app\model;
use think\permissions\traits\hasRoles;
class UserModel extends BaseModel
{
use hasRoles;
protected $name = 'users';
/**
* Users List
*
* @time at 2018年11月14日
* @param $params
* @return \think\Paginator
*/
public function getList($params, $limit = self::LIMIT)
{
if (!count($params)) {
return $this->paginate($limit);
}
if (isset($params['name'])) {
$user = $this->whereLike('name', '%'.$params['name'].'%');
}
if (isset($params['email'])) {
$user = $this->whereLike('email', '%'.$params['email'].'%');
}
return $user->paginate($limit, false, ['query' => request()->param()]);
}
}

View File

@ -1,15 +0,0 @@
<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com>
// +----------------------------------------------------------------------
// 应用容器绑定定义
return [
];

View File

@ -1,35 +0,0 @@
<?php
/**
* Created by PhpStorm.
* User: Administrator
* Date: 2019/1/17
* Time: 18:06
*/
namespace app\service;
use think\permissions\facade\Permissions;
use think\Request;
use app\model\LogRecordModel;
class LogService
{
public function record(Request $request)
{
$module = $request->module();
$controller = $request->controller();
$action = $request->action();
$user = $request->session('user');
$permission = Permissions::getPermissionByModuleAnd($module, $controller, $action);
(new LogRecordModel())->store([
'user_id' => $user->id,
'user_name' => $user->name,
'module' => $module,
'controller' => $controller,
'action' => $action,
'option' => $permission->name,
'method' => $request->method(),
]);
}
}

View File

@ -1,55 +0,0 @@
<?php
/**
* Created by PhpStorm.
* User: Administrator
* Date: 2018/11/13 0013
* Time: 上午 10:50
*/
namespace app\service;
use think\Collection;
class MenuService
{
/**
* 树形结构
*
* @time at 2018年11月13日
* @param $menu
* @return Collection
*/
public function tree(Collection $menus, int $pid = 0)
{
$collection = new Collection();
$menus->each(function ($item, $key) use ($pid, $menus, $collection){
if ($item->pid == $pid) {
$collection[$key] = $item;
$collection[$key][$item->id] = $this->tree($menus, $item->id);
}
});
return $collection;
}
/**
* 顺序结构
*
* @time at 2018年11月13日
* @param $menu
* @return Collection
*/
public function sort(Collection $menus, int $pid = 0, int $level = 0)
{
$collection = [];
foreach ($menus as $menu) {
if ($menu->pid == $pid) {
$menu->level = $level;
$collection[] = $menu;
$collection = array_merge($collection, $this->sort($menus, $menu->id, $level+1));
}
}
return $collection;
}
}

View File

@ -1,63 +0,0 @@
<?php
/**
* Created by PhpStorm.
* User: Administrator
* Date: 2018/11/16 0016
* Time: 上午 11:01
*/
namespace app\service;
use think\paginator\driver\Bootstrap;
class PaginateService extends Bootstrap
{
/**
* 渲染分页html
* @return mixed
*/
public function render()
{
if ($this->hasPages()) {
if ($this->simple) {
return sprintf(
'<ul class="pager">%s %s</ul>',
$this->getPreviousButton(),
$this->getNextButton()
);
} else {
return sprintf(
'<ul class="pagination">%s %s %s %s</ul>',
$this->getPreviousButton(),
$this->getLinks(),
$this->getNextButton(),
$this->changeLimit()
);
}
}
}
protected function changeLimit()
{
$query = $this->options['query'];
$html = '&nbsp;<li class="project_page">';
$pageLimit = config('admin.page_limit');
$html .= '<select class="page-form-control limit" name="limit">';
foreach ($pageLimit as $limit) {
if (isset($query['limit']) && $query['limit'] == $limit) {
$html .= sprintf('<option value="%s" selected>%s条/页</option>', $limit, $limit);
} else {
$html .= sprintf('<option value="%s">%s条/页</option>', $limit, $limit);
}
}
$html .= '</select></li>&nbsp;<li>';
$html .= sprintf('<input name="page" class="page-form-control-input" value="%s"> 页 ', $query['page'] ?? 1);
$html .='</li>';
$html .= '<li><button class="btn btn-primary btn-xs hrefTo"><i class="fa fa-location-arrow"></i> 跳转</button></li>';
return $html;
}
}

View File

@ -1,28 +0,0 @@
<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com>
// +----------------------------------------------------------------------
// 应用行为扩展定义文件
return [
// 应用初始化
'app_init' => [],
// 应用开始
'app_begin' => [],
// 模块初始化
'module_init' => [],
// 操作开始执行
'action_begin' => [],
// 视图内容过滤
'view_filter' => [],
// 日志写入
'log_write' => [],
// 应用结束
'app_end' => [],
];

View File

@ -1,183 +0,0 @@
<?php
namespace app\traits;
use think\Request;
use think\Validate;
use think\facade\Session;
use think\facade\Cookie;
use app\model\UserModel as User;
use app\behavior\LoginRecord;
trait Auth
{
protected $loginUserKey = 'user';
public function authLogin(Request $request)
{
$err = $this->validateLogin($request);
if ($err) {
$this->error($err);
}
// 正常输入登录
$userModel = new User();
$field = explode('|', $this->name());
$user = $userModel::where($field[0], $request->param($field[0]))->find();
if (!$user) {
$this->error('登录失败');
}
if (password_verify($request->param('password'), $user->password)) {
Session::set($this->loginUserKey, $user);
# 记住登录
$this->LoginRemember($user, $request);
# 登录记录
hook(LoginRecord::class, ['user' => $user]);
$this->success('登录成功', url($this->redirect));
}
$this->error('登录失败');
}
/**
* 记住登录
* @return bool
*/
public function rememberLogin()
{
// 如果记住登录
if (!Session::get($this->loginUserKey) && Cookie::get('remember_token') && $this->checkRememberToken()) {
return true;
}
return false;
}
/**
* 退出
* @return void
*/
public function authLogout()
{
$user = Session::get($this->loginUserKey);
$this->deleteToken($user);
Session::delete($this->loginUserKey);
}
protected function deleteToken($user)
{
if ($user->remember_token) {
$user->remember_token = null;
$user->save();
Cookie::delete('remember_token');
}
}
/**
* 验证
* @param Request $request
* @return array|bool
*/
protected function validateLogin(Request $request)
{
$validate = new Validate($this->rule());
if (!$validate->check($request->except(['remember']))) {
return $validate->getError();
}
return false;
}
/**
* 登录验证规则
* @return array
*/
protected function rule()
{
return [
$this->name() => 'require|token|alphaDash',
'password|密码' => 'require|alphaDash',
'captcha|验证码' => 'require|captcha'
];
}
/**
* 设置登录字段
*
* @return string
*/
protected function name()
{
return 'name|用户名';
}
/**
* Remember Token
*
* @return string
*/
public function generateRememberToken()
{
return uniqid(md5(time()+rand(10000, 99999)));
}
/**
* 加密 TOKEN
*
* @param $user_id
* @param $remember_token
* @return string
*/
protected function secretRememberToken($user_id, $remember_token)
{
list($key, $method, $iv) = $this->getSecret();
return base64_encode(openssl_encrypt($user_id . ':' . $remember_token, $method, $key, OPENSSL_RAW_DATA, $iv));
}
/**
* 检查remember token 是否正确
*
* @return bool
*/
protected function checkRememberToken()
{
if (!Cookie::has('remember_token')) {
return false;
}
$rememberToken = Cookie::get('remember_token');
// 解密
list($key, $method, $iv) = $this->getSecret();
list($userID) = explode(':', (openssl_decrypt(base64_decode($rememberToken), $method, $key, OPENSSL_RAW_DATA, $iv)));
// 校验
$user = (new User())->findBy($userID);
Session::set('user', $user);
return $user->remember_token == $rememberToken;
}
/**
* 加密
*
* @return array
*/
protected function getSecret()
{
return ['admin_auth', 'AES-128-CBC', '1234567890123412'];
}
/**
* 记住
*
* @param $user
* @return void
*/
protected function LoginRemember($user, Request $request)
{
if ($request->has('remember')) {
$rememberToken = $this->secretRememberToken($user->id, $this->generateRememberToken());
$user->remember_token = $rememberToken;
Cookie::forever('remember_token', $rememberToken);
}
}
}

View File

@ -1,80 +0,0 @@
<?php
/**
* Created by PhpStorm.
* User: Administrator
* Date: 2018/11/12 0012
* Time: 上午 11:43
*/
namespace app\traits;
use think\facade\Session;
use app\component\upload\UploadInterface;
use app\component\upload\LocalUpload;
trait ControllerTrait
{
protected $vars = [];
/**
* 绑定实现
*
* @time at 2018年11月16日
* @return void
*/
public function initialize()
{
bind(UploadInterface::class, LocalUpload::class);
}
/**
* 是否登录
*
* @time at 2018年11月15日
* @return bool
*/
protected function isLogin()
{
return $this->getLoginUser() ? true : false;
}
/**
* 获取登录用户
*
* @time at 2018年11月15日
* @return mixed
*/
protected function getLoginUser()
{
return Session::get('user');
}
/**
* fetch 重写
*
* @time at 2018年11月15日
* @param string $template
* @param array $vars
* @param array $config
* @return mixed
*/
protected function fetch($template = '', $vars = [], $config = [])
{
$vars = array_merge($this->vars, $vars);
return $this->view->fetch($template, $vars, $config);
}
/**
* Set Template Vars
*
* @time at 2018年11月12日
* @param $name
* @param $value
* @return void
*/
public function __set($name, $value)
{
// TODO: Implement __set() method.
$this->vars[$name] = $value;
}
}

View File

@ -1,26 +0,0 @@
<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com>
// +----------------------------------------------------------------------
return [
// 生成应用公共文件
'__file__' => ['common.php'],
// 定义demo模块的自动生成 (按照实际定义的文件名生成)
'demo' => [
'__file__' => ['common.php'],
'__dir__' => ['behavior', 'controller', 'model', 'view'],
'controller' => ['Index', 'Test', 'UserType'],
'model' => ['User', 'UserType'],
'view' => ['index/index'],
],
// 其他更多的模块定义
];

View File

@ -1,39 +0,0 @@
{
"name": "topthink/think",
"description": "the new thinkphp framework",
"type": "project",
"keywords": [
"framework",
"thinkphp",
"ORM"
],
"homepage": "http://thinkphp.cn/",
"license": "Apache-2.0",
"authors": [
{
"name": "liu21st",
"email": "liu21st@gmail.com"
}
],
"require": {
"php": ">=5.6.0",
"topthink/framework": "5.1.*",
"wyw/permission": "dev-master",
"topthink/think-captcha": "^2.0",
"guzzlehttp/guzzle": "~6.0",
"ext-json": "*"
},
"autoload": {
"psr-4": {
"app\\": "application",
"thinking\\socialite\\": "extend/socialite/src",
"thinking\\icloud\\": "extend/icloud/src"
}
},
"extra": {
"think-path": "thinkphp"
},
"config": {
"preferred-install": "dist"
}
}

261
composer.lock generated
View File

@ -1,261 +0,0 @@
{
"_readme": [
"This file locks the dependencies of your project to a known state",
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "2cce6ba66072812ae910895229605fa7",
"packages": [
{
"name": "topthink/framework",
"version": "v5.1.30",
"source": {
"type": "git",
"url": "https://github.com/top-think/framework.git",
"reference": "4fefa5ed2f9dc8a15fcf7bb271d0d918fb48dacc"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/top-think/framework/zipball/4fefa5ed2f9dc8a15fcf7bb271d0d918fb48dacc",
"reference": "4fefa5ed2f9dc8a15fcf7bb271d0d918fb48dacc",
"shasum": "",
"mirrors": [
{
"url": "https://dl.laravel-china.org/%package%/%reference%.%type%",
"preferred": true
}
]
},
"require": {
"php": ">=5.6.0",
"topthink/think-installer": "2.*"
},
"require-dev": {
"johnkary/phpunit-speedtrap": "^1.0",
"mikey179/vfsstream": "~1.6",
"phpdocumentor/reflection-docblock": "^2.0",
"phploc/phploc": "2.*",
"phpunit/phpunit": "^5.0|^6.0",
"sebastian/phpcpd": "2.*",
"squizlabs/php_codesniffer": "2.*"
},
"type": "think-framework",
"notification-url": "https://packagist.org/downloads/",
"license": [
"Apache-2.0"
],
"authors": [
{
"name": "liu21st",
"email": "liu21st@gmail.com"
},
{
"name": "yunwuxin",
"email": "448901948@qq.com"
}
],
"description": "the new thinkphp framework",
"homepage": "http://thinkphp.cn/",
"keywords": [
"framework",
"orm",
"thinkphp"
],
"time": "2018-11-30T07:46:23+00:00"
},
{
"name": "topthink/think-captcha",
"version": "v2.0.2",
"source": {
"type": "git",
"url": "https://github.com/top-think/think-captcha.git",
"reference": "54c8a51552f99ff9ea89ea9c272383a8f738ceee"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/top-think/think-captcha/zipball/54c8a51552f99ff9ea89ea9c272383a8f738ceee",
"reference": "54c8a51552f99ff9ea89ea9c272383a8f738ceee",
"shasum": "",
"mirrors": [
{
"url": "https://dl.laravel-china.org/%package%/%reference%.%type%",
"preferred": true
}
]
},
"require": {
"topthink/framework": "5.1.*"
},
"type": "library",
"autoload": {
"psr-4": {
"think\\captcha\\": "src/"
},
"files": [
"src/helper.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"Apache-2.0"
],
"authors": [
{
"name": "yunwuxin",
"email": "448901948@qq.com"
}
],
"description": "captcha package for thinkphp5",
"time": "2017-12-31T16:37:49+00:00"
},
{
"name": "topthink/think-installer",
"version": "v2.0.0",
"source": {
"type": "git",
"url": "https://github.com/top-think/think-installer.git",
"reference": "f5400a12c60e513911aef41fe443fa6920952675"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/top-think/think-installer/zipball/f5400a12c60e513911aef41fe443fa6920952675",
"reference": "f5400a12c60e513911aef41fe443fa6920952675",
"shasum": "",
"mirrors": [
{
"url": "https://dl.laravel-china.org/%package%/%reference%.%type%",
"preferred": true
}
]
},
"require": {
"composer-plugin-api": "^1.0"
},
"require-dev": {
"composer/composer": "1.0.*@dev"
},
"type": "composer-plugin",
"extra": {
"class": "think\\composer\\Plugin"
},
"autoload": {
"psr-4": {
"think\\composer\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"Apache-2.0"
],
"authors": [
{
"name": "yunwuxin",
"email": "448901948@qq.com"
}
],
"time": "2018-05-11T06:45:42+00:00"
},
{
"name": "topthink/think-migration",
"version": "v2.0.3",
"source": {
"type": "git",
"url": "https://github.com/top-think/think-migration.git",
"reference": "70c89850ca29c2eab988c7c3475d1d5331901bb8"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/top-think/think-migration/zipball/70c89850ca29c2eab988c7c3475d1d5331901bb8",
"reference": "70c89850ca29c2eab988c7c3475d1d5331901bb8",
"shasum": "",
"mirrors": [
{
"url": "https://dl.laravel-china.org/%package%/%reference%.%type%",
"preferred": true
}
]
},
"require": {
"topthink/framework": "5.1.*"
},
"type": "library",
"autoload": {
"psr-4": {
"Phinx\\": "phinx/src/Phinx",
"think\\migration\\": "src"
},
"files": [
"src/config.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"Apache-2.0"
],
"authors": [
{
"name": "yunwuxin",
"email": "448901948@qq.com"
}
],
"time": "2017-12-31T16:32:22+00:00"
},
{
"name": "wyw/permission",
"version": "dev-master",
"source": {
"type": "git",
"url": "https://github.com/yanwenwu/thinkphp-permission.git",
"reference": "c9341e22c73e30c963a3aebc6da842af7ebc3f26"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/yanwenwu/thinkphp-permission/zipball/c9341e22c73e30c963a3aebc6da842af7ebc3f26",
"reference": "c9341e22c73e30c963a3aebc6da842af7ebc3f26",
"shasum": "",
"mirrors": [
{
"url": "https://dl.laravel-china.org/%package%/%reference%.%type%",
"preferred": true
}
]
},
"require": {
"topthink/think-migration": "^2.0"
},
"type": "library",
"autoload": {
"psr-4": {
"think\\permissions\\": "src/"
},
"files": [
"src/helper.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "yanwenwu",
"email": "njphper@gmail.com"
}
],
"description": "rbac",
"time": "2018-11-30T02:01:37+00:00"
}
],
"packages-dev": [],
"aliases": [],
"minimum-stability": "stable",
"stability-flags": {
"wyw/permission": 20
},
"prefer-stable": false,
"prefer-lowest": false,
"platform": {
"php": ">=5.6.0"
},
"platform-dev": []
}

View File

@ -1,20 +0,0 @@
<?php
/**
* Created by PhpStorm.
* User: Administrator
* Date: 2018/11/12 0012
* Time: 下午 17:46
*/
return [
'title' => '后台管理',
'page_limit' => [ 10, 20, 30 ],
'image' => [
'ext' => 'gif, jpg, jpeg',
'size' => 1024 * 1024
],
'local_upload_path' => env('root_path') . DIRECTORY_SEPARATOR . 'upload',
];

View File

@ -1,146 +0,0 @@
<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com>
// +----------------------------------------------------------------------
// +----------------------------------------------------------------------
// | 应用设置
// +----------------------------------------------------------------------
return [
// 应用名称
'app_name' => '',
// 应用地址
'app_host' => '',
// 应用调试模式
'app_debug' => env('app_debug'),
// 应用Trace
'app_trace' => env('app_trace'),
// 是否支持多模块
'app_multi_module' => true,
// 入口自动绑定模块
'auto_bind_module' => false,
// 注册的根命名空间
'root_namespace' => [],
// 默认输出类型
'default_return_type' => 'html',
// 默认AJAX 数据返回格式,可选json xml ...
'default_ajax_return' => 'json',
// 默认JSONP格式返回的处理方法
'default_jsonp_handler' => 'jsonpReturn',
// 默认JSONP处理方法
'var_jsonp_handler' => 'callback',
// 默认时区
'default_timezone' => 'Asia/Shanghai',
// 是否开启多语言
'lang_switch_on' => false,
// 默认全局过滤方法 用逗号分隔多个
'default_filter' => '',
// 默认语言
'default_lang' => 'zh-cn',
// 应用类库后缀
'class_suffix' => false,
// 控制器类后缀
'controller_suffix' => false,
// +----------------------------------------------------------------------
// | 模块设置
// +----------------------------------------------------------------------
// 默认模块名
'default_module' => 'admin',
// 禁止访问模块
'deny_module_list' => ['common'],
// 默认控制器名
'default_controller' => 'Index',
// 默认操作名
'default_action' => 'index',
// 默认验证器
'default_validate' => '',
// 默认的空模块名
'empty_module' => '',
// 默认的空控制器名
'empty_controller' => 'Error',
// 操作方法前缀
'use_action_prefix' => false,
// 操作方法后缀
'action_suffix' => '',
// 自动搜索控制器
'controller_auto_search' => false,
// +----------------------------------------------------------------------
// | URL设置
// +----------------------------------------------------------------------
// PATHINFO变量名 用于兼容模式
'var_pathinfo' => 's',
// 兼容PATH_INFO获取
'pathinfo_fetch' => ['ORIG_PATH_INFO', 'REDIRECT_PATH_INFO', 'REDIRECT_URL'],
// pathinfo分隔符
'pathinfo_depr' => '/',
// HTTPS代理标识
'https_agent_name' => '',
// IP代理获取标识
'http_agent_ip' => 'X-REAL-IP',
// URL伪静态后缀
'url_html_suffix' => 'html',
// URL普通方式参数 用于自动生成
'url_common_param' => false,
// URL参数方式 0 按名称成对解析 1 按顺序解析
'url_param_type' => 0,
// 是否开启路由延迟解析
'url_lazy_route' => false,
// 是否强制使用路由
'url_route_must' => false,
// 合并路由规则
'route_rule_merge' => false,
// 路由是否完全匹配
'route_complete_match' => false,
// 使用注解路由
'route_annotation' => false,
// 域名根如thinkphp.cn
'url_domain_root' => '',
// 是否自动转换URL中的控制器和操作名
'url_convert' => true,
// 默认的访问控制器层
'url_controller_layer' => 'controller',
// 表单请求类型伪装变量
'var_method' => '_method',
// 表单ajax伪装变量
'var_ajax' => '_ajax',
// 表单pjax伪装变量
'var_pjax' => '_pjax',
// 是否开启请求缓存 true自动缓存 支持设置请求缓存规则
'request_cache' => false,
// 请求缓存有效期
'request_cache_expire' => null,
// 全局请求缓存排除规则
'request_cache_except' => [],
// 是否开启路由缓存
'route_check_cache' => false,
// 路由缓存的Key自定义设置闭包默认为当前URL和请求类型的md5
'route_check_cache_key' => '',
// 路由缓存类型及参数
'route_cache_option' => [],
// 默认跳转页面对应的模板文件
'dispatch_success_tmpl' => Env::get('root_path') . 'views' . DIRECTORY_SEPARATOR . 'admin/message.html',//Env::get('think_path') . 'tpl/dispatch_jump.tpl',
'dispatch_error_tmpl' => Env::get('root_path') . 'views' . DIRECTORY_SEPARATOR . 'admin/message.html',//Env::get('think_path') . 'tpl/dispatch_jump.tpl',
// 异常页面的模板文件
'exception_tmpl' => Env::get('think_path') . 'tpl/think_exception.tpl',
// 错误显示信息,非调试模式有效
'error_message' => '页面错误!请稍后再试~',
// 显示错误信息
'show_error_msg' => false,
// 异常处理handle类 留空使用 \think\exception\Handle
'exception_handle' => ''
];

View File

@ -1,25 +0,0 @@
<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com>
// +----------------------------------------------------------------------
// +----------------------------------------------------------------------
// | 缓存设置
// +----------------------------------------------------------------------
return [
// 驱动方式
'type' => 'File',
// 缓存保存目录
'path' => '',
// 缓存前缀
'prefix' => '',
// 缓存有效期 0表示永久缓存
'expire' => 0,
];

View File

@ -1,16 +0,0 @@
<?php
/**
* Created by PhpStorm.
* User: Administrator
* Date: 2018/11/13 0013
* Time: 上午 9:20
*/
return [
// 验证码字体大小
'fontSize' => 20,
// 验证码位数
'length' => 4,
// 关闭验证码杂点
'useNoise' => false,
];

View File

@ -1,78 +0,0 @@
<?php
/**
* Created by PhpStorm.
* User: Administrator
* Date: 2019/1/26
* Time: 14:41
*/
return [
'driver' => [
'default' => 'qiniu',
// 七牛驱动
'qiniu' => \thinking\icloud\cloud\QiNiuCloud::class,
// 又拍驱动
'uppay' => \thinking\icloud\cloud\UpYunCloud::class,
// 七牛驱动认证
'qiniuAuth' => \thinking\icloud\auth\QiNiuAuth::class,
// 又拍驱动认证
'uppayAuth' => \thinking\icloud\auth\UpYunAuth::class,
],
/* 七牛配置信息 */
'qiniu' => [
'app_key' => '',
'app_secret' => '',
//上传策略字段,上传凭证校验使用
'policyFields' => [
'callbackUrl',
'callbackBody',
'callbackHost',
'callbackBodyType',
'callbackFetchKey',
'returnUrl',
'returnBody',
'endUser',
'saveKey',
'insertOnly',
'detectMime',
'mimeLimit',
'fsizeMin',
'fsizeLimit',
'persistentOps',
'persistentNotifyUrl',
'persistentPipeline',
'deleteAfterDays',
'fileType',
'isPrefixalScope',
],
],
/* 又拍云配置信息 */
'upyun' => [
'opreator' => '',
'password' => '',
'buckets' => [''],
],
'oss' => [
'access_key' => '',
'access_secret' => '',
],
//api接口
'host' => [
//七牛host
'rs' => 'rs.qbox.me',
'api' => 'api.qiniu.com',
'uc' => 'uc.qbox.me',
'rsf' => 'rsf.qbox.me',
'iovip' => 'iovip.qbox.me',
'up' => 'up.qiniu.com',
//又拍host
'v0' => 'v0.api.upyun.com',
'v1' => 'v1.api.upyun.com',
'v2' => 'v2.api.upyun.com',
'v3' => 'v3.api.upyun.com',
],
];

View File

@ -1,20 +0,0 @@
<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com>
// +----------------------------------------------------------------------
// +----------------------------------------------------------------------
// | 控制台配置
// +----------------------------------------------------------------------
return [
'name' => 'Think Console',
'version' => '0.1',
'user' => null,
'auto_path' => env('app_path') . 'command' . DIRECTORY_SEPARATOR,
];

View File

@ -1,30 +0,0 @@
<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com>
// +----------------------------------------------------------------------
// +----------------------------------------------------------------------
// | Cookie设置
// +----------------------------------------------------------------------
return [
// cookie 名称前缀
'prefix' => '',
// cookie 保存时间
'expire' => 0,
// cookie 保存路径
'path' => '/',
// cookie 有效域名
'domain' => '',
// cookie 启用安全传输
'secure' => false,
// httponly设置
'httponly' => '',
// 是否使用 setcookie
'setcookie' => true,
];

View File

@ -1,63 +0,0 @@
<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com>
// +----------------------------------------------------------------------
return [
// 数据库类型
'type' => env('db_connection'),
// 服务器地址
'hostname' => env('db_host'),
// 数据库名
'database' => env('db_database'),
// 用户名
'username' => env('db_username'),
// 密码
'password' => env('db_password'),
// 端口
'hostport' => env('db_port'),
// 连接dsn
'dsn' => '',
// 数据库连接参数
'params' => [],
// 数据库编码默认采用utf8
'charset' => 'utf8',
// 数据库表前缀
'prefix' => 'cms_',
// 数据库调试模式
'debug' => true,
// 数据库部署方式:0 集中式(单一服务器),1 分布式(主从服务器)
'deploy' => 0,
// 数据库读写是否分离 主从式有效
'rw_separate' => false,
// 读写分离后 主服务器数量
'master_num' => 1,
// 指定从服务器序号
'slave_no' => '',
// 自动读取主库数据
'read_master' => false,
// 是否严格检查字段是否存在
'fields_strict' => true,
// 数据集返回类型
'resultset_type' => 'array',
// 自动写入时间戳字段
'auto_timestamp' => false,
// 时间字段取出后的默认时间格式
'datetime_format' => 'Y-m-d H:i:s',
// 是否需要进行SQL性能分析
'sql_explain' => false,
// Builder类
'builder' => '',
// Query类
'query' => '\\think\\db\\Query',
// 是否需要断线重连
'break_reconnect' => false,
// 断线标识字符串
'break_match_str' => [],
];

View File

@ -1,30 +0,0 @@
<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com>
// +----------------------------------------------------------------------
// +----------------------------------------------------------------------
// | 日志设置
// +----------------------------------------------------------------------
return [
// 日志记录方式,内置 file socket 支持扩展
'type' => 'File',
// 日志保存目录
'path' => '',
// 日志记录级别
'level' => [],
// 单文件日志写入
'single' => false,
// 独立日志级别
'apart_level' => [],
// 最大日志文件数量
'max_files' => 0,
// 是否关闭日志写入
'close' => false,
];

View File

@ -1,21 +0,0 @@
<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com>
// +----------------------------------------------------------------------
// +----------------------------------------------------------------------
// | 中间件配置
// +----------------------------------------------------------------------
return [
// 默认中间件命名空间
'default_namespace' => 'app\\http\\middleware\\',
'auth' => \think\permissions\PermissionMiddleware::class,
'checkLogin' => app\http\middleware\CheckLogin::class,
'logRecord' => app\http\middleware\LogRecord::class,
];

View File

@ -1,12 +0,0 @@
<?php
/**
* Created by PhpStorm.
* User: Administrator
* Date: 2018/11/16 0016
* Time: 上午 11:00
*/
return [
'type' => \app\service\PaginateService::class,
'var_page' => 'page',
];

View File

@ -1,25 +0,0 @@
<?php
/**
* permissions.php
* Created by wuyanwen <wuyanwen1992@gmail.com>
* Date: 2018/9/26 0026 20:23
*/
return [
'table' => [
'permission' => 'permissions',
'role' => 'roles',
'user_has_roles' => 'user_has_roles',
'role_has_permissions' => 'role_has_permissions',
],
'model' => [
'permission' => think\permissions\model\Permissions::class,
'role' => think\permissions\model\Roles::class,
// Must set User Model Class
'user' => app\model\UserModel::class,
],
// Login User Session Key
'user' => 'user',
];

View File

@ -1,26 +0,0 @@
<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com>
// +----------------------------------------------------------------------
// +----------------------------------------------------------------------
// | 会话设置
// +----------------------------------------------------------------------
return [
'id' => '',
// SESSION_ID的提交变量,解决flash上传跨域
'var_session_id' => '',
// SESSION 前缀
'prefix' => 'think',
// 驱动方式 支持redis memcache memcached
'type' => '',
// 是否自动开启 SESSION
'auto_start' => true,
];

View File

@ -1,43 +0,0 @@
<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com>
// +----------------------------------------------------------------------
// +----------------------------------------------------------------------
// | 模板设置
// +----------------------------------------------------------------------
return [
// 模板引擎类型 支持 php think 支持扩展
'type' => 'Think',
// 默认模板渲染规则 1 解析为小写+下划线 2 全部转换小写 3 保持操作方法
'auto_rule' => 1,
'view_base' => env('root_path') . 'views' . DIRECTORY_SEPARATOR,
// 模板路径
'view_path' => '',
// 模板后缀
'view_suffix' => 'html',
// 模板文件名分隔符
'view_depr' => DIRECTORY_SEPARATOR,
// 模板引擎普通标签开始标记
'tpl_begin' => '{',
// 模板引擎普通标签结束标记
'tpl_end' => '}',
// 标签库标签开始标记
'taglib_begin' => '{',
// 标签库标签结束标记
'taglib_end' => '}',
'tpl_replace_string' => [
'__PLUGINS__' => '/assets/plugins',
'__CSS__' => '/assets/css',
'__JS__' => '/assets/js',
'__IMG__' => '/assets/img',
],
];

View File

@ -1,18 +0,0 @@
<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com>
// +----------------------------------------------------------------------
// +----------------------------------------------------------------------
// | Trace设置 开启 app_trace 后 有效
// +----------------------------------------------------------------------
return [
// 内置Html Console 支持扩展
'type' => 'Html',
];

View File

@ -1,72 +0,0 @@
<?php
use think\migration\Migrator;
use think\migration\db\Column;
use Phinx\Db\Adapter\MysqlAdapter;
class Rbac extends Migrator
{
/**
* Change Method.
*
* Write your reversible migrations using this method.
*
* More information on writing migrations is available here:
* http://docs.phinx.org/en/latest/migrations.html#the-abstractmigration-class
*
* The following commands can be used in this method and Phinx will
* automatically reverse them when rolling back:
*
* createTable
* renameTable
* addColumn
* renameColumn
* addIndex
* addForeignKey
*
* Remember to call "create()" or "update()" and NOT "save()" when working
* with the Table class.
*/
public function change()
{
$this->up();
}
public function up()
{
$table = $this->table(config('permissions.table.role'), [ 'engine'=>'InnoDB', 'comment' => '角色表']);
$table->addColumn('name', 'string',['limit' => 50, 'default'=>'','comment'=>'角色名称'])
->addColumn('created_at', 'timestamp', ['default' => 'CURRENT_TIMESTAMP', 'comment' => '创建时间'])
->addColumn('updated_at', 'timestamp', [ 'default' => null,'comment' => '更新时间'])
->addIndex(['name'], ['unique' => true])
->create();
$table = $this->table(config('permissions.table.permission'), ['engine' => 'InnoDB', 'comment' => '权限菜单']);
$table->addColumn('name', 'string',['limit' => 50, 'default'=>'','comment'=>'菜单名称'])
->addColumn('icon', 'string', ['limit' => 50, 'default'=>'', 'comment'=>'菜单图标'])
->addColumn('pid', 'integer', ['limit' => MysqlAdapter::INT_SMALL, 'comment'=>'父级菜单ID'])
->addColumn('module', 'string',['limit' => 50, 'default'=>'','comment'=>'模块名称'])
->addColumn('controller', 'string',['limit' => 50, 'default'=>'','comment'=>'控制器名称'])
->addColumn('action', 'string',['limit' => 50, 'default'=>'1','comment'=>'方法名称'])
->addColumn('is_show', 'integer',['limit' => MysqlAdapter::INT_TINY, 'default'=> 1,'comment'=>'1 展示 2 隐藏'])
->addColumn('created_at', 'timestamp', [ 'default' => 'CURRENT_TIMESTAMP','comment' => '创建时间'])
->addColumn('updated_at', 'timestamp', ['default' => null, 'comment' => '更新时间'])
->addIndex(['name'], ['unique' => true])
->create();
$table = $this->table(config('permissions.table.user_has_roles'), ['engine' => 'InnoDB', 'identity' => true, 'comment' => '用户角色关联']);
$table->addColumn('uid', 'integer',['limit' => 11, 'comment'=>'用户ID'])
->addColumn('role_id', 'integer', [ 'comment' => '角色ID'])
->create();
$table = $this->table(config('permissions.table.role_has_permissions'), ['engine' => 'InnoDB', 'identity' => true, 'comment' => '角色权限关联']);
$table->addColumn('role_id', 'integer',['limit' => 11, 'comment'=>'角色ID'])
->addColumn('permission_id', 'integer', [ 'comment' => '权限ID'])
->create();
}
public function down()
{
}
}

View File

@ -1,42 +0,0 @@
<?php
use think\migration\Migrator;
use think\migration\db\Column;
class Users extends Migrator
{
/**
* Change Method.
*
* Write your reversible migrations using this method.
*
* More information on writing migrations is available here:
* http://docs.phinx.org/en/latest/migrations.html#the-abstractmigration-class
*
* The following commands can be used in this method and Phinx will
* automatically reverse them when rolling back:
*
* createTable
* renameTable
* addColumn
* renameColumn
* addIndex
* addForeignKey
*
* Remember to call "create()" or "update()" and NOT "save()" when working
* with the Table class.
*/
public function change()
{
$table = $this->table('users', ['engine' => 'InnoDB', 'comment' => '用户表']);
$table->addColumn('name', 'string',['limit' => 50, 'default'=>'','comment'=>'用户名'])
->addColumn('email', 'string',['limit' => 255, 'default'=>'','comment'=>'邮箱'])
->addColumn('password', 'string',['limit' => 255, 'default'=>'','comment'=>'密码'])
->addColumn('remember_token', 'string',['limit' => 255, 'default'=>'','comment'=>'记住token'])
->addColumn('login_ip', 'string',['limit' => 50, 'default'=>'','comment'=>'登录IP'])
->addColumn('created_at', 'timestamp', ['default' => 'CURRENT_TIMESTAMP', 'comment' => '更新时间'])
->addColumn('login_at', 'timestamp', [ 'default' => null, 'comment' => '最近登录时间'])
->addIndex(['name', 'email'], ['unique' => true])
->create();
}
}

View File

@ -1,44 +0,0 @@
<?php
use think\migration\Migrator;
use think\migration\db\Column;
use Phinx\Db\Adapter\MysqlAdapter;
class Log extends Migrator
{
/**
* Change Method.
*
* Write your reversible migrations using this method.
*
* More information on writing migrations is available here:
* http://docs.phinx.org/en/latest/migrations.html#the-abstractmigration-class
*
* The following commands can be used in this method and Phinx will
* automatically reverse them when rolling back:
*
* createTable
* renameTable
* addColumn
* renameColumn
* addIndex
* addForeignKey
*
* Remember to call "create()" or "update()" and NOT "save()" when working
* with the Table class.
*/
public function change()
{
$table = $this->table('option_log', ['engine' => 'InnoDB', 'comment' => '操作日志表']);
$table->addColumn('user_name', 'string',['limit' => 50, 'default'=>'','comment'=>'用户名'])
->addColumn('user_id', 'integer', ['limit' => MysqlAdapter::INT_REGULAR, 'comment' => '用户ID'])
->addColumn('module', 'string',['limit' => 20, 'default'=>'','comment'=>'模块'])
->addColumn('controller', 'string',['limit' => 20, 'default'=>'','comment'=>'控制器'])
->addColumn('action', 'string',['limit' => 20, 'default'=>'','comment'=>'方法'])
->addColumn('option', 'string',['limit' => 50, 'default'=>'','comment'=>'操作'])
->addColumn('method', 'string',['limit' => 15, 'default'=>'','comment'=>'请求方法'])
->addColumn('created_at', 'timestamp', [ 'default' => 'CURRENT_TIMESTAMP','comment' => '更新时间'])
->create();
}
}

View File

@ -1,244 +0,0 @@
<?php
use think\migration\Seeder;
class Permissions extends Seeder
{
/**
* Run Method.
*
* Write your database seeder using this method.
*
* More information on writing seeders is available here:
* http://docs.phinx.org/en/latest/seeding.html
*/
public function run()
{
$data = [
[
'id' => 1,
'name' => '权限管理',
'icon' => '',
'pid' => 0,
'module' => '',
'controller' => '',
'action' => '',
'is_show' => 1,
'created_at' => date('Y-m-d H:i:s'),
'updated_at' => date('Y-m-d H:i:s'),
],
[
'id' => 2,
'name' => '用户管理',
'icon' => '',
'pid' => 1,
'module' => 'admin',
'controller' => 'user',
'action' => 'index',
'is_show' => 1,
'created_at' => date('Y-m-d H:i:s'),
'updated_at' => date('Y-m-d H:i:s'),
],
[
'id' => 3,
'name' => '角色管理',
'icon' => '',
'pid' => 1,
'module' => 'admin',
'controller' => 'role',
'action' => 'index',
'is_show' => 1,
'created_at' => date('Y-m-d H:i:s'),
'updated_at' => date('Y-m-d H:i:s'),
],
[
'id' => 4,
'name' => '菜单管理',
'icon' => '',
'pid' => 1,
'module' => 'admin',
'controller' => 'permission',
'action' => 'index',
'is_show' => 1,
'created_at' => date('Y-m-d H:i:s'),
'updated_at' => date('Y-m-d H:i:s'),
],
[
'id' => 5,
'name' => '创建用户',
'icon' => '',
'pid' => 2,
'module' => 'admin',
'controller' => 'user',
'action' => 'create',
'is_show' => 2,
'created_at' => date('Y-m-d H:i:s'),
'updated_at' => date('Y-m-d H:i:s'),
],
[
'id' => 6,
'name' => '编辑用户',
'icon' => '',
'pid' => 2,
'module' => 'admin',
'controller' => 'user',
'action' => 'edit',
'is_show' => 2,
'created_at' => date('Y-m-d H:i:s'),
'updated_at' => date('Y-m-d H:i:s'),
],
[
'id' => 7,
'name' => '删除用户',
'icon' => '',
'pid' => 2,
'module' => 'admin',
'controller' => 'user',
'action' => 'delete',
'is_show' => 2,
'created_at' => date('Y-m-d H:i:s'),
'updated_at' => date('Y-m-d H:i:s'),
],
[
'id' => 8,
'name' => '创建角色',
'icon' => '',
'pid' => 3,
'module' => 'admin',
'controller' => 'role',
'action' => 'create',
'is_show' => 2,
'created_at' => date('Y-m-d H:i:s'),
'updated_at' => date('Y-m-d H:i:s'),
],
[
'id' => 9,
'name' => '编辑角色',
'icon' => '',
'pid' => 3,
'module' => 'admin',
'controller' => 'role',
'action' => 'edit',
'is_show' => 2,
'created_at' => date('Y-m-d H:i:s'),
'updated_at' => date('Y-m-d H:i:s'),
],
[
'id' => 10,
'name' => '删除角色',
'icon' => '',
'pid' => 3,
'module' => 'admin',
'controller' => 'role',
'action' => 'delete',
'is_show' => 2,
'created_at' => date('Y-m-d H:i:s'),
'updated_at' => date('Y-m-d H:i:s'),
],
[
'id' => 11,
'name' => '获取角色权限',
'icon' => '',
'pid' => 3,
'module' => 'admin',
'controller' => 'role',
'action' => 'getPermissionsOfRole',
'is_show' => 2,
'created_at' => date('Y-m-d H:i:s'),
'updated_at' => date('Y-m-d H:i:s'),
],
[
'id' => 12,
'name' => '分配权限',
'icon' => '',
'pid' => 3,
'module' => 'admin',
'controller' => 'role',
'action' => 'givePermissions',
'is_show' => 2,
'created_at' => date('Y-m-d H:i:s'),
'updated_at' => date('Y-m-d H:i:s'),
],
[
'id' => 13,
'name' => '分配角色',
'icon' => '',
'pid' => 2,
'module' => 'admin',
'controller' => 'user',
'action' => 'giveRoles',
'is_show' => 2,
'created_at' => date('Y-m-d H:i:s'),
'updated_at' => date('Y-m-d H:i:s'),
],
[
'id' => 14,
'name' => '创建菜单',
'icon' => '',
'pid' => 4,
'module' => 'admin',
'controller' => 'permission',
'action' => 'create',
'is_show' => 2,
'created_at' => date('Y-m-d H:i:s'),
'updated_at' => date('Y-m-d H:i:s'),
],
[
'id' => 15,
'name' => '编辑菜单',
'icon' => '',
'pid' => 4,
'module' => 'admin',
'controller' => 'permission',
'action' => 'edit',
'is_show' => 2,
'created_at' => date('Y-m-d H:i:s'),
'updated_at' => date('Y-m-d H:i:s'),
],
[
'id' => 16,
'name' => '删除菜单',
'icon' => '',
'pid' => 4,
'module' => 'admin',
'controller' => 'permission',
'action' => 'delete',
'is_show' => 2,
'created_at' => date('Y-m-d H:i:s'),
'updated_at' => date('Y-m-d H:i:s'),
],
[
'id' => 17,
'name' => '日志记录',
'icon' => '',
'pid' => 1,
'module' => 'admin',
'controller' => 'Log',
'action' => 'index',
'is_show' => 1,
'created_at' => date('Y-m-d H:i:s'),
'updated_at' => date('Y-m-d H:i:s'),
],
];
$this->table(config('permissions.table.permission'))->insert($data)->save();
}
}

View File

@ -1,28 +0,0 @@
<?php
use think\migration\Seeder;
class RoleHasPermissions extends Seeder
{
/**
* Run Method.
*
* Write your database seeder using this method.
*
* More information on writing seeders is available here:
* http://docs.phinx.org/en/latest/seeding.html
*/
public function run()
{
$p = \think\permissions\facade\Permissions::all();
$data = [];
foreach ($p as $v) {
$data[] = [
'role_id' => 1,
'permission_id' => $v->id,
];
}
$this->table(config('permissions.table.role_has_permissions'))->insert($data)->save();
}
}

View File

@ -1,26 +0,0 @@
<?php
use think\migration\Seeder;
class Roles extends Seeder
{
/**
* Run Method.
*
* Write your database seeder using this method.
*
* More information on writing seeders is available here:
* http://docs.phinx.org/en/latest/seeding.html
*/
public function run()
{
$data = [
'name' => '超级管理员',
'created_at' => date('Y-m-d H:i:s'),
'updated_at' => date('Y-m-d H:i:s'),
];
$this->table(config('permissions.table.role'))->insert($data)->save();
}
}

View File

@ -1,24 +0,0 @@
<?php
use think\migration\Seeder;
class UserHasRoles extends Seeder
{
/**
* Run Method.
*
* Write your database seeder using this method.
*
* More information on writing seeders is available here:
* http://docs.phinx.org/en/latest/seeding.html
*/
public function run()
{
$data = [
'uid' => 1,
'role_id' => 1,
];
$this->table(config('permissions.table.user_has_roles'))->insert($data)->save();
}
}

View File

@ -1,27 +0,0 @@
<?php
use think\migration\Seeder;
class Users extends Seeder
{
/**
* Run Method.
*
* Write your database seeder using this method.
*
* More information on writing seeders is available here:
* http://docs.phinx.org/en/latest/seeding.html
*/
public function run()
{
$data = [
'name' => 'admin',
'email' => 'admin@gmail.com',
'password' => password_hash('admin', PASSWORD_DEFAULT),
'created_at' => date('Y-m-d H:i:s'),
'login_at' => date('Y-m-d H:i:s'),
];
$this->table('users')->insert([$data])->save();
}
}

View File

@ -1,102 +0,0 @@
<?php
/**
* Created by PhpStorm.
* User: Administrator
* Date: 2019/1/26
* Time: 11:37
*/
namespace thinking\icloud;
use thinking\icloud\factory\AuthFactory;
use thinking\icloud\httpclient\Client;
use thinking\icloud\exception\NotFoundException;
use thinking\icloud\Utility;
class AbstractCloud
{
use Utility;
protected $api;
protected $host;
protected $namespace;
protected $response;
public function __construct()
{
$this->host = config('cloud.host');
}
/**
* 获取 api url
*
* @time at 2019年01月26日
* @param string $host
* @param bool $isHttps
* @throws NotFoundException
* @return string
*/
protected function host($host = 'rs', bool $isHttps = false)
{
if (!array_key_exists($host, $this->host)) {
throw NotFoundException::NotFoundKey("Host Key '{$host}' Not Found In Config File");
}
return self::getHost($host, $isHttps);
}
/**
* 指定目标资源空间与目标资源名编码
*
* @time at 2019年01月26日
* @param string $bucket
* @param string $resourceName
* @return mixed
*/
protected function encodedEntry(string $bucket, string $resourceName)
{
return self::urlSafeBase64Encode(sprintf('%s:%s', $bucket, $resourceName));
}
public function __call($name, $arguments)
{
// TODO: Implement __call() method.
$client = new Client;
$client->uri = $arguments[0];
$client->method = $name;
if (isset($arguments[1]['headers']['Authorization'])) {
$client->params = $arguments[1];
} else {
$headers = AuthFactory::authorization($arguments[0], $name);
$client->params = array_merge_recursive(['headers' => $headers], $arguments[1] ?? []);
}
return $client->send();
}
protected function send(string $uri, string $method, array $options = [])
{
$client = new Client;
$client->uri = $uri;
$client->method = $method;
if (isset($options['headers']['Authorization'])) {
$client->params = $options;
} else {
$headers = AuthFactory::authorization($uri, $method);
$client->params = array_merge_recursive(['headers' => $headers], $options);
}
return $client->send();
}
/**
* 上传凭证
*
* @time at 2019年01月26日
* @param mixed ...$argument
* @return mixed
*/
public function uploadToken(...$argument)
{
return AuthFactory::uploadToken(...$argument);
}
}

View File

@ -1,51 +0,0 @@
<?php
/**
* Created by PhpStorm.
* User: Administrator
* Date: 2019/1/26
* Time: 10:37
*/
namespace thinking\icloud;
trait Utility
{
/**
* URL Base64 加密
*
* @time at 2019年01月26日
* @param string $string
* @return mixed
*/
public static function urlSafeBase64Encode(string $string)
{
return str_replace(['+','/'], ['-','_'], base64_encode($string));
}
/**
* 获取接口 HOST
*
* @time at 2019年01月26日
* @param string $host
* @param bool $isHttps
* @return string
*/
public static function getHost(string $host = 'rs', bool $isHttps = false)
{
return $isHttps ? 'https://' : 'http://' . config('cloud.host.'. strtolower($host));
}
/**
* csc32 校验
*
* @time at 2019年01月26日
* @param string $data
* @return string
*/
public static function crc32_data(string $data)
{
$hash = hash('crc32b', $data);
$array = unpack('N', pack('H*', $hash));
return sprintf('%u', $array[1]);
}
}

View File

@ -1,17 +0,0 @@
<?php
/**
* Created by PhpStorm.
* User: Administrator
* Date: 2019/1/30
* Time: 16:32
*/
namespace thinking\icloud\auth;
use thinking\icloud\Utility;
final class OssAuth
{
use Utility;
}

View File

@ -1,134 +0,0 @@
<?php
/**
* Created by PhpStorm.
* User: Administrator
* Date: 2019/1/26
* Time: 10:30
*/
namespace thinking\icloud\auth;
use thinking\icloud\Utility;
final class QiNiuAuth
{
use Utility;
/**
* 授权凭证
*
* @time at 2019年01月26日
* @param string $uri
* @param string $method
* @return array
*/
public static function authorization(string $uri, string $method)
{
return ['Authorization' => sprintf('QBox %s', self::getAccessToken($uri, '', 'application/x-www-form-urlencoded'))];
}
/**
* 管理 Token
*
* @time at 2019年01月26日
* @param string $urlString
* @param string $body
* @param string $contentType
* @return string
*/
public static function getAccessToken(string $urlString, string $body, string $contentType = '')
{
$appKey = config('cloud.qiniu.app_key');
$appSecret = config('cloud.qiniu.app_secret');
$url = parse_url($urlString);
$data = '';
if (array_key_exists('path', $url)) {
$data = $url['path'];
}
if (array_key_exists('query', $url)) {
$data .= '?' . $url['query'];
}
$data .= "\n";
if ($body && $contentType === 'application/x-www-form-urlencoded') {
$data .= $body;
}
$data = hash_hmac('sha1', $data, $appSecret, true);
$encodedSign = self::urlSafeBase64Encode($data);
$accessToken = sprintf('%s:%s', $appKey, $encodedSign);
return $accessToken;
}
/**
* 获取上传凭证
*
* @time at 2019年01月26日
* @param string $bucket
* @param string $key
* @param int $expires
* @param string $policy
* @param bool $strictPolicy
* @return string
*/
public static function uploadToken(
string $bucket,
string $key = '',
int $expires = 3600,
string $policy = '',
bool $strictPolicy = true
){
$appKey = config('cloud.qiniu.app_key');
$appSecret = config('cloud.qiniu.app_secret');
$scope = $key ? sprintf('%s:%s', $bucket, $key) : $bucket;
$deadline = time() + $expires;
$args = self::copyPolicy($args, $policy, $strictPolicy);
$args['scope'] = $scope;
$args['deadline'] = $deadline;
$encodedPutPolicy = self::urlSafeBase64Encode(json_encode($args));
$sign = hash_hmac('sha1', $encodedPutPolicy, $appSecret, true);
$encodedSign = self::urlSafeBase64Encode($sign);
return sprintf('%s:%s:%s', $appKey, $encodedSign, $encodedPutPolicy);
}
private static function copyPolicy(&$policy, $originPolicy, $strictPolicy)
{
if (!$originPolicy) {
return [];
}
$policyFields = config('cloud.qiniu.policyFields');
foreach ($originPolicy as $key => $value) {
if (!$strictPolicy || in_array((string)$key, $policyFields, true)) {
$policy[$key] = $value;
}
}
return $policy;
}
/**
* 下载凭证
*
* @time at 2019年01月26日
* @param string $uri
* @param int $expires
* @return string
*/
public static function dowmloadToken(string $uri, int $expires = 3600)
{
$appSecret = config('cloud.qiniu.app_secret');
$appKey = config('cloud.qiniu.app_key');
$uri = sprintf('%s?e=%s', $uri, time() + $expires);
$sign = hash_hmac('sha1', $uri, $appSecret, true);
$encodedSign = self::urlSafeBase64Encode($sign);
return sprintf('%s:%s', $appKey, $encodedSign);
}
}

View File

@ -1,60 +0,0 @@
<?php
/**
* Created by PhpStorm.
* User: Administrator
* Date: 2019/1/26
* Time: 10:31
*/
namespace thinking\icloud\auth;
class UpYunAuth
{
/**
* 签名
*
* @time at 2019年01月26日
* @param string $uri
* @param string $method
* @param string $contentMD5
* @return array
*/
public static function authorization(string $uri, string $method, string $contentMD5= '')
{
$date = gmdate('D, d M Y H:i:s \G\M\T');
$singArr = [$method, parse_url($uri)['path'], $date];
if ($contentMD5) $singArr[] = $contentMD5;
$sign = base64_encode(hash_hmac('sha1', implode('&', $singArr), md5(config('cloud.upyun.password')), true));
return [
'Authorization' => sprintf('UPYUN %s:%s', config('cloud.upyun.opreator'), $sign),
'Date' => $date,
];
}
/**
* 获取 token
*
* @time at 2019年01月26日
* @param string $method
* @param int $expire
* @param string $uriPrefix
* @param string $uriPostfix
* @return string
*/
public static function uploadToken(string $method, int $expire = 3888000, string $uriPrefix = '', string $uriPostfix= '')
{
$operator = config('cloud.upyun.opreator');
$password = config('cloud.upyun.password');
$tokenArr = [$operator, $password, $method, $expire];
if ($uriPrefix) $tokenArr[] = $uriPrefix;
if ($uriPostfix) $tokenArr[] = $uriPostfix;
$token = base64_encode(hash_hmac('sha1',implode('&', $tokenArr) , $password, true));
return sprintf('UPYUN %s:%s', $operator, $token);
}
}

View File

@ -1,417 +0,0 @@
<?php
/**
* Created by PhpStorm.
* User: Administrator
* Date: 2019/1/26
* Time: 11:33
*/
namespace thinking\icloud\cloud;
use thinking\icloud\AbstractCloud;
use finfo;
use thinking\icloud\exception\NotFoundException;
use GuzzleHttp\Psr7\Stream;
class QiNiuCloud extends AbstractCloud
{
const BLOCK_SIZE = 4 * 1024 * 1024;
/**
* 获取 bucket 列表
*
* @time at 2019年01月26日
* @throws NotFoundException
* @return mixed
*/
public function buckets()
{
$uri = $this->host() . '/buckets' ;
return $this->get($uri);
}
/**
* 创建 bucket
*
* @time at 2019年01月26日
* @param string $bucket (bucket名称)
* @param string $region 地区)[z0华东 z1华北 z2华南 na0北美 as0新加坡 ]
* @throws \thinking\icloud\exception\NotFoundException
* @return mixed
*/
public function create(string $bucket, string $region)
{
$uri = sprintf($this->host() . '/mkbucketv2/%s/region/%s', self::urlSafeBase64Encode($bucket), $region);
return $this->post($uri);
}
/**
* 删除空间
*
* @time at 2019年01月26日
* @param string $bucket
* @throws \thinking\icloud\exception\NotFoundException
* @return mixed
*/
public function drop(string $bucket)
{
$uri = sprintf($this->host() . '/drop/%s', $bucket);
return $this->post($uri);
}
/**
* 获取空间名称
*
* @time at 2019年01月26日
* @param string $bucket
* @throws \thinking\icloud\exception\NotFoundException
* @return mixed
*/
public function getDomainListOfBucket(string $bucket)
{
$uri = sprintf($this->host( 'api') . '/v6/domain/list?tbl=%s', $bucket);
return $this->get($uri);
}
/**
* 设置空间权限
*
* @time at 2019年01月26日
* @param string $bucket
* @param int $private (0 公开 1 私有)
* @throws \thinking\icloud\exception\NotFoundException
* @return bool
*/
public function setPrivate(string $bucket, int $private = 0)
{
if (!in_array($private, [0, 1])) return false;
$uri = sprintf('%s?%s', $this->host( 'uc') . '/private', http_build_query(['bucket' => $bucket, 'private' => $private]));
return $this->post($uri);
}
/**
*
* 资源统计
* @space 获取标准存储的存储量统计
* @count 获取标准存储的文件数量统计
* @space_line 获取低频存储的存储量统计
* @count_line 获取低频存储的文件数量统计
* @blob_transfer 获取跨区域同步流量统计
* @rs_chtype 获取存储类型请求次数统计
* @blob_io 获取外网流出流量统计和 GET 请求次数统计
* @rs_put 获取 PUT 请求次数统计
* @time at 2019年01月26日
* @param string $begin
* @param string $end
* @param string $type
* @throws \thinking\icloud\exception\NotFoundException
* @return mixed
*/
public function statistics(string $begin, string $end, $type = 'space')
{
$urls = [
'space' => '/v6/space?begin=%s&end=%s&g=day',
'count' => '/v6/count?begin=%s&end=%s&g=day',
'space_line' => '/v6/space_line?begin=%s&end=%s&g=day',
'count_line' => '/v6/count_line?begin=%s&end=%s&g=day',
'blob_transfer' => '/v6/blob_transfer?begin=%s&end=%s&g=day&select=size',
'rs_chtype' => '/v6/rs_chtype?begin=%s&end=%s&g=day&select=hits',
'blob_io' => '/v6/blob_io?begin=%s&end=%s&g=day&select=flow&$src=origin',
'rs_put' => '/v6/rs_put?begin=%s&end=%s&g=day&select=hits',
];
$uri = sprintf($this->host('api') . $urls[$type], $begin, $end);
return $this->get($uri);
}
/**
* 列出空间所有资源
*
* @time at 2019年01月26日
* @param string $bucket
* @param string $marker
* @param int $limit
* @param string $prefix
* @param string $delimiter
* @throws \thinking\icloud\exception\NotFoundException
* @return mixed
*/
public function list(string $bucket, string $marker = '', int $limit = 10, string $prefix = '', string $delimiter = '')
{
$uri = sprintf($this->host('rsf') .'/list?bucket=%s&marker=%s&limit=%d&prefix=%s&delimiter=%s', $bucket, $marker, $limit, $prefix, $delimiter);
return $this->get($uri);
}
/**
* 获取资源原信息
*
* @time at 2019年01月26日
* @param string $bucket
* @param string $resourceName
* @throws \thinking\icloud\exception\NotFoundException
* @return mixed
*/
public function stat(string $bucket, string $resourceName)
{
//1372-the-dawn-of-hope-tomasz-chistowski.jpg
$encodedEntryUri = $this->encodedEntry($bucket, $resourceName);
$uri = sprintf($this->host() . '/stat/%s', $encodedEntryUri);
return $this->get($uri);
}
/**
* 将资源从一个空间移动到另一个空间, 该操作不支持跨账号操作, 不支持跨区域操作
*
* @time at 2019年01月26日
* @param string $localBucket
* @param string $destBucket
* @param string $localResourceName
* @param string $destResourceName
* @throws \thinking\icloud\exception\NotFoundException
* @return mixed
*/
public function move(string $localBucket, string $destBucket, string $localResourceName, string $destResourceName = '')
{
$encodedEntryURISrc = $this->encodedEntry($localBucket, $localResourceName);
$encodedEntryURIDest = $this->encodedEntry($destBucket, $destResourceName ? : $localResourceName);
$uri = sprintf($this->host() .'/move/%s/%s' , $encodedEntryURISrc, $encodedEntryURIDest);
return $this->post($uri);
}
/**
* 将资源从一个空间复制到另一个空间, 该操作不支持跨账号操作, 不支持跨区域操作
*
* @time at 2019年01月26日
* @param string $localBucket
* @param string $destBucket
* @param string $localResourceName
* @param string $destResourceName
* @throws \thinking\icloud\exception\NotFoundException
* @return mixed
*/
public function copy(string $localBucket, string $destBucket, string $localResourceName, string $destResourceName = '')
{
$encodedEntryURISrc = $this->encodedEntry($localBucket, $localResourceName);
$encodedEntryURIDest = $this->encodedEntry($destBucket, $destResourceName ? : $localResourceName);
$uri = sprintf($this->host() . '/copy/%s/%s', $encodedEntryURISrc, $encodedEntryURIDest);
return $this->post($uri);
}
/**
* 删除指定空间资源
*
* @time at 2019年01月26日
* @param string $bucket
* @param string $resourceName
* @throws \thinking\icloud\exception\NotFoundException
* @return mixed
*/
public function delete(string $bucket, string $resourceName)
{
$encodedEntryUri = $this->encodedEntry($bucket, $resourceName);
$uri = sprintf($this->host() . '/delete/%s', $encodedEntryUri);
return $this->post($uri);
}
/**
* 主权远程 IMG 到指定空间
*
* @time at 2019年01月26日
* @param string $remoteImgUri
* @param string $destBucket
* @throws \thinking\icloud\exception\NotFoundException
* @return mixed
*/
public function fetch(string $remoteImgUri, string $destBucket)
{
$imgEncodedUri = self::urlSafeBase64Encode($remoteImgUri);
$encodedEntryUri = self::urlSafeBase64Encode($destBucket);
$uri = sprintf($this->host( 'iovip') . '/fetch/%s/to/%s', $imgEncodedUri, $encodedEntryUri);
return $this->post($uri);
}
/**
* 批量操作
*
* @说明
* 数组格式
* [
* stat => ['bucket', 'resourceName']
* delete => ['bucket', 'resourceName']
* move => ['localbucket', 'destbucket', 'resourceName', 'destResourceName'(可不写)]
* copy => ['localbucket', 'destbucket', 'resourceName', 'destResourceName'(可不写)]
* ]
* @time at 2019年01月26日
* @param array $batchOptions
* @throws \thinking\icloud\exception\NotFoundException
* @return mixed
*/
public function batch(array $batchOptions)
{
$requestParams = '';
foreach ($batchOptions as $option => $param)
{
if ($option === 'stat' || $option === 'delete') {
$requestParams .= sprintf('op=/%s/%s&', $option, $this->encodedEntry($param[0], $param[1]));
} else if($option === 'move' || $option === 'copy') {
$encodedEntryURISrc = $this->encodedEntry($param[0], $param[2]);
$encodedEntryURIDest = $this->encodedEntry($param[1], count($param) >= 4 ? $param[3] : $param[2]);
$requestParams .= sprintf('op=/%s/%s/%s&', $option, $encodedEntryURISrc, $encodedEntryURIDest);
} else {
continue;
}
}
$uri = sprintf('%s?%s', $this->host() . '/batch', $requestParams);
return $this->post($uri);
}
/**
* 镜像资源更新
*
* @time at 2019年01月26日
* @param string $bucket
* @param string $resourceName
* @throws \thinking\icloud\exception\NotFoundException
* @return mixed
*/
public function prefetch(string $bucket, string $resourceName)
{
$encodedEntryUri = $this->encodedEntry($bucket, $resourceName);
$uri = sprintf($this->host('iovip') .'/prefetch/%s' , $encodedEntryUri);
return $this->post($uri);
}
/**
* Http 直传文件
*
* @time at 2019年01月26日
* @param string $bucket
* @param resource $file
* @param array $params 直传可选参数 => https://developer.qiniu.com/kodo/api/1312/upload
* @throws \thinking\icloud\exception\NotFoundException
* @return mixed
*/
public function uploadFile(string $bucket, $file, array $params = [])
{
if (!is_resource($file)) {
throw new \Exception('$file Must Be Resource Type');
}
$uri = $this->host( 'up');
$stream = new Stream($file);
//判断如果文件大于4M则使用分块上传
if ($stream->getSize() > self::BLOCK_SIZE) {
return $this->uploadFileByBlocks($bucket, $file);
}
//$filename = md5(basename($stream->getMetadata('uri')) . time());
$uploadToken = $this->UploadToken($bucket);
$options['multipart'] = [
['name' => 'key', 'contents' => basename($stream->getMetadata('uri'))],
['name' => 'file', 'contents' => $stream, 'filename' => basename($stream->getMetadata('uri'))],
['name' => 'token', 'contents' => $uploadToken],
['name' => 'crc32', 'contents' => self::crc32_data($stream)],
['name' => 'Content-Type', 'contents' => 'application/octet-stream'],
];
if (!empty($params)) {
$options['multipart'] = array_merge($params, $options['multipart']);
}
return $this->post($uri, $options);
}
/**
* 创建块
*
* @time at 2019年01月26日
* @param string $bucket
* @param $file
* @throws \thinking\icloud\exception\NotFoundException
* @return mixed
*/
protected function uploadFileByBlocks(string $bucket, $file)
{
//需要安装fileinfo扩展
if (!extension_loaded('fileinfo')) {
throw NotFoundException::NotFoundExtension('PHPExtension Fileinfo Not Found, Please Install It First');
}
$stream = new Stream($file);
$filezie = $stream->getSize();
//保存ctx值 用于后续合并文件
$ctxArr = [];
//已上传文件大小
$uploadSize = 0;
while ($uploadSize < $filezie) {
//剩余文件大小
$remainsize = $filezie - $uploadSize;
//需要读取的文件大小
$needReadSize = $remainsize > self::BLOCK_SIZE ? self::BLOCK_SIZE : $remainsize;
$content = $stream->read($needReadSize);
//创建块并且上传第一个片
$options['body'] = $content;
$headers = [
'Content-Type' => 'application/octet-stream',
'Content-Length' => $needReadSize,
];
$options['headers'] = $headers;
$uri = sprintf($this->host( 'up') .'/mkblk/%s' , $needReadSize);
$response = $this->post($uri, $options);
$data = json_decode($response->getBody()->getContents(), true);
array_push($ctxArr, $data['ctx']);
$uploadSize += $needReadSize;
}
return $this->mkfile($stream, $bucket, $ctxArr);
}
/**
* 创建文件
*
* @time at 2019年01月26日
* @param Stream $stream
* @param string $bucket
* @param array $ctx
* @throws \thinking\icloud\exception\NotFoundException
* @return mixed
*/
protected function mkfile(Stream $stream, string $bucket, array $ctx)
{
$file = $stream->getMetadata('uri');
$key = self::urlSafeBase64Encode(sprintf('%s', basename($file)));
$mimetype = (new finfo(FILEINFO_MIME_TYPE))->file($file);
$filesize = $stream->getSize();
$userVar = md5(time());
$options['headers'] = ['Authorization' => 'UpToken ' . $this->UploadToken($bucket, basename($file))];
$options['body'] = implode(',', $ctx);
$uri = sprintf($this->host( 'up') . '/mkfile/%s/key/%s/mimeType/%s/x:user-var/%s', $filesize, $key, self::urlSafeBase64Encode($mimetype), self::urlSafeBase64Encode($userVar));
return $this->post($uri, $options);
}
}

View File

@ -1,270 +0,0 @@
<?php
/**
* Created by PhpStorm.
* User: Administrator
* Date: 2019/1/26
* Time: 11:34
*/
namespace thinking\icloud\cloud;
use thinking\icloud\AbstractCloud;
use thinking\icloud\exception\NotFoundException;
use GuzzleHttp\Psr7\Stream;
class UpYunCloud extends AbstractCloud
{
const BLOCK_SIZE = 1024 * 1024;
const SUCCESS_CODE = 204;
protected $bucket;
protected $fileDir;
protected $stream;
protected $options;
protected $filename;
//本次上传任务的标识,是初始化断点续传任务时响应信息中的
protected $multiuuid;
//指定此次分片的唯一 ID应严格等于上一次请求返回的
protected $nextpartid;
/**
* 创建文件夹
*
* @time at 2019年01月26日
* @param string $bucket
* @param string $directory
* @throws NotFoundException
* @return mixed
*/
public function create(string $bucket, string $directory)
{
$uri = sprintf($this->host( 'v0') . '/%s/', $bucket . $directory );
return $this->post($uri);
}
/**
* 删除空间
*
* @time at 2019年01月26日
* @param string $bucket
* @param string $directory
* @throws NotFoundException
* @return mixed
*/
public function drop(string $bucket, string $directory)
{
$uri = sprintf($this->host( 'v0') . '/%s/', $bucket . $directory );
return $this->delete($uri);
}
/**
* 获取文件列表
*
* @time at 2019年01月26日
* @param string $bucket
* @param string $directory
* @param array $options ['x-list-iter' => '分页开始位置', 'x-list-limit' => '获取文件数量', 'x-list-order' => '排序' ]
* @throws NotFoundException
* @return mixed
*/
public function list(string $bucket, string $directory, array $options = ['x-list-limit' => 1])
{
$uri = sprintf($this->host( 'v0') . '/%s/', $bucket . $directory );
return $this->get($uri, $options);
}
/**
* 获取服务容量
*
* @time at 2019年01月26日
* @param string $bucket
* @throws NotFoundException
* @return mixed
*/
public function usage(string $bucket)
{
$uri = sprintf($this->host( 'v0') . '/%s/?usage', $bucket );
return $this->get($uri);
}
/**
* 删除文件
*
* @time at 2019年01月26日
* @param string $bucket
* @param string $fileDir
* @throws NotFoundException
* @return mixed
*/
public function deleteFile(string $bucket, string $fileDir)
{
$uri = sprintf($this->host( 'v0') . '/%s/%s' , $bucket, $fileDir );
return $this->delete($uri);
}
/**
* 下载文件
*
* @time at 2019年01月26日
* @param string $bucket
* @param string $fileDir
* @throws NotFoundException
* @return mixed
*/
public function downloadFile(string $bucket, string $fileDir)
{
$uri = sprintf($this->host( 'v0') . '/%s/%s' , $bucket, $fileDir );
return $this->get($uri, ['stream' => true]);
}
/**
* 上传文件
*
* @time at 2019年01月26日
* @param string $bucket
* @param string $fileDir
* @param $locationFile
* @param array $options => 参考http://docs.upyun.com/api/rest_api/#_2
* @throws NotFoundException
* @return mixed
*/
public function uploadFile(string $bucket, string $fileDir, $locationFile, array $options = [])
{
if (!is_resource($locationFile)) {
throw new \Exception('$localfile Must Be Resource Type', 500);
}
$stream = new Stream($locationFile);
$this->bucket = $bucket;
$this->fileDir = $fileDir;
$this->stream = $stream;
$this->options = $options;
$this->filename = basename($stream->getMetadata('uri'));
#上传文件大于限制文件大小, 则断点续传
if ( $stream->getSize() > self::BLOCK_SIZE ) {
return $this->uploadComplete();
}
$uri = sprintf($this->host('v0') . '/%s/%s', $this->bucket, $this->fileDir . $this->filename);
if (!empty($this->options)) $options['headers'] = $this->options;
$options['headers'] = ['Content-Length' => $stream->getSize()];
$options['body'] = $this->stream;
return $this->put($uri, $this->options);
}
/**
* 初始化断电续传
*
* @time at 2019年01月26日
* @throws NotFoundException
* @return void
*/
protected function initUpload()
{
$mimeType = (new finfo(FILEINFO_MIME_TYPE))->file($this->stream->getMetadata('uri'));
$headers = [
'x-upyun-multi-stage' => 'initiate',
'x-upyun-multi-length' => $this->stream->getSize(),
'x-upyun-multi-type' => $mimeType ? : 'application/octet-stream',
];
$this->options['headers'] = $headers;
$uri = sprintf($this->host( 'v0') . '/%s/%s', $this->bucket, $this->fileDir . $this->filename);
$response = $this->put($uri, $this->options);
if ( !($response->getStatusCode() == self::SUCCESS_CODE) ) {
throw new \Exception('Failed To Respond');
}
$headers = $response->getHeaders();
if (!isset($headers['x-upyun-multi-uuid'])) {
throw NotFoundException::NotFoundKey('Response Headers Not Found Key "x-upyun-multi-uuid"');
}
if (!isset($headers['x-upyun-next-part-id'])) {
throw NotFoundException::NotFoundKey('Response Headers Not Found Key "x-upyun-next-part-id"');
}
$this->multiuuid = $headers['x-upyun-multi-uuid'];
$this->nextpartid = $headers['x-upyun-next-part-id'];
}
/**
* 上传分块
*
* @time at 2019年01月26日
* @throws NotFoundException
* @return void
*/
protected function uploading()
{
$uploadSize = 0;
$filesize = $this->stream->getSize();
while ($uploadSize < $filesize) {
//剩余文件大小
$remainsize = $filesize - $uploadSize;
//需要读取的文件大小
$needReadSize = $remainsize > self::BLOCK_SIZE ? self::BLOCK_SIZE : $remainsize;
$content = $this->stream->read($needReadSize);
$headrs = [
'x-upyun-multi-stage' => 'upload',
'x-upyun-multi-uuid' => $this->multiuuid,
'x-upyun-part-id' => $this->nextpartid,
];
$this->options['body'] = $content;
$this->options['headers'] = $headrs;
$uri = sprintf($this->host( 'v0') . '/%s/%s', $this->bucket, $this->fileDir . $this->filename);
$response = $this->put($uri, $this->options);
if ( !($response->getStatusCode() == self::SUCCESS_CODE) ) {
throw new \Exception('Failed To Respond');
}
$headers = $response->getHeaders();
if (!isset($headers['x-upyun-multi-uuid'])) {
throw NotFoundException::NotFoundKey('Response Headers Not Found Key "x-upyun-multi-uuid"');
}
if (!isset($headers['x-upyun-next-part-id'])) {
throw NotFoundException::NotFoundKey('Response Headers Not Found Key "x-upyun-next-part-id"');
}
$this->multiuuid = $headers['x-upyun-multi-uuid'];
$this->nextpartid = $headers['x-upyun-next-part-id'];
$uploadSize += $needReadSize;
}
}
/**
* 完成上传
*
* @time at 2019年01月26日
* @throws NotFoundException
* @return mixed
*/
protected function uploadComplete()
{
//初始化
$this->initUpload();
//上传
$this->uploading();
//合并完成上传
$headers = [
'x-upyun-multi-stage' => 'complete',
'x-upyun-multi-uuid' => $this->multiuuid,
];
$this->options['headers'] = $headers;
$uri = sprintf($this->host( 'v0') .'/%s/%s', $this->bucket, $this->fileDir . $this->filename);
return $this->put($uri, $this->options);
}
}

View File

@ -1,50 +0,0 @@
<?php
/**
* Created by PhpStorm.
* User: Administrator
* Date: 2019/1/26
* Time: 11:38
*/
namespace thinking\icloud\exception;
class NotFoundException extends \Exception
{
/**
* key not found
*
* @time at 2019年01月26日
* @param string $msg
* @param int $code
* @return NotFoundException
*/
public static function NotFoundKey(string $msg, $code = 404)
{
return new static($msg, $code, null);
}
/**
* method not found
*
* @time at 2019年01月26日
* @param string $msg
* @param int $code
* @return NotFoundException
*/
public static function NotFoundMethod(string $msg, int $code = 404)
{
return new static($msg, $code, null);
}
/**
* extension not found
*
* @time at 2019年01月26日
* @param string $msg
* @param int $code
* @return NotFoundException
*/
public static function NotFoundExtension(string $msg, $code = 404)
{
return new static($msg, $code, null);
}
}

View File

@ -1,39 +0,0 @@
<?php
/**
* Created by PhpStorm.
* User: Administrator
* Date: 2019/1/26
* Time: 10:28
*/
namespace thinking\icloud\factory;
class AuthFactory
{
/**
* 认证驱动
*
* @time at 2019年01月26日
* @param string $name
* @param mixed ...$argument
* @return mixed
*/
public static function create(string $name, ...$argument)
{
$defaultDriver = config('cloud.driver.default');
$auth = config('cloud.driver.' . $defaultDriver . 'Auth');
return $auth::$name(...$argument);
}
/**
* 静态访问
*
* @time at 2019年01月26日
* @param string $name
* @param $argument
* @return mixed
*/
public static function __callstatic(string $name, $argument)
{
return self::create($name, ...$argument);
}
}

View File

@ -1,49 +0,0 @@
<?php
/**
* Created by PhpStorm.
* User: Administrator
* Date: 2019/1/26
* Time: 10:23
*/
namespace thinking\icloud\factory;
class ICloudFactory
{
protected static $driver = null;
/**
* set driver
*
* @time at 2019年01月26日
* @param string $driver
* @return static
*/
public static function driver(string $driver)
{
self::$driver = $driver;
// 设置 config 驱动
config('cloud.driver.default', $driver);
return new static();
}
/**
* 静态访问
*
* @time at 2019年01月26日
* @param $name
* @param mixed ...$arguments
* @return mixed
*/
public static function __callStatic($name, $arguments)
{
// TODO: Implement __callStatic() method.
$cloud = !self::$driver ? config('cloud.driver.' . config('cloud.driver.default')) : config('cloud.driver.' . self::$driver);
return (new $cloud)->$name(...$arguments);
}
}

View File

@ -1,70 +0,0 @@
<?php
/**
* Created by PhpStorm.
* User: Administrator
* Date: 2019/1/26
* Time: 18:23
*/
namespace thinking\icloud\httpclient;
use GuzzleHttp\Client as HttpClient;
class Client implements \ArrayAccess
{
protected $params = [];
protected $client = null;
protected $method = null;
protected $uri = null;
/**
* 发送数据
*
* @time at 2019年01月26日
* @throws \GuzzleHttp\Exception\GuzzleException
* @return mixed|\Psr\Http\Message\ResponseInterface
*/
public function send()
{
return (new HttpClient)->request($this->method, $this->uri, $this->params);
}
public function set($offset, $value)
{
$this->$offset = $value;
}
/**
* 魔术方法
*
* @time at 2019年01月26日
* @param string $key
* @param $value
* @return void
*/
public function __set(string $key, $value)
{
$this->$key = $value;
}
public function offsetSet($offset, $value)
{
$this->params[$offset] = $value;
}
public function offsetGet($offset)
{
return $this->params[$offset];
}
public function offsetExists($offset)
{
return isset($this->params[$offset]);
}
public function offsetUnset($offset)
{
unset($this->params[$offset]);
}
}

View File

@ -1,30 +0,0 @@
<?php
/**
* Created by PhpStorm.
* User: Administrator
* Date: 2018/12/29
* Time: 16:19
*/
namespace thinking\socialite\command;
use think\console\Command;
use think\console\Input;
use think\console\Output;
class SocialiteCommand extends Command
{
protected function configure()
{
$this->setName('socialite publish')
->setDescription('publish socialite config');
}
protected function execute(Input $input, Output $output)
{
$config = dirname(__DIR__) . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'socialite.php';
copy($config, app('config_path'));
$output->writeln('publish successfully, check it' . PHP_EOL);
}
}

View File

@ -1,17 +0,0 @@
{
"name": "thinking/socialite",
"description": "a socialite package for thinkphp5.1*",
"license": "MIT",
"authors": [
{
"name": "yanwnewu",
"email": "82664165@qq.com"
}
],
"minimum-stability": "dev",
"require": {
"php": "^7.1.3",
"ext-json": "*",
"guzzlehttp/guzzle": "~6.0"
}
}

View File

@ -1,35 +0,0 @@
<?php
/**
* Created by PhpStorm.
* User: Administrator
* Date: 2018/12/28
* Time: 11:21
*/
return [
'default' => 'qq',
'qq' => [
'app_id' => '',
'app_secret' => '',
'redirect_url' => 'http://127.0.0.1:8000/oauth',
],
'weibo' => [
'app_id' => '',
'app_secret' => '',
'redirect_url' => 'http://www.rllady.com/home/index/sinaLogin',
],
'github' => [
'app_id' => '',
'app_secret' => '',
'redirect_url' => 'http://127.0.0.1:8000/oauth',
],
'wx' => [
'app_id' => '',
'app_secret' => '',
'redirect_url' => 'http://127.0.0.1:8000/oauth',
'scope' => '',
],
];

View File

@ -1,110 +0,0 @@
<?php
/**
* Created by PhpStorm.
* User: Administrator
* Date: 2018/12/28
* Time: 14:25
*/
namespace thinking\socialite;
use thinking\socialite\provider\GithubProvider;
use thinking\socialite\provider\QqProvider;
use thinking\socialite\provider\WeiBoProvider;
use thinking\socialite\provider\WxProvider;
class Socialite
{
/**
* QQ 登录
*
* @time at 2018年12月28日
* @return QqProvider
*/
protected function qqDriver()
{
$config = config('socialite.qq');
return new QqProvider(
$config['app_id'], $config['app_secret'], $config['redirect_url'], $config['scope'] ?? ''
);
}
/**
* 微博 登录
*
* @time at 2018年12月28日
* @return WeiBoProvider
*/
protected function weiboDriver()
{
$config = config('socialite.weibo');
return new WeiBoProvider(
$config['app_id'], $config['app_secret'], $config['redirect_url'], $config['scope'] ?? ''
);
}
/**
* Github 登录
*
* @time at 2018年12月28日
* @return GithubProvider
*/
protected function githubDriver()
{
$config = config('socialite.github');
return new GithubProvider(
$config['app_id'], $config['app_secret'], $config['redirect_url'], $config['scope'] ?? ''
);
}
/**
* 微信 登录
*
* @time at 2018年12月28日
* @return WxProvider
*/
protected function wxDriver()
{
$config = config('socialite.wx');
return new WxProvider(
$config['app_id'], $config['app_secret'], $config['redirect_url'], $config['scope'] ?? ''
);
}
/**
* return provider
*
* @time at 2018年12月29日
* @param $type
* @return \thinking\socialite\provider\AbstractProvider
*/
public function driver($type = null)
{
$driver = $this->createDriver($type);
$driver->oauth();
return $driver;
}
/**
* create oauth provider
*
* @time at 2018年12月29日
* @param $type
* @return mixed
*/
protected function createDriver($type)
{
$defaultDriver = config('socialite.default');
$driver = $type ? : $defaultDriver;
$function = $driver . 'Driver';
return call_user_func([$this, $function]);
}
}

View File

@ -1,165 +0,0 @@
<?php
/**
* Created by PhpStorm.
* User: Administrator
* Date: 2018/12/29
* Time: 9:08
*/
namespace thinking\socialite;
class User
{
/**
* @var int
*/
public $id;
/**
* @var string
*/
public $nickname;
/**
* @var string
*/
public $email;
/**
* @var string
*/
public $avatar;
/**
* @var string
*/
public $name;
/**
* @var array
*/
public $user;
/**
* get userId
*
* @time at 2018年12月29日
* @return int
*/
public function getUserId()
{
return (int)$this->id;
}
/**
* get nickname
*
* @time at 2018年12月29日
* @return string
*/
public function getNickName()
{
return $this->nickname;
}
/**
* get email
*
* @time at 2018年12月29日
* @return string
*/
public function getEmail()
{
return $this->email;
}
/**
* get avatar
*
* @time at 2018年12月29日
* @return string
*/
public function getAvatar()
{
return $this->avatar;
}
/**
* get name
*
* @time at 2018年12月29日
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* set user
*
* @time at 2018年12月29日
* @param $user
* @return $this
*/
public function setUser($user)
{
$this->user = $user;
return $this;
}
/**
* set property
*
* @time at 2018年12月29日
* @param $user
* @return $this
*/
public function map($user)
{
foreach ($user as $attr => $value) {
if ($this->hasProperty($attr)) {
$this->{$attr} = $value;
}
}
return $this;
}
/**
* has property
*
* @time at 2018年12月29日
* @param $attr
* @return bool
*/
protected function hasProperty($attr)
{
return property_exists($this, $attr);
}
public function __get($name)
{
// TODO: Implement __get() method.
return $this->user[$name];
}
public function __isset($name)
{
// TODO: Implement __isset() method.
return isset($this->user[$name]);
}
public function __set($name, $value)
{
// TODO: Implement __set() method.
$this->user[$name] = $value;
}
public function __unset($name)
{
// TODO: Implement __unset() method.
unset($this->user[$name]);
}
}

View File

@ -1,14 +0,0 @@
<?php
/**
* Created by PhpStorm.
* User: Administrator
* Date: 2018/12/28
* Time: 11:36
*/
namespace thinking\socialite\contract;
interface Provider
{
public function user();
}

View File

@ -1,24 +0,0 @@
<?php
/**
* Created by PhpStorm.
* User: Administrator
* Date: 2018/12/29
* Time: 10:28
*/
namespace thinking\socialite\facade;
use think\Facade;
class Socialite extends Facade
{
/**
* @method static \thinking\socialite\Socialite driver($type) get provider
*
* @time at 2018年12月29日
* @return string
*/
public static function getFacadeClass()
{
return \thinking\socialite\Socialite::class;
}
}

View File

@ -1,170 +0,0 @@
<?php
/**
* Created by PhpStorm.
* User: Administrator
* Date: 2018/12/28
* Time: 11:50
*/
namespace thinking\socialite\provider;
use GuzzleHttp\Client;
use think\exception\HttpException;
use think\exception\HttpResponseException;
use think\facade\Session;
use GuzzleHttp\ClientInterface;
class AbstractProvider
{
// 应用ID
protected $appId;
// 应用秘钥
protected $appSecret;
// 回调地址
protected $redirectUrl;
// scope
protected $scope;
// http 客户端
protected $httpClient = null;
// request
protected $request;
protected $clientIdKey = 'client_id';
public function __construct($appId = '', $appSecret='', $redirectUrl='', $scope = '')
{
$this->appId = $appId;
$this->appSecret = $appSecret;
$this->redirectUrl = $redirectUrl;
$this->scope = $scope;
$this->request = app('request');
}
protected function getHttpClient()
{
if (is_null($this->httpClient)) {
$this->httpClient = new Client();
}
return $this->httpClient;
}
/**
* oauth login
*
* @time at 2018年12月29日
* @return void
*/
public function oauth()
{
if (!$this->request->get('code')) {
throw new HttpResponseException(redirect($this->authorizeUrl . '?' . http_build_query($this->createOauthParams())));
}
}
/**
* create oauth params
*
* @time at 2018年12月29日
* @return array
*/
protected function createOauthParams()
{
return [
'response_type' => 'code',
$this->clientIdKey => $this->appId,
'redirect_uri' => $this->redirectUrl,
'scope' => $this->getScope(),
'state' => $this->state(),
];
}
/**
* set scope
*
* @time at 2018年12月29日
* @param $scope
* @return $this
*/
public function setScope($scope)
{
$this->scope = $scope;
return $this;
}
/**
* get scope
*
* @time at 2018年12月29日
* @return string
*/
protected function getScope()
{
return is_array($this->scope) ? trim(implode($this->scope), ',') : $this->scope;
}
/**
* get state
*
* @time at 2018年12月29日
* @return mixed
*/
protected function getState()
{
$state = $this->request->session('state');
$this->request->session('state', null);
return $state;
}
/**
* check state
*
* @time at 2018年12月29日
* @return void
*/
protected function checkState()
{
if ($this->request->param('state') != $this->getState()) {
throw new HttpException(401, 'Authorized login State verification failed, Please check it');
}
}
/**
* generate state
*
* @time at 2018年12月29日
* @return string
*/
protected function state()
{
$state = md5(rand(1,100000));
Session::set('state', $state);
return $state;
}
/**
* get token params
*
* @time at 2018年12月29日
* @return array
*/
protected function getTokenParams()
{
$this->checkState();
return [
'code' => $this->request->get('code'),
'client_secret' => $this->appSecret,
$this->clientIdKey => $this->appId,
'redirect_uri' => $this->redirectUrl,
];
}
protected function getPostKey()
{
return (version_compare(ClientInterface::VERSION, '6') === 1) ? 'form_params' : 'body';
}
}

View File

@ -1,68 +0,0 @@
<?php
/**
* Created by PhpStorm.
* User: Administrator
* Date: 2018/12/28
* Time: 11:18
*/
namespace thinking\socialite\provider;
use think\exception\HttpException;
use thinking\socialite\User;
class GithubProvider extends AbstractProvider
{
protected $authorizeUrl = 'https://github.com/login/oauth/authorize';
protected $accessTokenUrl = 'https://github.com/login/oauth/access_token';
protected $userUrl = 'https://api.github.com/user';
/**
* 获取 Access Token
*
* @time at 2018年12月28日
* @return mixed
*/
protected function getAccessToken()
{
$response = $this->getHttpClient()->post($this->accessTokenUrl, [
'verify' => false,
'headers' => ['Accept' => 'application/json'],
$this->getPostKey() => array_merge($this->getTokenParams())
]);
$token = json_decode($response->getBody()->getContents(), true);
if (!isset($token['access_token'])) {
throw new HttpException(401, 'Access Token Missing, Please ReLogin');
}
return $token['access_token'];
}
/**
* 获取用户信息
*
* @time at 2018年12月28日
* @return mixed
*/
public function user()
{
$response = $this->getHttpClient()->get($this->userUrl,[
'verify' => false,
'headers' => ['Authorization' => sprintf('token %s', $this->getAccessToken())]
]);
$user = json_decode($response->getBody(), true);
return (new User)->setUser($user)->map([
'id' => $user['id'],
'nickname' => $user['login'],
'name' => $user['name'],
'email' => $user['email'],
'avatar' => $user['avatar_url'],
]);
}
}

View File

@ -1,100 +0,0 @@
<?php
/**
* Created by PhpStorm.
* User: Administrator
* Date: 2018/12/28
* Time: 11:18
*/
namespace thinking\socialite\provider;
use think\exception\HttpException;
use thinking\socialite\contract\Provider;
use thinking\socialite\User;
class QqProvider extends AbstractProvider implements Provider
{
protected $authorizeUrl = 'https://graph.qq.com/oauth2.0/authorize';
protected $accessTokenUrl = 'https://graph.qq.com/oauth2.0/token';
protected $openIdUrl = 'https://graph.qq.com/oauth2.0/me';
protected $userUrl = 'https://graph.qq.com/user/get_user_info';
/**
* 获取 Access Token
*
* @time at 2018年12月28日
* @return mixed
*/
protected function getAccessToken()
{
$response = $this->getHttpClient()->get($this->accessTokenUrl, [
'verify' => false,
'query' => array_merge($this->getTokenParams(), ['grant_type' => 'authorization_code'])
]);
parse_str($response->getBody()->getContents(), $token);
if (!isset($token['access_token'])) {
throw new HttpException(401, 'Access Token Missing, Please ReLogin');
}
return $token['access_token'];
}
/**
* 获取 Open ID
*
* @time at 2018年12月28日
* @return array
*/
protected function getOpenId()
{
$accessToken = $this->getAccessToken();
$response = $this->getHttpClient()->get($this->openIdUrl, [
'verify' => false,
'query' => ['access_token' => $accessToken]
]);
$openidStr = (string)$response->getBody()->getContents();
$openIdArr = json_decode(substr($openidStr,strpos($openidStr,'(')+1,-3),true);
return array_merge($openIdArr, ['access_token' => $accessToken]);
}
/**
* 获取用户信息
*
* @time at 2018年12月28日
* @return mixed
*/
public function user()
{
$getUserParams = $this->getOpenId();
unset($getUserParams['app_id']);
$getUserParams['oauth_consumer_key'] = $this->appId;
$response = $this->getHttpClient()->get($this->userUrl, [
'verify' => false,
'headers' => ['Accept' => 'application/json'],
'query' => $getUserParams,
]);
$user = json_decode($response->getBody()->getContents(), true);
$user['open_id'] = $getUserParams['openid'];
return (new User)->setUser($user)->map([
'id' => $getUserParams['openid'],
'nickname' => $user['nickname'],
'avatar' => $user['figureurl_2'],
]);
}
}

View File

@ -1,87 +0,0 @@
<?php
/**
* Created by PhpStorm.
* User: Administrator
* Date: 2018/12/28
* Time: 11:18
*/
namespace thinking\socialite\provider;
use think\exception\HttpException;
use thinking\socialite\User;
class WeiBoProvider extends AbstractProvider
{
protected $authorizeUrl = 'https://api.weibo.com/oauth2/authorize';
protected $accessTokenUrl = 'https://api.weibo.com/oauth2/access_token';
protected $tokenInfoUrl = 'https://api.weibo.com/oauth2/get_token_info';
protected $userUrl = 'https://api.weibo.com/2/users/show.json';
/**
* 获取 Access Token
*
* @time at 2018年12月28日
* @return mixed
*/
protected function getAccessToken()
{
$response = $this->getHttpClient()->post($this->accessTokenUrl, [
'verify' => false,
$this->getPostKey() => array_merge($this->getTokenParams(), ['grant_type' => 'authorization_code'])
]);
$token = json_decode($response->getBody()->getContents(), true);
if (!isset($token['access_token'])) {
throw new HttpException(401, 'Access Token Missing, Please ReLogin');
}
return $token['access_token'];
}
/**
* 获取 Open ID
*
* @time at 2018年12月28日
* @return array
*/
protected function getTokenInfo()
{
$accessToken = $this->getAccessToken();
$response = $this->getHttpClient()->post($this->tokenInfoUrl, [
'verify' => false,
$this->getPostKey() => ['access_token' => $accessToken]
]);
$tokenInfo = json_decode($response->getBody()->getContents(), true);
return ['access_token' => $accessToken, 'uid' => $tokenInfo['uid']];
}
/**
* 获取用户信息
*
* @time at 2018年12月28日
* @return mixed
*/
public function user()
{
$response = $this->getHttpClient()->get($this->userUrl,[
'verify' => false,
'query' => $this->getTokenInfo(),
]);
$user = json_decode($response->getBody(), true);
return (new User)->setUser($user)->map([
'id' => $user['idstr'],
'nickname' => $user['name'],
'avatar' => $user['profile_image_url'],
]);
}
}

View File

@ -1,101 +0,0 @@
<?php
/**
* Created by PhpStorm.
* User: Administrator
* Date: 2018/12/28
* Time: 11:18
*/
namespace thinking\socialite\provider;
use think\exception\HttpException;
use thinking\socialite\contract\Provider;
use thinking\socialite\User;
class WxProvider extends AbstractProvider implements Provider
{
protected $authorizeUrl = 'https://open.weixin.qq.com/connect/qrconnect';
protected $accessTokenUrl = 'https://api.weixin.qq.com/sns/oauth2/access_token';
protected $openIdUrl = 'https://graph.qq.com/oauth2.0/me';
protected $userUrl = 'https://api.weixin.qq.com/sns/userinfo';
protected $clientIdKey = 'appid';
/**
* 获取 Access Token
*
* @time at 2018年12月28日
* @return mixed
*/
protected function getAccessToken()
{
$response = $this->getHttpClient()->get($this->accessTokenUrl, [
'verify' => false,
'query' => array_merge($this->getTokenParams(), ['grant_type' => 'authorization_code'])
]);
parse_str($response->getBody()->getContents(), $token);
if (!isset($token['access_token'])) {
throw new HttpException(401, 'Access Token Missing, Please ReLogin');
}
return $token['access_token'];
}
/**
* 获取 Open ID
*
* @time at 2018年12月28日
* @return array
*/
protected function getOpenId()
{
$accessToken = $this->getAccessToken();
$response = $this->getHttpClient()->get($this->openIdUrl, [
'verify' => false,
'query' => ['access_token' => $accessToken]
]);
$openidStr = (string)$response->getBody()->getContents();
$openIdArr = json_decode(substr($openidStr,strpos($openidStr,'(')+1,-3),true);
return array_merge($openIdArr, ['access_token' => $accessToken]);
}
/**
* 获取用户信息
*
* @time at 2018年12月28日
* @return mixed
*/
public function user()
{
$getUserParams = $this->getOpenId();
unset($getUserParams['app_id']);
$getUserParams['oauth_consumer_key'] = $this->appId;
$response = $this->getHttpClient()->get($this->userUrl, [
'verify' => false,
'headers' => ['Accept' => 'application/json'],
'query' => $getUserParams,
]);
$user = json_decode($response->getBody()->getContents(), true);
$user['open_id'] = $getUserParams['openid'];
return (new User)->setUser($user)->map([
'id' => $getUserParams['openid'],
'nickname' => $user['nickname'],
'avatar' => $user['figureurl_2'],
]);
}
}

View File

@ -1,8 +0,0 @@
<IfModule mod_rewrite.c>
Options +FollowSymlinks -Multiviews
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php/$1 [QSA,PT,L]
</IfModule>

View File

@ -1,7 +0,0 @@
/.idea
/.vscode
/vendor
*.log
thinkphp
.env
.DS_Store

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -1,358 +0,0 @@
#container {
color: #838383;
font-size: 12px;
}
#uploader .queueList {
margin: 20px;
border: 3px dashed #e6e6e6;
}
#uploader .queueList.filled {
padding: 17px;
margin: 0;
border: 3px dashed transparent;
}
#uploader .queueList.webuploader-dnd-over {
border: 3px dashed #999999;
}
#uploader p {margin: 0;}
.element-invisible {
position: absolute !important;
clip: rect(1px 1px 1px 1px); /* IE6, IE7 */
clip: rect(1px,1px,1px,1px);
}
#uploader .placeholder {
min-height: 350px;
padding-top: 178px;
text-align: center;
background: url(../../../img/webuploader.png) center 93px no-repeat;
color: #cccccc;
font-size: 18px;
position: relative;
}
#uploader .placeholder .webuploader-pick {
font-size: 18px;
background: #00b7ee;
border-radius: 3px;
line-height: 44px;
padding: 0 30px;
*width: 120px;
color: #fff;
display: inline-block;
margin: 0 auto 20px auto;
cursor: pointer;
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);
}
#uploader .placeholder .webuploader-pick-hover {
background: #00a2d4;
}
#uploader .placeholder .flashTip {
color: #666666;
font-size: 12px;
position: absolute;
width: 100%;
text-align: center;
bottom: 20px;
}
#uploader .placeholder .flashTip a {
color: #0785d1;
text-decoration: none;
}
#uploader .placeholder .flashTip a:hover {
text-decoration: underline;
}
#uploader .filelist {
list-style: none;
margin: 0;
padding: 0;
}
#uploader .filelist:after {
content: '';
display: block;
width: 0;
height: 0;
overflow: hidden;
clear: both;
}
#uploader .filelist li {
width: 110px;
height: 110px;
background: url(../../img/bg.png) no-repeat;
text-align: center;
margin: 0 8px 20px 0;
position: relative;
display: inline;
float: left;
overflow: hidden;
font-size: 12px;
}
#uploader .filelist li p.log {
position: relative;
top: -45px;
}
#uploader .filelist li p.title {
position: absolute;
top: 0;
left: 0;
width: 100%;
overflow: hidden;
white-space: nowrap;
text-overflow : ellipsis;
top: 5px;
text-indent: 5px;
text-align: left;
}
#uploader .filelist li p.progress {
position: absolute;
width: 100%;
bottom: 0;
left: 0;
height: 8px;
overflow: hidden;
z-index: 50;
margin: 0;
border-radius: 0;
background: none;
-webkit-box-shadow: 0 0 0;
}
#uploader .filelist li p.progress span {
display: none;
overflow: hidden;
width: 0;
height: 100%;
background: #1483d8 url(../../img/progress.png) repeat-x;
-webit-transition: width 200ms linear;
-moz-transition: width 200ms linear;
-o-transition: width 200ms linear;
-ms-transition: width 200ms linear;
transition: width 200ms linear;
-webkit-animation: progressmove 2s linear infinite;
-moz-animation: progressmove 2s linear infinite;
-o-animation: progressmove 2s linear infinite;
-ms-animation: progressmove 2s linear infinite;
animation: progressmove 2s linear infinite;
-webkit-transform: translateZ(0);
}
@-webkit-keyframes progressmove {
0% {
background-position: 0 0;
}
100% {
background-position: 17px 0;
}
}
@-moz-keyframes progressmove {
0% {
background-position: 0 0;
}
100% {
background-position: 17px 0;
}
}
@keyframes progressmove {
0% {
background-position: 0 0;
}
100% {
background-position: 17px 0;
}
}
#uploader .filelist li p.imgWrap {
position: relative;
z-index: 2;
line-height: 110px;
vertical-align: middle;
overflow: hidden;
width: 110px;
height: 110px;
-webkit-transform-origin: 50% 50%;
-moz-transform-origin: 50% 50%;
-o-transform-origin: 50% 50%;
-ms-transform-origin: 50% 50%;
transform-origin: 50% 50%;
-webit-transition: 200ms ease-out;
-moz-transition: 200ms ease-out;
-o-transition: 200ms ease-out;
-ms-transition: 200ms ease-out;
transition: 200ms ease-out;
}
#uploader .filelist li img {
width: 100%;
}
#uploader .filelist li p.error {
background: #f43838;
color: #fff;
position: absolute;
bottom: 0;
left: 0;
height: 28px;
line-height: 28px;
width: 100%;
z-index: 100;
}
#uploader .filelist li .success {
display: block;
position: absolute;
left: 0;
bottom: 0;
height: 40px;
width: 100%;
z-index: 200;
background: url(../../img/success.png) no-repeat right bottom;
}
#uploader .filelist div.file-panel {
position: absolute;
height: 0;
filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0,startColorstr='#80000000', endColorstr='#80000000')\0;
background: rgba( 0, 0, 0, 0.5 );
width: 100%;
top: 0;
left: 0;
overflow: hidden;
z-index: 300;
}
#uploader .filelist div.file-panel span {
width: 24px;
height: 24px;
display: inline;
float: right;
text-indent: -9999px;
overflow: hidden;
background: url(../../img/icons.png) no-repeat;
margin: 5px 1px 1px;
cursor: pointer;
}
#uploader .filelist div.file-panel span.rotateLeft {
background-position: 0 -24px;
}
#uploader .filelist div.file-panel span.rotateLeft:hover {
background-position: 0 0;
}
#uploader .filelist div.file-panel span.rotateRight {
background-position: -24px -24px;
}
#uploader .filelist div.file-panel span.rotateRight:hover {
background-position: -24px 0;
}
#uploader .filelist div.file-panel span.cancel {
background-position: -48px -24px;
}
#uploader .filelist div.file-panel span.cancel:hover {
background-position: -48px 0;
}
#uploader .statusBar {
height: 63px;
border-top: 1px solid #dadada;
padding: 0 20px;
line-height: 63px;
vertical-align: middle;
position: relative;
}
#uploader .statusBar .progress {
border: 1px solid #1483d8;
width: 198px;
background: #fff;
height: 18px;
position: relative;
display: inline-block;
text-align: center;
line-height: 20px;
color: #6dbfff;
position: relative;
margin: 0 10px 0 0;
}
#uploader .statusBar .progress span.percentage {
width: 0;
height: 100%;
left: 0;
top: 0;
background: #1483d8;
position: absolute;
}
#uploader .statusBar .progress span.text {
position: relative;
z-index: 10;
}
#uploader .statusBar .info {
display: inline-block;
font-size: 14px;
color: #666666;
}
#uploader .statusBar .btns {
position: absolute;
top: 10px;
right: 20px;
line-height: 40px;
}
#filePicker2 {
display: inline-block;
float: left;
}
#uploader .statusBar .btns .webuploader-pick,
#uploader .statusBar .btns .uploadBtn,
#uploader .statusBar .btns .uploadBtn.state-uploading,
#uploader .statusBar .btns .uploadBtn.state-paused {
background: #ffffff;
border: 1px solid #cfcfcf;
color: #565656;
padding: 0 18px;
display: inline-block;
border-radius: 3px;
margin-left: 10px;
cursor: pointer;
font-size: 14px;
float: left;
}
#uploader .statusBar .btns .webuploader-pick-hover,
#uploader .statusBar .btns .uploadBtn:hover,
#uploader .statusBar .btns .uploadBtn.state-uploading:hover,
#uploader .statusBar .btns .uploadBtn.state-paused:hover {
background: #f0f0f0;
}
#uploader .statusBar .btns .uploadBtn {
background: #00b7ee;
color: #fff;
border-color: transparent;
}
#uploader .statusBar .btns .uploadBtn:hover {
background: #00a2d4;
}
#uploader .statusBar .btns .uploadBtn.disabled {
pointer-events: none;
opacity: 0.6;
}

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More