parent
a7691a1d1d
commit
3b9040028d
@ -0,0 +1,8 @@
|
||||
<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>
|
||||
@ -0,0 +1 @@
|
||||
deny from all
|
||||
@ -0,0 +1,12 @@
|
||||
<?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 [];
|
||||
@ -0,0 +1,41 @@
|
||||
<?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>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
// 应用公共文件
|
||||
function array_column_fix($array,$key){
|
||||
if(count($array) == count($array,1)){
|
||||
return array(0 =>$array[$key]);
|
||||
}else{
|
||||
return array_column($array,$key);
|
||||
}
|
||||
}
|
||||
function getAllowedExt($ext){
|
||||
$returnValue = "";
|
||||
foreach (json_decode($ext,true) as $key => $value) {
|
||||
$returnValue .= $value["ext"].",";
|
||||
}
|
||||
return rtrim($returnValue, ",");
|
||||
}
|
||||
function getDirName($name){
|
||||
$explode = explode("/", $name);
|
||||
return end($explode);
|
||||
}
|
||||
function getSize($bit,$array=false){
|
||||
$type = array('Bytes','KB','MB','GB','TB');
|
||||
$box = array('1','1024','1048576','1073741824','TB');
|
||||
for($i = 0; $bit >= 1024; $i++) {
|
||||
$bit/=1024;
|
||||
}
|
||||
if($array){
|
||||
return [(floor($bit*100)/100),$box[$i]];
|
||||
}
|
||||
return (floor($bit*100)/100).$type[$i];
|
||||
}
|
||||
@ -0,0 +1,53 @@
|
||||
<?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 <liu21st@gmail.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
return [
|
||||
// 数据库类型
|
||||
'type' => 'mysql',
|
||||
// 服务器地址
|
||||
'hostname' => '127.0.0.1',
|
||||
// 数据库名
|
||||
'database' => 'lite',
|
||||
// 用户名
|
||||
'username' => 'root',
|
||||
// 密码
|
||||
'password' => 'root',
|
||||
// 端口
|
||||
'hostport' => '3306',
|
||||
// 连接dsn
|
||||
'dsn' => '',
|
||||
// 数据库连接参数
|
||||
'params' => [],
|
||||
// 数据库编码默认采用utf8
|
||||
'charset' => 'utf8',
|
||||
// 数据库表前缀
|
||||
'prefix' => 'sd_',
|
||||
// 数据库调试模式
|
||||
'debug' => true,
|
||||
// 数据库部署方式:0 集中式(单一服务器),1 分布式(主从服务器)
|
||||
'deploy' => 0,
|
||||
// 数据库读写是否分离 主从式有效
|
||||
'rw_separate' => false,
|
||||
// 读写分离后 主服务器数量
|
||||
'master_num' => 1,
|
||||
// 指定从服务器序号
|
||||
'slave_no' => '',
|
||||
// 是否严格检查字段是否存在
|
||||
'fields_strict' => true,
|
||||
// 数据集返回类型
|
||||
'resultset_type' => 'array',
|
||||
// 自动写入时间戳字段
|
||||
'auto_timestamp' => false,
|
||||
// 时间字段取出后的默认时间格式
|
||||
'datetime_format' => 'Y-m-d H:i:s',
|
||||
// 是否需要进行SQL性能分析
|
||||
'sql_explain' => false,
|
||||
];
|
||||
@ -0,0 +1,53 @@
|
||||
<?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 <liu21st@gmail.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
return [
|
||||
// 数据库类型
|
||||
'type' => 'mysql',
|
||||
// 服务器地址
|
||||
'hostname' => '127.0.0.1',
|
||||
// 数据库名
|
||||
'database' => 'tp',
|
||||
// 用户名
|
||||
'username' => 'root',
|
||||
// 密码
|
||||
'password' => 'root',
|
||||
// 端口
|
||||
'hostport' => '3306',
|
||||
// 连接dsn
|
||||
'dsn' => '',
|
||||
// 数据库连接参数
|
||||
'params' => [],
|
||||
// 数据库编码默认采用utf8
|
||||
'charset' => 'utf8',
|
||||
// 数据库表前缀
|
||||
'prefix' => 'sd_',
|
||||
// 数据库调试模式
|
||||
'debug' => true,
|
||||
// 数据库部署方式:0 集中式(单一服务器),1 分布式(主从服务器)
|
||||
'deploy' => 0,
|
||||
// 数据库读写是否分离 主从式有效
|
||||
'rw_separate' => false,
|
||||
// 读写分离后 主服务器数量
|
||||
'master_num' => 1,
|
||||
// 指定从服务器序号
|
||||
'slave_no' => '',
|
||||
// 是否严格检查字段是否存在
|
||||
'fields_strict' => true,
|
||||
// 数据集返回类型
|
||||
'resultset_type' => 'array',
|
||||
// 自动写入时间戳字段
|
||||
'auto_timestamp' => false,
|
||||
// 时间字段取出后的默认时间格式
|
||||
'datetime_format' => 'Y-m-d H:i:s',
|
||||
// 是否需要进行SQL性能分析
|
||||
'sql_explain' => false,
|
||||
];
|
||||
@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
function classLoader($class)
|
||||
{
|
||||
$path = str_replace('\\', DIRECTORY_SEPARATOR, $class);
|
||||
$file = __DIR__ . '/src/' . $path . '.php';
|
||||
|
||||
if (file_exists($file)) {
|
||||
require_once $file;
|
||||
}
|
||||
}
|
||||
spl_autoload_register('classLoader');
|
||||
|
||||
require_once __DIR__ . '/src/Qiniu/functions.php';
|
||||
@ -0,0 +1,25 @@
|
||||
<?php
|
||||
function countSize($bit,$array=false){
|
||||
$type = array('Bytes','KB','MB','GB','TB');
|
||||
$box = array('1','1024','1048576','1073741824','TB');
|
||||
for($i = 0; $bit >= 1024; $i++) {
|
||||
$bit/=1024;
|
||||
}
|
||||
if($array){
|
||||
return [(floor($bit*100)/100),$box[$i]];
|
||||
}
|
||||
return (floor($bit*100)/100).$type[$i];
|
||||
}
|
||||
|
||||
function isPreview($fileName){
|
||||
$allowedSuffix=["jpg","jpeg","gif","bmp","png","svg","mp4","mp3","ogg"];
|
||||
$suffix = explode(".",$fileName);
|
||||
if(in_array(end($suffix),$allowedSuffix)){
|
||||
return "yes";
|
||||
}
|
||||
return "no";
|
||||
}
|
||||
function getDay($sec){
|
||||
return floor($sec/86400);
|
||||
}
|
||||
?>
|
||||
@ -0,0 +1,448 @@
|
||||
<?php
|
||||
namespace app\index\controller;
|
||||
|
||||
use think\Controller;
|
||||
use app\index\model\User;
|
||||
use think\Cookie;
|
||||
use think\Db;
|
||||
use \app\index\model\Option;
|
||||
use \app\index\model\AdminHandler;
|
||||
use \app\index\model\FileManage;
|
||||
|
||||
class Admin extends Controller{
|
||||
|
||||
public $userObj;
|
||||
public $siteOptions;
|
||||
public $adminObj;
|
||||
|
||||
public function _initialize(){
|
||||
$this->siteOptions = Option::getValues(["basic","admin"]);
|
||||
$this->userObj = new User(cookie('user_id'),cookie('login_key'));
|
||||
if(!$this->userObj->loginStatus){
|
||||
$this->redirect(url('/Login','',''));
|
||||
exit();
|
||||
}
|
||||
if($this->userObj->groupData["id"] != 1){
|
||||
$this->error('你无权访问此页面',403,$this->siteOptions);
|
||||
}
|
||||
$this->adminObj = new AdminHandler($this->siteOptions);
|
||||
}
|
||||
|
||||
public function index(){
|
||||
return view('admin_index', [
|
||||
'options' => $this->siteOptions,
|
||||
'statics' => $this->adminObj->getStatics(),
|
||||
]);
|
||||
}
|
||||
|
||||
public function Setting(){
|
||||
return view('basic_setting', [
|
||||
'options' => $this->siteOptions,
|
||||
]);
|
||||
}
|
||||
|
||||
public function Config(){
|
||||
$configType=input("?param.type") ? input("param.type") : "common";
|
||||
$configFile = $this->adminObj->getConfigFile($configType);
|
||||
return view('config_file', [
|
||||
'options' => $this->siteOptions,
|
||||
'type' => $configType,
|
||||
'content' => $configFile[0],
|
||||
'path' => $configFile[1],
|
||||
]);
|
||||
}
|
||||
|
||||
public function SaveConfigFile(){
|
||||
return $this->adminObj->saveConfigFile(input('post.'));
|
||||
}
|
||||
|
||||
public function SettingReg(){
|
||||
return view('reg_setting', [
|
||||
'options' => $this->siteOptions,
|
||||
'optionsForSet' => Option::getValues(["login","register"]),
|
||||
'groups' => $this->adminObj->getAvaliableGroup(),
|
||||
]);
|
||||
}
|
||||
|
||||
public function Theme(){
|
||||
$fileName=input("?param.name") ? input("param.name") : "error";
|
||||
$dir = ROOT_PATH."application/index/view/";
|
||||
if(!function_exists("scandir")){
|
||||
return "scandir被禁用";
|
||||
}
|
||||
$fileList=[];
|
||||
$fileList=$fileList+scandir($dir);
|
||||
$pathList=["/"=>$fileList];
|
||||
foreach (["admin","explore","file","home","index","member","profile","share"] as $key => $value) {
|
||||
$childPath = scandir($dir.$value."/");
|
||||
$fileList=array_merge($fileList,$childPath);
|
||||
$pathList = array_merge($pathList,[$value => $childPath]);
|
||||
}
|
||||
foreach ($fileList as $key => $value) {
|
||||
if(substr_compare($value, ".html", -strlen(".html")) != 0){
|
||||
unset($fileList[$key]);
|
||||
}
|
||||
}
|
||||
foreach($pathList as $key=>$val){
|
||||
if(in_array($fileName.".html",$val)){
|
||||
$parentPath = $key;
|
||||
break;
|
||||
}
|
||||
}
|
||||
$fileContent = file_get_contents($dir.rtrim($parentPath,"/")."/".$fileName.".html");
|
||||
return view('theme', [
|
||||
'options' => $this->siteOptions,
|
||||
'list' => $fileList,
|
||||
'content' => $fileContent,
|
||||
'path' => $parentPath,
|
||||
'name' => $fileName,
|
||||
]);
|
||||
}
|
||||
|
||||
public function SaveThemeFile(){
|
||||
return $this->adminObj->saveThemeFile(input('post.'));
|
||||
}
|
||||
|
||||
public function SettingMail(){
|
||||
return view('mail_setting', [
|
||||
'options' => $this->siteOptions,
|
||||
'optionsForSet' => Option::getValues(["mail_template","mail"]),
|
||||
]);
|
||||
}
|
||||
|
||||
public function SettingPay(){
|
||||
return view('pay_setting', [
|
||||
'options' => $this->siteOptions,
|
||||
'optionsForSet' => Option::getValues(["payment"]),
|
||||
]);
|
||||
}
|
||||
|
||||
public function SettingOther(){
|
||||
return view('other_setting', [
|
||||
'options' => $this->siteOptions,
|
||||
'optionsForSet' => Option::getValues(["file_edit","share","avatar","admin","storage_policy"]),
|
||||
]);
|
||||
}
|
||||
|
||||
public function Files(){
|
||||
$this->adminObj->listFile();
|
||||
return view('file_list', [
|
||||
'options' => $this->siteOptions,
|
||||
'groups' => $this->adminObj->getAvaliableGroup(),
|
||||
'list' => $this->adminObj->pageData,
|
||||
'originList' => $this->adminObj->listData,
|
||||
'pageNow' => $this->adminObj->pageNow,
|
||||
'pageTotal' => $this->adminObj->pageTotal,
|
||||
'dataTotal' => $this->adminObj->dataTotal,
|
||||
'policy' => $this->adminObj->getAvaliablePolicy(),
|
||||
]);
|
||||
}
|
||||
|
||||
Public function Users(){
|
||||
$this->adminObj->listUser();
|
||||
$group = $this->adminObj->getAvaliableGroup();
|
||||
return view('user_list', [
|
||||
'options' => $this->siteOptions,
|
||||
'group' => $group,
|
||||
'groups' => $group,
|
||||
'list' => $this->adminObj->pageData,
|
||||
'originList' => $this->adminObj->listData,
|
||||
'pageNow' => $this->adminObj->pageNow,
|
||||
'pageTotal' => $this->adminObj->pageTotal,
|
||||
'dataTotal' => $this->adminObj->dataTotal,
|
||||
'policy' => $this->adminObj->getAvaliablePolicy(),
|
||||
]);
|
||||
}
|
||||
|
||||
public function Shares(){
|
||||
$this->adminObj->listShare();
|
||||
return view('share_list', [
|
||||
'options' => $this->siteOptions,
|
||||
'groups' => $this->adminObj->getAvaliableGroup(),
|
||||
'list' => $this->adminObj->pageData,
|
||||
'originList' => $this->adminObj->listData,
|
||||
'pageNow' => $this->adminObj->pageNow,
|
||||
'pageTotal' => $this->adminObj->pageTotal,
|
||||
'dataTotal' => $this->adminObj->dataTotal,
|
||||
]);
|
||||
}
|
||||
|
||||
public function PolicyList(){
|
||||
$this->adminObj->listPolicy();
|
||||
return view('policy_list', [
|
||||
'options' => $this->siteOptions,
|
||||
'groups' => $this->adminObj->getAvaliableGroup(),
|
||||
'list' => $this->adminObj->pageData,
|
||||
'originList' => $this->adminObj->listData,
|
||||
'pageNow' => $this->adminObj->pageNow,
|
||||
'pageTotal' => $this->adminObj->pageTotal,
|
||||
'dataTotal' => $this->adminObj->dataTotal,
|
||||
]);
|
||||
}
|
||||
|
||||
public function GroupList(){
|
||||
$this->adminObj->listGroup();
|
||||
return view('group_list', [
|
||||
'options' => $this->siteOptions,
|
||||
'list' => $this->adminObj->pageData,
|
||||
'originList' => $this->adminObj->listData,
|
||||
'pageNow' => $this->adminObj->pageNow,
|
||||
'pageTotal' => $this->adminObj->pageTotal,
|
||||
'dataTotal' => $this->adminObj->dataTotal,
|
||||
]);
|
||||
}
|
||||
|
||||
public function OrderList(){
|
||||
$this->adminObj->listOrder();
|
||||
return view('order_list', [
|
||||
'options' => $this->siteOptions,
|
||||
'list' => $this->adminObj->pageData,
|
||||
'originList' => $this->adminObj->listData,
|
||||
'pageNow' => $this->adminObj->pageNow,
|
||||
'pageTotal' => $this->adminObj->pageTotal,
|
||||
'dataTotal' => $this->adminObj->dataTotal,
|
||||
]);
|
||||
}
|
||||
|
||||
public function SaveBasicSetting(){
|
||||
return $this->adminObj->saveBasicSetting(input('post.'));
|
||||
}
|
||||
|
||||
public function SaveRegSetting(){
|
||||
return $this->adminObj->saveRegSetting(input('post.'));
|
||||
}
|
||||
|
||||
public function SaveMailSetting(){
|
||||
return $this->adminObj->saveMailSetting(input('post.'));
|
||||
}
|
||||
|
||||
public function SendTestMail(){
|
||||
return $this->adminObj->sendTestMail(input('post.'));
|
||||
}
|
||||
|
||||
public function SaveMailTemplate(){
|
||||
return $this->adminObj->saveMailTemplate(input('post.'));
|
||||
}
|
||||
|
||||
public function GetFileInfo(){
|
||||
return $this->adminObj->getFileInfo(input('post.id'));
|
||||
}
|
||||
|
||||
public function GetUserInfo(){
|
||||
return $this->adminObj->getUserInfo(input('post.id'));
|
||||
}
|
||||
|
||||
public function savePolicy(){
|
||||
return $this->adminObj->addPolicy(input('post.'));
|
||||
}
|
||||
|
||||
public function SaveEditPolicy(){
|
||||
return $this->adminObj->editPolicy(input('post.'));
|
||||
}
|
||||
|
||||
public function SaveGroup(){
|
||||
return $this->adminObj->saveGroup(input('post.'));
|
||||
}
|
||||
|
||||
public function AddPack(){
|
||||
return $this->adminObj->addPack(input('post.'));
|
||||
}
|
||||
|
||||
public function AddGroupPurchase(){
|
||||
return $this->adminObj->addGroupPurchase(input('post.'));
|
||||
}
|
||||
|
||||
public function SaveCron(){
|
||||
$this->adminObj->saveCron(input('post.'));
|
||||
$this->redirect("/Admin/Cron",302);
|
||||
}
|
||||
|
||||
public function SaveUser(){
|
||||
return $this->adminObj->saveUser(input('post.'));
|
||||
}
|
||||
|
||||
public function BanUser(){
|
||||
return $this->adminObj->banUser(input('post.id'),$this->userObj->uid);
|
||||
}
|
||||
|
||||
public function AddUser(){
|
||||
return $this->adminObj->addUser(input('post.'));
|
||||
}
|
||||
|
||||
public function Preview(){
|
||||
$fileId = input('param.id');
|
||||
$fileRecord = Db::name("files")->where("id",$fileId)->find();
|
||||
$fileObj = new FileManage(rtrim($fileRecord["dir"],"/")."/".$fileRecord["orign_name"],$fileRecord["upload_user"]);
|
||||
$previewHandler = $fileObj->PreviewHandler(true);
|
||||
if($previewHandler[0]){
|
||||
$this->redirect($previewHandler[1],302);
|
||||
}
|
||||
}
|
||||
|
||||
public function Download(){
|
||||
$fileId = input('param.id');
|
||||
$fileRecord = Db::name("files")->where("id",$fileId)->find();
|
||||
$fileObj = new FileManage(rtrim($fileRecord["dir"],"/")."/".$fileRecord["orign_name"],$fileRecord["upload_user"]);
|
||||
$FileHandler = $fileObj->Download(true);
|
||||
if($FileHandler[0]){
|
||||
$this->redirect($FileHandler[1],302);
|
||||
}
|
||||
}
|
||||
|
||||
public function Delete(){
|
||||
return $this->adminObj->deleteSingle(input('post.id'));
|
||||
}
|
||||
|
||||
public function DeleteShare(){
|
||||
return $this->adminObj->deleteShare([0=>input('post.id')]);
|
||||
}
|
||||
|
||||
public function DeleteShareMultiple(){
|
||||
return $this->adminObj->deleteShare(json_decode(input('post.id'),true));
|
||||
}
|
||||
|
||||
public function DeleteMultiple(){
|
||||
return $this->adminObj->deleteMultiple(input('post.id'));
|
||||
}
|
||||
|
||||
public function DeletePolicy(){
|
||||
return $this->adminObj->deletePolicy(input('post.id'));
|
||||
}
|
||||
|
||||
public function DeleteGroup(){
|
||||
return $this->adminObj->deleteGroup(input('post.id'));
|
||||
}
|
||||
|
||||
public function DeleteOrder(){
|
||||
return $this->adminObj->deleteOrder(input('post.id'));
|
||||
}
|
||||
|
||||
public function ChangeShareType(){
|
||||
return $this->adminObj->changeShareType(input('post.id'));
|
||||
}
|
||||
|
||||
public function DeletePack(){
|
||||
return $this->adminObj->deletePack(input('post.id'));
|
||||
}
|
||||
|
||||
public function DeleteGroupPurchase(){
|
||||
return $this->adminObj->deleteGroupPurchase(input('post.id'));
|
||||
}
|
||||
|
||||
public function DeleteUser(){
|
||||
return $this->adminObj->deleteUser(input('post.id'),$this->userObj->uid);
|
||||
}
|
||||
|
||||
public function DeleteUsers(){
|
||||
$uidGroup = json_decode(input('post.id'),true);
|
||||
foreach ($uidGroup as $key => $value) {
|
||||
$this->adminObj->deleteUser($value,$this->userObj->uid);
|
||||
}
|
||||
return ["error"=>false,"msg"=>"删除成功"];
|
||||
}
|
||||
|
||||
public function SwitchColor(){
|
||||
$colorNow = Option::getValues(["admin"]);
|
||||
if($colorNow["admin_color_body"] == "fixed-nav sticky-footer bg-light"){
|
||||
$colorNew = [
|
||||
"admin_color_body" => "fixed-nav sticky-footer bg-dark",
|
||||
"admin_color_nav" => "navbar navbar-expand-lg fixed-top navbar-dark bg-dark",
|
||||
];
|
||||
}else{
|
||||
$colorNew = [
|
||||
"admin_color_body" => "fixed-nav sticky-footer bg-light",
|
||||
"admin_color_nav" => "navbar navbar-expand-lg fixed-top navbar-light bg-light",
|
||||
];
|
||||
}
|
||||
foreach ($colorNew as $key => $value) {
|
||||
Db::name("options")->where("option_name",$key)->update(["option_value" => $value]);
|
||||
}
|
||||
}
|
||||
|
||||
public function EditPolicy(){
|
||||
$policyId = input('param.id');
|
||||
$policyRecord = Db::name("policy")->where("id",$policyId)->find();
|
||||
return view('edit_policy', [
|
||||
'options' => $this->siteOptions,
|
||||
'policy' => $policyRecord,
|
||||
]);
|
||||
}
|
||||
|
||||
public function EditGroup(){
|
||||
$groupId = input('param.id');
|
||||
$groupRecord = Db::name("groups")->where("id",$groupId)->find();
|
||||
return view('edit_group', [
|
||||
'options' => $this->siteOptions,
|
||||
'group' => $groupRecord,
|
||||
'policy' => $this->adminObj->getAvaliablePolicy(),
|
||||
]);
|
||||
}
|
||||
|
||||
public function AddGroup(){
|
||||
return $this->adminObj->addGroup(input('post.'));
|
||||
}
|
||||
|
||||
public function PolicyAdd(){
|
||||
return view('add_policy', [
|
||||
'options' => $this->siteOptions,
|
||||
]);
|
||||
}
|
||||
|
||||
public function Cron(){
|
||||
$cronData = Db::name("corn")->select();
|
||||
$neverExcute = true;
|
||||
foreach ($cronData as $key => $value) {
|
||||
if($value["last_excute"] !=0){
|
||||
$neverExcute = false;
|
||||
}
|
||||
}
|
||||
return view('cron_list', [
|
||||
'options' => $this->siteOptions,
|
||||
'cron' => $cronData,
|
||||
'neverExcute' => $neverExcute,
|
||||
]);
|
||||
}
|
||||
|
||||
public function PolicyAddS3(){
|
||||
return view('add_policy_s3', [
|
||||
'options' => $this->siteOptions,
|
||||
]);
|
||||
}
|
||||
|
||||
public function About(){
|
||||
$verison = json_decode(file_get_contents(ROOT_PATH . "application/version.json"),true);
|
||||
return view('about', [
|
||||
'options' => $this->siteOptions,
|
||||
'programVersion' => $verison,
|
||||
"dbsVersion" => Option::getValue("database_version"),
|
||||
]);
|
||||
}
|
||||
|
||||
public function Purchase(){
|
||||
$packData = json_decode(Option::getValue("pack_data"),true);
|
||||
return view('purchase', [
|
||||
'options' => $this->siteOptions,
|
||||
'pack' => $packData,
|
||||
]);
|
||||
}
|
||||
|
||||
public function PurchaseGroup(){
|
||||
$groupData = json_decode(Option::getValue("group_sell_data"),true);
|
||||
foreach ($groupData as $key => $value) {
|
||||
$groupData[$key]["group"] = Db::name("groups")->where("id",$value["goup_id"])->find();
|
||||
}
|
||||
return view('purchase_group', [
|
||||
'options' => $this->siteOptions,
|
||||
'group' => $groupData,
|
||||
'group_list' => $this->adminObj->getAvaliableGroup(),
|
||||
]);
|
||||
}
|
||||
|
||||
public function GroupAdd(){
|
||||
return view('add_group', [
|
||||
'options' => $this->siteOptions,
|
||||
'policy' => $this->adminObj->getAvaliablePolicy(),
|
||||
]);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,84 @@
|
||||
<?php
|
||||
namespace app\index\controller;
|
||||
|
||||
use think\Controller;
|
||||
use think\Db;
|
||||
use think\Request;
|
||||
use \app\index\model\CallbackHandler;
|
||||
use \app\index\model\User;
|
||||
use \app\index\model\Option;
|
||||
use \app\index\model\FileManage;
|
||||
use think\Session;
|
||||
|
||||
class Callback extends Controller{
|
||||
|
||||
public function index(){
|
||||
return "";
|
||||
}
|
||||
|
||||
public function Qiniu(){
|
||||
ob_end_clean();
|
||||
header('Content-Type: application/json');
|
||||
$handllerObj = new CallbackHandler(file_get_contents("php://input"));
|
||||
$handllerObj -> qiniuHandler(Request::instance()->header('Authorization'));
|
||||
}
|
||||
|
||||
public function Oss(){
|
||||
ob_end_clean();
|
||||
header('Content-Type: application/json');
|
||||
$handllerObj = new CallbackHandler(file_get_contents("php://input"));
|
||||
$handllerObj -> ossHandler(Request::instance()->header('Authorization'),Request::instance()->header('x-oss-pub-key-url'));
|
||||
}
|
||||
|
||||
public function TmpPreview(){
|
||||
$basicOptions = Option::getValues(['basic']);
|
||||
$params = explode(":",input("param.key"));
|
||||
$fileData = Db::name("files")->where("id",$params[0])->find();
|
||||
if (empty($fileData)){
|
||||
abort(404);
|
||||
}
|
||||
$userData = Db::name("users")->where("id",$fileData["upload_user"])->find();
|
||||
if(md5($userData["user_pass"].$fileData["id"].$params[1].config("salt")) != $params[2] || time()<$params[0]){
|
||||
abort(403);
|
||||
}
|
||||
$fileObj = new FileManage(rtrim($fileData["dir"],"/")."/".$fileData["orign_name"],$userData["id"]);
|
||||
$Redirect = $fileObj->PreviewHandler();
|
||||
}
|
||||
|
||||
public function Upyun(){
|
||||
$signToken = Request::instance()->header('Authorization');
|
||||
$reqDate = Request::instance()->header('Date');
|
||||
$contentMd5 = Request::instance()->header('Content-MD5');
|
||||
ob_end_clean();
|
||||
header('Content-Type: application/json');
|
||||
$callbackData = [
|
||||
"code" => input("post.code"),
|
||||
"file_size" => input("post.file_size"),
|
||||
"url" => input("post.url"),
|
||||
"image-width" => input("post.image-width"),
|
||||
"image-height" => input("post.image-height"),
|
||||
"ext-param" => json_decode(input("post.ext-param"),true),
|
||||
];
|
||||
$handllerObj = new CallbackHandler($callbackData);
|
||||
$handllerObj -> upyunHandler($signToken,$reqDate,$contentMd5);
|
||||
}
|
||||
|
||||
public function S3(){
|
||||
$request = Request::instance();
|
||||
if($request->method() == "OPTIONS"){
|
||||
ob_end_clean();
|
||||
header("Access-Control-Allow-Origin: *");
|
||||
exit();
|
||||
}
|
||||
ob_end_clean();
|
||||
header("Access-Control-Allow-Origin: *");
|
||||
$callbackKey = input("param.key");
|
||||
$callbackData = [
|
||||
"bucket" => input("get.bucket"),
|
||||
"key" => input("get.key"),
|
||||
];
|
||||
$handllerObj = new CallbackHandler($callbackData);
|
||||
$handllerObj -> s3Handler($callbackKey);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,17 @@
|
||||
<?php
|
||||
namespace app\index\controller;
|
||||
|
||||
use think\Controller;
|
||||
use think\Db;
|
||||
use think\Request;
|
||||
use \app\index\model\CronHandler;
|
||||
use think\Session;
|
||||
|
||||
class Cron extends Controller{
|
||||
|
||||
public function index(){
|
||||
$cornObj = new CronHandler();
|
||||
$cornObj->Doit();
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,60 @@
|
||||
<?php
|
||||
namespace app\index\controller;
|
||||
|
||||
use think\Controller;
|
||||
use app\index\model\User;
|
||||
use think\Cookie;
|
||||
use think\Db;
|
||||
use \app\index\model\Option;
|
||||
|
||||
class Explore extends Controller{
|
||||
|
||||
public $visitorObj;
|
||||
public $userObj;
|
||||
public $siteOptions;
|
||||
|
||||
public function _initialize(){
|
||||
$this->siteOptions = Option::getValues(["basic"]);
|
||||
}
|
||||
|
||||
public function Search(){
|
||||
$this->visitorObj = new User(cookie('user_id'),cookie('login_key'));
|
||||
return view("search",[
|
||||
"options" => $this->siteOptions,
|
||||
'loginStatus' => $this->visitorObj->loginStatus,
|
||||
'userData' => $this->visitorObj->userSQLData,
|
||||
]);
|
||||
}
|
||||
|
||||
public function S(){
|
||||
$this->visitorObj = new User(cookie('user_id'),cookie('login_key'));
|
||||
$keyWords=input("param.key");
|
||||
if(empty($keyWords)){
|
||||
$this->redirect('/Explore/Search',302);
|
||||
}
|
||||
$list = Db::name('shares')
|
||||
->where('type',"public")
|
||||
->where('origin_name',"like","%".$keyWords."%")
|
||||
->order('id DESC')
|
||||
->paginate(10);
|
||||
$listData = $list->all();
|
||||
foreach ($listData as $key => $value) {
|
||||
if($value["source_type"]=="file"){
|
||||
$listData[$key]["fileData"] = $value["origin_name"];
|
||||
|
||||
}else{
|
||||
$pathDir = explode("/",$value["source_name"]);
|
||||
$listData[$key]["fileData"] = end($pathDir);
|
||||
}
|
||||
}
|
||||
return view("result",[
|
||||
"options" => $this->siteOptions,
|
||||
'loginStatus' => $this->visitorObj->loginStatus,
|
||||
'userData' => $this->visitorObj->userSQLData,
|
||||
'list' => $listData,
|
||||
'listOrigin' => $list,
|
||||
'keyWords' => $keyWords,
|
||||
]);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,175 @@
|
||||
<?php
|
||||
namespace app\index\controller;
|
||||
|
||||
use think\Controller;
|
||||
use think\Db;
|
||||
use think\Request;
|
||||
use \app\index\model\Option;
|
||||
use \app\index\model\User;
|
||||
use \app\index\model\FileManage;
|
||||
use \app\index\model\ShareHandler;
|
||||
use think\Session;
|
||||
|
||||
|
||||
class File extends Controller{
|
||||
|
||||
public $userObj;
|
||||
|
||||
/**
|
||||
* [_initialize description]
|
||||
* @return [type] [description]
|
||||
*/
|
||||
public function _initialize(){
|
||||
$this->userObj = new User(cookie('user_id'),cookie('login_key'));
|
||||
if(!$this->userObj->loginStatus){
|
||||
echo "Bad request";
|
||||
exit();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* [index description]
|
||||
* @Author Aaron
|
||||
* @DateTime 2017-07-03
|
||||
* @return [type] [description]
|
||||
*/
|
||||
public function index(){
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* [List description]
|
||||
* @Author Aaron
|
||||
* @DateTime 2017-07-03
|
||||
*/
|
||||
public function ListFile(){
|
||||
$reqPath = stripslashes(json_decode(file_get_contents("php://input"),true)['path']);
|
||||
return FileManage::ListFile($reqPath,$this->userObj->uid);
|
||||
}
|
||||
|
||||
public function Delete(){
|
||||
$reqPath = json_decode(file_get_contents("php://input"),true)['items'];
|
||||
$dirPath = json_decode(file_get_contents("php://input"),true)['dirs'];
|
||||
FileManage::DirDeleteHandler($dirPath,$this->userObj->uid);
|
||||
return FileManage::DeleteHandler($reqPath,$this->userObj->uid);
|
||||
}
|
||||
|
||||
public function Move(){
|
||||
$reqPath = json_decode(file_get_contents("php://input"),true)['items'];
|
||||
$dirPath = json_decode(file_get_contents("php://input"),true)['dirs'];
|
||||
$newPath = json_decode(file_get_contents("php://input"),true)['newPath'];
|
||||
return FileManage::MoveHandler($reqPath,$dirPath,$newPath,$this->userObj->uid);
|
||||
}
|
||||
|
||||
public function Rename(){
|
||||
$reqPath = json_decode(file_get_contents("php://input"),true)['item'];
|
||||
$newPath = json_decode(file_get_contents("php://input"),true)['newItemPath'];
|
||||
return FileManage::RenameHandler($reqPath,$newPath,$this->userObj->uid);
|
||||
}
|
||||
|
||||
public function Preview(){
|
||||
$reqPath = $_GET["path"];
|
||||
$fileObj = new FileManage($reqPath,$this->userObj->uid);
|
||||
$Redirect = $fileObj->PreviewHandler();
|
||||
if($Redirect[0]){
|
||||
$this->redirect($Redirect[1],302);
|
||||
}
|
||||
}
|
||||
|
||||
public function ListPic(){
|
||||
$reqPath = $_GET["path"];
|
||||
return FileManage::listPic($reqPath,$this->userObj->uid);
|
||||
}
|
||||
|
||||
public function Download(){
|
||||
$reqPath = $_GET["path"];
|
||||
$fileObj = new FileManage($reqPath,$this->userObj->uid);
|
||||
$FileHandler = $fileObj->Download();
|
||||
if($FileHandler[0]){
|
||||
$this->redirect($FileHandler[1],302);
|
||||
}
|
||||
}
|
||||
|
||||
public function Share(){
|
||||
$reqPath = json_decode(file_get_contents("php://input"),true)['item'];
|
||||
$shareType = json_decode(file_get_contents("php://input"),true)['shareType'];
|
||||
ShareHandler::createShare($reqPath,$shareType,$this->userObj->getSQLData(),$this->userObj->getGroupData());
|
||||
}
|
||||
|
||||
public function gerSource(){
|
||||
$reqPath = $_POST["path"];
|
||||
$fileObj = new FileManage($reqPath,$this->userObj->uid);
|
||||
$FileHandler = $fileObj->Source();
|
||||
}
|
||||
|
||||
public function Content(){
|
||||
$reqPath = json_decode(file_get_contents("php://input"),true)['item'];
|
||||
$fileObj = new FileManage($reqPath,$this->userObj->uid);
|
||||
$FileHandler = $fileObj->getContent();
|
||||
}
|
||||
|
||||
public function Edit(){
|
||||
$reqPath = json_decode(file_get_contents("php://input"),true)['item'];
|
||||
$fileContent = json_decode(file_get_contents("php://input"),true)['content'];
|
||||
$fileObj = new FileManage($reqPath,$this->userObj->uid);
|
||||
$FileHandler = $fileObj->saveContent($fileContent);
|
||||
}
|
||||
|
||||
public function OssDownload(){
|
||||
return view('oss_download', [
|
||||
'url' => urldecode(input("get.url")),
|
||||
'name' => urldecode(input("get.name")),
|
||||
]);
|
||||
}
|
||||
|
||||
public function DocPreview(){
|
||||
$filePath = input("get.path");
|
||||
$fileObj = new FileManage($filePath,$this->userObj->uid);
|
||||
$tmpUrl = $fileObj->signTmpUrl();
|
||||
$this->redirect("http://view.officeapps.live.com/op/view.aspx?src=".urlencode($tmpUrl),302);
|
||||
}
|
||||
|
||||
public function Thumb(){
|
||||
$filePath = input("get.path");
|
||||
if(input("get.isImg") != "true"){
|
||||
return "";
|
||||
}
|
||||
$fileObj = new FileManage($filePath,$this->userObj->uid);
|
||||
$Redirect = $fileObj->getThumb();
|
||||
if($Redirect[0]){
|
||||
$this->redirect($Redirect[1],302);
|
||||
}
|
||||
}
|
||||
|
||||
public function GoogleDocPreview(){
|
||||
$filePath = input("get.path");
|
||||
$fileObj = new FileManage($filePath,$this->userObj->uid);
|
||||
$tmpUrl = $fileObj->signTmpUrl();
|
||||
$this->redirect("https://docs.google.com/viewer?url=".urlencode($tmpUrl),302);
|
||||
}
|
||||
|
||||
/**
|
||||
* [createFolder description]
|
||||
* @Author Aaron
|
||||
* @DateTime 2017-07-03
|
||||
* @return [type] [description]
|
||||
*/
|
||||
public function createFolder(){
|
||||
$reqPath = stripslashes(json_decode(file_get_contents("php://input"),true)['newPath']);
|
||||
$pathSplit = explode("/",$reqPath);
|
||||
$dirName = end($pathSplit);
|
||||
$dirPosition="/";
|
||||
foreach ($pathSplit as $key => $value) {
|
||||
if (empty($value)){
|
||||
|
||||
}else if($key == (count($pathSplit)-2)){
|
||||
$dirPosition = $dirPosition.$value;
|
||||
}else if($key == (count($pathSplit)-1)){
|
||||
}else{
|
||||
$dirPosition = $dirPosition.$value."/";
|
||||
}
|
||||
|
||||
}
|
||||
return FileManage::createFolder($dirName,$dirPosition,$this->userObj->uid);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,75 @@
|
||||
<?php
|
||||
namespace app\index\controller;
|
||||
|
||||
use think\Controller;
|
||||
use think\Db;
|
||||
use \app\index\model\Option;
|
||||
use \app\index\model\User;
|
||||
use think\Session;
|
||||
|
||||
class Home extends Controller{
|
||||
|
||||
public $userObj;
|
||||
|
||||
public function _initialize(){
|
||||
$this->userObj = new User(cookie('user_id'),cookie('login_key'));
|
||||
if(!$this->userObj->loginStatus){
|
||||
$this->redirect(url('/Login','',''));
|
||||
exit();
|
||||
}
|
||||
}
|
||||
|
||||
public function index(){
|
||||
$userInfo = $this->userObj->getInfo();
|
||||
$policyData = $this->userObj->getPolicy();
|
||||
$groupData = $this->userObj->getGroupData();
|
||||
$extJson = json_decode($policyData["filetype"],true);
|
||||
$extLimit="";
|
||||
foreach ($extJson as $key => $value) {
|
||||
$extLimit.='{ title : "'.$value["title"].'", extensions : "'.$value["ext"].'" },';
|
||||
}
|
||||
$policyData["max_size"] = $policyData["max_size"]/(1024*1024);
|
||||
return view('home', [
|
||||
'options' => Option::getValues(['basic','upload']),
|
||||
'userInfo' => $userInfo,
|
||||
'extLimit' => $extLimit,
|
||||
'policyData' => $policyData,
|
||||
'groupData' => $groupData,
|
||||
]);
|
||||
}
|
||||
|
||||
public function Album(){
|
||||
$userInfo = $this->userObj->getInfo();
|
||||
$list = Db::name("files")->where("upload_user",$this->userObj->uid)
|
||||
->where(function ($query) {
|
||||
$query->where('orign_name', "like","%jpg")
|
||||
->whereor('orign_name', "like","%png")
|
||||
->whereor('orign_name', "like","%gif")
|
||||
->whereor('orign_name', "like","%bmp");
|
||||
})
|
||||
->order('id DESC')
|
||||
->paginate(9);
|
||||
$pageCount = ceil(Db::name("files")->where("upload_user",$this->userObj->uid)
|
||||
->where(function ($query) {
|
||||
$query->where('orign_name', "like","%jpg")
|
||||
->whereor('orign_name', "like","%png")
|
||||
->whereor('orign_name', "like","%gif")
|
||||
->whereor('orign_name', "like","%bmp");
|
||||
})
|
||||
->order('id DESC')->count()/9);
|
||||
$listData = $list->all();
|
||||
$pageNow = input("?get.page")?input("get.page"):1;
|
||||
if($pageNow>$pageCount){
|
||||
$this->error('页面不存在',404,Option::getValues(['basic','group_sell']));
|
||||
}
|
||||
return view('album', [
|
||||
'options' => Option::getValues(['basic','group_sell']),
|
||||
'userInfo' => $userInfo,
|
||||
'list' => $listData,
|
||||
'listOrigin' => $list,
|
||||
'pageCount' => $pageCount,
|
||||
'page' => $pageNow,
|
||||
]);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,23 @@
|
||||
<?php
|
||||
namespace app\index\controller;
|
||||
|
||||
use think\Controller;
|
||||
use think\Db;
|
||||
use \app\index\model\Option;
|
||||
use \app\index\model\User;
|
||||
|
||||
class Index extends Controller{
|
||||
|
||||
public $userObj;
|
||||
|
||||
public function index(){
|
||||
|
||||
$this->userObj = new User(cookie('user_id'),cookie('login_key'));
|
||||
$userInfo = $this->userObj->getInfo();
|
||||
return view('index', [
|
||||
'options' => Option::getValues(['basic']),
|
||||
'userInfo' => $userInfo,
|
||||
]);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,300 @@
|
||||
<?php
|
||||
namespace app\index\controller;
|
||||
|
||||
use think\Controller;
|
||||
use app\index\model\User;
|
||||
use think\Cookie;
|
||||
use think\Db;
|
||||
use \app\index\model\Option;
|
||||
use \app\index\model\Avatar;
|
||||
use \PHPGangsta_GoogleAuthenticator;
|
||||
use \app\index\model\TwoFactor;
|
||||
|
||||
class Member extends Controller{
|
||||
|
||||
public $userObj;
|
||||
|
||||
/**
|
||||
* [index description]
|
||||
* @return [type] [description]
|
||||
*/
|
||||
public function index(){
|
||||
echo "hello";
|
||||
}
|
||||
|
||||
/**
|
||||
* [Register description]
|
||||
*/
|
||||
public function Register(){
|
||||
if(input('?post.username-reg') && input('?post.password-reg')){
|
||||
$regAction = User::register(input('post.username-reg'),input('post.password-reg'),input('post.captchaCode'));
|
||||
if ($regAction[0]){
|
||||
return json(['code' => '200','message' => $regAction[1]]);
|
||||
}else{
|
||||
return json(['code' => '1','message' => $regAction[1]]);
|
||||
}
|
||||
}else{
|
||||
return json(['code' => '1','message' => "信息不完整"]);
|
||||
}
|
||||
}
|
||||
|
||||
public function ForgetPwd(){
|
||||
if(input('?post.regEmail') && input('?post.captchaCode') && !empty(input('post.captchaCode')) && !empty(input('post.regEmail'))){
|
||||
$findAction = User::findPwd(input('post.regEmail'),input('post.captchaCode'));
|
||||
if ($findAction[0]){
|
||||
return json(['code' => '200','message' => $findAction[1]]);
|
||||
}else{
|
||||
return json(['code' => '1','message' => $findAction[1]]);
|
||||
}
|
||||
}else{
|
||||
return json(['code' => '1','message' => "信息不完整"]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* [Login description]
|
||||
*/
|
||||
public function Login(){
|
||||
if(input('?post.userMail') && input('?post.userPass')){
|
||||
$logAction = User::login(input('post.userMail'),input('post.userPass'),input('post.captchaCode'));
|
||||
if ($logAction[0]){
|
||||
return json(['code' => '200','message' => '登陆成功']);
|
||||
}else{
|
||||
return json(['code' => '1','message' => $logAction[1]]);
|
||||
}
|
||||
}else{
|
||||
return json(['code' => '1','message' => "信息不完整"]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* [LogOut description]
|
||||
*/
|
||||
public function LogOut(){
|
||||
$this->userObj = new User(cookie('user_id'),cookie('login_key'));
|
||||
$this->userObj->clear();
|
||||
$this->redirect("/Login",302);
|
||||
|
||||
}
|
||||
|
||||
public function Memory(){
|
||||
$this->userObj = new User(cookie('user_id'),cookie('login_key'));
|
||||
$this->userObj->getMemory();
|
||||
}
|
||||
|
||||
public function LoginForm(){
|
||||
$this->userObj = new User(cookie('user_id'),cookie('login_key'));
|
||||
$this->isLoginStatusCheck();
|
||||
return view('login', [
|
||||
'options' => Option::getValues(['basic']),
|
||||
'RegOptions' => Option::getValues(['register','login']),
|
||||
'loginStatus' => $this->userObj->loginStatus,
|
||||
]);
|
||||
}
|
||||
|
||||
public function TwoStepCheck(){
|
||||
$checkCode = input("post.code");
|
||||
if(empty($checkCode)){
|
||||
return json(['code' => '1','message' => "验证码不能为空"]);
|
||||
}
|
||||
$userId = session("user_id_tmp");
|
||||
$userData = Db::name('users')->where('id',$userId)->find();
|
||||
$ga = new PHPGangsta_GoogleAuthenticator();
|
||||
$checkResult = $ga->verifyCode($userData["two_step"], $checkCode, 2);
|
||||
if($checkResult) {
|
||||
cookie('user_id',session("user_id_tmp"),604800);
|
||||
cookie('login_status',session("login_status_tmp"),604800);
|
||||
cookie('login_key',session("login_key_tmp"),604800);
|
||||
return json(['code' => '200','message' => '登陆成功']);
|
||||
}else{
|
||||
return json(['code' => '1','message' => "验证失败"]);
|
||||
}
|
||||
}
|
||||
|
||||
public function TwoStep(){
|
||||
$this->userObj = new User(cookie('user_id'),cookie('login_key'));
|
||||
$this->isLoginStatusCheck();
|
||||
return view('two_step', [
|
||||
'options' => Option::getValues(['basic']),
|
||||
'RegOptions' => Option::getValues(['register','login']),
|
||||
'loginStatus' => $this->userObj->loginStatus,
|
||||
]);
|
||||
}
|
||||
|
||||
public function setWebdavPwd(){
|
||||
$this->userObj = new User(cookie('user_id'),cookie('login_key'));
|
||||
$this->loginStatusCheck();
|
||||
Db::name("users")->where("id",$this->userObj->uid)
|
||||
->update([
|
||||
"webdav_key" => md5($this->userObj->userSQLData["user_email"].":CloudreveWebDav:".input("post.pwd")),
|
||||
]);
|
||||
return json(['error' => '200','msg' => '设置成功']);
|
||||
}
|
||||
|
||||
public function emailActivate(){
|
||||
$activationKey = input('param.key');
|
||||
$basicOptions = Option::getValues(['basic']);
|
||||
$this->userObj = new User(cookie('user_id'),cookie('login_key'));
|
||||
$this->isLoginStatusCheck();
|
||||
$activeAction = User::activicateUser($activationKey);
|
||||
if($activeAction[0]){
|
||||
return view('active_user', [
|
||||
'options' => $basicOptions,
|
||||
'loginStatus' => $this->userObj->loginStatus,
|
||||
]);
|
||||
}else{
|
||||
$this->error($activeAction[1],403,$basicOptions);
|
||||
}
|
||||
}
|
||||
|
||||
public function resetPwd(){
|
||||
$resetKey = input('param.key');
|
||||
$userId = input('get.uid');
|
||||
$basicOptions = Option::getValues(['basic']);
|
||||
$this->userObj = new User(cookie('user_id'),cookie('login_key'));
|
||||
$this->isLoginStatusCheck();
|
||||
$resetAction = User::resetUser($resetKey,$userId);
|
||||
if($resetAction[0]){
|
||||
return view('reset_user', [
|
||||
'options' => $basicOptions,
|
||||
'loginStatus' => $this->userObj->loginStatus,
|
||||
'key' => $resetKey."_".$userId,
|
||||
]);
|
||||
}else{
|
||||
$this->error($resetAction[1],403,$basicOptions);
|
||||
}
|
||||
}
|
||||
|
||||
public function Reset(){
|
||||
$newPwd = input('post.pwd');
|
||||
$resetKey = input('post.key');
|
||||
$resetAction = User::resetPwd($resetKey,$newPwd);
|
||||
if($resetAction[0]){
|
||||
return json(['code' => '200','message' => '重设成功,请前往登录页登录']);
|
||||
}else{
|
||||
return json(['code' => '1','message' => $resetAction[1]]);
|
||||
}
|
||||
}
|
||||
|
||||
public function Setting(){
|
||||
$this->userObj = new User(cookie('user_id'),cookie('login_key'));
|
||||
$userInfo = $this->userObj->getInfo();
|
||||
$this->loginStatusCheck();
|
||||
$policyList=[];
|
||||
foreach (explode(",",$this->userObj->groupData["policy_list"]) as $key => $value) {
|
||||
$policyList[$key] = $value;
|
||||
}
|
||||
$avaliablePolicy = Db::name("policy")->where("id","in",$policyList)->select();
|
||||
$basicOptions = Option::getValues(['basic']);
|
||||
return view('setting', [
|
||||
'options' => $basicOptions,
|
||||
'userInfo' => $userInfo,
|
||||
'userSQL' => $this->userObj->userSQLData,
|
||||
'groupData' => $this->userObj->groupData,
|
||||
'loginStatus' => $this->userObj->loginStatus,
|
||||
'avaliablePolicy' => $avaliablePolicy,
|
||||
]);
|
||||
}
|
||||
|
||||
public function SaveAvatar(){
|
||||
$this->userObj = new User(cookie('user_id'),cookie('login_key'));
|
||||
$file = request()->file("avatar");
|
||||
$avatarObj = new Avatar(true,$file);
|
||||
if(!$avatarObj->SaveAvatar()){
|
||||
return json_encode($avatarObj->errorMsg);
|
||||
}else{
|
||||
$avatarObj->bindUser($this->userObj->uid);
|
||||
return json_encode(["result" => "success"]);
|
||||
}
|
||||
}
|
||||
|
||||
public function Avatar(){
|
||||
if(!input("get.cache")=="no"){
|
||||
header("Cache-Control: max-age=10800");
|
||||
}
|
||||
$userId = input("param.uid");
|
||||
$avatarObj = new Avatar(false,$userId);
|
||||
$avatarImg = $avatarObj->Out(input("param.size"));
|
||||
$this->redirect($avatarImg,302);
|
||||
}
|
||||
|
||||
public function SetGravatar(){
|
||||
$this->userObj = new User(cookie('user_id'),cookie('login_key'));
|
||||
$avatarObj = new Avatar(false,$this->userObj->uid);
|
||||
$avatarObj->setGravatar();
|
||||
}
|
||||
|
||||
public function Nick(){
|
||||
$this->userObj = new User(cookie('user_id'),cookie('login_key'));
|
||||
$userInfo = $this->userObj->getInfo();
|
||||
$this->loginStatusCheck();
|
||||
$saveAction = $this->userObj->changeNick(input("post.nick"));
|
||||
if($saveAction[0]){
|
||||
return json(['error' => '200','msg' => '设置成功']);
|
||||
}else{
|
||||
return json(['error' => '1','msg' => $saveAction[1]]);
|
||||
}
|
||||
}
|
||||
|
||||
public function HomePage(){
|
||||
$this->userObj = new User(cookie('user_id'),cookie('login_key'));
|
||||
$userInfo = $this->userObj->getInfo();
|
||||
$this->loginStatusCheck();
|
||||
$saveAction = $this->userObj->homePageToggle(input("post.status"));
|
||||
if($saveAction[0]){
|
||||
return json(['error' => '200','msg' => '设置成功']);
|
||||
}else{
|
||||
return json(['error' => '1','msg' => $saveAction[1]]);
|
||||
}
|
||||
}
|
||||
|
||||
public function EnableTwoFactor(){
|
||||
$twoFactor = new TwoFactor();
|
||||
$twoFactor->qrcodeRender();
|
||||
}
|
||||
|
||||
public function TwoFactorConfirm(){
|
||||
$this->userObj = new User(cookie('user_id'),cookie('login_key'));
|
||||
$userInfo = $this->userObj->getInfo();
|
||||
$this->loginStatusCheck();
|
||||
$twoFactor = new TwoFactor();
|
||||
$confirmResult = $twoFactor->confirmCode(session("two_factor_enable"),input("post.code"));
|
||||
if($confirmResult[0]){
|
||||
$twoFactor->bindUser($this->userObj->uid);
|
||||
return json(['error' => '200','msg' => '设置成功']);
|
||||
}else{
|
||||
return json(['error' => '1','msg' => $confirmResult[1]]);
|
||||
}
|
||||
}
|
||||
|
||||
public function ChangePwd(){
|
||||
$this->userObj = new User(cookie('user_id'),cookie('login_key'));
|
||||
$userInfo = $this->userObj->getInfo();
|
||||
$this->loginStatusCheck();
|
||||
$changeAction = $this->userObj->changePwd(input("post.origin"),input("post.new"));
|
||||
if($changeAction[0]){
|
||||
return json(['error' => '200','msg' => '设置成功']);
|
||||
}else{
|
||||
return json(['error' => '1','msg' => $changeAction[1]]);
|
||||
}
|
||||
}
|
||||
|
||||
private function loginStatusCheck($login=true){
|
||||
if(!$this->userObj->loginStatus){
|
||||
if($login){
|
||||
$this->redirect(url('/Login','',''));
|
||||
}else{
|
||||
$this->redirect(url('/Home','',''));
|
||||
}
|
||||
exit();
|
||||
}
|
||||
}
|
||||
|
||||
private function isLoginStatusCheck(){
|
||||
if($this->userObj->loginStatus){
|
||||
$this->redirect(url('/Home','',''));
|
||||
exit();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,80 @@
|
||||
<?php
|
||||
namespace app\index\controller;
|
||||
|
||||
use think\Controller;
|
||||
use app\index\model\User;
|
||||
use think\Cookie;
|
||||
use think\Db;
|
||||
use \app\index\model\Option;
|
||||
|
||||
class Profile extends Controller{
|
||||
|
||||
public $visitorObj;
|
||||
public $userObj;
|
||||
public $siteOptions;
|
||||
|
||||
public function _initialize(){
|
||||
$this->siteOptions = Option::getValues(["basic"]);
|
||||
}
|
||||
|
||||
public function index(){
|
||||
$this->visitorObj = new User(cookie('user_id'),cookie('login_key'));
|
||||
$userId = (string)input("param.uid");
|
||||
$userData = Db::name("users")->where("id",$userId)->find();
|
||||
if (empty($userId) || empty($userData) || $userData["profile"] == 0){
|
||||
$this->error('用户主页不存或者用户关闭了个人主页',404,$this->siteOptions);
|
||||
}
|
||||
$groupData = Db::name("groups")->where("id",$userData["user_group"])->find();
|
||||
$shareCount = Db::name('shares')
|
||||
->where('owner',$userId)
|
||||
->where('type',"public")
|
||||
->count();
|
||||
$regDays = (int)((time()-strtotime($userData["user_date"]))/86400);
|
||||
switch (input("get.type")) {
|
||||
case 'all':
|
||||
$list = Db::name('shares')
|
||||
->where('owner',$userId)
|
||||
->where('type',"public")
|
||||
->order('id DESC')
|
||||
->paginate(10);
|
||||
break;
|
||||
case 'hot':
|
||||
$num = Option::getValue("hot_share_num");
|
||||
$list = Db::name('shares')
|
||||
->where('owner',$userId)
|
||||
->where('type',"public")
|
||||
->paginate($num);
|
||||
break;
|
||||
default:
|
||||
$list = Db::name('shares')
|
||||
->where('owner',$userId)
|
||||
->where('type',"public")
|
||||
->order('id DESC')
|
||||
->paginate(10);
|
||||
break;
|
||||
}
|
||||
$listData = $list->all();
|
||||
foreach ($listData as $key => $value) {
|
||||
if($value["source_type"]=="file"){
|
||||
$listData[$key]["fileData"] = Db::name('files')->where('id',$value["source_name"])->find()["orign_name"];
|
||||
|
||||
}else{
|
||||
$pathDir = explode("/",$value["source_name"]);
|
||||
$listData[$key]["fileData"] = end($pathDir);
|
||||
}
|
||||
}
|
||||
return view("profile",[
|
||||
"options" => $this->siteOptions,
|
||||
'loginStatus' => $this->visitorObj->loginStatus,
|
||||
'userInfo' => $userData,
|
||||
'userData' => $this->visitorObj->userSQLData,
|
||||
'groupData' => $groupData,
|
||||
'list' => $listData,
|
||||
'listOrigin' => $list,
|
||||
'type' => input("get.type"),
|
||||
'shareCount' => $shareCount,
|
||||
'regDays' => $regDays,
|
||||
]);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,185 @@
|
||||
<?php
|
||||
namespace app\index\controller;
|
||||
|
||||
use think\Controller;
|
||||
use think\Db;
|
||||
use \app\index\model\Option;
|
||||
use \app\index\model\User;
|
||||
use \app\index\model\ShareHandler;
|
||||
use think\Session;
|
||||
use think\Request;
|
||||
|
||||
class Share extends Controller{
|
||||
|
||||
public $userObj;
|
||||
public $siteOptions;
|
||||
|
||||
public function _initialize(){
|
||||
$this->userObj = new User(cookie('user_id'),cookie('login_key'));
|
||||
$this->siteOptions = Option::getValues(["basic"]);
|
||||
}
|
||||
|
||||
public function index(){
|
||||
$shareKey = input('param.key');
|
||||
$shareObj = new ShareHandler($shareKey);
|
||||
if(!$shareObj->querryStatus){
|
||||
header('HTTP/1.1 404 Not Found');
|
||||
$this->error('当前分享不存在或者已经失效',404,$this->siteOptions);
|
||||
}
|
||||
if(!$shareObj->lockStatus){
|
||||
$shareObj->numIncrease("view_num");
|
||||
if($shareObj->shareData["source_type"] == "dir"){
|
||||
return view('share_dir', [
|
||||
'options' => Option::getValues(['basic','share']),
|
||||
'userInfo' => $shareObj->shareOwner->userSQLData,
|
||||
'dirData' => $shareObj->dirData,
|
||||
'shareData' => $shareObj->shareData,
|
||||
'loginStatus' => $this->userObj->loginStatus,
|
||||
'userData' => $this->userObj->userSQLData,
|
||||
'groupData' => $shareObj->shareOwner->groupData,
|
||||
'allowPreview' => Option::getValue("allowdVisitorDownload"),
|
||||
]);
|
||||
}else{
|
||||
return view('share_single', [
|
||||
'options' => Option::getValues(['basic','share']),
|
||||
'userInfo' => $shareObj->shareOwner->userSQLData,
|
||||
'fileData' => $shareObj->fileData,
|
||||
'shareData' => $shareObj->shareData,
|
||||
'loginStatus' => $this->userObj->loginStatus,
|
||||
'userData' => $this->userObj->userSQLData,
|
||||
'allowPreview' => Option::getValue("allowdVisitorDownload"),
|
||||
]);
|
||||
}
|
||||
}else{
|
||||
return view('share_lock', [
|
||||
'options' => Option::getValues(['basic','share']),
|
||||
'userInfo' => $shareObj->shareOwner->userSQLData,
|
||||
'fileData' => $shareObj->fileData,
|
||||
'shareData' => $shareObj->shareData,
|
||||
'loginStatus' => $this->userObj->loginStatus,
|
||||
'userData' => $this->userObj->userSQLData,
|
||||
'pwd' => input("?get.pwd") ? input("get.pwd") : "",
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
public function getDownloadUrl(){
|
||||
$shareId = input('key');
|
||||
$shareObj = new ShareHandler($shareId,false);
|
||||
return $shareObj->getDownloadUrl($this->userObj);
|
||||
}
|
||||
|
||||
public function Download(){
|
||||
$shareId = input('param.key');
|
||||
$filePath = input('get.path');
|
||||
$shareObj = new ShareHandler($shareId,false);
|
||||
if(empty($filePath)){
|
||||
$DownloadHandler = $shareObj->Download($this->userObj);
|
||||
}else{
|
||||
$DownloadHandler = $shareObj->DownloadFolder($this->userObj,$filePath);
|
||||
}
|
||||
if($DownloadHandler[0]){
|
||||
$this->redirect($DownloadHandler[1],302);
|
||||
}else{
|
||||
$this->error($DownloadHandler[1],404,$this->siteOptions);
|
||||
}
|
||||
}
|
||||
|
||||
public function chekPwd(){
|
||||
$shareId = input('key');
|
||||
$inputPwd = input('password');
|
||||
$shareObj = new ShareHandler($shareId,false);
|
||||
if(!$shareObj->querryStatus){
|
||||
return array(
|
||||
"error" => 1,
|
||||
"msg" => "分享不存在"
|
||||
);
|
||||
}
|
||||
return $shareObj->checkPwd($inputPwd);
|
||||
}
|
||||
|
||||
public function Preview(){
|
||||
$shareId = input('param.key');
|
||||
$filePath = input('get.path');
|
||||
$shareObj = new ShareHandler($shareId,false);
|
||||
if(empty($filePath)){
|
||||
$previewHandler = $shareObj->Preview($this->userObj);
|
||||
}else{
|
||||
if(!empty(input('get.folder'))){
|
||||
$previewHandler = $shareObj->PreviewFolder($this->userObj,$filePath,true);
|
||||
}else{
|
||||
$previewHandler = $shareObj->PreviewFolder($this->userObj,$filePath);
|
||||
}
|
||||
}
|
||||
if($previewHandler[0]){
|
||||
$this->redirect($previewHandler[1],302);
|
||||
}else{
|
||||
$this->error($previewHandler[1],404,$this->siteOptions);
|
||||
}
|
||||
}
|
||||
|
||||
public function ListFile(){
|
||||
$shareId = input('param.key');
|
||||
$reqPathTo = stripslashes(json_decode(file_get_contents("php://input"),true)['path']);
|
||||
$shareObj = new ShareHandler($shareId,false);
|
||||
return $shareObj->ListFile($reqPathTo);
|
||||
}
|
||||
|
||||
public function ListPic(){
|
||||
$filePath = input('get.path');
|
||||
$shareId = input('get.id');
|
||||
$shareObj = new ShareHandler($shareId,false);
|
||||
return $shareObj->listPic($shareId,$filePath);
|
||||
}
|
||||
|
||||
public function Delete(){
|
||||
$shareId = input('post.id');
|
||||
$shareObj = new ShareHandler($shareId,false);
|
||||
if(!$shareObj->querryStatus){
|
||||
return array(
|
||||
"error" => 1,
|
||||
"msg" => "分享不存在"
|
||||
);
|
||||
}
|
||||
return $shareObj->deleteShare($this->userObj->uid);
|
||||
}
|
||||
|
||||
public function ChangePromission(){
|
||||
$shareId = input('post.id');
|
||||
$shareObj = new ShareHandler($shareId,false);
|
||||
if(!$shareObj->querryStatus){
|
||||
return array(
|
||||
"error" => 1,
|
||||
"msg" => "分享不存在"
|
||||
);
|
||||
}
|
||||
return $shareObj->changePromission($this->userObj->uid);
|
||||
}
|
||||
|
||||
public function My(){
|
||||
if(!$this->userObj->loginStatus){
|
||||
$this->redirect(url('/Login','',''));
|
||||
exit();
|
||||
}
|
||||
$userInfo = $this->userObj->getInfo();
|
||||
$groupData = $this->userObj->getGroupData();
|
||||
$list = Db::name('shares')->where('owner',$this->userObj->uid)->paginate(10);
|
||||
$listData = $list->all();
|
||||
foreach ($listData as $key => $value) {
|
||||
if($value["source_type"]=="file"){
|
||||
$listData[$key]["fileData"] = Db::name('files')->where('id',$value["source_name"])->find()["orign_name"];
|
||||
|
||||
}else{
|
||||
$listData[$key]["fileData"] = $value["source_name"];
|
||||
}
|
||||
}
|
||||
return view('share_home', [
|
||||
'options' => Option::getValues(['basic','share']),
|
||||
'userInfo' => $userInfo,
|
||||
'groupData' => $groupData,
|
||||
'list' => $listData,
|
||||
'listOrigin' => $list
|
||||
]);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,78 @@
|
||||
<?php
|
||||
namespace app\index\controller;
|
||||
|
||||
use think\Controller;
|
||||
use think\Db;
|
||||
use think\Request;
|
||||
use \app\index\model\Option;
|
||||
use \app\index\model\User;
|
||||
use \app\index\model\UploadHandler;
|
||||
use think\Session;
|
||||
|
||||
class Upload extends Controller{
|
||||
|
||||
public $userObj;
|
||||
|
||||
public function _initialize(){
|
||||
$this->userObj = new User(cookie('user_id'),cookie('login_key'));
|
||||
if(!$this->userObj->loginStatus){
|
||||
echo "Bad request";
|
||||
exit();
|
||||
}
|
||||
}
|
||||
|
||||
public function index(){
|
||||
ob_end_clean();
|
||||
$file = request()->file('file');
|
||||
$fileInfo = Request::instance()->request();
|
||||
$UploadHandler = new UploadHandler($this->userObj->groupData['policy_name'],$this->userObj->uid);
|
||||
return $UploadHandler->fileReceive($file,$fileInfo);
|
||||
}
|
||||
|
||||
public function Token(){
|
||||
$uploadObj = new UploadHandler($this->userObj->groupData['policy_name'],$this->userObj->uid);
|
||||
$upToken = $uploadObj->getToken();
|
||||
if(!empty($uploadObj->upyunPolicy)){
|
||||
return json([
|
||||
"token" => $upToken,
|
||||
"policy" => $uploadObj->upyunPolicy,
|
||||
]);
|
||||
}
|
||||
if(!empty($uploadObj->s3Policy)){
|
||||
return json([
|
||||
"policy" => $uploadObj->s3Policy,
|
||||
"sign" => $uploadObj->s3Sign,
|
||||
"key" => $uploadObj->dirName,
|
||||
"credential" => $uploadObj->s3Credential,
|
||||
"x_amz_date" => $uploadObj->x_amz_date,
|
||||
"siteUrl"=>$uploadObj->siteUrl,
|
||||
"callBackKey" => $uploadObj->callBackKey,
|
||||
]);
|
||||
}
|
||||
if(!$uploadObj->getToken()){
|
||||
return json([
|
||||
"uptoken" => $uploadObj->ossToken,
|
||||
"sign" => $uploadObj->ossSign,
|
||||
"id" => $uploadObj->ossAccessId,
|
||||
"key" => $uploadObj->ossFileName,
|
||||
"callback" => $uploadObj->ossCallBack,
|
||||
]);
|
||||
}
|
||||
return json(["uptoken" => $uploadObj->getToken()]);
|
||||
}
|
||||
|
||||
public function chunk(){
|
||||
$file = file_get_contents('php://input');
|
||||
$uploadObj = new UploadHandler($this->userObj->groupData['policy_name'],$this->userObj->uid);
|
||||
$uploadObj->setChunk(input('param.chunk'),input('param.chunks'),$file);
|
||||
}
|
||||
|
||||
public function mkFile(){
|
||||
$ctx = file_get_contents('php://input');
|
||||
$originName = UploadHandler::b64Decode(input('param.fname'));
|
||||
$filePath = UploadHandler::b64Decode(input('param.path'));
|
||||
$uploadObj = new UploadHandler($this->userObj->groupData['policy_name'],$this->userObj->uid);
|
||||
$uploadObj->generateFile($ctx,$originName,$filePath);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,45 @@
|
||||
<?php
|
||||
namespace app\index\controller;
|
||||
|
||||
use think\Controller;
|
||||
use think\Db;
|
||||
|
||||
use \app\index\model\Option;
|
||||
use \app\index\model\User;
|
||||
use \app\index\model\Directory;
|
||||
use \app\index\model\Object;
|
||||
use \app\index\model\DavAuth;
|
||||
use \app\index\model\BasicCallBack;
|
||||
|
||||
use Sabre\DAV;
|
||||
use Sabre\DAV\Auth;
|
||||
|
||||
class WebDav extends Controller{
|
||||
|
||||
public $userObj;
|
||||
public $uid;
|
||||
|
||||
public function index(){
|
||||
|
||||
}
|
||||
|
||||
public function Api(){
|
||||
$this->uid = input("param.uid");
|
||||
$publicDir = new Directory($this->uid."/");
|
||||
|
||||
$server = new DAV\Server($publicDir);
|
||||
$server->setBaseUri('/WebDav/Api/uid/'.$this->uid);
|
||||
$lockBackend = new DAV\Locks\Backend\File(ROOT_PATH.'public/locks');
|
||||
$lockPlugin = new DAV\Locks\Plugin($lockBackend);
|
||||
$server->addPlugin($lockPlugin);
|
||||
$check = new DavAuth($this->uid);
|
||||
$callBack = new BasicCallBack($check);
|
||||
$authPlugin = new Auth\Plugin($callBack);
|
||||
$server->addPlugin($authPlugin);
|
||||
$server->addPlugin(new DAV\Browser\Plugin());
|
||||
$server->addPlugin(new \Sabre\DAV\Browser\GuessContentType());
|
||||
ob_end_clean();
|
||||
$server->exec();
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,657 @@
|
||||
<?php
|
||||
namespace app\index\model;
|
||||
|
||||
use think\Model;
|
||||
use think\Db;
|
||||
use \app\index\model\Mail;
|
||||
use \app\index\model\FileManage;
|
||||
|
||||
class AdminHandler extends Model{
|
||||
|
||||
public $siteOptions;
|
||||
public $pageData;
|
||||
public $listData;
|
||||
public $pageNow;
|
||||
public $pageTotal;
|
||||
public $dataTotal;
|
||||
|
||||
public function __construct($options){
|
||||
$this->siteOptions = $options;
|
||||
}
|
||||
|
||||
public function getStatics(){
|
||||
$statics["fileNum"] = Db::name('files')->count();
|
||||
$statics["privateShareNum"] = Db::name('shares')->where("type","private")->count();
|
||||
$statics["publicShareNum"] = Db::name('shares')->where("type","public")->count();
|
||||
$statics["userNum"] = Db::name('users')->where("user_status",0)->count();
|
||||
if($statics["fileNum"]==0){
|
||||
$statics["imgRate"] = 0;
|
||||
$statics["audioRate"] = 0;
|
||||
$statics["videoRate"] = 0;
|
||||
$statics['otherRate'] = 0;
|
||||
}else{
|
||||
$statics["imgRate"] =floor(Db::name('files')
|
||||
->where('pic_info',"<>"," ")
|
||||
->where('pic_info',"<>","0,0")
|
||||
->where('pic_info',"<>","null,null")
|
||||
->count()/$statics["fileNum"]*10000)/100;
|
||||
$statics["audioRate"] =floor(Db::name('files')
|
||||
->where(function ($query) {
|
||||
$query->where('orign_name', "like","%mp3")
|
||||
->whereor('orign_name', "like","%flac")
|
||||
->whereor('orign_name', "like","%wma")
|
||||
->whereor('orign_name', "like","%aac")
|
||||
->whereor('orign_name', "like","%wav")
|
||||
->whereor('orign_name', "like","%ogg");
|
||||
})
|
||||
->count()/$statics["fileNum"]*10000)/100;
|
||||
$statics["videoRate"] =floor(Db::name('files')
|
||||
->where(function ($query) {
|
||||
$query->where('orign_name', "like","%mp4")
|
||||
->whereor('orign_name', "like","%avi")
|
||||
->whereor('orign_name', "like","%rmvb")
|
||||
->whereor('orign_name', "like","%aac")
|
||||
->whereor('orign_name', "like","%wav")
|
||||
->whereor('orign_name', "like","%mkv");
|
||||
})
|
||||
->count()/$statics["fileNum"]*10000)/100;
|
||||
$statics['otherRate'] = 100-($statics["videoRate"]+$statics["audioRate"]+$statics["imgRate"]);
|
||||
}
|
||||
$timeNow=time();
|
||||
$statics["trendFile"]="";
|
||||
$statics["trendUser"]="";
|
||||
$statics["trendDate"]="";
|
||||
for ($i=0; $i < 13; $i++) {
|
||||
$statics["trendFile"].= Db::name('files')->where('upload_date','between time',[date("Y-m-d",$timeNow-(12-$i)*3600*24),date("Y-m-d",$timeNow-(11-$i)*3600*24)])->count().",";
|
||||
}
|
||||
for ($i=0; $i < 13; $i++) {
|
||||
$statics["trendUser"].= Db::name('users')->where('user_date','between time',[date("Y-m-d",$timeNow-(12-$i)*3600*24),date("Y-m-d",$timeNow-(11-$i)*3600*24)])->count().",";
|
||||
}
|
||||
for ($i=0; $i < 13; $i++) {
|
||||
$statics["trendDate"].='"'.date("m月d日",$timeNow-(12-$i)*3600*24).'",';
|
||||
}
|
||||
$statics["trendFile"] = rtrim($statics["trendFile"],",");
|
||||
$statics["trendDate"] = rtrim($statics["trendDate"],",");
|
||||
$statics["trendUser"] = rtrim($statics["trendUser"],",");
|
||||
return $statics;
|
||||
}
|
||||
|
||||
public function saveBasicSetting($options){
|
||||
$siteUrl = rtrim($options["siteURL"],"/")."/";
|
||||
$options["siteURL"]=$siteUrl;
|
||||
return $this->saveOptions($options);
|
||||
}
|
||||
|
||||
public function saveRegSetting($options){
|
||||
foreach(["email_active","login_captcha","reg_captcha","forget_captcha"] as $key){
|
||||
$options[$key] = array_key_exists($key,$options) ? $options[$key] : 0;
|
||||
}
|
||||
return $this->saveOptions($options);
|
||||
}
|
||||
|
||||
public function saveMailSetting($options){
|
||||
return $this->saveOptions($options);
|
||||
}
|
||||
|
||||
public function saveMailTemplate($options){
|
||||
return $this->saveOptions($options);
|
||||
}
|
||||
|
||||
public function AddGroup($options){
|
||||
$options["max_storage"] = $options["max_storage"]*$options["sizeTimes"];
|
||||
unset($options["sizeTimes"]);
|
||||
$options["grade_policy"] = 0;
|
||||
$options["policy_list"] = $options["policy_name"];
|
||||
try {
|
||||
Db::name("groups")->insert($options);
|
||||
} catch (Exception $e) {
|
||||
return ["error"=>1,"msg"=>$e->getMessage()];
|
||||
}
|
||||
return ["error"=>200,"msg"=>"设置已保存"];
|
||||
}
|
||||
|
||||
public function addPolicy($options){
|
||||
$options["max_size"] = $options["max_size"]*$options["sizeTimes"];
|
||||
unset($options["sizeTimes"]);
|
||||
$options["server"] = isset($options["server"]) ? $options["server"] : "/Upload";
|
||||
foreach (["bucketname","bucket_private","bucketname","ak","sk","op_name","op_pwd","mimetype","namerule"] as $key => $value) {
|
||||
$options[$value] = isset($options[$value]) ? $options[$value] : "0";
|
||||
}
|
||||
if(empty($options["filetype"])){
|
||||
$options["filetype"]="[]";
|
||||
}else{
|
||||
$options["filetype"] = json_encode([0=>["ext"=>$options["filetype"],"title"=>"default"]]);
|
||||
}
|
||||
if($options["policy_type"] == "upyun"){
|
||||
$options["server"] = "https://v0.api.upyun.com/".$options["bucketname"];
|
||||
}
|
||||
try {
|
||||
Db::name("policy")->insert($options);
|
||||
} catch (Exception $e) {
|
||||
return ["error"=>1,"msg"=>$e->getMessage()];
|
||||
}
|
||||
return ["error"=>200,"msg"=>"设置已保存"];
|
||||
}
|
||||
|
||||
public function editPolicy($options){
|
||||
$policyId = $options["id"];
|
||||
$options["max_size"] = $options["max_size"]*$options["sizeTimes"];
|
||||
unset($options["sizeTimes"]);
|
||||
unset($options["id"]);
|
||||
if(empty($options["filetype"])){
|
||||
$options["filetype"]="[]";
|
||||
}else{
|
||||
$options["filetype"] = json_encode([0=>["ext"=>$options["filetype"],"title"=>"default"]]);
|
||||
}
|
||||
try {
|
||||
Db::name("policy")->where("id",$policyId)->update($options);
|
||||
} catch (Exception $e) {
|
||||
return ["error"=>1,"msg"=>$e->getMessage()];
|
||||
}
|
||||
return ["error"=>200,"msg"=>"设置已保存"];
|
||||
}
|
||||
|
||||
public function saveGroup($options){
|
||||
$groupId = $options["id"];
|
||||
unset($options["id"]);
|
||||
$options["max_storage"] = $options["max_storage"]*$options["sizeTimes"];
|
||||
unset($options["sizeTimes"]);
|
||||
try {
|
||||
Db::name("groups")->where("id",$groupId)->update($options);
|
||||
} catch (Exception $e) {
|
||||
return ["error"=>1,"msg"=>$e->getMessage()];
|
||||
}
|
||||
return ["error"=>200,"msg"=>"设置已保存"];
|
||||
}
|
||||
|
||||
public function saveOptions($options){
|
||||
try {
|
||||
foreach ($options as $key => $value) {
|
||||
Db::name("options")->where("option_name",$key)->update(["option_value"=>$value]);
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
return ["error"=>1,"msg"=>$e->getMessage()];
|
||||
}
|
||||
return ["error"=>200,"msg"=>"设置已保存"];
|
||||
}
|
||||
|
||||
public function getAvaliableGroup(){
|
||||
$groupData = Db::name("groups")->where("id","neq",2)->select();
|
||||
return $groupData;
|
||||
}
|
||||
|
||||
public function saveCron($options){
|
||||
$cronId = $options["id"];
|
||||
unset($options["id"]);
|
||||
Db::name("corn")->where("id",$cronId)->update($options);
|
||||
}
|
||||
|
||||
public function getAvaliablePolicy(){
|
||||
$policyData = Db::name("policy")->select();
|
||||
return $policyData;
|
||||
}
|
||||
|
||||
public function sendTestMail($options){
|
||||
$mailObj = new Mail();
|
||||
if(empty($options["receiveMail"])){
|
||||
return ["error"=>1,"msg"=>"接收邮箱不能为空"];
|
||||
}
|
||||
$sendResult = $mailObj->Send($options["receiveMail"],"发信测试",$options["subject"],$options["content"]);
|
||||
if($sendResult){
|
||||
return ["error"=>200,"msg"=>"发送成功"];
|
||||
}else{
|
||||
return ["error"=>1,"msg"=>$mailObj->errorMsg];
|
||||
}
|
||||
}
|
||||
|
||||
public function deleteSingle($id){
|
||||
$fileRecord = Db::name("files")->where("id",$id)->find();
|
||||
return FileManage::DeleteHandler([0 => rtrim($fileRecord["dir"],"/")."/".$fileRecord["orign_name"]],$fileRecord["upload_user"]);
|
||||
}
|
||||
|
||||
public function deletePolicy($id){
|
||||
$groupData = Db::name("groups")->where("policy_name",$id)->select();
|
||||
if(!empty($groupData)){
|
||||
return ["error"=>true,"msg"=>"此上传策略正在被以下用户组使用:".join(",",array_column($groupData, "group_name"))];
|
||||
}
|
||||
Db::name("policy")->where("id",$id)->delete();
|
||||
return ["error"=>false,"msg"=>"已删除"];
|
||||
}
|
||||
|
||||
public function deleteGroup($id){
|
||||
$userData = Db::name("users")->where("user_group",$id)->find();
|
||||
if(!empty($userData)){
|
||||
return ["error"=>true,"msg"=>"此用户组下仍有用户,请先删除这些用户"];
|
||||
}
|
||||
if($id == 1 || $id == 2){
|
||||
return ["error"=>true,"msg"=>"系统保留用户组,无法删除"];
|
||||
}
|
||||
Db::name("groups")->where("id",$id)->delete();
|
||||
return ["error"=>false,"msg"=>"已删除"];
|
||||
}
|
||||
|
||||
public function getConfigFile($type){
|
||||
switch ($type) {
|
||||
case 'common':
|
||||
$configPath = ROOT_PATH ."application/config.php";
|
||||
$basicPath = "application/config.php";
|
||||
break;
|
||||
case 'database':
|
||||
if(file_exists( ROOT_PATH ."application/database.lock")){
|
||||
return ["出于安全考虑,默认禁止直接编辑数据库配置文件。如果需要开启编辑,请手动删除 application/database.lock 文件。","application/database.php"];
|
||||
}
|
||||
$configPath = ROOT_PATH ."application/database.php";
|
||||
$basicPath = "application/database.php";
|
||||
break;
|
||||
case 'route':
|
||||
$configPath = ROOT_PATH ."application/route.php";
|
||||
$basicPath = "application/route.php";
|
||||
break;
|
||||
case 'tags':
|
||||
$configPath = ROOT_PATH ."application/tags.php";
|
||||
$basicPath = "application/tags.php";
|
||||
break;
|
||||
default:
|
||||
die("");
|
||||
break;
|
||||
}
|
||||
return [file_get_contents($configPath),$basicPath];
|
||||
}
|
||||
|
||||
public function saveConfigFile($options){
|
||||
switch ($options["type"]) {
|
||||
case 'common':
|
||||
file_put_contents(ROOT_PATH ."application/config.php",$options["content"]);
|
||||
break;
|
||||
case 'route':
|
||||
file_put_contents(ROOT_PATH ."application/route.php",$options["content"]);
|
||||
break;
|
||||
case 'tags':
|
||||
file_put_contents(ROOT_PATH ."application/tags.php",$options["content"]);
|
||||
break;
|
||||
case 'database':
|
||||
if(file_exists( ROOT_PATH ."application/database.lock")){
|
||||
return ["error"=>true,"msg"=>"出于安全考虑,默认禁止直接编辑数据库配置文件。如果需要开启编辑,请手动删除 application/database.lock 文件。"];
|
||||
}
|
||||
file_put_contents(ROOT_PATH ."application/database.php",$options["content"]);
|
||||
break;
|
||||
default:
|
||||
# code...
|
||||
break;
|
||||
}
|
||||
return ["error"=>false,"msg"=>""];
|
||||
}
|
||||
|
||||
public function deleteMultiple($id){
|
||||
$fileInfo = json_decode($id,true);
|
||||
$pathGroup = [];
|
||||
foreach ($fileInfo as $key => $value) {
|
||||
$pathGroup[$value["uid"]] = isset($pathGroup[$value["uid"]]) ? $pathGroup[$value["uid"]] : [];
|
||||
array_push($pathGroup[$value["uid"]], $value["path"]);
|
||||
}
|
||||
foreach ($pathGroup as $key => $value) {
|
||||
FileManage::DeleteHandler($value,$key);
|
||||
}
|
||||
return ["error"=>200,"msg"=>"删除成功"];
|
||||
}
|
||||
|
||||
public function deleteShare($ids){
|
||||
Db::name("shares")->where("id","in",$ids)->delete();
|
||||
return ["error"=>false,"msg"=>"删除成功"];
|
||||
}
|
||||
|
||||
public function deleteOrder($id){
|
||||
Db::name("order")->where("id",$id)->delete();
|
||||
return ["error"=>false,"msg"=>"删除成功"];
|
||||
}
|
||||
|
||||
public function deleteUser($id,$userNow){
|
||||
if($userNow == $id){
|
||||
return ["error"=>true,"msg"=>"我的老伙计,你可不能删除你自己"];
|
||||
}
|
||||
//删除用户所有文件及目录
|
||||
FileManage::DirDeleteHandler([0 => "/"],$id);
|
||||
//删除此用户所有分享
|
||||
Db::name("shares")->where("owner",$id)->delete();
|
||||
//删除此用户
|
||||
Db::name("users")->where("id",$id)->delete();
|
||||
return ["error"=>false,"msg"=>"删除成功"];
|
||||
}
|
||||
|
||||
public function changeShareType($id){
|
||||
$shareId = $id;
|
||||
$shareObj = new ShareHandler($shareId,false);
|
||||
if(!$shareObj->querryStatus){
|
||||
return array(
|
||||
"error" => 1,
|
||||
"msg" => "分享不存在"
|
||||
);
|
||||
}
|
||||
return $shareObj->changePromission(0,true);
|
||||
}
|
||||
|
||||
public function getUserInfo($id){
|
||||
$userData = Db::name("users")->where("id",$id)->find();
|
||||
$userData["used_storage"] =getSize($userData["used_storage"]);
|
||||
return $userData;
|
||||
}
|
||||
|
||||
public function listFile(){
|
||||
$pageSize = empty(cookie('pageSize')) ? 10 : cookie('pageSize');
|
||||
$orderType = empty(cookie('orderMethodFile')) ? "id DESC" : cookie('orderMethodFile');
|
||||
$this->pageData = Db::name("files")
|
||||
->where(function ($query) {
|
||||
if(!empty(cookie('fileSearch'))){
|
||||
$query->where('orign_name', "like","%".cookie('fileSearch')."%");
|
||||
}
|
||||
})
|
||||
->where(function ($query) {
|
||||
if(!empty(cookie('filePolicy'))){
|
||||
$query->where('policy_id', cookie('filePolicy'));
|
||||
}
|
||||
})
|
||||
->where(function ($query) {
|
||||
if(!empty(cookie('searchValue'))){
|
||||
$query->where(cookie('searchCol'),"like", cookie('searchValue'));
|
||||
}
|
||||
})
|
||||
->order($orderType)
|
||||
->paginate($pageSize);
|
||||
$this->dataTotal = Db::name("files")
|
||||
->where(function ($query) {
|
||||
if(!empty(cookie('fileSearch'))){
|
||||
$query->where('orign_name', "like","%".cookie('fileSearch')."%");
|
||||
}
|
||||
})
|
||||
->where(function ($query) {
|
||||
if(!empty(cookie('filePolicy'))){
|
||||
$query->where('policy_id', cookie('filePolicy'));
|
||||
}
|
||||
})
|
||||
->where(function ($query) {
|
||||
if(!empty(cookie('searchValue'))){
|
||||
$query->where(cookie('searchCol'),"like", cookie('searchValue'));
|
||||
}
|
||||
})
|
||||
->order($orderType)
|
||||
->count();
|
||||
$this->pageTotal = ceil($this->dataTotal/$pageSize);
|
||||
$this->listData = $this->pageData->all();
|
||||
$userCache=[];
|
||||
$userCacheList=[];
|
||||
foreach ($this->listData as $key => $value) {
|
||||
if(in_array($value["upload_user"], $userCacheList)){
|
||||
$this->listData[$key]["user"] = $userCache[$value["upload_user"]];
|
||||
}else{
|
||||
$this->listData[$key]["user"] = Db::name("users")->where("id",$value["upload_user"])->find();
|
||||
array_push($userCacheList,$value["upload_user"]);
|
||||
$userCache[$value["upload_user"]] = $this->listData[$key]["user"];
|
||||
}
|
||||
}
|
||||
$this->pageNow = input("?get.page")?input("get.page"):1;
|
||||
}
|
||||
|
||||
public function listUser(){
|
||||
$pageSize = empty(cookie('pageSize')) ? 10 : cookie('pageSize');
|
||||
$orderType = empty(cookie('orderMethodUser')) ? "id DESC" : cookie('orderMethodUser');
|
||||
$this->pageData = Db::name("users")
|
||||
->where(function ($query) {
|
||||
if(!empty(cookie('userStatus'))){
|
||||
$query->where('user_status', cookie('userStatus')-1);
|
||||
}
|
||||
})
|
||||
->where(function ($query) {
|
||||
if(!empty(cookie('userSearch'))){
|
||||
$query->where('user_nick', "like","%".cookie('userSearch')."%")
|
||||
->whereOr("id",cookie('userSearch'))
|
||||
->whereOr("user_email","like","%".cookie('userSearch')."%");
|
||||
}
|
||||
})
|
||||
->where(function ($query) {
|
||||
if(!empty(cookie('userGroup'))){
|
||||
$query->where('user_group', cookie('userGroup'));
|
||||
}
|
||||
})
|
||||
->where(function ($query) {
|
||||
if(!empty(cookie('searchValueUser'))){
|
||||
$query->where(cookie('searchColUser'),"like", cookie('searchValueUser'));
|
||||
}
|
||||
})
|
||||
->order($orderType)
|
||||
->paginate($pageSize);
|
||||
$this->dataTotal = Db::name("users")
|
||||
->where(function ($query) {
|
||||
if(!empty(cookie('userStatus'))){
|
||||
$query->where('user_status', cookie('userStatus')-1);
|
||||
}
|
||||
})
|
||||
->where(function ($query) {
|
||||
if(!empty(cookie('userSearch'))){
|
||||
$query->where('user_nick', "like","%".cookie('userSearch')."%")
|
||||
->whereOr("id",cookie('userSearch'))
|
||||
->whereOr("user_email","like","%".cookie('userSearch')."%");
|
||||
}
|
||||
})
|
||||
->where(function ($query) {
|
||||
if(!empty(cookie('userGroup'))){
|
||||
$query->where('user_group', cookie('userGroup'));
|
||||
}
|
||||
})
|
||||
->where(function ($query) {
|
||||
if(!empty(cookie('searchValueUser'))){
|
||||
$query->where(cookie('searchColUser'),"like", cookie('searchValueUser'));
|
||||
}
|
||||
})
|
||||
->order($orderType)
|
||||
->count();
|
||||
$this->pageTotal = ceil($this->dataTotal/$pageSize);
|
||||
$this->listData = $this->pageData->all();
|
||||
$groupCache=[];
|
||||
$groupCacheList=[];
|
||||
foreach ($this->listData as $key => $value) {
|
||||
if(in_array($value["user_group"], $groupCacheList)){
|
||||
$this->listData[$key]["group"] = $groupCache[$value["user_group"]];
|
||||
}else{
|
||||
$this->listData[$key]["group"] = Db::name("groups")->where("id",$value["user_group"])->find();
|
||||
array_push($groupCacheList,$value["user_group"]);
|
||||
$groupCache[$value["user_group"]] = $this->listData[$key]["group"];
|
||||
}
|
||||
}
|
||||
$this->pageNow = input("?get.page")?input("get.page"):1;
|
||||
}
|
||||
|
||||
public function listShare(){
|
||||
$pageSize = empty(cookie('pageSize')) ? 10 : cookie('pageSize');
|
||||
$orderType = empty(cookie('orderMethodShare')) ? "id DESC" : cookie('orderMethodShare');
|
||||
$this->pageData = Db::name("shares")
|
||||
->where(function ($query) {
|
||||
if(!empty(cookie('shareSearch'))){
|
||||
$query->where('source_name', "like","%".cookie('shareSearch')."%")->whereOr('origin_name', "like","%".cookie('shareSearch')."%");
|
||||
}
|
||||
})
|
||||
->where(function ($query) {
|
||||
if(!empty(cookie('shareType'))){
|
||||
$query->where('type', cookie('shareType'));
|
||||
}
|
||||
})
|
||||
->order($orderType)
|
||||
->paginate($pageSize);
|
||||
$this->dataTotal = Db::name("shares")
|
||||
->where(function ($query) {
|
||||
if(!empty(cookie('shareSearch'))){
|
||||
$query->where('source_name', "like","%".cookie('shareSearch')."%")->whereOr('origin_name', "like","%".cookie('shareSearch')."%");
|
||||
}
|
||||
})
|
||||
->where(function ($query) {
|
||||
if(!empty(cookie('shareType'))){
|
||||
$query->where('type', cookie('shareType'));
|
||||
}
|
||||
})
|
||||
->order($orderType)
|
||||
->count();
|
||||
$this->pageTotal = ceil($this->dataTotal/$pageSize);
|
||||
$this->listData = $this->pageData->all();
|
||||
$userCache=[];
|
||||
$userCacheList=[];
|
||||
foreach ($this->listData as $key => $value) {
|
||||
if(in_array($value["owner"], $userCacheList)){
|
||||
$this->listData[$key]["user"] = $userCache[$value["owner"]];
|
||||
}else{
|
||||
$this->listData[$key]["user"] = Db::name("users")->where("id",$value["owner"])->find();
|
||||
array_push($userCacheList,$value["owner"]);
|
||||
$userCache[$value["owner"]] = $this->listData[$key]["user"];
|
||||
}
|
||||
}
|
||||
$this->pageNow = input("?get.page")?input("get.page"):1;
|
||||
}
|
||||
|
||||
public function listPolicy(){
|
||||
$pageSize = empty(cookie('pageSize')) ? 10 : cookie('pageSize');
|
||||
$this->pageData = Db::name("policy")
|
||||
->where(function ($query) {
|
||||
if(!empty(cookie('policySearch'))){
|
||||
$query->where('policy_name', "like","%".cookie('policySearch')."%");
|
||||
}
|
||||
})
|
||||
->where(function ($query) {
|
||||
if(!empty(cookie('policyType'))){
|
||||
$query->where('policy_type', cookie('policyType'));
|
||||
}
|
||||
})
|
||||
->order("id DESC")
|
||||
->paginate($pageSize);
|
||||
$this->dataTotal = Db::name("policy")
|
||||
->where(function ($query) {
|
||||
if(!empty(cookie('policySearch'))){
|
||||
$query->where('policy_name', "like","%".cookie('policySearch')."%");
|
||||
}
|
||||
})
|
||||
->where(function ($query) {
|
||||
if(!empty(cookie('policyType'))){
|
||||
$query->where('policy_type', cookie('policyType'));
|
||||
}
|
||||
})
|
||||
->order("id DESC")
|
||||
->count();
|
||||
$this->pageTotal = ceil($this->dataTotal/$pageSize);
|
||||
$this->listData = $this->pageData->all();
|
||||
$this->pageNow = input("?get.page")?input("get.page"):1;
|
||||
foreach ($this->listData as $key => $value) {
|
||||
$this->listData[$key]["file_num"] = Db::name("files")->where("policy_id",$value["id"])->count();
|
||||
$this->listData[$key]["file_size"] = Db::name("files")->where("policy_id",$value["id"])->sum("size");
|
||||
}
|
||||
}
|
||||
|
||||
public function getFileInfo($id){
|
||||
$fileRecord = Db::name("files")->where("id",$id)->find();
|
||||
$policyRecord = Db::name("policy")->where("id",$fileRecord["policy_id"])->find();
|
||||
$fileRecord["policy"] = $policyRecord;
|
||||
return $fileRecord;
|
||||
}
|
||||
|
||||
public function saveThemeFile($options){
|
||||
$fileName=$options["name"];
|
||||
$dir = ROOT_PATH."application/index/view/";
|
||||
$fileList=[];
|
||||
$fileList=$fileList+scandir($dir);
|
||||
$pathList=["/"=>$fileList];
|
||||
foreach (["admin","explore","file","home","index","member","profile","share"] as $key => $value) {
|
||||
$childPath = scandir($dir.$value."/");
|
||||
$fileList=array_merge($fileList,$childPath);
|
||||
$pathList = array_merge($pathList,[$value => $childPath]);
|
||||
}
|
||||
foreach ($fileList as $key => $value) {
|
||||
if(substr_compare($value, ".html", -strlen(".html")) != 0){
|
||||
unset($fileList[$key]);
|
||||
}
|
||||
}
|
||||
foreach($pathList as $key=>$val){
|
||||
if(in_array($fileName.".html",$val)){
|
||||
$parentPath = $key;
|
||||
break;
|
||||
}
|
||||
}
|
||||
file_put_contents($dir.rtrim($parentPath,"/")."/".$fileName.".html",$options["content"]);
|
||||
return ["error"=>false,"msg"=>"成功"];
|
||||
}
|
||||
|
||||
public function saveUser($options){
|
||||
if(empty($options["user_pass"])){
|
||||
unset($options["user_pass"]);
|
||||
}else{
|
||||
$options["user_pass"] = md5(config('salt').$options["user_pass"]);
|
||||
}
|
||||
$userId = $options["uid"];
|
||||
unset($options["uid"]);
|
||||
try {
|
||||
Db::name("users")->where("id",$userId)->update($options);
|
||||
} catch (Exception $e) {
|
||||
return ["error"=>1,"msg"=>$e->getMessage()];
|
||||
}
|
||||
return ["error"=>200,"msg"=>"设置已保存"];
|
||||
}
|
||||
|
||||
public function banUser($id,$uid){
|
||||
if($id == $uid){
|
||||
return ["error"=>1,"msg"=>"我的老伙计,你怎么能封禁你自己?"];
|
||||
}
|
||||
$userData = Db::name("users")->where("id",$id)->find();
|
||||
$statusNew = $userData["user_status"] == 1 ? 0 : 1;
|
||||
Db::name("users")->where("id",$id)->update(["user_status" => $statusNew]);
|
||||
return ["error"=>200,"msg"=>"设置已保存"];
|
||||
}
|
||||
|
||||
public function listGroup(){
|
||||
$pageSize = empty(cookie('pageSize')) ? 10 : cookie('pageSize');
|
||||
$this->pageData = Db::name("groups")
|
||||
->order("id DESC")
|
||||
->paginate($pageSize);
|
||||
$this->dataTotal = Db::name("groups")
|
||||
->order("id DESC")
|
||||
->count();
|
||||
$this->pageTotal = ceil($this->dataTotal/$pageSize);
|
||||
$this->listData = $this->pageData->all();
|
||||
$this->pageNow = input("?get.page")?input("get.page"):1;
|
||||
foreach ($this->listData as $key => $value) {
|
||||
$this->listData[$key]["policy"] = Db::name("policy")->where("id",$value["policy_name"])->find();
|
||||
$this->listData[$key]["user_num"] = Db::name("users")->where("user_group",$value["id"])->count();
|
||||
}
|
||||
}
|
||||
|
||||
public function addUser($options){
|
||||
$options["user_pass"] = md5(config('salt').$options["user_pass"]);
|
||||
if(Db::name('users')->where('user_email',$options["user_email"])->find() !=null){
|
||||
return ["error" => true,"msg"=>"该邮箱已被注册"];
|
||||
}
|
||||
$sqlData = [
|
||||
'user_email' => $options["user_email"],
|
||||
'user_pass' => $options["user_pass"],
|
||||
'user_status' => $options["user_status"],
|
||||
'user_group' => $options["user_group"],
|
||||
'group_primary' => $options["user_group"],
|
||||
'user_date' => date("Y-m-d H:i:s"),
|
||||
'user_nick' => $options["user_nick"],
|
||||
'user_activation_key' => "n",
|
||||
'used_storage' => 0,
|
||||
'two_step'=>"0",
|
||||
'webdav_key' =>$options["user_pass"],
|
||||
'delay_time' =>0,
|
||||
'avatar' => "default",
|
||||
'profile' => true,
|
||||
];
|
||||
if(Db::name('users')->insert($sqlData)){
|
||||
$userId = Db::name('users')->getLastInsID();
|
||||
Db::name('folders')->insert( [
|
||||
'folder_name' => '根目录',
|
||||
'parent_folder' => 0,
|
||||
'position' => '.',
|
||||
'owner' => $userId,
|
||||
'date' => date("Y-m-d H:i:s"),
|
||||
'position_absolute' => '/',
|
||||
]);
|
||||
}
|
||||
return ["error"=>0,"msg"=>"设置已保存"];
|
||||
}
|
||||
|
||||
}
|
||||
?>
|
||||
@ -0,0 +1,146 @@
|
||||
<?php
|
||||
namespace app\index\model;
|
||||
|
||||
use think\Model;
|
||||
use think\Db;
|
||||
use \app\index\model\Option;
|
||||
use \app\index\model\FileManage;
|
||||
|
||||
class Avatar extends Model{
|
||||
|
||||
public $avatarObj;
|
||||
public $errorMsg;
|
||||
public $fileName;
|
||||
public $avatarKey;
|
||||
public $userData;
|
||||
public $avatarType;
|
||||
|
||||
public function __construct($new=false,$obj){
|
||||
$this->avatarObj = $obj;
|
||||
if(!$new){
|
||||
$userData = Db::name("users")->where('id',$obj)->find();
|
||||
$this->userData = $userData;
|
||||
if($userData["avatar"] == "default"){
|
||||
$this->avatarType = "default";
|
||||
}else{
|
||||
$avatarPrarm = explode(".",$userData["avatar"]);
|
||||
$this->avatarType = $avatarPrarm[0];
|
||||
$this->fileName = ltrim(ltrim($userData["avatar"],"g."),"f.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function SaveAvatar(){
|
||||
$info = $this->avatarObj->validate(['size'=>2097152,'ext'=>'jpg,png,gif.bmp'])->rule('uniqid')->move(ROOT_PATH . 'public' . DS . 'avatars');
|
||||
if($info){
|
||||
$_path = ROOT_PATH.'public/avatars/'.$info->getSaveName();
|
||||
$_img = new Image($_path);
|
||||
$_img->thumb(200, 200);
|
||||
$_img->output();
|
||||
$_img = new Image($_path);
|
||||
$_img->thumb(130, 130);
|
||||
$_img->output("_130");
|
||||
$_img = new Image($_path);
|
||||
$_img->thumb(50, 50);
|
||||
$_img->output("_50");
|
||||
$this->fileName = $info->getSaveName();
|
||||
return true;
|
||||
}else{
|
||||
$this->errorMsg=["result"=>"error","msg"=>$this->avatarObj->getError()];
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public function bindUser($uid){
|
||||
$this->avatarKey = "f.".$this->fileName;
|
||||
Db::name("users")->where('id',$uid)->update(["avatar" => $this->avatarKey]);
|
||||
}
|
||||
|
||||
public function Out($size){
|
||||
switch ($this->avatarType) {
|
||||
case 'f':
|
||||
$this->outPutFile($size);
|
||||
exit();
|
||||
break;
|
||||
case 'default':
|
||||
$this->defaultAvatar($size);
|
||||
exit();
|
||||
break;
|
||||
case 'g':
|
||||
return $this->outGravatar($size);
|
||||
break;
|
||||
default:
|
||||
# code...
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public function outPutFile($size){
|
||||
switch ($size) {
|
||||
case 's':
|
||||
$siezSuffix = "_50";
|
||||
break;
|
||||
case 'm':
|
||||
$siezSuffix = "_130";
|
||||
break;
|
||||
default:
|
||||
$siezSuffix = "";
|
||||
break;
|
||||
}
|
||||
$filePath = ROOT_PATH . 'public/avatars/' . $this->fileName.$siezSuffix;
|
||||
if(file_exists($filePath)){
|
||||
ob_end_clean();
|
||||
header('Content-Type: '.FileManage::getMimetype($filePath));
|
||||
$fileObj = fopen($filePath,"r");
|
||||
while(!feof($fileObj)){
|
||||
echo fread($fileObj,2097152);
|
||||
}
|
||||
}else{
|
||||
$this->defaultAvatar($siezSuffix);
|
||||
}
|
||||
}
|
||||
|
||||
public function outGravatar($size){
|
||||
switch ($size) {
|
||||
case 's':
|
||||
$siezSuffix = "50";
|
||||
break;
|
||||
case 'm':
|
||||
$siezSuffix = "130";
|
||||
break;
|
||||
default:
|
||||
$siezSuffix = "200";
|
||||
break;
|
||||
}
|
||||
ob_end_clean();
|
||||
$gravatarServer = Option::getValue("gravatar_server");
|
||||
return $gravatarServer.$this->fileName."?d=mm&s=".$siezSuffix;
|
||||
}
|
||||
|
||||
public function defaultAvatar($size){
|
||||
switch ($size) {
|
||||
case 's':
|
||||
$siezSuffix = "_50";
|
||||
break;
|
||||
case 'm':
|
||||
$siezSuffix = "_130";
|
||||
break;
|
||||
default:
|
||||
$siezSuffix = "";
|
||||
break;
|
||||
}
|
||||
ob_end_clean();
|
||||
$filePath = ROOT_PATH . 'static/img/default.png' .$siezSuffix;
|
||||
header('Content-Type: '.FileManage::getMimetype($filePath));
|
||||
$fileObj = fopen($filePath,"r");
|
||||
while(!feof($fileObj)){
|
||||
echo fread($fileObj,2097152);
|
||||
}
|
||||
}
|
||||
|
||||
public function setGravatar(){
|
||||
$this->avatarKey="g.".md5($this->userData["user_email"]);
|
||||
Db::name("users")->where('id',$this->userData["id"])->update(["avatar" => $this->avatarKey]);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,39 @@
|
||||
<?php
|
||||
namespace app\index\model;
|
||||
|
||||
use think\Model;
|
||||
use Sabre\DAV;
|
||||
use Sabre\DAV\Auth\Backend;
|
||||
|
||||
class BasicCallBack extends \Sabre\DAV\Auth\Backend\AbstractDigest {
|
||||
|
||||
/**
|
||||
* Callback
|
||||
*
|
||||
* @var callable
|
||||
*/
|
||||
protected $callBack;
|
||||
|
||||
/**
|
||||
* Creates the backend.
|
||||
*
|
||||
* A callback must be provided to handle checking the username and
|
||||
* password.
|
||||
*
|
||||
* @param callable $callBack
|
||||
* @return void
|
||||
*/
|
||||
function __construct(callable $callBack) {
|
||||
|
||||
$this->callBack = $callBack;
|
||||
$this->realm = 'CloudreveWebDav';
|
||||
|
||||
}
|
||||
|
||||
|
||||
public function getDigestHash($realm, $username){
|
||||
$cb = $this->callBack;
|
||||
return $cb($realm,$username);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,206 @@
|
||||
<?php
|
||||
namespace app\index\model;
|
||||
|
||||
require_once 'extend/Qiniu/functions.php';
|
||||
|
||||
use think\Model;
|
||||
use think\Db;
|
||||
use Qiniu\Auth;
|
||||
use \app\index\model\Option;
|
||||
use \app\index\model\FileManage;
|
||||
use \app\index\model\UploadHandler;
|
||||
|
||||
class CallbackHandler extends Model{
|
||||
|
||||
public $CallbackData;
|
||||
public $policyData;
|
||||
public $userData;
|
||||
|
||||
public function __construct($data){
|
||||
$this->CallbackData = $data;
|
||||
}
|
||||
|
||||
public function qiniuHandler($header){
|
||||
$jsonData = json_decode($this->CallbackData,true);
|
||||
$CallbackSqlData = Db::name('callback')->where('callback_key',$jsonData['callbackkey'])->find();
|
||||
$this->policyData = Db::name('policy')->where('id',$CallbackSqlData['pid'])->find();
|
||||
|
||||
if(!$this->IsQiniuCallback($header)){
|
||||
$this->setError("Undelegated Request");
|
||||
}
|
||||
if($this->policyData == null){
|
||||
$this->setError("CallbackKey Not Exist.");
|
||||
}
|
||||
if(!FileManage::sotrageCheck($CallbackSqlData["uid"],$jsonData["fsize"])){
|
||||
$this->setError("空间容量不足",true);
|
||||
}
|
||||
$picInfo = $jsonData["picinfo"];
|
||||
$addAction = FileManage::addFile($jsonData,$this->policyData,$CallbackSqlData["uid"],$picInfo);
|
||||
if(!$addAction[0]){
|
||||
$this->setError($addAction[1],true);
|
||||
}
|
||||
FileManage::storageCheckOut($CallbackSqlData["uid"],$jsonData["fsize"]);
|
||||
$this->setSuccess($jsonData['fname']);
|
||||
}
|
||||
|
||||
public function ossHandler($auth,$pubKey){
|
||||
if(!$this->IsOssCallback($auth,$pubKey)){
|
||||
$this->setError("Undelegated Request");
|
||||
}
|
||||
$jsonData = json_decode($this->CallbackData,true);
|
||||
$jsonData["fname"] = urldecode($jsonData["fname"]);
|
||||
$jsonData["objname"] = urldecode($jsonData["objname"]);
|
||||
$jsonData["path"] = urldecode($jsonData["path"]);
|
||||
$CallbackSqlData = Db::name('callback')->where('callback_key',$jsonData['callbackkey'])->find();
|
||||
$this->policyData = Db::name('policy')->where('id',$CallbackSqlData['pid'])->find();
|
||||
if($this->policyData == null){
|
||||
$this->setError("CallbackKey Not Exist.");
|
||||
}
|
||||
if(!FileManage::sotrageCheck($CallbackSqlData["uid"],$jsonData["fsize"])){
|
||||
$this->setError("空间容量不足",true);
|
||||
}
|
||||
$picInfo = $jsonData["picinfo"];
|
||||
$addAction = FileManage::addFile($jsonData,$this->policyData,$CallbackSqlData["uid"],$picInfo);
|
||||
if(!$addAction[0]){
|
||||
$this->setError($addAction[1],true);
|
||||
}
|
||||
FileManage::storageCheckOut($CallbackSqlData["uid"],$jsonData["fsize"]);
|
||||
$this->setSuccess($jsonData['fname']);
|
||||
}
|
||||
|
||||
public function upyunHandler($token,$date,$md5){
|
||||
$this->policyData = Db::name("policy")->where("id",$this->CallbackData["ext-param"]["pid"])->find();
|
||||
if(!$this->IsUpyunCallback($token,$date,$md5)){
|
||||
$this->setError("Undelegated Request",false,true);
|
||||
}
|
||||
if(!FileManage::sotrageCheck($this->CallbackData["ext-param"]["uid"],$this->CallbackData["file_size"])){
|
||||
FileManage::deleteFile($this->CallbackData["url"],$this->policyData);
|
||||
$this->setError("空间容量不足",false,true);
|
||||
}
|
||||
$picInfo = empty($this->CallbackData["image-width"]) ? "" :$this->CallbackData["image-width"].",".$this->CallbackData["image-height"];
|
||||
$fileNameExplode = explode("CLSUFF",$this->CallbackData["url"]);
|
||||
$jsonData["fname"] = end($fileNameExplode);
|
||||
$jsonData["objname"] = $this->CallbackData["url"];
|
||||
$jsonData["path"] = $this->CallbackData["ext-param"]["path"];
|
||||
$jsonData["fsize"] = $this->CallbackData["file_size"];
|
||||
$addAction = FileManage::addFile($jsonData,$this->policyData,$this->CallbackData["ext-param"]["uid"],$picInfo);
|
||||
if(!$addAction[0]){
|
||||
FileManage::deleteFile($this->CallbackData["url"],$this->policyData);
|
||||
$this->setError($addAction[1],false,true);
|
||||
}
|
||||
FileManage::storageCheckOut($this->CallbackData["ext-param"]["uid"],$jsonData["fsize"]);
|
||||
$this->setSuccess($jsonData['fname']);
|
||||
}
|
||||
|
||||
public function s3Handler($key){
|
||||
$CallbackSqlData = Db::name('callback')->where('callback_key',$key)->find();
|
||||
//删除callback记录
|
||||
if(empty($CallbackSqlData)){
|
||||
$this->setError("Undelegated Request",false,true);
|
||||
}
|
||||
$this->policyData = Db::name('policy')->where('id',$CallbackSqlData['pid'])->find();
|
||||
$this->userData = Db::name('users')->where('id',$CallbackSqlData['uid'])->find();
|
||||
$paths = explode("/",$this->CallbackData["key"]);
|
||||
$jsonData["fname"] = end($paths);
|
||||
$jsonData["objname"] = $this->CallbackData["key"];
|
||||
$jsonData["path"] ="";
|
||||
foreach ($paths as $key => $value) {
|
||||
if($key == 0 || $key == count($paths)-1) continue;
|
||||
$jsonData["path"].=$value.",";
|
||||
}
|
||||
$jsonData["path"] = rtrim($jsonData["path"],",");
|
||||
$jsonData["fsize"] = $this->getS3FileInfo();
|
||||
if(!$jsonData["fsize"]){
|
||||
$this->setError("File not exist",false,true);
|
||||
}
|
||||
$jsonData["fsize"] = $jsonData["fsize"]["size"];
|
||||
$picInfo = "";
|
||||
$addAction = FileManage::addFile($jsonData,$this->policyData,$this->userData["id"],"");
|
||||
if(!$addAction[0]){
|
||||
FileManage::deleteFile($this->CallbackData["key"],$this->policyData);
|
||||
$this->setError($addAction[1],false,true);
|
||||
}
|
||||
FileManage::storageCheckOut($this->userData["id"],$jsonData["fsize"]);
|
||||
$this->setSuccess($jsonData['fname']);
|
||||
}
|
||||
|
||||
private function getS3FileInfo(){
|
||||
$s3 = new \S3\S3($this->policyData["ak"], $this->policyData["sk"],false,$this->policyData["op_pwd"]);
|
||||
$s3->setSignatureVersion('v4');
|
||||
try {
|
||||
$returnVal = $s3->getObjectInfo($this->policyData["bucketname"],$this->CallbackData["key"]);
|
||||
} catch (Exception $e) {
|
||||
return false;
|
||||
}
|
||||
return $returnVal;
|
||||
}
|
||||
|
||||
public function setSuccess($fname){
|
||||
die(json_encode(["key"=> $fname]));
|
||||
}
|
||||
|
||||
public function setError($text,$delete = false,$ignore=false){
|
||||
header("HTTP/1.1 401 Unauthorized");
|
||||
if(!$ignore){
|
||||
$deletedFile = json_decode($this->CallbackData,true);
|
||||
$fileNmae = $deletedFile['objname'];
|
||||
if($delete){
|
||||
FileManage::deleteFile($fileNmae,$this->policyData);
|
||||
}
|
||||
}
|
||||
die(json_encode(["error"=> $text]));
|
||||
}
|
||||
|
||||
private function isUpyunCallback($token,$date,$md5){
|
||||
if(UploadHandler::upyunSign($this->policyData["op_name"],md5($this->policyData["op_pwd"]),"POST","/Callback/Upyun",$date,$md5) != $token){
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function IsQiniuCallback($httpHeader){
|
||||
$auth = new Auth($this->policyData['ak'], $this->policyData['sk']);
|
||||
$callbackBody = $this->CallbackData;
|
||||
$contentType = 'application/json';
|
||||
$authorization = $httpHeader;
|
||||
$url = Option::getValue("siteUrl")."Callback/Qiniu";
|
||||
$isQiniuCallback = $auth->verifyCallback($contentType, $authorization, $url,$callbackBody);
|
||||
if ($isQiniuCallback) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public function IsOssCallback($auth,$pubKey){
|
||||
if (empty($auth) || empty($pubKey)){
|
||||
header("http/1.1 403 Forbidden");
|
||||
exit();
|
||||
}
|
||||
$authorization = base64_decode($auth);
|
||||
$pubKeyUrl = base64_decode($pubKey);
|
||||
$pubOssKey = file_get_contents($pubKeyUrl);
|
||||
if ($pubOssKey == ""){
|
||||
return false;
|
||||
}
|
||||
$body = file_get_contents('php://input');
|
||||
$authStr = '';
|
||||
$path = $_SERVER['REQUEST_URI'];
|
||||
$pos = strpos($path, '?');
|
||||
if ($pos === false){
|
||||
$authStr = urldecode($path)."\n".$body;
|
||||
}else{
|
||||
$authStr = urldecode(substr($path, 0, $pos)).substr($path, $pos, strlen($path) - $pos)."\n".$body;
|
||||
}
|
||||
$ok = openssl_verify($authStr, $authorization, $pubOssKey, OPENSSL_ALGO_MD5);
|
||||
if ($ok == 1){
|
||||
return true;
|
||||
}else{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
?>
|
||||
@ -0,0 +1,73 @@
|
||||
<?php
|
||||
namespace app\index\model;
|
||||
|
||||
use think\Model;
|
||||
use think\Db;
|
||||
use \think\Session;
|
||||
use \app\index\model\FileManage;
|
||||
use \app\index\model\Option;
|
||||
use \app\index\model\Mail;
|
||||
|
||||
class CronHandler extends Model{
|
||||
|
||||
public $cornTasks;
|
||||
public $timeNow;
|
||||
public $notifiedUid = [];
|
||||
|
||||
public function __construct(){
|
||||
$this->cornTasks = Db::name('corn')->where('enable',1)->order('rank desc')->select();
|
||||
$this->timeNow = time();
|
||||
}
|
||||
|
||||
public function checkInterval($interval,$last){
|
||||
return ($last+$interval)<= $this->timeNow ? true : false;
|
||||
}
|
||||
|
||||
public function setComplete($name){
|
||||
Db::name('corn')->where('name', $name)->update(['last_excute' => $this->timeNow]);
|
||||
}
|
||||
|
||||
public function Doit(){
|
||||
foreach ($this->cornTasks as $key => $value) {
|
||||
switch ($value["name"]) {
|
||||
case 'delete_unseful_chunks':
|
||||
if($this->checkInterval($value["interval_s"],$value["last_excute"])){
|
||||
$this->deleteUnsefulChunks($value["interval_s"]);
|
||||
}
|
||||
break;
|
||||
case 'delete_callback_data':
|
||||
if($this->checkInterval($value["interval_s"],$value["last_excute"])){
|
||||
$this->deleteCallbackData($value["interval_s"]);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
# code...
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function deleteUnsefulChunks($interval){
|
||||
echo("deleteUnsefulChunks...");
|
||||
$chunkInfo = Db::name('chunks')->whereTime('time', '<', date('Y-m-d', time()-86400))->select();
|
||||
$deleteList=[];
|
||||
foreach ($chunkInfo as $key => $value) {
|
||||
$fileSize = @filesize(ROOT_PATH . 'public/uploads/chunks/'.$value["obj_name"].".chunk");
|
||||
@unlink(ROOT_PATH . 'public/uploads/chunks/'.$value["obj_name"].".chunk");
|
||||
FileManage::storageGiveBack($value["user"],$fileSize?$fileSize:0);
|
||||
$deleteList["$key"] = $value["id"];
|
||||
}
|
||||
Db::name('chunks')->where(['id' => ["in",$deleteList],])->delete();
|
||||
$this->setComplete("delete_unseful_chunks");
|
||||
echo("Complete<br>");
|
||||
}
|
||||
|
||||
private function deleteCallbackData($interval){
|
||||
echo("deleteCallbackData...");
|
||||
Db::name("callback")->delete(true);
|
||||
echo("Complete<br>");
|
||||
$this->setComplete("delete_callback_data");
|
||||
}
|
||||
|
||||
}
|
||||
?>
|
||||
@ -0,0 +1,30 @@
|
||||
<?php
|
||||
namespace app\index\model;
|
||||
|
||||
use think\Model;
|
||||
use think\Db;
|
||||
use app\index\model\User;
|
||||
|
||||
class DavAuth extends Model{
|
||||
|
||||
public $uid;
|
||||
|
||||
function __construct($id) {
|
||||
$this->uid = $id;
|
||||
}
|
||||
|
||||
public function __invoke($realm,$um){
|
||||
$userData = Db::name("users")->where("id",$this->uid)->find();
|
||||
if(empty($userData) || $userData["user_email"] != $um){
|
||||
return null;
|
||||
}
|
||||
$userGroup = Db::name("groups")->where("id",$userData["user_group"])->find();
|
||||
if(!$userGroup["webdav"]){
|
||||
return null;
|
||||
}
|
||||
return $userData["webdav_key"];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
@ -0,0 +1,186 @@
|
||||
<?php
|
||||
namespace app\index\model;
|
||||
|
||||
use think\Model;
|
||||
use think\Db;
|
||||
use Sabre\DAV;
|
||||
use \app\index\model\FileManage;
|
||||
use \app\index\model\User;
|
||||
use \app\index\model\UploadHandler;
|
||||
|
||||
class Directory extends DAV\Node implements DAV\ICollection, DAV\IQuota{
|
||||
|
||||
private $myPath;
|
||||
public $uid;
|
||||
public $userObj;
|
||||
|
||||
function __construct($path) {
|
||||
$ex = explode("/",$path);
|
||||
$this->uid = $ex[0];
|
||||
if(empty($this->uid)){
|
||||
return false;
|
||||
}
|
||||
$t = strpos($path,$this->uid);
|
||||
if($t == 0){
|
||||
$this->myPath = substr($path,$t+strlen($this->uid));
|
||||
}else{
|
||||
$this->myPath = $path;
|
||||
}
|
||||
$this->myPath = empty($this->myPath) ? "/" : $this->myPath;
|
||||
}
|
||||
|
||||
function createFile($name, $data = NULL){
|
||||
$userData = Db::name("users")->where("id",$this->uid)->find();
|
||||
$groupData = Db::name("groups")->where("id",$userData["user_group"])->find();
|
||||
$policyData = Db::name("policy")->where("id",$groupData["policy_name"])->find();
|
||||
$uploadHandle = new UploadHandler($groupData["policy_name"],$this->uid);
|
||||
$allowedExt = UploadHandler::getAllowedExt(json_decode($policyData["filetype"],true));
|
||||
if(!empty($allowedExt)){
|
||||
$ex = explode(".",$name);
|
||||
$fileSuffix = end($ex);
|
||||
if(!in_array($fileSuffix, explode(",",$allowedExt))){
|
||||
throw new DAV\Exception\InvalidResourceType('File type not allowed');
|
||||
}
|
||||
}
|
||||
if($policyData["policy_type"] !="local"){
|
||||
throw new DAV\Exception\Forbidden('Poliyc not supported yet');
|
||||
}
|
||||
$fileSize = fstat($data)["size"];
|
||||
if(empty($fileSize)){
|
||||
$fileSize = 0;
|
||||
}
|
||||
if($fileSize>$policyData["max_size"]){
|
||||
throw new DAV\Exception\InsufficientStorage('File is to large');
|
||||
}
|
||||
if(!FileManage::sotrageCheck($this->uid,$fileSize)){
|
||||
throw new DAV\Exception\InsufficientStorage('Quota is not enough');
|
||||
}
|
||||
if($policyData['autoname']){
|
||||
$fileName = $uploadHandle->getObjName($policyData['namerule'],"local",$name);
|
||||
}else{
|
||||
$fileName = $name;
|
||||
}
|
||||
$generatePath = $uploadHandle->getDirName($policyData['dirrule']);
|
||||
$savePath = ROOT_PATH . 'public/uploads/'.$generatePath;
|
||||
if(!file_exists($savePath)){
|
||||
mkdir($savePath,0777,true);
|
||||
}
|
||||
file_put_contents($savePath."/".$fileName, $data);
|
||||
$jsonData = array(
|
||||
"path" => str_replace("/",",",ltrim($this->myPath,"/")),
|
||||
"fname" => $name,
|
||||
"objname" => $generatePath."/".$fileName,
|
||||
"fsize" => $fileSize,
|
||||
);
|
||||
@list($width, $height, $type, $attr) = getimagesize(rtrim($savePath, DS).DS.$fileName);
|
||||
$picInfo = empty($width)?" ":$width.",".$height;
|
||||
$addAction = FileManage::addFile($jsonData,$policyData,$this->uid,$picInfo);
|
||||
if(!$addAction[0]){
|
||||
unlink($savePath."/".$fileName);
|
||||
throw new DAV\Exception\Conflict($addAction[1]);
|
||||
}
|
||||
FileManage::storageCheckOut($this->uid,$jsonData["fsize"]);
|
||||
//echo json_encode(array("key" => $info["name"]));
|
||||
}
|
||||
|
||||
function getQuotaInfo() {
|
||||
$this->userObj = new User($this->uid,"",true);
|
||||
$quotaInfo = json_decode($this->userObj->getMemory(true),true);
|
||||
return [
|
||||
$quotaInfo["used"],
|
||||
$quotaInfo["total"]
|
||||
];
|
||||
|
||||
}
|
||||
|
||||
function setName($name){
|
||||
$reqPath = $this->myPath;
|
||||
$ex = explode("/",$reqPath);
|
||||
$newPath = rtrim(dirname($reqPath) == "\\" ?"/":dirname($reqPath),"/")."/".$name;
|
||||
$renameAction = json_decode(FileManage::RenameHandler($reqPath,$newPath,$this->uid,true),true);
|
||||
if(!$renameAction["result"]["success"]){
|
||||
throw new DAV\Exception\InvalidResourceType($renameAction["result"]["error"]);
|
||||
}
|
||||
}
|
||||
|
||||
function getChildren() {
|
||||
$children = array();
|
||||
$fileList = Db::name('files')->where('upload_user',$this->uid)->where('dir',$this->myPath)->select();
|
||||
$dirList = Db::name('folders')->where('owner',$this->uid)->where('position',$this->myPath)->select();
|
||||
foreach($fileList as $node) {
|
||||
// Ignoring files staring with .
|
||||
$children[] = $this->getChildFile($node,false);
|
||||
}
|
||||
foreach($dirList as $node) {
|
||||
// Ignoring files staring with .
|
||||
$children[] = $this->getChildDir($node,true);
|
||||
}
|
||||
return $children;
|
||||
}
|
||||
|
||||
function getChildFile($name){
|
||||
$path = $this->uid.rtrim($this->myPath,"/") . '/' . $name["orign_name"];
|
||||
return new Object($path);
|
||||
}
|
||||
|
||||
function getChildDir($name){
|
||||
$path = $this->uid.rtrim($this->myPath,"/") . '/' . $name["folder_name"];
|
||||
return new Directory($path);
|
||||
}
|
||||
|
||||
function delete(){
|
||||
foreach ($this->getChildren() as $child) $child->delete();
|
||||
FileManage::DirDeleteHandler([0=>$this->myPath],$this->uid);
|
||||
}
|
||||
|
||||
function getChild($name) {
|
||||
if(!$this->childExists($name)){
|
||||
throw new DAV\Exception\NotFound('File with name ' . $name . ' could not be located');
|
||||
}
|
||||
$path = $this->uid.rtrim($this->myPath,"/") . '/' . $name;
|
||||
if($this->findDir(rtrim($this->myPath,"/") . '/' . $name)){
|
||||
$returnObj = new Directory($path);
|
||||
return $returnObj;
|
||||
}else{
|
||||
return new Object($path);
|
||||
}
|
||||
}
|
||||
|
||||
function childExists($name) {
|
||||
$fileObj = new Object($this->uid.rtrim($this->myPath,"/") . '/' . $name);
|
||||
if($this->findDir(rtrim($this->myPath,"/") . '/' . $name) || $fileObj->isExist){
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function findDir($path){
|
||||
if($path == "/"){
|
||||
return true;
|
||||
}
|
||||
$explode = explode("/",$path);
|
||||
$dirName = end($explode);
|
||||
$rootPath = rtrim($path,"/".$dirName);
|
||||
$rootPath = empty($rootPath) ? "/" : $rootPath;
|
||||
$dirData = Db::name('folders')->where('owner',$this->uid)->where('position',dirname($path) == "\\" ?"/":dirname($path))->where("folder_name",basename($path))->find();
|
||||
if(empty($dirData)){
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function getName() {
|
||||
$explode = explode("/", $this->myPath);
|
||||
return end($explode);
|
||||
|
||||
}
|
||||
|
||||
function createDirectory($name) {
|
||||
$createAction = FileManage::createFolder($name,$this->myPath,$this->uid);
|
||||
if(!$createAction["result"]["success"]){
|
||||
die($this->myPath);
|
||||
throw new DAV\Exception\InvalidResourceType($createAction["result"]["error"]);
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,89 @@
|
||||
<?php
|
||||
namespace app\index\model;
|
||||
|
||||
use think\Model;
|
||||
|
||||
class Image extends Model{
|
||||
private $file; //图片地址
|
||||
private $width; //图片长度
|
||||
private $height; //图片长度
|
||||
private $itype; //图片类型
|
||||
private $img; //原图的资源句柄
|
||||
private $new; //新图的资源句柄
|
||||
|
||||
//构造方法,初始化
|
||||
public function __construct($_file) {
|
||||
$this->file = $_file;
|
||||
list($this->width, $this->height, $this->itype) = getimagesize($this->file);
|
||||
$this->img = $this->getFromImg($this->file, $this->itype);
|
||||
}
|
||||
//缩略图(固定长高容器,图像等比例,扩容填充,裁剪)[固定了大小,不失真,不变形]
|
||||
public function thumb($new_width = 0,$new_height = 0) {
|
||||
|
||||
if (empty($new_width) && empty($new_height)) {
|
||||
$new_width = $this->width;
|
||||
$new_height = $this->height;
|
||||
}
|
||||
|
||||
if (!is_numeric($new_width) || !is_numeric($new_height)) {
|
||||
$new_width = $this->width;
|
||||
$new_height = $this->height;
|
||||
}
|
||||
|
||||
//创建一个容器
|
||||
$_n_w = $new_width;
|
||||
$_n_h = $new_height;
|
||||
|
||||
//创建裁剪点
|
||||
$_cut_width = 0;
|
||||
$_cut_height = 0;
|
||||
|
||||
if ($this->width < $this->height) {
|
||||
$new_width = ($new_height / $this->height) * $this->width;
|
||||
} else {
|
||||
$new_height = ($new_width / $this->width) * $this->height;
|
||||
}
|
||||
if ($new_width < $_n_w) { //如果新高度小于新容器高度
|
||||
$r = $_n_w / $new_width; //按长度求出等比例因子
|
||||
$new_width *= $r; //扩展填充后的长度
|
||||
$new_height *= $r; //扩展填充后的高度
|
||||
$_cut_height = ($new_height - $_n_h) / 2; //求出裁剪点的高度
|
||||
}
|
||||
|
||||
if ($new_height < $_n_h) { //如果新高度小于容器高度
|
||||
$r = $_n_h / $new_height; //按高度求出等比例因子
|
||||
$new_width *= $r; //扩展填充后的长度
|
||||
$new_height *= $r; //扩展填充后的高度
|
||||
$_cut_width = ($new_width - $_n_w) / 2; //求出裁剪点的长度
|
||||
}
|
||||
|
||||
$this->new = imagecreatetruecolor($_n_w,$_n_h);
|
||||
imagecopyresampled($this->new,$this->img,0,0,$_cut_width,$_cut_height,$new_width,$new_height,$this->width,$this->height);
|
||||
}
|
||||
|
||||
//加载图片,各种类型,返回图片的资源句柄
|
||||
public function getFromImg($_file, $_type) {
|
||||
switch ($_type) {
|
||||
case 1 :
|
||||
$img = imagecreatefromgif($_file);
|
||||
break;
|
||||
case 2 :
|
||||
$img = imagecreatefromjpeg($_file);
|
||||
break;
|
||||
case 3 :
|
||||
$img = imagecreatefrompng($_file);
|
||||
break;
|
||||
default:
|
||||
$img = '';
|
||||
}
|
||||
return $img;
|
||||
}
|
||||
|
||||
//图像输出
|
||||
public function output($name = "") {
|
||||
imagepng($this->new,$this->file.$name);//第二个参数为新生成的图片名
|
||||
imagedestroy($this->img);
|
||||
imagedestroy($this->new);
|
||||
}
|
||||
}
|
||||
?>
|
||||
@ -0,0 +1,60 @@
|
||||
<?php
|
||||
namespace app\index\model;
|
||||
|
||||
use think\Model;
|
||||
use think\Db;
|
||||
use \app\index\model\Option;
|
||||
use \PHPMailer\PHPMailer\PHPMailer;
|
||||
use \PHPMailer\PHPMailer\Exception;
|
||||
|
||||
class Mail extends Model{
|
||||
|
||||
public $fromName;
|
||||
public $fromAdress;
|
||||
public $smtpHost;
|
||||
public $smtpPort;
|
||||
public $replyTo;
|
||||
public $smtpUser;
|
||||
public $smtpPass;
|
||||
public $encriptionType;
|
||||
public $errorMsg;
|
||||
|
||||
public function __construct(){
|
||||
$mailOptions = Option::getValues(["mail"]);
|
||||
$this->fromName = $mailOptions["fromName"];
|
||||
$this->fromAdress = $mailOptions["fromAdress"];
|
||||
$this->smtpHost = $mailOptions["smtpHost"];
|
||||
$this->smtpPort = $mailOptions["smtpPort"];
|
||||
$this->replyTo = $mailOptions["replyTo"];
|
||||
$this->smtpUser = $mailOptions["smtpUser"];
|
||||
$this->smtpPass = $mailOptions["smtpPass"];
|
||||
$this->encriptionType = $mailOptions["encriptionType"];
|
||||
}
|
||||
|
||||
public function Send($to,$name,$title,$content){
|
||||
$mail = new PHPMailer();
|
||||
$mail->isSMTP();
|
||||
$mail->SMTPAuth=true;
|
||||
$mail->Host = $this->smtpHost;
|
||||
if(!empty($this->encriptionType) && $this->encriptionType != "no"){
|
||||
$mail->SMTPSecure = $this->encriptionType;
|
||||
}
|
||||
$mail->Port = $this->smtpPort;
|
||||
$mail->CharSet = 'UTF-8';
|
||||
$mail->FromName = $this->fromName;
|
||||
$mail->Username =$this->smtpUser;
|
||||
$mail->Password = $this->smtpPass;
|
||||
$mail->From = $this->fromAdress;
|
||||
$mail->isHTML(true);
|
||||
$mail->addAddress($to,$name);
|
||||
$mail->Subject = $title;
|
||||
$mail->Body = $content;
|
||||
$status = $mail->send();
|
||||
if(!$status){
|
||||
$this->errorMsg = $mail->ErrorInfo;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
?>
|
||||
@ -0,0 +1,95 @@
|
||||
<?php
|
||||
namespace app\index\model;
|
||||
|
||||
use think\Model;
|
||||
use think\Db;
|
||||
use Sabre\DAV;
|
||||
use \app\index\model\FileManage;
|
||||
|
||||
class Object extends DAV\File{
|
||||
|
||||
private $myPath;
|
||||
public $id;
|
||||
public $fileData;
|
||||
public $uid;
|
||||
public $fileName;
|
||||
public $dir;
|
||||
public $actualPath;
|
||||
public $isExist;
|
||||
|
||||
function __construct($path) {
|
||||
$ex = explode("/",$path);
|
||||
$this->uid = $ex[0];
|
||||
$t = strpos($path,$this->uid);
|
||||
if($t == 0){
|
||||
$this->myPath = substr($path,$t+strlen($this->uid));
|
||||
}else{
|
||||
$this->myPath = $path;
|
||||
}
|
||||
$this->fileName = end($ex);
|
||||
$this->dir = dirname($this->myPath) == "\\" ? "/" :dirname($this->myPath);
|
||||
$this->fileData = Db::name('files')->where('upload_user',$this->uid)->where('dir',$this->dir)->where('orign_name',$this->fileName)->find();
|
||||
if(empty($this->fileData)){
|
||||
$this->isExist = false;
|
||||
}else{
|
||||
$this->isExist = true;
|
||||
}
|
||||
$this->actualPath = ROOT_PATH . 'public/uploads/'.$this->fileData["pre_name"];
|
||||
}
|
||||
|
||||
function getName() {
|
||||
return $this->fileName;
|
||||
}
|
||||
|
||||
function get() {
|
||||
return fopen($this->actualPath, 'r');
|
||||
}
|
||||
|
||||
function getSize() {
|
||||
return $this->fileData["size"];
|
||||
}
|
||||
|
||||
function setName($name){
|
||||
$reqPath = $this->myPath;
|
||||
$ex = explode("/",$reqPath);
|
||||
$newPath = rtrim($reqPath,end($ex)).$name;
|
||||
$renameAction = json_decode(FileManage::RenameHandler($reqPath,$newPath,$this->uid,true),true);
|
||||
if(!$renameAction["result"]["success"]){
|
||||
throw new DAV\Exception\Forbidden($renameAction["result"]["error"]);
|
||||
}
|
||||
}
|
||||
|
||||
function getContentType() {
|
||||
return null;
|
||||
}
|
||||
|
||||
function put($data){
|
||||
$fileSize = (int)$_SERVER['CONTENT_LENGTH'];
|
||||
if(!FileManage::sotrageCheck($this->uid,$fileSize)){
|
||||
throw new DAV\Exception\InsufficientStorage("Quota is not enough");
|
||||
}
|
||||
$filePath = ROOT_PATH . 'public/uploads/' . $this->fileData["pre_name"];
|
||||
file_put_contents($filePath, "");
|
||||
file_put_contents($filePath, $data);
|
||||
FileManage::storageGiveBack($this->uid,$this->fileData["size"]);
|
||||
FileManage::storageCheckOut($this->uid,$fileSize);
|
||||
@list($width, $height, $type, $attr) = getimagesize($filePath);
|
||||
$picInfo = empty($width)?" ":$width.",".$height;
|
||||
Db::name('files')->where('id', $this->fileData["id"])->update(['size' => $fileSize,'pic_info' => $picInfo]);
|
||||
}
|
||||
|
||||
function delete(){
|
||||
FileManage::DeleteHandler([0=>$this->myPath],$this->uid);
|
||||
}
|
||||
|
||||
function getETag() {
|
||||
|
||||
return '"' . sha1(
|
||||
fileinode($this->actualPath) .
|
||||
filesize($this->actualPath) .
|
||||
filemtime($this->actualPath)
|
||||
) . '"';
|
||||
|
||||
}
|
||||
}
|
||||
?>
|
||||
@ -0,0 +1,16 @@
|
||||
<?php
|
||||
namespace app\index\model;
|
||||
|
||||
use think\Model;
|
||||
use think\Db;
|
||||
|
||||
class Option extends Model{
|
||||
static function getValues($groups = ['basic']){
|
||||
$t = Db::name('options')->where('option_type','in',$groups)->column('option_value','option_name');
|
||||
return $t;
|
||||
}
|
||||
static function getValue($optionName){
|
||||
return Db::name('options')->where('option_name',$optionName)->value('option_value');
|
||||
}
|
||||
}
|
||||
?>
|
||||
@ -0,0 +1,308 @@
|
||||
<?php
|
||||
namespace app\index\model;
|
||||
|
||||
use think\Model;
|
||||
use think\Db;
|
||||
use \think\Session;
|
||||
use \app\index\model\FileManage;
|
||||
use \app\index\model\Option;
|
||||
use \app\index\model\User;
|
||||
|
||||
class ShareHandler extends Model{
|
||||
|
||||
public $shareData;
|
||||
public $querryStatus = true;
|
||||
public $shareOwner;
|
||||
public $fileData;
|
||||
public $dirData;
|
||||
public $lockStatus = false;
|
||||
|
||||
public function __construct($key,$notExist=true){
|
||||
$this->shareData = Db::name('shares')->where('share_key',$key)->find();
|
||||
if(empty($this->shareData)){
|
||||
$this->querryStatus = false;
|
||||
}else{
|
||||
if($notExist){
|
||||
if($this->shareData["source_type"] == "file"){
|
||||
$this->fileShareHandler();
|
||||
}else{
|
||||
$this->dirShareHandler();
|
||||
}
|
||||
}
|
||||
}
|
||||
if($this->shareData["type"] == "private"){
|
||||
$this->lockStatus = Session::has("share".$this->shareData["id"])?false:true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function deleteShare($uid){
|
||||
if($this->shareData["owner"] != $uid){
|
||||
return array(
|
||||
"error" => 1,
|
||||
"msg" => "无权操作"
|
||||
);
|
||||
}
|
||||
Db::name('shares')->where('share_key',$this->shareData["share_key"])->delete();
|
||||
return array(
|
||||
"error" => 0,
|
||||
"msg" => "分享取消成功"
|
||||
);
|
||||
}
|
||||
|
||||
public function changePromission($uid,$ignore=false){
|
||||
if($this->shareData["owner"] != $uid && $ignore == false){
|
||||
return array(
|
||||
"error" => 1,
|
||||
"msg" => "无权操作"
|
||||
);
|
||||
}
|
||||
Db::name('shares')->where('share_key',$this->shareData["share_key"])->update([
|
||||
'type' => $this->shareData["type"] == "public"?"private":"public",
|
||||
'share_pwd' => self::getRandomKey(6)
|
||||
]);
|
||||
return array(
|
||||
"error" =>0,
|
||||
"msg" => "更改成功"
|
||||
);
|
||||
}
|
||||
|
||||
public function checkPwd($pwd){
|
||||
if($pwd == $this->shareData["share_pwd"]){
|
||||
Session::set("share".$this->shareData["id"],"1");
|
||||
return array(
|
||||
"error" =>0,
|
||||
);
|
||||
}else{
|
||||
return array(
|
||||
"error" =>1,
|
||||
"msg" => "密码错误"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public function checkSession($user){
|
||||
if($this->lockStatus){
|
||||
return [false,"会话过期,请刷新页面"];
|
||||
}
|
||||
if(Option::getValue("allowdVisitorDownload") == "false" && !$user->loginStatus){
|
||||
return [false,"未登录用户禁止下载,请先登录"];
|
||||
}
|
||||
if(!$this->querryStatus){
|
||||
return [false,"分享不存在,请检查链接是否正确"];
|
||||
}
|
||||
return[true,null];
|
||||
}
|
||||
|
||||
public function Download($user){
|
||||
$checkStatus = $this->checkSession($user);
|
||||
if(!$checkStatus[0]){
|
||||
return [$checkStatus[0],$checkStatus[1]];
|
||||
}
|
||||
$reqPath = Db::name('files')->where('id',$this->shareData["source_name"])->find();
|
||||
if($reqPath["dir"] == "/"){
|
||||
$reqPath["dir"] = $reqPath["dir"].$reqPath["orign_name"];
|
||||
}else{
|
||||
$reqPath["dir"] = $reqPath["dir"]."/".$reqPath["orign_name"];
|
||||
}
|
||||
$fileObj = new FileManage($reqPath["dir"],$this->shareData["owner"]);
|
||||
$FileHandler = $fileObj->Download();
|
||||
return $FileHandler;
|
||||
}
|
||||
|
||||
public function DownloadFolder($user,$path){
|
||||
$checkStatus = $this->checkSession($user);
|
||||
if(!$checkStatus[0]){
|
||||
return [$checkStatus[0],$checkStatus[1]];
|
||||
}
|
||||
$reqPath = Db::name('folders')->where('position_absolute',$this->shareData["source_name"])->find();
|
||||
$path = $path == "/"?"":$path;
|
||||
$fileObj = new FileManage($reqPath["position_absolute"].$path,$this->shareData["owner"]);
|
||||
$this->numIncrease("download_num");
|
||||
$FileHandler = $fileObj->Download();
|
||||
return $FileHandler;
|
||||
}
|
||||
|
||||
public function ListFile($path){
|
||||
if($this->lockStatus){
|
||||
die('{ "result": { "success": false, "error": "会话过期,请重新登陆" } }');
|
||||
}
|
||||
if(!$this->querryStatus){
|
||||
return [false,"分享不存在,请检查链接是否正确"];
|
||||
}
|
||||
$reqPath = Db::name('folders')->where('position_absolute',$this->shareData["source_name"])->find();
|
||||
$path = $path == "/"?"":$path;
|
||||
return FileManage::ListFile($this->shareData["source_name"].$path,$this->shareData["owner"]);
|
||||
}
|
||||
|
||||
public function Preview($user){
|
||||
$checkStatus = $this->checkSession($user);
|
||||
if(!$checkStatus[0]){
|
||||
return [$checkStatus[0],$checkStatus[1]];
|
||||
}
|
||||
$reqPath = Db::name('files')->where('id',$this->shareData["source_name"])->find();
|
||||
if($reqPath["dir"] == "/"){
|
||||
$reqPath["dir"] = $reqPath["dir"].$reqPath["orign_name"];
|
||||
}else{
|
||||
$reqPath["dir"] = $reqPath["dir"]."/".$reqPath["orign_name"];
|
||||
}
|
||||
$fileObj = new FileManage($reqPath["dir"],$this->shareData["owner"]);
|
||||
return $fileObj->PreviewHandler();
|
||||
}
|
||||
|
||||
public function PreviewFolder($user,$path,$folder=false){
|
||||
$checkStatus = $this->checkSession($user);
|
||||
if(!$checkStatus[0]){
|
||||
return [$checkStatus[0],$checkStatus[1]];
|
||||
}
|
||||
$reqPath = Db::name('folders')->where('position_absolute',$this->shareData["source_name"])->find();
|
||||
if($folder){
|
||||
$fileObj = new FileManage($path,$this->shareData["owner"]);
|
||||
}else{
|
||||
$fileObj = new FileManage($reqPath["position_absolute"].$path,$this->shareData["owner"]);
|
||||
}
|
||||
return $fileObj->PreviewHandler();
|
||||
}
|
||||
|
||||
public function listPic($id,$path){
|
||||
if($this->lockStatus){
|
||||
die('{ "result": { "success": false, "error": "会话过期,请重新登陆" } }');
|
||||
}
|
||||
if(!$this->querryStatus){
|
||||
return [false,"分享不存在,请检查链接是否正确"];
|
||||
}
|
||||
$reqPath = Db::name('folders')->where('position_absolute',$this->shareData["source_name"])->find();
|
||||
$path = $path == "/"?"":$path;
|
||||
return FileManage::listPic($this->shareData["source_name"].$path,$this->shareData["owner"],"/Share/Preview/".$this->shareData["share_key"]."?folder=true");
|
||||
}
|
||||
|
||||
public function numIncrease($name){
|
||||
Db::name('shares')->where('share_key',$this->shareData["share_key"])->setInc($name);
|
||||
}
|
||||
|
||||
public function getDownloadUrl($user){
|
||||
if(Option::getValue("allowdVisitorDownload") == "false" && !$user->loginStatus){
|
||||
return array(
|
||||
"error" => 1,
|
||||
"msg" => "未登录用户禁止下载,请先登录",
|
||||
);
|
||||
}else{
|
||||
$this->numIncrease("download_num");
|
||||
return array(
|
||||
"error" => 0,
|
||||
"result" => "/Share/Download/".$this->shareData["share_key"],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public function fileShareHandler(){
|
||||
$this->shareOwner = new User($this->shareData["owner"],null,true);
|
||||
$this->fileData = Db::name('files')
|
||||
->where('upload_user',$this->shareData["owner"])
|
||||
->where('id',(int)$this->shareData["source_name"])
|
||||
->find();
|
||||
if(!$this->shareOwner->loginStatus || empty($this->fileData)){
|
||||
$this->querryStatus = false;
|
||||
}else{
|
||||
$this->querryStatus = true;
|
||||
}
|
||||
}
|
||||
|
||||
public function dirShareHandler(){
|
||||
$this->shareOwner = new User($this->shareData["owner"],null,true);
|
||||
$this->dirData = Db::name('folders')
|
||||
->where('owner',$this->shareData["owner"])
|
||||
->where('position_absolute',$this->shareData["source_name"])
|
||||
->find();
|
||||
if(!$this->shareOwner->loginStatus || empty($this->dirData)){
|
||||
$this->querryStatus = false;
|
||||
}else{
|
||||
$this->querryStatus = true;
|
||||
}
|
||||
}
|
||||
|
||||
static function createShare($fname,$type,$user,$group){
|
||||
if(!$group["allow_share"]){
|
||||
self::setError("您当前的用户组无权分享文件");
|
||||
}
|
||||
$path = FileManage::getFileName($fname)[1];
|
||||
$fnameTmp = FileManage::getFileName($fname)[0];
|
||||
$fileRecord = Db::name('files')->where('upload_user',$user["id"])->where('orign_name',$fnameTmp)->where('dir',$path)->find();
|
||||
if(empty($fileRecord)){
|
||||
self::createDirShare($fname,$type,$user,$group);
|
||||
}else{
|
||||
self::createFileShare($fileRecord,$type,$user,$group);
|
||||
}
|
||||
}
|
||||
|
||||
static function setError($text){
|
||||
die('{ "result": { "success": false, "error": "'.$text.'" } }');
|
||||
}
|
||||
|
||||
static function setSuccess($text){
|
||||
die('{ "result": "'.$text.'" }');
|
||||
}
|
||||
|
||||
static function createDirShare($fname,$type,$user,$group){
|
||||
$dirRecord = Db::name('folders')->where('owner',$user["id"])->where('position_absolute',$fname)->find();
|
||||
if(empty($dirRecord)){
|
||||
self::setError("目录不存在");
|
||||
}
|
||||
$shareKey = self::getRandomKey(8);
|
||||
$sharePwd = $type=="public" ? "0" : self::getRandomKey(6);
|
||||
$SQLData = [
|
||||
'type' => $type=="public" ? "public" : "private",
|
||||
'share_time' => date("Y-m-d H:i:s"),
|
||||
'owner' => $user["id"],
|
||||
'source_name' => $fname,
|
||||
'origin_name' => $fname,
|
||||
'download_num' => 0,
|
||||
'view_num' => 0,
|
||||
'source_type' => "dir",
|
||||
'share_key' => $shareKey,
|
||||
'share_pwd' => $sharePwd,
|
||||
];
|
||||
if(Db::name('shares')->insert($SQLData)){
|
||||
if($sharePwd == "0"){
|
||||
self::setSuccess(Option::getValue("siteURL")."s/".$shareKey);
|
||||
}else{
|
||||
self::setSuccess("链接:".Option::getValue("siteURL")."s/".$shareKey." 密码:".$sharePwd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static function createFileShare($file,$type,$user,$group){
|
||||
$shareKey = self::getRandomKey(8);
|
||||
$sharePwd = $type=="public" ? "0" : self::getRandomKey(6);
|
||||
$SQLData = [
|
||||
'type' => $type=="public" ? "public" : "private",
|
||||
'share_time' => date("Y-m-d H:i:s"),
|
||||
'owner' => $user["id"],
|
||||
'source_name' => $file["id"],
|
||||
'origin_name' => $file["orign_name"],
|
||||
'download_num' => 0,
|
||||
'view_num' => 0,
|
||||
'source_type' => "file",
|
||||
'share_key' => $shareKey,
|
||||
'share_pwd' => $sharePwd,
|
||||
];
|
||||
if(Db::name('shares')->insert($SQLData)){
|
||||
if($sharePwd == "0"){
|
||||
self::setSuccess(Option::getValue("siteURL")."s/".$shareKey);
|
||||
}else{
|
||||
self::setSuccess("链接:".Option::getValue("siteURL")."s/".$shareKey." 密码:".$sharePwd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static function getRandomKey($length = 16){
|
||||
$charTable = 'abcdefghijklmnopqrstuvwxyz0123456789';
|
||||
$result = "";
|
||||
for ( $i = 0; $i < $length; $i++ ){
|
||||
$result .= $charTable[ mt_rand(0, strlen($charTable) - 1) ];
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
}
|
||||
?>
|
||||
@ -0,0 +1,91 @@
|
||||
<?php
|
||||
namespace app\index\model;
|
||||
|
||||
use think\Model;
|
||||
use think\Db;
|
||||
|
||||
class Thumb extends Model{
|
||||
|
||||
private $file; //图片地址
|
||||
private $width; //图片长度
|
||||
private $height; //图片长度
|
||||
private $img_type; //图片类型
|
||||
private $img; //原图的资源句柄
|
||||
private $new; //新图的资源句柄
|
||||
|
||||
//构造方法,初始化
|
||||
public function __construct($_file) {
|
||||
$this->file = $_file;
|
||||
list($this->width, $this->height, $this->img_type) = getimagesize($this->file);
|
||||
$this->img = $this->getFromImg($this->file, $this->img_type);
|
||||
}
|
||||
//缩略图(固定长高容器,图像等比例,扩容填充,裁剪)[固定了大小,不失真,不变形]
|
||||
public function thumb($new_width = 0,$new_height = 0) {
|
||||
|
||||
if (empty($new_width) && empty($new_height)) {
|
||||
$new_width = $this->width;
|
||||
$new_height = $this->height;
|
||||
}
|
||||
|
||||
if (!is_numeric($new_width) || !is_numeric($new_height)) {
|
||||
$new_width = $this->width;
|
||||
$new_height = $this->height;
|
||||
}
|
||||
|
||||
//创建一个容器
|
||||
$_n_w = $new_width;
|
||||
$_n_h = $new_height;
|
||||
|
||||
//创建裁剪点
|
||||
$_cut_width = 0;
|
||||
$_cut_height = 0;
|
||||
|
||||
if ($this->width < $this->height) {
|
||||
$new_width = ($new_height / $this->height) * $this->width;
|
||||
} else {
|
||||
$new_height = ($new_width / $this->width) * $this->height;
|
||||
}
|
||||
if ($new_width < $_n_w) { //如果新高度小于新容器高度
|
||||
$r = $_n_w / $new_width; //按长度求出等比例因子
|
||||
$new_width *= $r; //扩展填充后的长度
|
||||
$new_height *= $r; //扩展填充后的高度
|
||||
$_cut_height = ($new_height - $_n_h) / 2; //求出裁剪点的高度
|
||||
}
|
||||
|
||||
if ($new_height < $_n_h) { //如果新高度小于容器高度
|
||||
$r = $_n_h / $new_height; //按高度求出等比例因子
|
||||
$new_width *= $r; //扩展填充后的长度
|
||||
$new_height *= $r; //扩展填充后的高度
|
||||
$_cut_width = ($new_width - $_n_w) / 2; //求出裁剪点的长度
|
||||
}
|
||||
|
||||
$this->new = imagecreatetruecolor($_n_w,$_n_h);
|
||||
imagecopyresampled($this->new,$this->img,0,0,$_cut_width,$_cut_height,$new_width,$new_height,$this->width,$this->height);
|
||||
}
|
||||
|
||||
//加载图片,各种类型,返回图片的资源句柄
|
||||
private function getFromImg($_file, $_type) {
|
||||
switch ($_type) {
|
||||
case 1 :
|
||||
$img = imagecreatefromgif($_file);
|
||||
break;
|
||||
case 2 :
|
||||
$img = imagecreatefromjpeg($_file);
|
||||
break;
|
||||
case 3 :
|
||||
$img = imagecreatefrompng($_file);
|
||||
break;
|
||||
default:
|
||||
$img = '';
|
||||
}
|
||||
return $img;
|
||||
}
|
||||
|
||||
//图像输出
|
||||
public function out($name) {
|
||||
imagepng($this->new,$name);//第二个参数为新生成的图片名
|
||||
imagedestroy($this->img);
|
||||
imagedestroy($this->new);
|
||||
}
|
||||
}
|
||||
?>
|
||||
@ -0,0 +1,53 @@
|
||||
<?php
|
||||
namespace app\index\model;
|
||||
|
||||
use think\Model;
|
||||
use think\Db;
|
||||
use \think\Session;
|
||||
use \PHPGangsta_GoogleAuthenticator;
|
||||
use \Endroid\QrCode\QrCode;
|
||||
use \app\index\model\Option;
|
||||
|
||||
class TwoFactor extends Model{
|
||||
|
||||
public $ga;
|
||||
public $secretKey;
|
||||
public $checkResult;
|
||||
|
||||
public function __construct(){
|
||||
$this->ga = new PHPGangsta_GoogleAuthenticator();
|
||||
}
|
||||
|
||||
public function qrcodeRender(){
|
||||
ob_end_clean();
|
||||
header("content-type: image/png");
|
||||
$this->secretKey = $this->ga->createSecret();
|
||||
$qrCode = new QrCode();
|
||||
session("two_factor_enable",$this->secretKey);
|
||||
$qrCode->setText(urldecode($this->ga->getQRCodeGoogleUrl(Option::getValue("siteName"), $this->secretKey)))
|
||||
->setPadding(5)
|
||||
->render();
|
||||
}
|
||||
|
||||
public function confirmCode($key,$code){
|
||||
$this->secretKey = $key;
|
||||
if(empty($code)){
|
||||
return [0,"验证码不能为空"];
|
||||
}
|
||||
if(empty($key)){
|
||||
return [0,"二维码过期,请刷新页面后重新扫描"];
|
||||
}
|
||||
$this->checkResult = $this->ga->verifyCode($key, $code, 2);
|
||||
if($this->checkResult){
|
||||
return [1,"验证成功"];
|
||||
}else{
|
||||
return [0,"验证码错误"];
|
||||
}
|
||||
}
|
||||
|
||||
public function bindUser($uid){
|
||||
Db::name("users")->where("id",$uid)->update(["two_step" => $this->secretKey]);
|
||||
}
|
||||
|
||||
}
|
||||
?>
|
||||
@ -0,0 +1,452 @@
|
||||
<?php
|
||||
namespace app\index\model;
|
||||
|
||||
require_once 'extend/Qiniu/functions.php';
|
||||
|
||||
use think\Model;
|
||||
use think\Db;
|
||||
use Qiniu\Auth;
|
||||
use \app\index\model\Option;
|
||||
use \app\index\model\FileManage;
|
||||
|
||||
class UploadHandler extends Model{
|
||||
|
||||
public $policyId;
|
||||
public $policyContent;
|
||||
public $userId;
|
||||
public $chunkData;
|
||||
public $fileSizeTmp;
|
||||
public $ossToken;
|
||||
public $ossSign;
|
||||
public $ossCallback;
|
||||
public $ossAccessId;
|
||||
public $ossFileName;
|
||||
public $ossCallBack;
|
||||
public $upyunPolicy;
|
||||
public $s3Policy;
|
||||
public $s3Sign;
|
||||
public $dirName;
|
||||
public $s3Credential;
|
||||
public $siteUrl;
|
||||
public $callBackKey;
|
||||
|
||||
public function __construct($id,$uid){
|
||||
$this->policyId = $id;
|
||||
$this->userId = $uid;
|
||||
$this->policyContent = Db::name('policy')->where('id',$id)->find();
|
||||
}
|
||||
|
||||
public function setChunk($chunkId,$chunkSum,$file){
|
||||
$sqlData = [
|
||||
'user' => $this->userId,
|
||||
'ctx' => self::getRandomKey(),
|
||||
'obj_name' => self::getRandomKey(8),
|
||||
'time' => date("Y-m-d H:i:s"),
|
||||
'chunk_id' => $chunkId,
|
||||
'sum' => $chunkSum,
|
||||
];
|
||||
$this->chunkData = $sqlData;
|
||||
Db::name('chunks')->insert($sqlData);
|
||||
$this->saveChunk($file);
|
||||
$this->chunkInfo();
|
||||
}
|
||||
|
||||
public function saveChunk($file){
|
||||
$chunkSize = strlen($file);
|
||||
if(!FileManage::sotrageCheck($this->userId,$chunkSize)){
|
||||
$this->setError("空间容量不足",false);
|
||||
}
|
||||
FileManage::storageCheckOut($this->userId,$chunkSize);
|
||||
if($chunkSize >=4195304){
|
||||
$this->setError("分片错误",false);
|
||||
}
|
||||
$chunkObj=fopen (ROOT_PATH . 'public/uploads/chunks/'.$this->chunkData["obj_name"].".chunk","w+");
|
||||
$chunkObjWrite = fwrite ($chunkObj,$file);
|
||||
if(!$chunkObj || !$chunkObjWrite){
|
||||
$this->setError("分片创建错误",false);
|
||||
}
|
||||
}
|
||||
|
||||
public function chunkInfo(){
|
||||
$returnJson = array(
|
||||
"ctx" => $this->chunkData["ctx"],
|
||||
);
|
||||
echo json_encode($returnJson);
|
||||
return 0;
|
||||
}
|
||||
|
||||
public function generateFile($ctx,$fname,$path){
|
||||
$ctxTmp = explode(",",$ctx);
|
||||
$chunks = Db::name('chunks')->where([
|
||||
'ctx' => ["in",$ctxTmp],
|
||||
])->order('id asc')->select();
|
||||
$file = $this->combineChunks($chunks);
|
||||
$this->filterCheck($file,$fname);
|
||||
$suffixTmp = explode('.', $fname);
|
||||
$fileSuffix = array_pop($suffixTmp);
|
||||
if($this->policyContent['autoname']){
|
||||
$fileName = $this->getObjName($this->policyContent['namerule'],"local",$fname).".".$fileSuffix;
|
||||
}else{
|
||||
$fileName = $fname;
|
||||
}
|
||||
$generatePath = $this->getDirName($this->policyContent['dirrule']);
|
||||
$savePath = ROOT_PATH . 'public/uploads/'.$generatePath;
|
||||
is_dir($savePath)? :mkdir($savePath,0777,true);
|
||||
if(file_exists($savePath.DS.$fileName)){
|
||||
$this->setError("文件重名",true,$file,ROOT_PATH . 'public/uploads/chunks/');
|
||||
}
|
||||
if(!@rename(ROOT_PATH . 'public/uploads/chunks/'.$file,$savePath.DS.$fileName)){
|
||||
$this->setError("文件创建失败",true,$file,ROOT_PATH . 'public/uploads/chunks/');
|
||||
}else{
|
||||
if($path == "ROOTDIR"){
|
||||
$path = "";
|
||||
}
|
||||
$jsonData = array(
|
||||
"path" => $path,
|
||||
"fname" => $fname,
|
||||
"objname" => $generatePath."/".$fileName,
|
||||
"fsize" => $this->fileSizeTmp,
|
||||
);
|
||||
$addAction = FileManage::addFile($jsonData,$this->policyContent,$this->userId);
|
||||
if(!$addAction[0]){
|
||||
$this->setError($addAction[1],true,$fileName,$savePath);
|
||||
}
|
||||
echo json_encode(array("key" => $fname));
|
||||
}
|
||||
}
|
||||
|
||||
public function filterCheck($file,$fname){
|
||||
$fileSize = filesize(ROOT_PATH . 'public/uploads/chunks/'.$file);
|
||||
$suffixTmp = explode('.', $fname);
|
||||
$fileSuffix = array_pop($suffixTmp);
|
||||
$allowedSuffix = explode(',', self::getAllowedExt(json_decode($this->policyContent["filetype"],true)));
|
||||
$sufficCheck = !in_array($fileSuffix,$allowedSuffix);
|
||||
if(empty(self::getAllowedExt(json_decode($this->policyContent["filetype"],true)))){
|
||||
$sufficCheck = false;
|
||||
}
|
||||
if(($fileSize >= (int)$this->policyContent["max_size"]) || $sufficCheck){
|
||||
FileManage::storageGiveBack($this->userId,$fileSize);
|
||||
$this->setError("文件效验失败",true,$file,ROOT_PATH . 'public/uploads/chunks/');
|
||||
}
|
||||
$this->fileSizeTmp = $fileSize;
|
||||
}
|
||||
|
||||
public function combineChunks($fname){
|
||||
$fileName = "file_".self::getRandomKey(8);
|
||||
$fileObj=fopen (ROOT_PATH . 'public/uploads/chunks/'.$fileName,"a+");
|
||||
$deleteList=[];
|
||||
foreach ($fname as $key => $value) {
|
||||
$chunkObj = fopen(ROOT_PATH . 'public/uploads/chunks/'.$value["obj_name"].".chunk", "rb");
|
||||
if(!$fileObj || !$chunkObj){
|
||||
$this->setError("文件创建失败",false);
|
||||
}
|
||||
$content = fread($chunkObj, 4195304);
|
||||
fwrite($fileObj, $content, 4195304);
|
||||
unset($content);
|
||||
fclose($chunkObj);
|
||||
unlink(ROOT_PATH . 'public/uploads/chunks/'.$value["obj_name"].".chunk");
|
||||
array_push($deleteList, $value["id"]);
|
||||
}
|
||||
$chunks = Db::name('chunks')->where([
|
||||
'id' => ["in",$deleteList],
|
||||
])->delete();
|
||||
return $fileName;
|
||||
}
|
||||
|
||||
public function fileReceive($file,$info){
|
||||
$allowedExt = self::getAllowedExt(json_decode($this->policyContent["filetype"],true));
|
||||
$filter = array('size'=>(int)$this->policyContent["max_size"]);
|
||||
if(!empty($allowedExt)){
|
||||
$filter = array_merge($filter,array("ext" => $allowedExt));
|
||||
}
|
||||
if(!FileManage::sotrageCheck($this->userId,$file->getInfo('size'))){
|
||||
$this->setError("空间容量不足",false);
|
||||
}
|
||||
if($this->policyContent['autoname']){
|
||||
$fileName = $this->getObjName($this->policyContent['namerule'],"local",$file->getInfo('name'));
|
||||
}else{
|
||||
$fileName = $file->getInfo('name');
|
||||
}
|
||||
$generatePath = $this->getDirName($this->policyContent['dirrule']);
|
||||
$savePath = ROOT_PATH . 'public/uploads/'.$generatePath;
|
||||
$Uploadinfo = $file
|
||||
->validate($filter)
|
||||
->move($savePath,$fileName,false);
|
||||
if($Uploadinfo){
|
||||
$jsonData = array(
|
||||
"path" => $info["path"],
|
||||
"fname" => $info["name"],
|
||||
"objname" => $generatePath."/".$Uploadinfo->getSaveName(),
|
||||
"fsize" => $Uploadinfo->getSize(),
|
||||
);
|
||||
@list($width, $height, $type, $attr) = getimagesize(rtrim($savePath, DS).DS.$Uploadinfo->getSaveName());
|
||||
$picInfo = empty($width)?" ":$width.",".$height;
|
||||
$addAction = FileManage::addFile($jsonData,$this->policyContent,$this->userId,$picInfo);
|
||||
if(!$addAction[0]){
|
||||
$tmpFileName = $Uploadinfo->getSaveName();
|
||||
unset($Uploadinfo);
|
||||
$this->setError($addAction[1],true,$tmpFileName,$savePath);
|
||||
}
|
||||
FileManage::storageCheckOut($this->userId,$jsonData["fsize"],$Uploadinfo->getInfo('size'));
|
||||
echo json_encode(array("key" => $info["name"]));
|
||||
}else{
|
||||
header("HTTP/1.1 401 Unauthorized");
|
||||
echo json_encode(array("error" => $file->getError()));
|
||||
}
|
||||
}
|
||||
|
||||
public function setError($text,$delete = false,$fname="",$path=""){
|
||||
header("HTTP/1.1 401 Unauthorized");
|
||||
if($delete){
|
||||
unlink(rtrim($path, DS).DS.$fname);
|
||||
}
|
||||
die(json_encode(["error"=> $text]));
|
||||
}
|
||||
|
||||
static function getAllowedExt($ext){
|
||||
$returnValue = "";
|
||||
foreach ($ext as $key => $value) {
|
||||
$returnValue .= $value["ext"].",";
|
||||
}
|
||||
return rtrim($returnValue, ",");
|
||||
}
|
||||
|
||||
public function getToken(){
|
||||
switch ($this->policyContent['policy_type']) {
|
||||
case 'qiniu':
|
||||
return $this->getQiniuToken();
|
||||
break;
|
||||
case 'local':
|
||||
return $this->getLocalToken();
|
||||
break;
|
||||
case 'oss':
|
||||
return $this->getOssToken();
|
||||
break;
|
||||
case 'upyun':
|
||||
return $this->getUpyunToken();
|
||||
break;
|
||||
case 's3':
|
||||
return $this->getS3Token();
|
||||
break;
|
||||
default:
|
||||
# code...
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public function getObjName($expression,$type = "qiniu",$origin = ""){
|
||||
$policy = array(
|
||||
'{date}' =>date("Ymd"),
|
||||
'{datetime}' =>date("YmdHis"),
|
||||
'{uid}' =>$this->userId,
|
||||
'{timestamp}' =>time(),
|
||||
'{randomkey16}' =>self::getRandomKey(16),
|
||||
'{randomkey8}' =>self::getRandomKey(8),
|
||||
);
|
||||
if($type == "qiniu"){
|
||||
$policy = array_merge($policy,array("{originname}" => "$(fname)"));
|
||||
}else if($type == "local"){
|
||||
$policy = array_merge($policy,array("{originname}" => $origin));
|
||||
}else if ($type="oss"){
|
||||
$policy = array_merge($policy,array("{originname}" => '${filename}'));
|
||||
}else if ($type="upyun"){
|
||||
$policy = array_merge($policy,array("{originname}" => '{filename}{.suffix}'));
|
||||
}
|
||||
return strtr($expression,$policy);
|
||||
}
|
||||
|
||||
public function getDirName($expression){
|
||||
$policy = array(
|
||||
'{date}' =>date("Ymd"),
|
||||
'{datetime}' =>date("YmdHis"),
|
||||
'{uid}' =>$this->userId,
|
||||
'{timestamp}' =>time(),
|
||||
'{randomkey16}' =>self::getRandomKey(16),
|
||||
'{randomkey8}' =>self::getRandomKey(8),
|
||||
);
|
||||
return trim(strtr($expression,$policy),"/");
|
||||
}
|
||||
|
||||
public function getQiniuToken(){
|
||||
$callbackKey = $this->getRandomKey();
|
||||
$sqlData = [
|
||||
'callback_key' => $callbackKey,
|
||||
'pid' => $this->policyId,
|
||||
'uid' => $this->userId
|
||||
];
|
||||
Db::name('callback')->insert($sqlData);
|
||||
$auth = new Auth($this->policyContent['ak'], $this->policyContent['sk']);
|
||||
$policy = array(
|
||||
'callbackUrl' =>Option::getValue("siteURL").'Callback/Qiniu',
|
||||
'callbackBody' => '{"fname":"$(fname)","objname":"$(key)","fsize":"$(fsize)","callbackkey":"'.$callbackKey.'","path":"$(x:path)","picinfo":"$(imageInfo.width),$(imageInfo.height)"}',
|
||||
'callbackBodyType' => 'application/json',
|
||||
'fsizeLimit' => (int)$this->policyContent['max_size'],
|
||||
);
|
||||
$dirName = $this->getObjName($this->policyContent['dirrule']);
|
||||
if($this->policyContent["autoname"]){
|
||||
$policy = array_merge($policy,array("saveKey" => $dirName.(empty($dirName)?"":"/").$this->getObjName($this->policyContent['namerule'])));
|
||||
}else{
|
||||
$policy = array_merge($policy,array("saveKey" => $dirName.(empty($dirName)?"":"/")."$(fname)"));
|
||||
}
|
||||
if(!empty($this->policyContent['mimetype'])){
|
||||
$policy = array_merge($policy,array("mimeLimit" => $this->policyContent['mimetype']));
|
||||
}
|
||||
$token = $auth->uploadToken($this->policyContent['bucketname'], null, 3600, $policy);
|
||||
return $token;
|
||||
}
|
||||
|
||||
static function upyunSign($key, $secret, $method, $uri, $date, $policy=null, $md5=null){
|
||||
$elems = array();
|
||||
foreach (array($method, $uri, $date, $policy, $md5) as $v){
|
||||
if ($v){
|
||||
$elems[] = $v;
|
||||
}
|
||||
}
|
||||
$value = implode('&', $elems);
|
||||
$sign = base64_encode(hash_hmac('sha1', $value, $secret, true));
|
||||
return 'UPYUN ' . $key . ':' . $sign;
|
||||
}
|
||||
|
||||
|
||||
public function getUpyunToken(){
|
||||
$callbackKey = $this->getRandomKey();
|
||||
$sqlData = [
|
||||
'callback_key' => $callbackKey,
|
||||
'pid' => $this->policyId,
|
||||
'uid' => $this->userId
|
||||
];
|
||||
Db::name('callback')->insert($sqlData);
|
||||
$options = Option::getValues(["oss","basic"]);
|
||||
$dateNow = gmdate('D, d M Y H:i:s \G\M\T');
|
||||
$policy=[
|
||||
"bucket" => $this->policyContent['bucketname'],
|
||||
"expiration" => time()+$options["timeout"],
|
||||
"notify-url" => $options["siteURL"]."Callback/Upyun",
|
||||
"content-length-range" =>"0,".$this->policyContent['max_size'],
|
||||
"date" => $dateNow,
|
||||
"ext-param"=>json_encode([
|
||||
"path"=>cookie("path"),
|
||||
"uid" => $this->userId,
|
||||
"pid" => $this->policyId,
|
||||
]),
|
||||
];
|
||||
$allowedExt = self::getAllowedExt(json_decode($this->policyContent["filetype"],true));
|
||||
if(!empty($allowedExt)){
|
||||
$policy = array_merge($policy,array("allow-file-type" => $allowedExt));
|
||||
}
|
||||
$dirName = $this->getObjName($this->policyContent['dirrule']);
|
||||
$policy = array_merge($policy,array("save-key" => $dirName.(empty($dirName)?"":"/").uniqid()."CLSUFF{filename}{.suffix}"));
|
||||
$this->upyunPolicy = base64_encode(json_encode($policy));
|
||||
return self::upyunSign($this->policyContent['op_name'], md5($this->policyContent['op_pwd']), "POST", "/".$this->policyContent['bucketname'],$dateNow,$this->upyunPolicy);
|
||||
}
|
||||
|
||||
public function ossCallback(){
|
||||
$callbackKey = $this->getRandomKey();
|
||||
$sqlData = [
|
||||
'callback_key' => $callbackKey,
|
||||
'pid' => $this->policyId,
|
||||
'uid' => $this->userId
|
||||
];
|
||||
Db::name('callback')->insert($sqlData);
|
||||
$returnValue["callbackUrl"] = Option::getValue("siteUrl").'Callback/Oss';
|
||||
$returnValue["callbackBody"] = '{"fname":"${x:fname}","objname":"${object}","fsize":"${size}","callbackkey":"'.$callbackKey.'","path":"${x:path}","picinfo":"${imageInfo.width},${imageInfo.height}"}';
|
||||
$this->ossCallBack = base64_encode(json_encode($returnValue));
|
||||
return base64_encode(json_encode($returnValue));
|
||||
}
|
||||
|
||||
public function getS3Token(){
|
||||
$dirName = $this->getDirName($this->policyContent['dirrule']);
|
||||
$longDate = gmdate('Ymd\THis\Z');
|
||||
$shortDate = gmdate('Ymd');
|
||||
$credential = $this->policyContent['ak'] . '/' . $shortDate . '/' . $this->policyContent['op_name'] . '/s3/aws4_request';
|
||||
$callbackKey = $this->getRandomKey();
|
||||
$sqlData = [
|
||||
'callback_key' => $callbackKey,
|
||||
'pid' => $this->policyId,
|
||||
'uid' => $this->userId
|
||||
];
|
||||
Db::name('callback')->insert($sqlData);
|
||||
$this->siteUrl = Option::getValue("siteUrl");
|
||||
$returnValue = [
|
||||
"expiration" => date("Y-m-d",time()+1800)."T".date("H:i:s",time()+1800).".000Z",
|
||||
"conditions" => [
|
||||
0 => ["bucket" => $this->policyContent['bucketname']],
|
||||
1 => ["starts-with",'$key', $dirName],
|
||||
2 => ["starts-with",'$success_action_redirect' ,$this->siteUrl."Callback/S3/key/".$callbackKey],
|
||||
3 => ["content-length-range",1,(int)$this->policyContent['max_size']],
|
||||
4 => ['x-amz-algorithm' => 'AWS4-HMAC-SHA256'],
|
||||
5 => ['x-amz-credential' => $credential],
|
||||
6 => ['x-amz-date' => $longDate],
|
||||
7 => ["starts-with", '$name', ""],
|
||||
8 => ["starts-with", '$Content-Type', ""],
|
||||
]
|
||||
];
|
||||
$this->s3Policy = base64_encode(json_encode($returnValue));
|
||||
$signingKey = hash_hmac("sha256",$shortDate,"AWS4".$this->policyContent['sk'],true);
|
||||
$signingKey = hash_hmac("sha256",$this->policyContent['op_name'],$signingKey,true);
|
||||
$signingKey = hash_hmac("sha256","s3",$signingKey,true);
|
||||
$signingKey = hash_hmac("sha256","aws4_request",$signingKey,true);
|
||||
$signingKey = hash_hmac("sha256",$this->s3Policy,$signingKey);
|
||||
$this->s3Sign = $signingKey;
|
||||
$this->dirName = $dirName;
|
||||
$this->s3Credential = $credential;
|
||||
$this->x_amz_date = $longDate;
|
||||
$this->callBackKey = $callbackKey;
|
||||
}
|
||||
|
||||
public function getOssToken(){
|
||||
$dirName = $this->getObjName($this->policyContent['dirrule']);
|
||||
$returnValu["expiration"] = date("Y-m-d",time()+1800)."T".date("H:i:s",time()+1800).".000Z";
|
||||
$returnValu["conditions"][0]["bucket"] = $this->policyContent['bucketname'];
|
||||
$returnValu["conditions"][1][0]="starts-with";
|
||||
$returnValu["conditions"][1][1]='$key';
|
||||
if($this->policyContent["autoname"]){
|
||||
$this->ossFileName = $dirName.(empty($dirName)?"":"/").$this->getObjName($this->policyContent['namerule'],"oss");;
|
||||
}else{
|
||||
$this->ossFileName = $dirName.(empty($dirName)?"":"/").'${filename}';
|
||||
}
|
||||
$returnValu["conditions"][1][2]=$dirName.(empty($dirName)?"":"/");
|
||||
$returnValu["conditions"][2]=["content-length-range",1,(int)$this->policyContent['max_size']];
|
||||
$returnValu["conditions"][3]["callback"] = $this->ossCallback();
|
||||
$this->ossToken=base64_encode(json_encode($returnValu));
|
||||
$this->ossSignToken();
|
||||
$this->ossAccessId = $this->policyContent['ak'];
|
||||
return false;
|
||||
}
|
||||
|
||||
public function ossSignToken(){
|
||||
$this->ossSign = base64_encode(hash_hmac("sha1", $this->ossToken, $this->policyContent['sk'],true));
|
||||
}
|
||||
|
||||
public function getLocalToken(){
|
||||
$auth = new Auth($this->policyContent['ak'], $this->policyContent['sk']);
|
||||
$policy = array(
|
||||
'callbackBody' => '{"path":"'.cookie('path').'"}',
|
||||
'callbackBodyType' => 'application/json',
|
||||
);
|
||||
$token = $auth->uploadToken($this->policyContent['bucketname'], null, 3600, $policy);
|
||||
return $token;
|
||||
}
|
||||
|
||||
static function getRandomKey($length = 16){
|
||||
$charTable = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
|
||||
$result = "";
|
||||
for ( $i = 0; $i < $length; $i++ ){
|
||||
$result .= $charTable[ mt_rand(0, strlen($charTable) - 1) ];
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
static function b64Decode($string) {
|
||||
$data = str_replace(array('-','_'),array('+','/'),$string);
|
||||
$mod4 = strlen($data) % 4;
|
||||
if ($mod4) {
|
||||
$data .= substr('====', $mod4);
|
||||
}
|
||||
return base64_decode($data);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
?>
|
||||
@ -0,0 +1,229 @@
|
||||
{extend name="header_admin" /}
|
||||
{block name="title"}管理面板- {$options.siteName}{/block}
|
||||
{block name="content"}
|
||||
<div class="content-wrapper">
|
||||
<div class="container-fluid">
|
||||
<!-- Breadcrumbs-->
|
||||
<ol class="breadcrumb">
|
||||
<li class="breadcrumb-item">
|
||||
<a href="#">管理面板</a>
|
||||
</li>
|
||||
<li class="breadcrumb-item active">数据概况</li>
|
||||
</ol>
|
||||
<!-- Icon Cards-->
|
||||
<div class="row">
|
||||
<div class="col-xl-3 col-sm-6 mb-3">
|
||||
<div class="card text-white bg-primary o-hidden h-100">
|
||||
<div class="card-body">
|
||||
<div class="card-body-icon">
|
||||
<i class="fa fa-fw fa-users"></i>
|
||||
</div>
|
||||
<div class="mr-5">{$statics.userNum} 位用户</div>
|
||||
</div>
|
||||
<a class="card-footer text-white clearfix small z-1" href="/Admin/Users">
|
||||
<span class="float-left">查看详情</span>
|
||||
<span class="float-right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-xl-3 col-sm-6 mb-3">
|
||||
<div class="card text-white bg-warning o-hidden h-100">
|
||||
<div class="card-body">
|
||||
<div class="card-body-icon">
|
||||
<i class="fa fa-fw fa-file"></i>
|
||||
</div>
|
||||
<div class="mr-5">{$statics.fileNum} 个文件</div>
|
||||
</div>
|
||||
<a class="card-footer text-white clearfix small z-1" href="/Admin/Files">
|
||||
<span class="float-left">查看详情</span>
|
||||
<span class="float-right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-xl-3 col-sm-6 mb-3">
|
||||
<div class="card text-white bg-success o-hidden h-100">
|
||||
<div class="card-body">
|
||||
<div class="card-body-icon">
|
||||
<i class="fa fa-fw fa-share-alt"></i>
|
||||
</div>
|
||||
<div class="mr-5">{$statics.publicShareNum} 个公开分享</div>
|
||||
</div>
|
||||
<a class="card-footer text-white clearfix small z-1" href="/Admin/Shares">
|
||||
<span class="float-left">查看详情</span>
|
||||
<span class="float-right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-xl-3 col-sm-6 mb-3">
|
||||
<div class="card text-white bg-danger o-hidden h-100">
|
||||
<div class="card-body">
|
||||
<div class="card-body-icon">
|
||||
<i class="fa fa-fw fa-lock"></i>
|
||||
</div>
|
||||
<div class="mr-5">{$statics.privateShareNum} 个私密分享</div>
|
||||
</div>
|
||||
<a class="card-footer text-white clearfix small z-1" href="/Admin/Shares">
|
||||
<span class="float-left">查看详情</span>
|
||||
<span class="float-right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Area Chart Example-->
|
||||
<div class="card mb-3">
|
||||
<div class="card-header">
|
||||
<i class="fa fa-area-chart"></i> 近期趋势</div>
|
||||
<div class="card-body">
|
||||
<canvas id="myAreaChart" width="100%" height="30"></canvas>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-lg-8">
|
||||
<!-- Example Bar Chart Card-->
|
||||
<div class="card mb-3">
|
||||
<div class="card-header">
|
||||
<i class="fa fa-bell-o"></i> 订阅新闻</div>
|
||||
<div class="list-group list-group-flush small" id="news">
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<!-- Card Columns Example Social Feed-->
|
||||
|
||||
|
||||
|
||||
<!-- /Card Columns-->
|
||||
</div>
|
||||
<div class="col-lg-4">
|
||||
<!-- Example Pie Chart Card-->
|
||||
<div class="card mb-3">
|
||||
<div class="card-header">
|
||||
<i class="fa fa-pie-chart"></i> 文件组成</div>
|
||||
<div class="card-body">
|
||||
<canvas id="myPieChart" width="100%" height="80"></canvas>
|
||||
</div>
|
||||
<div class="card-footer small text-muted">*此结果仅供参考</div>
|
||||
</div>
|
||||
<!-- Example Notifications Card-->
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<!-- Example DataTables Card-->
|
||||
|
||||
</div>
|
||||
<!-- /.container-fluid-->
|
||||
<!-- /.content-wrapper-->
|
||||
<footer class="sticky-footer">
|
||||
<div class="container">
|
||||
<div class="text-center">
|
||||
<small>Copyright © Cloudreve {php}echo date("Y");{/php} </small>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
<!-- Scroll to Top Button-->
|
||||
<a class="scroll-to-top rounded" href="#page-top">
|
||||
<i class="fa fa-angle-up"></i>
|
||||
</a>
|
||||
<!-- Logout Modal-->
|
||||
|
||||
<!-- Bootstrap core JavaScript-->
|
||||
|
||||
|
||||
{/block}
|
||||
{block name="js"}
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function() {
|
||||
$.getJSON("https://cloudreve.org/api/notice/?callback=?", function(data){
|
||||
|
||||
$("#news").html(data[0]);
|
||||
|
||||
})
|
||||
})
|
||||
Chart.defaults.global.defaultFontFamily = '-apple-system,system-ui,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif',
|
||||
Chart.defaults.global.defaultFontColor = "#292b2c";
|
||||
var ctx = document.getElementById("myAreaChart"),
|
||||
myLineChart = new Chart(ctx, {
|
||||
type: "line",
|
||||
data: {
|
||||
labels: [{$statics.trendDate}],
|
||||
datasets: [{
|
||||
label: "上传文件",
|
||||
lineTension: .3,
|
||||
backgroundColor: "rgba(2,117,216,0.2)",
|
||||
borderColor: "rgba(2,117,216,1)",
|
||||
pointRadius: 5,
|
||||
pointBackgroundColor: "rgba(2,117,216,1)",
|
||||
pointBorderColor: "rgba(255,255,255,0.8)",
|
||||
pointHoverRadius: 5,
|
||||
pointHoverBackgroundColor: "rgba(2,117,216,1)",
|
||||
pointHitRadius: 20,
|
||||
pointBorderWidth: 2,
|
||||
data: [{$statics.trendFile}]
|
||||
},{
|
||||
label: "注册用户",
|
||||
lineTension: .3,
|
||||
backgroundColor: "rgba(83, 216, 2, 0.2)",
|
||||
borderColor: "#4CAF50",
|
||||
pointRadius: 5,
|
||||
pointBackgroundColor: "#4CAF50",
|
||||
pointBorderColor: "rgba(255,255,255,0.8)",
|
||||
pointHoverRadius: 5,
|
||||
pointHoverBackgroundColor: "#4CAF50",
|
||||
pointHitRadius: 20,
|
||||
pointBorderWidth: 2,
|
||||
data: [{$statics.trendUser}]
|
||||
},
|
||||
|
||||
]
|
||||
},
|
||||
options: {
|
||||
scales: {
|
||||
xAxes: [{
|
||||
time: {
|
||||
unit: "date"
|
||||
},
|
||||
gridLines: {
|
||||
display: !1
|
||||
},
|
||||
ticks: {
|
||||
maxTicksLimit: 7
|
||||
}
|
||||
}],
|
||||
yAxes: [{
|
||||
ticks: {
|
||||
|
||||
maxTicksLimit: 5
|
||||
},
|
||||
gridLines: {
|
||||
color: "rgba(0, 0, 0, .125)"
|
||||
}
|
||||
}]
|
||||
},
|
||||
legend: {
|
||||
display: !1
|
||||
}
|
||||
}
|
||||
}),
|
||||
|
||||
ctx = document.getElementById("myPieChart"),
|
||||
myPieChart = new Chart(ctx, {
|
||||
type: "pie",
|
||||
data: {
|
||||
labels: ["其他", "图片", "音频", "视频"],
|
||||
datasets: [{
|
||||
data: [{$statics.otherRate}, {$statics.imgRate}, {$statics.audioRate}, {$statics.videoRate}],
|
||||
backgroundColor: ["#007bff", "#dc3545", "#ffc107", "#28a745"]
|
||||
}]
|
||||
}
|
||||
});
|
||||
</script>
|
||||
{/block}
|
||||
@ -0,0 +1,51 @@
|
||||
{extend name="header_admin" /}
|
||||
{block name="title"}基础设置- {$options.siteName}{/block}
|
||||
{block name="content"}
|
||||
<div class="content-wrapper">
|
||||
<div class="container-fluid">
|
||||
<!-- Breadcrumbs-->
|
||||
<ol class="breadcrumb">
|
||||
<li class="breadcrumb-item">
|
||||
<a href="/Admin">管理面板</a>
|
||||
</li>
|
||||
<li class="breadcrumb-item active">设置</li>
|
||||
<li class="breadcrumb-item active">配置文件</li>
|
||||
</ol>
|
||||
|
||||
<!-- Area Chart Example-->
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<h2>配置文件</h2>
|
||||
{$path}
|
||||
<br> <br>
|
||||
<div class="row">
|
||||
<div class="col-md-9">
|
||||
<input type="text" id="configType" value="{$type}" style="display: none">
|
||||
<textarea rows="15" class="form-control" spellcheck="false">{$content}</textarea>
|
||||
<br>
|
||||
<button class="btn btn-primary" id="save">保存</button>
|
||||
<br><br>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="nav flex-column nav-pills" id="v-pills-tab" role="tablist" aria-orientation="vertical">
|
||||
<a class="nav-link" id="v-pills-home-tab" href="/Admin/Config/type/common" role="tab" data-type="common">系统公共配置</a>
|
||||
<a class="nav-link" id="v-pills-profile-tab" href="/Admin/Config/type/database" role="tab" data-type="database">数据库</a>
|
||||
<a class="nav-link" id="v-pills-messages-tab" href="/Admin/Config/type/route" role="tab" data-type="route">路由</a>
|
||||
<a class="nav-link" id="v-pills-settings-tab" href="/Admin/Config/type/tags" role="tab" data-type="tags">行为扩展</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Example DataTables Card-->
|
||||
</div>
|
||||
<!-- /.container-fluid-->
|
||||
</div>
|
||||
{/block}
|
||||
{block name="js"}
|
||||
<script src="/static/js/admin/config.js"></script>
|
||||
<script type="text/javascript">
|
||||
</script>
|
||||
{/block}
|
||||
@ -0,0 +1,194 @@
|
||||
{extend name="header_admin" /}
|
||||
{block name="title"}文件列表- {$options.siteName}{/block}
|
||||
{block name="content"}
|
||||
<div class="content-wrapper">
|
||||
<div class="container-fluid">
|
||||
<!-- Breadcrumbs-->
|
||||
<ol class="breadcrumb">
|
||||
<li class="breadcrumb-item">
|
||||
<a href="/Admin">管理面板</a>
|
||||
</li>
|
||||
<li class="breadcrumb-item active">文件</li>
|
||||
</ol>
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<h2>文件</h2>
|
||||
<br>
|
||||
<div class="card mb-3">
|
||||
<div class="card-header">
|
||||
<i class="fa fa-tags"></i> 条件检索</div>
|
||||
<div class="card-body">
|
||||
<div class="row">
|
||||
<div class="col-1 form-label-search mb-2">排序方式</div>
|
||||
<div class="col-md-10">
|
||||
<ul class="nav nav-pills" id="order">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link selectLab" href="javascript:void()" data-method="id DESC">日期</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link selectLab" href="javascript:void()" data-method="orign_name ASC">文件名</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link selectLab" href="javascript:void()" data-method="size DESC">大小</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-1 form-label-search mb-2">上传策略</div>
|
||||
<div class="col-md-10">
|
||||
<ul class="nav nav-pills" id="policy_select">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link selectLab" href="javascript:void()" data-policy="">全部</a>
|
||||
</li>
|
||||
{volist name="policy" id="policy"}
|
||||
<li class="nav-item">
|
||||
<a class="nav-link selectLab" href="javascript:void()" data-policy="{$policy.id}">{$policy.policy_name}</a>
|
||||
</li>
|
||||
{/volist}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row" style="margin-top: 5px;">
|
||||
<div class="col-1 form-label-search mb-2">高级检索</div>
|
||||
<div class="col-md-10">
|
||||
<div class="row">
|
||||
<div class="col-md-2">
|
||||
<select class="form-control form-control-sm" id="searchCol">
|
||||
<option value="id" selected>ID</option>
|
||||
<option value="orign_name">文件名</option>
|
||||
<option value="pre_name">实际文件名</option>
|
||||
<option value="upload_user">上传者UID</option>
|
||||
<option value="upload_date">上传日期</option>
|
||||
<option value="pic_info">图像尺寸</option>
|
||||
<option value="parent_folder">所属目录ID</option>
|
||||
<option value="policy_id">上传策略ID</option>
|
||||
<option value="dir">目录路径</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<input type="text" class="form-control form-control-sm" placeholder="检索表达式" id="searchValue">
|
||||
</div>
|
||||
<div class="col-md-1">
|
||||
<button type="button" class="btn btn-primary btn-sm" id="applySearch">应用</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card mb-3">
|
||||
<div class="card-header">
|
||||
<i class="fa fa-table"></i> 文件列表</div>
|
||||
<div class="card-body">
|
||||
<div class="table-responsive">
|
||||
<div id="dataTable_wrapper" class="dataTables_wrapper container-fluid dt-bootstrap4"><div class="row"><div class="col-sm-12 col-md-6"><div class="dataTables_length" ><label>每页展示 <select id="dataTable_length" aria-controls="dataTable" class="form-control form-control-sm"><option value="10">10</option><option value="25">25</option><option value="50">50</option><option value="100">100</option></select> 个</label></div></div><div class="col-sm-12 col-md-6"><div id="dataTable_filter" class="dataTables_filter"><label>搜索:<input type="search" class="form-control form-control-sm" placeholder="" id="searchFrom"></label></div></div></div><div class="row"><div class="col-sm-12">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-bordered dataTable" id="dataTable" width="100%" cellspacing="0" role="grid" aria-describedby="dataTable_info" style="width: 100%;">
|
||||
<thead>
|
||||
<tr role="row" class="textCenter"><th><input type="checkbox" data-type="all"></th><th>文件名</th><th class="textCenter">大小</th><th class="textCenter">上传者</th><th class="textCenter">日期</th><th class="textCenter">操作</th></tr>
|
||||
</thead>
|
||||
<tfoot>
|
||||
<tr><th rowspan="1" colspan="1" class="textCenter"><input type="checkbox" data-type="all"></th><th rowspan="1" colspan="1">文件名</th><th rowspan="1" colspan="1" class="textCenter">大小</th><th rowspan="1" colspan="1" class="textCenter">上传者</th><th rowspan="1" colspan="1" class="textCenter">日期</th><th rowspan="1" colspan="1" class="textCenter">操作</th></tr>
|
||||
</tfoot>
|
||||
<tbody>
|
||||
<tr role="row" class="odd" id="fileList">
|
||||
|
||||
{volist name='list' id='file'}
|
||||
<tr role="row" class="odd">
|
||||
<td class="sorting_1 textCenter"><input type="checkbox" data-type="mark" data-path="{:rtrim($file.dir,'/')}/{$file.orign_name}" data-uid="{$file.upload_user}"></td>
|
||||
<td>
|
||||
{eq name=":isPreview($file.orign_name)" value="yes"}
|
||||
<a href="/Admin/Preview/id/{$file.id}" class="noAColor" target="_blank">{$file.orign_name|htmlspecialchars=ENT_NOQUOTES}</a>
|
||||
{else}
|
||||
<a href="/Admin/Download/id/{$file.id}" class="noAColor" target="_blank">{$file.orign_name|htmlspecialchars=ENT_NOQUOTES}</a>
|
||||
{/eq}
|
||||
</td>
|
||||
<td class="textCenter">{:countSize($file.size)}</td>
|
||||
<td class="textCenter">{$originList[$key]["user"]["user_nick"]}</td>
|
||||
<td class="textCenter">{$file.upload_date}</td>
|
||||
<td class="textCenter"><button type="button" class="btn btn-secondary fix" data-toggle="tooltip" data-placement="top" title="删除" data-action="delete" data-id="{$file.id}"><i class="fa fa-trash" aria-hidden="true"></i></button>
|
||||
<button type="button" class="btn btn-secondary fix" data-toggle="tooltip" data-placement="top" title="下载" data-action="download" data-id="{$file.id}"><i class="fa fa-download" aria-hidden="true"></i></button>
|
||||
<button type="button" class="btn btn-secondary fix" data-toggle="tooltip" data-placement="top" title="详情" data-action="info" data-id="{$file.id}"><i class="fa fa-info-circle" aria-hidden="true"></i></button>
|
||||
</td>
|
||||
</tr>
|
||||
{/volist}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="col-md-5 mb-2 mt-2" style="display: none" id="del">
|
||||
<button type="button" class="btn btn-danger" id="delAll"><i class="fa fa-trash" aria-hidden="true"></i> 删除选中文件</button>
|
||||
</div>
|
||||
</div></div><div class="row"><div class="col-sm-12 col-md-5"><div class="dataTables_info" id="dataTable_info" role="status" aria-live="polite">展示第 {$pageNow} 页,共 {$pageTotal} 页 {$dataTotal} 条数据</div></div><div class="col-sm-12 col-md-7">
|
||||
<div class="dataTables_paginate paging_simple_numbers" id="dataTable_paginate">
|
||||
{$list->render()}
|
||||
</div></div></div></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Example DataTables Card-->
|
||||
</div>
|
||||
<!-- /.container-fluid-->
|
||||
</div>
|
||||
<div class="modal fade bd-example-modal-sm" tabindex="-1" role="dialog" aria-labelledby="mySmallModalLabel" aria-hidden="true" id="fileInfo">
|
||||
<div class="modal-dialog modal-sm">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="exampleModalLabel">文件详情</h5>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="row">
|
||||
<div class="col-md-12"><strong>ID:</strong></div>
|
||||
<div class="col-md-12 break" id="fileId">12</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-12"><strong>文件名:</strong></div>
|
||||
<div class="col-md-12 break" id="fileName">5c06e532e7afdb4389e4ae846ea7876c_w - 副本 - 副本.jpg</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-12"><strong>源文件名:</strong></div>
|
||||
<div class="col-md-12 break" id="fileOrigin">5c06e532e7afdb4389e4ae846ea7876c_w - 副本 - 副本.jpg</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-12"><strong>上传者UID:</strong></div>
|
||||
<div class="col-md-12 break" id="fileUID">17</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-12"><strong>大小(字节):</strong></div>
|
||||
<div class="col-md-12 break" id="fileSize">7481817</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-12"><strong>图像尺寸:</strong></div>
|
||||
<div class="col-md-12 break" id="filePic">147,445</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-12"><strong>上传策略:</strong></div>
|
||||
<div class="col-md-12 break" id="filePolicy">147,445</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-12"><strong>所属目录:</strong></div>
|
||||
<div class="col-md-12 break" id="fileDir">147,445</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-dismiss="modal">关闭</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- /.content-wrapper-->
|
||||
{/block}
|
||||
{block name="js"}
|
||||
<script src="/static/js/admin/files.js"></script>
|
||||
<script type="text/javascript">
|
||||
</script>
|
||||
{/block}
|
||||
@ -0,0 +1,131 @@
|
||||
{extend name="header_admin" /}
|
||||
{block name="title"}上传策略- {$options.siteName}{/block}
|
||||
{block name="content"}
|
||||
<div class="content-wrapper">
|
||||
<div class="container-fluid">
|
||||
<!-- Breadcrumbs-->
|
||||
<ol class="breadcrumb">
|
||||
<li class="breadcrumb-item">
|
||||
<a href="/Admin">管理面板</a>
|
||||
</li>
|
||||
<li class="breadcrumb-item active">用户组</li>
|
||||
</ol>
|
||||
|
||||
<!-- Area Chart Example-->
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<h2>用户组</h2>
|
||||
<br>
|
||||
|
||||
|
||||
<div class="card mb-3">
|
||||
<div class="card-header">
|
||||
<i class="fa fa-table"></i> 用户组列表</div>
|
||||
<div class="card-body">
|
||||
<div class="table-responsive">
|
||||
<div id="dataTable_wrapper" class="dataTables_wrapper container-fluid dt-bootstrap4"><div class="row"><div class="col-sm-12 col-md-6"><div class="dataTables_length" ><label>每页展示 <select id="dataTable_length" aria-controls="dataTable" class="form-control form-control-sm"><option value="10">10</option><option value="25">25</option><option value="50">50</option><option value="100">100</option></select> 个</label></div></div></div><div class="row"><div class="col-sm-12">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-bordered dataTable" id="dataTable" width="100%" cellspacing="0" role="grid" aria-describedby="dataTable_info" style="width: 100%;">
|
||||
<thead>
|
||||
<tr role="row" class="textCenter"><th>#</th><th>名称</th><th class="textCenter">上传策略</th><th class="textCenter">最大容量</th><th class="textCenter">下属用户数</th><th class="textCenter">操作</th></tr>
|
||||
</thead>
|
||||
<tfoot>
|
||||
<tr><th rowspan="1" colspan="1" class="textCenter">#</th><th rowspan="1" colspan="1">名称</th><th rowspan="1" colspan="1" class="textCenter">上传策略</th><th rowspan="1" colspan="1" class="textCenter">最大容量</th><th rowspan="1" colspan="1" class="textCenter">下属用户数</th><th rowspan="1" colspan="1" class="textCenter">操作</th></tr>
|
||||
</tfoot>
|
||||
<tbody>
|
||||
<tr role="row" class="odd" id="fileList">
|
||||
|
||||
{volist name='list' id='group'}
|
||||
<tr role="row" class="odd">
|
||||
<td class="sorting_1 textCenter">{$group.id}</td>
|
||||
<td>
|
||||
{$group.group_name}
|
||||
</td>
|
||||
<td class="textCenter">
|
||||
{$originList[$key]["policy"]["policy_name"]}
|
||||
</td>
|
||||
<td class="textCenter">{:countSize($group["max_storage"])}</td>
|
||||
<td class="textCenter">{$originList[$key]["user_num"]}</td>
|
||||
<td class="textCenter"><button type="button" class="btn btn-secondary fix" data-toggle="tooltip" data-placement="top" title="删除" data-action="delete" data-id="{$group.id}" data-unable="{eq name="$originList[$key]['user_num']" value="0"}0{else}1{/eq}"><i class="fa fa-trash" aria-hidden="true"></i></button>
|
||||
<button type="button" class="btn btn-secondary fix" data-toggle="tooltip" data-placement="top" title="编辑" data-action="edit" data-id="{$group.id}"><i class="fa fa-edit" aria-hidden="true"></i></button>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
{/volist}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="col-md-5 mb-2 mt-2" style="display: none" id="del">
|
||||
<button type="button" class="btn btn-danger" id="delAll"><i class="fa fa-trash" aria-hidden="true"></i> 删除选中文件</button>
|
||||
</div>
|
||||
</div></div><div class="row"><div class="col-sm-12 col-md-5"><div class="dataTables_info" id="dataTable_info" role="status" aria-live="polite">展示第 {$pageNow} 页,共 {$pageTotal} 页 {$dataTotal} 条数据</div></div><div class="col-sm-12 col-md-7">
|
||||
<div class="dataTables_paginate paging_simple_numbers" id="dataTable_paginate">
|
||||
{$list->render()}
|
||||
</div></div></div></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Example DataTables Card-->
|
||||
</div>
|
||||
<!-- /.container-fluid-->
|
||||
</div>
|
||||
<div class="modal fade bd-example-modal-sm" tabindex="-1" role="dialog" aria-labelledby="mySmallModalLabel" aria-hidden="true" id="fileInfo">
|
||||
<div class="modal-dialog modal-sm">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="exampleModalLabel">文件详情</h5>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="row">
|
||||
<div class="col-md-12"><strong>ID:</strong></div>
|
||||
<div class="col-md-12 break" id="fileId">12</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-12"><strong>文件名:</strong></div>
|
||||
<div class="col-md-12 break" id="fileName">5c06e532e7afdb4389e4ae846ea7876c_w - 副本 - 副本.jpg</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-12"><strong>源文件名:</strong></div>
|
||||
<div class="col-md-12 break" id="fileOrigin">5c06e532e7afdb4389e4ae846ea7876c_w - 副本 - 副本.jpg</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-12"><strong>上传者UID:</strong></div>
|
||||
<div class="col-md-12 break" id="fileUID">17</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-12"><strong>大小(字节):</strong></div>
|
||||
<div class="col-md-12 break" id="fileSize">7481817</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-12"><strong>图像尺寸:</strong></div>
|
||||
<div class="col-md-12 break" id="filePic">147,445</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-12"><strong>上传策略:</strong></div>
|
||||
<div class="col-md-12 break" id="filePolicy">147,445</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-12"><strong>所属目录:</strong></div>
|
||||
<div class="col-md-12 break" id="fileDir">147,445</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-dismiss="modal">关闭</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- /.content-wrapper-->
|
||||
{/block}
|
||||
{block name="js"}
|
||||
<script src="/static/js/admin/group_list.js"></script>
|
||||
<script type="text/javascript">
|
||||
</script>
|
||||
{/block}
|
||||
@ -0,0 +1,96 @@
|
||||
{extend name="header_admin" /}
|
||||
{block name="title"}注册访问- {$options.siteName}{/block}
|
||||
{block name="content"}
|
||||
<div class="content-wrapper">
|
||||
<div class="container-fluid">
|
||||
<!-- Breadcrumbs-->
|
||||
<ol class="breadcrumb">
|
||||
<li class="breadcrumb-item">
|
||||
<a href="/Admin">管理面板</a>
|
||||
</li>
|
||||
<li class="breadcrumb-item active">设置</li>
|
||||
<li class="breadcrumb-item active">杂项</li>
|
||||
</ol>
|
||||
|
||||
<!-- Area Chart Example-->
|
||||
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<h2>杂项设置</h2>
|
||||
<br>
|
||||
<form id="mailTemplate">
|
||||
|
||||
<div class="row form-setting">
|
||||
<div class="col-md-1 form-label ">
|
||||
<label for="maxEditSize" class="col-form-label col-form-label-sm">文本编辑大小限制</label>
|
||||
</div>
|
||||
<div class="col-md-4"> <input type="email" class="form-control" name="maxEditSize" value="{$optionsForSet.maxEditSize}" spellcheck="false"></div>
|
||||
<div class="col-md-4 option-des"> 用户可在线编辑的文本类文件的最大尺寸。单位:字节</div>
|
||||
</div>
|
||||
|
||||
<div class="row form-setting">
|
||||
<div class="col-md-1 form-label ">
|
||||
<label for="maxEditSize" class="col-form-label col-form-label-sm">允许游客下载</label>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
{eq name="$optionsForSet.allowdVisitorDownload" value="true"}
|
||||
<input class="" type="radio" name="allowdVisitorDownload" id="inlineRadio1" value="true" checked>
|
||||
<label class="" for="inlineRadio1" >允许</label>
|
||||
|
||||
<input class="" type="radio" name="allowdVisitorDownload" id="inlineRadio2" value="false">
|
||||
<label class="" for="inlineRadio2">拒绝</label>
|
||||
{else}
|
||||
<input class="" type="radio" name="allowdVisitorDownload" id="inlineRadio1" value="true">
|
||||
<label class="" for="inlineRadio1" >允许</label>
|
||||
|
||||
<input class="" type="radio" name="allowdVisitorDownload" id="inlineRadio2" value="false" checked>
|
||||
<label class="" for="inlineRadio2">拒绝</label>
|
||||
{/eq}
|
||||
</div>
|
||||
<div class="col-md-4 option-des"> 是否允许未登录用户下载被分享的文件</div>
|
||||
</div>
|
||||
|
||||
<div class="row form-setting">
|
||||
<div class="col-md-1 form-label ">
|
||||
<label for="hot_share_num" class="col-form-label col-form-label-sm">热门分享展示数量</label>
|
||||
</div>
|
||||
<div class="col-md-4"> <input type="email" class="form-control" name="hot_share_num" value="{$optionsForSet.hot_share_num}" spellcheck="false"></div>
|
||||
<div class="col-md-4 option-des"> 在用户个人主页展示的热门分享的个数</div>
|
||||
</div>
|
||||
|
||||
<div class="row form-setting">
|
||||
<div class="col-md-1 form-label ">
|
||||
<label for="gravatar_server" class="col-form-label col-form-label-sm">Gravatar服务器</label>
|
||||
</div>
|
||||
<div class="col-md-4"> <input type="email" class="form-control" name="gravatar_server" value="{$optionsForSet.gravatar_server}" spellcheck="false"></div>
|
||||
<div class="col-md-4 option-des"> 用于展示用户头像的Gravatar服务器地址</div>
|
||||
</div>
|
||||
|
||||
<div class="row form-setting">
|
||||
<div class="col-md-1 form-label ">
|
||||
</div>
|
||||
<div class="col-md-4"> <button type="button" class="btn btn-primary" id="saveTemplate">保存设置</button></div>
|
||||
<div class="col-md-4 option-des"> </div>
|
||||
<br><br><br>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Example DataTables Card-->
|
||||
|
||||
</div>
|
||||
<!-- /.container-fluid-->
|
||||
</div>
|
||||
|
||||
<!-- /.content-wrapper-->
|
||||
|
||||
|
||||
|
||||
{/block}
|
||||
{block name="js"}
|
||||
<script src="/static/js/admin/setting.js"></script>
|
||||
<script type="text/javascript">
|
||||
|
||||
</script>
|
||||
{/block}
|
||||
@ -0,0 +1,168 @@
|
||||
{extend name="header_admin" /}
|
||||
{block name="title"}上传策略- {$options.siteName}{/block}
|
||||
{block name="content"}
|
||||
<div class="content-wrapper">
|
||||
<div class="container-fluid">
|
||||
<!-- Breadcrumbs-->
|
||||
<ol class="breadcrumb">
|
||||
<li class="breadcrumb-item">
|
||||
<a href="/Admin">管理面板</a>
|
||||
</li>
|
||||
<li class="breadcrumb-item active">上传策略</li>
|
||||
</ol>
|
||||
|
||||
<!-- Area Chart Example-->
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<h2>上传策略</h2>
|
||||
<br>
|
||||
<div class="card mb-3">
|
||||
<div class="card-header">
|
||||
<i class="fa fa-tags"></i> 条件检索</div>
|
||||
<div class="card-body">
|
||||
<div class="row">
|
||||
<div class="col-1 form-label-search mb-2">类型</div>
|
||||
<div class="col-md-10">
|
||||
<ul class="nav nav-pills" id="policyType">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link selectLab" href="javascript:void()" data-policy="">全部</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link selectLab" href="javascript:void()" data-policy="local">本地</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link selectLab" href="javascript:void()" data-policy="qiniu">七牛</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link selectLab" href="javascript:void()" data-policy="oss">OSS</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link selectLab" href="javascript:void()" data-policy="upyun">又拍云</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link selectLab" href="javascript:void()" data-policy="s3">S3</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card mb-3">
|
||||
<div class="card-header">
|
||||
<i class="fa fa-table"></i> 上传策略列表</div>
|
||||
<div class="card-body">
|
||||
<div class="table-responsive">
|
||||
<div id="dataTable_wrapper" class="dataTables_wrapper container-fluid dt-bootstrap4"><div class="row"><div class="col-sm-12 col-md-6"><div class="dataTables_length" ><label>每页展示 <select id="dataTable_length" aria-controls="dataTable" class="form-control form-control-sm"><option value="10">10</option><option value="25">25</option><option value="50">50</option><option value="100">100</option></select> 个</label></div></div><div class="col-sm-12 col-md-6"><div id="dataTable_filter" class="dataTables_filter"><label>搜索:<input type="search" class="form-control form-control-sm" placeholder="" id="searchFrom"></label></div></div></div><div class="row"><div class="col-sm-12">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-bordered dataTable" id="dataTable" width="100%" cellspacing="0" role="grid" aria-describedby="dataTable_info" style="width: 100%;">
|
||||
<thead>
|
||||
<tr role="row" class="textCenter"><th>#</th><th>名称</th><th class="textCenter">类型</th><th class="textCenter">下属文件数</th><th class="textCenter">数据量</th><th class="textCenter">操作</th></tr>
|
||||
</thead>
|
||||
<tfoot>
|
||||
<tr><th rowspan="1" colspan="1" class="textCenter">#</th><th rowspan="1" colspan="1">名称</th><th rowspan="1" colspan="1" class="textCenter">类型</th><th rowspan="1" colspan="1" class="textCenter">下属文件数</th><th rowspan="1" colspan="1" class="textCenter">数据量</th><th rowspan="1" colspan="1" class="textCenter">操作</th></tr>
|
||||
</tfoot>
|
||||
<tbody>
|
||||
<tr role="row" class="odd" id="fileList">
|
||||
|
||||
{volist name='list' id='policy'}
|
||||
<tr role="row" class="odd">
|
||||
<td class="sorting_1 textCenter">{$policy.id}</td>
|
||||
<td>
|
||||
{$policy.policy_name}
|
||||
</td>
|
||||
<td class="textCenter">
|
||||
{switch name="policy.policy_type"}
|
||||
{case value="local"}本地{/case}
|
||||
{case value="qiniu"}七牛{/case}
|
||||
{case value="oss"}OSS{/case}
|
||||
{case value="upyun"}又拍云{/case}
|
||||
{case value="s3"}Amazon S3{/case}
|
||||
{default /}其他
|
||||
{/switch}
|
||||
</td>
|
||||
<td class="textCenter">{$originList[$key]["file_num"]}</td>
|
||||
<td class="textCenter">{:countSize($originList[$key]["file_size"])}</td>
|
||||
<td class="textCenter"><button type="button" class="btn btn-secondary fix" data-toggle="tooltip" data-placement="top" title="删除" data-action="delete" data-id="{$policy.id}" data-unable="{eq name="$originList[$key]['file_num']" value="0"}0{else}1{/eq}"><i class="fa fa-trash" aria-hidden="true"></i></button>
|
||||
<button type="button" class="btn btn-secondary fix" data-toggle="tooltip" data-placement="top" title="编辑" data-action="edit" data-id="{$policy.id}"><i class="fa fa-edit" aria-hidden="true"></i></button>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
{/volist}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="col-md-5 mb-2 mt-2" style="display: none" id="del">
|
||||
<button type="button" class="btn btn-danger" id="delAll"><i class="fa fa-trash" aria-hidden="true"></i> 删除选中文件</button>
|
||||
</div>
|
||||
</div></div><div class="row"><div class="col-sm-12 col-md-5"><div class="dataTables_info" id="dataTable_info" role="status" aria-live="polite">展示第 {$pageNow} 页,共 {$pageTotal} 页 {$dataTotal} 条数据</div></div><div class="col-sm-12 col-md-7">
|
||||
<div class="dataTables_paginate paging_simple_numbers" id="dataTable_paginate">
|
||||
{$list->render()}
|
||||
</div></div></div></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Example DataTables Card-->
|
||||
</div>
|
||||
<!-- /.container-fluid-->
|
||||
</div>
|
||||
<div class="modal fade bd-example-modal-sm" tabindex="-1" role="dialog" aria-labelledby="mySmallModalLabel" aria-hidden="true" id="fileInfo">
|
||||
<div class="modal-dialog modal-sm">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="exampleModalLabel">文件详情</h5>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="row">
|
||||
<div class="col-md-12"><strong>ID:</strong></div>
|
||||
<div class="col-md-12 break" id="fileId">12</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-12"><strong>文件名:</strong></div>
|
||||
<div class="col-md-12 break" id="fileName">5c06e532e7afdb4389e4ae846ea7876c_w - 副本 - 副本.jpg</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-12"><strong>源文件名:</strong></div>
|
||||
<div class="col-md-12 break" id="fileOrigin">5c06e532e7afdb4389e4ae846ea7876c_w - 副本 - 副本.jpg</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-12"><strong>上传者UID:</strong></div>
|
||||
<div class="col-md-12 break" id="fileUID">17</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-12"><strong>大小(字节):</strong></div>
|
||||
<div class="col-md-12 break" id="fileSize">7481817</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-12"><strong>图像尺寸:</strong></div>
|
||||
<div class="col-md-12 break" id="filePic">147,445</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-12"><strong>上传策略:</strong></div>
|
||||
<div class="col-md-12 break" id="filePolicy">147,445</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-12"><strong>所属目录:</strong></div>
|
||||
<div class="col-md-12 break" id="fileDir">147,445</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-dismiss="modal">关闭</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- /.content-wrapper-->
|
||||
{/block}
|
||||
{block name="js"}
|
||||
<script src="/static/js/admin/policy.js"></script>
|
||||
<script type="text/javascript">
|
||||
</script>
|
||||
{/block}
|
||||
@ -0,0 +1,134 @@
|
||||
{extend name="header_admin" /}
|
||||
{block name="title"}注册访问- {$options.siteName}{/block}
|
||||
{block name="content"}
|
||||
<div class="content-wrapper">
|
||||
<div class="container-fluid">
|
||||
<!-- Breadcrumbs-->
|
||||
<ol class="breadcrumb">
|
||||
<li class="breadcrumb-item">
|
||||
<a href="/Admin">管理面板</a>
|
||||
</li>
|
||||
<li class="breadcrumb-item active">设置</li>
|
||||
<li class="breadcrumb-item active">注册访问</li>
|
||||
</ol>
|
||||
|
||||
<!-- Area Chart Example-->
|
||||
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<h2>注册与访问</h2>
|
||||
<br>
|
||||
<form id="basicOptionsForm">
|
||||
<div class="row form-setting">
|
||||
<div class="col-md-1 form-label ">
|
||||
<label for="colFormLabelSm" class="col-form-label col-form-label-sm">允许注册</label>
|
||||
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
{eq name="$optionsForSet.regStatus" value="0"}
|
||||
<input class="" type="radio" name="regStatus" id="inlineRadio1" value="0"checked>
|
||||
<label class="" for="inlineRadio1" >是</label>
|
||||
|
||||
<input class="" type="radio" name="regStatus" id="inlineRadio2" value="1">
|
||||
<label class="" for="inlineRadio2">否</label>
|
||||
{else}
|
||||
<input class="" type="radio" name="regStatus" id="inlineRadio1" value="0">
|
||||
<label class="" for="inlineRadio1" >是</label>
|
||||
|
||||
<input class="" type="radio" name="regStatus" id="inlineRadio2" value="1" checked>
|
||||
<label class="" for="inlineRadio2">否</label>
|
||||
{/eq}
|
||||
</div>
|
||||
<div class="col-md-4 option-des"> 是否允许新用户注册</div>
|
||||
</div>
|
||||
|
||||
<div class="row form-setting">
|
||||
<div class="col-md-1 form-label ">
|
||||
<label for="colFormLabelSm" class="col-form-label col-form-label-sm">默认用户组</label>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<select class="form-control" name="defaultGroup">
|
||||
{volist name="groups" id="group"}
|
||||
{eq name="$group.id" value="$optionsForSet.defaultGroup"}
|
||||
<option value="{$group.id}" selected>{$group.group_name}</option>
|
||||
{else}
|
||||
<option value="{$group.id}">{$group.group_name}</option>
|
||||
{/eq}
|
||||
{/volist}
|
||||
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-4 option-des"> 用户注册后默认属于的用户组</div>
|
||||
</div>
|
||||
|
||||
<div class="row form-setting">
|
||||
<div class="col-md-1 form-label ">
|
||||
<label for="colFormLabelSm" class="col-form-label col-form-label-sm">邮件激活</label>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<input type="checkbox" id="inlineCheckbox3" name="email_active" value="1" {eq name="$optionsForSet.email_active" value="1" }checked{/eq}>
|
||||
<label for="inlineCheckbox3">启用</label>
|
||||
</div>
|
||||
<div class="col-md-4 option-des"> 启用后,新用户注册需要点击邮件中的激活链接才能完成。请确认邮件发送设置是否正确,否则激活邮件无法送达</div>
|
||||
</div>
|
||||
|
||||
<div class="row form-setting">
|
||||
<div class="col-md-1 form-label ">
|
||||
<label for="colFormLabelSm" class="col-form-label col-form-label-sm">登录验证码</label>
|
||||
</div>
|
||||
<div class="col-md-4"> <input type="checkbox" id="login_captcha" name="login_captcha" value="1" {eq name="$optionsForSet.login_captcha" value="1" }checked{/eq}>
|
||||
<label for="login_captcha">启用</label>
|
||||
</div>
|
||||
<div class="col-md-4 option-des"> 是否启用登录表单验证码</div>
|
||||
</div>
|
||||
|
||||
<div class="row form-setting">
|
||||
<div class="col-md-1 form-label ">
|
||||
<label for="colFormLabelSm" class="col-form-label col-form-label-sm">注册验证码</label>
|
||||
</div>
|
||||
<div class="col-md-4"> <input type="checkbox" id="reg_captcha" name="reg_captcha" value="1" {eq name="$optionsForSet.reg_captcha" value="1" }checked{/eq}>
|
||||
<label for="reg_captcha">启用</label>
|
||||
</div>
|
||||
<div class="col-md-4 option-des"> 是否启用注册表单验证码</div>
|
||||
</div>
|
||||
|
||||
<div class="row form-setting">
|
||||
<div class="col-md-1 form-label ">
|
||||
<label for="colFormLabelSm" class="col-form-label col-form-label-sm">找回密码验证码</label>
|
||||
</div>
|
||||
<div class="col-md-4"> <input type="checkbox" id="forget_captcha" name="forget_captcha" value="1" {eq name="$optionsForSet.forget_captcha" value="1" }checked{/eq}>
|
||||
<label for="forget_captcha">启用</label>
|
||||
</div>
|
||||
<div class="col-md-4 option-des"> 是否启用找回密码表单验证码</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="row form-setting">
|
||||
<div class="col-md-1 form-label ">
|
||||
</div>
|
||||
<div class="col-md-4"> <button type="button" class="btn btn-primary" id="saveReg">保存设置</button></div>
|
||||
<div class="col-md-4 option-des"> </div>
|
||||
<br><br><br>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Example DataTables Card-->
|
||||
|
||||
</div>
|
||||
<!-- /.container-fluid-->
|
||||
</div>
|
||||
|
||||
<!-- /.content-wrapper-->
|
||||
|
||||
|
||||
|
||||
{/block}
|
||||
{block name="js"}
|
||||
<script src="/static/js/admin/setting.js"></script>
|
||||
<script type="text/javascript">
|
||||
|
||||
</script>
|
||||
{/block}
|
||||
@ -0,0 +1,110 @@
|
||||
{extend name="header_admin" /}
|
||||
{block name="title"}文件列表- {$options.siteName}{/block}
|
||||
{block name="content"}
|
||||
<div class="content-wrapper">
|
||||
<div class="container-fluid">
|
||||
<!-- Breadcrumbs-->
|
||||
<ol class="breadcrumb">
|
||||
<li class="breadcrumb-item">
|
||||
<a href="/Admin">管理面板</a>
|
||||
</li>
|
||||
<li class="breadcrumb-item active">分享</li>
|
||||
</ol>
|
||||
|
||||
<!-- Area Chart Example-->
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<h2>分享</h2>
|
||||
<br>
|
||||
<div class="card mb-3">
|
||||
<div class="card-header">
|
||||
<i class="fa fa-tags"></i> 条件检索</div>
|
||||
<div class="card-body">
|
||||
<div class="row">
|
||||
<div class="col-1 form-label-search mb-2">排序方式</div>
|
||||
<div class="col-md-10">
|
||||
<ul class="nav nav-pills" id="order">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link selectLab" href="javascript:void()" data-method="id DESC">日期</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link selectLab" href="javascript:void()" data-method="download_num DESC">下载次数</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link selectLab" href="javascript:void()" data-method="view_num DESC">浏览次数</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card mb-3">
|
||||
<div class="card-header">
|
||||
<i class="fa fa-table"></i> 分享列表</div>
|
||||
<div class="card-body">
|
||||
<div class="table-responsive">
|
||||
<div id="dataTable_wrapper" class="dataTables_wrapper container-fluid dt-bootstrap4"><div class="row"><div class="col-sm-12 col-md-6"><div class="dataTables_length" ><label>每页展示 <select id="dataTable_length" aria-controls="dataTable" class="form-control form-control-sm"><option value="10">10</option><option value="25">25</option><option value="50">50</option><option value="100">100</option></select> 个</label></div></div><div class="col-sm-12 col-md-6"><div id="dataTable_filter" class="dataTables_filter"><label>搜索:<input type="search" class="form-control form-control-sm" placeholder="" id="searchFrom"></label></div></div></div><div class="row"><div class="col-sm-12">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-bordered dataTable" id="dataTable" width="100%" cellspacing="0" role="grid" aria-describedby="dataTable_info" style="width: 100%;">
|
||||
<thead>
|
||||
<tr role="row" class="textCenter"><th><input type="checkbox" data-type="all"></th><th>分享名称</th><th class="textCenter">分享者</th><th class="textCenter">类型</th><th class="textCenter">日期</th><th class="textCenter">浏览次数</th><th class="textCenter">下载次数</th><th class="textCenter">操作</th></tr>
|
||||
</thead>
|
||||
<tfoot>
|
||||
<tr><th rowspan="1" colspan="1" class="textCenter"><input type="checkbox" data-type="all"></th><th rowspan="1" colspan="1" class="textCenter">分享名称</th><th rowspan="1" colspan="1" class="textCenter">分享者</th><th rowspan="1" colspan="1" class="textCenter">类型</th><th rowspan="1" colspan="1" class="textCenter">日期</th><th rowspan="1" colspan="1" class="textCenter">浏览次数</th><th rowspan="1" colspan="1" class="textCenter">下载次数</th><th rowspan="1" colspan="1" class="textCenter">操作</th></tr>
|
||||
</tfoot>
|
||||
<tbody>
|
||||
<tr role="row" class="odd" id="fileList">
|
||||
|
||||
{volist name='list' id='share'}
|
||||
<tr role="row" class="odd">
|
||||
<td class="sorting_1 textCenter"><input type="checkbox" data-type="mark" data-id="{$share.id}"></td>
|
||||
<td>
|
||||
{eq name="$share.source_type" value="dir"}
|
||||
<i class="fa fa-folder-open-o" aria-hidden="true"></i> <a href="/S/{$share.share_key}?pwd={$share.share_pwd}" class="noAColor" target="_blank">{:htmlspecialchars(getDirName($share.source_name),ENT_NOQUOTES)}</a>
|
||||
{else}
|
||||
<i class="fa fa-file" aria-hidden="true"></i> <a href="/S/{$share.share_key}?pwd={$share.share_pwd}" class="noAColor" target="_blank">{$share.origin_name|htmlspecialchars=ENT_NOQUOTES}</a>
|
||||
{/eq}
|
||||
</td>
|
||||
<td class="textCenter">{$originList[$key]["user"]["user_nick"]}</td>
|
||||
<td class="textCenter">
|
||||
{eq name="share.type" value="public"}
|
||||
<i class="fa fa-eye" aria-hidden="true"></i> 公开
|
||||
{else/}
|
||||
<i class="fa fa-lock" aria-hidden="true"></i> 私密
|
||||
{/eq}
|
||||
</td>
|
||||
<td class="textCenter">{$share.share_time}</td>
|
||||
<td class="textCenter">{$share.view_num}</td>
|
||||
<td class="textCenter">{$share.download_num}</td>
|
||||
<td class="textCenter"><button type="button" class="btn btn-secondary fix" data-toggle="tooltip" data-placement="top" title="删除" data-action="delete" data-id="{$share.id}"><i class="fa fa-trash" aria-hidden="true"></i></button> <button type="button" class="btn btn-secondary fix" data-toggle="tooltip" data-placement="top" title="变更分享类型" data-action="change" data-id="{$share.share_key}"><i class="fa fa-lock" aria-hidden="true"></i></button></td>
|
||||
</tr>
|
||||
{/volist}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="col-md-5 mb-2 mt-2" style="display: none" id="del">
|
||||
<button type="button" class="btn btn-danger" id="delAll"><i class="fa fa-trash" aria-hidden="true"></i> 删除选中文件</button>
|
||||
</div>
|
||||
</div></div><div class="row"><div class="col-sm-12 col-md-5"><div class="dataTables_info" id="dataTable_info" role="status" aria-live="polite">展示第 {$pageNow} 页,共 {$pageTotal} 页 {$dataTotal} 条数据</div></div><div class="col-sm-12 col-md-7">
|
||||
<div class="dataTables_paginate paging_simple_numbers" id="dataTable_paginate">
|
||||
{$list->render()}
|
||||
</div></div></div></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Example DataTables Card-->
|
||||
</div>
|
||||
<!-- /.container-fluid-->
|
||||
</div>
|
||||
<!-- /.content-wrapper-->
|
||||
{/block}
|
||||
{block name="js"}
|
||||
<script src="/static/js/admin/shares.js"></script>
|
||||
<script type="text/javascript">
|
||||
</script>
|
||||
{/block}
|
||||
@ -0,0 +1,51 @@
|
||||
{extend name="header_admin" /}
|
||||
{block name="title"}基础设置- {$options.siteName}{/block}
|
||||
{block name="content"}
|
||||
<div class="content-wrapper">
|
||||
<div class="container-fluid">
|
||||
<!-- Breadcrumbs-->
|
||||
<ol class="breadcrumb">
|
||||
<li class="breadcrumb-item">
|
||||
<a href="/Admin">管理面板</a>
|
||||
</li>
|
||||
<li class="breadcrumb-item active">模板</li>
|
||||
</ol>
|
||||
|
||||
<!-- Area Chart Example-->
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<h2>编辑模板</h2>
|
||||
application/index/view/{:rtrim($path,"/")}/{$name}.html
|
||||
<br> <br>
|
||||
<div class="row">
|
||||
<div class="col-md-9">
|
||||
<input type="text" id="fileName" value="{$name}" style="display: none">
|
||||
<textarea rows="15" class="form-control" spellcheck="false" style=" font-family: 'Courier New';">{:htmlspecialchars($content)}</textarea>
|
||||
<br>
|
||||
<button class="btn btn-primary" id="saveTheme">保存</button>
|
||||
<br><br>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="file_side">
|
||||
<div class="nav flex-column nav-pills" id="v-pills-tab" role="tablist" aria-orientation="vertical">
|
||||
{volist name="list" id="file"}
|
||||
<a class="nav-link" id="v-pills-home-tab" href="/Admin/Theme/name/{:str_replace(".html","",$file)}" role="tab" data-name="{:str_replace(".html","",$file)}">{$file}</a>
|
||||
{/volist}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Example DataTables Card-->
|
||||
</div>
|
||||
<!-- /.container-fluid-->
|
||||
</div>
|
||||
{/block}
|
||||
{block name="js"}
|
||||
<script src="/static/js/admin/config.js"></script>
|
||||
<script type="text/javascript">
|
||||
</script>
|
||||
{/block}
|
||||
@ -0,0 +1,298 @@
|
||||
{extend name="header_admin" /}
|
||||
{block name="title"}文件列表- {$options.siteName}{/block}
|
||||
{block name="content"}
|
||||
<div class="content-wrapper">
|
||||
<div class="container-fluid">
|
||||
<!-- Breadcrumbs-->
|
||||
<ol class="breadcrumb">
|
||||
<li class="breadcrumb-item">
|
||||
<a href="/Admin">管理面板</a>
|
||||
</li>
|
||||
<li class="breadcrumb-item active">用户</li>
|
||||
</ol>
|
||||
|
||||
<!-- Area Chart Example-->
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<h2>用户 <button class="btn btn-secondary btn-sm" data-toggle="modal" data-target="#addUser"><li class="fa fa-plus"></li></button></h2>
|
||||
<br>
|
||||
<div class="card mb-3">
|
||||
<div class="card-header">
|
||||
<i class="fa fa-tags"></i> 条件检索</div>
|
||||
<div class="card-body">
|
||||
<div class="row">
|
||||
<div class="col-1 form-label-search mb-2">排序方式</div>
|
||||
<div class="col-md-10">
|
||||
<ul class="nav nav-pills" id="order">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link selectLab" href="javascript:void()" data-method="user_nick ASC">用户名</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link selectLab" href="javascript:void()" data-method="id DESC">注册日期</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link selectLab" href="javascript:void()" data-method="used_storage DESC">已用空间</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-1 form-label-search mb-2">用户组</div>
|
||||
<div class="col-md-10">
|
||||
<ul class="nav nav-pills" id="groupS">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link selectLab" href="javascript:void()" data-group="">全部</a>
|
||||
</li>
|
||||
{volist name="group" id="group"}
|
||||
<li class="nav-item">
|
||||
<a class="nav-link selectLab" href="javascript:void()" data-group="{$group.id}">{$group.group_name}</a>
|
||||
</li>
|
||||
{/volist}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-1 form-label-search mb-2">用户状态</div>
|
||||
<div class="col-md-10">
|
||||
<ul class="nav nav-pills" id="status">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link selectLab" href="javascript:void()" data-status="">全部</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link selectLab" href="javascript:void()" data-status="1">正常</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link selectLab" href="javascript:void()" data-status="2">封禁/未激活</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row" style="margin-top: 5px;">
|
||||
<div class="col-1 form-label-search mb-2">高级检索</div>
|
||||
<div class="col-md-10">
|
||||
<div class="row">
|
||||
<div class="col-md-2">
|
||||
<select class="form-control form-control-sm" id="searchColUser">
|
||||
<option value="id">用户UID</option>
|
||||
<option value="user_nick">用户昵称</option>
|
||||
<option value="user_date">注册日期</option>
|
||||
<option value="user_email">邮箱</option>
|
||||
<option value="group_primary">初始用户组</option>
|
||||
<option value="user_activation_key">邮箱激活密钥</option>
|
||||
<option value="used_storage">已用空间</option>
|
||||
<option value="delay_time">用户组过期日期</option>
|
||||
<option value="avatar">头像标识</option>
|
||||
<option value="profile">个人主页状态</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<input type="text" class="form-control form-control-sm" placeholder="检索表达式" id="searchValueUser">
|
||||
</div>
|
||||
<div class="col-md-1">
|
||||
<button type="button" class="btn btn-primary btn-sm" id="applySearch">应用</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card mb-3">
|
||||
<div class="card-header">
|
||||
<i class="fa fa-table"></i> 用户列表 </div>
|
||||
<div class="card-body">
|
||||
<div class="table-responsive">
|
||||
<div id="dataTable_wrapper" class="dataTables_wrapper container-fluid dt-bootstrap4"><div class="row"><div class="col-sm-12 col-md-6"><div class="dataTables_length" ><label>每页展示 <select id="dataTable_length" aria-controls="dataTable" class="form-control form-control-sm"><option value="10">10</option><option value="25">25</option><option value="50">50</option><option value="100">100</option></select> 个</label></div></div><div class="col-sm-12 col-md-6"><div id="dataTable_filter" class="dataTables_filter"><label>搜索:<input type="search" class="form-control form-control-sm" placeholder="" id="searchFrom"></label></div></div></div><div class="row"><div class="col-sm-12">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-bordered dataTable" id="dataTable" width="100%" cellspacing="0" role="grid" aria-describedby="dataTable_info" style="width: 100%;">
|
||||
<thead>
|
||||
<tr role="row" class="textCenter"><th><input type="checkbox" data-type="all"></th><th>UID</th><th>昵称</th><th class="textCenter">邮箱</th><th class="textCenter">用户组</th><th class="textCenter">空间用量</th><th class="textCenter">状态</th><th class="textCenter">操作</th></tr>
|
||||
</thead>
|
||||
<tfoot>
|
||||
<tr><th rowspan="1" colspan="1" class="textCenter"><input type="checkbox" data-type="all"></th><th rowspan="1" colspan="1" class="textCenter">UID</th><th rowspan="1" colspan="1" class="textCenter">昵称</th><th rowspan="1" colspan="1" class="textCenter">邮箱</th><th rowspan="1" colspan="1" class="textCenter">用户组</th><th rowspan="1" colspan="1" class="textCenter">空间用量</th><th rowspan="1" colspan="1" class="textCenter">状态</th><th rowspan="1" colspan="1" class="textCenter">操作</th></tr>
|
||||
</tfoot>
|
||||
<tbody>
|
||||
<tr role="row" class="odd" id="userList">
|
||||
|
||||
{volist name='list' id='user'}
|
||||
<tr role="row" class="odd">
|
||||
<td class="sorting_1 textCenter"><input type="checkbox" data-type="mark" data-id="{$user.id}"></td>
|
||||
<td class="textCenter">{$user.id}</td>
|
||||
<td class="textCenter">{$user.user_nick}</td>
|
||||
<td class="textCenter">{$user.user_email}</td>
|
||||
<td class="textCenter">{:$originList[$key]["group"]["group_name"]}</td>
|
||||
<td class="textCenter">{:countSize($user.used_storage)}</td>
|
||||
<td class="textCenter">
|
||||
{eq name="user.user_status" value="0"}
|
||||
<span class="order_success">正常</span>
|
||||
{else/}
|
||||
<span class="order_warning">封禁/未激活</span>
|
||||
{/eq}
|
||||
</td>
|
||||
<td class="textCenter">
|
||||
<button type="button" class="btn btn-secondary fix" data-toggle="tooltip" data-placement="top" title="删除" data-action="delete" data-id="{$user.id}" data-unable="{eq name="user.used_storage" value="0"}0{else/}1{/eq}"><i class="fa fa-trash" aria-hidden="true"></i></button>
|
||||
<button type="button" class="btn btn-secondary fix" data-toggle="tooltip" data-placement="top" title="编辑" data-action="edit" data-id="{$user.id}"><i class="fa fa-id-card" aria-hidden="true"></i></button>
|
||||
<button type="button" class="btn btn-secondary fix" data-toggle="tooltip" data-placement="top" title="封号/解封" data-action="ban" data-id="{$user.id}"><i class="fa fa-ban" aria-hidden="true"></i></button>
|
||||
</td>
|
||||
</tr>
|
||||
{/volist}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="col-md-5 mb-2 mt-2" style="display: none" id="del">
|
||||
<button type="button" class="btn btn-danger" id="delAll"><i class="fa fa-trash" aria-hidden="true"></i> 删除选中用户</button>
|
||||
</div>
|
||||
</div></div><div class="row"><div class="col-sm-12 col-md-5"><div class="dataTables_info" id="dataTable_info" role="status" aria-live="polite">展示第 {$pageNow} 页,共 {$pageTotal} 页 {$dataTotal} 条数据</div></div><div class="col-sm-12 col-md-7">
|
||||
<div class="dataTables_paginate paging_simple_numbers" id="dataTable_paginate">
|
||||
{$list->render()}
|
||||
</div></div></div></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Example DataTables Card-->
|
||||
</div>
|
||||
<!-- /.container-fluid-->
|
||||
</div>
|
||||
<div class="modal fade bd-example-modal-sm" tabindex="-1" role="dialog" aria-labelledby="mySmallModalLabel" aria-hidden="true" id="editUser">
|
||||
<div class="modal-dialog modal-sm">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="exampleModalLabel">用户详情</h5>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form id="editUserForm">
|
||||
<div class="form-group">
|
||||
<label>
|
||||
头像
|
||||
</label>
|
||||
<img src="" id="user_avatar">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="name">UID</label>
|
||||
<input type="text" name="uid" id="uid" style="display: none;">
|
||||
<input class="form-control" id="id" type="text" value="17" readonly>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="lovelyname">昵称</label>
|
||||
<input type="text " class="form-control" id="user_nick" name="user_nick" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="InputPassword1">密码</label>
|
||||
<input type="password" class="form-control" id="user_pass" name="user_pass" placeholder="如果不修改密码则留空" >
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="InputEmail1">邮箱</label>
|
||||
<input type="email" class="form-control" id="user_email" name="user_email" placeholder="Email" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="date">注册日期</label>
|
||||
<input class="form-control" id="user_date" type="text" value="2017.12.31" readonly>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="space">已用空间</label>
|
||||
<input class="form-control" id="used_storage" type="text" value="500M" readonly>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="openid">二步验证秘钥</label>
|
||||
<input type="text " class="form-control" id="two_step" name="two_step" placeholder="取消二步验证请填写0" required="">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="inputState">用户状态</label>
|
||||
<select class="form-control" id="user_status" name="user_status">
|
||||
<option value="0">正常</option>
|
||||
<option value="1">封禁/未激活</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="inputState">用户组</label>
|
||||
<select id="user_group" class="form-control" name="user_group">
|
||||
{foreach $groups as $g}
|
||||
<option value="{$g.id}">{$g.group_name}</option>
|
||||
{/foreach}
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="inputState">个人主页状态</label>
|
||||
<div class="radio">
|
||||
<label>
|
||||
<input type="radio" name="profile" id="profile1" value="1">
|
||||
开启
|
||||
</label>
|
||||
<label>
|
||||
<input type="radio" name="profile" id="profile0" value="0">
|
||||
关闭
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal">取消</button>
|
||||
<button type="submit" class="btn btn-primary" id="editUserSubmit">保存</button>
|
||||
</div></form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal fade bd-example-modal-sm" tabindex="-1" role="dialog" aria-labelledby="mySmallModalLabel" aria-hidden="true" id="addUser">
|
||||
<div class="modal-dialog modal-sm">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="exampleModalLabel">添加用户</h5>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form id="addUserForm">
|
||||
<div class="form-group">
|
||||
<label for="lovelyname">昵称</label>
|
||||
<input type="text " class="form-control" id="user_nick" name="user_nick" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="InputPassword1">密码</label>
|
||||
<input type="password" class="form-control" id="user_pass" name="user_pass" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="InputEmail1">邮箱</label>
|
||||
<input type="email" class="form-control" id="user_email" name="user_email" placeholder="Email" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="inputState">用户状态</label>
|
||||
<select class="form-control" name="user_status">
|
||||
<option value="0">正常</option>
|
||||
<option value="1">封禁/未激活</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="inputState">用户组</label>
|
||||
<select class="form-control" name="user_group">
|
||||
{foreach $groups as $g}
|
||||
<option value="{$g.id}">{$g.group_name}</option>
|
||||
{/foreach}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal">取消</button>
|
||||
<button type="submit" class="btn btn-primary" id="addUserSubmit">保存</button>
|
||||
</div></form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- /.content-wrapper-->
|
||||
{/block}
|
||||
{block name="js"}
|
||||
<script src="/static/js/admin/users.js"></script>
|
||||
<script type="text/javascript">
|
||||
</script>
|
||||
{/block}
|
||||
@ -0,0 +1,23 @@
|
||||
{extend name="header_public" /}
|
||||
{block name="title"}支付成功 - {$options.siteName}{/block}
|
||||
{block name="content"}
|
||||
<link rel="stylesheet" href="/static/css/error.css" />
|
||||
</head>
|
||||
<body data-ma-header="teal">
|
||||
|
||||
<div class="container" align="center">
|
||||
<header align="left">
|
||||
<br>
|
||||
<img src="/img/logo_s.png" style="width:192px;">
|
||||
</header>
|
||||
<div class="error_content" >
|
||||
<div class="jumbotron animated bounce" style="padding-left:30px;">
|
||||
<h1>支付成功</h1>
|
||||
<br>
|
||||
<p> 付款成功,您所购买的服务已开通。</p>
|
||||
<p><a class="btn btn-primary btn-lg" href="/Home/Quota">查看详情</a></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
{/block}
|
||||
@ -0,0 +1,24 @@
|
||||
{extend name="header_public" /}
|
||||
{block name="title"}错误提示 - {$options.siteName}{/block}
|
||||
{block name="content"}
|
||||
<link rel="stylesheet" href="/static/css/error.css" />
|
||||
</head>
|
||||
<body data-ma-header="teal">
|
||||
|
||||
<div class="container" align="center">
|
||||
<header align="left">
|
||||
<br>
|
||||
<img src="/static/img/logo_s.png" style="width:192px;">
|
||||
</header>
|
||||
<div class="error_content" >
|
||||
<div class="jumbotron animated bounce" style="padding-left:30px;">
|
||||
<h1>发生错误</h1>
|
||||
<br>
|
||||
<p> {$msg}</p>
|
||||
<p><a class="btn btn-primary btn-lg" onclick="history.go(-1);"><< 返回</a></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{$options.js_code}
|
||||
</body>
|
||||
{/block}
|
||||
@ -0,0 +1,24 @@
|
||||
{extend name="header_public" /}
|
||||
{block name="title"}错误提示 - {$options.siteName}{/block}
|
||||
{block name="content"}
|
||||
<link rel="stylesheet" href="/static/css/error.css" />
|
||||
</head>
|
||||
<body data-ma-header="teal">
|
||||
|
||||
<div class="container" align="center">
|
||||
<header align="left">
|
||||
<br>
|
||||
<img src="/static/img/logo_s.png" style="width:192px;">
|
||||
</header>
|
||||
<div class="error_content" >
|
||||
<div class="jumbotron animated bounce" style="padding-left:30px;">
|
||||
<h1>发生错误</h1>
|
||||
<br>
|
||||
<p> {$msg}</p>
|
||||
<p><a class="btn btn-primary btn-lg" onclick="history.go(-1);"><< 返回</a></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{$options.js_code}
|
||||
</body>
|
||||
{/block}
|
||||
@ -0,0 +1,76 @@
|
||||
{extend name="header_public" /}
|
||||
{block name="title"}“{$keyWords}”搜索结果 - {$options.siteName}{/block}
|
||||
{block name="content"}
|
||||
<link rel="stylesheet" href="/static/css/search.css" />
|
||||
</head>
|
||||
<body data-ma-header="teal">
|
||||
<nav class="navbar navbar-inverse" >
|
||||
<div class="container-fluid">
|
||||
<div class="container" >
|
||||
{include file="navbar_public" /}
|
||||
<div class="header-panel shadow-z-2">
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="container main-h">
|
||||
|
||||
<div class="col-md-12">
|
||||
<h1>搜索分享</h1>
|
||||
<input type="text" placeholder="请输入关键词,回车键发起搜索" value="{$keyWords}" autofocus="true"><br><br>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th width="50%">文件名 </th>
|
||||
<th class="cent">分享日期</th>
|
||||
<th class="cent">下载次数</th>
|
||||
<th class="cent">浏览次数</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>{volist name='list' id='shares'}
|
||||
<tr>
|
||||
<td >{switch $shares.source_type}
|
||||
{case file}<i class="fa fa-file" aria-hidden="true"></i> {/case}
|
||||
{case dir}<i class="fa fa-folder-open blue" aria-hidden="true"></i> {/case}
|
||||
|
||||
{/switch} <a href="/s/{$shares.share_key}" class="notWave" target="_blank">{$shares.fileData|htmlspecialchars=ENT_NOQUOTES}</a></td>
|
||||
<td class="cent">{$shares.share_time}</td>
|
||||
<td align="center">{$shares.download_num}</td>
|
||||
<td align="center">{$shares.view_num}</td>
|
||||
</tr>
|
||||
|
||||
{/volist}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
{$listOrigin->render()}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
<script type="text/javascript">
|
||||
</script>
|
||||
<script src="/static/js/material.js"></script>
|
||||
<script >
|
||||
$.material.init();
|
||||
document.onkeydown=function(){
|
||||
if (event.keyCode == 13){
|
||||
keyWords = $("input").val();
|
||||
if(keyWords ==""){
|
||||
toastr["warning"]("关键字不能为空");
|
||||
}else{
|
||||
window.location="/Explore/S/"+keyWords;
|
||||
}
|
||||
}
|
||||
else{
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
{$options.js_code}
|
||||
{/block}
|
||||
@ -0,0 +1,47 @@
|
||||
{extend name="header_public" /}
|
||||
{block name="title"}用户主页 - {$options.siteName}{/block}
|
||||
{block name="content"}
|
||||
<link rel="stylesheet" href="/static/css/search.css" />
|
||||
</head>
|
||||
<body data-ma-header="teal">
|
||||
<nav class="navbar navbar-inverse" >
|
||||
<div class="container-fluid">
|
||||
<div class="container" >
|
||||
{include file="navbar_public" /}
|
||||
<div class="header-panel shadow-z-2">
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="container main-h">
|
||||
|
||||
<div class="col-md-12">
|
||||
<h1>搜索分享</h1>
|
||||
<input type="text" placeholder="请输入关键词,回车键发起搜索" autofocus="true">
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
<script type="text/javascript">
|
||||
</script>
|
||||
<script src="/static/js/material.js"></script>
|
||||
<script >
|
||||
document.onkeydown=function(){
|
||||
if (event.keyCode == 13){
|
||||
keyWords = $("input").val();
|
||||
if(keyWords ==""){
|
||||
toastr["warning"]("关键字不能为空");
|
||||
}else{
|
||||
window.location="/Explore/S/"+keyWords;
|
||||
}
|
||||
}
|
||||
else{
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
{$options.js_code}
|
||||
{/block}
|
||||
@ -0,0 +1,5 @@
|
||||
下载已开始...
|
||||
<a href="{$url}" download="" id="downloadA">手动下载</a>
|
||||
<script type="text/javascript">
|
||||
document.getElementById("downloadA").click();
|
||||
</script>
|
||||
@ -0,0 +1,36 @@
|
||||
<!DOCTYPE html>
|
||||
<html class="full-height">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<meta http-equiv="x-ua-compatible" content="ie=edge">
|
||||
<meta name="keywords" content="{$options.siteKeywords}"/>
|
||||
<meta name="description" content="{$options.siteDes}"/>
|
||||
<title>{$options.siteName} - {$options.siteTitle}</title>
|
||||
|
||||
<!-- Font Awesome -->
|
||||
<link rel="stylesheet" href="/static/css/font-awesome.min.css">
|
||||
<!-- Bootstrap core CSS -->
|
||||
<link href="/static/css/bootstrap4/bootstrap.min.css" rel="stylesheet">
|
||||
<!-- Material Design Bootstrap -->
|
||||
<link href="/static/css/mdb.css" rel="stylesheet">
|
||||
|
||||
</head>
|
||||
<body class="grey-skin intro-page creative-lp">
|
||||
<!--Navigation & Intro-->
|
||||
<header>
|
||||
|
||||
<!--Navbar-->
|
||||
<nav class="navbar fixed-top navbar-dark ">
|
||||
|
||||
<div class="container">
|
||||
|
||||
|
||||
<a class="navbar-brand" href="#">
|
||||
<img src="static/img/logo_s.png" style=" width: 192px;">
|
||||
</a>
|
||||
|
||||
|
||||
</div>
|
||||
</nav>
|
||||
<!--/Navbar-->
|
||||
@ -0,0 +1,15 @@
|
||||
<html lang="zh-cn" data-ng-app="FileManagerApp">
|
||||
<head>
|
||||
<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
|
||||
<meta charset="utf-8">
|
||||
<title>{block name="title"}{/block}</title>
|
||||
<!-- third party -->
|
||||
<link rel="stylesheet" href="/static/css/bootstrap.min.css" />
|
||||
<link rel="stylesheet" href="/static/css/material.css" />
|
||||
<link rel="stylesheet" href="/static/css/animate.css" />
|
||||
<link rel="stylesheet" href="/static/css/font-awesome.min.css">
|
||||
<!-- /third party -->
|
||||
<!-- Comment if you need to use raw source code -->
|
||||
<link href="/static/css/toastr.min.css" rel="stylesheet">
|
||||
<!-- /Comment if you need to use raw source code -->
|
||||
{block name="content"}{/block}
|
||||
@ -0,0 +1,27 @@
|
||||
<!doctype html>
|
||||
<html lang="zh-cn" data-ng-app="FileManagerApp">
|
||||
<head>
|
||||
<!--
|
||||
* Angular FileManager v1.5.1 (https://github.com/joni2back/angular-filemanager)
|
||||
* Jonas Sciangula Street <joni2back@gmail.com>
|
||||
* Licensed under MIT (https://github.com/joni2back/angular-filemanager/blob/master/LICENSE)
|
||||
-->
|
||||
<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
|
||||
<meta charset="utf-8">
|
||||
<title>{block name="title"}{/block}</title>
|
||||
<!-- third party -->
|
||||
|
||||
<script src="/static/js/jquery.min.js"></script>
|
||||
<link rel="stylesheet" href="/static/css/bootstrap.min.css" />
|
||||
<link rel="stylesheet" href="/static/css/material.css" />
|
||||
<script src="/static/js/bootstrap.min.js"></script>
|
||||
<link rel="stylesheet" href="/static/css/font-awesome.min.css">
|
||||
<!-- /third party -->
|
||||
<!-- Comment if you need to use raw source code -->
|
||||
<link href="/static/css/angular-filemanager.min.css" rel="stylesheet">
|
||||
<link href="/static/css/toastr.min.css" rel="stylesheet">
|
||||
<script type="text/javascript" src="/static/js/toastr.min.js"></script>
|
||||
<!-- /Comment if you need to use raw source code -->
|
||||
<script type="text/javascript">
|
||||
</script>
|
||||
{block name="content"}{/block}
|
||||
@ -0,0 +1,19 @@
|
||||
<html lang="zh-cn" data-ng-app="FileManagerApp">
|
||||
<head>
|
||||
<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
|
||||
<meta charset="utf-8">
|
||||
<title>{block name="title"}{/block}</title>
|
||||
<!-- third party -->
|
||||
<script src="/static/js/jquery.min.js"></script>
|
||||
<link rel="stylesheet" href="/static/css/bootstrap.min.css" />
|
||||
<link rel="stylesheet" href="/static/css/material.css" />
|
||||
<link rel="stylesheet" href="/static/css/animate.css" />
|
||||
<script src="/static/js/material.js"></script>
|
||||
<script src="/static/js/bootstrap.min.js"></script>
|
||||
<link rel="stylesheet" href="/static/css/font-awesome.min.css">
|
||||
<!-- /third party -->
|
||||
<!-- Comment if you need to use raw source code -->
|
||||
<link href="/static/css/toastr.min.css" rel="stylesheet">
|
||||
<script type="text/javascript" src="/static/js/toastr.min.js"></script>
|
||||
<!-- /Comment if you need to use raw source code -->
|
||||
{block name="content"}{/block}
|
||||
@ -0,0 +1,82 @@
|
||||
<!DOCTYPE HTML>
|
||||
<!--
|
||||
Multiverse by HTML5 UP
|
||||
html5up.net | @ajlkn
|
||||
Free for personal and commercial use under the CCA 3.0 license (html5up.net/license)
|
||||
-->
|
||||
<html>
|
||||
<head>
|
||||
<title>图片集 - {$options.siteName}</title>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no" />
|
||||
<!--[if lte IE 8]><script src="https://file.aoaoao.me/content/themes/material/pages/js/ie/html5shiv.js"></script><![endif]-->
|
||||
<link rel="stylesheet" href="/static/css/main.css" />
|
||||
<link href="/static/css/font-awesome.min.css" rel="stylesheet">
|
||||
<!--[if lte IE 9]><link rel="stylesheet" href="https://file.aoaoao.me/content/themes/material/pages/css/ie9.css" /><![endif]-->
|
||||
<!--[if lte IE 8]><link rel="stylesheet" href="https://file.aoaoao.me/content/themes/material/pages/css/ie8.css" /><![endif]-->
|
||||
<style type="text/css">
|
||||
body{
|
||||
font-family: "微软雅黑","黑体";
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<!-- Wrapper -->
|
||||
<div id="wrapper">
|
||||
<!-- Header -->
|
||||
|
||||
<div id="main">
|
||||
{volist name='list' id='pic'}
|
||||
<article class="thumb">
|
||||
<a href="/File/Preview?action=preview&path={$pic.dir|urlencode}/{$pic.orign_name|urlencode}" class="image"><img src="/File/Preview?action=preview&path={$pic.dir|urlencode}/{$pic.orign_name|urlencode}" alt="" /></a>
|
||||
<h2>{$pic.orign_name}</h2>
|
||||
|
||||
</article>
|
||||
{/volist}
|
||||
</div>
|
||||
<header id="header">
|
||||
<h1><a href="/Home"><strong>图片集</strong> {$options.siteName}</a></h1>
|
||||
<nav>
|
||||
<ul>
|
||||
<li><a href="javascript:previous();" class="icon fa-arrow-circle-left">上一页</a></li>
|
||||
{$page}/{$pageCount} <li><a href="javascript:next();" class="icon fa-arrow-circle-right">下一页</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
<!-- Main -->
|
||||
<!-- Footer -->
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<!-- Scripts -->
|
||||
<script src = "/static/js/jquery.min.js"></script>
|
||||
<script src="/static/js/jquery.poptrox.min.js"></script>
|
||||
<script src="/static/js/skel.min.js"></script>
|
||||
<script src="/static/js/util.js"></script>
|
||||
<!--[if lte IE 8]><script src="assets/js/ie/respond.min.js"></script><![endif]-->
|
||||
<script src="/static/js/album.js"></script>
|
||||
<script type="text/javascript">
|
||||
pageNow = {$page};
|
||||
pageTotal = {$pageCount};
|
||||
function next(){
|
||||
if(pageNow == pageTotal){
|
||||
|
||||
}else{
|
||||
window.location.href="/Home/Album?page="+(pageNow+1);
|
||||
}
|
||||
}
|
||||
function previous(){
|
||||
if(pageNow == 1){
|
||||
|
||||
}else{
|
||||
window.location.href="/Home/Album?page="+(pageNow-1);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
{$options.js_code}
|
||||
</body>
|
||||
</html>
|
||||
@ -0,0 +1,109 @@
|
||||
<!doctype html>
|
||||
<html lang="en" data-ng-app="FileManagerApp">
|
||||
<head>
|
||||
<!--
|
||||
* Angular FileManager v1.5.1 (https://github.com/joni2back/angular-filemanager)
|
||||
* Jonas Sciangula Street <joni2back@gmail.com>
|
||||
* Licensed under MIT (https://github.com/joni2back/angular-filemanager/blob/master/LICENSE)
|
||||
-->
|
||||
<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
|
||||
<meta charset="utf-8">
|
||||
<title>我的文件 - {$options.siteName}</title>
|
||||
<!-- third party -->
|
||||
<script src="/static/js/angular.min.js"></script>
|
||||
<script src="/static/js/angular-translate.min.js"></script>
|
||||
|
||||
<script src="/static/js/jquery.min.js"></script>
|
||||
<link rel="stylesheet" href="/static/css/bootstrap.min.css" />
|
||||
<link rel="stylesheet" href="/static/css/material.css" />
|
||||
|
||||
<script src="/static/js/bootstrap.min.js"></script>
|
||||
<link rel="stylesheet" href="/static/css/font-awesome.min.css">
|
||||
<!-- /third party -->
|
||||
<!-- Comment if you need to use raw source code -->
|
||||
<link href="/static/css/angular-filemanager.min.css" rel="stylesheet">
|
||||
<link href="/static/css/toastr.min.css" rel="stylesheet">
|
||||
<script type="text/javascript" src="/static/js/toastr.min.js"></script>
|
||||
<script src="/static/js/angular-filemanager.min.js"></script>
|
||||
<link rel="stylesheet" href="/static/css/photoswipe.css">
|
||||
<link rel="stylesheet" href="/static/css/default-skin/default-skin.css">
|
||||
|
||||
<!-- /Comment if you need to use raw source code -->
|
||||
<script type="text/javascript">
|
||||
uploadConfig={
|
||||
saveType : "{$policyData.policy_type}",
|
||||
maxSize : "{$policyData.max_size}mb",
|
||||
allowedType: [
|
||||
{$extLimit}
|
||||
],
|
||||
allowSource : "{$policyData.origin_link}",
|
||||
upUrl : "{$policyData.server}",
|
||||
allowShare:"{$groupData.allow_share}",
|
||||
};
|
||||
</script>
|
||||
<script src="/static/js/home.js"></script>
|
||||
</head>
|
||||
<body class="ng-cloak">
|
||||
<div id="container">
|
||||
{include file="navbar_home" /}
|
||||
<div class="pswp" tabindex="-1" role="dialog" aria-hidden="true">
|
||||
|
||||
<!-- Background of PhotoSwipe.
|
||||
It's a separate element, as animating opacity is faster than rgba(). -->
|
||||
<div class="pswp__bg"></div>
|
||||
<!-- Slides wrapper with overflow:hidden. -->
|
||||
<div class="pswp__scroll-wrap">
|
||||
<!-- Container that holds slides. PhotoSwipe keeps only 3 slides in DOM to save memory. -->
|
||||
<div class="pswp__container">
|
||||
<!-- don't modify these 3 pswp__item elements, data is added later on -->
|
||||
<div class="pswp__item"></div>
|
||||
<div class="pswp__item"></div>
|
||||
<div class="pswp__item"></div>
|
||||
</div>
|
||||
<!-- Default (PhotoSwipeUI_Default) interface on top of sliding area. Can be changed. -->
|
||||
<div class="pswp__ui pswp__ui--hidden">
|
||||
<div class="pswp__top-bar">
|
||||
<!-- Controls are self-explanatory. Order can be changed. -->
|
||||
<div class="pswp__counter"></div>
|
||||
|
||||
<button class="pswp__button pswp__button--close" title="Close (Esc)"></button>
|
||||
<button class="pswp__button pswp__button--fs" title="Toggle fullscreen"></button>
|
||||
<button class="pswp__button pswp__button--zoom" title="Zoom in/out"></button>
|
||||
<!-- Preloader demo https://codepen.io/dimsemenov/pen/yyBWoR -->
|
||||
<!-- element will get class pswp__preloader--active when preloader is running -->
|
||||
<div class="pswp__preloader">
|
||||
<div class="pswp__preloader__icn">
|
||||
<div class="pswp__preloader__cut">
|
||||
<div class="pswp__preloader__donut"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pswp__share-modal pswp__share-modal--hidden pswp__single-tap">
|
||||
<div class="pswp__share-tooltip"></div>
|
||||
</div>
|
||||
<button class="pswp__button pswp__button--arrow--left" title="Previous (arrow left)">
|
||||
</button>
|
||||
<button class="pswp__button pswp__button--arrow--right" title="Next (arrow right)">
|
||||
</button>
|
||||
<div class="pswp__caption">
|
||||
<div class="pswp__caption__center"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-10 max_height">
|
||||
<angular-filemanager></angular-filemanager>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
<script src="/static/js/material.js"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
upload_load=0;
|
||||
|
||||
</script>
|
||||
{$options.js_code}
|
||||
</html>
|
||||
@ -0,0 +1,48 @@
|
||||
{include file="header" /}
|
||||
|
||||
|
||||
<!--Video-->
|
||||
<div class="intro-video view" id="home">
|
||||
<img src="static/img/output.jpg">
|
||||
|
||||
|
||||
<div class="hm-gradient">
|
||||
<div class="full-bg-img flex-center">
|
||||
<div class="container smooth-scroll">
|
||||
<div class="row">
|
||||
<div class="col-md-12 white-text text-center smooth-scroll">
|
||||
<div class="fadeInDown" data-wow-delay="0.2s">
|
||||
<h3 class="brand-name font-bold white-text mb-2">开始云上之旅</h3>
|
||||
<hr class="hr-light">
|
||||
<h4 class="subtext-header mt-2 mb-2">只需十秒钟,注册后即可开始使用免费高速的云存储服务</h4>
|
||||
</div>
|
||||
<a href="/Login" class="btn btn-rounded btn-light-green-2" ><i class="fa fa-paper-plane-o"></i> 立即注册</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--/Video-->
|
||||
|
||||
</header>
|
||||
|
||||
<!--/.Content-->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- JQuery -->
|
||||
<script type="text/javascript" src="/static/js/jquery.min.js"></script>
|
||||
|
||||
|
||||
|
||||
<script>
|
||||
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@ -0,0 +1,59 @@
|
||||
{extend name="header_public" /}
|
||||
{block name="title"}注册成功- {$options.siteName}{/block}
|
||||
{block name="content"}
|
||||
<link rel="stylesheet" href="/static/css/login.css" />
|
||||
<link rel="stylesheet" href="/static/css/photoswipe.css">
|
||||
<link rel="stylesheet" href="/static/css/default-skin/default-skin.css">
|
||||
<script src="/static/js/jquery.color.js"></script>
|
||||
</head>
|
||||
<body data-ma-header="teal">
|
||||
|
||||
|
||||
<nav class="navbar navbar-inverse" >
|
||||
<div class="container-fluid">
|
||||
<div class="container" >
|
||||
{include file="navbar_public" loginStatus=$loginStatus userData=$userData /}
|
||||
<div class="header-panel shadow-z-2">
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="container main" >
|
||||
<div class="col-md-4"></div>
|
||||
<div class="col-md-4">
|
||||
<div class="jumbotron" >
|
||||
<div class="card_top">
|
||||
<div class="row top-color">
|
||||
<div class="card-top-row">
|
||||
<div class="login-icon"><i class="fa fa-check" aria-hidden="true"></i></div>
|
||||
<div class="login-text">注册成功</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card_botom">
|
||||
<div class="row bottom-width">
|
||||
<br>
|
||||
您已成功激活账号。<br><br>
|
||||
<a class="btn btn-raised btn-primary" href="/Login">立即登录</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div></div>
|
||||
<div class="col-md-4"></div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
|
||||
</script>
|
||||
<script src="/static/js/two_step.js"> </script>
|
||||
{$options.js_code}
|
||||
{/block}
|
||||
@ -0,0 +1,185 @@
|
||||
{extend name="header_public" /}
|
||||
{block name="title"}登录- {$options.siteName}{/block}
|
||||
{block name="content"}
|
||||
<link rel="stylesheet" href="/static/css/login.css" />
|
||||
<link rel="stylesheet" href="/static/css/photoswipe.css">
|
||||
<link rel="stylesheet" href="/static/css/default-skin/default-skin.css">
|
||||
<script src="/static/js/jquery.color.js"></script>
|
||||
</head>
|
||||
<body data-ma-header="teal">
|
||||
|
||||
|
||||
<nav class="navbar navbar-inverse" >
|
||||
<div class="container-fluid">
|
||||
<div class="container" >
|
||||
{include file="navbar_public" loginStatus=$loginStatus userData=$userData /}
|
||||
<div class="header-panel shadow-z-2">
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="container main" >
|
||||
<div class="col-md-4"></div>
|
||||
<div class="col-md-4">
|
||||
<div class="jumbotron" id="logForm">
|
||||
<div class="card_top">
|
||||
<div class="row top-color">
|
||||
<div class="card-top-row">
|
||||
<div class="login-icon"><i class="fa fa-user-circle-o" aria-hidden="true"></i></div>
|
||||
<div class="login-text">登录后方可享用精彩内容</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card_botom">
|
||||
<div class="row bottom-width">
|
||||
<form id="loginForm">
|
||||
<div class="form-group label-floating">
|
||||
<label class="control-label" for="inputEmail">Email 电子邮箱</label>
|
||||
<input type="text" class="form-control" id="inputEmail" name="userMail">
|
||||
</div>
|
||||
<div class="form-group label-floating">
|
||||
<label class="control-label" for="inputPwd">密码</label>
|
||||
<input type="password" class="form-control" id="inputPwd" name="userPass">
|
||||
</div>
|
||||
{eq name="$RegOptions.login_captcha" value="1"}
|
||||
|
||||
<div class="input-group form-group label-floating">
|
||||
<label class="control-label" for="captcha">验证码</label>
|
||||
<input type="text" id="captcha" class="form-control" name="captchaCode">
|
||||
<span class="input-group-btn">
|
||||
<div class="captcha_img">{:captcha_img()}</div>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{else/}
|
||||
{/eq}
|
||||
|
||||
</form> <button class="btn btn-raised btn-primary" id="loginButton">登录</button>
|
||||
<div class="link-group">
|
||||
<a href="javascript:void" class="noWave" id="create" data-change="true">创建一个账户</a><br>
|
||||
<a href="javascript:void" class="noWave" id="forgetSwitch2" data-change="true">忘记密码?</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="jumbotron" id="regForm" style="display: none;">
|
||||
<div class="card_top">
|
||||
<div class="row top-color">
|
||||
<div class="card-top-row">
|
||||
<div class="login-icon"><i class="fa fa-sign-in" aria-hidden="true"></i></div>
|
||||
<div class="login-text">注册账户</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card_botom">
|
||||
<div class="row bottom-width">
|
||||
<form id="registerForm">
|
||||
<div class="form-group label-floating">
|
||||
<label class="control-label" for="inputEmail">Email 电子邮箱</label>
|
||||
<input type="text" class="form-control" id="inputEmail" name="username-reg">
|
||||
</div>
|
||||
<div class="form-group label-floating">
|
||||
<label class="control-label" for="inputPwd">密码</label>
|
||||
<input type="password" class="form-control" id="inputPwd" name="password-reg">
|
||||
</div>
|
||||
<div class="form-group label-floating">
|
||||
<label class="control-label" for="inputPwd">重复密码</label>
|
||||
<input type="password" class="form-control" id="inputPwd" name="password-check">
|
||||
</div>
|
||||
{eq name="$RegOptions.reg_captcha" value="1"}
|
||||
|
||||
<div class="input-group form-group label-floating">
|
||||
<label class="control-label" for="captcha">验证码</label>
|
||||
<input type="text" id="captcha" class="form-control" name="captchaCode">
|
||||
<span class="input-group-btn">
|
||||
<div class="captcha_img">{:captcha_img()}</div>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{else/}
|
||||
{/eq}
|
||||
|
||||
</form> <button class="btn btn-raised btn-primary" id="regButton">注册</button> <div class="link-group">
|
||||
<a href="javascript:void" class="noWave" id="loginSwitch3" data-change="true">已有账号?立即登录</a><br>
|
||||
<a href="javascript:void" class="noWave" id="forgetSwitch" data-change="true">忘记密码?</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="jumbotron" id="emailCheck" style="display: none;">
|
||||
<div class="card_top">
|
||||
<div class="row top-color">
|
||||
<div class="card-top-row">
|
||||
<div class="login-icon"><i class="fa fa-envelope" aria-hidden="true"></i></div>
|
||||
<div class="login-text">激活账户</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card_botom">
|
||||
<div class="row bottom-width"><br>
|
||||
我们已经向您的注册邮箱发送了一封确认邮件,请访问邮件中的激活链接以完成注册。如果未收到邮件,请检查您的垃圾邮件。<br><br>如果还仍无法接受邮件,请尝试更换注册邮箱或联系站点管理员。
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="jumbotron" id="forgetForm" style="display: none;">
|
||||
<div class="card_top">
|
||||
<div class="row top-color">
|
||||
<div class="card-top-row">
|
||||
<div class="login-icon"><i class="fa fa-question-circle-o" aria-hidden="true"></i></div>
|
||||
<div class="login-text">找回密码</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card_botom">
|
||||
<div class="row bottom-width">
|
||||
<form id="forgetPwdForm">
|
||||
|
||||
<div class="form-group label-floating">
|
||||
<label class="control-label" for="inputEmail">请填写注册时绑定的邮箱</label>
|
||||
<input type="text" class="form-control" id="regEmail" name="regEmail">
|
||||
</div>
|
||||
{eq name="$RegOptions.forget_captcha" value="1"}
|
||||
|
||||
<div class="input-group form-group label-floating">
|
||||
<label class="control-label" for="captcha">验证码</label>
|
||||
<input type="text" id="captcha" class="form-control" name="captchaCode">
|
||||
<span class="input-group-btn">
|
||||
<div class="captcha_img">{:captcha_img()}</div>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{else/}
|
||||
{/eq}
|
||||
|
||||
</form> <button class="btn btn-raised btn-primary" id="findMyFuckingPwd">找回密码</button> <div class="link-group">
|
||||
<a href="javascript:void" class="noWave" id="loginSwitch2" data-change="true">返回登录</a><br>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div></div>
|
||||
<div class="col-md-4"></div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
|
||||
</script>
|
||||
<script src="/static/js/login.js"> </script>
|
||||
{$options.js_code}
|
||||
{/block}
|
||||
@ -0,0 +1,122 @@
|
||||
{extend name="header_public" /}
|
||||
{block name="title"}登录- {$options.siteName}{/block}
|
||||
{block name="content"}
|
||||
<link rel="stylesheet" href="/static/css/login.css" />
|
||||
<link rel="stylesheet" href="/static/css/photoswipe.css">
|
||||
<link rel="stylesheet" href="/static/css/default-skin/default-skin.css">
|
||||
<script src="/static/js/jquery.color.js"></script>
|
||||
</head>
|
||||
<body data-ma-header="teal">
|
||||
|
||||
|
||||
<nav class="navbar navbar-inverse" >
|
||||
<div class="container-fluid">
|
||||
<div class="container" >
|
||||
{include file="navbar_public" loginStatus=$loginStatus userData=$userData /}
|
||||
<div class="header-panel shadow-z-2">
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="container main" >
|
||||
<div class="col-md-4"></div>
|
||||
<div class="col-md-4">
|
||||
<div class="jumbotron" id="logForm">
|
||||
<div class="card_top">
|
||||
<div class="row top-color">
|
||||
<div class="card-top-row">
|
||||
<div class="login-icon"><i class="fa fa-user-circle-o" aria-hidden="true"></i></div>
|
||||
<div class="login-text">登录后方可享用精彩内容</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card_botom">
|
||||
<div class="row bottom-width">
|
||||
<form id="loginForm">
|
||||
<div class="form-group label-floating">
|
||||
<label class="control-label" for="inputEmail">Email 电子邮箱</label>
|
||||
<input type="text" class="form-control" id="inputEmail" name="userMail">
|
||||
</div>
|
||||
<div class="form-group label-floating">
|
||||
<label class="control-label" for="inputPwd">密码</label>
|
||||
<input type="password" class="form-control" id="inputPwd" name="userPass">
|
||||
</div>
|
||||
{eq name="$RegOptions.login_captcha" value="1"}
|
||||
|
||||
<div class="input-group form-group label-floating">
|
||||
<label class="control-label" for="captcha">验证码</label>
|
||||
<input type="text" id="captcha" class="form-control" name="captchaCode">
|
||||
<span class="input-group-btn">
|
||||
<div class="captcha_img">{:captcha_img()}</div>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{else/}
|
||||
{/eq}
|
||||
|
||||
</form> <button class="btn btn-raised btn-primary" id="loginButton">登录</button> <button class="btn btn-raised btn-info" ><i class="fa fa-qq" aria-hidden="true"></i> 使用QQ账号登录</button><div class="link-group">
|
||||
<a href="#" class="noWave">创建一个账户</a><br>
|
||||
<a href="#" class="noWave">忘记密码?</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="jumbotron" id="regForm">
|
||||
<div class="card_top">
|
||||
<div class="row top-color">
|
||||
<div class="card-top-row">
|
||||
<div class="login-icon"><i class="fa fa-user-circle-o" aria-hidden="true"></i></div>
|
||||
<div class="login-text">登录后方可享用精彩内容</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card_botom">
|
||||
<div class="row bottom-width">
|
||||
<form id="loginForm">
|
||||
<div class="form-group label-floating">
|
||||
<label class="control-label" for="inputEmail">Email 电子邮箱</label>
|
||||
<input type="text" class="form-control" id="inputEmail" name="userMail">
|
||||
</div>
|
||||
<div class="form-group label-floating">
|
||||
<label class="control-label" for="inputPwd">密码</label>
|
||||
<input type="password" class="form-control" id="inputPwd" name="userPass">
|
||||
</div>
|
||||
{eq name="$RegOptions.login_captcha" value="1"}
|
||||
|
||||
<div class="input-group form-group label-floating">
|
||||
<label class="control-label" for="captcha">验证码</label>
|
||||
<input type="text" id="captcha" class="form-control" name="captchaCode">
|
||||
<span class="input-group-btn">
|
||||
<div class="captcha_img">{:captcha_img()}</div>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{else/}
|
||||
{/eq}
|
||||
|
||||
</form> <button class="btn btn-raised btn-primary" id="loginButton">登录</button> <button class="btn btn-raised btn-info" ><i class="fa fa-qq" aria-hidden="true"></i> 使用QQ账号登录</button><div class="link-group">
|
||||
<a href="#" class="noWave">创建一个账户</a><br>
|
||||
<a href="#" class="noWave">忘记密码?</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div></div>
|
||||
<div class="col-md-4"></div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
|
||||
</script>
|
||||
<script src="/static/js/login_bind.js"> </script>
|
||||
{$options.js_code}
|
||||
{/block}
|
||||
@ -0,0 +1,70 @@
|
||||
{extend name="header_public" /}
|
||||
{block name="title"}密码重置- {$options.siteName}{/block}
|
||||
{block name="content"}
|
||||
<link rel="stylesheet" href="/static/css/login.css" />
|
||||
<link rel="stylesheet" href="/static/css/photoswipe.css">
|
||||
<link rel="stylesheet" href="/static/css/default-skin/default-skin.css">
|
||||
<script src="/static/js/jquery.color.js"></script>
|
||||
</head>
|
||||
<body data-ma-header="teal">
|
||||
|
||||
|
||||
<nav class="navbar navbar-inverse" >
|
||||
<div class="container-fluid">
|
||||
<div class="container" >
|
||||
{include file="navbar_public" loginStatus=$loginStatus userData=$userData /}
|
||||
<div class="header-panel shadow-z-2">
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="container main" >
|
||||
<div class="col-md-4"></div>
|
||||
<div class="col-md-4">
|
||||
<div class="jumbotron" >
|
||||
<div class="card_top">
|
||||
<div class="row top-color">
|
||||
<div class="card-top-row">
|
||||
<div class="login-icon"><i class="fa fa-id-card-o" aria-hidden="true"></i></div>
|
||||
<div class="login-text">密码重置</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card_botom">
|
||||
<div class="row bottom-width">
|
||||
<form id="resetForm">
|
||||
<div class="form-group label-floating">
|
||||
<label class="control-label" for="inputPwd">请输入新密码</label>
|
||||
<input type="password" class="form-control" id="inputPwd" name="password-reg">
|
||||
</div>
|
||||
<div class="form-group label-floating">
|
||||
<label class="control-label" for="inputPwd">重复密码</label>
|
||||
<input type="password" class="form-control" id="inputPwd" name="password-check">
|
||||
</div>
|
||||
<input type="text" style="display:none" class="form-control" id="resetKey" name="key" value="{$key}">
|
||||
|
||||
|
||||
</form> <button class="btn btn-raised btn-primary" id="regButton">重设密码</button>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div></div>
|
||||
<div class="col-md-4"></div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
|
||||
</script>
|
||||
<script src="/static/js/reset.js"> </script>
|
||||
{$options.js_code}
|
||||
{/block}
|
||||
@ -0,0 +1,140 @@
|
||||
<nav class="navbar navbar-inverse" >
|
||||
<div class="container-fluid">
|
||||
<!-- Brand and toggle get grouped for better mobile display -->
|
||||
<div class="navbar-header">
|
||||
<a class="navbar-brand" href="/">
|
||||
|
||||
</a>
|
||||
|
||||
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
|
||||
<span class="sr-only">Toggle navigation</span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</button>
|
||||
|
||||
</div>
|
||||
<!-- Collect the nav links, forms, and other content for toggling -->
|
||||
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
|
||||
<ul class="nav navbar-nav navbar-right">
|
||||
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle avatar-a" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"><img src="/Member/Avatar/{$userInfo.uid}/s" class="img-circle avatar-s"> {$userInfo.userNick} <span class="caret"></span></a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="/Profile/{$userInfo.uid}">个人主页</a></li>
|
||||
<li><a href="/Member/Setting">设置</a></li>
|
||||
<li role="separator" class="divider"></li>
|
||||
<li><a href="/Member/LogOut">退出登录</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div><!-- /.navbar-collapse -->
|
||||
</div><!-- /.container-fluid -->
|
||||
</nav>
|
||||
|
||||
<!-- Modal -->
|
||||
<div class="modal fade" id="upload_modal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" onclick = "closeUpload()" data-dismiss="modal" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
<span class="sr-only">Close</span>
|
||||
</button>
|
||||
<h4 class="modal-title" id="myModalLabel">上传文件</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="row" style="margin-top: 20px;">
|
||||
<input type="hidden" id="domain" value="http://7xocov.com1.z0.glb.clouddn.com/">
|
||||
<input type="hidden" id="uptoken_url" value="uptoken">
|
||||
<div class="up_button col-md-4">
|
||||
|
||||
<div id="container">
|
||||
|
||||
<button class="btn btn-raised btn-info btn-lg upload_button" id="pickfiles" >
|
||||
<i class="glyphicon glyphicon-plus"></i>
|
||||
<span id="up_text"></span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div style="display:none" id="success" class="indo col-md-8">
|
||||
<div class="alert alert-success">
|
||||
队列全部文件处理完毕
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-12 " align="center">
|
||||
<div class="info_box" id="info_box">
|
||||
<br>
|
||||
<div class="drag_info">
|
||||
<span class="info_icon"><i class="glyphicon glyphicon-inbox"></i></span>
|
||||
<div class="info_text">拖动文件至此开始上传</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="upload_box" style="display:none;" id="upload_box">
|
||||
<table class="table table-striped table-hover text-left" style="display:none;">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="col-md-4">文件名</th>
|
||||
<th class="col-md-2">大小</th>
|
||||
<th class="col-md-6">进度</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="fsUploadProgress">
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="container" style="display: none;">
|
||||
|
||||
<div class="body">
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-2 s" id="side">
|
||||
<div class="list-group" id="b">
|
||||
<a href="/Home" class="list-group-item">
|
||||
<i class="fa fa-file" aria-hidden="true"></i> 我的文件
|
||||
</a>
|
||||
<a href="/Share/My" class="list-group-item"> <i class="fa fa-share-alt" aria-hidden="true"></i> 我的分享
|
||||
</a>
|
||||
<a href="/Explore/Search" class="list-group-item">
|
||||
<i class="fa fa-search" aria-hidden="true"></i> 搜索分享
|
||||
</a>
|
||||
<a href="/Home/Album" class="list-group-item">
|
||||
<i class="fa fa-picture-o" aria-hidden="true"></i> 图片集
|
||||
</a>
|
||||
</div>
|
||||
<div clss="usage" style=" visibility: visible;
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100px;
|
||||
top: auto;
|
||||
bottom: 0px;
|
||||
|
||||
background-color: #f9f9f9;padding: 15px">
|
||||
<div class="usage-title">容量使用:</div>
|
||||
<div class="usage-bar">
|
||||
<div class="progress progress-striped active">
|
||||
<div class="progress-bar" id="memory_bar"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="usage-text"><span id="used">--</span>/<span id="total">--</span></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
@ -0,0 +1,42 @@
|
||||
<div class="navbar-header">
|
||||
<div >
|
||||
<a class="navbar-brand" href="/">
|
||||
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
|
||||
<span class="sr-only">Toggle navigation</span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</button>
|
||||
|
||||
</div>
|
||||
<!-- Collect the nav links, forms, and other content for toggling -->
|
||||
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
|
||||
|
||||
<ul class="nav navbar-nav navbar-right">
|
||||
{eq name="$loginStatus" value="1"}
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle avatar-a" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"><img src="/Member/Avatar/{$userData.id}/s" class="img-circle avatar-s"> {$userData.user_nick} <span class="caret"></span></a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="/Home">我的文件</a></li>
|
||||
<li><a href="/Profile/{$userData.id}">个人主页</a></li>
|
||||
<li><a href="/Member/Setting">设置</a></li>
|
||||
<li role="separator" class="divider"></li>
|
||||
<li><a href="/Member/LogOut">退出登录</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
{else/}
|
||||
<li >
|
||||
<a href="/Login" class="dropdown-toggle" role="button" aria-haspopup="true" aria-expanded="false"><i class="fa fa-user mr-1"></i> 登录/注册 </a>
|
||||
|
||||
</li>
|
||||
{/eq}
|
||||
|
||||
</ul>
|
||||
</div><!-- /.navbar-collapse -->
|
||||
</div><!-- /.container-fluid -->
|
||||
</div>
|
||||
</nav>
|
||||
@ -0,0 +1,115 @@
|
||||
{extend name="header_public" /}
|
||||
{block name="title"}用户主页 - {$options.siteName}{/block}
|
||||
{block name="content"}
|
||||
<link rel="stylesheet" href="/static/css/profile.css" />
|
||||
</head>
|
||||
<body data-ma-header="teal">
|
||||
<nav class="navbar navbar-inverse" >
|
||||
<div class="container-fluid">
|
||||
<div class="container" >
|
||||
{include file="navbar_public" /}
|
||||
<div class="header-panel shadow-z-2">
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="container main-h">
|
||||
<div class="col-md-3">
|
||||
<div class="card type--profile">
|
||||
<header class="card-heading card-background" id="card_img_02">
|
||||
<img src="/Member/Avatar/{$userInfo.id}/l" alt="" class="img-circle">
|
||||
<ul class="card-actions icons right-top">
|
||||
<li class="dropdown" style="display: none;">
|
||||
<a href="javascript:void(0)" data-toggle="dropdown" aria-expanded="false">
|
||||
<i class="zmdi zmdi-more-vert text-white"></i>
|
||||
</a>
|
||||
<ul class="dropdown-menu dropdown-menu-right">
|
||||
<li>
|
||||
<a href="javascript:void(0)">Option One</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="javascript:void(0)">Option Two</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="javascript:void(0)">Option Three</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</header>
|
||||
<div class="card-body">
|
||||
<h3 class="name">{$userInfo.user_nick|htmlspecialchars=ENT_NOQUOTES}</h3>
|
||||
<span class="title span-fix"><span class="label span-fix label-{$groupData.color}">{$groupData.group_name}</span></span>
|
||||
|
||||
</div>
|
||||
<footer class="card-footer border-top">
|
||||
<div class="row row p-t-10 p-b-10">
|
||||
<div class="col-xs-4"><span class="count">{$shareCount}</span><span>公开分享</span></div>
|
||||
<div class="col-xs-4"><span class="count">{$regDays}</span><span>注册天数</span></div>
|
||||
<div class="col-xs-4"><span class="count">{$userInfo.id}</span><span>用户编号</span></div>
|
||||
</div>
|
||||
</footer>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-9">
|
||||
<div class="jumbotron">
|
||||
<div class="card_botom">
|
||||
<div class="row bottom-width">
|
||||
<ul class="nav nav-tabs" >
|
||||
<li id="all"><a href="?page=1" aria-expanded="true">全部分享<div class="ripple-container"></div></a></li>
|
||||
<li id="hot"><a href="?type=hot" aria-expanded="false">热门分享<div class="ripple-container"></div></a></li>
|
||||
|
||||
</ul>
|
||||
<div id="myTabContent" class="tab-content">
|
||||
<div class="tab-pane fade active in">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-body" >
|
||||
|
||||
<div class="table-responsive">
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th width="50%">文件名 </th>
|
||||
<th class="cent">分享日期</th>
|
||||
<th class="cent">下载次数</th>
|
||||
<th class="cent">浏览次数</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>{volist name='list' id='shares'}
|
||||
<tr>
|
||||
<td >{switch $shares.source_type}
|
||||
{case file}<i class="fa fa-file" aria-hidden="true"></i> {/case}
|
||||
{case dir}<i class="fa fa-folder-open blue" aria-hidden="true"></i> {/case}
|
||||
|
||||
{/switch} <a href="/s/{$shares.share_key}" class="fname" target="_blank">{$shares.fileData|htmlspecialchars=ENT_NOQUOTES}</a></td>
|
||||
<td class="cent">{$shares.share_time}</td>
|
||||
<td align="center">{$shares.download_num}</td>
|
||||
<td align="center">{$shares.view_num}</td>
|
||||
</tr>
|
||||
|
||||
{/volist}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
<div class="navi">
|
||||
{eq name="$type" value="hot"}
|
||||
{else/}
|
||||
{$listOrigin->render()}
|
||||
{/eq}
|
||||
</div>
|
||||
</div></div></div></div>
|
||||
</div>
|
||||
</div>
|
||||
</div></div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
<script type="text/javascript">
|
||||
</script>
|
||||
<script src="/static/js/material.js"></script>
|
||||
<script src="/static/js/profile.js"> </script>
|
||||
{$options.js_code}
|
||||
{/block}
|
||||
@ -0,0 +1,83 @@
|
||||
<!doctype html>
|
||||
<html lang="en" data-ng-app="FileManagerApp">
|
||||
<head>
|
||||
<!--
|
||||
* Angular FileManager v1.5.1 (https://github.com/joni2back/angular-filemanager)
|
||||
* Jonas Sciangula Street <joni2back@gmail.com>
|
||||
* Licensed under MIT (https://github.com/joni2back/angular-filemanager/blob/master/LICENSE)
|
||||
-->
|
||||
<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
|
||||
<meta charset="utf-8">
|
||||
<title>我的文件 - {$options.siteName}</title>
|
||||
<!-- third party -->
|
||||
<script src="/static/js/angular.min.js"></script>
|
||||
<script src="/static/js/angular-translate.min.js"></script>
|
||||
|
||||
<script src="/static/js/jquery.min.js"></script>
|
||||
<link rel="stylesheet" href="/static/css/bootstrap.min.css" />
|
||||
<link rel="stylesheet" href="/static/css/material.css" />
|
||||
|
||||
<script src="/static/js/bootstrap.min.js"></script>
|
||||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.6.0/css/font-awesome.min.css">
|
||||
<!-- /third party -->
|
||||
<!-- Comment if you need to use raw source code -->
|
||||
<link href="/static/css/angular-filemanager.min.css" rel="stylesheet">
|
||||
<link href="/static/css/toastr.min.css" rel="stylesheet">
|
||||
<script type="text/javascript" src="/static/js/toastr.min.js"></script>
|
||||
<script src="/static/js/angular-filemanager.min.js"></script>
|
||||
<!-- /Comment if you need to use raw source code -->
|
||||
<script type="text/javascript">
|
||||
uploadConfig={
|
||||
saveType : "{$policyData.policy_type}",
|
||||
maxSize : "{$policyData.max_size}mb",
|
||||
allowedType: [
|
||||
{$extLimit}
|
||||
],
|
||||
allowSource : "{$policyData.origin_link}",
|
||||
upUrl : "{$policyData.server}",
|
||||
allowShare:"{$groupData.allow_share}",
|
||||
};
|
||||
</script>
|
||||
<script src="/static/js/home.js"></script>
|
||||
</head>
|
||||
<body class="ng-cloak">
|
||||
<div id="container">
|
||||
{include file="navbar_home" /}
|
||||
<div class="col-md-2 s" id="side">
|
||||
<div class="list-group" id="b">
|
||||
<a href="/Home" class="list-group-item active">
|
||||
<i class="fa fa-file" aria-hidden="true"></i> 我的文件
|
||||
</a>
|
||||
<a href="/Share" class="list-group-item"> <i class="fa fa-share-alt" aria-hidden="true"></i> 我的分享
|
||||
</a>
|
||||
<a href="#" class="list-group-item"><i class="fa fa-database" aria-hidden="true"></i> 容量配额
|
||||
</a>
|
||||
</div>
|
||||
<div clss="usage" style=" visibility: visible;
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100px;
|
||||
top: auto;
|
||||
bottom: 0px;
|
||||
background-color: #f3f3f3;padding: 15px">
|
||||
<div class="usage-title">容量使用:</div>
|
||||
<div class="usage-bar">
|
||||
<div class="progress progress-striped active">
|
||||
<div class="progress-bar" id="memory_bar"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="usage-text"><span id="used">--</span>/<span id="total">--</span></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-10">
|
||||
<angular-filemanager></angular-filemanager>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
<script src="/static/js/material.js"></script>
|
||||
<script type="text/javascript">
|
||||
upload_load=0;
|
||||
|
||||
</script>
|
||||
{$options.js_code}
|
||||
</html>
|
||||
@ -0,0 +1,53 @@
|
||||
{extend name="header_public" /}
|
||||
{block name="title"}私密分享 - {$options.siteName}{/block}
|
||||
{block name="content"}
|
||||
<link rel="stylesheet" href="/static/css/share.css" />
|
||||
<link rel="stylesheet" href="/static/css/lock.css" />
|
||||
<script src="/static/js/jquery.color.js"></script>
|
||||
</head>
|
||||
<body data-ma-header="teal">
|
||||
<nav class="navbar navbar-inverse" >
|
||||
<div class="container-fluid">
|
||||
<div class="container" >
|
||||
{include file="navbar_public" loginStatus=$loginStatus userData=$userData /}
|
||||
<div class="header-panel shadow-z-2">
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="container main" >
|
||||
<div class="col-md-4"></div>
|
||||
<div class="col-md-4">
|
||||
<div class="jumbotron" >
|
||||
<div class="card_top">
|
||||
<div class="row top-color">
|
||||
<div class="card-top-row">
|
||||
加密分享
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="card_botom">
|
||||
<div class="row bottom-width" align="right">
|
||||
<input type="password" class="form-control" id="inputPassword" placeholder="请输入分享密码" value="{$pwd}">
|
||||
<button href="javascript:void(0)" id="submit_pwd" class="btn btn-raised active"><i class="fa fa-arrow-right" aria-hidden="true"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4"></div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
<script src="/static/js/jquery.liMarquee.js"></script>
|
||||
<script type="text/javascript">
|
||||
shareInfo={
|
||||
shareId : "{$shareData.share_key}",
|
||||
};
|
||||
|
||||
</script>
|
||||
<script src="/static/js/lock.js"> </script>
|
||||
{$options.js_code}
|
||||
{/block}
|
||||
@ -0,0 +1,27 @@
|
||||
<?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 <liu21st@gmail.com>
|
||||
// +----------------------------------------------------------------------
|
||||
use think\Route;
|
||||
Route::rule([
|
||||
'Upload/mkblk/:chunkSize'=>'index/Upload/chunk',
|
||||
'Upload/mkfile/:fileSize/key/:keyValue/fname/:fname/path/:path'=>'index/Upload/mkFile',
|
||||
's/:key'=>'index/Share/index',
|
||||
'Share/Download/:key'=>'index/Share/Download',
|
||||
'Share/Preview/:key'=>'index/Share/Preview',
|
||||
'Share/List/:key'=>'index/Share/List',
|
||||
'Login'=>'index/Member/LoginForm',
|
||||
'Member/emailActivate/:key'=>'index/Member/emailActivate',
|
||||
'Member/resetPwd/:key'=>'index/Member/resetPwd',
|
||||
'Callback/Payment/Jinshajiang' => 'index/Callback/Jinshajiang',
|
||||
'Explore/S/:key' => 'index/Explore/S',
|
||||
'Member/Avatar/:uid/:size' => ['Member/Avatar',[],['uid'=>'\d+']],
|
||||
'Profile/:uid' => ['Profile/index',[],['uid'=>'\d+']],
|
||||
'Callback/Payment/Jinshajiang' => 'index/Callback/Jinshajiang',
|
||||
]);
|
||||
@ -0,0 +1,28 @@
|
||||
<?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 <liu21st@gmail.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
// 应用行为扩展定义文件
|
||||
return [
|
||||
// 应用初始化
|
||||
'app_init' => [],
|
||||
// 应用开始
|
||||
'app_begin' => [],
|
||||
// 模块初始化
|
||||
'module_init' => [],
|
||||
// 操作开始执行
|
||||
'action_begin' => [],
|
||||
// 视图内容过滤
|
||||
'view_filter' => [],
|
||||
// 日志写入
|
||||
'log_write' => [],
|
||||
// 应用结束
|
||||
'app_end' => [],
|
||||
];
|
||||
@ -0,0 +1 @@
|
||||
{"type":"","version":"1.0 Beta","version_id":1}
|
||||
@ -0,0 +1,40 @@
|
||||
{
|
||||
"name": "HFO4/Cloudreve",
|
||||
"description": "A program help you build your own cloud in minutes.",
|
||||
"keywords": ["php", "cloud", "ThinkPHP", "file-sharing"],
|
||||
"homepage": "https://cloudreve.org",
|
||||
"type": "project",
|
||||
"license": "GPL-3.0",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Aaron",
|
||||
"email": "abslant@foxmail.com",
|
||||
"homepage": "https://aoaoao.me",
|
||||
"role": "Developer"
|
||||
},
|
||||
{
|
||||
"name": "Qnner",
|
||||
"email": "admin@qnner.com",
|
||||
"homepage": "http://me.qnner.com",
|
||||
"role": "Developer"
|
||||
},
|
||||
{
|
||||
"name": "dune",
|
||||
"email": "rainaysann@gmail.com",
|
||||
"homepage": "https://github.com/rainays",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=5.6.0",
|
||||
"ext-curl":"*",
|
||||
"ext-fileinfo":"*",
|
||||
"ext-gd":"*",
|
||||
"topthink/think-captcha":"1.*",
|
||||
"phpgangsta/googleauthenticator": "dev-master",
|
||||
"endroid/qrcode": "1.*@dev",
|
||||
"aliyuncs/oss-sdk-php": "~2.0",
|
||||
"sabre/dav":"~3.2.0",
|
||||
"upyun/sdk": "^3.3"
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,39 @@
|
||||
<?php
|
||||
/**
|
||||
* PHPMailer Exception class.
|
||||
* PHP Version 5.5.
|
||||
*
|
||||
* @see https://github.com/PHPMailer/PHPMailer/ The PHPMailer GitHub project
|
||||
*
|
||||
* @author Marcus Bointon (Synchro/coolbru) <phpmailer@synchromedia.co.uk>
|
||||
* @author Jim Jagielski (jimjag) <jimjag@gmail.com>
|
||||
* @author Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net>
|
||||
* @author Brent R. Matzelle (original founder)
|
||||
* @copyright 2012 - 2017 Marcus Bointon
|
||||
* @copyright 2010 - 2012 Jim Jagielski
|
||||
* @copyright 2004 - 2009 Andy Prevost
|
||||
* @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
|
||||
* @note This program is distributed in the hope that it will be useful - WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
namespace PHPMailer\PHPMailer;
|
||||
|
||||
/**
|
||||
* PHPMailer exception handler.
|
||||
*
|
||||
* @author Marcus Bointon <phpmailer@synchromedia.co.uk>
|
||||
*/
|
||||
class Exception extends \Exception
|
||||
{
|
||||
/**
|
||||
* Prettify error message output.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function errorMessage()
|
||||
{
|
||||
return '<strong>' . htmlspecialchars($this->getMessage()) . "</strong><br />\n";
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,504 @@
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 2.1, February 1999
|
||||
|
||||
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
[This is the first released version of the Lesser GPL. It also counts
|
||||
as the successor of the GNU Library Public License, version 2, hence
|
||||
the version number 2.1.]
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
Licenses are intended to guarantee your freedom to share and change
|
||||
free software--to make sure the software is free for all its users.
|
||||
|
||||
This license, the Lesser General Public License, applies to some
|
||||
specially designated software packages--typically libraries--of the
|
||||
Free Software Foundation and other authors who decide to use it. You
|
||||
can use it too, but we suggest you first think carefully about whether
|
||||
this license or the ordinary General Public License is the better
|
||||
strategy to use in any particular case, based on the explanations below.
|
||||
|
||||
When we speak of free software, we are referring to freedom of use,
|
||||
not price. Our General Public Licenses are designed to make sure that
|
||||
you have the freedom to distribute copies of free software (and charge
|
||||
for this service if you wish); that you receive source code or can get
|
||||
it if you want it; that you can change the software and use pieces of
|
||||
it in new free programs; and that you are informed that you can do
|
||||
these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
distributors to deny you these rights or to ask you to surrender these
|
||||
rights. These restrictions translate to certain responsibilities for
|
||||
you if you distribute copies of the library or if you modify it.
|
||||
|
||||
For example, if you distribute copies of the library, whether gratis
|
||||
or for a fee, you must give the recipients all the rights that we gave
|
||||
you. You must make sure that they, too, receive or can get the source
|
||||
code. If you link other code with the library, you must provide
|
||||
complete object files to the recipients, so that they can relink them
|
||||
with the library after making changes to the library and recompiling
|
||||
it. And you must show them these terms so they know their rights.
|
||||
|
||||
We protect your rights with a two-step method: (1) we copyright the
|
||||
library, and (2) we offer you this license, which gives you legal
|
||||
permission to copy, distribute and/or modify the library.
|
||||
|
||||
To protect each distributor, we want to make it very clear that
|
||||
there is no warranty for the free library. Also, if the library is
|
||||
modified by someone else and passed on, the recipients should know
|
||||
that what they have is not the original version, so that the original
|
||||
author's reputation will not be affected by problems that might be
|
||||
introduced by others.
|
||||
|
||||
Finally, software patents pose a constant threat to the existence of
|
||||
any free program. We wish to make sure that a company cannot
|
||||
effectively restrict the users of a free program by obtaining a
|
||||
restrictive license from a patent holder. Therefore, we insist that
|
||||
any patent license obtained for a version of the library must be
|
||||
consistent with the full freedom of use specified in this license.
|
||||
|
||||
Most GNU software, including some libraries, is covered by the
|
||||
ordinary GNU General Public License. This license, the GNU Lesser
|
||||
General Public License, applies to certain designated libraries, and
|
||||
is quite different from the ordinary General Public License. We use
|
||||
this license for certain libraries in order to permit linking those
|
||||
libraries into non-free programs.
|
||||
|
||||
When a program is linked with a library, whether statically or using
|
||||
a shared library, the combination of the two is legally speaking a
|
||||
combined work, a derivative of the original library. The ordinary
|
||||
General Public License therefore permits such linking only if the
|
||||
entire combination fits its criteria of freedom. The Lesser General
|
||||
Public License permits more lax criteria for linking other code with
|
||||
the library.
|
||||
|
||||
We call this license the "Lesser" General Public License because it
|
||||
does Less to protect the user's freedom than the ordinary General
|
||||
Public License. It also provides other free software developers Less
|
||||
of an advantage over competing non-free programs. These disadvantages
|
||||
are the reason we use the ordinary General Public License for many
|
||||
libraries. However, the Lesser license provides advantages in certain
|
||||
special circumstances.
|
||||
|
||||
For example, on rare occasions, there may be a special need to
|
||||
encourage the widest possible use of a certain library, so that it becomes
|
||||
a de-facto standard. To achieve this, non-free programs must be
|
||||
allowed to use the library. A more frequent case is that a free
|
||||
library does the same job as widely used non-free libraries. In this
|
||||
case, there is little to gain by limiting the free library to free
|
||||
software only, so we use the Lesser General Public License.
|
||||
|
||||
In other cases, permission to use a particular library in non-free
|
||||
programs enables a greater number of people to use a large body of
|
||||
free software. For example, permission to use the GNU C Library in
|
||||
non-free programs enables many more people to use the whole GNU
|
||||
operating system, as well as its variant, the GNU/Linux operating
|
||||
system.
|
||||
|
||||
Although the Lesser General Public License is Less protective of the
|
||||
users' freedom, it does ensure that the user of a program that is
|
||||
linked with the Library has the freedom and the wherewithal to run
|
||||
that program using a modified version of the Library.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow. Pay close attention to the difference between a
|
||||
"work based on the library" and a "work that uses the library". The
|
||||
former contains code derived from the library, whereas the latter must
|
||||
be combined with the library in order to run.
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License Agreement applies to any software library or other
|
||||
program which contains a notice placed by the copyright holder or
|
||||
other authorized party saying it may be distributed under the terms of
|
||||
this Lesser General Public License (also called "this License").
|
||||
Each licensee is addressed as "you".
|
||||
|
||||
A "library" means a collection of software functions and/or data
|
||||
prepared so as to be conveniently linked with application programs
|
||||
(which use some of those functions and data) to form executables.
|
||||
|
||||
The "Library", below, refers to any such software library or work
|
||||
which has been distributed under these terms. A "work based on the
|
||||
Library" means either the Library or any derivative work under
|
||||
copyright law: that is to say, a work containing the Library or a
|
||||
portion of it, either verbatim or with modifications and/or translated
|
||||
straightforwardly into another language. (Hereinafter, translation is
|
||||
included without limitation in the term "modification".)
|
||||
|
||||
"Source code" for a work means the preferred form of the work for
|
||||
making modifications to it. For a library, complete source code means
|
||||
all the source code for all modules it contains, plus any associated
|
||||
interface definition files, plus the scripts used to control compilation
|
||||
and installation of the library.
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running a program using the Library is not restricted, and output from
|
||||
such a program is covered only if its contents constitute a work based
|
||||
on the Library (independent of the use of the Library in a tool for
|
||||
writing it). Whether that is true depends on what the Library does
|
||||
and what the program that uses the Library does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Library's
|
||||
complete source code as you receive it, in any medium, provided that
|
||||
you conspicuously and appropriately publish on each copy an
|
||||
appropriate copyright notice and disclaimer of warranty; keep intact
|
||||
all the notices that refer to this License and to the absence of any
|
||||
warranty; and distribute a copy of this License along with the
|
||||
Library.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy,
|
||||
and you may at your option offer warranty protection in exchange for a
|
||||
fee.
|
||||
|
||||
2. You may modify your copy or copies of the Library or any portion
|
||||
of it, thus forming a work based on the Library, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) The modified work must itself be a software library.
|
||||
|
||||
b) You must cause the files modified to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
c) You must cause the whole of the work to be licensed at no
|
||||
charge to all third parties under the terms of this License.
|
||||
|
||||
d) If a facility in the modified Library refers to a function or a
|
||||
table of data to be supplied by an application program that uses
|
||||
the facility, other than as an argument passed when the facility
|
||||
is invoked, then you must make a good faith effort to ensure that,
|
||||
in the event an application does not supply such function or
|
||||
table, the facility still operates, and performs whatever part of
|
||||
its purpose remains meaningful.
|
||||
|
||||
(For example, a function in a library to compute square roots has
|
||||
a purpose that is entirely well-defined independent of the
|
||||
application. Therefore, Subsection 2d requires that any
|
||||
application-supplied function or table used by this function must
|
||||
be optional: if the application does not supply it, the square
|
||||
root function must still compute square roots.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Library,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Library, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote
|
||||
it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Library.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Library
|
||||
with the Library (or with a work based on the Library) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||
License instead of this License to a given copy of the Library. To do
|
||||
this, you must alter all the notices that refer to this License, so
|
||||
that they refer to the ordinary GNU General Public License, version 2,
|
||||
instead of to this License. (If a newer version than version 2 of the
|
||||
ordinary GNU General Public License has appeared, then you can specify
|
||||
that version instead if you wish.) Do not make any other change in
|
||||
these notices.
|
||||
|
||||
Once this change is made in a given copy, it is irreversible for
|
||||
that copy, so the ordinary GNU General Public License applies to all
|
||||
subsequent copies and derivative works made from that copy.
|
||||
|
||||
This option is useful when you wish to copy part of the code of
|
||||
the Library into a program that is not a library.
|
||||
|
||||
4. You may copy and distribute the Library (or a portion or
|
||||
derivative of it, under Section 2) in object code or executable form
|
||||
under the terms of Sections 1 and 2 above provided that you accompany
|
||||
it with the complete corresponding machine-readable source code, which
|
||||
must be distributed under the terms of Sections 1 and 2 above on a
|
||||
medium customarily used for software interchange.
|
||||
|
||||
If distribution of object code is made by offering access to copy
|
||||
from a designated place, then offering equivalent access to copy the
|
||||
source code from the same place satisfies the requirement to
|
||||
distribute the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
5. A program that contains no derivative of any portion of the
|
||||
Library, but is designed to work with the Library by being compiled or
|
||||
linked with it, is called a "work that uses the Library". Such a
|
||||
work, in isolation, is not a derivative work of the Library, and
|
||||
therefore falls outside the scope of this License.
|
||||
|
||||
However, linking a "work that uses the Library" with the Library
|
||||
creates an executable that is a derivative of the Library (because it
|
||||
contains portions of the Library), rather than a "work that uses the
|
||||
library". The executable is therefore covered by this License.
|
||||
Section 6 states terms for distribution of such executables.
|
||||
|
||||
When a "work that uses the Library" uses material from a header file
|
||||
that is part of the Library, the object code for the work may be a
|
||||
derivative work of the Library even though the source code is not.
|
||||
Whether this is true is especially significant if the work can be
|
||||
linked without the Library, or if the work is itself a library. The
|
||||
threshold for this to be true is not precisely defined by law.
|
||||
|
||||
If such an object file uses only numerical parameters, data
|
||||
structure layouts and accessors, and small macros and small inline
|
||||
functions (ten lines or less in length), then the use of the object
|
||||
file is unrestricted, regardless of whether it is legally a derivative
|
||||
work. (Executables containing this object code plus portions of the
|
||||
Library will still fall under Section 6.)
|
||||
|
||||
Otherwise, if the work is a derivative of the Library, you may
|
||||
distribute the object code for the work under the terms of Section 6.
|
||||
Any executables containing that work also fall under Section 6,
|
||||
whether or not they are linked directly with the Library itself.
|
||||
|
||||
6. As an exception to the Sections above, you may also combine or
|
||||
link a "work that uses the Library" with the Library to produce a
|
||||
work containing portions of the Library, and distribute that work
|
||||
under terms of your choice, provided that the terms permit
|
||||
modification of the work for the customer's own use and reverse
|
||||
engineering for debugging such modifications.
|
||||
|
||||
You must give prominent notice with each copy of the work that the
|
||||
Library is used in it and that the Library and its use are covered by
|
||||
this License. You must supply a copy of this License. If the work
|
||||
during execution displays copyright notices, you must include the
|
||||
copyright notice for the Library among them, as well as a reference
|
||||
directing the user to the copy of this License. Also, you must do one
|
||||
of these things:
|
||||
|
||||
a) Accompany the work with the complete corresponding
|
||||
machine-readable source code for the Library including whatever
|
||||
changes were used in the work (which must be distributed under
|
||||
Sections 1 and 2 above); and, if the work is an executable linked
|
||||
with the Library, with the complete machine-readable "work that
|
||||
uses the Library", as object code and/or source code, so that the
|
||||
user can modify the Library and then relink to produce a modified
|
||||
executable containing the modified Library. (It is understood
|
||||
that the user who changes the contents of definitions files in the
|
||||
Library will not necessarily be able to recompile the application
|
||||
to use the modified definitions.)
|
||||
|
||||
b) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (1) uses at run time a
|
||||
copy of the library already present on the user's computer system,
|
||||
rather than copying library functions into the executable, and (2)
|
||||
will operate properly with a modified version of the library, if
|
||||
the user installs one, as long as the modified version is
|
||||
interface-compatible with the version that the work was made with.
|
||||
|
||||
c) Accompany the work with a written offer, valid for at
|
||||
least three years, to give the same user the materials
|
||||
specified in Subsection 6a, above, for a charge no more
|
||||
than the cost of performing this distribution.
|
||||
|
||||
d) If distribution of the work is made by offering access to copy
|
||||
from a designated place, offer equivalent access to copy the above
|
||||
specified materials from the same place.
|
||||
|
||||
e) verify that the user has already received a copy of these
|
||||
materials or that you have already sent this user a copy.
|
||||
|
||||
For an executable, the required form of the "work that uses the
|
||||
Library" must include any data and utility programs needed for
|
||||
reproducing the executable from it. However, as a special exception,
|
||||
the materials to be distributed need not include anything that is
|
||||
normally distributed (in either source or binary form) with the major
|
||||
components (compiler, kernel, and so on) of the operating system on
|
||||
which the executable runs, unless that component itself accompanies
|
||||
the executable.
|
||||
|
||||
It may happen that this requirement contradicts the license
|
||||
restrictions of other proprietary libraries that do not normally
|
||||
accompany the operating system. Such a contradiction means you cannot
|
||||
use both them and the Library together in an executable that you
|
||||
distribute.
|
||||
|
||||
7. 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 not covered by this License, and distribute such a combined
|
||||
library, provided that the separate distribution of the work based on
|
||||
the Library and of the other library facilities is otherwise
|
||||
permitted, and provided that you do these two things:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work
|
||||
based on the Library, uncombined with any other library
|
||||
facilities. This must be distributed under the terms of the
|
||||
Sections above.
|
||||
|
||||
b) Give prominent notice with the combined library of the fact
|
||||
that part of it is a work based on the Library, and explaining
|
||||
where to find the accompanying uncombined form of the same work.
|
||||
|
||||
8. You may not copy, modify, sublicense, link with, or distribute
|
||||
the Library except as expressly provided under this License. Any
|
||||
attempt otherwise to copy, modify, sublicense, link with, or
|
||||
distribute the Library is void, and will automatically terminate your
|
||||
rights under this License. However, parties who have received copies,
|
||||
or rights, from you under this License will not have their licenses
|
||||
terminated so long as such parties remain in full compliance.
|
||||
|
||||
9. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Library or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Library (or any work based on the
|
||||
Library), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Library or works based on it.
|
||||
|
||||
10. Each time you redistribute the Library (or any work based on the
|
||||
Library), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute, link with or modify the Library
|
||||
subject to these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties with
|
||||
this License.
|
||||
|
||||
11. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Library at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Library by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Library.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under any
|
||||
particular circumstance, the balance of the section is intended to apply,
|
||||
and the section as a whole is intended to apply in other circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
12. If the distribution and/or use of the Library is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Library under this License may add
|
||||
an explicit geographical distribution limitation excluding those countries,
|
||||
so that distribution is permitted only in or among countries not thus
|
||||
excluded. In such case, this License incorporates the limitation as if
|
||||
written in the body of this License.
|
||||
|
||||
13. The Free Software Foundation may publish revised and/or new
|
||||
versions of the 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
|
||||
specifies a version number of this License which applies to it and
|
||||
"any later version", you have the option of following the terms and
|
||||
conditions either of that version or of any later version published by
|
||||
the Free Software Foundation. If the Library does not specify a
|
||||
license version number, you may choose any version ever published by
|
||||
the Free Software Foundation.
|
||||
|
||||
14. If you wish to incorporate parts of the Library into other free
|
||||
programs whose distribution conditions are incompatible with these,
|
||||
write to the author to ask for permission. For software which is
|
||||
copyrighted by the Free Software Foundation, write to the Free
|
||||
Software Foundation; we sometimes make exceptions for this. Our
|
||||
decision will be guided by the two goals of preserving the free status
|
||||
of all derivatives of our free software and of promoting the sharing
|
||||
and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
|
||||
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
|
||||
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
||||
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
||||
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
|
||||
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
|
||||
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
|
||||
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
|
||||
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||||
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Libraries
|
||||
|
||||
If you develop a new library, and you want it to be of the greatest
|
||||
possible use to the public, we recommend making it free software that
|
||||
everyone can redistribute and change. You can do so by permitting
|
||||
redistribution under these terms (or, alternatively, under the terms of the
|
||||
ordinary General Public License).
|
||||
|
||||
To apply these terms, attach the following notices to the library. It is
|
||||
safest to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least the
|
||||
"copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the library's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the library, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
||||
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1990
|
||||
Ty Coon, President of Vice
|
||||
|
||||
That's all there is to it!
|
||||
|
||||
|
||||
@ -0,0 +1,138 @@
|
||||
<?php
|
||||
/**
|
||||
* PHPMailer - PHP email creation and transport class.
|
||||
* PHP Version 5.5.
|
||||
*
|
||||
* @see https://github.com/PHPMailer/PHPMailer/ The PHPMailer GitHub project
|
||||
*
|
||||
* @author Marcus Bointon (Synchro/coolbru) <phpmailer@synchromedia.co.uk>
|
||||
* @author Jim Jagielski (jimjag) <jimjag@gmail.com>
|
||||
* @author Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net>
|
||||
* @author Brent R. Matzelle (original founder)
|
||||
* @copyright 2012 - 2015 Marcus Bointon
|
||||
* @copyright 2010 - 2012 Jim Jagielski
|
||||
* @copyright 2004 - 2009 Andy Prevost
|
||||
* @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
|
||||
* @note This program is distributed in the hope that it will be useful - WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
namespace PHPMailer\PHPMailer;
|
||||
|
||||
use League\OAuth2\Client\Grant\RefreshToken;
|
||||
use League\OAuth2\Client\Provider\AbstractProvider;
|
||||
use League\OAuth2\Client\Token\AccessToken;
|
||||
|
||||
/**
|
||||
* OAuth - OAuth2 authentication wrapper class.
|
||||
* Uses the oauth2-client package from the League of Extraordinary Packages.
|
||||
*
|
||||
* @see http://oauth2-client.thephpleague.com
|
||||
*
|
||||
* @author Marcus Bointon (Synchro/coolbru) <phpmailer@synchromedia.co.uk>
|
||||
*/
|
||||
class OAuth
|
||||
{
|
||||
/**
|
||||
* An instance of the League OAuth Client Provider.
|
||||
*
|
||||
* @var AbstractProvider
|
||||
*/
|
||||
protected $provider = null;
|
||||
|
||||
/**
|
||||
* The current OAuth access token.
|
||||
*
|
||||
* @var AccessToken
|
||||
*/
|
||||
protected $oauthToken = null;
|
||||
|
||||
/**
|
||||
* The user's email address, usually used as the login ID
|
||||
* and also the from address when sending email.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $oauthUserEmail = '';
|
||||
|
||||
/**
|
||||
* The client secret, generated in the app definition of the service you're connecting to.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $oauthClientSecret = '';
|
||||
|
||||
/**
|
||||
* The client ID, generated in the app definition of the service you're connecting to.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $oauthClientId = '';
|
||||
|
||||
/**
|
||||
* The refresh token, used to obtain new AccessTokens.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $oauthRefreshToken = '';
|
||||
|
||||
/**
|
||||
* OAuth constructor.
|
||||
*
|
||||
* @param array $options Associative array containing
|
||||
* `provider`, `userName`, `clientSecret`, `clientId` and `refreshToken` elements
|
||||
*/
|
||||
public function __construct($options)
|
||||
{
|
||||
$this->provider = $options['provider'];
|
||||
$this->oauthUserEmail = $options['userName'];
|
||||
$this->oauthClientSecret = $options['clientSecret'];
|
||||
$this->oauthClientId = $options['clientId'];
|
||||
$this->oauthRefreshToken = $options['refreshToken'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a new RefreshToken.
|
||||
*
|
||||
* @return RefreshToken
|
||||
*/
|
||||
protected function getGrant()
|
||||
{
|
||||
return new RefreshToken();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a new AccessToken.
|
||||
*
|
||||
* @return AccessToken
|
||||
*/
|
||||
protected function getToken()
|
||||
{
|
||||
return $this->provider->getAccessToken(
|
||||
$this->getGrant(),
|
||||
['refresh_token' => $this->oauthRefreshToken]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a base64-encoded OAuth token.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getOauth64()
|
||||
{
|
||||
// Get a new token if it's not available or has expired
|
||||
if (null === $this->oauthToken or $this->oauthToken->hasExpired()) {
|
||||
$this->oauthToken = $this->getToken();
|
||||
}
|
||||
|
||||
return base64_encode(
|
||||
'user=' .
|
||||
$this->oauthUserEmail .
|
||||
"\001auth=Bearer " .
|
||||
$this->oauthToken .
|
||||
"\001\001"
|
||||
);
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,49 @@
|
||||
<?php
|
||||
/**
|
||||
* PHPMailer SPL autoloader.
|
||||
* PHP Version 5
|
||||
* @package PHPMailer
|
||||
* @link https://github.com/PHPMailer/PHPMailer/ The PHPMailer GitHub project
|
||||
* @author Marcus Bointon (Synchro/coolbru) <phpmailer@synchromedia.co.uk>
|
||||
* @author Jim Jagielski (jimjag) <jimjag@gmail.com>
|
||||
* @author Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net>
|
||||
* @author Brent R. Matzelle (original founder)
|
||||
* @copyright 2012 - 2014 Marcus Bointon
|
||||
* @copyright 2010 - 2012 Jim Jagielski
|
||||
* @copyright 2004 - 2009 Andy Prevost
|
||||
* @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
|
||||
* @note This program is distributed in the hope that it will be useful - WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* PHPMailer SPL autoloader.
|
||||
* @param string $classname The name of the class to load
|
||||
*/
|
||||
function PHPMailerAutoload($classname)
|
||||
{
|
||||
//Can't use __DIR__ as it's only in PHP 5.3+
|
||||
$filename = dirname(__FILE__).DIRECTORY_SEPARATOR.'class.'.strtolower($classname).'.php';
|
||||
if (is_readable($filename)) {
|
||||
require $filename;
|
||||
}
|
||||
}
|
||||
|
||||
if (version_compare(PHP_VERSION, '5.1.2', '>=')) {
|
||||
//SPL autoloading was introduced in PHP 5.1.2
|
||||
if (version_compare(PHP_VERSION, '5.3.0', '>=')) {
|
||||
spl_autoload_register('PHPMailerAutoload', true, true);
|
||||
} else {
|
||||
spl_autoload_register('PHPMailerAutoload');
|
||||
}
|
||||
} else {
|
||||
/**
|
||||
* Fall back to traditional autoload for old PHP versions
|
||||
* @param string $classname The name of the class to load
|
||||
*/
|
||||
function __autoload($classname)
|
||||
{
|
||||
PHPMailerAutoload($classname);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,197 @@
|
||||
<?php
|
||||
/**
|
||||
* PHPMailer - PHP email creation and transport class.
|
||||
* PHP Version 5.4
|
||||
* @package PHPMailer
|
||||
* @link https://github.com/PHPMailer/PHPMailer/ The PHPMailer GitHub project
|
||||
* @author Marcus Bointon (Synchro/coolbru) <phpmailer@synchromedia.co.uk>
|
||||
* @author Jim Jagielski (jimjag) <jimjag@gmail.com>
|
||||
* @author Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net>
|
||||
* @author Brent R. Matzelle (original founder)
|
||||
* @copyright 2012 - 2014 Marcus Bointon
|
||||
* @copyright 2010 - 2012 Jim Jagielski
|
||||
* @copyright 2004 - 2009 Andy Prevost
|
||||
* @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
|
||||
* @note This program is distributed in the hope that it will be useful - WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* PHPMailerOAuth - PHPMailer subclass adding OAuth support.
|
||||
* @package PHPMailer
|
||||
* @author @sherryl4george
|
||||
* @author Marcus Bointon (@Synchro) <phpmailer@synchromedia.co.uk>
|
||||
*/
|
||||
class PHPMailerOAuth extends PHPMailer
|
||||
{
|
||||
/**
|
||||
* The OAuth user's email address
|
||||
* @var string
|
||||
*/
|
||||
public $oauthUserEmail = '';
|
||||
|
||||
/**
|
||||
* The OAuth refresh token
|
||||
* @var string
|
||||
*/
|
||||
public $oauthRefreshToken = '';
|
||||
|
||||
/**
|
||||
* The OAuth client ID
|
||||
* @var string
|
||||
*/
|
||||
public $oauthClientId = '';
|
||||
|
||||
/**
|
||||
* The OAuth client secret
|
||||
* @var string
|
||||
*/
|
||||
public $oauthClientSecret = '';
|
||||
|
||||
/**
|
||||
* An instance of the PHPMailerOAuthGoogle class.
|
||||
* @var PHPMailerOAuthGoogle
|
||||
* @access protected
|
||||
*/
|
||||
protected $oauth = null;
|
||||
|
||||
/**
|
||||
* Get a PHPMailerOAuthGoogle instance to use.
|
||||
* @return PHPMailerOAuthGoogle
|
||||
*/
|
||||
public function getOAUTHInstance()
|
||||
{
|
||||
if (!is_object($this->oauth)) {
|
||||
$this->oauth = new PHPMailerOAuthGoogle(
|
||||
$this->oauthUserEmail,
|
||||
$this->oauthClientSecret,
|
||||
$this->oauthClientId,
|
||||
$this->oauthRefreshToken
|
||||
);
|
||||
}
|
||||
return $this->oauth;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initiate a connection to an SMTP server.
|
||||
* Overrides the original smtpConnect method to add support for OAuth.
|
||||
* @param array $options An array of options compatible with stream_context_create()
|
||||
* @uses SMTP
|
||||
* @access public
|
||||
* @return bool
|
||||
* @throws phpmailerException
|
||||
*/
|
||||
public function smtpConnect($options = array())
|
||||
{
|
||||
if (is_null($this->smtp)) {
|
||||
$this->smtp = $this->getSMTPInstance();
|
||||
}
|
||||
|
||||
if (is_null($this->oauth)) {
|
||||
$this->oauth = $this->getOAUTHInstance();
|
||||
}
|
||||
|
||||
// Already connected?
|
||||
if ($this->smtp->connected()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$this->smtp->setTimeout($this->Timeout);
|
||||
$this->smtp->setDebugLevel($this->SMTPDebug);
|
||||
$this->smtp->setDebugOutput($this->Debugoutput);
|
||||
$this->smtp->setVerp($this->do_verp);
|
||||
$hosts = explode(';', $this->Host);
|
||||
$lastexception = null;
|
||||
|
||||
foreach ($hosts as $hostentry) {
|
||||
$hostinfo = array();
|
||||
if (!preg_match('/^((ssl|tls):\/\/)*([a-zA-Z0-9\.-]*):?([0-9]*)$/', trim($hostentry), $hostinfo)) {
|
||||
// Not a valid host entry
|
||||
continue;
|
||||
}
|
||||
// $hostinfo[2]: optional ssl or tls prefix
|
||||
// $hostinfo[3]: the hostname
|
||||
// $hostinfo[4]: optional port number
|
||||
// The host string prefix can temporarily override the current setting for SMTPSecure
|
||||
// If it's not specified, the default value is used
|
||||
$prefix = '';
|
||||
$secure = $this->SMTPSecure;
|
||||
$tls = ($this->SMTPSecure == 'tls');
|
||||
if ('ssl' == $hostinfo[2] or ('' == $hostinfo[2] and 'ssl' == $this->SMTPSecure)) {
|
||||
$prefix = 'ssl://';
|
||||
$tls = false; // Can't have SSL and TLS at the same time
|
||||
$secure = 'ssl';
|
||||
} elseif ($hostinfo[2] == 'tls') {
|
||||
$tls = true;
|
||||
// tls doesn't use a prefix
|
||||
$secure = 'tls';
|
||||
}
|
||||
//Do we need the OpenSSL extension?
|
||||
$sslext = defined('OPENSSL_ALGO_SHA1');
|
||||
if ('tls' === $secure or 'ssl' === $secure) {
|
||||
//Check for an OpenSSL constant rather than using extension_loaded, which is sometimes disabled
|
||||
if (!$sslext) {
|
||||
throw new phpmailerException($this->lang('extension_missing').'openssl', self::STOP_CRITICAL);
|
||||
}
|
||||
}
|
||||
$host = $hostinfo[3];
|
||||
$port = $this->Port;
|
||||
$tport = (integer)$hostinfo[4];
|
||||
if ($tport > 0 and $tport < 65536) {
|
||||
$port = $tport;
|
||||
}
|
||||
if ($this->smtp->connect($prefix . $host, $port, $this->Timeout, $options)) {
|
||||
try {
|
||||
if ($this->Helo) {
|
||||
$hello = $this->Helo;
|
||||
} else {
|
||||
$hello = $this->serverHostname();
|
||||
}
|
||||
$this->smtp->hello($hello);
|
||||
//Automatically enable TLS encryption if:
|
||||
// * it's not disabled
|
||||
// * we have openssl extension
|
||||
// * we are not already using SSL
|
||||
// * the server offers STARTTLS
|
||||
if ($this->SMTPAutoTLS and $sslext and $secure != 'ssl' and $this->smtp->getServerExt('STARTTLS')) {
|
||||
$tls = true;
|
||||
}
|
||||
if ($tls) {
|
||||
if (!$this->smtp->startTLS()) {
|
||||
throw new phpmailerException($this->lang('connect_host'));
|
||||
}
|
||||
// We must resend HELO after tls negotiation
|
||||
$this->smtp->hello($hello);
|
||||
}
|
||||
if ($this->SMTPAuth) {
|
||||
if (!$this->smtp->authenticate(
|
||||
$this->Username,
|
||||
$this->Password,
|
||||
$this->AuthType,
|
||||
$this->Realm,
|
||||
$this->Workstation,
|
||||
$this->oauth
|
||||
)
|
||||
) {
|
||||
throw new phpmailerException($this->lang('authenticate'));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
} catch (phpmailerException $exc) {
|
||||
$lastexception = $exc;
|
||||
$this->edebug($exc->getMessage());
|
||||
// We must have connected, but then failed TLS or Auth, so close connection nicely
|
||||
$this->smtp->quit();
|
||||
}
|
||||
}
|
||||
}
|
||||
// If we get here, all connection attempts have failed, so close connection hard
|
||||
$this->smtp->close();
|
||||
// As we've caught all exceptions, just report whatever the last one was
|
||||
if ($this->exceptions and !is_null($lastexception)) {
|
||||
throw $lastexception;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,419 @@
|
||||
<?php
|
||||
/**
|
||||
* PHPMailer POP-Before-SMTP Authentication Class.
|
||||
* PHP Version 5.5.
|
||||
*
|
||||
* @see https://github.com/PHPMailer/PHPMailer/ The PHPMailer GitHub project
|
||||
*
|
||||
* @author Marcus Bointon (Synchro/coolbru) <phpmailer@synchromedia.co.uk>
|
||||
* @author Jim Jagielski (jimjag) <jimjag@gmail.com>
|
||||
* @author Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net>
|
||||
* @author Brent R. Matzelle (original founder)
|
||||
* @copyright 2012 - 2017 Marcus Bointon
|
||||
* @copyright 2010 - 2012 Jim Jagielski
|
||||
* @copyright 2004 - 2009 Andy Prevost
|
||||
* @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
|
||||
* @note This program is distributed in the hope that it will be useful - WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
namespace PHPMailer\PHPMailer;
|
||||
|
||||
/**
|
||||
* PHPMailer POP-Before-SMTP Authentication Class.
|
||||
* Specifically for PHPMailer to use for RFC1939 POP-before-SMTP authentication.
|
||||
* 1) This class does not support APOP authentication.
|
||||
* 2) Opening and closing lots of POP3 connections can be quite slow. If you need
|
||||
* to send a batch of emails then just perform the authentication once at the start,
|
||||
* and then loop through your mail sending script. Providing this process doesn't
|
||||
* take longer than the verification period lasts on your POP3 server, you should be fine.
|
||||
* 3) This is really ancient technology; you should only need to use it to talk to very old systems.
|
||||
* 4) This POP3 class is deliberately lightweight and incomplete, and implements just
|
||||
* enough to do authentication.
|
||||
* If you want a more complete class there are other POP3 classes for PHP available.
|
||||
*
|
||||
* @author Richard Davey (original author) <rich@corephp.co.uk>
|
||||
* @author Marcus Bointon (Synchro/coolbru) <phpmailer@synchromedia.co.uk>
|
||||
* @author Jim Jagielski (jimjag) <jimjag@gmail.com>
|
||||
* @author Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net>
|
||||
*/
|
||||
class POP3
|
||||
{
|
||||
/**
|
||||
* The POP3 PHPMailer Version number.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const VERSION = '6.0.1';
|
||||
|
||||
/**
|
||||
* Default POP3 port number.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
const DEFAULT_PORT = 110;
|
||||
|
||||
/**
|
||||
* Default timeout in seconds.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
const DEFAULT_TIMEOUT = 30;
|
||||
|
||||
/**
|
||||
* Debug display level.
|
||||
* Options: 0 = no, 1+ = yes.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $do_debug = 0;
|
||||
|
||||
/**
|
||||
* POP3 mail server hostname.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $host;
|
||||
|
||||
/**
|
||||
* POP3 port number.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $port;
|
||||
|
||||
/**
|
||||
* POP3 Timeout Value in seconds.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $tval;
|
||||
|
||||
/**
|
||||
* POP3 username.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $username;
|
||||
|
||||
/**
|
||||
* POP3 password.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $password;
|
||||
|
||||
/**
|
||||
* Resource handle for the POP3 connection socket.
|
||||
*
|
||||
* @var resource
|
||||
*/
|
||||
protected $pop_conn;
|
||||
|
||||
/**
|
||||
* Are we connected?
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $connected = false;
|
||||
|
||||
/**
|
||||
* Error container.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $errors = [];
|
||||
|
||||
/**
|
||||
* Line break constant.
|
||||
*/
|
||||
const LE = "\r\n";
|
||||
|
||||
/**
|
||||
* Simple static wrapper for all-in-one POP before SMTP.
|
||||
*
|
||||
* @param string $host The hostname to connect to
|
||||
* @param int|bool $port The port number to connect to
|
||||
* @param int|bool $timeout The timeout value
|
||||
* @param string $username
|
||||
* @param string $password
|
||||
* @param int $debug_level
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function popBeforeSmtp(
|
||||
$host,
|
||||
$port = false,
|
||||
$timeout = false,
|
||||
$username = '',
|
||||
$password = '',
|
||||
$debug_level = 0
|
||||
) {
|
||||
$pop = new self();
|
||||
|
||||
return $pop->authorise($host, $port, $timeout, $username, $password, $debug_level);
|
||||
}
|
||||
|
||||
/**
|
||||
* Authenticate with a POP3 server.
|
||||
* A connect, login, disconnect sequence
|
||||
* appropriate for POP-before SMTP authorisation.
|
||||
*
|
||||
* @param string $host The hostname to connect to
|
||||
* @param int|bool $port The port number to connect to
|
||||
* @param int|bool $timeout The timeout value
|
||||
* @param string $username
|
||||
* @param string $password
|
||||
* @param int $debug_level
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorise($host, $port = false, $timeout = false, $username = '', $password = '', $debug_level = 0)
|
||||
{
|
||||
$this->host = $host;
|
||||
// If no port value provided, use default
|
||||
if (false === $port) {
|
||||
$this->port = static::DEFAULT_PORT;
|
||||
} else {
|
||||
$this->port = (int) $port;
|
||||
}
|
||||
// If no timeout value provided, use default
|
||||
if (false === $timeout) {
|
||||
$this->tval = static::DEFAULT_TIMEOUT;
|
||||
} else {
|
||||
$this->tval = (int) $timeout;
|
||||
}
|
||||
$this->do_debug = $debug_level;
|
||||
$this->username = $username;
|
||||
$this->password = $password;
|
||||
// Reset the error log
|
||||
$this->errors = [];
|
||||
// connect
|
||||
$result = $this->connect($this->host, $this->port, $this->tval);
|
||||
if ($result) {
|
||||
$login_result = $this->login($this->username, $this->password);
|
||||
if ($login_result) {
|
||||
$this->disconnect();
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// We need to disconnect regardless of whether the login succeeded
|
||||
$this->disconnect();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Connect to a POP3 server.
|
||||
*
|
||||
* @param string $host
|
||||
* @param int|bool $port
|
||||
* @param int $tval
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function connect($host, $port = false, $tval = 30)
|
||||
{
|
||||
// Are we already connected?
|
||||
if ($this->connected) {
|
||||
return true;
|
||||
}
|
||||
|
||||
//On Windows this will raise a PHP Warning error if the hostname doesn't exist.
|
||||
//Rather than suppress it with @fsockopen, capture it cleanly instead
|
||||
set_error_handler([$this, 'catchWarning']);
|
||||
|
||||
if (false === $port) {
|
||||
$port = static::DEFAULT_PORT;
|
||||
}
|
||||
|
||||
// connect to the POP3 server
|
||||
$this->pop_conn = fsockopen(
|
||||
$host, // POP3 Host
|
||||
$port, // Port #
|
||||
$errno, // Error Number
|
||||
$errstr, // Error Message
|
||||
$tval
|
||||
); // Timeout (seconds)
|
||||
// Restore the error handler
|
||||
restore_error_handler();
|
||||
|
||||
// Did we connect?
|
||||
if (false === $this->pop_conn) {
|
||||
// It would appear not...
|
||||
$this->setError(
|
||||
"Failed to connect to server $host on port $port. errno: $errno; errstr: $errstr"
|
||||
);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Increase the stream time-out
|
||||
stream_set_timeout($this->pop_conn, $tval, 0);
|
||||
|
||||
// Get the POP3 server response
|
||||
$pop3_response = $this->getResponse();
|
||||
// Check for the +OK
|
||||
if ($this->checkResponse($pop3_response)) {
|
||||
// The connection is established and the POP3 server is talking
|
||||
$this->connected = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Log in to the POP3 server.
|
||||
* Does not support APOP (RFC 2828, 4949).
|
||||
*
|
||||
* @param string $username
|
||||
* @param string $password
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function login($username = '', $password = '')
|
||||
{
|
||||
if (!$this->connected) {
|
||||
$this->setError('Not connected to POP3 server');
|
||||
}
|
||||
if (empty($username)) {
|
||||
$username = $this->username;
|
||||
}
|
||||
if (empty($password)) {
|
||||
$password = $this->password;
|
||||
}
|
||||
|
||||
// Send the Username
|
||||
$this->sendString("USER $username" . static::LE);
|
||||
$pop3_response = $this->getResponse();
|
||||
if ($this->checkResponse($pop3_response)) {
|
||||
// Send the Password
|
||||
$this->sendString("PASS $password" . static::LE);
|
||||
$pop3_response = $this->getResponse();
|
||||
if ($this->checkResponse($pop3_response)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disconnect from the POP3 server.
|
||||
*/
|
||||
public function disconnect()
|
||||
{
|
||||
$this->sendString('QUIT');
|
||||
//The QUIT command may cause the daemon to exit, which will kill our connection
|
||||
//So ignore errors here
|
||||
try {
|
||||
@fclose($this->pop_conn);
|
||||
} catch (Exception $e) {
|
||||
//Do nothing
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a response from the POP3 server.
|
||||
*
|
||||
* @param int $size The maximum number of bytes to retrieve
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getResponse($size = 128)
|
||||
{
|
||||
$response = fgets($this->pop_conn, $size);
|
||||
if ($this->do_debug >= 1) {
|
||||
echo 'Server -> Client: ', $response;
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send raw data to the POP3 server.
|
||||
*
|
||||
* @param string $string
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
protected function sendString($string)
|
||||
{
|
||||
if ($this->pop_conn) {
|
||||
if ($this->do_debug >= 2) { //Show client messages when debug >= 2
|
||||
echo 'Client -> Server: ', $string;
|
||||
}
|
||||
|
||||
return fwrite($this->pop_conn, $string, strlen($string));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the POP3 server response.
|
||||
* Looks for for +OK or -ERR.
|
||||
*
|
||||
* @param string $string
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function checkResponse($string)
|
||||
{
|
||||
if (substr($string, 0, 3) !== '+OK') {
|
||||
$this->setError("Server reported an error: $string");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an error to the internal error store.
|
||||
* Also display debug output if it's enabled.
|
||||
*
|
||||
* @param string $error
|
||||
*/
|
||||
protected function setError($error)
|
||||
{
|
||||
$this->errors[] = $error;
|
||||
if ($this->do_debug >= 1) {
|
||||
echo '<pre>';
|
||||
foreach ($this->errors as $error) {
|
||||
print_r($error);
|
||||
}
|
||||
echo '</pre>';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an array of error messages, if any.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getErrors()
|
||||
{
|
||||
return $this->errors;
|
||||
}
|
||||
|
||||
/**
|
||||
* POP3 connection error handler.
|
||||
*
|
||||
* @param int $errno
|
||||
* @param string $errstr
|
||||
* @param string $errfile
|
||||
* @param int $errline
|
||||
*/
|
||||
protected function catchWarning($errno, $errstr, $errfile, $errline)
|
||||
{
|
||||
$this->setError(
|
||||
'Connecting to the POP3 server raised a PHP warning:' .
|
||||
"errno: $errno errstr: $errstr; errfile: $errfile; errline: $errline"
|
||||
);
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,163 @@
|
||||
<?php
|
||||
namespace Qiniu;
|
||||
|
||||
use Qiniu;
|
||||
use Qiniu\Zone;
|
||||
|
||||
final class Auth
|
||||
{
|
||||
private $accessKey;
|
||||
private $secretKey;
|
||||
|
||||
public function __construct($accessKey, $secretKey)
|
||||
{
|
||||
$this->accessKey = $accessKey;
|
||||
$this->secretKey = $secretKey;
|
||||
}
|
||||
|
||||
public function getAccessKey()
|
||||
{
|
||||
return $this->accessKey;
|
||||
}
|
||||
|
||||
public function sign($data)
|
||||
{
|
||||
$hmac = hash_hmac('sha1', $data, $this->secretKey, true);
|
||||
return $this->accessKey . ':' . \Qiniu\base64_urlSafeEncode($hmac);
|
||||
}
|
||||
|
||||
public function signWithData($data)
|
||||
{
|
||||
$data = \Qiniu\base64_urlSafeEncode($data);
|
||||
return $this->sign($data) . ':' . $data;
|
||||
}
|
||||
|
||||
public function signRequest($urlString, $body, $contentType = null)
|
||||
{
|
||||
$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 !== null && $contentType === 'application/x-www-form-urlencoded') {
|
||||
$data .= $body;
|
||||
}
|
||||
return $this->sign($data);
|
||||
}
|
||||
|
||||
public function verifyCallback($contentType, $originAuthorization, $url, $body)
|
||||
{
|
||||
$authorization = 'QBox ' . $this->signRequest($url, $body, $contentType);
|
||||
return $originAuthorization === $authorization;
|
||||
}
|
||||
|
||||
public function privateDownloadUrl($baseUrl, $expires = 3600)
|
||||
{
|
||||
$deadline = time() + $expires;
|
||||
|
||||
$pos = strpos($baseUrl, '?');
|
||||
if ($pos !== false) {
|
||||
$baseUrl .= '&e=';
|
||||
} else {
|
||||
$baseUrl .= '?e=';
|
||||
}
|
||||
$baseUrl .= $deadline;
|
||||
|
||||
$token = $this->sign($baseUrl);
|
||||
return "$baseUrl&token=$token";
|
||||
}
|
||||
|
||||
public function uploadToken(
|
||||
$bucket,
|
||||
$key = null,
|
||||
$expires = 3600,
|
||||
$policy = null,
|
||||
$strictPolicy = true,
|
||||
Zone $zone = null
|
||||
) {
|
||||
$deadline = time() + $expires;
|
||||
$scope = $bucket;
|
||||
if ($key !== null) {
|
||||
$scope .= ':' . $key;
|
||||
}
|
||||
$args = array();
|
||||
$args = self::copyPolicy($args, $policy, $strictPolicy);
|
||||
$args['scope'] = $scope;
|
||||
$args['deadline'] = $deadline;
|
||||
|
||||
if ($zone === null) {
|
||||
$zone = new Zone();
|
||||
}
|
||||
|
||||
list($upHosts, $err) = $zone->getUpHosts($this->accessKey, $bucket);
|
||||
if ($err === null) {
|
||||
$args['upHosts'] = $upHosts;
|
||||
}
|
||||
|
||||
$b = json_encode($args);
|
||||
return $this->signWithData($b);
|
||||
}
|
||||
|
||||
/**
|
||||
*上传策略,参数规格详见
|
||||
*http://developer.qiniu.com/docs/v6/api/reference/security/put-policy.html
|
||||
*/
|
||||
private static $policyFields = array(
|
||||
'callbackUrl',
|
||||
'callbackBody',
|
||||
'callbackHost',
|
||||
'callbackBodyType',
|
||||
'callbackFetchKey',
|
||||
|
||||
'returnUrl',
|
||||
'returnBody',
|
||||
|
||||
'endUser',
|
||||
'saveKey',
|
||||
'insertOnly',
|
||||
|
||||
'detectMime',
|
||||
'mimeLimit',
|
||||
'fsizeMin',
|
||||
'fsizeLimit',
|
||||
|
||||
'persistentOps',
|
||||
'persistentNotifyUrl',
|
||||
'persistentPipeline',
|
||||
|
||||
'deleteAfterDays',
|
||||
|
||||
'upHosts',
|
||||
);
|
||||
|
||||
private static $deprecatedPolicyFields = array(
|
||||
'asyncOps',
|
||||
);
|
||||
|
||||
private static function copyPolicy(&$policy, $originPolicy, $strictPolicy)
|
||||
{
|
||||
if ($originPolicy === null) {
|
||||
return array();
|
||||
}
|
||||
foreach ($originPolicy as $key => $value) {
|
||||
if (in_array((string) $key, self::$deprecatedPolicyFields, true)) {
|
||||
throw new \InvalidArgumentException("{$key} has deprecated");
|
||||
}
|
||||
if (!$strictPolicy || in_array((string) $key, self::$policyFields, true)) {
|
||||
$policy[$key] = $value;
|
||||
}
|
||||
}
|
||||
return $policy;
|
||||
}
|
||||
|
||||
public function authorization($url, $body = null, $contentType = null)
|
||||
{
|
||||
$authorization = 'QBox ' . $this->signRequest($url, $body, $contentType);
|
||||
return array('Authorization' => $authorization);
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue