@ -0,0 +1,25 @@
|
|||||||
|
APP_DEBUG = true
|
||||||
|
|
||||||
|
[APP]
|
||||||
|
DEFAULT_TIMEZONE = Asia/Taipei
|
||||||
|
|
||||||
|
[DATABASE]
|
||||||
|
TYPE = mysql
|
||||||
|
HOSTNAME = 127.0.0.1
|
||||||
|
DATABASE = sso_h888_fun
|
||||||
|
USERNAME = sso_h888_fun
|
||||||
|
PASSWORD = EFyGDeDdnidrrsL3
|
||||||
|
HOSTPORT = 3306
|
||||||
|
CHARSET = utf8mb4
|
||||||
|
DEBUG = true
|
||||||
|
PREFIX = asc_
|
||||||
|
|
||||||
|
[LANG]
|
||||||
|
default_lang = zh-tw
|
||||||
|
|
||||||
|
[JWT]
|
||||||
|
SECRET=6dffd0dcd8d732d6b5e5e6c7bd7d1eff
|
||||||
|
refresh_ttl = 360
|
||||||
|
|
||||||
|
[ASC]
|
||||||
|
SMS_DISABLE = false
|
||||||
@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"name": "My Server",
|
||||||
|
"host": "stage",
|
||||||
|
"protocol": "sftp",
|
||||||
|
"port": 22,
|
||||||
|
"username": "root",
|
||||||
|
"password": "%1WoCvN7FD.oUYhf",
|
||||||
|
"remotePath": "/www/wwwroot/sso.h888.fun",
|
||||||
|
"uploadOnSave": true,
|
||||||
|
"useTempFile": false,
|
||||||
|
"openSsh": false
|
||||||
|
}
|
||||||
@ -0,0 +1 @@
|
|||||||
|
deny from all
|
||||||
@ -0,0 +1,22 @@
|
|||||||
|
<?php
|
||||||
|
declare (strict_types = 1);
|
||||||
|
|
||||||
|
namespace app;
|
||||||
|
|
||||||
|
use think\Service;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 应用服务类
|
||||||
|
*/
|
||||||
|
class AppService extends Service
|
||||||
|
{
|
||||||
|
public function register()
|
||||||
|
{
|
||||||
|
// 服务注册
|
||||||
|
}
|
||||||
|
|
||||||
|
public function boot()
|
||||||
|
{
|
||||||
|
// 服务启动
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,94 @@
|
|||||||
|
<?php
|
||||||
|
declare (strict_types = 1);
|
||||||
|
|
||||||
|
namespace app;
|
||||||
|
|
||||||
|
use think\App;
|
||||||
|
use think\exception\ValidateException;
|
||||||
|
use think\Validate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 控制器基础类
|
||||||
|
*/
|
||||||
|
abstract class BaseController
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Request实例
|
||||||
|
* @var \think\Request
|
||||||
|
*/
|
||||||
|
protected $request;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 应用实例
|
||||||
|
* @var \think\App
|
||||||
|
*/
|
||||||
|
protected $app;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否批量验证
|
||||||
|
* @var bool
|
||||||
|
*/
|
||||||
|
protected $batchValidate = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 控制器中间件
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $middleware = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构造方法
|
||||||
|
* @access public
|
||||||
|
* @param App $app 应用对象
|
||||||
|
*/
|
||||||
|
public function __construct(App $app)
|
||||||
|
{
|
||||||
|
$this->app = $app;
|
||||||
|
$this->request = $this->app->request;
|
||||||
|
|
||||||
|
// 控制器初始化
|
||||||
|
$this->initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 初始化
|
||||||
|
protected function initialize()
|
||||||
|
{}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 验证数据
|
||||||
|
* @access protected
|
||||||
|
* @param array $data 数据
|
||||||
|
* @param string|array $validate 验证器名或者验证规则数组
|
||||||
|
* @param array $message 提示信息
|
||||||
|
* @param bool $batch 是否批量验证
|
||||||
|
* @return array|string|true
|
||||||
|
* @throws ValidateException
|
||||||
|
*/
|
||||||
|
protected function validate(array $data, $validate, array $message = [], bool $batch = false)
|
||||||
|
{
|
||||||
|
if (is_array($validate)) {
|
||||||
|
$v = new Validate();
|
||||||
|
$v->rule($validate);
|
||||||
|
} else {
|
||||||
|
if (strpos($validate, '.')) {
|
||||||
|
// 支持场景
|
||||||
|
[$validate, $scene] = explode('.', $validate);
|
||||||
|
}
|
||||||
|
$class = false !== strpos($validate, '\\') ? $validate : $this->app->parseClass('validate', $validate);
|
||||||
|
$v = new $class();
|
||||||
|
if (!empty($scene)) {
|
||||||
|
$v->scene($scene);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$v->message($message);
|
||||||
|
|
||||||
|
// 是否批量验证
|
||||||
|
if ($batch || $this->batchValidate) {
|
||||||
|
$v->batch(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $v->failException(true)->check($data);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,58 @@
|
|||||||
|
<?php
|
||||||
|
namespace app;
|
||||||
|
|
||||||
|
use think\db\exception\DataNotFoundException;
|
||||||
|
use think\db\exception\ModelNotFoundException;
|
||||||
|
use think\exception\Handle;
|
||||||
|
use think\exception\HttpException;
|
||||||
|
use think\exception\HttpResponseException;
|
||||||
|
use think\exception\ValidateException;
|
||||||
|
use think\Response;
|
||||||
|
use Throwable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 应用异常处理类
|
||||||
|
*/
|
||||||
|
class ExceptionHandle extends Handle
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 不需要记录信息(日志)的异常类列表
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $ignoreReport = [
|
||||||
|
HttpException::class,
|
||||||
|
HttpResponseException::class,
|
||||||
|
ModelNotFoundException::class,
|
||||||
|
DataNotFoundException::class,
|
||||||
|
ValidateException::class,
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 记录异常信息(包括日志或者其它方式记录)
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param Throwable $exception
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function report(Throwable $exception): void
|
||||||
|
{
|
||||||
|
// 使用内置的方式记录异常日志
|
||||||
|
parent::report($exception);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render an exception into an HTTP response.
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param \think\Request $request
|
||||||
|
* @param Throwable $e
|
||||||
|
* @return Response
|
||||||
|
*/
|
||||||
|
public function render($request, Throwable $e): Response
|
||||||
|
{
|
||||||
|
// 添加自定义异常处理机制
|
||||||
|
|
||||||
|
// 其他错误交给系统处理
|
||||||
|
return parent::render($request, $e);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
<?php
|
||||||
|
namespace app;
|
||||||
|
|
||||||
|
// 应用请求对象类
|
||||||
|
class Request extends \think\Request
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,167 @@
|
|||||||
|
<?php
|
||||||
|
namespace app\adminapi\controller\v1;
|
||||||
|
|
||||||
|
use app\adminapi\ApiController;
|
||||||
|
use think\facade\Db;
|
||||||
|
|
||||||
|
class Admin extends ApiController
|
||||||
|
{
|
||||||
|
public function getAdminUsers()
|
||||||
|
{
|
||||||
|
if(!input('search')){
|
||||||
|
$result=Db::name('admin')
|
||||||
|
->page(input('current'),input('size'))
|
||||||
|
->select();
|
||||||
|
|
||||||
|
$total=Db::name('admin')
|
||||||
|
->count();
|
||||||
|
}else{
|
||||||
|
$result=Db::name('admin')
|
||||||
|
->where('username','like','%'.input('search').'%')
|
||||||
|
->page(input('current'),input('size'))
|
||||||
|
->select();
|
||||||
|
|
||||||
|
$total=Db::name('admin')
|
||||||
|
->where('username','like','%'.input('search').'%')
|
||||||
|
->count();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!$result){
|
||||||
|
$result=[];
|
||||||
|
}
|
||||||
|
|
||||||
|
$rtn=[
|
||||||
|
'total' => $total,
|
||||||
|
'data' => $result
|
||||||
|
];
|
||||||
|
|
||||||
|
return $this->Success($rtn);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getUser(){
|
||||||
|
|
||||||
|
$id=input('id');
|
||||||
|
|
||||||
|
$result=Db::name('admin')
|
||||||
|
->field('id,username,email,status,role_id as role')
|
||||||
|
->where('id',$id)
|
||||||
|
->find();
|
||||||
|
|
||||||
|
if(!$result){
|
||||||
|
$result=[];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->success($result);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function addUser(){
|
||||||
|
|
||||||
|
$req=input();
|
||||||
|
|
||||||
|
$password_hash = password_hash($req['password'], PASSWORD_DEFAULT);
|
||||||
|
|
||||||
|
$data=[
|
||||||
|
'username' => $req['username'],
|
||||||
|
'password' => $password_hash,
|
||||||
|
'email' => $req['email'],
|
||||||
|
'action_list' => '',
|
||||||
|
'status' => $req['status'],
|
||||||
|
];
|
||||||
|
|
||||||
|
$result=Db::name('admin')
|
||||||
|
->insert($data);
|
||||||
|
|
||||||
|
if(!$result){
|
||||||
|
$result=[];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->success($result);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function updateUser(){
|
||||||
|
|
||||||
|
$req=input();
|
||||||
|
$data=[
|
||||||
|
'username' => $req['username'],
|
||||||
|
'email' => $req['email'],
|
||||||
|
'role_id' => $req['role'],
|
||||||
|
'action_list' => '',
|
||||||
|
'status' => $req['status'],
|
||||||
|
];
|
||||||
|
|
||||||
|
if(strlen($req['password'])>0){
|
||||||
|
$data['password']=$req['password'];
|
||||||
|
}
|
||||||
|
|
||||||
|
$result=Db::name('admin')
|
||||||
|
->where('id',$req['id'])
|
||||||
|
->update($data);
|
||||||
|
|
||||||
|
if(!$result){
|
||||||
|
$result=[];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->success($result);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function deleteUser(){
|
||||||
|
$id=input('id');
|
||||||
|
|
||||||
|
$result=Db::name('admin')
|
||||||
|
->where('id',$id)
|
||||||
|
->delete();
|
||||||
|
|
||||||
|
return $this->success($result);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function updateStatus(){
|
||||||
|
$id=input('id');
|
||||||
|
$status=input('status');
|
||||||
|
|
||||||
|
$result=Db::name('admin')
|
||||||
|
->where('id',$id)
|
||||||
|
->update(['status'=>$status]);
|
||||||
|
|
||||||
|
if(!$result){
|
||||||
|
$result=[];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->success($result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function getAdminLogs()
|
||||||
|
{
|
||||||
|
if(!input('search')){
|
||||||
|
$result=Db::name('admin_log')
|
||||||
|
->page(input('current'),input('size'))
|
||||||
|
->order('id','desc')
|
||||||
|
->select();
|
||||||
|
|
||||||
|
$total=Db::name('admin_log')
|
||||||
|
->count();
|
||||||
|
}else{
|
||||||
|
$result=Db::name('admin_log')
|
||||||
|
->where('admin_name','like','%'.input('search').'%')
|
||||||
|
->page(input('current'),input('size'))
|
||||||
|
->order('id','desc')
|
||||||
|
->select();
|
||||||
|
|
||||||
|
$total=Db::name('admin_log')
|
||||||
|
->where('admin_name','like','%'.input('search').'%')
|
||||||
|
->count();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!$result){
|
||||||
|
$result=[];
|
||||||
|
}
|
||||||
|
|
||||||
|
$rtn=[
|
||||||
|
'total' => $total,
|
||||||
|
'data' => $result
|
||||||
|
];
|
||||||
|
|
||||||
|
return $this->Success($rtn);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,153 @@
|
|||||||
|
<?php
|
||||||
|
namespace app\adminapi\controller\v1;
|
||||||
|
|
||||||
|
use app\adminapi\ApiController;
|
||||||
|
use think\facade\Db;
|
||||||
|
use think\facade\Session;
|
||||||
|
use thans\jwt\facade\JWTAuth;
|
||||||
|
use think\facade\Log;
|
||||||
|
|
||||||
|
class Auth extends ApiController
|
||||||
|
{
|
||||||
|
public function Login()
|
||||||
|
{
|
||||||
|
$username=input('username');
|
||||||
|
$password=input('password');
|
||||||
|
|
||||||
|
// $captcha=input('captcha');
|
||||||
|
|
||||||
|
// Log::write(json_encode(Session::all()));
|
||||||
|
|
||||||
|
// if(!captcha_check($captcha)){
|
||||||
|
// return $this->Error('驗證碼錯誤','請求失敗',301);
|
||||||
|
// }
|
||||||
|
$result=Db::name('admin')
|
||||||
|
->where('username',$username)
|
||||||
|
->find();
|
||||||
|
|
||||||
|
if(!$result){
|
||||||
|
return $this->Error('帳號或密碼錯誤','請求失敗',302);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!password_verify($password , $result['password'])){
|
||||||
|
return $this->Error('帳號或密碼錯誤','請求失敗',303);
|
||||||
|
}
|
||||||
|
|
||||||
|
$token = JWTAuth::builder(['uid' => $result['id']]);
|
||||||
|
|
||||||
|
$result=[
|
||||||
|
'user'=>[
|
||||||
|
'uid'=>$result['id'],
|
||||||
|
"name" => $result['username'],
|
||||||
|
"avatar" => "https://gw.alipayobjects.com/zos/rmsportal/ubnKSIfAJTxIgXOKlciN.png",
|
||||||
|
"address" => "固原市",
|
||||||
|
"position" => [
|
||||||
|
"CN" => "產品分析師 | 螞蟻金服-計算服務事業群-IOS平臺部",
|
||||||
|
"TW" => "產品分析師 | 螞蟻金服-計算服務事業群-IOS平臺部",
|
||||||
|
"US" => "Product analyst | Ant Financial - Computing services business group - IOS platform division"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
'permissions'=>[
|
||||||
|
[
|
||||||
|
'id'=>'queryForm',
|
||||||
|
'operation'=>['add','edit','delete']
|
||||||
|
]
|
||||||
|
],
|
||||||
|
'roles'=>[
|
||||||
|
[
|
||||||
|
'id'=>'admin',
|
||||||
|
'operation'=>['add','edit','delete']
|
||||||
|
]
|
||||||
|
],
|
||||||
|
'token'=>$token,
|
||||||
|
'expireAt'=>time()+30*60*1000
|
||||||
|
];
|
||||||
|
return $this->Success($result);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function check(){
|
||||||
|
print_r(JWTAuth::auth());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function captcha($id=''){
|
||||||
|
return captcha($id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function checkC($value){
|
||||||
|
print_r(Session::all());
|
||||||
|
|
||||||
|
if(!captcha_check($value)){
|
||||||
|
//驗證失敗
|
||||||
|
echo 'failure';
|
||||||
|
};
|
||||||
|
echo 'Success';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getRoute(){
|
||||||
|
$routes=[
|
||||||
|
[
|
||||||
|
"router" => "root",
|
||||||
|
"children" => [
|
||||||
|
"DashBoard",
|
||||||
|
[
|
||||||
|
"router" => "system",
|
||||||
|
"children" => [
|
||||||
|
[
|
||||||
|
"router" => "systemConfig",
|
||||||
|
"name" => "站台設置",
|
||||||
|
"authority" => [
|
||||||
|
"permission" => "demo",
|
||||||
|
"role" => "admin"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"router" => "admin",
|
||||||
|
"children" => [
|
||||||
|
"adminUser",
|
||||||
|
"adminLog",
|
||||||
|
"adminRole",
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"router" => "goods",
|
||||||
|
"children" => [
|
||||||
|
"goodsList",
|
||||||
|
"goodsCategory",
|
||||||
|
"goodsType",
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"router" => "order",
|
||||||
|
"children" => [
|
||||||
|
"orderList",
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"router" => "room",
|
||||||
|
"children" => [
|
||||||
|
"roomList",
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"router" => "user",
|
||||||
|
"children" => [
|
||||||
|
"userList"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"router" => "setting",
|
||||||
|
"children" => [
|
||||||
|
"settingBase",
|
||||||
|
"settingConfig"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
]
|
||||||
|
]
|
||||||
|
];
|
||||||
|
|
||||||
|
return $this->Success($routes);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,187 @@
|
|||||||
|
<?php
|
||||||
|
namespace app\adminapi\controller\v1;
|
||||||
|
|
||||||
|
use app\adminapi\ApiController;
|
||||||
|
use think\facade\Db;
|
||||||
|
|
||||||
|
use app\common\lib\Vcard;
|
||||||
|
use app\common\lib\Aes;
|
||||||
|
|
||||||
|
class Card extends ApiController
|
||||||
|
{
|
||||||
|
public function addPrecard(){
|
||||||
|
$req=input();
|
||||||
|
//取得prefix
|
||||||
|
$agent = Db::name('agent')
|
||||||
|
->where('id',$req['agent_id'])
|
||||||
|
->find();
|
||||||
|
|
||||||
|
$aes = new Aes([]);
|
||||||
|
|
||||||
|
for($i=0;$i<input('number');$i++){
|
||||||
|
|
||||||
|
// $user_id=genUniqid($agent['prefix']);
|
||||||
|
// $verify_code = genSerialNo();
|
||||||
|
|
||||||
|
// $params = urlencode($aes->encrypt('user_id='.$user_id.'&verify_code='.$verify_code));
|
||||||
|
// $nfcUrl = genQrCode(getUrl().'/card/?params='.$params,$user_id,'nfc');
|
||||||
|
|
||||||
|
$data[]=[
|
||||||
|
// 'user_id'=>$user_id,
|
||||||
|
'agent_id'=>$req['agent_id'],
|
||||||
|
'try_days'=>7,
|
||||||
|
'verify_code'=>'',
|
||||||
|
'expire_time'=>$req['expire_time'],
|
||||||
|
'status'=>0,
|
||||||
|
];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
try{
|
||||||
|
Db::name('precard')
|
||||||
|
->insertAll($data);
|
||||||
|
}catch(\Exception $e){
|
||||||
|
print_r($e);
|
||||||
|
return $this->error('新增失敗');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->success('新增成功');
|
||||||
|
}
|
||||||
|
|
||||||
|
// 取得預開卡資料
|
||||||
|
public function getPrecard(){
|
||||||
|
$do=Db::name('precard');
|
||||||
|
|
||||||
|
if(!input('search')){
|
||||||
|
$result=$do
|
||||||
|
->page(input('current'),input('size'))
|
||||||
|
->order('id','desc')
|
||||||
|
->select()->toArray();
|
||||||
|
|
||||||
|
$total=$do
|
||||||
|
->count();
|
||||||
|
}else{
|
||||||
|
$result=$do
|
||||||
|
->where('user_id','like','%'.input('search').'%')
|
||||||
|
->page(input('current'),input('size'))
|
||||||
|
->order('id','desc')
|
||||||
|
->select()->toArray();
|
||||||
|
|
||||||
|
$total=$do
|
||||||
|
->where('user_id','like','%'.input('search').'%')
|
||||||
|
->count();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!$result){
|
||||||
|
$result=[];
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach($result as $key => $val){
|
||||||
|
// $aes = new Aes([]);
|
||||||
|
// $nfc_url = 'user_id='.$val['user_id'].'&verify_code='.$val['verify_code'];
|
||||||
|
// $result[$key]['params'] = getUrl().'/card/'.urlencode($aes->encrypt($nfc_url));
|
||||||
|
$result[$key]['agent_name'] = Db::name('agent')->where('id',$val['agent_id'])->value('name');
|
||||||
|
$result[$key]['expire'] = date('Y-m-d',$val['expire_time']);
|
||||||
|
switch($val['status']){
|
||||||
|
case 0:
|
||||||
|
$result[$key]['status_name']='未制卡';
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
$result[$key]['status_name']='已制卡';
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
$result[$key]['status_name']='已開通';
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
$result[$key]['status_name']='已作癈';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
$aes = new Aes([]);
|
||||||
|
$params = urlencode($aes->encrypt('verify_code='.$val['verify_code']));
|
||||||
|
$result[$key]['nfcurl']= getUrl().'/card/?params='.$params;
|
||||||
|
// $nfcUrl = genQrCode('https://'.$_SERVER['HTTP_HOST'].'/card/?params='.$params,$data['user_id'],'nfc');
|
||||||
|
}
|
||||||
|
|
||||||
|
$rtn=[
|
||||||
|
'total' => $total,
|
||||||
|
'data' => $result
|
||||||
|
];
|
||||||
|
|
||||||
|
return $this->Success($rtn);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function deleteCard(){
|
||||||
|
$id=input('id');
|
||||||
|
|
||||||
|
$result=Db::name('precard')
|
||||||
|
->where('id',$id)
|
||||||
|
->delete();
|
||||||
|
|
||||||
|
return $this->success($result);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function updateStatus(){
|
||||||
|
$id=input('id');
|
||||||
|
$status=input('status');
|
||||||
|
|
||||||
|
$result=Db::name('precard')
|
||||||
|
->where('id',$id)
|
||||||
|
->update(['status'=>$status]);
|
||||||
|
|
||||||
|
if(!$result){
|
||||||
|
$result=[];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->success($result);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function updateVerifyCode(){
|
||||||
|
$id=input('id');
|
||||||
|
$verify_code=strtoupper(input('code'));
|
||||||
|
|
||||||
|
$is_user = Db::name('user')
|
||||||
|
->where('uniqid',$verify_code)
|
||||||
|
->count();
|
||||||
|
|
||||||
|
if($is_user){
|
||||||
|
return $this->error('卡片已綁定會員');
|
||||||
|
}
|
||||||
|
|
||||||
|
$is_precard = Db::name('precard')
|
||||||
|
->where('verify_code',$verify_code)
|
||||||
|
->count();
|
||||||
|
|
||||||
|
if($is_precard){
|
||||||
|
return $this->error('已存在預製卡');
|
||||||
|
}
|
||||||
|
|
||||||
|
try{
|
||||||
|
$result=Db::name('precard')
|
||||||
|
->where('id',$id)
|
||||||
|
->update(['verify_code'=>$verify_code,'status'=>1]);
|
||||||
|
|
||||||
|
return $this->success('設定成功');
|
||||||
|
}catch(\Exception $e){
|
||||||
|
return $this->error('系統錯誤');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function downloadQr(){
|
||||||
|
$id=input('id');
|
||||||
|
|
||||||
|
$pc=Db::name('precard')
|
||||||
|
->where('id',$id)
|
||||||
|
->find();
|
||||||
|
|
||||||
|
if(strlen($pc['nfc_qrcode'])>0){
|
||||||
|
$nfc_qrcode = $pc['nfc_qrcode'];
|
||||||
|
}else{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->success($result);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,18 @@
|
|||||||
|
<?php
|
||||||
|
namespace app\adminapi\controller\v1;
|
||||||
|
|
||||||
|
use app\BaseController;
|
||||||
|
|
||||||
|
use app\common\lib\Vcard;
|
||||||
|
|
||||||
|
class Index extends BaseController
|
||||||
|
{
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
return 'Admin Index';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test(){
|
||||||
|
Vcard::genVcf('mc638ac4d74c7e6');
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,87 @@
|
|||||||
|
<?php
|
||||||
|
namespace app\admin\controller\v1;
|
||||||
|
|
||||||
|
use app\api\ApiController;
|
||||||
|
use think\facade\Db;
|
||||||
|
|
||||||
|
class Right extends ApiController
|
||||||
|
{
|
||||||
|
public function getTree()
|
||||||
|
{
|
||||||
|
|
||||||
|
$data=[
|
||||||
|
'title'=>'所有權限',
|
||||||
|
'key'=>'all',
|
||||||
|
'level'=>0,
|
||||||
|
'index'=>0
|
||||||
|
];
|
||||||
|
|
||||||
|
$data=$this->buildTree($data);
|
||||||
|
|
||||||
|
|
||||||
|
if(!$data){
|
||||||
|
$result=[];
|
||||||
|
}
|
||||||
|
|
||||||
|
// $result['children']=$children;
|
||||||
|
|
||||||
|
|
||||||
|
$rtn=[
|
||||||
|
// 'total' => $total,
|
||||||
|
$data
|
||||||
|
];
|
||||||
|
|
||||||
|
return $this->Success($rtn);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static function buildTree($data,$level=0){
|
||||||
|
$level=$level+1;
|
||||||
|
$menu = Db::name('menu')
|
||||||
|
->where('pid',$data['index'])
|
||||||
|
->select();
|
||||||
|
|
||||||
|
if(!$menu){
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
$children=[];
|
||||||
|
|
||||||
|
foreach($menu as $key => $val){
|
||||||
|
$children[$key]['title']=$val['title'];
|
||||||
|
$children[$key]['index']=$val['id'];
|
||||||
|
$children[$key]['level']=$level;
|
||||||
|
$children[$key]['key']=$val['node'];
|
||||||
|
if($level < 2){
|
||||||
|
$children[$key]=self::buildTree($children[$key],$level);
|
||||||
|
}else{
|
||||||
|
$children[$key]=self::appendPermission($children[$key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if($children){
|
||||||
|
$data['children'] = $children;
|
||||||
|
}
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static function appendPermission($data){
|
||||||
|
$perm = Db::name('permission')
|
||||||
|
->where('menu_id',$data['index'])
|
||||||
|
->select();
|
||||||
|
|
||||||
|
if(!$perm){
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
$children=[];
|
||||||
|
|
||||||
|
foreach($perm as $key => $val){
|
||||||
|
$children[$key]['title']=lang($val['code']);
|
||||||
|
$children[$key]['index']=$val['id'];
|
||||||
|
$children[$key]['key']=$val['code'];
|
||||||
|
}
|
||||||
|
if($children){
|
||||||
|
$data['children'] = $children;
|
||||||
|
}
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,86 @@
|
|||||||
|
<?php
|
||||||
|
namespace app\adminapi\controller\v1;
|
||||||
|
|
||||||
|
use app\adminapi\ApiController;
|
||||||
|
use think\facade\Db;
|
||||||
|
|
||||||
|
class Role extends ApiController
|
||||||
|
{
|
||||||
|
public function getRoles()
|
||||||
|
{
|
||||||
|
$result=Db::name('role')
|
||||||
|
->select();
|
||||||
|
|
||||||
|
if(!$result){
|
||||||
|
$result=[];
|
||||||
|
}
|
||||||
|
// foreach($result as $key=>$val){
|
||||||
|
// // $rtn=Db::name('goods')->where('gc_id',$val['id'])->select()->toArray();
|
||||||
|
// // if($rtn){
|
||||||
|
// // $result[$key]['goods']=[];
|
||||||
|
// // }
|
||||||
|
// $result[$key]['goods']=Db::name('goods')->where('gc_id',$val['id'])->select()->toArray();
|
||||||
|
// }
|
||||||
|
return $this->Success($result);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getRoleById(){
|
||||||
|
$id=input('id');
|
||||||
|
|
||||||
|
$result=Db::name('role')
|
||||||
|
->where('id',$id)
|
||||||
|
->find();
|
||||||
|
|
||||||
|
$rtn=[
|
||||||
|
'id' => $result['id'],
|
||||||
|
'name' => $result['name'],
|
||||||
|
'desc' => $result['desc'],
|
||||||
|
'permission'=>json_decode($result['limits'])
|
||||||
|
];
|
||||||
|
|
||||||
|
return $this->Success($rtn);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function addRole(){
|
||||||
|
$req=input();
|
||||||
|
|
||||||
|
$data = [
|
||||||
|
'name'=>$req['name'],
|
||||||
|
'desc'=>$req['desc'],
|
||||||
|
'limits'=>json_encode($req['permission'])
|
||||||
|
];
|
||||||
|
|
||||||
|
$result=Db::name('role')
|
||||||
|
->insert($data);
|
||||||
|
|
||||||
|
return $this->Success($result);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function updateRole(){
|
||||||
|
$req=input();
|
||||||
|
|
||||||
|
$data = [
|
||||||
|
'name' =>$req['name'],
|
||||||
|
'desc' =>$req['desc'],
|
||||||
|
'limits' =>json_encode($req['permission'])
|
||||||
|
];
|
||||||
|
|
||||||
|
$result=Db::name('role')
|
||||||
|
->where('id',$req['id'])
|
||||||
|
->update($data);
|
||||||
|
|
||||||
|
return $this->Success($result);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function deleteRole(){
|
||||||
|
$id=input('id');
|
||||||
|
|
||||||
|
|
||||||
|
$result=Db::name('role')
|
||||||
|
->where('id',$id)
|
||||||
|
->delete();
|
||||||
|
|
||||||
|
return $this->Success($result);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,45 @@
|
|||||||
|
<?php
|
||||||
|
namespace app\adminapi\controller\v1;
|
||||||
|
|
||||||
|
use app\adminapi\ApiController;
|
||||||
|
use think\facade\Db;
|
||||||
|
|
||||||
|
class Site extends ApiController
|
||||||
|
{
|
||||||
|
public function getSiteConfig(){
|
||||||
|
$result = Db::name('site_config')
|
||||||
|
->where('parent_id','<>',0)
|
||||||
|
->select();
|
||||||
|
|
||||||
|
foreach($result as $key => $val){
|
||||||
|
$rtn[$val['code']]=$val['value'];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->success($rtn);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setSiteConfig(){
|
||||||
|
$data = input();
|
||||||
|
unset($data['version']);
|
||||||
|
unset($data['controller']);
|
||||||
|
unset($data['action']);
|
||||||
|
try{
|
||||||
|
foreach($data as $key => $val){
|
||||||
|
Db::name('site_config')
|
||||||
|
->where('code',$key)
|
||||||
|
->update(['value'=>$val]);
|
||||||
|
}
|
||||||
|
}catch(\Exception $e){
|
||||||
|
return $this->error('更新失敗');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->success('更新成功');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getAgents(){
|
||||||
|
$result = Db::name('agent')
|
||||||
|
->select();
|
||||||
|
|
||||||
|
return $this->success($result);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,305 @@
|
|||||||
|
<?php
|
||||||
|
namespace app\adminapi\controller\v1;
|
||||||
|
|
||||||
|
use app\adminapi\ApiController;
|
||||||
|
use think\facade\Db;
|
||||||
|
|
||||||
|
use app\common\lib\Vcard;
|
||||||
|
use app\common\lib\Aes;
|
||||||
|
|
||||||
|
class User extends ApiController
|
||||||
|
{
|
||||||
|
public function getInfo()
|
||||||
|
{
|
||||||
|
$id=$this->request->uid;
|
||||||
|
$result=Db::name('user')
|
||||||
|
->where('id',$id)
|
||||||
|
->find();
|
||||||
|
|
||||||
|
if(!$result){
|
||||||
|
$result=[];
|
||||||
|
}
|
||||||
|
// foreach($result as $key=>$val){
|
||||||
|
// // $rtn=Db::name('goods')->where('gc_id',$val['id'])->select()->toArray();
|
||||||
|
// // if($rtn){
|
||||||
|
// // $result[$key]['goods']=[];
|
||||||
|
// // }
|
||||||
|
// $result[$key]['goods']=Db::name('goods')->where('gc_id',$val['id'])->select()->toArray();
|
||||||
|
// }
|
||||||
|
return $this->Success($result);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 取得會員資料
|
||||||
|
public function getUsers(){
|
||||||
|
$do=Db::name('user');
|
||||||
|
|
||||||
|
if(!input('search')){
|
||||||
|
$result=$do
|
||||||
|
->page(input('current'),input('size'))
|
||||||
|
->order('id','desc')
|
||||||
|
->select()->toArray();
|
||||||
|
|
||||||
|
$total=$do
|
||||||
|
->count();
|
||||||
|
}else{
|
||||||
|
$result=$do
|
||||||
|
->where('user_id','like','%'.input('search').'%')
|
||||||
|
->page(input('current'),input('size'))
|
||||||
|
->order('id','desc')
|
||||||
|
->select()->toArray();
|
||||||
|
|
||||||
|
$total=$do
|
||||||
|
->where('user_id','like','%'.input('search').'%')
|
||||||
|
->count();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!$result){
|
||||||
|
$result=[];
|
||||||
|
}
|
||||||
|
|
||||||
|
$aes = new Aes([]);
|
||||||
|
|
||||||
|
foreach($result as $key => $val){
|
||||||
|
$result[$key]['level_name']= Db::name('user_level')->where('level_id',$val['level'])->where('agent_id',$val['agent_id'])->value('name');
|
||||||
|
|
||||||
|
if($val['parent_id']>0){
|
||||||
|
$result[$key]['parent_name']=Db::name('user')->where('id',$val['parent_id'])->value('real_name');
|
||||||
|
}
|
||||||
|
if($val['overdue_time']>0){
|
||||||
|
$result[$key]['overdue'] = date('Y-m-d',$val['overdue_time']);
|
||||||
|
}else{
|
||||||
|
$result[$key]['overdue'] = '無限期';
|
||||||
|
}
|
||||||
|
if(strlen($val['uniqid'])>0){
|
||||||
|
$uniqid = $val['uniqid'];
|
||||||
|
}else{
|
||||||
|
$uniqid = '00000000';
|
||||||
|
}
|
||||||
|
$params = urlencode($aes->encrypt('user_id='.$val['user_id'].'&verify_code='.$uniqid));
|
||||||
|
$result[$key]['nfcurl']= getUrl().'/card/?params='.$params;
|
||||||
|
}
|
||||||
|
|
||||||
|
$rtn=[
|
||||||
|
'total' => $total,
|
||||||
|
'data' => $result
|
||||||
|
];
|
||||||
|
|
||||||
|
return $this->Success($rtn);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getUser(){
|
||||||
|
|
||||||
|
$id=input('id');
|
||||||
|
|
||||||
|
$result=Db::name('user')
|
||||||
|
->where('id',$id)
|
||||||
|
->find();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if(!$result){
|
||||||
|
$result=[];
|
||||||
|
}
|
||||||
|
|
||||||
|
$levels=Db::name('user_level')
|
||||||
|
->where('agent_id',$result['agent_id'])
|
||||||
|
->select();
|
||||||
|
|
||||||
|
$result['levels']=$levels;
|
||||||
|
|
||||||
|
|
||||||
|
return $this->success($result);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function addUser(){
|
||||||
|
|
||||||
|
$req=input();
|
||||||
|
unset($req['version']);
|
||||||
|
unset($req['controller']);
|
||||||
|
unset($req['action']);
|
||||||
|
$req['user_id'] = 'mc'.uniqid();
|
||||||
|
$req['line_id'] = $req['user_id'];
|
||||||
|
$req['create_time']=date('Y-m-d H:i:s');
|
||||||
|
$req['update_time']=date('Y-m-d H:i:s');
|
||||||
|
|
||||||
|
$result=Db::name('user')
|
||||||
|
->insert($req);
|
||||||
|
|
||||||
|
if(!$result){
|
||||||
|
$result=[];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->success($result);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function updateUser(){
|
||||||
|
|
||||||
|
$req=input();
|
||||||
|
unset($req['version']);
|
||||||
|
unset($req['controller']);
|
||||||
|
unset($req['action']);
|
||||||
|
unset($req['levels']);
|
||||||
|
unset($req['status']);
|
||||||
|
|
||||||
|
$level_option = Db::name('user_level')
|
||||||
|
->where('agent_id',$req['agent_id'])
|
||||||
|
->where('level_id',$req['level'])
|
||||||
|
->find();
|
||||||
|
|
||||||
|
$req['nc_type']=$level_option['nc_type'];
|
||||||
|
$req['nc_func']=$level_option['nc_func'];
|
||||||
|
|
||||||
|
$req['update_time']=date('Y-m-d H:i:s');
|
||||||
|
|
||||||
|
$result=Db::name('user')
|
||||||
|
->where('id',$req['id'])
|
||||||
|
->update($req);
|
||||||
|
|
||||||
|
Vcard::genVcf(input('user_id'));
|
||||||
|
|
||||||
|
if(!$result){
|
||||||
|
$result=[];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->success($result);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function deleteUser(){
|
||||||
|
$id=input('id');
|
||||||
|
|
||||||
|
$result=Db::name('user')
|
||||||
|
->where('id',$id)
|
||||||
|
->delete();
|
||||||
|
|
||||||
|
return $this->success($result);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function updateStatus(){
|
||||||
|
$id=input('id');
|
||||||
|
$status=input('status');
|
||||||
|
|
||||||
|
$result=Db::name('user')
|
||||||
|
->where('id',$id)
|
||||||
|
->update(['status'=>$status]);
|
||||||
|
|
||||||
|
if(!$result){
|
||||||
|
$result=[];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->success($result);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getUserCard(){
|
||||||
|
|
||||||
|
$id=input('id');
|
||||||
|
|
||||||
|
$result=Db::name('user_card')
|
||||||
|
->field('id,type,title,content,nfc_show,sort_id')
|
||||||
|
->where('user_id',$id)
|
||||||
|
->order('sort_id')
|
||||||
|
->select();
|
||||||
|
|
||||||
|
|
||||||
|
if(!$result){
|
||||||
|
$result=[];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->success($result);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function uploadAvatar(){
|
||||||
|
$files = request()->file('avatar');
|
||||||
|
$savename = \think\facade\Filesystem::disk('public')->putFile( input('id'), $files);
|
||||||
|
|
||||||
|
$avatar = getUrl().'/storage/'.$savename;
|
||||||
|
|
||||||
|
return $this->Success($avatar);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function updateUserCard(){
|
||||||
|
$user_id=input('id');
|
||||||
|
$cards=input('cards');
|
||||||
|
|
||||||
|
Db::name('user_card')
|
||||||
|
->where('user_id',$user_id)
|
||||||
|
->delete();
|
||||||
|
|
||||||
|
foreach($cards as $key => $val){
|
||||||
|
$nfc_show = $val['nfc_show']?1:0;
|
||||||
|
|
||||||
|
Db::name('user_card')
|
||||||
|
->insert([
|
||||||
|
'user_id' => $user_id,
|
||||||
|
'type' => $val['type'],
|
||||||
|
'title' => $val['title'],
|
||||||
|
'content' => $val['content'],
|
||||||
|
'nfc_show' => $nfc_show,
|
||||||
|
'sort_id' => $key,
|
||||||
|
'create_time' => time()
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// if(!$result){
|
||||||
|
// $result=[];
|
||||||
|
// }
|
||||||
|
|
||||||
|
return $this->success(['code'=>200]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function updateVerifyCode(){
|
||||||
|
$id=input('id');
|
||||||
|
$uniqid=strtoupper(input('code'));
|
||||||
|
|
||||||
|
$result=Db::name('user')
|
||||||
|
->where('id',$id)
|
||||||
|
->update(['uniqid'=>$uniqid]);
|
||||||
|
|
||||||
|
return $this->success('設定成功');
|
||||||
|
}
|
||||||
|
|
||||||
|
// 取得預開卡資料
|
||||||
|
public function getPrecard(){
|
||||||
|
$do=Db::name('precard');
|
||||||
|
|
||||||
|
if(!input('search')){
|
||||||
|
$result=$do
|
||||||
|
->page(input('current'),input('size'))
|
||||||
|
->order('id','desc')
|
||||||
|
->select()->toArray();
|
||||||
|
|
||||||
|
$total=$do
|
||||||
|
->count();
|
||||||
|
}else{
|
||||||
|
$result=$do
|
||||||
|
->where('user_id','like','%'.input('search').'%')
|
||||||
|
->page(input('current'),input('size'))
|
||||||
|
->order('id','desc')
|
||||||
|
->select()->toArray();
|
||||||
|
|
||||||
|
$total=$do
|
||||||
|
->where('user_id','like','%'.input('search').'%')
|
||||||
|
->count();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!$result){
|
||||||
|
$result=[];
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach($result as $key => $val){
|
||||||
|
$aes = new Aes([]);
|
||||||
|
$nfc_url = 'user_id='.$val['user_id'].'&verify_code='.$val['verify_code'];
|
||||||
|
$result[$key]['params'] = getUrl().'/card/'.urlencode($aes->encrypt($nfc_url));
|
||||||
|
}
|
||||||
|
|
||||||
|
$rtn=[
|
||||||
|
'total' => $total,
|
||||||
|
'data' => $result
|
||||||
|
];
|
||||||
|
|
||||||
|
return $this->Success($rtn);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,6 @@
|
|||||||
|
<?php
|
||||||
|
return [
|
||||||
|
\think\middleware\SessionInit::class,
|
||||||
|
\think\middleware\AllowCrossDomain::class,
|
||||||
|
// app\api\middleware\CheckSiteCode::class
|
||||||
|
];
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
<?php
|
||||||
|
use think\facade\Route;
|
||||||
|
|
||||||
|
|
||||||
|
// Route::group(function () {
|
||||||
|
// Route::rule(':version/user/:action', 'api/:version.user/:action');
|
||||||
|
// })->middleware(\app\api\middleware\JWT::class);
|
||||||
|
|
||||||
|
Route::rule(':version/:controller/:action','adminapi/:version.:controller/:action');
|
||||||
@ -0,0 +1,12 @@
|
|||||||
|
<?php
|
||||||
|
// api公用函數
|
||||||
|
use think\facade\Db;
|
||||||
|
|
||||||
|
|
||||||
|
function getPrefixByAppId($appid){
|
||||||
|
return 'tg';
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkParams(){
|
||||||
|
print_r('aaaaa');
|
||||||
|
}
|
||||||
@ -0,0 +1,194 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace app\api\controller\v1;
|
||||||
|
|
||||||
|
use app\api\ApiController;
|
||||||
|
use think\facade\Db;
|
||||||
|
|
||||||
|
// use app\api\validate\User as UserValidate;
|
||||||
|
// use think\exception\ValidateException;
|
||||||
|
use app\common\lib\Token;
|
||||||
|
|
||||||
|
class User extends ApiController
|
||||||
|
{
|
||||||
|
public function getInfo()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$user = Db::name('user')
|
||||||
|
->field('user_id,avatar,line_id,line_name,line_picture,phone,real_name,email, code,parent_id')
|
||||||
|
->where('user_id', input('user_id'))
|
||||||
|
// ->whereNotNull('delete_time')
|
||||||
|
->find();
|
||||||
|
|
||||||
|
return $this->success($user);
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
return $this->error('操作失敗');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getUsers()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$users = Db::name('user')
|
||||||
|
->field('user_id,avatar,line_id,line_name,line_picture,phone,real_name,code')
|
||||||
|
->whereNotNull('delete_time')
|
||||||
|
->select();
|
||||||
|
|
||||||
|
return $this->success($users);
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
return $this->error('操作失敗');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function add()
|
||||||
|
{
|
||||||
|
|
||||||
|
$data = input();
|
||||||
|
|
||||||
|
unset($data['version']);
|
||||||
|
unset($data['action']);
|
||||||
|
unset($data['controller']);
|
||||||
|
|
||||||
|
|
||||||
|
$user_id = genUniqid($data['appid']);
|
||||||
|
|
||||||
|
$data['user_id'] = $user_id;
|
||||||
|
|
||||||
|
$avatar = isset($data['line_picture']) ? $this->saveLineImage($data['line_picture'], $data['user_id']) : '';
|
||||||
|
|
||||||
|
if (!empty($avatar)) {
|
||||||
|
$data['line_picture'] = getUrl() . '/storage/' . $data['user_id'] . '/' . $avatar;
|
||||||
|
} else {
|
||||||
|
$data['line_picture'] = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isset($data['avatar'])) {
|
||||||
|
$data['avatar'] = $data['line_picture'];
|
||||||
|
} else {
|
||||||
|
$file_path = $_SERVER['DOCUMENT_ROOT'] . '/storage/' . $data['user_id'] . '/' . date('Ymd') . '/';
|
||||||
|
if (!is_dir($file_path)) {
|
||||||
|
mkdir($file_path, 0777, true);
|
||||||
|
}
|
||||||
|
$temp_file = str_replace(getUrl(), "", $data['avatar']);
|
||||||
|
$avatar_file = $file_path . basename($temp_file);
|
||||||
|
if (!rename($_SERVER['DOCUMENT_ROOT'] . $temp_file, $avatar_file)) {
|
||||||
|
return $this->error('搬移檔案失敗');
|
||||||
|
}
|
||||||
|
$data['avatar'] = getUrl() . '/storage/' . $data['user_id'] . '/' . date('Ymd') . '/' . basename($temp_file);
|
||||||
|
}
|
||||||
|
|
||||||
|
$phone_exist = Db::name('user')
|
||||||
|
->where('phone', input('phone'))
|
||||||
|
->find();
|
||||||
|
|
||||||
|
// 檢查會員電話是否存在
|
||||||
|
if (!$phone_exist) {
|
||||||
|
// 檢查推薦碼是否存在,存在的話取得推薦人的id
|
||||||
|
if (input('refer_code')) {
|
||||||
|
$refer_id = Db::name('user')
|
||||||
|
->where('code', input('refer_code'))
|
||||||
|
->value('user_id');
|
||||||
|
|
||||||
|
if ($refer_id) {
|
||||||
|
$data['parent_id'] = $refer_id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unset($data['appid']);
|
||||||
|
unset($data['timestamp']);
|
||||||
|
unset($data['sign']);
|
||||||
|
unset($data['refer_code']);
|
||||||
|
|
||||||
|
try {
|
||||||
|
if ($phone_exist) {
|
||||||
|
Db::name('user')
|
||||||
|
->where('phone', input('phone'))
|
||||||
|
->update($data);
|
||||||
|
} else {
|
||||||
|
$id = Db::name('user')
|
||||||
|
->insertGetId($data);
|
||||||
|
|
||||||
|
$refer_code = encodeRefer($id);
|
||||||
|
|
||||||
|
Db::name('user')
|
||||||
|
->where('id', $id)
|
||||||
|
->update(['code' => $refer_code]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//使用id取得user資料庫的資料
|
||||||
|
$result = Db::name('user')
|
||||||
|
->where('phone', input('phone'))
|
||||||
|
->find();
|
||||||
|
|
||||||
|
$payload = [
|
||||||
|
'user_id' => $data['user_id'],
|
||||||
|
];
|
||||||
|
|
||||||
|
$token = Token::genToken($payload);
|
||||||
|
|
||||||
|
return $this->success(['uid' => $data['user_id'], 'info' => $result, 'token' => 'Bearer ' . $token]);
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
return $this->error($e->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function delete()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
Db::name('user')
|
||||||
|
->where('user_id', input('user_id'))
|
||||||
|
->update([
|
||||||
|
'delete_time' => time()
|
||||||
|
]);
|
||||||
|
return $this->success('操作成功');
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
return $this->error('操作失敗');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function update()
|
||||||
|
{
|
||||||
|
$data = input('post.');
|
||||||
|
|
||||||
|
unset($data['appid']);
|
||||||
|
unset($data['timestamp']);
|
||||||
|
unset($data['sign']);
|
||||||
|
|
||||||
|
try {
|
||||||
|
Db::name('user')
|
||||||
|
->where('user_id', $data['user_id'])
|
||||||
|
->update($data);
|
||||||
|
|
||||||
|
return $this->success('操作成功');
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
return $this->error('操作失敗');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function saveLineImage($pictureUrl, $uid)
|
||||||
|
{
|
||||||
|
if ($pictureUrl) {
|
||||||
|
$curl = curl_init($pictureUrl);
|
||||||
|
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
|
||||||
|
$imageData = curl_exec($curl);
|
||||||
|
curl_close($curl);
|
||||||
|
|
||||||
|
$filename = $uid . "_line.jpg";
|
||||||
|
$filedir = $_SERVER['DOCUMENT_ROOT'] . '/storage/' . $uid;
|
||||||
|
if (!file_exists($filedir)) {
|
||||||
|
mkdir($filedir, 0777, true);
|
||||||
|
}
|
||||||
|
$fp = fopen($filedir . '/' . $filename, 'a');
|
||||||
|
fwrite($fp, $imageData);
|
||||||
|
fclose($fp);
|
||||||
|
|
||||||
|
return $filename;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,7 @@
|
|||||||
|
<?php
|
||||||
|
return [
|
||||||
|
// \think\middleware\SessionInit::class,
|
||||||
|
// \think\middleware\AllowCrossDomain::class,
|
||||||
|
// app\api\middleware\CheckParams::class
|
||||||
|
// app\api\middleware\CheckSiteCode::class
|
||||||
|
];
|
||||||
@ -0,0 +1,41 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare (strict_types=1);
|
||||||
|
|
||||||
|
namespace app\api\middleware;
|
||||||
|
|
||||||
|
use think\exception\HttpException;
|
||||||
|
|
||||||
|
class CheckParams
|
||||||
|
{
|
||||||
|
public function handle($request, \Closure $next): object
|
||||||
|
{
|
||||||
|
|
||||||
|
$params = $request->param();
|
||||||
|
if(!isset($params['sign'])){
|
||||||
|
return json(['code'=>401,'message'=>'API驗證失敗','data'=>'No Sign','time'=>time()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$sign = $params['sign'];
|
||||||
|
|
||||||
|
unset($params['sign']);
|
||||||
|
unset($params['controller']);
|
||||||
|
unset($params['action']);
|
||||||
|
unset($params['version']);
|
||||||
|
ksort($params);
|
||||||
|
|
||||||
|
$string = md5(md5(strtolower(http_build_query($params))).'seckey');
|
||||||
|
// print_r($string === $sign);
|
||||||
|
// var_dump($sign);
|
||||||
|
// var_dump($string);
|
||||||
|
|
||||||
|
if($string !== $sign){
|
||||||
|
// throw new HttpException(401, 'Sign Error!!!');
|
||||||
|
return json(['code'=>401,'message'=>'API驗證失敗','data'=>'Sign Error','time'=>time()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$response = $next($request);
|
||||||
|
|
||||||
|
return $response;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,14 @@
|
|||||||
|
<?php
|
||||||
|
use think\facade\Route;
|
||||||
|
|
||||||
|
|
||||||
|
Route::group(function () {
|
||||||
|
Route::rule(':version/user/:action', 'api/:version.user/:action');
|
||||||
|
})->middleware(\app\api\middleware\CheckParams::class);
|
||||||
|
|
||||||
|
Route::group(function(){
|
||||||
|
Route::rule(':version/:controller/:action','api/:version.:controller/:action');
|
||||||
|
})->allowCrossDomain([
|
||||||
|
'Access-Control-Allow-Headers' => 'Origin, X-Requested-With, Content-Type, Accept, Authorization, SessionId, sessionid',
|
||||||
|
'Access-Control-Expose-Headers' => 'Authorization, SessionId, sessionid'
|
||||||
|
]);
|
||||||
@ -0,0 +1,25 @@
|
|||||||
|
<?php
|
||||||
|
namespace app\api\validate;
|
||||||
|
|
||||||
|
use think\Validate;
|
||||||
|
|
||||||
|
class User extends Validate
|
||||||
|
{
|
||||||
|
protected $rule = [
|
||||||
|
'appid' => 'require',
|
||||||
|
'user_id' => 'require|max:255',
|
||||||
|
'name' => 'require|max:25',
|
||||||
|
'level' => 'number|between:0,3',
|
||||||
|
'overdue_time' => 'number'
|
||||||
|
];
|
||||||
|
|
||||||
|
protected $message = [
|
||||||
|
'appid.require' => 'appid 不可為空',
|
||||||
|
'user_id.require' => 'User Id不可為空',
|
||||||
|
'name.require' => 'Name不得為空',
|
||||||
|
'name.max' => 'Name不得超過25個字',
|
||||||
|
'level.number' => 'Level必需是數字',
|
||||||
|
'level.between' => 'Level只能在0-3之間',
|
||||||
|
'overdue_time.require' => 'overdue_time必需是數字',
|
||||||
|
];
|
||||||
|
}
|
||||||
@ -0,0 +1,24 @@
|
|||||||
|
<?php
|
||||||
|
namespace app\api\validate;
|
||||||
|
|
||||||
|
use think\Validate;
|
||||||
|
|
||||||
|
class UserLevel extends Validate
|
||||||
|
{
|
||||||
|
protected $rule = [
|
||||||
|
'appid' => 'require',
|
||||||
|
'user_id' => 'require|max:255',
|
||||||
|
'level' => 'require|number|between:0,3',
|
||||||
|
'overdue_time' => 'require|number'
|
||||||
|
];
|
||||||
|
|
||||||
|
protected $message = [
|
||||||
|
'appid.require' => 'appid 不可為空',
|
||||||
|
'user_id.require' => 'User Id不可為空',
|
||||||
|
'level.require' => 'Level不可為空',
|
||||||
|
'level.number' => 'Level必需是數字',
|
||||||
|
'level.between' => 'Level只能在0-3之間',
|
||||||
|
'overdue_time.require' => 'overdue_time不可為空',
|
||||||
|
'overdue_time.number' => 'overdue_time必需是數字',
|
||||||
|
];
|
||||||
|
}
|
||||||
@ -0,0 +1,60 @@
|
|||||||
|
<?php
|
||||||
|
declare (strict_types = 1);
|
||||||
|
|
||||||
|
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\facade\Db;
|
||||||
|
|
||||||
|
class CheckExpire extends Command
|
||||||
|
{
|
||||||
|
protected function configure()
|
||||||
|
{
|
||||||
|
// 指令配置
|
||||||
|
$this->setName('checkexpire')
|
||||||
|
->setDescription('the checkexpire command');
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function execute(Input $input, Output $output)
|
||||||
|
{
|
||||||
|
// 取得代理資料
|
||||||
|
$t_agents = Db::name('agent')->select();
|
||||||
|
|
||||||
|
foreach($t_agents as $val){
|
||||||
|
$agents[$val['id']] = $val;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 取得過期用戶
|
||||||
|
$e_users = Db::name('user')
|
||||||
|
->where('status',1)
|
||||||
|
->where('overdue_time','<',time())
|
||||||
|
->select();
|
||||||
|
|
||||||
|
// 更新過期用戶
|
||||||
|
foreach($e_users as $val){
|
||||||
|
$data['level']=0;
|
||||||
|
$data['status']=1;
|
||||||
|
|
||||||
|
$level_option = Db::name('user_level')
|
||||||
|
->where('agent_id',$val['agent_id'])
|
||||||
|
->where('level_id',$data['level'])
|
||||||
|
->find();
|
||||||
|
|
||||||
|
$data['nc_type']=$level_option['nc_type'];
|
||||||
|
$data['nc_func']=$level_option['nc_func'];
|
||||||
|
|
||||||
|
|
||||||
|
Db::name('user')
|
||||||
|
->where('id',$val['id'])
|
||||||
|
->update($data);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 指令输出
|
||||||
|
$output->writeln('checkexpire');
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,62 @@
|
|||||||
|
<?php
|
||||||
|
declare (strict_types = 1);
|
||||||
|
|
||||||
|
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\facade\Db;
|
||||||
|
|
||||||
|
class CheckTrial extends Command
|
||||||
|
{
|
||||||
|
protected function configure()
|
||||||
|
{
|
||||||
|
// 指令配置
|
||||||
|
$this->setName('checktrial')
|
||||||
|
->setDescription('the checktrial command');
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function execute(Input $input, Output $output)
|
||||||
|
{
|
||||||
|
// 取得代理資料
|
||||||
|
$t_agents = Db::name('agent')
|
||||||
|
->select();
|
||||||
|
|
||||||
|
foreach($t_agents as $val){
|
||||||
|
$agents[$val['id']] = $val;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 取得試用過期用戶
|
||||||
|
$e_users = Db::name('user')
|
||||||
|
->where('status',2)
|
||||||
|
->where('overdue_time','<',time())
|
||||||
|
->select();
|
||||||
|
|
||||||
|
// 更新試用過期用戶
|
||||||
|
foreach($e_users as $val){
|
||||||
|
$data['overdue_time']=strtotime("+".$agents[$val['agent_id']]['base_days']." days");
|
||||||
|
$data['level']=$agents[$val['agent_id']]['base_level'];
|
||||||
|
|
||||||
|
$level_option = Db::name('user_level')
|
||||||
|
->where('agent_id',$val['agent_id'])
|
||||||
|
->where('level_id',$data['level'])
|
||||||
|
->find();
|
||||||
|
|
||||||
|
$data['nc_type']=$level_option['nc_type'];
|
||||||
|
$data['nc_func']=$level_option['nc_func'];
|
||||||
|
|
||||||
|
$data['status']=1;
|
||||||
|
print_r($data);
|
||||||
|
Db::name('user')
|
||||||
|
->where('id',$val['id'])
|
||||||
|
->update($data);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 指令输出
|
||||||
|
$output->writeln('檢查試用會員完成');
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,29 @@
|
|||||||
|
<?php
|
||||||
|
namespace app\common\lib;
|
||||||
|
|
||||||
|
class Aes{
|
||||||
|
|
||||||
|
private $key = 'iloveutel';
|
||||||
|
private $iv = '1234567890123456';
|
||||||
|
private $method = 'AES-128-CBC';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 構造方法
|
||||||
|
*/
|
||||||
|
public function __construct($config){
|
||||||
|
foreach($config as $k=>$v){
|
||||||
|
|
||||||
|
$this->$k = $v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 加密
|
||||||
|
public function encrypt($data){
|
||||||
|
return base64_encode(openssl_encrypt($data, $this->method,$this->key, OPENSSL_RAW_DATA , $this->iv));
|
||||||
|
}
|
||||||
|
|
||||||
|
//解密
|
||||||
|
public function descrypt($data){
|
||||||
|
return openssl_decrypt(base64_decode($data), $this->method, $this->key, OPENSSL_RAW_DATA, $this->iv);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,38 @@
|
|||||||
|
<?php
|
||||||
|
namespace app\common\lib;
|
||||||
|
|
||||||
|
use Firebase\JWT\JWT;
|
||||||
|
use Firebase\JWT\Key;
|
||||||
|
|
||||||
|
class Token{
|
||||||
|
/**
|
||||||
|
* 構造方法
|
||||||
|
*/
|
||||||
|
public function __construct(){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function genToken($payload){
|
||||||
|
$payload = array_merge($payload,[
|
||||||
|
'aud' => '',
|
||||||
|
'exp' => time() + (365 * 24 * 60 * 60),
|
||||||
|
'iat' => time(),
|
||||||
|
'iss' => '',
|
||||||
|
'jti' => uniqid(mt_rand(), true),
|
||||||
|
'nbf' => time(),
|
||||||
|
'sub' => '',
|
||||||
|
]);
|
||||||
|
|
||||||
|
return JWT::encode($payload, \think\facade\Config::get('jwt.secret'), 'HS256');
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function check($token){
|
||||||
|
try{
|
||||||
|
$decode = JWT::decode($token, new Key(\think\facade\Config::get('jwt.secret'), 'HS256'));
|
||||||
|
return true;
|
||||||
|
}catch(\Exception $e){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,51 @@
|
|||||||
|
<?php
|
||||||
|
namespace app\common\lib;
|
||||||
|
|
||||||
|
use think\facade\Db;
|
||||||
|
|
||||||
|
use JeroenDesloovere\VCard\VCard as VCardApi;
|
||||||
|
|
||||||
|
class Vcard{
|
||||||
|
|
||||||
|
public static function genVcf($userid){
|
||||||
|
$userInfo = Db::name('user')->where('user_id',$userid)->find();
|
||||||
|
if(!$userInfo){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
$vcard = new VCardApi();
|
||||||
|
|
||||||
|
$lastname = $userInfo['real_name'];
|
||||||
|
$firstname = '';
|
||||||
|
$additional = '';
|
||||||
|
$prefix = '';
|
||||||
|
$suffix = '';
|
||||||
|
|
||||||
|
$vcard->addName($lastname, $firstname, $additional, $prefix, $suffix);
|
||||||
|
|
||||||
|
// add work data
|
||||||
|
$vcard->addCompany($userInfo['company']);
|
||||||
|
$vcard->addJobtitle($userInfo['title']);
|
||||||
|
// $vcard->addRole('Data Protection Officer');
|
||||||
|
$vcard->addEmail($userInfo['email']);
|
||||||
|
$vcard->addPhoneNumber($userInfo['phone'], 'PREF;CELL');
|
||||||
|
$vcard->addPhoneNumber($userInfo['tel'], 'WORK');
|
||||||
|
// $vcard->addAddress(null, null, 'street', 'worktown', null, 'workpostcode', 'Belgium');
|
||||||
|
// $vcard->addLabel('street, worktown, workpostcode Belgium');
|
||||||
|
if($userInfo['url']){
|
||||||
|
// $vcard->addURL(getUrl().'/card/?userid='.$userInfo['user_id']);
|
||||||
|
$vcard->addURL($userInfo['url']);
|
||||||
|
}
|
||||||
|
|
||||||
|
$vcard->addPhoto(__DIR__.'/../../../public/storage/'.$userInfo['user_id'].'/'.$userInfo['user_id'].'_line.jpg');
|
||||||
|
|
||||||
|
// return vcard as a string
|
||||||
|
//return $vcard->getOutput();
|
||||||
|
|
||||||
|
// return vcard as a download
|
||||||
|
// return $vcard->download();
|
||||||
|
$vcard->setSavePath(__DIR__.'/../../../public/storage/'.$userInfo['user_id'].'/');
|
||||||
|
$vcard->setFilename($userInfo['user_id']);
|
||||||
|
$vcard->save();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,6 @@
|
|||||||
|
<?php
|
||||||
|
namespace app\common\sms;
|
||||||
|
|
||||||
|
interface Isms {
|
||||||
|
public function sendSms(array $data);
|
||||||
|
}
|
||||||
@ -0,0 +1,23 @@
|
|||||||
|
<?php
|
||||||
|
namespace app\common\sms;
|
||||||
|
|
||||||
|
use think\facade\Db;
|
||||||
|
use app\common\sms\SmsFactory;
|
||||||
|
|
||||||
|
class Sms
|
||||||
|
{
|
||||||
|
//使用靜態方法,建立物流單
|
||||||
|
public static function createSms($smscode,$data)
|
||||||
|
{
|
||||||
|
|
||||||
|
$sms = SmsFactory::createSmsService($smscode);
|
||||||
|
|
||||||
|
$result = $sms->sendSms($data);
|
||||||
|
|
||||||
|
if(!$result){
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,17 @@
|
|||||||
|
<?php
|
||||||
|
namespace app\common\sms;
|
||||||
|
|
||||||
|
use app\common\sms\SmskingSms;
|
||||||
|
use think\Exception;
|
||||||
|
|
||||||
|
class SmsFactory
|
||||||
|
{
|
||||||
|
public static function createSmsService($serviceName) {
|
||||||
|
switch ($serviceName) {
|
||||||
|
case 'smsking':
|
||||||
|
return new SmskingSms('slash1000','a810309');
|
||||||
|
default:
|
||||||
|
throw new Exception("Unsupported sms service: $serviceName");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,53 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace app\common\sms;
|
||||||
|
|
||||||
|
use GuzzleHttp\Client;
|
||||||
|
|
||||||
|
use app\common\sms\Isms;
|
||||||
|
|
||||||
|
use think\facade\Db;
|
||||||
|
|
||||||
|
//實作物流串接介面
|
||||||
|
class SmskingSms implements Isms
|
||||||
|
{
|
||||||
|
private $username;
|
||||||
|
private $password;
|
||||||
|
|
||||||
|
public function __construct(string $username, string $password)
|
||||||
|
{
|
||||||
|
$this->username = $username;
|
||||||
|
$this->password = $password;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function sendSms(array $data)
|
||||||
|
{
|
||||||
|
// 將$message 轉為 Big5 編碼
|
||||||
|
$message = mb_convert_encoding($data['message'], 'BIG5', 'UTF-8');
|
||||||
|
|
||||||
|
$url = 'https://api.kotsms.com.tw/kotsmsapi-1.php';
|
||||||
|
|
||||||
|
$query = http_build_query([
|
||||||
|
'username' => $this->username,
|
||||||
|
'password' => $this->password,
|
||||||
|
'dstaddr' => $data['recipient'],
|
||||||
|
'smbody' => $message,
|
||||||
|
]);
|
||||||
|
|
||||||
|
$url .= '?' . $query;
|
||||||
|
// 使用 Guzzle 發送 API 請求
|
||||||
|
$client = new Client();
|
||||||
|
$response = $client->request('GET', $url);
|
||||||
|
|
||||||
|
// 處理 API 回應
|
||||||
|
$body = $response->getBody()->getContents();
|
||||||
|
$result =explode('=',$body);
|
||||||
|
// $result = json_decode($body, true);
|
||||||
|
if (is_numeric(intval($result[1])) && intval($result[1])>=0) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,12 @@
|
|||||||
|
<?php
|
||||||
|
namespace app\controller;
|
||||||
|
|
||||||
|
use app\BaseController;
|
||||||
|
|
||||||
|
class Index extends BaseController
|
||||||
|
{
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,19 @@
|
|||||||
|
<?php
|
||||||
|
namespace app\controller;
|
||||||
|
|
||||||
|
use app\BaseController;
|
||||||
|
|
||||||
|
use think\facade\Db;
|
||||||
|
|
||||||
|
use app\common\lib\Vcard;
|
||||||
|
|
||||||
|
class Vcf extends BaseController
|
||||||
|
{
|
||||||
|
|
||||||
|
public function index(){
|
||||||
|
$userid=input('userid');
|
||||||
|
$userid='mc622b0cda299c6';
|
||||||
|
|
||||||
|
Vcard::genVcf($userid);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,17 @@
|
|||||||
|
<?php
|
||||||
|
// 事件定义文件
|
||||||
|
return [
|
||||||
|
'bind' => [
|
||||||
|
],
|
||||||
|
|
||||||
|
'listen' => [
|
||||||
|
'AppInit' => [],
|
||||||
|
'HttpRun' => [],
|
||||||
|
'HttpEnd' => [],
|
||||||
|
'LogLevel' => [],
|
||||||
|
'LogWrite' => [],
|
||||||
|
],
|
||||||
|
|
||||||
|
'subscribe' => [
|
||||||
|
],
|
||||||
|
];
|
||||||
@ -0,0 +1,10 @@
|
|||||||
|
<?php
|
||||||
|
// 全局中间件定义文件
|
||||||
|
return [
|
||||||
|
// 全局请求缓存
|
||||||
|
// \think\middleware\CheckRequestCache::class,
|
||||||
|
// 多语言加载
|
||||||
|
// \think\middleware\LoadLangPack::class,
|
||||||
|
// Session初始化
|
||||||
|
// \think\middleware\SessionInit::class
|
||||||
|
];
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
<?php
|
||||||
|
use app\ExceptionHandle;
|
||||||
|
use app\Request;
|
||||||
|
|
||||||
|
// 容器Provider定义文件
|
||||||
|
return [
|
||||||
|
'think\Request' => Request::class,
|
||||||
|
'think\exception\Handle' => ExceptionHandle::class,
|
||||||
|
];
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use app\AppService;
|
||||||
|
|
||||||
|
// 系统服务定义文件
|
||||||
|
// 服务在完成全局初始化之后执行
|
||||||
|
return [
|
||||||
|
AppService::class,
|
||||||
|
];
|
||||||
@ -0,0 +1,55 @@
|
|||||||
|
{
|
||||||
|
"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"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "yunwuxin",
|
||||||
|
"email": "448901948@qq.com"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"require": {
|
||||||
|
"php": ">=7.2.5",
|
||||||
|
"topthink/framework": "^6.0.0",
|
||||||
|
"topthink/think-orm": "^2.0",
|
||||||
|
"topthink/think-multi-app": "^1.0",
|
||||||
|
"thans/tp-jwt-auth": "^1.2",
|
||||||
|
"guzzlehttp/guzzle": "~6.0",
|
||||||
|
"aferrandini/phpqrcode": "^1.0",
|
||||||
|
"jeroendesloovere/vcard": "^1.7",
|
||||||
|
"topthink/think-filesystem": "^2.0",
|
||||||
|
"firebase/php-jwt": "^6.4"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"symfony/var-dumper": "^4.2",
|
||||||
|
"topthink/think-trace":"^1.0"
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"app\\": "app"
|
||||||
|
},
|
||||||
|
"psr-0": {
|
||||||
|
"": "extend/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"config": {
|
||||||
|
"preferred-install": "dist"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"post-autoload-dump": [
|
||||||
|
"@php think service:discover",
|
||||||
|
"@php think vendor:publish"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,29 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | 缓存设置
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
|
||||||
|
return [
|
||||||
|
// 默认缓存驱动
|
||||||
|
'default' => env('cache.driver', 'file'),
|
||||||
|
|
||||||
|
// 缓存连接方式配置
|
||||||
|
'stores' => [
|
||||||
|
'file' => [
|
||||||
|
// 驱动方式
|
||||||
|
'type' => 'File',
|
||||||
|
// 缓存保存目录
|
||||||
|
'path' => '',
|
||||||
|
// 缓存前缀
|
||||||
|
'prefix' => '',
|
||||||
|
// 缓存有效期 0表示永久缓存
|
||||||
|
'expire' => 0,
|
||||||
|
// 缓存标签前缀
|
||||||
|
'tag_prefix' => 'tag:',
|
||||||
|
// 序列化机制 例如 ['serialize', 'unserialize']
|
||||||
|
'serialize' => [],
|
||||||
|
],
|
||||||
|
// 更多的缓存连接
|
||||||
|
],
|
||||||
|
];
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
<?php
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | 控制台配置
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
return [
|
||||||
|
// 指令定义
|
||||||
|
'commands' => [
|
||||||
|
'checktrial' => app\command\CheckTrial::class,
|
||||||
|
'checkexpire' => app\command\CheckExpire::class,
|
||||||
|
],
|
||||||
|
];
|
||||||
@ -0,0 +1,20 @@
|
|||||||
|
<?php
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | Cookie设置
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
return [
|
||||||
|
// cookie 保存时间
|
||||||
|
'expire' => 0,
|
||||||
|
// cookie 保存路径
|
||||||
|
'path' => '/',
|
||||||
|
// cookie 有效域名
|
||||||
|
'domain' => '',
|
||||||
|
// cookie 启用安全传输
|
||||||
|
'secure' => false,
|
||||||
|
// httponly设置
|
||||||
|
'httponly' => false,
|
||||||
|
// 是否使用 setcookie
|
||||||
|
'setcookie' => true,
|
||||||
|
// samesite 设置,支持 'strict' 'lax'
|
||||||
|
'samesite' => '',
|
||||||
|
];
|
||||||
@ -0,0 +1,24 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
return [
|
||||||
|
// 默认磁盘
|
||||||
|
'default' => env('filesystem.driver', 'local'),
|
||||||
|
// 磁盘列表
|
||||||
|
'disks' => [
|
||||||
|
'local' => [
|
||||||
|
'type' => 'local',
|
||||||
|
'root' => app()->getRuntimePath() . 'storage',
|
||||||
|
],
|
||||||
|
'public' => [
|
||||||
|
// 磁盘类型
|
||||||
|
'type' => 'local',
|
||||||
|
// 磁盘路径
|
||||||
|
'root' => app()->getRootPath() . 'public/storage',
|
||||||
|
// 磁盘路径对应的外部URL路径
|
||||||
|
'url' => '/storage',
|
||||||
|
// 可见性
|
||||||
|
'visibility' => 'public',
|
||||||
|
],
|
||||||
|
// 更多的磁盘配置信息
|
||||||
|
],
|
||||||
|
];
|
||||||
@ -0,0 +1,27 @@
|
|||||||
|
<?php
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | 多语言设置
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
|
||||||
|
return [
|
||||||
|
// 默认语言
|
||||||
|
'default_lang' => env('lang.default_lang', 'zh-cn'),
|
||||||
|
// 允许的语言列表
|
||||||
|
'allow_lang_list' => [],
|
||||||
|
// 多语言自动侦测变量名
|
||||||
|
'detect_var' => 'lang',
|
||||||
|
// 是否使用Cookie记录
|
||||||
|
'use_cookie' => true,
|
||||||
|
// 多语言cookie变量
|
||||||
|
'cookie_var' => 'think_lang',
|
||||||
|
// 多语言header变量
|
||||||
|
'header_var' => 'think-lang',
|
||||||
|
// 扩展语言包
|
||||||
|
'extend_list' => [],
|
||||||
|
// Accept-Language转义为对应语言包名称
|
||||||
|
'accept_language' => [
|
||||||
|
'zh-hans-cn' => 'zh-cn',
|
||||||
|
],
|
||||||
|
// 是否支持语言分组
|
||||||
|
'allow_group' => false,
|
||||||
|
];
|
||||||
@ -0,0 +1,45 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | 日志设置
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
return [
|
||||||
|
// 默认日志记录通道
|
||||||
|
'default' => env('log.channel', 'file'),
|
||||||
|
// 日志记录级别
|
||||||
|
'level' => [],
|
||||||
|
// 日志类型记录的通道 ['error'=>'email',...]
|
||||||
|
'type_channel' => [],
|
||||||
|
// 关闭全局日志写入
|
||||||
|
'close' => false,
|
||||||
|
// 全局日志处理 支持闭包
|
||||||
|
'processor' => null,
|
||||||
|
|
||||||
|
// 日志通道列表
|
||||||
|
'channels' => [
|
||||||
|
'file' => [
|
||||||
|
// 日志记录方式
|
||||||
|
'type' => 'File',
|
||||||
|
// 日志保存目录
|
||||||
|
'path' => '',
|
||||||
|
// 单文件日志写入
|
||||||
|
'single' => false,
|
||||||
|
// 独立日志级别
|
||||||
|
'apart_level' => [],
|
||||||
|
// 最大日志文件数量
|
||||||
|
'max_files' => 0,
|
||||||
|
// 使用JSON格式记录
|
||||||
|
'json' => false,
|
||||||
|
// 日志处理
|
||||||
|
'processor' => null,
|
||||||
|
// 关闭通道日志写入
|
||||||
|
'close' => false,
|
||||||
|
// 日志输出格式化
|
||||||
|
'format' => '[%s][%s] %s',
|
||||||
|
// 是否实时写入
|
||||||
|
'realtime_write' => false,
|
||||||
|
],
|
||||||
|
// 其它日志通道配置
|
||||||
|
],
|
||||||
|
|
||||||
|
];
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
<?php
|
||||||
|
// 中间件配置
|
||||||
|
return [
|
||||||
|
// 别名或分组
|
||||||
|
'alias' => [],
|
||||||
|
// 优先级设置,此数组中的中间件会按照数组中的顺序优先执行
|
||||||
|
'priority' => [],
|
||||||
|
];
|
||||||
@ -0,0 +1,45 @@
|
|||||||
|
<?php
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | 路由设置
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
|
||||||
|
return [
|
||||||
|
// pathinfo分隔符
|
||||||
|
'pathinfo_depr' => '/',
|
||||||
|
// URL伪静态后缀
|
||||||
|
'url_html_suffix' => 'html',
|
||||||
|
// URL普通方式参数 用于自动生成
|
||||||
|
'url_common_param' => true,
|
||||||
|
// 是否开启路由延迟解析
|
||||||
|
'url_lazy_route' => false,
|
||||||
|
// 是否强制使用路由
|
||||||
|
'url_route_must' => false,
|
||||||
|
// 合并路由规则
|
||||||
|
'route_rule_merge' => false,
|
||||||
|
// 路由是否完全匹配
|
||||||
|
'route_complete_match' => false,
|
||||||
|
// 访问控制器层名称
|
||||||
|
'controller_layer' => 'controller',
|
||||||
|
// 空控制器名
|
||||||
|
'empty_controller' => 'Error',
|
||||||
|
// 是否使用控制器后缀
|
||||||
|
'controller_suffix' => false,
|
||||||
|
// 默认的路由变量规则
|
||||||
|
'default_route_pattern' => '[\w\.]+',
|
||||||
|
// 是否开启请求缓存 true自动缓存 支持设置请求缓存规则
|
||||||
|
'request_cache_key' => false,
|
||||||
|
// 请求缓存有效期
|
||||||
|
'request_cache_expire' => null,
|
||||||
|
// 全局请求缓存排除规则
|
||||||
|
'request_cache_except' => [],
|
||||||
|
// 默认控制器名
|
||||||
|
'default_controller' => 'Index',
|
||||||
|
// 默认操作名
|
||||||
|
'default_action' => 'index',
|
||||||
|
// 操作方法后缀
|
||||||
|
'action_suffix' => '',
|
||||||
|
// 默认JSONP格式返回的处理方法
|
||||||
|
'default_jsonp_handler' => 'jsonpReturn',
|
||||||
|
// 默认JSONP处理方法
|
||||||
|
'var_jsonp_handler' => 'callback',
|
||||||
|
];
|
||||||
@ -0,0 +1,19 @@
|
|||||||
|
<?php
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | 会话设置
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
|
||||||
|
return [
|
||||||
|
// session name
|
||||||
|
'name' => 'PHPSESSID',
|
||||||
|
// SESSION_ID的提交变量,解决flash上传跨域
|
||||||
|
'var_session_id' => '',
|
||||||
|
// 驱动方式 支持file cache
|
||||||
|
'type' => 'file',
|
||||||
|
// 存储连接标识 当type使用cache的时候有效
|
||||||
|
'store' => null,
|
||||||
|
// 过期时间
|
||||||
|
'expire' => 1440,
|
||||||
|
// 前缀
|
||||||
|
'prefix' => '',
|
||||||
|
];
|
||||||
@ -0,0 +1,10 @@
|
|||||||
|
<?php
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | Trace设置 开启调试模式后有效
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
return [
|
||||||
|
// 内置Html和Console两种方式 支持扩展
|
||||||
|
'type' => 'Html',
|
||||||
|
// 读取的日志通道名
|
||||||
|
'channel' => '',
|
||||||
|
];
|
||||||
@ -0,0 +1,25 @@
|
|||||||
|
<?php
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | 模板设置
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
|
||||||
|
return [
|
||||||
|
// 模板引擎类型使用Think
|
||||||
|
'type' => 'Think',
|
||||||
|
// 默认模板渲染规则 1 解析为小写+下划线 2 全部转换小写 3 保持操作方法
|
||||||
|
'auto_rule' => 1,
|
||||||
|
// 模板目录名
|
||||||
|
'view_dir_name' => 'view',
|
||||||
|
// 模板后缀
|
||||||
|
'view_suffix' => 'html',
|
||||||
|
// 模板文件名分隔符
|
||||||
|
'view_depr' => DIRECTORY_SEPARATOR,
|
||||||
|
// 模板引擎普通标签开始标记
|
||||||
|
'tpl_begin' => '{',
|
||||||
|
// 模板引擎普通标签结束标记
|
||||||
|
'tpl_end' => '}',
|
||||||
|
// 标签库标签开始标记
|
||||||
|
'taglib_begin' => '{',
|
||||||
|
// 标签库标签结束标记
|
||||||
|
'taglib_end' => '}',
|
||||||
|
];
|
||||||
@ -0,0 +1,2 @@
|
|||||||
|
*
|
||||||
|
!.gitignore
|
||||||
@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"name": "ecard_api",
|
||||||
|
"lockfileVersion": 2,
|
||||||
|
"requires": true,
|
||||||
|
"packages": {}
|
||||||
|
}
|
||||||
@ -0,0 +1 @@
|
|||||||
|
{}
|
||||||
@ -0,0 +1 @@
|
|||||||
|
open_basedir=/www/wwwroot/sso.h888.fun/:/tmp/
|
||||||
@ -0,0 +1,198 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="zh-TW">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<title>Error!!!</title>
|
||||||
|
<style>
|
||||||
|
* {
|
||||||
|
margin:0px auto;
|
||||||
|
padding: 0px;
|
||||||
|
text-align:center;
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
background-color: #D4D9ED;
|
||||||
|
}
|
||||||
|
.cont_principal {
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.cont_error {
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
height: 300px;
|
||||||
|
top: 50%;
|
||||||
|
margin-top:-150px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cont_error > h1 {
|
||||||
|
font-family: 'Lato', sans-serif;
|
||||||
|
font-weight: 400;
|
||||||
|
font-size:150px;
|
||||||
|
color:#fff;
|
||||||
|
position: relative;
|
||||||
|
left:-100%;
|
||||||
|
transition: all 0.5s;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.cont_error > p {
|
||||||
|
font-family: 'Lato', sans-serif;
|
||||||
|
font-weight: 300;
|
||||||
|
font-size:24px;
|
||||||
|
letter-spacing: 5px;
|
||||||
|
color:#9294AE;
|
||||||
|
position: relative;
|
||||||
|
left:100%;
|
||||||
|
transition: all 0.5s;
|
||||||
|
transition-delay: 0.5s;
|
||||||
|
-webkit-transition: all 0.5s;
|
||||||
|
-webkit-transition-delay: 0.5s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cont_aura_1 {
|
||||||
|
position:absolute;
|
||||||
|
width:300px;
|
||||||
|
height: 120%;
|
||||||
|
top:25px;
|
||||||
|
right: -340px;
|
||||||
|
background-color: #8A65DF;
|
||||||
|
box-shadow: 0px 0px 60px 20px rgba(137,100,222,0.5);
|
||||||
|
-webkit-transition: all 0.5s;
|
||||||
|
transition: all 0.5s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cont_aura_2 {
|
||||||
|
position:absolute;
|
||||||
|
width:100%;
|
||||||
|
height: 300px;
|
||||||
|
right:-10%;
|
||||||
|
bottom:-301px;
|
||||||
|
background-color: #8B65E4;
|
||||||
|
box-shadow: 0px 0px 60px 10px rgba(131, 95, 214, 0.5),0px 0px 20px 0px rgba(0,0,0,0.1);
|
||||||
|
z-index:5;
|
||||||
|
transition: all 0.5s;
|
||||||
|
-webkit-transition: all 0.5s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cont_error_active > .cont_error > h1 {
|
||||||
|
left:0%;
|
||||||
|
}
|
||||||
|
.cont_error_active > .cont_error > p {
|
||||||
|
left:0%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cont_error_active > .cont_aura_2 {
|
||||||
|
animation-name: animation_error_2;
|
||||||
|
animation-duration: 4s;
|
||||||
|
animation-timing-function: linear;
|
||||||
|
animation-iteration-count: infinite;
|
||||||
|
animation-direction: alternate;
|
||||||
|
transform: rotate(-20deg);
|
||||||
|
}
|
||||||
|
.cont_error_active > .cont_aura_1 {
|
||||||
|
transform: rotate(20deg);
|
||||||
|
right:-170px;
|
||||||
|
animation-name: animation_error_1;
|
||||||
|
animation-duration: 4s;
|
||||||
|
animation-timing-function: linear;
|
||||||
|
animation-iteration-count: infinite;
|
||||||
|
animation-direction: alternate;
|
||||||
|
}
|
||||||
|
|
||||||
|
@-webkit-keyframes animation_error_1 {
|
||||||
|
from {
|
||||||
|
-webkit-transform: rotate(20deg);
|
||||||
|
transform: rotate(20deg);
|
||||||
|
}
|
||||||
|
to { -webkit-transform: rotate(25deg);
|
||||||
|
transform: rotate(25deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@-o-keyframes animation_error_1 {
|
||||||
|
from {
|
||||||
|
-webkit-transform: rotate(20deg);
|
||||||
|
transform: rotate(20deg);
|
||||||
|
}
|
||||||
|
to { -webkit-transform: rotate(25deg);
|
||||||
|
transform: rotate(25deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
@-moz-keyframes animation_error_1 {
|
||||||
|
from {
|
||||||
|
-webkit-transform: rotate(20deg);
|
||||||
|
transform: rotate(20deg);
|
||||||
|
}
|
||||||
|
to { -webkit-transform: rotate(25deg);
|
||||||
|
transform: rotate(25deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
@keyframes animation_error_1 {
|
||||||
|
from {
|
||||||
|
-webkit-transform: rotate(20deg);
|
||||||
|
transform: rotate(20deg);
|
||||||
|
}
|
||||||
|
to { -webkit-transform: rotate(25deg);
|
||||||
|
transform: rotate(25deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@-webkit-keyframes animation_error_2 {
|
||||||
|
from { -webkit-transform: rotate(-15deg);
|
||||||
|
transform: rotate(-15deg);
|
||||||
|
}
|
||||||
|
to { -webkit-transform: rotate(-20deg);
|
||||||
|
transform: rotate(-20deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@-o-keyframes animation_error_2 {
|
||||||
|
from { -webkit-transform: rotate(-15deg);
|
||||||
|
transform: rotate(-15deg);
|
||||||
|
}
|
||||||
|
to { -webkit-transform: rotate(-20deg);
|
||||||
|
transform: rotate(-20deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@-moz-keyframes animation_error_2 {
|
||||||
|
from { -webkit-transform: rotate(-15deg);
|
||||||
|
transform: rotate(-15deg);
|
||||||
|
}
|
||||||
|
to { -webkit-transform: rotate(-20deg);
|
||||||
|
transform: rotate(-20deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@keyframes animation_error_2 {
|
||||||
|
from { -webkit-transform: rotate(-15deg);
|
||||||
|
transform: rotate(-15deg);
|
||||||
|
}
|
||||||
|
to { -webkit-transform: rotate(-20deg);
|
||||||
|
transform: rotate(-20deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="cont_principal">
|
||||||
|
<div class="cont_error">
|
||||||
|
<h1>Oops</h1>
|
||||||
|
<p>The Page you're looking for isn't here.</p>
|
||||||
|
</div>
|
||||||
|
<div class="cont_aura_1"></div>
|
||||||
|
<div class="cont_aura_2"></div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
<script>
|
||||||
|
window.onload = function(){
|
||||||
|
document.querySelector('.cont_principal').className= "cont_principal cont_error_active";
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</html>
|
||||||
|
After Width: | Height: | Size: 1.1 KiB |
@ -0,0 +1,25 @@
|
|||||||
|
<?php
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | Copyright (c) 2006-2019 http://thinkphp.cn All rights reserved.
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | Author: liu21st <liu21st@gmail.com>
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
|
||||||
|
// [ 应用入口文件 ]
|
||||||
|
namespace think;
|
||||||
|
|
||||||
|
require __DIR__ . '/../vendor/autoload.php';
|
||||||
|
|
||||||
|
define('ROOT_PATH',$_SERVER['DOCUMENT_ROOT']);
|
||||||
|
// 执行HTTP应用并响应
|
||||||
|
$http = (new App())->http;
|
||||||
|
|
||||||
|
$response = $http->run();
|
||||||
|
|
||||||
|
$response->send();
|
||||||
|
|
||||||
|
$http->end($response);
|
||||||
@ -0,0 +1,17 @@
|
|||||||
|
<?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>
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
use think\facade\Route;
|
||||||
|
|
||||||
|
Route::get('think', function () {
|
||||||
|
return 'hello,ThinkPHP6!';
|
||||||
|
});
|
||||||
|
|
||||||
|
Route::get('hello/:name', 'index/hello');
|
||||||
@ -0,0 +1,2 @@
|
|||||||
|
*
|
||||||
|
!.gitignore
|
||||||
@ -0,0 +1,10 @@
|
|||||||
|
#!/usr/bin/env php
|
||||||
|
<?php
|
||||||
|
namespace think;
|
||||||
|
|
||||||
|
// 命令行入口文件
|
||||||
|
// 加载基础文件
|
||||||
|
require __DIR__ . '/vendor/autoload.php';
|
||||||
|
|
||||||
|
// 应用初始化
|
||||||
|
(new App())->console->run();
|
||||||
@ -0,0 +1 @@
|
|||||||
|
.idea
|
||||||
@ -0,0 +1,165 @@
|
|||||||
|
GNU LESSER GENERAL PUBLIC LICENSE
|
||||||
|
Version 3, 29 June 2007
|
||||||
|
|
||||||
|
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
|
||||||
|
This version of the GNU Lesser General Public License incorporates
|
||||||
|
the terms and conditions of version 3 of the GNU General Public
|
||||||
|
License, supplemented by the additional permissions listed below.
|
||||||
|
|
||||||
|
0. Additional Definitions.
|
||||||
|
|
||||||
|
As used herein, "this License" refers to version 3 of the GNU Lesser
|
||||||
|
General Public License, and the "GNU GPL" refers to version 3 of the GNU
|
||||||
|
General Public License.
|
||||||
|
|
||||||
|
"The Library" refers to a covered work governed by this License,
|
||||||
|
other than an Application or a Combined Work as defined below.
|
||||||
|
|
||||||
|
An "Application" is any work that makes use of an interface provided
|
||||||
|
by the Library, but which is not otherwise based on the Library.
|
||||||
|
Defining a subclass of a class defined by the Library is deemed a mode
|
||||||
|
of using an interface provided by the Library.
|
||||||
|
|
||||||
|
A "Combined Work" is a work produced by combining or linking an
|
||||||
|
Application with the Library. The particular version of the Library
|
||||||
|
with which the Combined Work was made is also called the "Linked
|
||||||
|
Version".
|
||||||
|
|
||||||
|
The "Minimal Corresponding Source" for a Combined Work means the
|
||||||
|
Corresponding Source for the Combined Work, excluding any source code
|
||||||
|
for portions of the Combined Work that, considered in isolation, are
|
||||||
|
based on the Application, and not on the Linked Version.
|
||||||
|
|
||||||
|
The "Corresponding Application Code" for a Combined Work means the
|
||||||
|
object code and/or source code for the Application, including any data
|
||||||
|
and utility programs needed for reproducing the Combined Work from the
|
||||||
|
Application, but excluding the System Libraries of the Combined Work.
|
||||||
|
|
||||||
|
1. Exception to Section 3 of the GNU GPL.
|
||||||
|
|
||||||
|
You may convey a covered work under sections 3 and 4 of this License
|
||||||
|
without being bound by section 3 of the GNU GPL.
|
||||||
|
|
||||||
|
2. Conveying Modified Versions.
|
||||||
|
|
||||||
|
If you modify a copy of the Library, and, in your modifications, a
|
||||||
|
facility refers to a function or data to be supplied by an Application
|
||||||
|
that uses the facility (other than as an argument passed when the
|
||||||
|
facility is invoked), then you may convey a copy of the modified
|
||||||
|
version:
|
||||||
|
|
||||||
|
a) under this License, provided that you make a good faith effort to
|
||||||
|
ensure that, in the event an Application does not supply the
|
||||||
|
function or data, the facility still operates, and performs
|
||||||
|
whatever part of its purpose remains meaningful, or
|
||||||
|
|
||||||
|
b) under the GNU GPL, with none of the additional permissions of
|
||||||
|
this License applicable to that copy.
|
||||||
|
|
||||||
|
3. Object Code Incorporating Material from Library Header Files.
|
||||||
|
|
||||||
|
The object code form of an Application may incorporate material from
|
||||||
|
a header file that is part of the Library. You may convey such object
|
||||||
|
code under terms of your choice, provided that, if the incorporated
|
||||||
|
material is not limited to numerical parameters, data structure
|
||||||
|
layouts and accessors, or small macros, inline functions and templates
|
||||||
|
(ten or fewer lines in length), you do both of the following:
|
||||||
|
|
||||||
|
a) Give prominent notice with each copy of the object code that the
|
||||||
|
Library is used in it and that the Library and its use are
|
||||||
|
covered by this License.
|
||||||
|
|
||||||
|
b) Accompany the object code with a copy of the GNU GPL and this license
|
||||||
|
document.
|
||||||
|
|
||||||
|
4. Combined Works.
|
||||||
|
|
||||||
|
You may convey a Combined Work under terms of your choice that,
|
||||||
|
taken together, effectively do not restrict modification of the
|
||||||
|
portions of the Library contained in the Combined Work and reverse
|
||||||
|
engineering for debugging such modifications, if you also do each of
|
||||||
|
the following:
|
||||||
|
|
||||||
|
a) Give prominent notice with each copy of the Combined Work that
|
||||||
|
the Library is used in it and that the Library and its use are
|
||||||
|
covered by this License.
|
||||||
|
|
||||||
|
b) Accompany the Combined Work with a copy of the GNU GPL and this license
|
||||||
|
document.
|
||||||
|
|
||||||
|
c) For a Combined Work that displays copyright notices during
|
||||||
|
execution, include the copyright notice for the Library among
|
||||||
|
these notices, as well as a reference directing the user to the
|
||||||
|
copies of the GNU GPL and this license document.
|
||||||
|
|
||||||
|
d) Do one of the following:
|
||||||
|
|
||||||
|
0) Convey the Minimal Corresponding Source under the terms of this
|
||||||
|
License, and the Corresponding Application Code in a form
|
||||||
|
suitable for, and under terms that permit, the user to
|
||||||
|
recombine or relink the Application with a modified version of
|
||||||
|
the Linked Version to produce a modified Combined Work, in the
|
||||||
|
manner specified by section 6 of the GNU GPL for conveying
|
||||||
|
Corresponding Source.
|
||||||
|
|
||||||
|
1) Use a suitable shared library mechanism for linking with the
|
||||||
|
Library. A suitable mechanism is one that (a) uses at run time
|
||||||
|
a copy of the Library already present on the user's computer
|
||||||
|
system, and (b) will operate properly with a modified version
|
||||||
|
of the Library that is interface-compatible with the Linked
|
||||||
|
Version.
|
||||||
|
|
||||||
|
e) Provide Installation Information, but only if you would otherwise
|
||||||
|
be required to provide such information under section 6 of the
|
||||||
|
GNU GPL, and only to the extent that such information is
|
||||||
|
necessary to install and execute a modified version of the
|
||||||
|
Combined Work produced by recombining or relinking the
|
||||||
|
Application with a modified version of the Linked Version. (If
|
||||||
|
you use option 4d0, the Installation Information must accompany
|
||||||
|
the Minimal Corresponding Source and Corresponding Application
|
||||||
|
Code. If you use option 4d1, you must provide the Installation
|
||||||
|
Information in the manner specified by section 6 of the GNU GPL
|
||||||
|
for conveying Corresponding Source.)
|
||||||
|
|
||||||
|
5. Combined Libraries.
|
||||||
|
|
||||||
|
You may place library facilities that are a work based on the
|
||||||
|
Library side by side in a single library together with other library
|
||||||
|
facilities that are not Applications and are not covered by this
|
||||||
|
License, and convey such a combined library under terms of your
|
||||||
|
choice, if you do both of the following:
|
||||||
|
|
||||||
|
a) Accompany the combined library with a copy of the same work based
|
||||||
|
on the Library, uncombined with any other library facilities,
|
||||||
|
conveyed under the terms of this License.
|
||||||
|
|
||||||
|
b) Give prominent notice with the combined library that part of it
|
||||||
|
is a work based on the Library, and explaining where to find the
|
||||||
|
accompanying uncombined form of the same work.
|
||||||
|
|
||||||
|
6. Revised Versions of the GNU Lesser General Public License.
|
||||||
|
|
||||||
|
The Free Software Foundation may publish revised and/or new versions
|
||||||
|
of the GNU Lesser General Public License from time to time. Such new
|
||||||
|
versions will be similar in spirit to the present version, but may
|
||||||
|
differ in detail to address new problems or concerns.
|
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the
|
||||||
|
Library as you received it specifies that a certain numbered version
|
||||||
|
of the GNU Lesser General Public License "or any later version"
|
||||||
|
applies to it, you have the option of following the terms and
|
||||||
|
conditions either of that published version or of any later version
|
||||||
|
published by the Free Software Foundation. If the Library as you
|
||||||
|
received it does not specify a version number of the GNU Lesser
|
||||||
|
General Public License, you may choose any version of the GNU Lesser
|
||||||
|
General Public License ever published by the Free Software Foundation.
|
||||||
|
|
||||||
|
If the Library as you received it specifies that a proxy can decide
|
||||||
|
whether future versions of the GNU Lesser General Public License shall
|
||||||
|
apply, that proxy's public statement of acceptance of any version is
|
||||||
|
permanent authorization for you to choose that version for the
|
||||||
|
Library.
|
||||||
@ -0,0 +1,2 @@
|
|||||||
|
1.1.5
|
||||||
|
2012021604
|
||||||
|
After Width: | Height: | Size: 126 B |
|
After Width: | Height: | Size: 202 B |
|
After Width: | Height: | Size: 205 B |
|
After Width: | Height: | Size: 216 B |
|
After Width: | Height: | Size: 210 B |
|
After Width: | Height: | Size: 213 B |
|
After Width: | Height: | Size: 219 B |
|
After Width: | Height: | Size: 211 B |
|
After Width: | Height: | Size: 211 B |
|
After Width: | Height: | Size: 228 B |
|
After Width: | Height: | Size: 225 B |