Feat: User profile

This commit is contained in:
HFO4 2019-03-14 10:00:53 +08:00
parent 737665c62c
commit 3a4912083c
5 changed files with 145 additions and 418 deletions

View file

@ -14,11 +14,63 @@ class Profile extends Controller{
public $siteOptions;
public function _initialize(){
$this->siteOptions = Option::getValues(["basic"]);
}
public function getList(){
$userId = (string)input("post.uid");
$userData = Db::name("users")->where("id",$userId)->find();
$page = (int)input("post.page");
if (empty($userId) || empty($userData) || $userData["profile"] == 0){
$this->error('用户主页不存或者用户关闭了个人主页',404,$this->siteOptions);
}
switch (input("post.type")) {
case 'all':
$list = Db::name('shares')
->where('owner',$userId)
->where('type',"public")
->order('share_time DESC')
->page($page.',10')
->select();
break;
case 'hot':
$num = Option::getValue("hot_share_num");
$list = Db::name('shares')
->where('owner',$userId)
->where('type',"public")
->order('download_num DESC')
->limit($num)
->select();
break;
default:
$list = Db::name('shares')
->where('owner',$userId)
->where('type',"public")
->order('share_time DESC')
->page($page.',10')
->select();
break;
}
$listData = $list;
foreach ($listData as $key => $value) {
unset($listData[$key]["share_pwd"]);
unset($listData[$key]["source_name"]);
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 json($listData);
}
public function index(){
$this->visitorObj = new User(cookie('user_id'),cookie('login_key'));
$this->siteOptions = Option::getValues(["basic"],$this->visitorObj->userSQLData);
$userId = (string)input("param.uid");
$userData = Db::name("users")->where("id",$userId)->find();
if (empty($userId) || empty($userData) || $userData["profile"] == 0){
@ -30,47 +82,14 @@ class Profile extends Controller{
->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('share_time 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('share_time 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,
'targetUserInfo' => $userData,
'userSQL' => $this->visitorObj->userSQLData,
'userInfo' => $this->visitorObj->getInfo(),
'groupData' => $groupData,
'list' => $listData,
'listOrigin' => $list,
'type' => input("get.type"),
'shareCount' => $shareCount,
'regDays' => $regDays,

View file

@ -83,10 +83,11 @@
<script src="http://192.168.123.19:3000/static/js/2.chunk.js"></script>
<script src="http://192.168.123.19:3000/static/js/3.chunk.js"></script>
<script src="http://192.168.123.19:3000/static/js/4.chunk.js"></script>
<script src="http://192.168.123.19:3000/static/js/6.chunk.js"></script>
<script src="http://192.168.123.19:3000/static/js/1.chunk.js"></script>
<script src="http://192.168.123.19:3000/static/js/9.chunk.js"></script>
<script src="http://192.168.123.19:3000/static/js/5.chunk.js"></script>
<script src="http://192.168.123.19:3000/static/js/7.chunk.js"></script>
<script src="http://192.168.123.19:3000/static/js/1.chunk.js"></script>
<script src="http://192.168.123.19:3000/static/js/6.chunk.js"></script>
<script src="http://192.168.123.19:3000/static/js/11.chunk.js"></script>
<script src="http://192.168.123.19:3000/static/js/index.chunk.js"></script>
</html>

View file

@ -74,8 +74,10 @@
<script src="http://192.168.123.19:3000/static/js/0.chunk.js"></script>
<script src="http://192.168.123.19:3000/static/js/2.chunk.js"></script>
<script src="http://192.168.123.19:3000/static/js/3.chunk.js"></script>
<script src="http://192.168.123.19:3000/static/js/8.chunk.js"></script>
<script src="http://192.168.123.19:3000/static/js/4.chunk.js"></script>
<script src="http://192.168.123.19:3000/static/js/9.chunk.js"></script>
<script src="http://192.168.123.19:3000/static/js/10.chunk.js"></script>
<script src="http://192.168.123.19:3000/static/js/12.chunk.js"></script>
<script src="http://192.168.123.19:3000/static/js/1.chunk.js"></script>
<script src="http://192.168.123.19:3000/static/js/setting.chunk.js"></script>

View file

@ -1,265 +0,0 @@
{extend name="header_home" /}
{block name="title"}用户设置- {$options.siteName}{/block}
{block name="content"}
<link rel="stylesheet" href="/static/css/setting.css" />
<style type="text/css">
.col-md-3{
padding-right: 15px;
padding-left: 15px;
}
</style>
</head>
<body >
<div id="container">
{include file="navbar_home" /}
<div class="col-md-10 quota_content">
<h1>用户设置</h1>
<br>
<div class="fix_side">
<div class="fix">
<div class="col-md-9">
<ul class="nav nav-tabs" >
<li class="active"><a href="#home" data-toggle="tab" aria-expanded="true">基本信息<div class="ripple-container"></div></a></li>
<li class=""><a href="#security" data-toggle="tab" aria-expanded="false">安全隐私<div class="ripple-container"></div></a></li>
<li class=""><a href="#password" data-toggle="tab" aria-expanded="false">修改密码<div class="ripple-container"></div></a></li>
<li class=""><a href="#webdav" data-toggle="tab" aria-expanded="false">WebDAV<div class="ripple-container"></div></a></li>
</ul>
<div id="myTabContent" class="tab-content">
<div class="tab-pane fade active in" id="home">
<div class="panel panel-default">
<div class="panel-body" id="packs">
<div class="col-md-8">
<div class="row fix">
<div class="col-md-3 option_name"><label for="uid">UID</label></div>
<div class="col-md-9">
<div class="non_input">{$userInfo.uid}</div>
</div>
</div>
<div class="row fix">
<div class="col-md-3 option_name"><label for="nick">昵称:</label></div>
<div class="col-md-6">
<input type="text" class="form-control" id="nick" value="{$userInfo.userNick}" >
</div>
</div>
<div class="row fix">
<div class="col-md-3 option_name"><label for="email">Email</label></div>
<div class="col-md-9">
<input type="email" class="form-control" id="email" value="{$userInfo.userMail}" disabled>
</div>
</div>
<div class="row fix">
<div class="col-md-3 option_name"><label for="inputEmail">用户组:</label></div>
<div class="col-md-9">
<div class="non_input group">{$groupData.group_name} </div>
</div>
</div>
<div class="row fix">
<div class="col-md-3 option_name"><label for="inputEmail">注册日期:</label></div>
<div class="col-md-9">
<div class="non_input ">{$userInfo.regDate}</div>
</div>
</div>
<div class="row fix">
<div class="col-md-3 option_name"><label for="inputEmail"></label></div>
<div class="col-md-9">
<div class="non_input "><button class="btn btn-raised btn-primary" id="saveNick">保存更改</button></div>
</div>
</div>
</div>
<div class="col-md-4">
<div class="avatar">
<img src="/Member/Avatar/{$userInfo.uid}/l?cache=no" class="img-circle avatar-img"><br>
<button class="btn btn-primary" data-toggle="modal" data-target="#avatar_modal"><i class="fa fa-pencil-square-o" aria-hidden="true"></i> 修改头像</button>
</div>
</div>
</div>
</div>
</div>
<div class="tab-pane fade" id="security">
<div class="panel panel-default">
<div class="panel-body" >
<div class="row fix">
<div class="col-md-3 option_name"><label for="inputEmail">个人主页:</label></div>
<div class="col-md-9">
<div ><div class="togglebutton">
<label>
<input type="checkbox" id="homePage" {eq name="$userSQL.profile" value="1"}checked{else}{/eq}>
</label>
</div></div>
</div>
</div>
<div class="row fix">
<div class="col-md-3 option_name" style="margin-top: 10px;"><label for="inputEmail">二步验证:</label></div>
<div class="col-md-9">
{eq name="$userSQL.two_step" value="0"}
<button class="btn btn-primary btn-raised" id="twoStep"><i class="fa fa-lock" aria-hidden="true"></i> 开启二步验证</button>
{else}
<button class="btn btn-primary btn-raised"><i class="fa fa-check" aria-hidden="true"></i> 已开启</button>
{/eq}
</div>
</div>
</div>
</div>
</div>
<div class="tab-pane fade" id="password">
<div class="panel panel-default">
<div class="panel-body" >
<div class="row fix">
<div class="col-md-3 option_name"><label for="inputEmail">原密码:</label></div>
<div class="col-md-6">
<input type="password" class="form-control" id="passOrigin" >
</div>
</div>
<div class="row fix">
<div class="col-md-3 option_name"><label for="inputEmail">新密码:</label></div>
<div class="col-md-6">
<input type="password" class="form-control" id="passNew" >
</div>
</div>
<div class="row fix">
<div class="col-md-3 option_name"><label for="inputEmail">确认新密码:</label></div>
<div class="col-md-6">
<input type="password" class="form-control" id="passNewRepet" >
</div>
</div>
<div class="row fix">
<div class="col-md-3 option_name"><label for="inputEmail"></label></div>
<div class="col-md-9">
<div class="non_input "><button class="btn btn-raised btn-primary waves-effect" id="savePwd">保存更改</button></div>
</div>
</div>
</div>
</div>
</div>
<div class="tab-pane fade" id="webdav">
<div class="panel panel-default">
<div class="panel-body" >
{eq name="groupData.webdav" value="0"}
<div class="alert alert-warning" role="alert">
您当前的用户组不支持WebDAV
</div>
{else/}
<div class="row fix">
<div class="col-md-3 option_name"><label for="inputEmail">连接地址:</label></div>
<div class="col-md-6">
<input type="text" class="form-control" id="webdavUrl" value="{$options.siteURL}WebDav/Api/uid/{$userInfo.uid}" spellcheck="false" readonly>
</div>
</div>
<div class="row fix">
<div class="col-md-3 option_name"><label for="inputEmail">用户名:</label></div>
<div class="col-md-6">
<input type="text" class="form-control" id="webdavUsername" value="{$userInfo.userMail}" spellcheck="false" readonly>
</div>
</div>
<div class="row fix">
<div class="col-md-3 option_name" style="margin-top: 10px;"><label for="inputEmail">登录密码:</label></div>
<div class="col-md-9">
<button class="btn btn-primary btn-raised" id="setWebdavPwd"><i class="fa fa-lock" aria-hidden="true"></i> 设置/更改密码</button>
</div>
</div>
{/eq}<br>
<p>你可以使用任何支持WebDAV协议的文件管理工具或操作系统将网盘映射到本地方便多端同步管理。初次使用请先设置WebDAV登录密码此密码默认与登录密码不相同。</p>
</div>
</div>
</div>
</div>
</div>
<div class="col-md-3"><div class="panel panel-default">
<div class="panel-heading">公告</div>
<div class="panel-body">
公告内容
</div>
</div></div>
</div>
</div>
<br>
<div class="fix_side">
<div class="fix">
</div>
</div>
</div>
<div class="modal fade" tabindex="-1" role="dialog" id="avatar_modal">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
<h4 class="modal-title">修改头像</h4>
</div>
<div class="modal-body">
<div class="row fix">
<div class="col-md-4"><div class="avatar"><img src="/Member/Avatar/{$userInfo.uid}/l?cache=no" class="img-circle avatar-img"><br></div></div>
<div class="col-md-8">
<span class="btn btn-raised btn-info fileinput-button" id="uploadAvatar">
<span id="upload-text">上传头像</span>
<input type="file" accept="image/*" id="avatar_file" name="avatar">
</span>
<br><button class="btn btn-raised btn-info" id="useGravatar">使用Gravatar头像</button>
<br>修改头像后请清理浏览器缓存
</div>
</div>
</div>
<div class="modal-footer">
<button class="btn btn-primary " data-dismiss="modal">取消</button>
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div><!-- /.modal -->
<div class="modal fade" tabindex="-1" role="dialog" id="two_step_modal">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
<h4 class="modal-title">开启二步验证</h4>
</div>
<div class="modal-body">
<div class="row fix">
<div class="col-md-4"><img id="qrcode"></div>
<div class="col-md-8">
<div class="alert alert-success" role="alert">请使用任意二步验证APP或者支持二步验证的密码管理软件扫描左侧二维码添加本站。扫描完成后请填写二步验证APP给出的6位验证码以开启二步验证。</div>
<input type="number" class="form-control" placeholder="请输入6位验证码" id="vCode">
</div>
</div>
</div>
<div class="modal-footer">
<button class="btn btn-info " id="confirm">确认开启</button>
<button class="btn btn-primary " data-dismiss="modal">取消</button>
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div><!-- /.modal -->
<div class="modal fade" tabindex="-1" role="dialog" id="set_webdav_pwd">
<div class="modal-dialog modal-sm" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
<h4 class="modal-title">设置WebDAV认证密码</h4>
</div>
<div class="modal-body">
<div class="row fix">
<label>请输入密码:</label>
<input type="password" id="webdav_pwd" class="form-control" autocomplete="false">
</div>
</div>
<div class="modal-footer">
<button class="btn btn-info " id="confirmWebdav">保存</button>
<button class="btn btn-primary " data-dismiss="modal">取消</button>
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div><!-- /.modal -->
</body>
<script src="/static/js/material.js"></script>
<script src="/static/js/uploader.min.js"></script>
<script type="text/javascript">
upload_load=0;
</script>
<script src="/static/js/setting.js"></script>
{$options.js_code}
</html>
{/block}

View file

@ -1,115 +1,85 @@
{extend name="header_public" /}
{block name="title"}用户主页 - {$options.siteName}{/block}
{block name="content"}
<link rel="stylesheet" href="/static/css/profile.css" />
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="utf-8">
<link rel="shortcut icon" href="/favicon.ico">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="theme-color" content="{$options.themeColor}" />
<!--
manifest.json provides metadata used when your web app is added to the
homescreen on Android. See https://developers.google.com/web/fundamentals/web-app-manifest/
-->
<link rel="manifest" href="/manifest.json">
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>用户主页 - {$options.siteName}</title>
<script type="text/javascript">
colorTheme = {:json_encode($options["themeConfig"])};
isHomePage = false;
isSharePage = false;
pageId="profile";
taegetUserInfo = {
uid:{$targetUserInfo.id},
nickname:"{$targetUserInfo.user_nick}",
regDate:"{$targetUserInfo.user_date}",
shareCount:"{$shareCount}",
group:"{$groupData.group_name}",
};
userInfo = {
uid: {$userInfo.uid},
nick: "{$userInfo.userNick}",
email: "{$userInfo.userMail}",
group: "{$userInfo.groupData.group_name}",
groupId: {$userInfo.groupData.id},
groupColor: "{$userInfo.groupData.color}",
regTime: "{$userSQL.user_date}",
homePage: "{$userSQL.profile}",
twoFactor: "{$userSQL.two_step}",
webdav:"{$userInfo.groupData.webdav}",
};
siteInfo = {
mainTitle: "{$options.siteName}",
};
uploadConfig = {
allowSource: false,
allowShare: false,
allowRemoteDownload: "0",
allowTorrentDownload: "0",
};
isMobile = window.innerWidth < 600;
</script>
</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>
<body>
{/volist}
</tbody>
</table>
<noscript>
You need to enable JavaScript to run this app.
</noscript>
<div id="root"></div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
</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}
You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the <body> tag.
To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
</body>
<script src="http://192.168.123.19:3000/static/js/runtime~profile.bundle.js"></script>
<script src="http://192.168.123.19:3000/static/js/0.chunk.js"></script>
<script src="http://192.168.123.19:3000/static/js/3.chunk.js"></script>
<script src="http://192.168.123.19:3000/static/js/9.chunk.js"></script>
<script src="http://192.168.123.19:3000/static/js/1.chunk.js"></script>
<script src="http://192.168.123.19:3000/static/js/profile.chunk.js"></script>
</html>